Skip to content

Commit 2860af4

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

File tree

3 files changed

+107
-4
lines changed

3 files changed

+107
-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;

src/Symfony/Bridge/Doctrine/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"symfony/expression-language": "~2.2|~3.0.0",
3131
"symfony/validator": "~2.5,>=2.5.5|~3.0.0",
3232
"symfony/translation": "~2.7|~3.0.0",
33+
"symfony/config": "~2.3,>=2.3.12|~3.0.0",
3334
"doctrine/data-fixtures": "1.0.*",
3435
"doctrine/dbal": "~2.2",
3536
"doctrine/orm": "~2.2,>=2.2.3",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy