feature #22459 [HttpKernel] Fix deprecation of Extension::addClassesToCompile() / AddClassesToCachePass (nicolas-grekas)
This PR was merged into the 3.3-dev branch.
Discussion
----------
[HttpKernel] Fix deprecation of Extension::addClassesToCompile() / AddClassesToCachePass
| Q | A
| ------------- | ---
| Branch? | 3.3
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
As done in https://github.com/symfony/symfony/pull/20735
Commits
-------
f4b5784dd9
[HttpKernel] Fix deprecation of Extension::addClassesToCompile() / AddClassesToCachePass
This commit is contained in:
commit
610a2385f6
@ -255,6 +255,8 @@ HttpFoundation
|
|||||||
HttpKernel
|
HttpKernel
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
* The `Extension::addClassesToCompile()` method has been deprecated and will be removed in 4.0.
|
||||||
|
|
||||||
* The `Psr6CacheClearer::addPool()` method has been deprecated. Pass an array
|
* The `Psr6CacheClearer::addPool()` method has been deprecated. Pass an array
|
||||||
of pools indexed by name to the constructor instead.
|
of pools indexed by name to the constructor instead.
|
||||||
|
|
||||||
|
@ -366,6 +366,8 @@ HttpFoundation
|
|||||||
HttpKernel
|
HttpKernel
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
* The `Extension::addClassesToCompile()` method has been removed.
|
||||||
|
|
||||||
* Possibility to pass non-scalar values as URI attributes to the ESI and SSI
|
* Possibility to pass non-scalar values as URI attributes to the ESI and SSI
|
||||||
renderers has been removed. The inline fragment renderer should be used with
|
renderers has been removed. The inline fragment renderer should be used with
|
||||||
non-scalar attributes.
|
non-scalar attributes.
|
||||||
|
@ -4,12 +4,13 @@ CHANGELOG
|
|||||||
3.3.0
|
3.3.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
* Added `kernel.project_dir` and `Kernel::getProjectDir()`
|
* added `kernel.project_dir` and `Kernel::getProjectDir()`
|
||||||
* Deprecated `kernel.root_dir` and `Kernel::getRootDir()`
|
* deprecated `kernel.root_dir` and `Kernel::getRootDir()`
|
||||||
* Deprecated `Kernel::getEnvParameters()`
|
* deprecated `Kernel::getEnvParameters()`
|
||||||
* Deprecated the special `SYMFONY__` environment variables
|
* deprecated the special `SYMFONY__` environment variables
|
||||||
* added the possibility to change the query string parameter used by `UriSigner`
|
* added the possibility to change the query string parameter used by `UriSigner`
|
||||||
* deprecated `LazyLoadingFragmentHandler::addRendererService()`
|
* deprecated `LazyLoadingFragmentHandler::addRendererService()`
|
||||||
|
* deprecated `Extension::addClassesToCompile()`
|
||||||
|
|
||||||
3.2.0
|
3.2.0
|
||||||
-----
|
-----
|
||||||
|
@ -0,0 +1,153 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||||
|
|
||||||
|
use Composer\Autoload\ClassLoader;
|
||||||
|
use Symfony\Component\Debug\DebugClassLoader;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\HttpKernel\Kernel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the classes to compile in the cache for the container.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class AddAnnotatedClassesToCachePass implements CompilerPassInterface
|
||||||
|
{
|
||||||
|
private $kernel;
|
||||||
|
|
||||||
|
public function __construct(Kernel $kernel)
|
||||||
|
{
|
||||||
|
$this->kernel = $kernel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function process(ContainerBuilder $container)
|
||||||
|
{
|
||||||
|
$classes = array();
|
||||||
|
$annotatedClasses = array();
|
||||||
|
foreach ($container->getExtensions() as $extension) {
|
||||||
|
if ($extension instanceof Extension) {
|
||||||
|
if (PHP_VERSION_ID < 70000) {
|
||||||
|
$classes = array_merge($classes, $extension->getClassesToCompile());
|
||||||
|
}
|
||||||
|
$annotatedClasses = array_merge($annotatedClasses, $extension->getAnnotatedClassesToCompile());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingClasses = $this->getClassesInComposerClassMaps();
|
||||||
|
|
||||||
|
if (PHP_VERSION_ID < 70000) {
|
||||||
|
$classes = $container->getParameterBag()->resolveValue($classes);
|
||||||
|
$this->kernel->setClassCache($this->expandClasses($classes, $existingClasses));
|
||||||
|
}
|
||||||
|
$annotatedClasses = $container->getParameterBag()->resolveValue($annotatedClasses);
|
||||||
|
$this->kernel->setAnnotatedClassCache($this->expandClasses($annotatedClasses, $existingClasses));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expands the given class patterns using a list of existing classes.
|
||||||
|
*
|
||||||
|
* @param array $patterns The class patterns to expand
|
||||||
|
* @param array $classes The existing classes to match against the patterns
|
||||||
|
*
|
||||||
|
* @return array A list of classes derivated from the patterns
|
||||||
|
*/
|
||||||
|
private function expandClasses(array $patterns, array $classes)
|
||||||
|
{
|
||||||
|
$expanded = array();
|
||||||
|
|
||||||
|
// Explicit classes declared in the patterns are returned directly
|
||||||
|
foreach ($patterns as $key => $pattern) {
|
||||||
|
if (substr($pattern, -1) !== '\\' && false === strpos($pattern, '*')) {
|
||||||
|
unset($patterns[$key]);
|
||||||
|
$expanded[] = ltrim($pattern, '\\');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match patterns with the classes list
|
||||||
|
$regexps = $this->patternsToRegexps($patterns);
|
||||||
|
|
||||||
|
foreach ($classes as $class) {
|
||||||
|
$class = ltrim($class, '\\');
|
||||||
|
|
||||||
|
if ($this->matchAnyRegexps($class, $regexps)) {
|
||||||
|
$expanded[] = $class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_unique($expanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClassesInComposerClassMaps()
|
||||||
|
{
|
||||||
|
$classes = array();
|
||||||
|
|
||||||
|
foreach (spl_autoload_functions() as $function) {
|
||||||
|
if (!is_array($function)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($function[0] instanceof DebugClassLoader) {
|
||||||
|
$function = $function[0]->getClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($function) && $function[0] instanceof ClassLoader) {
|
||||||
|
$classes += array_filter($function[0]->getClassMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_keys($classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function patternsToRegexps($patterns)
|
||||||
|
{
|
||||||
|
$regexps = array();
|
||||||
|
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
|
// Escape user input
|
||||||
|
$regex = preg_quote(ltrim($pattern, '\\'));
|
||||||
|
|
||||||
|
// Wildcards * and **
|
||||||
|
$regex = strtr($regex, array('\\*\\*' => '.*?', '\\*' => '[^\\\\]*?'));
|
||||||
|
|
||||||
|
// If this class does not end by a slash, anchor the end
|
||||||
|
if (substr($regex, -1) !== '\\') {
|
||||||
|
$regex .= '$';
|
||||||
|
}
|
||||||
|
|
||||||
|
$regexps[] = '{^\\\\'.$regex.'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $regexps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function matchAnyRegexps($class, $regexps)
|
||||||
|
{
|
||||||
|
$blacklisted = false !== strpos($class, 'Test');
|
||||||
|
|
||||||
|
foreach ($regexps as $regex) {
|
||||||
|
if ($blacklisted && false === strpos($regex, 'Test')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match($regex, '\\'.$class)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -11,15 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||||
|
|
||||||
if (PHP_VERSION_ID >= 70000) {
|
@trigger_error('The '.__NAMESPACE__.'\AddClassesToCachePass class is deprecated since version 3.3 and will be removed in 4.0.', E_USER_DEPRECATED);
|
||||||
@trigger_error('The '.__NAMESPACE__.'\AddClassesToCachePass class is deprecated since version 3.3 and will be removed in 4.0.', E_USER_DEPRECATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
use Composer\Autoload\ClassLoader;
|
|
||||||
use Symfony\Component\Debug\DebugClassLoader;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
||||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
|
||||||
use Symfony\Component\HttpKernel\Kernel;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the classes to compile in the cache for the container.
|
* Sets the classes to compile in the cache for the container.
|
||||||
@ -28,128 +20,6 @@ use Symfony\Component\HttpKernel\Kernel;
|
|||||||
*
|
*
|
||||||
* @deprecated since version 3.3, to be removed in 4.0.
|
* @deprecated since version 3.3, to be removed in 4.0.
|
||||||
*/
|
*/
|
||||||
class AddClassesToCachePass implements CompilerPassInterface
|
class AddClassesToCachePass extends AddAnnotatedClassesToCachePass
|
||||||
{
|
{
|
||||||
private $kernel;
|
|
||||||
|
|
||||||
public function __construct(Kernel $kernel)
|
|
||||||
{
|
|
||||||
$this->kernel = $kernel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function process(ContainerBuilder $container)
|
|
||||||
{
|
|
||||||
$classes = array();
|
|
||||||
$annotatedClasses = array();
|
|
||||||
foreach ($container->getExtensions() as $extension) {
|
|
||||||
if ($extension instanceof Extension) {
|
|
||||||
$classes = array_merge($classes, $extension->getClassesToCompile());
|
|
||||||
$annotatedClasses = array_merge($annotatedClasses, $extension->getAnnotatedClassesToCompile());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$classes = $container->getParameterBag()->resolveValue($classes);
|
|
||||||
$annotatedClasses = $container->getParameterBag()->resolveValue($annotatedClasses);
|
|
||||||
$existingClasses = $this->getClassesInComposerClassMaps();
|
|
||||||
|
|
||||||
$this->kernel->setClassCache($this->expandClasses($classes, $existingClasses));
|
|
||||||
$this->kernel->setAnnotatedClassCache($this->expandClasses($annotatedClasses, $existingClasses));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expands the given class patterns using a list of existing classes.
|
|
||||||
*
|
|
||||||
* @param array $patterns The class patterns to expand
|
|
||||||
* @param array $classes The existing classes to match against the patterns
|
|
||||||
*
|
|
||||||
* @return array A list of classes derivated from the patterns
|
|
||||||
*/
|
|
||||||
private function expandClasses(array $patterns, array $classes)
|
|
||||||
{
|
|
||||||
$expanded = array();
|
|
||||||
|
|
||||||
// Explicit classes declared in the patterns are returned directly
|
|
||||||
foreach ($patterns as $key => $pattern) {
|
|
||||||
if (substr($pattern, -1) !== '\\' && false === strpos($pattern, '*')) {
|
|
||||||
unset($patterns[$key]);
|
|
||||||
$expanded[] = ltrim($pattern, '\\');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match patterns with the classes list
|
|
||||||
$regexps = $this->patternsToRegexps($patterns);
|
|
||||||
|
|
||||||
foreach ($classes as $class) {
|
|
||||||
$class = ltrim($class, '\\');
|
|
||||||
|
|
||||||
if ($this->matchAnyRegexps($class, $regexps)) {
|
|
||||||
$expanded[] = $class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_unique($expanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getClassesInComposerClassMaps()
|
|
||||||
{
|
|
||||||
$classes = array();
|
|
||||||
|
|
||||||
foreach (spl_autoload_functions() as $function) {
|
|
||||||
if (!is_array($function)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($function[0] instanceof DebugClassLoader) {
|
|
||||||
$function = $function[0]->getClassLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($function) && $function[0] instanceof ClassLoader) {
|
|
||||||
$classes += array_filter($function[0]->getClassMap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_keys($classes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function patternsToRegexps($patterns)
|
|
||||||
{
|
|
||||||
$regexps = array();
|
|
||||||
|
|
||||||
foreach ($patterns as $pattern) {
|
|
||||||
// Escape user input
|
|
||||||
$regex = preg_quote(ltrim($pattern, '\\'));
|
|
||||||
|
|
||||||
// Wildcards * and **
|
|
||||||
$regex = strtr($regex, array('\\*\\*' => '.*?', '\\*' => '[^\\\\]*?'));
|
|
||||||
|
|
||||||
// If this class does not end by a slash, anchor the end
|
|
||||||
if (substr($regex, -1) !== '\\') {
|
|
||||||
$regex .= '$';
|
|
||||||
}
|
|
||||||
|
|
||||||
$regexps[] = '{^\\\\'.$regex.'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $regexps;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function matchAnyRegexps($class, $regexps)
|
|
||||||
{
|
|
||||||
$blacklisted = false !== strpos($class, 'Test');
|
|
||||||
|
|
||||||
foreach ($regexps as $regex) {
|
|
||||||
if ($blacklisted && false === strpos($regex, 'Test')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preg_match($regex, '\\'.$class)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
|||||||
use Symfony\Component\HttpKernel\Config\EnvParametersResource;
|
use Symfony\Component\HttpKernel\Config\EnvParametersResource;
|
||||||
use Symfony\Component\HttpKernel\Config\FileLocator;
|
use Symfony\Component\HttpKernel\Config\FileLocator;
|
||||||
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
|
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
|
||||||
use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass;
|
use Symfony\Component\HttpKernel\DependencyInjection\AddAnnotatedClassesToCachePass;
|
||||||
use Symfony\Component\Config\Loader\GlobFileLoader;
|
use Symfony\Component\Config\Loader\GlobFileLoader;
|
||||||
use Symfony\Component\Config\Loader\LoaderResolver;
|
use Symfony\Component\Config\Loader\LoaderResolver;
|
||||||
use Symfony\Component\Config\Loader\DelegatingLoader;
|
use Symfony\Component\Config\Loader\DelegatingLoader;
|
||||||
@ -652,9 +652,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
|||||||
$container->merge($cont);
|
$container->merge($cont);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 70000) {
|
$container->addCompilerPass(new AddAnnotatedClassesToCachePass($this));
|
||||||
$container->addCompilerPass(new AddClassesToCachePass($this));
|
|
||||||
}
|
|
||||||
$container->addResource(new EnvParametersResource('SYMFONY__'));
|
$container->addResource(new EnvParametersResource('SYMFONY__'));
|
||||||
|
|
||||||
return $container;
|
return $container;
|
||||||
|
@ -12,18 +12,15 @@
|
|||||||
namespace Symfony\Component\HttpKernel\Tests\DependencyInjection;
|
namespace Symfony\Component\HttpKernel\Tests\DependencyInjection;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass;
|
use Symfony\Component\HttpKernel\DependencyInjection\AddAnnotatedClassesToCachePass;
|
||||||
|
|
||||||
/**
|
class AddAnnotatedClassesToCachePassTest extends TestCase
|
||||||
* @group legacy
|
|
||||||
*/
|
|
||||||
class AddClassesToCachePassTest extends TestCase
|
|
||||||
{
|
{
|
||||||
public function testExpandClasses()
|
public function testExpandClasses()
|
||||||
{
|
{
|
||||||
$r = new \ReflectionClass(AddClassesToCachePass::class);
|
$r = new \ReflectionClass(AddAnnotatedClassesToCachePass::class);
|
||||||
$pass = $r->newInstanceWithoutConstructor();
|
$pass = $r->newInstanceWithoutConstructor();
|
||||||
$r = new \ReflectionMethod(AddClassesToCachePass::class, 'expandClasses');
|
$r = new \ReflectionMethod(AddAnnotatedClassesToCachePass::class, 'expandClasses');
|
||||||
$r->setAccessible(true);
|
$r->setAccessible(true);
|
||||||
$expand = $r->getClosure($pass);
|
$expand = $r->getClosure($pass);
|
||||||
|
|
Reference in New Issue
Block a user