diff --git a/DependencyInjection/Compiler/RemoveClassesFromCachePass.php b/DependencyInjection/Compiler/RemoveClassesFromCachePass.php new file mode 100644 index 00000000..74701dd4 --- /dev/null +++ b/DependencyInjection/Compiler/RemoveClassesFromCachePass.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\HttpCacheBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Compiler pass to remove some classes from Symfony's class cache to prevent + * from redeclaration in early cache lookup phase + * (see https://github.com/FriendsOfSymfony/FOSHttpCacheBundle/issues/242). + */ +class RemoveClassesFromCachePass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasParameter('fos_http_cache.invalidation.enabled')) { + return; + } + + $frameworkExt = $container->getExtension('framework'); + $classes = $frameworkExt->getClassesToCompile(); + + // remove classes + $classesToRemove = array( + 'Symfony\\Component\\EventDispatcher\\Event', + 'Symfony\\Component\\HttpKernel\\Event\\KernelEvent', + 'Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent', + 'Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent', + 'Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent', + 'Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent', + 'Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent', + ); + foreach ($classesToRemove as $className) { + $index = array_search($className, $classes); + array_splice($classes, $index, 1); + } + + // overwrite array for class cache via reflection (no other way) + $reflClass = new \ReflectionClass('Symfony\\Component\\HttpKernel\\DependencyInjection\\Extension'); + $reflProp = $reflClass->getProperty('classes'); + $reflProp->setAccessible(true); + $reflProp->setValue($frameworkExt, $classes); + } +} \ No newline at end of file diff --git a/DependencyInjection/FOSHttpCacheExtension.php b/DependencyInjection/FOSHttpCacheExtension.php index 5c3e8f32..d72b5aa0 100644 --- a/DependencyInjection/FOSHttpCacheExtension.php +++ b/DependencyInjection/FOSHttpCacheExtension.php @@ -100,6 +100,7 @@ public function load(array $configs, ContainerBuilder $container) if (!empty($config['invalidation']['rules'])) { $this->loadInvalidatorRules($container, $config['invalidation']['rules']); } + $container->setParameter($this->getAlias().'.invalidation.enabled', true); } if ($config['user_context']['enabled']) { diff --git a/FOSHttpCacheBundle.php b/FOSHttpCacheBundle.php index 7d4734cd..d9a2cc1d 100644 --- a/FOSHttpCacheBundle.php +++ b/FOSHttpCacheBundle.php @@ -15,6 +15,7 @@ use FOS\HttpCacheBundle\DependencyInjection\Compiler\SecurityContextPass; use FOS\HttpCacheBundle\DependencyInjection\Compiler\TagSubscriberPass; use FOS\HttpCacheBundle\DependencyInjection\Compiler\HashGeneratorPass; +use FOS\HttpCacheBundle\DependencyInjection\Compiler\RemoveClassesFromCachePass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -29,5 +30,6 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new SecurityContextPass()); $container->addCompilerPass(new TagSubscriberPass()); $container->addCompilerPass(new HashGeneratorPass()); + $container->addCompilerPass(new RemoveClassesFromCachePass()); } }