Skip to content

Commit

Permalink
bug #23057 [Translation][FrameworkBundle] Fix resource loading order …
Browse files Browse the repository at this point in the history
…inconsistency reported in #23034 (mpdude)

This PR was squashed before being merged into the 2.7 branch (closes #23057).

Discussion
----------

[Translation][FrameworkBundle] Fix resource loading order inconsistency reported in #23034

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #23034
| License       | MIT
| Doc PR        |

Fixes the bug reported in #23034:

When mixing `addResource()` calls and providing the `resource_files` option, the order in which resources are loaded depends on the `kernel.debug` setting and whether a cache is used.

In particular, when several loaders provide translations for the same message, the one that "wins" may change between development and production mode.

Commits
-------

2a9e65d [Translation][FrameworkBundle] Fix resource loading order inconsistency reported in #23034
  • Loading branch information
fabpot committed Jun 14, 2017
2 parents d44f143 + 2a9e65d commit baf988d
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
29 changes: 22 additions & 7 deletions src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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']);
}
Expand All @@ -93,6 +99,11 @@ public function warmUp($cacheDir)
}
}

public function addResource($format, $resource, $locale, $domain = null)
{
$this->resources[] = array($format, $resource, $locale, $domain);
}

/**
* {@inheritdoc}
*/
Expand All @@ -104,22 +115,26 @@ 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));
}
}
}

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]);
}
}
}
Expand Down

0 comments on commit baf988d

Please sign in to comment.