8000 [Translation][Cache][Doctrine] refresh cache when resources file change. · symfony/symfony@69225b8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 69225b8

Browse files
committed
[Translation][Cache][Doctrine] refresh cache when resources file change.
1 parent af78b62 commit 69225b8

File tree

2 files changed

+106
-4
lines changed

2 files changed

+106
-4
lines changed

src/Symfony/Bridge/Doctrine/Tests/Translation/TranslatorDoctrineCacheTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,45 @@
1616
use Symfony\Component\Translation\MessageSelector;
1717
use Symfony\Bridge\Doctrine\Translation\DoctrineMessageCache;
1818
use Doctrine\Common\Cache\ArrayCache;
19+
use Symfony\Component\Translation\Loader\PhpFileLoader;
20+
use Symfony\Component\Translation\Dumper\PhpFileDumper;
1921

2022
class TranslatorDoctrineCacheTest extends \PHPUnit_Framework_TestCase
2123
{
24+
protected $tmpDir;
25+
2226
protected function setUp()
2327
{
2428
if (!interface_exists('Doctrine\Common\Cache\Cache')) {
2529
$this->markTestSkipped('The "Doctrine Cache" is not available');
2630
}
31+
32+
$this->tmpDir = sys_get_temp_dir().'/sf2_translation';
33+
$this->deleteTmpDir();
34+
}
35+
protected function tearDown()
36+
{
37+
$this->deleteTmpDir();
38+
}
39+
40+
protected function deleteTmpDir()
41+
{
42+
if (!file_exists($dir = $this->tmpDir)) {
43+
return;
44+
}
45+
46+
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->tmpDir), \RecursiveIteratorIterator::CHILD_FIRST);
47+
foreach ($iterator as $path) {
48+
if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
49+
continue;
50+
}
51+
if ($path->isDir()) {
52+
rmdir($path->__toString());
53+
} else {
54+
unlink($path->__toString());
55+
}
56+
}
57+
rmdir($this->tmpDir);
2758
}
2859

2960
public function testTrans()
@@ -98,6 +129,34 @@ public function testRefreshCacheWhenResourcesChange()
98129
$this->assertEquals('foo B', $translator->trans('foo'));
99130
}
100131

132+
public function testRefreshCacheWhenResourcesFileChange()
133+
{
134+
$resourceFile = $this->tmpDir.'/messages.fr.php';
135+
$loader = new PhpFileLoader();
136+
$dumper = new PhpFileDumper();
137+
138+
// prime the cache
139+
$cache = new DoctrineMessageCache(new ArrayCache(), true);
140+
$dumper->dump(new MessageCatalogue('fr', array('messages' => array('foo' => 'foo A'))), array('path' => $this->tmpDir));
141+
142+
$translator = new Translator('fr', new MessageSelector(), $cache);
143+
$translator->addLoader('loader', $loader);
144+
$translator->addResource('loader', $resourceFile, 'fr');
145+
146+
$this->assertEquals('foo A', $translator->trans('foo'));
147+
148+
// add a new resource to refresh the cache
149+
$dumper->dump(new MessageCatalogue('fr', array('messages' => array('foo' => 'foo B'))), array('path' => $this->tmpDir));
150+
touch($resourceFile, time() + 3600);
151+
clearstatcache(true, $resourceFile);
152+
153+
$translator = new Translator('fr', new MessageSelector(), $cache);
154+
$translator->addLoader('loader', $loader);
155+
$translator->addResource('loader', $resourceFile, 'fr');
156+
157+
$this->assertEquals('foo B', $translator->trans('foo'));
158+
}
159+
101160
protected function getLoader()
102161
{
103162
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');

src/Symfony/Bridge/Doctrine/Translation/DoctrineMessageCache.php

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
class DoctrineMessageCache implements MessageCacheInterface
2222
{
2323
const CACHE_RESOURCE_HASH = 'resources_hash';
24+
const CACHE_DUMP_TIME = 'time';
25+
const CACHE_META_DATA = 'meta';
2426
const CATALOGUE_FALLBACK_LOCALE = 'fallback_locale';
2527

2628
/**
@@ -39,21 +41,26 @@ class DoctrineMessageCache implements MessageCacheInterface
3941
*/
4042
public function __construct(Cache $cache, $debug = false)
4143
{
42-
$this->debug = $debug;
4344
$this->cache = $cache;
45+
$this->debug = $debug;
4446
}
4547

4648
/**
4749
* {@inheritdoc}
4850
*/
4951
public function isFresh($locale, array $options = array())
5052
{
51-
$currentResourcesHash = isset($options['resources_hash']) ? $options['resources_hash'] : '';
5253
$resourcesHash = $this->cache->fetch($this->getResourceHashKey($locale));
53-
if (false === $resourcesHash || ($this->debug && $resourcesHash !== $currentResourcesHash)) {
54+
if (false === $resourcesHash) {
5455
return false;
5556
}
5657

58+
if ($this->debug) {
59+
$currentResourcesHash = isset($options['resources_hash']) ? $options['resources_hash'] : '';
60+
61+
return $this->isMetaDataFresh($locale, $currentResourcesHash);
62+
}
63+
5764
return true;
5865
}
5966

@@ -83,7 +90,8 @@ public function dump(MessageCatalogueInterface $messages, array $options = array
8390
$catalogue = new DoctrineMessageCatalogue($messages->getLocale(), $this->cache);
8491
$catalogue->addCatalogue($messages);
8592

86-
$this->cache->save($this->getResourceHashKey($messages->getLocale()), $resourcesHash);
93+
$this->dumpMetaDataCatalogue($messages->getLocale(), $messages->getResources(), $resourcesHash);
94+
8795
if ($fallback = $messages->getFallbackCatalogue()) {
8896
$this->cache->save($this->getFallbackLocaleKey($messages->getLocale()), $fallback->getLocale());
8997
}
@@ -92,6 +100,41 @@ public function dump(MessageCatalogueInterface $messages, array $options = array
92100
}
93101
}
94102

103+
private function isMetaDataFresh($locale, $currentResourcesHash)
104+
{
105+
$resourcesHash = $this->cache->fetch($this->getResourceHashKey($locale));
106+
if ($resourcesHash !== $currentResourcesHash) {
107+
return false;
108+
}
109+
110+
$time = $this->cache->fetch($this->getDumpTimeKey($locale));
111+
$meta = unserialize($this->cache->fetch($this->getMetaDataKey($locale)));
112+
foreach ($meta as $resource) {
113+
if (!$resource->isFresh($time)) {
114+
return false;
115+
}
116+
}
117+
118+
return true;
119+
}
120+
121+
private function dumpMetaDataCatalogue($locale, $metadata, $resourcesHash)
122+
{
123+
$this->cache->save($this->getMetaDataKey($locale), serialize($metadata));
124+
$this->cache->save($this->getResourceHashKey($locale), $resourcesHash);
125+
$this->cache->save($this->getDumpTimeKey($locale), time());
126+
}
127+
128+
private function getDumpTimeKey($locale)
129+
{
130+
return self::CACHE_DUMP_TIME.'_'.$locale;
131+
}
132+
133+
private function getMetaDataKey($locale)
134+
{
135+
return self::CACHE_META_DATA.'_'.$locale;
136+
}
137+
95138
private function getResourceHashKey($locale)
96139
{
97140
return self::CACHE_RESOURCE_HASH.'_'.$locale;

0 commit comments

Comments
 (0)
0