Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b01ed89

Browse files
committed
feature #14178 [Config] Delegate creation of ConfigCache instances to a factory. (mpdude)
This PR was squashed before being merged into the 2.7 branch (closes #14178). Discussion ---------- [Config] Delegate creation of ConfigCache instances to a factory. | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes (refactoring, new flex point) | BC breaks? | no | Deprecations? | yes | Tests pass? | we'll see :-) | Fixed tickets | n/a | License | MIT | Doc PR | symfony/symfony-docs#5136 In the Routing/Router and Translation/Translator, delegate creation of ConfigCache instances to a factory. The factory can be setter-injected but will default to a BC implementation. The ```ConfigCacheFactoryInterface``` is designed in a way that captures the common ```$cache = new ...; if (!$cache->isFresh()) { ... do sth }``` pattern. But more importantly, this design allows factory implementations to take additional measures to avoid race conditions before actually filling the cache. By using an exchangeable ConfigCache factory it becomes possible to implement different resource (freshness) checking strategies, especially service-based ones. The goal is to be able to validate Translators and Routers generated by database-based loaders. It might also help with symfony/AsseticBundle#168. This PR only contains the minimum changes needed, so the rest could be implemented in a bundle outside the core (at least for the beginning). Component/HttpKernel/Kernel::initializeContainer still uses the ConfigCache implementation directly as there is no sensible way of getting/injecting a factory service (chicken-egg). This is a pick off #7230. It replaces #7781 which was against the master branch. Also see #7781 for additional comments/explanations. ## Todo * [ ] Allow `symfony/config` `~3.0.0` in `composer.json` for the HttpKernel and Translator component as well as TwigBundle once this PR has been merged into the master branch (fail deps=high tests for the time being). Commits ------- 6fbe9b1 [Config] Delegate creation of ConfigCache instances to a factory.
2 parents 90a7fa0 + 6fbe9b1 commit b01ed89

File tree

13 files changed

+347
-72
lines changed

13 files changed

+347
-72
lines changed

UPGRADE-2.7.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ Router
1616
but in 2.7 you would get an error if `bar` parameter
1717
doesn't exist or unexpected result otherwise.
1818

19+
* The `getMatcherDumperInstance()` and `getGeneratorDumperInstance()` methods in the
20+
`Symfony\Component\Routing\Router` have been changed from `protected` to `public`.
21+
If you override these methods in a subclass, you will need to change your
22+
methods to `public` as well. Note however that this is a temporary change needed for
23+
PHP 5.3 compatibility only. It will be reverted in Symfony 3.0.
24+
1925
Form
2026
----
2127

@@ -515,3 +521,10 @@ PropertyAccess
515521

516522
new UnexpectedTypeException($value, $path, $pathIndex);
517523
```
524+
525+
Config
526+
------
527+
528+
* The `__toString()` method of the `\Symfony\Component\Config\ConfigCache` is marked as
529+
deprecated in favor of the new `getPath()` method.
530+

src/Symfony/Component/Config/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
2.7.0
5+
-----
6+
7+
* added `ConfigCacheInterface`, `ConfigCacheFactoryInterface` and a basic `ConfigCacheFactory`
8+
implementation to delegate creation of ConfigCache instances
9+
410
2.2.0
511
-----
612

src/Symfony/Component/Config/ConfigCache.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@
2323
*
2424
* @author Fabien Potencier <[email protected]>
2525
*/
26-
class ConfigCache
26+
class ConfigCache implements ConfigCacheInterface
2727
{
2828
private $debug;
2929
private $file;
3030

3131
/**
32-
* Constructor.
33-
*
3432
* @param string $file The absolute cache path
3533
* @param bool $debug Whether debugging is enabled or not
3634
*/
@@ -44,8 +42,21 @@ public function __construct($file, $debug)
4442
* Gets the cache file path.
4543
*
4644
* @return string The cache file path
45+
* @deprecated since 2.7, to be removed in 3.0. Use getPath() instead.
4746
*/
4847
public function __toString()
48+
{
49+
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);
50+
51+
return $this->file;
52+
}
53+
54+
/**
55+
* Gets the cache file path.
56+
*
57+
* @return string The cache file path
58+
*/
59+
public function getPath()
4960
{
5061
return $this->file;
5162
}
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 <[email protected]>
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+
* Basic implementation for ConfigCacheFactoryInterface
16+
* that will simply create an instance of ConfigCache.
17+
*
18+
* @author Matthias Pigulla <[email protected]>
19+
*/
20+
class ConfigCacheFactory implements ConfigCacheFactoryInterface
21+
{
22+
/**
23+
* @var bool Debug flag passed to the ConfigCache
24+
*/
25+
private $debug;
26+
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+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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 <[email protected]>
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+
*
29+
* @return ConfigCacheInterface $configCache The cache instance
30+
*/
31+
public function cache($file, $callable);
32+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
use Symfony\Component\Config\Resource\ResourceInterface;
15+
16+
/**
17+
* Interface for ConfigCache
18+
*
19+
* @author Matthias Pigulla <[email protected]>
20+
*/
21+
interface ConfigCacheInterface
22+
{
23+
/**
24+
* Gets the cache file path.
25+
*
26+
* @return string The cache file path
27+
*/
28+
public function getPath();
29+
30+
/**
31+
* Checks if the cache is still fresh.
32+
*
33+
* This check should take the metadata passed to the write() method into consideration.
34+
*
35+
* @return bool Whether the cache is still fresh.
36+
*/
37+
public function isFresh();
38+
39+
/**
40+
* Writes the given content into the cache file. Metadata will be stored
41+
* independently and can be used to check cache freshness at a later time.
42+
*
43+
* @param string $content The content to write into the cache
44+
* @param ResourceInterface[]|null $metadata An array of ResourceInterface instances
45+
*
46+
* @throws \RuntimeException When the cache file cannot be written
47+
*/
48+
public function write($content, array $metadata = null);
49+
}

src/Symfony/Component/Config/Tests/ConfigCacheTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function testToString()
4747
{
4848
$cache = new ConfigCache($this->cacheFile, true);
4949

50-
$this->assertSame($this->cacheFile, (string) $cache);
50+
$this->assertSame($this->cacheFile, $cache->getPath());
5151
}
5252

5353
public function testCacheIsNotFreshIfFileDoesNotExist()

src/Symfony/Component/HttpKernel/Kernel.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ public function getBundle($name, $first = true)
252252
}
253253

254254
/**
255-
* {@inheritDoc}
255+
* {@inheritdoc}
256256
*
257257
* @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle
258258
*/
@@ -546,7 +546,7 @@ protected function initializeContainer()
546546
$fresh = false;
547547
}
548548

549-
require_once $cache;
549+
require_once $cache->getPath();
550550

551551
$this->container = new $class();
552552
$this->container->set('kernel', $this);
@@ -695,7 +695,7 @@ protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container
695695
$dumper->setProxyDumper(new ProxyDumper());
696696
}
697697

698-
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass, 'file' => (string) $cache));
698+
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass, 'file' => $cache->getPath()));
699699
if (!$this->debug) {
700700
$content = static::stripComments($content);
701701
}

src/Symfony/Component/HttpKernel/composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"symfony/phpunit-bridge": "~2.7|~3.0.0",
2727
"symfony/browser-kit": "~2.3|~3.0.0",
2828
"symfony/class-loader": "~2.1|~3.0.0",
29-
"symfony/config": "~2.0,>=2.0.5|~3.0.0",
29+
"symfony/config": "~2.7",
3030
"symfony/console": "~2.3|~3.0.0",
3131
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
3232
"symfony/dependency-injection": "~2.2|~3.0.0",
@@ -40,6 +40,9 @@
4040
"symfony/translation": "~2.0,>=2.0.5|~3.0.0",
4141
"symfony/var-dumper": "~2.6|~3.0.0"
4242
},
43+
"conflict": {
44+
"symfony/config": "<2.7"
45+
},
4346
"suggest": {
4447
"symfony/browser-kit": "",
4548
"symfony/class-loader": "",

0 commit comments

Comments
 (0)