Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit daac4e8

Browse filesBrowse files
committed
[FrameworkBundle] Allow clearing private cache pools
1 parent 4033b60 commit daac4e8
Copy full SHA for daac4e8

File tree

13 files changed

+338
-50
lines changed
Filter options

13 files changed

+338
-50
lines changed

‎UPGRADE-3.3.md

Copy file name to clipboardExpand all lines: UPGRADE-3.3.md
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,21 @@ ClassLoader
66

77
* The ApcClassLoader, WinCacheClassLoader and XcacheClassLoader classes have been deprecated
88
in favor of the `--apcu-autoloader` option introduced in composer 1.3
9+
10+
Security
11+
--------
12+
13+
* The `RoleInterface` has been deprecated. Extend the `Symfony\Component\Security\Core\Role\Role`
14+
class in your custom role implementations instead.
15+
16+
SecurityBundle
17+
--------------
18+
19+
* The `FirewallContext::getContext()` method has been deprecated and will be removed in 4.0.
20+
Use the `getListeners()` method instead.
21+
22+
HttpKernel
23+
-----------
24+
25+
* The `Psr6CacheClearer::addPool()` method has been deprecated. Pass an array of pools indexed
26+
by name to the constructor instead.

‎UPGRADE-4.0.md

Copy file name to clipboardExpand all lines: UPGRADE-4.0.md
+54-36Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ FrameworkBundle
134134
`serializer.mapping.cache.apc` and `serializer.mapping.cache.doctrine.apc`
135135
have been removed. APCu should now be automatically used when available.
136136

137+
SecurityBundle
138+
--------------
139+
140+
* The `FirewallContext::getContext()` method has been removed, use the `getListeners()` method instead.
141+
137142
HttpFoundation
138143
---------------
139144

@@ -169,13 +174,26 @@ HttpKernel
169174
inject an `ArgumentResolverInterface` instance.
170175

171176
* The `DataCollector::varToString()` method has been removed in favor of `cloneVar()`.
177+
178+
* The `Psr6CacheClearer::addPool()` method has been removed. Pass an array of pools indexed
179+
by name to the constructor instead.
180+
181+
Security
182+
--------
183+
184+
* The `RoleInterface` has been removed. Extend the `Symfony\Component\Security\Core\Role\Role`
185+
class instead.
172186

173187
Serializer
174188
----------
175189

176190
* The ability to pass a Doctrine `Cache` instance to the `ClassMetadataFactory`
177191
class has been removed. You should use the `CacheClassMetadataFactory` class
178192
instead.
193+
194+
* Not defining the 6th argument `$format = null` of the
195+
`AbstractNormalizer::instantiateObject()` method when overriding it is not
196+
supported anymore.
179197

180198
Translation
181199
-----------
@@ -188,6 +206,42 @@ TwigBridge
188206
* The possibility to inject the Form Twig Renderer into the form extension
189207
has been removed. Inject it into the `TwigRendererEngine` instead.
190208

209+
Validator
210+
---------
211+
212+
* The `DateTimeValidator::PATTERN` constant was removed.
213+
214+
* `Tests\Constraints\AbstractConstraintValidatorTest` has been removed in
215+
favor of `Test\ConstraintValidatorTestCase`.
216+
217+
Before:
218+
219+
```php
220+
// ...
221+
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
222+
223+
class MyCustomValidatorTest extends AbstractConstraintValidatorTest
224+
{
225+
// ...
226+
}
227+
```
228+
229+
After:
230+
231+
```php
232+
// ...
233+
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
234+
235+
class MyCustomValidatorTest extends ConstraintValidatorTestCase
236+
{
237+
// ...
238+
}
239+
```
240+
241+
* The default value of the strict option of the `Choice` Constraint has been
242+
changed to `true` as of 4.0. If you need the the previous behaviour ensure to
243+
set the option to `false`.
244+
191245
Yaml
192246
----
193247

@@ -279,39 +333,3 @@ Yaml
279333
the `!php/object` tag.
280334

281335
* Duplicate mapping keys lead to a `ParseException`.
282-
283-
Validator
284-
---------
285-
286-
* The `DateTimeValidator::PATTERN` constant was removed.
287-
288-
* `Tests\Constraints\AbstractConstraintValidatorTest` has been removed in
289-
favor of `Test\ConstraintValidatorTestCase`.
290-
291-
Before:
292-
293-
```php
294-
// ...
295-
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
296-
297-
class MyCustomValidatorTest extends AbstractConstraintValidatorTest
298-
{
299-
// ...
300-
}
301-
```
302-
303-
After:
304-
305-
```php
306-
// ...
307-
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
308-
309-
class MyCustomValidatorTest extends ConstraintValidatorTestCase
310-
{
311-
// ...
312-
}
313-
```
314-
315-
* The default value of the strict option of the `Choice` Constraint has been
316-
changed to `true` as of 4.0. If you need the the previous behaviour ensure to
317-
set the option to `false`.

