From 20f7d116ab6b75a9c3a0bfd55ea8e0c34d5148a0 Mon Sep 17 00:00:00 2001 From: Abdellatif Ait boudad Date: Tue, 10 Mar 2015 21:45:35 +0000 Subject: [PATCH 1/4] [translation] fixed loading resources performances. --- .../Compiler/TranslatorPass.php | 4 +++- .../FrameworkExtension.php | 15 ++----------- .../Resources/config/translation.xml | 1 + .../Compiler/TranslatorPassTest.php | 7 +++++- .../Tests/Translation/TranslatorTest.php | 1 + .../Translation/Translator.php | 22 ++++++++++++++++++- 6 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php index 4e450166afa44..3519901c68153 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php @@ -40,6 +40,8 @@ public function process(ContainerBuilder $container) } } - $container->findDefinition('translator.default')->replaceArgument(2, $loaders); + $translatorDefinition = $container->findDefinition('translator.default'); + $translatorDefinition->replaceArgument(2, $loaders); + $translatorDefinition->replaceArgument(3, $container->getParameter('translator.resource.directories')); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 5755dbe4f814f..d53f645ed63fb 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) @@ -682,23 +683,11 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder } // Register translation resources + $container->setParameter('translator.resource.directories', $dirs); if ($dirs) { foreach ($dirs as $dir) { $container->addResource(new DirectoryResource($dir)); } - $finder = Finder::create() - ->files() - ->filter(function (\SplFileInfo $file) { - return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename()); - }) - ->in($dirs) - ; - - 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)); - } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index b0dac08e3f255..e53f5c6f60f08 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -40,6 +40,7 @@ + %kernel.cache_dir%/translations %kernel.debug% diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php index 83f70514d5456..d6d6e89b393e8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php @@ -28,7 +28,7 @@ public function testValidCollector() $container = $this->getMock( 'Symfony\Component\DependencyInjection\ContainerBuilder', - array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'findDefinition') + array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'findDefinition', 'getParameter') ); $container->expects($this->any()) ->method('hasDefinition') @@ -42,6 +42,11 @@ public function testValidCollector() $container->expects($this->once()) ->method('findDefinition') ->will($this->returnValue($this->getMock('Symfony\Component\DependencyInjection\Definition'))); + $container->expects($this->once()) + ->method('getParameter') + ->with('translator.resource.directories') + ->will($this->returnValue(array())); + $pass = new TranslatorPass(); $pass->process($container); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index 1ae14e83d0bcc..17355825e6a6e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -188,6 +188,7 @@ public function getTranslator($loader, $options = array(), $translatorClass = '\ $this->getContainer($loader), new MessageSelector(), array('loader' => array('loader')), + array(), $options ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index 80b4d198ac505..d054e6b59c10d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -14,6 +14,7 @@ use Symfony\Component\Translation\Translator as BaseTranslator; use Symfony\Component\Translation\MessageSelector; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Finder\Finder; /** * Translator. @@ -24,6 +25,7 @@ class Translator extends BaseTranslator { protected $container; protected $loaderIds; + protected $resourceDirs; protected $options = array( 'cache_dir' => null, @@ -41,14 +43,16 @@ class Translator extends BaseTranslator * @param ContainerInterface $container A ContainerInterface instance * @param MessageSelector $selector The message selector for pluralization * @param array $loaderIds An array of loader Ids + * @param array $resourceDirs An array of resource directories * @param array $options An array of options * * @throws \InvalidArgumentException */ - public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array()) + public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), $resourceDirs = array(), array $options = array()) { $this->container = $container; $this->loaderIds = $loaderIds; + $this->resourceDirs = $resourceDirs; // check option names if ($diff = array_diff(array_keys($options), array_keys($this->options))) { @@ -76,5 +80,21 @@ protected function initialize() $this->addLoader($alias, $this->container->get($id)); } } + + if ($this->resourceDirs) { + $finder = Finder::create() + ->files() + ->filter(function (\SplFileInfo $file) { + return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename()); + }) + ->in($this->resourceDirs) + ; + + foreach ($finder as $file) { + // filename is domain.locale.format + list($domain, $locale, $format) = explode('.', $file->getBasename(), 3); + $this->addResource($format, (string) $file, $locale, $domain); + } + } } } From 5c2d1ed7d38c6b7d3bc1a0aaf2dcf07453b7652f Mon Sep 17 00:00:00 2001 From: Abdellatif Ait boudad Date: Tue, 10 Mar 2015 23:15:54 +0000 Subject: [PATCH 2/4] [translation][loading resources] added test. --- .../Compiler/TranslatorPass.php | 4 +- .../FrameworkExtension.php | 2 +- .../Resources/config/translation.xml | 2 +- .../Compiler/TranslatorPassTest.php | 8 ++- .../FrameworkExtensionTest.php | 25 +++------ .../Resources/translations/messages.fr.yml | 1 + .../Tests/Translation/TranslatorTest.php | 52 ++++++++++++++----- .../Translation/Translator.php | 4 +- 8 files changed, 62 insertions(+), 36 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/translations/messages.fr.yml diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php index 3519901c68153..f4867616e823c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php @@ -42,6 +42,8 @@ public function process(ContainerBuilder $container) $translatorDefinition = $container->findDefinition('translator.default'); $translatorDefinition->replaceArgument(2, $loaders); - $translatorDefinition->replaceArgument(3, $container->getParameter('translator.resource.directories')); + if ($container->hasParameter('translator.resource_directories')) { + $translatorDefinition->replaceArgument(4, $container->getParameter('translator.resource_directories')); + } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index d53f645ed63fb..d7aa1702acf17 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -683,7 +683,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder } // Register translation resources - $container->setParameter('translator.resource.directories', $dirs); + $container->setParameter('translator.resource_directories', $dirs); if ($dirs) { foreach ($dirs as $dir) { $container->addResource(new DirectoryResource($dir)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index e53f5c6f60f08..1c6eb323b0fb4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -40,11 +40,11 @@ - %kernel.cache_dir%/translations %kernel.debug% + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php index d6d6e89b393e8..55c8c1cbe0cd3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php @@ -28,7 +28,7 @@ public function testValidCollector() $container = $this->getMock( 'Symfony\Component\DependencyInjection\ContainerBuilder', - array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'findDefinition', 'getParameter') + array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'findDefinition', 'hasParameter', 'getParameter') ); $container->expects($this->any()) ->method('hasDefinition') @@ -42,9 +42,13 @@ public function testValidCollector() $container->expects($this->once()) ->method('findDefinition') ->will($this->returnValue($this->getMock('Symfony\Component\DependencyInjection\Definition'))); + $container->expects($this->once()) + ->method('hasParameter') + ->with('translator.resource_directories') + ->will($this->returnValue(true)); $container->expects($this->once()) ->method('getParameter') - ->with('translator.resource.directories') + ->with('translator.resource_directories') ->will($this->returnValue(array())); $pass = new TranslatorPass(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 8fa733579e3a2..586d8464559fc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -222,31 +222,22 @@ public function testTranslator() $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 = array(); - foreach ($container->getDefinition('translator.default')->getMethodCalls() as $call) { - if ('addResource' == $call[0]) { - $resources[] = $call[1]; - } - } + $dirs = $container->getParameter('translator.resource_directories'); - $files = array_map(function ($resource) { return realpath($resource[1]); }, $resources); $ref = new \ReflectionClass('Symfony\Component\Validator\Validation'); $this->assertContains( - strtr(dirname($ref->getFileName()).'/Resources/translations/validators.en.xlf', '/', DIRECTORY_SEPARATOR), - $files, - '->registerTranslatorConfiguration() finds Validator translation resources' + dirname($ref->getFileName()).'/Resources/translations', + $dirs ); $ref = new \ReflectionClass('Symfony\Component\Form\Form'); $this->assertContains( - strtr(dirname($ref->getFileName()).'/Resources/translations/validators.en.xlf', '/', DIRECTORY_SEPARATOR), - $files, - '->registerTranslatorConfiguration() finds Form translation resources' + dirname($ref->getFileName()).'/Resources/translations', + $dirs ); - $ref = new \ReflectionClass('Symfony\Component\Security\Core\Security'); + $ref = new \ReflectionClass('Symfony\Component\Security\Core\Exception\AuthenticationException'); $this->assertContains( - strtr(dirname($ref->getFileName()).'/Resources/translations/security.en.xlf', '/', DIRECTORY_SEPARATOR), - $files, - '->registerTranslatorConfiguration() finds Security translation resources' + dirname($ref->getFileName()).'/../Resources/translations', + $dirs ); $calls = $container->getDefinition('translator.default')->getMethodCalls(); 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 0000000000000..767141de628f0 --- /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 17355825e6a6e..1bcdee7716746 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -95,13 +95,39 @@ public function testTransWithCaching() 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(); + + // prime the cache + $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), array(__DIR__.'/../Fixtures/Resources/translations'), '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(); + $translator = $this->getTranslator($loader, array(), array(__DIR__.'/../Fixtures/Resources/translations'), 'yml'); + $translator->setLocale('fr'); + + $this->assertEquals('répertoire', $translator->trans('folder')); + } + protected function getCatalogue($locale, $messages) { $catalogue = new MessageCatalogue($locale); @@ -182,23 +208,25 @@ protected function getContainer($loader) 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')), - array(), - $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 d054e6b59c10d..95d671334c0e8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -43,12 +43,12 @@ class Translator extends BaseTranslator * @param ContainerInterface $container A ContainerInterface instance * @param MessageSelector $selector The message selector for pluralization * @param array $loaderIds An array of loader Ids - * @param array $resourceDirs An array of resource directories * @param array $options An array of options + * @param array $resourceDirs An array of resource directories * * @throws \InvalidArgumentException */ - public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), $resourceDirs = array(), array $options = array()) + public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array(), $resourceDirs = array()) { $this->container = $container; $this->loaderIds = $loaderIds; From 7be239f789fe4720a6fc8dc2ae089453efab5411 Mon Sep 17 00:00:00 2001 From: Abdellatif Ait boudad Date: Wed, 11 Mar 2015 09:01:42 +0000 Subject: [PATCH 3/4] [translation] load resources per locale. --- .../Compiler/TranslatorPass.php | 24 +++++++++++- .../Compiler/TranslatorPassTest.php | 15 +++++++- .../Tests/Translation/TranslatorTest.php | 15 +++++++- .../Translation/Translator.php | 38 +++++++++---------- 4 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php index f4867616e823c..88806d05f491a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php @@ -14,6 +14,7 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\Finder\Finder; class TranslatorPass implements CompilerPassInterface { @@ -43,7 +44,28 @@ public function process(ContainerBuilder $container) $translatorDefinition = $container->findDefinition('translator.default'); $translatorDefinition->replaceArgument(2, $loaders); if ($container->hasParameter('translator.resource_directories')) { - $translatorDefinition->replaceArgument(4, $container->getParameter('translator.resource_directories')); + $resourceDirs = $container->getParameter('translator.resource_directories'); + $files = array(); + if ($resourceDirs) { + $finder = Finder::create() + ->files() + ->filter(function (\SplFileInfo $file) { + return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename()); + }) + ->in($resourceDirs) + ; + + foreach ($finder as $file) { + list($domain, $locale, $format) = explode('.', $file->getBasename(), 3); + if (!isset($files[$locale])) { + $files[$locale] = array(); + } + + $files[$locale][] = (string) $file; + } + } + + $translatorDefinition->replaceArgument(4, $files); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php index 55c8c1cbe0cd3..7e8ca0830c8ca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php @@ -26,6 +26,17 @@ public function testValidCollector() ->method('addMethodCall') ->with('addLoader', array('xlf', new Reference('xliff'))); + $translatorDefinition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + + $expectedResourceFiles = array( + 'fr' => array( + (__DIR__.'/../../Fixtures/Resources/translations/messages.fr.yml'), + ), + ); + $translatorDefinition->expects($this->at(1)) + ->method('replaceArgument') + ->with(4, $expectedResourceFiles); + $container = $this->getMock( 'Symfony\Component\DependencyInjection\ContainerBuilder', array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'findDefinition', 'hasParameter', 'getParameter') @@ -41,7 +52,7 @@ public function testValidCollector() ->will($this->returnValue(array('xliff' => array(array('alias' => 'xliff', 'legacy-alias' => 'xlf'))))); $container->expects($this->once()) ->method('findDefinition') - ->will($this->returnValue($this->getMock('Symfony\Component\DependencyInjection\Definition'))); + ->will($this->returnValue($translatorDefinition)); $container->expects($this->once()) ->method('hasParameter') ->with('translator.resource_directories') @@ -49,7 +60,7 @@ public function testValidCollector() $container->expects($this->once()) ->method('getParameter') ->with('translator.resource_directories') - ->will($this->returnValue(array())); + ->will($this->returnValue(array(__DIR__.'/../../Fixtures/Resources/translations'))); $pass = new TranslatorPass(); $pass->process($container); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index 1bcdee7716746..d9ce054ce8fcb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -105,9 +105,14 @@ public function testTransWithCachingWithInvalidLocale() 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), array(__DIR__.'/../Fixtures/Resources/translations'), 'yml'); + $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), $resourceFiles, 'yml'); $translator->setLocale('fr'); $this->assertEquals('répertoire', $translator->trans('folder')); @@ -122,7 +127,13 @@ public function testLoadRessourcesWithCaching() public function testLoadRessourcesWithoutCaching() { $loader = new \Symfony\Component\Translation\Loader\YamlFileLoader(); - $translator = $this->getTranslator($loader, array(), array(__DIR__.'/../Fixtures/Resources/translations'), 'yml'); + $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')); diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index 95d671334c0e8..12ecda38c51bb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -14,7 +14,6 @@ use Symfony\Component\Translation\Translator as BaseTranslator; use Symfony\Component\Translation\MessageSelector; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Finder\Finder; /** * Translator. @@ -25,7 +24,7 @@ class Translator extends BaseTranslator { protected $container; protected $loaderIds; - protected $resourceDirs; + protected $resourceFiles; protected $options = array( 'cache_dir' => null, @@ -40,19 +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 array $resourceDirs An array of resource directories + * @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(), $resourceDirs = array()) + public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array(), $resourceFiles = array()) { $this->container = $container; $this->loaderIds = $loaderIds; - $this->resourceDirs = $resourceDirs; + $this->resourceFiles = $resourceFiles; // check option names if ($diff = array_diff(array_keys($options), array_keys($this->options))) { @@ -70,6 +69,7 @@ public function __construct(ContainerInterface $container, MessageSelector $sele protected function initializeCatalogue($locale) { $this->initialize(); + $this->loadResources($locale); parent::initializeCatalogue($locale); } @@ -80,21 +80,17 @@ protected function initialize() $this->addLoader($alias, $this->container->get($id)); } } + } - if ($this->resourceDirs) { - $finder = Finder::create() - ->files() - ->filter(function (\SplFileInfo $file) { - return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename()); - }) - ->in($this->resourceDirs) - ; - - foreach ($finder as $file) { + private function loadResources($locale) + { + if (isset($this->resourceFiles[$locale])) { + foreach ($this->resourceFiles[$locale] as $file) { // filename is domain.locale.format - list($domain, $locale, $format) = explode('.', $file->getBasename(), 3); - $this->addResource($format, (string) $file, $locale, $domain); + list($domain, $locale, $format) = explode('.', basename($file), 3); + $this->addResource($format, $file, $locale, $domain); } + unset($this->resourceFiles[$locale]); } } } From 9a1d6d9876d0a2c673fec549e22bc53c99a6ea8e Mon Sep 17 00:00:00 2001 From: Abdellatif Ait boudad Date: Wed, 11 Mar 2015 10:19:40 +0000 Subject: [PATCH 4/4] [translation][loading resources] added Fallback Locales. --- .../Compiler/TranslatorPass.php | 28 +------------------ .../FrameworkExtension.php | 21 +++++++++++++- .../Compiler/TranslatorPassTest.php | 24 ++-------------- .../FrameworkExtensionTest.php | 22 ++++++++------- .../Translation/Translator.php | 15 ++++++---- 5 files changed, 44 insertions(+), 66 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php index 88806d05f491a..4e450166afa44 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php @@ -14,7 +14,6 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\Finder\Finder; class TranslatorPass implements CompilerPassInterface { @@ -41,31 +40,6 @@ public function process(ContainerBuilder $container) } } - $translatorDefinition = $container->findDefinition('translator.default'); - $translatorDefinition->replaceArgument(2, $loaders); - if ($container->hasParameter('translator.resource_directories')) { - $resourceDirs = $container->getParameter('translator.resource_directories'); - $files = array(); - if ($resourceDirs) { - $finder = Finder::create() - ->files() - ->filter(function (\SplFileInfo $file) { - return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename()); - }) - ->in($resourceDirs) - ; - - foreach ($finder as $file) { - list($domain, $locale, $format) = explode('.', $file->getBasename(), 3); - if (!isset($files[$locale])) { - $files[$locale] = array(); - } - - $files[$locale][] = (string) $file; - } - } - - $translatorDefinition->replaceArgument(4, $files); - } + $container->findDefinition('translator.default')->replaceArgument(2, $loaders); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index d7aa1702acf17..20ec2e2dbf41e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -683,11 +683,30 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder } // Register translation resources - $container->setParameter('translator.resource_directories', $dirs); if ($dirs) { foreach ($dirs as $dir) { $container->addResource(new DirectoryResource($dir)); } + + $files = array(); + $finder = Finder::create() + ->files() + ->filter(function (\SplFileInfo $file) { + return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename()); + }) + ->in($dirs) + ; + + foreach ($finder as $file) { + list($domain, $locale, $format) = explode('.', $file->getBasename(), 3); + if (!isset($files[$locale])) { + $files[$locale] = array(); + } + + $files[$locale][] = (string) $file; + } + + $translator->replaceArgument(4, $files); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php index 7e8ca0830c8ca..83f70514d5456 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php @@ -26,20 +26,9 @@ public function testValidCollector() ->method('addMethodCall') ->with('addLoader', array('xlf', new Reference('xliff'))); - $translatorDefinition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); - - $expectedResourceFiles = array( - 'fr' => array( - (__DIR__.'/../../Fixtures/Resources/translations/messages.fr.yml'), - ), - ); - $translatorDefinition->expects($this->at(1)) - ->method('replaceArgument') - ->with(4, $expectedResourceFiles); - $container = $this->getMock( 'Symfony\Component\DependencyInjection\ContainerBuilder', - array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'findDefinition', 'hasParameter', 'getParameter') + array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'findDefinition') ); $container->expects($this->any()) ->method('hasDefinition') @@ -52,16 +41,7 @@ public function testValidCollector() ->will($this->returnValue(array('xliff' => array(array('alias' => 'xliff', 'legacy-alias' => 'xlf'))))); $container->expects($this->once()) ->method('findDefinition') - ->will($this->returnValue($translatorDefinition)); - $container->expects($this->once()) - ->method('hasParameter') - ->with('translator.resource_directories') - ->will($this->returnValue(true)); - $container->expects($this->once()) - ->method('getParameter') - ->with('translator.resource_directories') - ->will($this->returnValue(array(__DIR__.'/../../Fixtures/Resources/translations'))); - + ->will($this->returnValue($this->getMock('Symfony\Component\DependencyInjection\Definition'))); $pass = new TranslatorPass(); $pass->process($container); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 586d8464559fc..d771ce7e3b357 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -218,26 +218,28 @@ public function testAssets() 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); - $dirs = $container->getParameter('translator.resource_directories'); - + $files = array_map(function ($resource) { return realpath($resource); }, $resources['en']); $ref = new \ReflectionClass('Symfony\Component\Validator\Validation'); $this->assertContains( - dirname($ref->getFileName()).'/Resources/translations', - $dirs + strtr(dirname($ref->getFileName()).'/Resources/translations/validators.en.xlf', '/', DIRECTORY_SEPARATOR), + $files, + '->registerTranslatorConfiguration() finds Validator translation resources' ); $ref = new \ReflectionClass('Symfony\Component\Form\Form'); $this->assertContains( - dirname($ref->getFileName()).'/Resources/translations', - $dirs + strtr(dirname($ref->getFileName()).'/Resources/translations/validators.en.xlf', '/', DIRECTORY_SEPARATOR), + $files, + '->registerTranslatorConfiguration() finds Form translation resources' ); - $ref = new \ReflectionClass('Symfony\Component\Security\Core\Exception\AuthenticationException'); + $ref = new \ReflectionClass('Symfony\Component\Security\Core\Security'); $this->assertContains( - dirname($ref->getFileName()).'/../Resources/translations', - $dirs + strtr(dirname($ref->getFileName()).'/Resources/translations/security.en.xlf', '/', DIRECTORY_SEPARATOR), + $files, + '->registerTranslatorConfiguration() finds Security translation resources' ); $calls = $container->getDefinition('translator.default')->getMethodCalls(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index 12ecda38c51bb..8e9843931d500 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -84,13 +84,16 @@ protected function initialize() private function loadResources($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); + $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]); } - unset($this->resourceFiles[$locale]); } } }