8000 Delegate creation of ConfigCache instances to a factory. · symfony/symfony@02159ae · GitHub
[go: up one dir, main page]

Skip to content

Commit 02159ae

Browse files
committed
Delegate creation of ConfigCache instances to a factory.
This cherry-picks the changes suggested in #7781 and ports them to the 2.7 branch (the original PR was against master, which was correct at the time it was opened).
1 parent aa82fb0 commit 02159ae

File tree

6 files changed

+307
-64
lines changed

6 files changed

+307
-64
lines changed

src/Symfony/Component/Config/ConfigCache.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
* @author Fabien Potencier <fabien@symfony.com>
2525
*/
26-
class ConfigCache
26+
class ConfigCache implements ConfigCacheInterface
2727
{
2828
private $debug;
2929
private $file;
@@ -44,12 +44,23 @@ public function __construct($file, $debug)
4444
* Gets the cache file path.
4545
*
4646
* @return string The cache file path
47+
* @deprecated since 2.7, to be removed in 3.0. Use getFilePath() instead.
4748
*/
4849
public function __toString()
4950
{
5051
return $this->file;
5152
}
5253

54+
/**
55+
* Gets the cache file path.
56+
*
57+
* @return string The cache file path
58+
*/
59+
public function getPath()
60+
{
61+
return $this->file;
62+
}
63+
5364
/**
5465
* Checks if the cache is still fresh.
5566
*
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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\Config;
13+
14+
/**
15+
* Interface for a ConfigCache factory. This factory creates
16+
* an instance of ConfigCacheInterface and initializes the
17+
* cache if necessary.
18+
*
19+
* @author Matthias Pigulla <mp@webfactory.de>
20+
*/
21+
interface ConfigCacheFactoryInterface
22+
{
23+
/**
24+
* Creates a cache instance and (re-)initializes it if necessary.
25+
*
26+
* @param string $file The absolute cache file path
27+
* @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.
28+
* @return ConfigCacheInterface $configCache The cache instance.
29+
*/
30+
public function cache($file, $callable);
31+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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\Config;
13+
14+
/**
15+
* Interface for ConfigCache
16+
*
17+
* @author Matthias Pigulla <mp@webfactory.de>
18+
*/
19+
interface ConfigCacheInterface
20+
{
21+
/**
22+
* Gets the cache file path.
23+
*
24+
* @deprecated since version 2.7, to be removed in 3.0.
25+
* @return string The cache file path
26+
*/
27+
public function __toString();
28+
29+
/**
30+
* Gets the cache file path.
31+
*
32+
* @return string The cache file path
33+
*/
34+
public function getPath();
35+
36+
/**
37+
* Checks if the cache is still fresh.
38+
*
39+
* @return Boolean true if the cache is fresh, false otherwise
40+
*/
41+
public function isFresh();
42+
43+
/**
44+
* Writes cache.
45+
*
46+
* @param string $content The content to write into the cache
47+
* @param ResourceInterface[] $metadata An array of ResourceInterface instances
48+
*
49+
* @throws \RuntimeException When the cache file cannot be written
50+
*/
51+
public function write($content, array $metadata = null);
52+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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\Config;
13+
14+
/**
15+
* Default implementation for ConfigCacheFactoryInterface
16+
* that will create an instance of ConfigCache.
17+
*
18+
* @author Matthias Pigulla <mp@webfactory.de>
19+
*/
20+
class DefaultConfigCacheFactory implements ConfigCacheFactoryInterface
21+
{
22+
/** @var bool Debug flag passed to the ConfigCache */
23+
private $debug;
24+
25+
/**
26+
* Constructor.
27+
*
28+
* @param bool $debug The debug flag to pass to ConfigCache.
29+
*/
30+
public function __construct($debug)
31+
{
32+
$this->debug = $debug;
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function cache($file, $callback)
39+
{
40+
$cache = new ConfigCache($file, $this->debug);
41+
42+
if (!$cache->isFresh()) {
43+
call_user_func($callback, $cache);
44+
}
45+
46+
return $cache;
47+
}
48+
}

src/Symfony/Component/Routing/Router.php

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
namespace Symfony\Component\Routing;
1313

1414
use Symfony\Component\Config\Loader\LoaderInterface;
15-
use Symfony\Component\Config\ConfigCache;
15+
use Symfony\Component\Config\ConfigCacheInterface;
16+
use Symfony\Component\Config\ConfigCacheFactoryInterface;
17+
use Symfony\Component\Config\DefaultConfigCacheFactory;
1618
use Psr\Log\LoggerInterface;
1719
use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
1820
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
@@ -71,6 +73,11 @@ class Router implements RouterInterface, RequestMatcherInterface
7173
*/
7274
protected $logger;
7375

76+
/**
77+
* @var ConfigCacheFactoryInterface|null
78+
*/
79+
private $configCacheFactory;
80+
7481
/**
7582
* @var ExpressionFunctionProviderInterface[]
7683
*/
@@ -209,6 +216,16 @@ public function getContext()
209216
return $this->context;
210217
}
211218

219+
/**
220+
* Sets the ConfigCache factory to use.
221+
*
222+
* @param ConfigCacheFactoryInterface $configCacheFactory The factory to use.
223+
*/
224+
public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
225+
{
226+
$this->configCacheFactory = $configCacheFactory;
227+
}
228+
212229
/**
213230
* {@inheritdoc}
214231
*/
@@ -262,24 +279,29 @@ public function getMatcher()
262279
}
263280

264281
$class = $this->options['matcher_cache_class'];
265-
$cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
266-
if (!$cache->isFresh()) {
267-
$dumper = $this->getMatcherDumperInstance();
268-
if (method_exists($dumper, 'addExpressionLanguageProvider')) {
269-
foreach ($this->expressionLanguageProviders as $provider) {
270-
$dumper->addExpressionLanguageProvider($provider);
282+
$baseClass = $this->options['matcher_base_class'];
283+
$expressionLanguageProviders = $this->expressionLanguageProviders;
284+
$self = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
285+
286+
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php',
287+
function (ConfigCacheInterface $cache) use ($self, $class, $baseClass, $expressionLanguageProviders) {
288+
$dumper = $self->getMatcherDumperInstance();
289+
if (method_exists($dumper, 'addExpressionLanguageProvider')) {
290+
foreach ($expressionLanguageProviders as $provider) {
291+
$dumper->addExpressionLanguageProvider($provider);
292+
}
271293
}
272-
}
273294

274-
$options = array(
275-
'class' => $class,
276-
'base_class' => $this->options['matcher_base_class'],
277-
);
295+
$options = array(
296+
'class' => $class,
297+
'base_class' => $baseClass,
298+
);
278299

279-
$cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
280-
}
300+
$cache->write($dumper->dump($options), $self->getRouteCollection()->getResources());
301+
}
302+
);
281303

282-
require_once $cache;
304+
require_once $cache->getPath();
283305

284306
return $this->matcher = new $class($this->context);
285307
}
@@ -299,19 +321,22 @@ public function getGenerator()
299321
$this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
300322
} else {
301323
$class = $this->options['generator_cache_class'];
302-
$cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
303-
if (!$cache->isFresh()) {
304-
$dumper = $this->getGeneratorDumperInstance();
305-
306-
$options = array(
307-
'class' => $class,
308-
'base_class' => $this->options['generator_base_class'],
309-
);
310-
311-
$cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
312-
}
324+
$baseClass = $this->options['generator_base_class'];
325+
$self = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
326+
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php',
327+
function (ConfigCacheInterface $cache) use ($self, $class, $baseClass) {
328+
$dumper = $self->getGeneratorDumperInstance();
329+
330+
$options = array(
331+
'class' => $class,
332+
'base_class' => $baseClass,
333+
);
334+
335+
$cache->write($dumper->dump($options), $self->getRouteCollection()->getResources());
336+
}
337+
);
313338

