minor #14281 [2.7][Translation] avoid freshness check based on content *inside* the cache (mpdude, aitboudad)
This PR was merged into the 2.7 branch. Discussion ---------- [2.7][Translation] avoid freshness check based on content *inside* the cache | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Fixed tickets | ~ | Tests pass? | yes | License | MIT it's mainly based on #14268 Commits -------f9939d8
[Translation] avoid freshness check based on content *inside* the cache.f666657
[Translator] Cache does not take fallback locales into consideration
This commit is contained in:
commit
b5da2ae876
|
@ -255,12 +255,17 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
||||||
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
|
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
$catalogueHash = sha1(serialize(array(
|
||||||
|
'resources' => array(),
|
||||||
|
'fallback_locales' => array(),
|
||||||
|
)));
|
||||||
|
|
||||||
// prime the cache
|
// prime the cache
|
||||||
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles), 'yml');
|
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles), 'yml');
|
||||||
$this->assertFalse(file_exists($this->tmpDir.'/catalogue.fr.php'));
|
|
||||||
|
$this->assertFalse(file_exists($this->tmpDir.'/catalogue.fr.'.$catalogueHash.'.php'));
|
||||||
$translator->warmup($this->tmpDir);
|
$translator->warmup($this->tmpDir);
|
||||||
$this->assertTrue(file_exists($this->tmpDir.'/catalogue.fr.php'));
|
$this->assertTrue(file_exists($this->tmpDir.'/catalogue.fr.'.$catalogueHash.'.php'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
namespace Symfony\Component\Translation\Tests;
|
namespace Symfony\Component\Translation\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Translation\Loader\ArrayLoader;
|
||||||
use Symfony\Component\Translation\Translator;
|
use Symfony\Component\Translation\Translator;
|
||||||
use Symfony\Component\Translation\MessageCatalogue;
|
use Symfony\Component\Translation\MessageCatalogue;
|
||||||
use Symfony\Component\Translation\MessageSelector;
|
use Symfony\Component\Translation\MessageSelector;
|
||||||
|
@ -164,6 +165,37 @@ class TranslatorCacheTest extends \PHPUnit_Framework_TestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDifferentCacheFilesAreUsedForDifferentSetsOfFallbackLocales()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Because the cache file contains a catalogue including all of its fallback
|
||||||
|
* catalogues (either "inlined" in Symfony 2.7 production or "standalone"),
|
||||||
|
* we must take the active set of fallback locales into consideration when
|
||||||
|
* loading a catalogue from the cache.
|
||||||
|
*/
|
||||||
|
$translator = new Translator('a', null, $this->tmpDir);
|
||||||
|
$translator->setFallbackLocales(array('b'));
|
||||||
|
|
||||||
|
$translator->addLoader('array', new ArrayLoader());
|
||||||
|
$translator->addResource('array', array('foo' => 'foo (a)'), 'a');
|
||||||
|
$translator->addResource('array', array('bar' => 'bar (b)'), 'b');
|
||||||
|
|
||||||
|
$this->assertEquals('bar (b)', $translator->trans('bar'));
|
||||||
|
|
||||||
|
// Remove fallback locale
|
||||||
|
$translator->setFallbackLocales(array());
|
||||||
|
$this->assertEquals('bar', $translator->trans('bar'));
|
||||||
|
|
||||||
|
// Use a fresh translator with no fallback locales, result should be the same
|
||||||
|
$translator = new Translator('a', null, $this->tmpDir);
|
||||||
|
|
||||||
|
$translator->addLoader('array', new ArrayLoader());
|
||||||
|
$translator->addResource('array', array('foo' => 'foo (a)'), 'a');
|
||||||
|
$translator->addResource('array', array('bar' => 'bar (b)'), 'b');
|
||||||
|
|
||||||
|
$this->assertEquals('bar', $translator->trans('bar'));
|
||||||
|
}
|
||||||
|
|
||||||
protected function getCatalogue($locale, $messages)
|
protected function getCatalogue($locale, $messages)
|
||||||
{
|
{
|
||||||
$catalogue = new MessageCatalogue($locale);
|
$catalogue = new MessageCatalogue($locale);
|
||||||
|
|
|
@ -372,9 +372,8 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertValidLocale($locale);
|
$this->assertValidLocale($locale);
|
||||||
$cacheFile = $this->cacheDir.'/catalogue.'.$locale.'.php';
|
|
||||||
$self = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
|
$self = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
|
||||||
$cache = $this->getConfigCacheFactory()->cache($cacheFile,
|
$cache = $this->getConfigCacheFactory()->cache($this->getCatalogueCachePath($locale),
|
||||||
function (ConfigCacheInterface $cache) use ($self, $locale) {
|
function (ConfigCacheInterface $cache) use ($self, $locale) {
|
||||||
$self->dumpCatalogue($locale, $cache);
|
$self->dumpCatalogue($locale, $cache);
|
||||||
}
|
}
|
||||||
|
@ -386,40 +385,12 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read catalogue from cache. */
|
/* Read catalogue from cache. */
|
||||||
$catalogue = include $cache->getPath();
|
$this->catalogues[$locale] = include $cache->getPath();
|
||||||
|
|
||||||
/*
|
|
||||||
* Gracefully handle the case when the cached catalogue is in an "old" format, without a resourcesHash
|
|
||||||
*/
|
|
||||||
$resourcesHash = null;
|
|
||||||
if (is_array($catalogue)) {
|
|
||||||
list($catalogue, $resourcesHash) = $catalogue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->debug && $resourcesHash !== $this->getResourcesHash($locale)) {
|
|
||||||
/*
|
|
||||||
* This approach of resource checking has the disadvantage that a second
|
|
||||||
* type of freshness check happens based on content *inside* the cache, while
|
|
||||||
* the idea of ConfigCache is to make this check transparent to the client (and keeps
|
|
||||||
* the resources in a .meta file).
|
|
||||||
*
|
|
||||||
* Thus, we might run into the unfortunate situation that we just thought (a few lines above)
|
|
||||||
* that the cache is fresh -- and now that we look into it, we figure it's not.
|
|
||||||
*
|
|
||||||
* For now, just unlink the cache and try again. See
|
|
||||||
* https://github.com/symfony/symfony/pull/11862#issuecomment-54634631 and/or
|
|
||||||
* https://github.com/symfony/symfony/issues/7176 for possible better approaches.
|
|
||||||
*/
|
|
||||||
unlink($cacheFile);
|
|
||||||
$this->initializeCacheCatalogue($locale);
|
|
||||||
} else {
|
|
||||||
/* Initialize with catalogue from cache. */
|
|
||||||
$this->catalogues[$locale] = $catalogue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is public because it needs to be callable from a closure in PHP 5.3. It should be made protected (or even private, if possible) in 3.0.
|
* This method is public because it needs to be callable from a closure in PHP 5.3. It should be made protected (or even private, if possible) in 3.0.
|
||||||
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public function dumpCatalogue($locale, ConfigCacheInterface $cache)
|
public function dumpCatalogue($locale, ConfigCacheInterface $cache)
|
||||||
|
@ -432,15 +403,13 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
|
||||||
|
|
||||||
use Symfony\Component\Translation\MessageCatalogue;
|
use Symfony\Component\Translation\MessageCatalogue;
|
||||||
|
|
||||||
\$resourcesHash = '%s';
|
|
||||||
\$catalogue = new MessageCatalogue('%s', %s);
|
\$catalogue = new MessageCatalogue('%s', %s);
|
||||||
|
|
||||||
%s
|
%s
|
||||||
return array(\$catalogue, \$resourcesHash);
|
return \$catalogue;
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
,
|
,
|
||||||
$this->getResourcesHash($locale),
|
|
||||||
$locale,
|
$locale,
|
||||||
var_export($this->catalogues[$locale]->all(), true),
|
var_export($this->catalogues[$locale]->all(), true),
|
||||||
$fallbackContent
|
$fallbackContent
|
||||||
|
@ -494,13 +463,14 @@ EOF
|
||||||
return $fallbackContent;
|
return $fallbackContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getResourcesHash($locale)
|
private function getCatalogueCachePath($locale)
|
||||||
{
|
{
|
||||||
if (!isset($this->resources[$locale])) {
|
$catalogueHash = sha1(serialize(array(
|
||||||
return '';
|
'resources' => isset($this->resources[$locale]) ? $this->resources[$locale] : array(),
|
||||||
}
|
'fallback_locales' => $this->fallbackLocales,
|
||||||
|
)));
|
||||||
|
|
||||||
return sha1(serialize($this->resources[$locale]));
|
return $this->cacheDir.'/catalogue.'.$locale.'.'.$catalogueHash.'.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
private function doLoadCatalogue($locale)
|
private function doLoadCatalogue($locale)
|
||||||
|
|
Reference in New Issue