Skip to content

Commit

Permalink
bug #34129 [FrameworkBundle][Translation] Invalidate cached catalogue…
Browse files Browse the repository at this point in the history
…s when the scanned directories change (fancyweb)

This PR was merged into the 4.3 branch.

Discussion
----------

[FrameworkBundle][Translation] Invalidate cached catalogues when the scanned directories change

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #33992
| License       | MIT
| Doc PR        | -

The cache file name needs to depend on the scanned directories list. Otherwise, when a new directory is added, even if the container is rebuilt and the `FWB Translator` gets the new scanned directories list, the cached catalogue name is still the same and is resolved accordingly.

An alternative would be to make the `Translation Translator` `getCatalogueCachePath()` method and `fallbackLocales` `@internal` and `protected` to just override everything in the `FWB Translator`. The `cacheVary` argument has the benefit to be reusable by all the `Translation` component users.

Note that there is a negative minor performance impact that increases when the list of scanned directories grows.

Commits
-------

6cbee09 [FrameworkBundle][Translation] Invalidate cached catalogues when the scanned directories change
  • Loading branch information
fabpot committed Nov 6, 2019
2 parents e91488c + 6cbee09 commit 4056baf
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 6 deletions.
@@ -0,0 +1 @@
foo: bar
Expand Up @@ -18,6 +18,7 @@
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Translation\Formatter\MessageFormatter;
use Symfony\Component\Translation\Loader\YamlFileLoader;
use Symfony\Component\Translation\MessageCatalogue;

class TranslatorTest extends TestCase
Expand Down Expand Up @@ -244,6 +245,41 @@ public function testCatalogResourcesAreAddedForScannedDirectories()
$this->assertEquals(new FileExistenceResource('/tmp/I/sure/hope/this/does/not/exist'), $resources[2]);
}

public function testCachedCatalogueIsReDumpedWhenScannedDirectoriesChange()
{
/** @var Translator $translator */
$translator = $this->getTranslator(new YamlFileLoader(), [
'cache_dir' => $this->tmpDir,
'resource_files' => [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
],
],
'scanned_directories' => [
__DIR__.'/../Fixtures/Resources/translations/',
],
], 'yml');

// Cached catalogue is dumped
$this->assertSame('répertoire', $translator->trans('folder', [], 'messages', 'fr'));

$translator = $this->getTranslator(new YamlFileLoader(), [
'cache_dir' => $this->tmpDir,
'resource_files' => [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
__DIR__.'/../Fixtures/Resources/translations2/ccc.fr.yml',
],
],
'scanned_directories' => [
__DIR__.'/../Fixtures/Resources/translations/',
__DIR__.'/../Fixtures/Resources/translations2/',
],
], 'yml');

$this->assertSame('bar', $translator->trans('foo', [], 'ccc', 'fr'));
}

protected function getCatalogue($locale, $messages, $resources = [])
{
$catalogue = new MessageCatalogue($locale);
Expand Down
Expand Up @@ -82,7 +82,9 @@ public function __construct(ContainerInterface $container, MessageFormatterInter
$this->resourceFiles = $this->options['resource_files'];
$this->scannedDirectories = $this->options['scanned_directories'];

parent::__construct($defaultLocale, $formatter, $this->options['cache_dir'], $this->options['debug']);
parent::__construct($defaultLocale, $formatter, $this->options['cache_dir'], $this->options['debug'], [
'scanned_directories' => $this->scannedDirectories,
]);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/composer.json
Expand Up @@ -49,7 +49,7 @@
"symfony/security-http": "~3.4|~4.0",
"symfony/serializer": "^4.3",
"symfony/stopwatch": "~3.4|~4.0",
"symfony/translation": "~4.3",
"symfony/translation": "^4.3.6",
"symfony/templating": "~3.4|~4.0",
"symfony/twig-bundle": "~2.8|~3.2|~4.0",
"symfony/validator": "^4.1",
Expand Down Expand Up @@ -77,7 +77,7 @@
"symfony/property-info": "<3.4",
"symfony/serializer": "<4.2",
"symfony/stopwatch": "<3.4",
"symfony/translation": "<4.3",
"symfony/translation": "<4.3.6",
"symfony/twig-bridge": "<4.1.1",
"symfony/validator": "<4.1",
"symfony/workflow": "<4.3.6"
Expand Down
16 changes: 16 additions & 0 deletions src/Symfony/Component/Translation/Tests/TranslatorCacheTest.php
Expand Up @@ -269,6 +269,22 @@ public function testRefreshCacheWhenResourcesAreNoLongerFresh()
$translator->trans('foo');
}

public function testCachedCatalogueIsReDumpedWhenCacheVaryChange()
{
$translator = new Translator('a', null, $this->tmpDir, false, []);
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', ['foo' => 'bar'], 'a', 'messages');

// Cached catalogue is dumped
$this->assertSame('bar', $translator->trans('foo', [], 'messages', 'a'));

$translator = new Translator('a', null, $this->tmpDir, false, ['vary']);
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', ['foo' => 'ccc'], 'a', 'messages');

$this->assertSame('ccc', $translator->trans('foo', [], 'messages', 'a'));
}

protected function getCatalogue($locale, $messages, $resources = [])
{
$catalogue = new MessageCatalogue($locale);
Expand Down
9 changes: 6 additions & 3 deletions src/Symfony/Component/Translation/Translator.php
Expand Up @@ -71,6 +71,8 @@ class Translator implements LegacyTranslatorInterface, TranslatorInterface, Tran
*/
private $debug;

private $cacheVary;

/**
* @var ConfigCacheFactoryInterface|null
*/
Expand All @@ -86,7 +88,7 @@ class Translator implements LegacyTranslatorInterface, TranslatorInterface, Tran
/**
* @throws InvalidArgumentException If a locale contains invalid characters
*/
public function __construct(?string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false)
public function __construct(?string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [])
{
$this->setLocale($locale);

Expand All @@ -97,6 +99,7 @@ public function __construct(?string $locale, MessageFormatterInterface $formatte
$this->formatter = $formatter;
$this->cacheDir = $cacheDir;
$this->debug = $debug;
$this->cacheVary = $cacheVary;
$this->hasIntlFormatter = $formatter instanceof IntlFormatterInterface;
}

Expand Down Expand Up @@ -176,7 +179,7 @@ public function setFallbackLocales(array $locales)
$this->assertValidLocale($locale);
}

$this->fallbackLocales = $locales;
$this->fallbackLocales = $this->cacheVary['fallback_locales'] = $locales;
}

/**
Expand Down Expand Up @@ -392,7 +395,7 @@ private function getFallbackContent(MessageCatalogue $catalogue): string

private function getCatalogueCachePath($locale)
{
return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->fallbackLocales), true)), 0, 7), '/', '_').'.php';
return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->cacheVary), true)), 0, 7), '/', '_').'.php';
}

/**
Expand Down

0 comments on commit 4056baf

Please sign in to comment.