8000 bug #21339 [FrameworkBundle] CachePoolClearerPass fails if "cache.ann… · symfony/symfony@62c601e · GitHub
[go: up one dir, main page]

Skip to content

Commit 62c601e

Browse files
author
Antanas Arvasevicius
committed
bug #21339 [FrameworkBundle] CachePoolClearerPass fails if "cache.annotations" service is created
1 parent 922b7c1 commit 62c601e

File tree

7 files changed

+191
-18
lines changed

7 files changed

+191
-18
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\Cache\Adapter\AbstractAdapter;
15+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
19+
final class CacheAnnotationsMonologInjectorPass implements CompilerPassInterface
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function process(ContainerBuilder $container)
25+
{
26+
if (!($container->hasDefinition('cache.annotations') || $container->hasAlias('cache.annotations'))) {
27+
return;
28+
}
29+
$factory = array(AbstractAdapter::class, 'createSystemCache');
30+
$annotationsPool = $container->findDefinition('cache.annotations');
31+
if ($factory !== $annotationsPool->getFactory() || 4 !== count($annotationsPool->getArguments())) {
32+
return;
33+
}
34+
if ($container->has('monolog.logger.cache')) {
35+
$annotationsPool->addArgument(new Reference('monolog.logger.cache'));
36+
} elseif ($container->hasDefinitio 8000 n('cache.system')) {
37+
$systemPool = $container->getDefinition('cache.system');
38+
if ($factory === $systemPool->getFactory() && 5 <= count($systemArgs = $systemPool->getArguments())) {
39+
$annotationsPool->addArgument($systemArgs[4]);
40+
}
41+
}
42+
}
43+
}

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

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
1313

14-
use Symfony\Component\Cache\Adapter\AbstractAdapter;
1514
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1615
use Symfony\Component\DependencyInjection\ContainerBuilder;
1716
use Symfony\Component\DependencyInjection\Reference;
@@ -39,22 +38,5 @@ public function process(ContainerBuilder $container)
3938
}
4039
}
4140
}
42-
43-
if (!$container->has('cache.annotations')) {
44-
return;
45-
}
46-
$factory = array(AbstractAdapter::class, 'createSystemCache');
47-
$annotationsPool = $container->getDefinition('cache.annotations');
48-
if ($factory !== $annotationsPool->getFactory() || 4 !== count($annotationsPool->getArguments())) {
49-
return;
50-
}
51-
if ($container->has('monolog.logger.cache')) {
52-
$annotationsPool->addArgument(new Reference('monolog.logger.cache'));
53-
} elseif ($container->has('cache.system')) {
54-
$systemPool = $container->getDefinition('cache.system');
55-
if ($factory === $systemPool->getFactory() && 5 <= count($systemArgs = $systemPool->getArguments())) {
56-
$annotationsPool->addArgument($systemArgs[4]);
57-
}
58-
}
5941
}
6042
}

src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddDebugLogProcessorPass;
1616
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass;
1717
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass;
18+
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CacheAnnotationsMonologInjectorPass;
1819
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass;
1920
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolClearerPass;
2021
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ControllerArgumentValueResolverPass;
@@ -96,6 +97,7 @@ public function build(ContainerBuilder $container)
9697
$container->addCompilerPass(new CachePoolPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 32);
9798
$container->addCompilerPass(new ValidateWorkflowsPass());
9899
$container->addCompilerPass(new CachePoolClearerPass(), PassConfig::TYPE_AFTER_REMOVING);
100+
$container->addCompilerPass(new CacheAnnotationsMonologInjectorPass(), PassConfig::TYPE_BEFORE_REMOVING, 32);
99101

100102
if ($container->getParameter('kernel.debug')) {
101103
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDumpTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,14 @@ public function testContainerCompilation()
2929

3030
$this->assertTrue($client->getContainer()->has('serializer'));
3131
}
32+
33+
/**
34+
* @see https://github.com/symfony/symfony/issues/21339
35+
*/
36+
public function testContainerCompilationErrorDueCachePoolClearerPassBug()
37+
{
38+
$client = $this->createClient(array('test_case' => 'ContainerDumpCacheAnnotationsBug', 'root_config' => 'config.yml', 'debug' => true));
39+
40+
$this->assertTrue($client->getContainer()->has('serializer'));
41+
}
3242
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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\app\ContainerDumpCacheAnnotationsBug;
13+
14+
use Psr\Cache\CacheItemInterface;
15+
use Psr\Cache\CacheItemPoolInterface;
16+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17+
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
18+
use Symfony\Component\DependencyInjection\ContainerBuilder;
19+
use Symfony\Component\DependencyInjection\Reference;
20+
use Symfony\Component\HttpKernel\Bundle\Bundle;
21+
22+
class BeforeOptimizationCompilerPass implements CompilerPassInterface
23+
{
24+
public function process(ContainerBuilder $container)
25+
{
26+
// force to use service in compiler pass which does DiExtraBundle
27+
$container->get('cache.annotations');
28+
}
29+
}
30+
31+
/**
32+
* Emulate CacheCollectorPass which aliasias cache.annotations service (used in debug mode).
33+
*
34+
* @see src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CacheCollectorPass.php:24
35+
*/
36+
class CacheCollectorEmulationPass implements CompilerPassInterface
37+
{
38+
public function process(ContainerBuilder $container)
39+
{
40+
$id = 'cache.annotations';
41+
42+
$container->register($id.'.recorder', DummyDecorator::class)
43+
->setDecoratedService($id)
44+
->addArgument(new Reference($id.'.recorder.inner'))
45+
->setPublic(false);
46+
}
47+
}
48+
49+
class DummyDecorator implements CacheItemPoolInterface
50+
{
51+
public function getItem($key)
52+
{
53+
}
54+
55+
public function getItems(array $keys = array())
56+
{
57+
}
58+
59+
public function hasItem($key)
60+
{
61+
}
62+
63+
public function clear()
64+
{
65+
}
66+
67+
public function deleteItem($key)
68+
{
69+
}
70+
71+
public function deleteItems(array $keys)
72+
{
73+
}
74+
75+
public function save(CacheItemInterface $item)
76+
{
77+
}
78+
79+
public function saveDeferred(CacheItemInterface $item)
80+
{
81+
}
82+
83+
public function commit()
84+
{
85+
}
86+
}
87+
88+
class SetupBundle extends Bundle
89+
{
90+
public function build(ContainerBuilder $container)
91+
{
92+
$container->addCompilerPass(new BeforeOptimizationCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION);
93+
$container->addCompilerPass(new CacheCollectorEmulationPass());
94+
}
95+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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\app\ContainerDumpCacheAnnotationsBug\SetupBundle;
13+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
14+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
15+
16+
return array(
17+
new FrameworkBundle(),
18+
new TestBundle(),
19+
new SetupBundle(),
20+
);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
imports:
2+
- { resource: ../config/default.yml }
3+
4+
framework:
5+
esi: true
6+
ssi: true
7+
fragments: true
8+
profiler: true
9+
router: true
10+
session: true
11+
request: true
12+
templating:
13+
enabled: true
14+
engines: ['php']
15+
assets: true
16+
translator: true
17+
validation: true
18+
serializer: true
19+
property_info: true
20+
csrf_protection: true
21+
form: true

0 commit comments

Comments
 (0)
0