[Translation] Added flatten method on ArrayLoader

This allows the translations to be deeply nested arrays that will be flattened, allowing for namespacing of translations easily.

The following:
  'key' => array('key2' => array('key3' => 'value'))
Becomes:
  'key.key2.key3' => 'value'

This isn't applied to Xliff since it does not make sense within the scope of the XLIFF standard
This commit is contained in:
Jordi Boggiano 2010-11-14 20:31:11 +01:00 committed by Fabien Potencier
parent 4e5c99dab0
commit 3cbc99c180
4 changed files with 74 additions and 8 deletions

View File

@ -25,9 +25,42 @@ class ArrayLoader implements LoaderInterface
*/
public function load($resource, $locale, $domain = 'messages')
{
$catalogue = $this->flatten($resource);
$catalogue = new MessageCatalogue($locale);
$catalogue->addMessages($resource, $domain);
return $catalogue;
}
/**
* Flattens an nested array of translations
*
* The scheme used is:
* 'key' => array('key2' => array('key3' => 'value'))
* Becomes:
* 'key.key2.key3' => 'value'
*
* This function takes an array by reference and will modify it
*
* @param array $messages the array that will be flattened
* @param array $subnode current subnode being parsed, used internally for recursive calls
* @param string $path current path being parsed, used internally for recursive calls
*/
protected function flatten(array &$messages, array $subnode = null, $path = null)
{
if ($subnode === null) {
$subnode =& $messages;
}
foreach ($subnode as $key => $value) {
if (is_array($value)) {
$nodePath = $path ? $path.'.'.$key : $key;
$this->flatten($messages, $value, $nodePath);
if ($path === null) {
unset($messages[$key]);
}
} elseif ($path !== null) {
$messages[$path.'.'.$key] = $value;
}
}
}
}

View File

@ -2,7 +2,6 @@
namespace Symfony\Component\Translation\Loader;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Resource\FileResource;
/*
@ -19,15 +18,16 @@ use Symfony\Component\Translation\Resource\FileResource;
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class PhpFileLoader implements LoaderInterface
class PhpFileLoader extends ArrayLoader implements LoaderInterface
{
/**
* {@inheritdoc}
*/
public function load($resource, $locale, $domain = 'messages')
{
$catalogue = new MessageCatalogue($locale);
$catalogue->addMessages(require($resource), $domain);
$messages = require($resource);
$catalogue = parent::load($messages, $locale, $domain);
$catalogue->addResource(new FileResource($resource));
return $catalogue;

View File

@ -2,7 +2,6 @@
namespace Symfony\Component\Translation\Loader;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Resource\FileResource;
use Symfony\Component\Yaml\Yaml;
@ -20,7 +19,7 @@ use Symfony\Component\Yaml\Yaml;
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class YamlFileLoader implements LoaderInterface
class YamlFileLoader extends ArrayLoader implements LoaderInterface
{
/**
* {@inheritdoc}
@ -29,8 +28,7 @@ class YamlFileLoader implements LoaderInterface
{
$messages = Yaml::load($resource);
$catalogue = new MessageCatalogue($locale);
$catalogue->addMessages($messages, $domain);
$catalogue = parent::load($messages, $locale, $domain);
$catalogue->addResource(new FileResource($resource));
return $catalogue;

View File

@ -74,6 +74,18 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
}
/**
* @dataProvider getFlattenedTransTests
*/
public function testFlattenedTrans($expected, $messages, $id)
{
$translator = new Translator('en', new MessageSelector());
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', $messages, 'fr', '');
$this->assertEquals($expected, $translator->trans($id, array(), '', 'fr'));
}
/**
* @dataProvider getTransChoiceTests
*/
@ -94,6 +106,29 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
);
}
public function getFlattenedTransTests()
{
$messages = array(
'symfony2' => array(
'is' => array(
'great' => 'Symfony2 est super!'
)
),
'foo' => array(
'bar' => array(
'baz' => 'Foo Bar Baz'
),
'baz' => 'Foo Baz',
),
);
return array(
array('Symfony2 est super!', $messages, 'symfony2.is.great'),
array('Foo Bar Baz', $messages, 'foo.bar.baz'),
array('Foo Baz', $messages, 'foo.baz'),
);
}
public function getTransChoiceTests()
{
return array(