diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php new file mode 100644 index 0000000000..146c3c8c73 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Nicolas Grekas + */ +final class CachePoolClearerPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->findTaggedServiceIds('cache.pool') as $id => $attributes) { + foreach (array_reverse($attributes) as $attr) { + if (isset($attr['clearer'])) { + $clearer = $container->getDefinition($attr['clearer']); + $clearer->addMethodCall('addPool', array(new Reference($id))); + } + if (array_key_exists('clearer', $attr)) { + break; + } + } + } + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php index a625648a4a..3740922b43 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php @@ -37,6 +37,7 @@ class CachePoolPass implements CompilerPassInterface } } + $aliases = $container->getAliases(); $attributes = array( 'provider', 'namespace', @@ -57,7 +58,10 @@ class CachePoolPass implements CompilerPassInterface $tags[0]['namespace'] = $this->getNamespace($namespaceSuffix, $id); } if (isset($tags[0]['clearer'])) { - $clearer = $container->getDefinition($tags[0]['clearer']); + $clearer = strtolower($tags[0]['clearer']); + while (isset($aliases[$clearer])) { + $clearer = (string) $aliases[$clearer]; + } } else { $clearer = null; } @@ -78,7 +82,7 @@ class CachePoolPass implements CompilerPassInterface } if (null !== $clearer) { - $clearer->addMethodCall('addPool', array(new Reference($id))); + $pool->addTag('cache.pool', array('clearer' => $clearer)); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 7ed44c5bb8..63055fd303 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -15,6 +15,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintVal use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolClearerPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ControllerArgumentValueResolverPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass; @@ -91,6 +92,7 @@ class FrameworkBundle extends Bundle $container->addCompilerPass(new PropertyInfoPass()); $container->addCompilerPass(new ControllerArgumentValueResolverPass()); $container->addCompilerPass(new CachePoolPass()); + $container->addCompilerPass(new CachePoolClearerPass(), PassConfig::TYPE_AFTER_REMOVING); if ($container->getParameter('kernel.debug')) { $container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml index 89fac7324d..eb3703cb6c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml @@ -88,7 +88,7 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php new file mode 100644 index 0000000000..62a4196231 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolClearerPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass; +use Symfony\Component\DependencyInjection\Compiler\RemoveUnusedDefinitionsPass; +use Symfony\Component\DependencyInjection\Compiler\RepeatedPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class CachePoolClearerPassTest extends \PHPUnit_Framework_TestCase +{ + public function testPoolRefsAreWeak() + { + $container = new ContainerBuilder(); + + $publicPool = new Definition(); + $publicPool->addArgument('namespace'); + $publicPool->addTag('cache.pool', array('clearer' => 'clearer_alias')); + $container->setDefinition('public.pool', $publicPool); + + $privatePool = new Definition(); + $privatePool->setPublic(false); + $privatePool->addArgument('namespace'); + $privatePool->addTag('cache.pool', array('clearer' => 'clearer_alias')); + $container->setDefinition('private.pool', $privatePool); + + $clearer = new Definition(); + $container->setDefinition('clearer', $clearer); + $container->setAlias('clearer_alias', 'clearer'); + + $pass = new RemoveUnusedDefinitionsPass(); + $pass->setRepeatedPass(new RepeatedPass(array($pass))); + foreach (array(new CachePoolPass(), $pass, new CachePoolClearerPass()) as $pass) { + $pass->process($container); + } + + $this->assertEquals(array(array('addPool', array(new Reference('public.pool')))), $clearer->getMethodCalls()); + } +}