[Config] Delegate creation of ConfigCache instances to a factory.
This commit is contained in:
parent
aa82fb065d
commit
6fbe9b1064
@ -16,6 +16,12 @@ Router
|
|||||||
but in 2.7 you would get an error if `bar` parameter
|
but in 2.7 you would get an error if `bar` parameter
|
||||||
doesn't exist or unexpected result otherwise.
|
doesn't exist or unexpected result otherwise.
|
||||||
|
|
||||||
|
* The `getMatcherDumperInstance()` and `getGeneratorDumperInstance()` methods in the
|
||||||
|
`Symfony\Component\Routing\Router` have been changed from `protected` to `public`.
|
||||||
|
If you override these methods in a subclass, you will need to change your
|
||||||
|
methods to `public` as well. Note however that this is a temporary change needed for
|
||||||
|
PHP 5.3 compatibility only. It will be reverted in Symfony 3.0.
|
||||||
|
|
||||||
Form
|
Form
|
||||||
----
|
----
|
||||||
|
|
||||||
@ -515,3 +521,10 @@ PropertyAccess
|
|||||||
|
|
||||||
new UnexpectedTypeException($value, $path, $pathIndex);
|
new UnexpectedTypeException($value, $path, $pathIndex);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Config
|
||||||
|
------
|
||||||
|
|
||||||
|
* The `__toString()` method of the `\Symfony\Component\Config\ConfigCache` is marked as
|
||||||
|
deprecated in favor of the new `getPath()` method.
|
||||||
|
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
2.7.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* added `ConfigCacheInterface`, `ConfigCacheFactoryInterface` and a basic `ConfigCacheFactory`
|
||||||
|
implementation to delegate creation of ConfigCache instances
|
||||||
|
|
||||||
2.2.0
|
2.2.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -23,14 +23,12 @@ use Symfony\Component\Filesystem\Filesystem;
|
|||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
*/
|
*/
|
||||||
class ConfigCache
|
class ConfigCache implements ConfigCacheInterface
|
||||||
{
|
{
|
||||||
private $debug;
|
private $debug;
|
||||||
private $file;
|
private $file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param string $file The absolute cache path
|
* @param string $file The absolute cache path
|
||||||
* @param bool $debug Whether debugging is enabled or not
|
* @param bool $debug Whether debugging is enabled or not
|
||||||
*/
|
*/
|
||||||
@ -44,8 +42,21 @@ class ConfigCache
|
|||||||
* Gets the cache file path.
|
* Gets the cache file path.
|
||||||
*
|
*
|
||||||
* @return string The cache file path
|
* @return string The cache file path
|
||||||
|
* @deprecated since 2.7, to be removed in 3.0. Use getPath() instead.
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
|
{
|
||||||
|
trigger_error('ConfigCache::__toString() is deprecated since version 2.7 and will be removed in 3.0. Use the getPath() method instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
return $this->file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the cache file path.
|
||||||
|
*
|
||||||
|
* @return string The cache file path
|
||||||
|
*/
|
||||||
|
public function getPath()
|
||||||
{
|
{
|
||||||
return $this->file;
|
return $this->file;
|
||||||
}
|
}
|
||||||
|
48
src/Symfony/Component/Config/ConfigCacheFactory.php
Normal file
48
src/Symfony/Component/Config/ConfigCacheFactory.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic implementation for ConfigCacheFactoryInterface
|
||||||
|
* that will simply create an instance of ConfigCache.
|
||||||
|
*
|
||||||
|
* @author Matthias Pigulla <mp@webfactory.de>
|
||||||
|
*/
|
||||||
|
class ConfigCacheFactory implements ConfigCacheFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var bool Debug flag passed to the ConfigCache
|
||||||
|
*/
|
||||||
|
private $debug;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $debug The debug flag to pass to ConfigCache
|
||||||
|
*/
|
||||||
|
public function __construct($debug)
|
||||||
|
{
|
||||||
|
$this->debug = $debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function cache($file, $callback)
|
||||||
|
{
|
||||||
|
$cache = new ConfigCache($file, $this->debug);
|
||||||
|
|
||||||
|
if (!$cache->isFresh()) {
|
||||||
|
call_user_func($callback, $cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cache;
|
||||||
|
}
|
||||||
|
}
|
32
src/Symfony/Component/Config/ConfigCacheFactoryInterface.php
Normal file
32
src/Symfony/Component/Config/ConfigCacheFactoryInterface.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for a ConfigCache factory. This factory creates
|
||||||
|
* an instance of ConfigCacheInterface and initializes the
|
||||||
|
* cache if necessary.
|
||||||
|
*
|
||||||
|
* @author Matthias Pigulla <mp@webfactory.de>
|
||||||
|
*/
|
||||||
|
interface ConfigCacheFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a cache instance and (re-)initializes it if necessary.
|
||||||
|
*
|
||||||
|
* @param string $file The absolute cache file path
|
||||||
|
* @param callable $callable The callable to be executed when the cache needs to be filled (i. e. is not fresh). The cache will be passed as the only parameter to this callback
|
||||||
|
*
|
||||||
|
* @return ConfigCacheInterface $configCache The cache instance
|
||||||
|
*/
|
||||||
|
public function cache($file, $callable);
|
||||||
|
}
|
49
src/Symfony/Component/Config/ConfigCacheInterface.php
Normal file
49
src/Symfony/Component/Config/ConfigCacheInterface.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Config;
|
||||||
|
|
||||||
|
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for ConfigCache
|
||||||
|
*
|
||||||
|
* @author Matthias Pigulla <mp@webfactory.de>
|
||||||
|
*/
|
||||||
|
interface ConfigCacheInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Gets the cache file path.
|
||||||
|
*
|
||||||
|
* @return string The cache file path
|
||||||
|
*/
|
||||||
|
public function getPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the cache is still fresh.
|
||||||
|
*
|
||||||
|
* This check should take the metadata passed to the write() method into consideration.
|
||||||
|
*
|
||||||
|
* @return bool Whether the cache is still fresh.
|
||||||
|
*/
|
||||||
|
public function isFresh();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the given content into the cache file. Metadata will be stored
|
||||||
|
* independently and can be used to check cache freshness at a later time.
|
||||||
|
*
|
||||||
|
* @param string $content The content to write into the cache
|
||||||
|
* @param ResourceInterface[]|null $metadata An array of ResourceInterface instances
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the cache file cannot be written
|
||||||
|
*/
|
||||||
|
public function write($content, array $metadata = null);
|
||||||
|
}
|
@ -47,7 +47,7 @@ class ConfigCacheTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$cache = new ConfigCache($this->cacheFile, true);
|
$cache = new ConfigCache($this->cacheFile, true);
|
||||||
|
|
||||||
$this->assertSame($this->cacheFile, (string) $cache);
|
$this->assertSame($this->cacheFile, $cache->getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCacheIsNotFreshIfFileDoesNotExist()
|
public function testCacheIsNotFreshIfFileDoesNotExist()
|
||||||
|
@ -252,7 +252,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle
|
* @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle
|
||||||
*/
|
*/
|
||||||
@ -546,7 +546,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
|||||||
$fresh = false;
|
$fresh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once $cache;
|
require_once $cache->getPath();
|
||||||
|
|
||||||
$this->container = new $class();
|
$this->container = new $class();
|
||||||
$this->container->set('kernel', $this);
|
$this->container->set('kernel', $this);
|
||||||
@ -695,7 +695,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
|||||||
$dumper->setProxyDumper(new ProxyDumper());
|
$dumper->setProxyDumper(new ProxyDumper());
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass, 'file' => (string) $cache));
|
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass, 'file' => $cache->getPath()));
|
||||||
if (!$this->debug) {
|
if (!$this->debug) {
|
||||||
$content = static::stripComments($content);
|
$content = static::stripComments($content);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
"symfony/phpunit-bridge": "~2.7|~3.0.0",
|
"symfony/phpunit-bridge": "~2.7|~3.0.0",
|
||||||
"symfony/browser-kit": "~2.3|~3.0.0",
|
"symfony/browser-kit": "~2.3|~3.0.0",
|
||||||
"symfony/class-loader": "~2.1|~3.0.0",
|
"symfony/class-loader": "~2.1|~3.0.0",
|
||||||
"symfony/config": "~2.0,>=2.0.5|~3.0.0",
|
"symfony/config": "~2.7",
|
||||||
"symfony/console": "~2.3|~3.0.0",
|
"symfony/console": "~2.3|~3.0.0",
|
||||||
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
|
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
|
||||||
"symfony/dependency-injection": "~2.2|~3.0.0",
|
"symfony/dependency-injection": "~2.2|~3.0.0",
|
||||||
@ -40,6 +40,9 @@
|
|||||||
"symfony/translation": "~2.0,>=2.0.5|~3.0.0",
|
"symfony/translation": "~2.0,>=2.0.5|~3.0.0",
|
||||||
"symfony/var-dumper": "~2.6|~3.0.0"
|
"symfony/var-dumper": "~2.6|~3.0.0"
|
||||||
},
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/config": "<2.7"
|
||||||
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/browser-kit": "",
|
"symfony/browser-kit": "",
|
||||||
"symfony/class-loader": "",
|
"symfony/class-loader": "",
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
namespace Symfony\Component\Routing;
|
namespace Symfony\Component\Routing;
|
||||||
|
|
||||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||||
use Symfony\Component\Config\ConfigCache;
|
use Symfony\Component\Config\ConfigCacheInterface;
|
||||||
|
use Symfony\Component\Config\ConfigCacheFactoryInterface;
|
||||||
|
use Symfony\Component\Config\ConfigCacheFactory;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
|
use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
@ -71,6 +73,11 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
*/
|
*/
|
||||||
protected $logger;
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ConfigCacheFactoryInterface|null
|
||||||
|
*/
|
||||||
|
private $configCacheFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ExpressionFunctionProviderInterface[]
|
* @var ExpressionFunctionProviderInterface[]
|
||||||
*/
|
*/
|
||||||
@ -209,6 +216,16 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
return $this->context;
|
return $this->context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the ConfigCache factory to use.
|
||||||
|
*
|
||||||
|
* @param ConfigCacheFactoryInterface $configCacheFactory The factory to use.
|
||||||
|
*/
|
||||||
|
public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
|
||||||
|
{
|
||||||
|
$this->configCacheFactory = $configCacheFactory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -262,24 +279,29 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$class = $this->options['matcher_cache_class'];
|
$class = $this->options['matcher_cache_class'];
|
||||||
$cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
|
$baseClass = $this->options['matcher_base_class'];
|
||||||
if (!$cache->isFresh()) {
|
$expressionLanguageProviders = $this->expressionLanguageProviders;
|
||||||
$dumper = $this->getMatcherDumperInstance();
|
$that = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
|
||||||
|
|
||||||
|
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php',
|
||||||
|
function (ConfigCacheInterface $cache) use ($that, $class, $baseClass, $expressionLanguageProviders) {
|
||||||
|
$dumper = $that->getMatcherDumperInstance();
|
||||||
if (method_exists($dumper, 'addExpressionLanguageProvider')) {
|
if (method_exists($dumper, 'addExpressionLanguageProvider')) {
|
||||||
foreach ($this->expressionLanguageProviders as $provider) {
|
foreach ($expressionLanguageProviders as $provider) {
|
||||||
$dumper->addExpressionLanguageProvider($provider);
|
$dumper->addExpressionLanguageProvider($provider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$options = array(
|
$options = array(
|
||||||
'class' => $class,
|
'class' => $class,
|
||||||
'base_class' => $this->options['matcher_base_class'],
|
'base_class' => $baseClass,
|
||||||
);
|
);
|
||||||
|
|
||||||
$cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
|
$cache->write($dumper->dump($options), $that->getRouteCollection()->getResources());
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
require_once $cache;
|
require_once $cache->getPath();
|
||||||
|
|
||||||
return $this->matcher = new $class($this->context);
|
return $this->matcher = new $class($this->context);
|
||||||
}
|
}
|
||||||
@ -299,19 +321,22 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
$this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
|
$this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
|
||||||
} else {
|
} else {
|
||||||
$class = $this->options['generator_cache_class'];
|
$class = $this->options['generator_cache_class'];
|
||||||
$cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
|
$baseClass = $this->options['generator_base_class'];
|
||||||
if (!$cache->isFresh()) {
|
$that = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
|
||||||
$dumper = $this->getGeneratorDumperInstance();
|
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php',
|
||||||
|
function (ConfigCacheInterface $cache) use ($that, $class, $baseClass) {
|
||||||
|
$dumper = $that->getGeneratorDumperInstance();
|
||||||
|
|
||||||
$options = array(
|
$options = array(
|
||||||
'class' => $class,
|
'class' => $class,
|
||||||
'base_class' => $this->options['generator_base_class'],
|
'base_class' => $baseClass,
|
||||||
);
|
);
|
||||||
|
|
||||||
$cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
|
$cache->write($dumper->dump($options), $that->getRouteCollection()->getResources());
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
require_once $cache;
|
require_once $cache->getPath();
|
||||||
|
|
||||||
$this->generator = new $class($this->context, $this->logger);
|
$this->generator = new $class($this->context, $this->logger);
|
||||||
}
|
}
|
||||||
@ -329,18 +354,37 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This method is public because it needs to be callable from a closure in PHP 5.3. It should be converted back to protected in 3.0.
|
||||||
|
* @internal
|
||||||
* @return GeneratorDumperInterface
|
* @return GeneratorDumperInterface
|
||||||
*/
|
*/
|
||||||
protected function getGeneratorDumperInstance()
|
public function getGeneratorDumperInstance()
|
||||||
{
|
{
|
||||||
return new $this->options['generator_dumper_class']($this->getRouteCollection());
|
return new $this->options['generator_dumper_class']($this->getRouteCollection());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This method is public because it needs to be callable from a closure in PHP 5.3. It should be converted back to protected in 3.0.
|
||||||
|
* @internal
|
||||||
* @return MatcherDumperInterface
|
* @return MatcherDumperInterface
|
||||||
*/
|
*/
|
||||||
protected function getMatcherDumperInstance()
|
public function getMatcherDumperInstance()
|
||||||
{
|
{
|
||||||
return new $this->options['matcher_dumper_class']($this->getRouteCollection());
|
return new $this->options['matcher_dumper_class']($this->getRouteCollection());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the ConfigCache factory implementation, falling back to a
|
||||||
|
* default implementation if necessary.
|
||||||
|
*
|
||||||
|
* @return ConfigCacheFactoryInterface $configCacheFactory
|
||||||
|
*/
|
||||||
|
private function getConfigCacheFactory()
|
||||||
|
{
|
||||||
|
if (null === $this->configCacheFactory) {
|
||||||
|
$this->configCacheFactory = new ConfigCacheFactory($this->options['debug']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->configCacheFactory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/phpunit-bridge": "~2.7|~3.0.0",
|
"symfony/phpunit-bridge": "~2.7|~3.0.0",
|
||||||
"symfony/config": "~2.2|~3.0.0",
|
"symfony/config": "~2.7|~3.0.0",
|
||||||
"symfony/http-foundation": "~2.3|~3.0.0",
|
"symfony/http-foundation": "~2.3|~3.0.0",
|
||||||
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0",
|
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0",
|
||||||
"symfony/expression-language": "~2.4|~3.0.0",
|
"symfony/expression-language": "~2.4|~3.0.0",
|
||||||
@ -28,6 +28,9 @@
|
|||||||
"doctrine/common": "~2.2",
|
"doctrine/common": "~2.2",
|
||||||
"psr/log": "~1.0"
|
"psr/log": "~1.0"
|
||||||
},
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/config": "<2.7"
|
||||||
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/config": "For using the all-in-one router or any loader",
|
"symfony/config": "For using the all-in-one router or any loader",
|
||||||
"symfony/yaml": "For using the YAML loader",
|
"symfony/yaml": "For using the YAML loader",
|
||||||
|
@ -13,7 +13,9 @@ namespace Symfony\Component\Translation;
|
|||||||
|
|
||||||
use Symfony\Component\Translation\Loader\LoaderInterface;
|
use Symfony\Component\Translation\Loader\LoaderInterface;
|
||||||
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
||||||
use Symfony\Component\Config\ConfigCache;
|
use Symfony\Component\Config\ConfigCacheInterface;
|
||||||
|
use Symfony\Component\Config\ConfigCacheFactoryInterface;
|
||||||
|
use Symfony\Component\Config\ConfigCacheFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translator.
|
* Translator.
|
||||||
@ -64,6 +66,11 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
|
|||||||
*/
|
*/
|
||||||
private $debug;
|
private $debug;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ConfigCacheFactoryInterface|null
|
||||||
|
*/
|
||||||
|
private $configCacheFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@ -84,6 +91,16 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
|
|||||||
$this->debug = $debug;
|
$this->debug = $debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the ConfigCache factory to use.
|
||||||
|
*
|
||||||
|
* @param ConfigCacheFactoryInterface $configCacheFactory
|
||||||
|
*/
|
||||||
|
public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
|
||||||
|
{
|
||||||
|
$this->configCacheFactory = $configCacheFactory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a Loader.
|
* Adds a Loader.
|
||||||
*
|
*
|
||||||
@ -315,7 +332,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
|
|||||||
return $messages;
|
return $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* @param string $locale
|
* @param string $locale
|
||||||
*/
|
*/
|
||||||
protected function loadCatalogue($locale)
|
protected function loadCatalogue($locale)
|
||||||
@ -346,17 +363,67 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $locale
|
* @param string $locale
|
||||||
* @param bool $forceRefresh
|
|
||||||
*/
|
*/
|
||||||
private function initializeCacheCatalogue($locale, $forceRefresh = false)
|
private function initializeCacheCatalogue($locale)
|
||||||
{
|
{
|
||||||
if (isset($this->catalogues[$locale])) {
|
if (isset($this->catalogues[$locale])) {
|
||||||
|
/* Catalogue already initialized. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertValidLocale($locale);
|
$this->assertValidLocale($locale);
|
||||||
$cache = new ConfigCache($this->cacheDir.'/catalogue.'.$locale.'.php', $this->debug);
|
$cacheFile = $this->cacheDir.'/catalogue.'.$locale.'.php';
|
||||||
if ($forceRefresh || !$cache->isFresh()) {
|
$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,
|
||||||
|
function (ConfigCacheInterface $cache) use ($self, $locale) {
|
||||||
|
$self->dumpCatalogue($locale, $cache);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($this->catalogues[$locale])) {
|
||||||
|
/* Catalogue has been initialized as it was written out to cache. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read catalogue from cache. */
|
||||||
|
$catalogue = 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.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function dumpCatalogue($locale, ConfigCacheInterface $cache)
|
||||||
|
{
|
||||||
$this->initializeCatalogue($locale);
|
$this->initializeCatalogue($locale);
|
||||||
$fallbackContent = $this->getFallbackContent($this->catalogues[$locale]);
|
$fallbackContent = $this->getFallbackContent($this->catalogues[$locale]);
|
||||||
|
|
||||||
@ -380,25 +447,6 @@ EOF
|
|||||||
);
|
);
|
||||||
|
|
||||||
$cache->write($content, $this->catalogues[$locale]->getResources());
|
$cache->write($content, $this->catalogues[$locale]->getResources());
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$catalogue = include $cache;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Old cache returns only the catalogue, without resourcesHash
|
|
||||||
*/
|
|
||||||
$resourcesHash = null;
|
|
||||||
if (is_array($catalogue)) {
|
|
||||||
list($catalogue, $resourcesHash) = $catalogue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->debug && $resourcesHash !== $this->getResourcesHash($locale)) {
|
|
||||||
return $this->initializeCacheCatalogue($locale, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->catalogues[$locale] = $catalogue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFallbackContent(MessageCatalogue $catalogue)
|
private function getFallbackContent(MessageCatalogue $catalogue)
|
||||||
@ -514,4 +562,19 @@ EOF
|
|||||||
throw new \InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
|
throw new \InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the ConfigCache factory implementation, falling back to a
|
||||||
|
* default implementation if necessary.
|
||||||
|
*
|
||||||
|
* @return ConfigCacheFactoryInterface $configCacheFactory
|
||||||
|
*/
|
||||||
|
private function getConfigCacheFactory()
|
||||||
|
{
|
||||||
|
if (!$this->configCacheFactory) {
|
||||||
|
$this->configCacheFactory = new ConfigCacheFactory($this->debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->configCacheFactory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,14 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/phpunit-bridge": "~2.7|~3.0.0",
|
"symfony/phpunit-bridge": "~2.7|~3.0.0",
|
||||||
"symfony/config": "~2.3,>=2.3.12|~3.0.0",
|
"symfony/config": "~2.7",
|
||||||
"symfony/intl": "~2.3|~3.0.0",
|
"symfony/intl": "~2.3|~3.0.0",
|
||||||
"symfony/yaml": "~2.2|~3.0.0",
|
"symfony/yaml": "~2.2|~3.0.0",
|
||||||
"psr/log": "~1.0"
|
"psr/log": "~1.0"
|
||||||
},
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/config": "<2.7"
|
||||||
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/config": "",
|
"symfony/config": "",
|
||||||
"symfony/yaml": "",
|
"symfony/yaml": "",
|
||||||
|
Reference in New Issue
Block a user