‎src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php
+18-8Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,21 @@ protected function execute(InputInterface $input, OutputInterface $output)
5555
$clearers = array();
5656
$container = $this->getContainer();
5757
$cacheDir = $container->getParameter('kernel.cache_dir');
58+
$globalClearer = $container->get('cache.global_clearer');
5859

5960
foreach ($input->getArgument('pools') as $id) {
60-
$pool = $container->get($id);
61-
62-
if ($pool instanceof CacheItemPoolInterface) {
63-
$pools[$id] = $pool;
64-
} elseif ($pool instanceof Psr6CacheClearer) {
65-
$clearers[$id] = $pool;
61+
if ($globalClearer->hasPool($id)) {
62+
$pools[$id] = $id;
6663
} else {
67-
throw new \InvalidArgumentException(sprintf('"%s" is not a cache pool nor a cache clearer.', $id));
64+
$pool = $container->get($id);
65+
66+
if ($pool instanceof CacheItemPoolInterface) {
67+
$pools[$id] = $pool;
68+
} elseif ($pool instanceof Psr6CacheClearer) {
69+
$clearers[$id] = $pool;
70+
} else {
71+
throw new \InvalidArgumentException(sprintf('"%s" is not a cache pool nor a cache clearer.', $id));
72+
}
6873
}
6974
}
7075

@@ -75,7 +80,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
7580

7681
foreach ($pools as $id => $pool) {
7782
$io->comment(sprintf('Clearing cache pool: <info>%s</info>', $id));
78-
$pool->clear();
83+
84+
if ($pool instanceof CacheItemPoolInterface) {
85+
$pool->clear();
86+
} else {
87+
$globalClearer->clearPool($id);
88+
}
7989
}
8090

8191
$io->success('Cache was successfully cleared.');

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php
+15-3Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,31 @@ final class CachePoolClearerPass implements CompilerPassInterface
2727
public function process(ContainerBuilder $container)
2828
{
2929
$container->getParameterBag()->remove('cache.prefix.seed');
30+
$poolsByClearer = array();
31+
$pools = array();
3032

3133
foreach ($container->findTaggedServiceIds('cache.pool') as $id => $attributes) {
34+
$pools[$id] = new Reference($id);
3235
foreach (array_reverse($attributes) as $attr) {
3336
if (isset($attr['clearer'])) {
34-
$clearer = $container->getDefinition($attr['clearer']);
35-
$clearer->addMethodCall('addPool', array(new Reference($id)));
37+
$poolsByClearer[$attr['clearer']][$id] = $pools[$id];
3638
}
37-
if (array_key_exists('clearer', $attr)) {
39+
if (!empty($attr['unlazy'])) {
40+
$container->getDefinition($id)->setLazy(false);
41+
}
42+
if (array_key_exists('clearer', $attr) || array_key_exists('unlazy', $attr)) {
3843
break;
3944
}
4045
}
4146
}
4247

48+
$container->getDefinition('cache.global_clearer')->addArgument($pools);
49+
50+
foreach ($poolsByClearer as $clearer => $pools) {
51+
$clearer = $container->getDefinition($clearer);
52+
$clearer->addArgument($pools);
53+
}
54+
4355
if (!$container->has('cache.annotations')) {
4456
return;
4557
}

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php
+11-1Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ public function process(ContainerBuilder $container)
4747
if ($pool->isAbstract()) {
4848
continue;
4949
}
50+
$isLazy = $pool->isLazy();
5051
while ($adapter instanceof DefinitionDecorator) {
5152
$adapter = $container->findDefinition($adapter->getParent());
53+
$isLazy = $isLazy || $adapter->isLazy();
5254
if ($t = $adapter->getTag('cache.pool')) {
5355
$tags[0] += $t[0];
5456
}
@@ -80,8 +82,16 @@ public function process(ContainerBuilder $container)
8082
throw new InvalidArgumentException(sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "namespace" and "default_lifetime", found "%s".', $id, implode('", "', array_keys($tags[0]))));
8183
}
8284

85+
$attr = array();
8386
if (null !== $clearer) {
84-
$pool->addTag('cache.pool', array('clearer' => $clearer));
87+
$attr['clearer'] = $clearer;
88+
}
89+
if (!$isLazy) {
90+
$pool->setLazy(true);
91+
$attr['unlazy'] = true;
92+
}
93+
if ($attr) {
94+
$pool->addTag('cache.pool', $attr);
8595
}
8696
}
8797
}

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
<tag name="kernel.cache_clearer" />
9898
</service>
9999

100+
<service id="cache.global_clearer" parent="cache.default_clearer" />
100101
<service id="cache.app_clearer" alias="cache.default_clearer" />
101102

102103
</services>

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\DependencyInjection\ContainerBuilder;
1919
use Symfony\Component\DependencyInjection\Definition;
2020
use Symfony\Component\DependencyInjection\Reference;
21+
use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
2122

2223
class CachePoolClearerPassTest extends \PHPUnit_Framework_TestCase
2324
{
@@ -29,6 +30,9 @@ public function testPoolRefsAreWeak()
2930
$container->setParameter('kernel.environment', 'prod');
3031
$container->setParameter('kernel.root_dir', 'foo');
3132

33+
$globalClearer = new Definition(Psr6CacheClearer::class);
34+
$container->setDefinition('cache.global_clearer', $globalClearer);
35+
3236
$publicPool = new Definition();
3337
$publicPool->addArgument('namespace');
3438
$publicPool->addTag('cache.pool', array('clearer' => 'clearer_alias'));
@@ -50,6 +54,7 @@ public function testPoolRefsAreWeak()
5054
$pass->process($container);
5155
}
5256

53-
$this->assertEquals(array(array('addPool', array(new Reference('public.pool')))), $clearer->getMethodCalls());
57+
$this->assertEquals(array(array('public.pool' => new Reference('public.pool'))), $clearer->getArguments());
58+
$this->assertEquals(array(array('public.pool' => new Reference('public.pool'))), $globalClearer->getArguments());
5459
}
5560
}
+86Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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\Bundle\FrameworkBundle\Tests\Functional;
13+
14+
use Symfony\Bundle\FrameworkBundle\Command\CachePoolClearCommand;
15+
use Symfony\Component\Console\Tester\CommandTester;
16+
17+
/**
18+
* @group functional
19+
*/
20+
class CachePoolClearCommandTest extends WebTestCase
21+
{
22+
private $application;
23+
24+
protected function setUp()
25+
{
26+
static::bootKernel(array('test_case' => 'CachePoolClear', 'root_config' => 'config.yml'));
27+
}
28+
29+
public function testClearPrivatePool()
30+
{
31+
$tester = $this->createCommandTester();
32+
$tester->execute(array('pools' => array('cache.private_pool')), array('decorated' => false));
33+
34+
$this->assertSame(0, $tester->getStatusCode(), 'cache:pool:clear exits with 0 in case of success');
35+
$this->assertContains('Clearing cache pool: cache.private_pool', $tester->getDisplay());
36+
$this->assertContains('[OK] Cache was successfully cleared.', $tester->getDisplay());
37+
}
38+
39+
public function testClearPublicPool()
40+
{
41+
$tester = $this->createCommandTester();
42+
$tester->execute(array('pools' => array('cache.public_pool')), array('decorated' => false));
43+
44+
$this->assertSame(0, $tester->getStatusCode(), 'cache:pool:clear exits with 0 in case of success');
45+
$this->assertContains('Clearing cache pool: cache.public_pool', $tester->getDisplay());
46+
$this->assertContains('[OK] Cache was successfully cleared.', $tester->getDisplay());
47+
}
48+
49+
public function testClearPoolWithCustomClearer()
50+
{
51+
$tester = $this->createCommandTester();
52+
$tester->execute(array('pools' => array('cache.pool_with_clearer')), array('decorated' => false));
53+
54+
$this->assertSame(0, $tester->getStatusCode(), 'cache:pool:clear exits with 0 in case of success');
55+
$this->assertContains('Clearing cache pool: cache.pool_with_clearer', $tester->getDisplay());
56+
$this->assertContains('[OK] Cache was successfully cleared.', $tester->getDisplay());
57+
}
58+
59+
public function testCallClearer()
60+
{
61+
$tester = $this->createCommandTester();
62+
$tester->execute(array('pools' => array('cache.default_clearer')), array('decorated' => false));
63+
64+
$this->assertSame(0, $tester->getStatusCode(), 'cache:pool:clear exits with 0 in case of success');
65+
$this->assertContains('Calling cache clearer: cache.default_clearer', $tester->getDisplay());
66+
$this->assertContains('[OK] Cache was successfully cleared.', $tester->getDisplay());
67+
}
68+
69+
/**
70+
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
71+
* @expectedExceptionMessage You have requested a non-existent service "unknown_pool"
72+
*/
73+
public function testClearUnexistingPool()
74+
{
75+
$this->createCommandTester()
76+
->execute(array('pools' => array('unknown_pool')), array('decorated' => false));
77+
}
78+
79+
private function createCommandTester()
80+
{
81+
$command = new CachePoolClearCommand();
82+
$command->setContainer(static::$kernel->getContainer());
83+
84+
return new CommandTester($command);
85+
}
86+
}
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
13+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
14+
15+
return array(
16+
new FrameworkBundle(),
17+
new TestBundle(),
18+
);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.