diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index 361bcf001b560..75f4281952227 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -135,6 +135,51 @@ public function testGetDefaultLocale() $this->assertSame('en', $translator->getLocale()); } + /** @dataProvider getDebugModeAndCacheDirCombinations */ + public function testResourceFilesOptionLoadsBeforeOtherAddedResources($debug, $enableCache) + { + $someCatalogue = $this->getCatalogue('some_locale', array()); + + $loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock(); + + $loader->expects($this->at(0)) + ->method('load') + /* The "messages.some_locale.loader" is passed via the resource_file option and shall be loaded first */ + ->with('messages.some_locale.loader', 'some_locale', 'messages') + ->willReturn($someCatalogue); + + $loader->expects($this->at(1)) + ->method('load') + /* This resource is added by an addResource() call and shall be loaded after the resource_files */ + ->with('second_resource.some_locale.loader', 'some_locale', 'messages') + ->willReturn($someCatalogue); + + $options = array( + 'resource_files' => array('some_locale' => array('messages.some_locale.loader')), + 'debug' => $debug, + ); + + if ($enableCache) { + $options['cache_dir'] = $this->tmpDir; + } + + /** @var Translator $translator */ + $translator = $this->createTranslator($loader, $options); + $translator->addResource('loader', 'second_resource.some_locale.loader', 'some_locale', 'messages'); + + $translator->trans('some_message', array(), null, 'some_locale'); + } + + public function getDebugModeAndCacheDirCombinations() + { + return array( + array(false, false), + array(true, false), + array(false, true), + array(true, true), + ); + } + protected function getCatalogue($locale, $messages, $resources = array()) { $catalogue = new MessageCatalogue($locale); diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index fba6d70d6978b..9fdfb645d372a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -37,6 +37,14 @@ class Translator extends BaseTranslator implements WarmableInterface */ private $resourceLocales; + /** + * Holds parameters from addResource() calls so we can defer the actual + * parent::addResource() calls until initialize() is executed. + * + * @var array + */ + private $resources = array(); + /** * Constructor. * @@ -65,9 +73,7 @@ public function __construct(ContainerInterface $container, MessageSelector $sele $this->options = array_merge($this->options, $options); $this->resourceLocales = array_keys($this->options['resource_files']); - if (null !== $this->options['cache_dir'] && $this->options['debug']) { - $this->loadResources(); - } + $this->addResourceFiles($this->options['resource_files']); parent::__construct($container->getParameter('kernel.default_locale'), $selector, $this->options['cache_dir'], $this->options['debug']); } @@ -93,6 +99,11 @@ public function warmUp($cacheDir) } } + public function addResource($format, $resource, $locale, $domain = null) + { + $this->resources[] = array($format, $resource, $locale, $domain); + } + /** * {@inheritdoc} */ @@ -104,7 +115,12 @@ protected function initializeCatalogue($locale) protected function initialize() { - $this->loadResources(); + foreach ($this->resources as $key => $params) { + list($format, $resource, $locale, $domain) = $params; + parent::addResource($format, $resource, $locale, $domain); + } + $this->resources = array(); + foreach ($this->loaderIds as $id => $aliases) { foreach ($aliases as $alias) { $this->addLoader($alias, $this->container->get($id)); @@ -112,14 +128,13 @@ protected function initialize() } } - private function loadResources() + private function addResourceFiles($filesByLocale) { - foreach ($this->options['resource_files'] as $locale => $files) { + foreach ($filesByLocale as $locale => $files) { foreach ($files as $key => $file) { // filename is domain.locale.format list($domain, $locale, $format) = explode('.', basename($file), 3); $this->addResource($format, $file, $locale, $domain); - unset($this->options['resource_files'][$locale][$key]); } } }