314-
require_once $cache;
339+
require_once $cache->getPath();
315340

316341
$this->generator = new $class($this->context, $this->logger);
317342
}
@@ -329,18 +354,37 @@ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterfac
329354
}
330355

331356
/**
357+
* 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.
358+
* @internal
332359
* @return GeneratorDumperInterface
333360
*/
334-
protected function getGeneratorDumperInstance()
361+
public function getGeneratorDumperInstance()
335362
{
336363
return new $this->options['generator_dumper_class']($this->getRouteCollection());
337364
}
338365

339366
/**
367+
* 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.
368+
* @internal
340369
* @return MatcherDumperInterface
341370
*/
342-
protected function getMatcherDumperInstance()
371+
public function getMatcherDumperInstance()
343372
{
344373
return new $this->options['matcher_dumper_class']($this->getRouteCollection());
345374
}
375+
376+
/**
377+
* Provides the ConfigCache factory implementation, falling back to a
378+
* default implementation if necessary.
379+
*
380+
* @return ConfigCacheFactoryInterface $configCacheFactory
381+
*/
382+
private function getConfigCacheFactory()
383+
{
384+
if (null === $this->configCacheFactory) {
385+
$this->configCacheFactory = new DefaultConfigCacheFactory($this->options['debug']);
386+
}
387+
388+
return $this->configCacheFactory;
389+
}
346390
}

0 commit comments

Comments
 (0)
0