diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 5755dbe4f8..20ec2e2dbf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -40,6 +40,7 @@ class FrameworkExtension extends Extension * * @param array $configs * @param ContainerBuilder $container + * * @throws LogicException */ public function load(array $configs, ContainerBuilder $container) @@ -686,6 +687,8 @@ class FrameworkExtension extends Extension foreach ($dirs as $dir) { $container->addResource(new DirectoryResource($dir)); } + + $files = array(); $finder = Finder::create() ->files() ->filter(function (\SplFileInfo $file) { @@ -695,10 +698,15 @@ class FrameworkExtension extends Extension ; foreach ($finder as $file) { - // filename is domain.locale.format list($domain, $locale, $format) = explode('.', $file->getBasename(), 3); - $translator->addMethodCall('addResource', array($format, (string) $file, $locale, $domain)); + if (!isset($files[$locale])) { + $files[$locale] = array(); + } + + $files[$locale][] = (string) $file; } + + $translator->replaceArgument(4, $files); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index b0dac08e3f..1c6eb323b0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -44,6 +44,7 @@ %kernel.cache_dir%/translations %kernel.debug% + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 8fa733579e..d771ce7e3b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -218,18 +218,11 @@ abstract class FrameworkExtensionTest extends TestCase public function testTranslator() { $container = $this->createContainerFromFile('full'); - $this->assertTrue($container->hasDefinition('translator.default'), '->registerTranslatorConfiguration() loads translation.xml'); $this->assertEquals('translator.default', (string) $container->getAlias('translator'), '->registerTranslatorConfiguration() redefines translator service from identity to real translator'); + $resources = $container->getDefinition('translator.default')->getArgument(4); - $resources = array(); - foreach ($container->getDefinition('translator.default')->getMethodCalls() as $call) { - if ('addResource' == $call[0]) { - $resources[] = $call[1]; - } - } - - $files = array_map(function ($resource) { return realpath($resource[1]); }, $resources); + $files = array_map(function ($resource) { return realpath($resource); }, $resources['en']); $ref = new \ReflectionClass('Symfony\Component\Validator\Validation'); $this->assertContains( strtr(dirname($ref->getFileName()).'/Resources/translations/validators.en.xlf', '/', DIRECTORY_SEPARATOR), diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/translations/messages.fr.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/translations/messages.fr.yml new file mode 100644 index 0000000000..767141de62 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/translations/messages.fr.yml @@ -0,0 +1 @@ +folder: répertoire diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index 1ae14e83d0..d9ce054ce8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -95,13 +95,50 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase public function testTransWithCachingWithInvalidLocale() { $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface'); - $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), '\Symfony\Bundle\FrameworkBundle\Tests\Translation\TranslatorWithInvalidLocale'); + $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), array(), 'loader', '\Symfony\Bundle\FrameworkBundle\Tests\Translation\TranslatorWithInvalidLocale'); $translator->setLocale('invalid locale'); $this->setExpectedException('\InvalidArgumentException'); $translator->trans('foo'); } + public function testLoadRessourcesWithCaching() + { + $loader = new \Symfony\Component\Translation\Loader\YamlFileLoader(); + $resourceFiles = array( + 'fr' => array( + __DIR__.'/../Fixtures/Resources/translations/messages.fr.yml', + ), + ); + + // prime the cache + $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), $resourceFiles, 'yml'); + $translator->setLocale('fr'); + + $this->assertEquals('répertoire', $translator->trans('folder')); + + // do it another time as the cache is primed now + $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), array(), 'yml'); + $translator->setLocale('fr'); + + $this->assertEquals('répertoire', $translator->trans('folder')); + } + + public function testLoadRessourcesWithoutCaching() + { + $loader = new \Symfony\Component\Translation\Loader\YamlFileLoader(); + $resourceFiles = array( + 'fr' => array( + __DIR__.'/../Fixtures/Resources/translations/messages.fr.yml', + ), + ); + + $translator = $this->getTranslator($loader, array(), $resourceFiles, 'yml'); + $translator->setLocale('fr'); + + $this->assertEquals('répertoire', $translator->trans('folder')); + } + protected function getCatalogue($locale, $messages) { $catalogue = new MessageCatalogue($locale); @@ -182,22 +219,25 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase return $container; } - public function getTranslator($loader, $options = array(), $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator') + public function getTranslator($loader, $options = array(), $resources = array(), $loaderFomat = 'loader', $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator') { $translator = new $translatorClass( $this->getContainer($loader), new MessageSelector(), - array('loader' => array('loader')), - $options + array($loaderFomat => array($loaderFomat)), + $options, + $resources ); - $translator->addResource('loader', 'foo', 'fr'); - $translator->addResource('loader', 'foo', 'en'); - $translator->addResource('loader', 'foo', 'es'); - $translator->addResource('loader', 'foo', 'pt-PT'); // European Portuguese - $translator->addResource('loader', 'foo', 'pt_BR'); // Brazilian Portuguese - $translator->addResource('loader', 'foo', 'fr.UTF-8'); - $translator->addResource('loader', 'foo', 'sr@latin'); // Latin Serbian + if ('loader' === $loaderFomat) { + $translator->addResource('loader', 'foo', 'fr'); + $translator->addResource('loader', 'foo', 'en'); + $translator->addResource('loader', 'foo', 'es'); + $translator->addResource('loader', 'foo', 'pt-PT'); // European Portuguese + $translator->addResource('loader', 'foo', 'pt_BR'); // Brazilian Portuguese + $translator->addResource('loader', 'foo', 'fr.UTF-8'); + $translator->addResource('loader', 'foo', 'sr@latin'); // Latin Serbian + } return $translator; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index 80b4d198ac..8e9843931d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -24,6 +24,7 @@ class Translator extends BaseTranslator { protected $container; protected $loaderIds; + protected $resourceFiles; protected $options = array( 'cache_dir' => null, @@ -38,17 +39,19 @@ class Translator extends BaseTranslator * * cache_dir: The cache directory (or null to disable caching) * * debug: Whether to enable debugging or not (false by default) * - * @param ContainerInterface $container A ContainerInterface instance - * @param MessageSelector $selector The message selector for pluralization - * @param array $loaderIds An array of loader Ids - * @param array $options An array of options + * @param ContainerInterface $container A ContainerInterface instance + * @param MessageSelector $selector The message selector for pluralization + * @param array $loaderIds An array of loader Ids + * @param array $options An array of options + * @param array $resourceFiles An array of resource directories * * @throws \InvalidArgumentException */ - public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array()) + public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array(), $resourceFiles = array()) { $this->container = $container; $this->loaderIds = $loaderIds; + $this->resourceFiles = $resourceFiles; // check option names if ($diff = array_diff(array_keys($options), array_keys($this->options))) { @@ -66,6 +69,7 @@ class Translator extends BaseTranslator protected function initializeCatalogue($locale) { $this->initialize(); + $this->loadResources($locale); parent::initializeCatalogue($locale); } @@ -77,4 +81,19 @@ class Translator extends BaseTranslator } } } + + private function loadResources($locale) + { + $locales = array_merge(array($locale), $this->computeFallbackLocales($locale)); + foreach ($locales as $locale) { + if (isset($this->resourceFiles[$locale])) { + foreach ($this->resourceFiles[$locale] as $file) { + // filename is domain.locale.format + list($domain, $locale, $format) = explode('.', basename($file), 3); + $this->addResource($format, $file, $locale, $domain); + } + unset($this->resourceFiles[$locale]); + } + } + } }