Skip to content

Commit e20e348

Browse files
committed
[Translation] added message cache.
1 parent 3f0fd7c commit e20e348

File tree

7 files changed

+328
-77
lines changed

7 files changed

+328
-77
lines changed

src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ public function __construct(ContainerInterface $container, MessageSelector $sele
6363
parent::__construct(null, $selector, $this->options['cache_dir'], $this->options['debug']);
6464
}
6565

66+
/*
67+
* @param string $locale
68+
*/
69+
protected function loadCatalogue($locale)
70+
{
71+
if ($this->options['debug']) {
72+
$this->loadResources($locale);
73+
}
74+
75+
parent::loadCatalogue($locale);
76+
}
77+
6678
/**
6779
* {@inheritdoc}
6880
*/

src/Symfony/Component/Translation/Dumper/FileDumper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ abstract protected function getExtension();
111111
*
112112
* @return string The relative file path
113113
*/
114-
private function getRelativePath($domain, $locale)
114+
public function getRelativePath($domain, $locale)
115115
{
116116
return strtr($this->relativePathTemplate, array(
117117
'%domain%' => $domain,
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Dumper;
13+
14+
use Symfony\Component\Config\ConfigCache;
15+
use Symfony\Component\Translation\MessageCatalogue;
16+
17+
/**
18+
* @author Abdellatif Ait Boudad <a.aitboudad@gmail.com>
19+
*/
20+
class PhpFileCacheDumper extends PhpFileDumper
21+
{
22+
/**
23+
* debug mode.
24+
*
25+
* @var bool
26+
*/
27+
private $debug = true;
28+
29+
/**
30+
* @param bool $debug
31+
*/
32+
public function __construct($debug = false)
33+
{
34+
$this->debug = $debug;
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function dump(MessageCatalogue $messages, $options = array())
41+
{
42+
if (!array_key_exists('path', $options)) {
43+
throw new \InvalidArgumentException('The file dumper needs a path option.');
44+
}
45+
46+
// save file
47+
$cache = new ConfigCache($options['path'].'/'.$this->getRelativePath('catalogue', $messages->getLocale()), $this->debug);
48+
$fallbackContent = $this->getFallbackContent($messages);
49+
50+
$content = sprintf(<<<EOF
51+
<?php
52+
53+
use Symfony\Component\Translation\MessageCatalogue;
54+
55+
\$resourcesHash = '%s';
56+
\$catalogue = new MessageCatalogue('%s', %s);
57+
58+
%s
59+
return array(\$catalogue, \$resourcesHash);
60+
61+
EOF
62+
,
63+
$options['resources_hash'],
64+
$messages->getLocale(),
65+
var_export($messages->all(), true),
66+
$fallbackContent
67+
);
68+
69+
$cache->write($content, $messages->getResources());
70+
}
71+
72+
private function getFallbackContent(MessageCatalogue $catalogue)
73+
{
74+
if (!$this->debug) {
75+
// merge all fallback catalogues messages into $catalogue
76+
$fallbackCatalogue = $catalogue->getFallbackCatalogue();
77+
78+
$messages = $catalogue->all();
79+
while ($fallbackCatalogue) {
80+
$messages = array_replace_recursive($fallbackCatalogue->all(), $messages);
81+
$fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
82+
}
83+
84+
foreach ($messages as $domain => $domainMessages) {
85+
$catalogue->add($domainMessages, $domain);
86+
}
87+
88+
return;
89+
}
90+
91+
$current = '';
92+
$fallbackContent = '';
93+
$replacementPattern = '/[^a-z0-9_]/i';
94+
95+
$fallbackCatalogue = $catalogue->getFallbackCatalogue();
96+
while ($fallbackCatalogue) {
97+
$fallback = $fallbackCatalogue->getLocale();
98+
$fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback));
99+
$currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current));
100+
101+
$fallbackContent .= sprintf(<<<EOF
102+
\$catalogue%s = new MessageCatalogue('%s', %s);
103+
\$catalogue%s->addFallbackCatalogue(\$catalogue%s);
104+
105+
106+
EOF
107+
,
108+
$fallbackSuffix,
109+
$fallback,
110+
var_export($fallbackCatalogue->all(), true),
111+
$currentSuffix,
112+
$fallbackSuffix
113+
);
114+
$current = $fallbackCatalogue->getLocale();
115+
$fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
116+
}
117+
118+
return $fallbackContent;
119+
}
120+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Loader;
13+
14+
use Symfony\Component\Config\ConfigCache;
15+
use Symfony\Component\Config\Resource\FileResource;
16+
use Symfony\Component\Translation\Exception\NotFoundResourceException;
17+
18+
/**
19+
* @author Abdellatif Ait Boudad <a.aitboudad@gmail.com>
20+
*/
21+
class PhpFileCacheLoader extends PhpFileLoader implements LoaderInterface
22+
{
23+
/**
24+
* @var bool
25+
*/
26+
private $debug;
27+
28+
/**
29+
* @param bool $debug
30+
*/
31+
public function __construct($debug = false)
32+
{
33+
$this->debug = $debug;
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*
39+
* @api
40+
*/
41+
public function load($resource, $locale, $domain = 'messages')
42+
{
43+
if (!stream_is_local($resource)) {
44+
throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
45+
}
46+
47+
if (!file_exists($resource)) {
48+
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
49+
}
50+
51+
list($catalogue, $resourcesHash) = include $resource;
52+
$catalogue->addResource(new FileResource($resource));
53+
54+
return $catalogue;
55+
}
56+
57+
public function isFresh($resource, $options)
58+
{
59+
$cache = new ConfigCache($resource, $this->debug);
60+
$isFresh = $cache->isFresh();
61+
if ($isFresh && $this->debug) {
62+
list($catalogue, $resourcesHash) = include $resource;
63+
if ($resourcesHash !== $options['resources_hash']) {
64+
return false;
65+
}
66+
}
67+
68+
return $isFresh;
69+
}
70+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation;
13+
14+
use Symfony\Component\Translation\Dumper\FileDumper;
15+
use Symfony\Component\Translation\Dumper\PhpFileCacheDumper;
16+
use Symfony\Component\Translation\Loader\LoaderInterface;
17+
use Symfony\Component\Translation\Loader\PhpFileCacheLoader;
18+
19+
/**
20+
* @author Abdellatif Ait Boudad <a.aitboudad@gmail.com>
21+
*/
22+
class MessageCache implements MessageCacheInterface
23+
{
24+
private $cacheDir;
25+
private $dumper;
26+
private $loader;
27+
private $debug;
28+
29+
/**
30+
* @param string $cacheDir The directory to use for the cache
31+
* @param FileDumper $dumper
32+
* @param LoaderInterface $loader
33+
* @param [type] $debug Use cache in debug mode ?
34+
*/
35+
public function __construct($cacheDir, $debug = false, FileDumper $dumper = null, LoaderInterface $loader = null)
36+
{
37+
$this->cacheDir = $cacheDir;
38+
$this->dumper = $dumper ?: new PhpFileCacheDumper($debug);
39+
$this->loader = $loader ?: new PhpFileCacheLoader($debug);
40+
$this->debug = $debug;
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function load($resource, $locale, $domain = null)
47+
{
48+
if (null === $resource) {
49+
$resource = $this->getResourcePath($locale);
50+
}
51+
52+
return $this->loader->load($resource, $locale, $domain);
53+
}
54+
55+
/**
56+
* {@inheritdoc}
57+
*/
58+
public function dump(MessageCatalogue $messages, $options = array())
59+
{
60+
$options = array_merge(array('path' => $this->cacheDir), $options);
61+
$this->dumper->dump($messages, $options);
62+
}
63+
64+
/**
65+
* {@inheritdoc}
66+
*/
67+
public function isFresh($locale, $options = array())
68+
{
69+
return $this->loader->isFresh($this->getResourcePath($locale), $options);
70+
}
71+
72+
private function getResourcePath($locale)
73+
{
74+
return $this->cacheDir.'/'.$this->dumper->getRelativePath('catalogue', $locale);
75+
}
76+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation;
13+
14+
use Symfony\Component\Translation\Loader\LoaderInterface;
15+
use Symfony\Component\Translation\Dumper\DumperInterface;
16+
17+
/**
18+
* @author Abdellatif Ait Boudad <a.aitboudad@gmail.com>
19+
*/
20+
interface MessageCacheInterface extends LoaderInterface, DumperInterface
21+
{
22+
/**
23+
* @param string $ressource
24+
* @param array $options
25+
*
26+
* @return bool
27+
*/
28+
public function isFresh($ressource, $options = array());
29+
}

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