[ClassLoader][HttpKernel] Remove ClassCollectionLoader & Kernel::loadClassCache BC layer
This commit is contained in:
parent
7047b41449
commit
4f8916cb59
@ -1,67 +0,0 @@
|
||||
<?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\Bundle\FrameworkBundle\CacheWarmer;
|
||||
|
||||
use Symfony\Component\ClassLoader\ClassCollectionLoader;
|
||||
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
||||
|
||||
/**
|
||||
* Generates the Class Cache (classes.php) file.
|
||||
*
|
||||
* @author Tugdual Saunier <tucksaun@gmail.com>
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
class ClassCacheCacheWarmer implements CacheWarmerInterface
|
||||
{
|
||||
private $declaredClasses;
|
||||
|
||||
public function __construct(array $declaredClasses = null)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
@trigger_error('The '.__CLASS__.' class is deprecated since version 3.3 and will be removed in 4.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->declaredClasses = $declaredClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Warms up the cache.
|
||||
*
|
||||
* @param string $cacheDir The cache directory
|
||||
*/
|
||||
public function warmUp($cacheDir)
|
||||
{
|
||||
$classmap = $cacheDir.'/classes.map';
|
||||
|
||||
if (!is_file($classmap)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_exists($cacheDir.'/classes.php')) {
|
||||
return;
|
||||
}
|
||||
$declared = null !== $this->declaredClasses ? $this->declaredClasses : array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
||||
|
||||
ClassCollectionLoader::inline(include($classmap), $cacheDir.'/classes.php', $declared);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this warmer is optional or not.
|
||||
*
|
||||
* @return bool always true
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -95,14 +95,6 @@ class FrameworkExtension extends Extension
|
||||
|
||||
$loader->load('web.xml');
|
||||
$loader->load('services.xml');
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$definition = $container->getDefinition('kernel.class_cache.cache_warmer');
|
||||
$definition->addTag('kernel.cache_warmer');
|
||||
// Ignore deprecation for PHP versions below 7.0
|
||||
$definition->setDeprecated(false);
|
||||
}
|
||||
|
||||
$loader->load('fragment_renderer.xml');
|
||||
|
||||
if (class_exists(Application::class)) {
|
||||
@ -288,46 +280,6 @@ class FrameworkExtension extends Extension
|
||||
->addTag('validator.constraint_validator');
|
||||
$container->registerForAutoconfiguration(ObjectInitializerInterface::class)
|
||||
->addTag('validator.initializer');
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Component\\Config\\ConfigCache',
|
||||
'Symfony\\Component\\Config\\FileLocator',
|
||||
|
||||
'Symfony\\Component\\Debug\\ErrorHandler',
|
||||
|
||||
'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface',
|
||||
'Symfony\\Component\\DependencyInjection\\Container',
|
||||
|
||||
'Symfony\\Component\\EventDispatcher\\Event',
|
||||
|
||||
'Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener',
|
||||
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener',
|
||||
'Symfony\\Component\\HttpKernel\\Bundle\\Bundle',
|
||||
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver',
|
||||
'Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver',
|
||||
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata',
|
||||
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory',
|
||||
'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',
|
||||
'Symfony\\Component\\HttpKernel\\HttpKernel',
|
||||
'Symfony\\Component\\HttpKernel\\KernelEvents',
|
||||
'Symfony\\Component\\HttpKernel\\Config\\FileLocator',
|
||||
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerNameParser',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver',
|
||||
|
||||
// Cannot be included because annotations will parse the big compiled class file
|
||||
// 'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller',
|
||||
|
||||
// cannot be included as commands are discovered based on the path to this class via Reflection
|
||||
// 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -668,16 +620,6 @@ class FrameworkExtension extends Extension
|
||||
|
||||
$container->setParameter('request_listener.http_port', $config['http_port']);
|
||||
$container->setParameter('request_listener.https_port', $config['https_port']);
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
||||
'Symfony\\Component\\Routing\\RequestContext',
|
||||
'Symfony\\Component\\Routing\\Router',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Routing\\RedirectableUrlMatcher',
|
||||
$container->findDefinition('router.default')->getClass(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -720,24 +662,6 @@ class FrameworkExtension extends Extension
|
||||
|
||||
$container->setParameter('session.save_path', $config['save_path']);
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Component\\HttpKernel\\EventListener\\SessionListener',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\PhpBridgeSessionStorage',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\AbstractProxy',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\SessionHandlerProxy',
|
||||
$container->getDefinition('session')->getClass(),
|
||||
));
|
||||
|
||||
if ($container->hasDefinition($config['storage_id'])) {
|
||||
$this->addClassesToCompile(array(
|
||||
$container->findDefinition('session.storage')->getClass(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$container->setParameter('session.metadata.update_threshold', $config['metadata_update_threshold']);
|
||||
}
|
||||
|
||||
@ -805,15 +729,6 @@ class FrameworkExtension extends Extension
|
||||
$container->setDefinition('templating.loader', $loaderCache);
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Templating\\TemplateReference',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Templating\\TemplateNameParser',
|
||||
$container->findDefinition('templating.locator')->getClass(),
|
||||
));
|
||||
}
|
||||
|
||||
$container->setParameter('templating.engines', $config['engines']);
|
||||
$engines = array_map(function ($engine) { return new Reference('templating.engine.'.$engine); }, $config['engines']);
|
||||
|
||||
@ -845,14 +760,6 @@ class FrameworkExtension extends Extension
|
||||
$container->setAlias('debug.templating.engine.php', 'templating.engine.php');
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Component\\Templating\\Storage\\FileStorage',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Templating\\PhpEngine',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Templating\\Loader\\FilesystemLoader',
|
||||
));
|
||||
}
|
||||
|
||||
if ($container->has('assets.packages')) {
|
||||
$container->getDefinition('templating.helper.assets')->replaceArgument(0, new Reference('assets.packages'));
|
||||
} else {
|
||||
@ -1185,13 +1092,6 @@ class FrameworkExtension extends Extension
|
||||
// Enable warmer only if PHP array is used for cache
|
||||
$definition = $container->findDefinition('annotations.cache_warmer');
|
||||
$definition->addTag('kernel.cache_warmer');
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\Component\Cache\Adapter\PhpArrayAdapter',
|
||||
'Symfony\Component\Cache\DoctrineProvider',
|
||||
));
|
||||
}
|
||||
} elseif ('file' === $config['cache']) {
|
||||
$cacheDir = $container->getParameterBag()->resolveValue($config['file_cache_dir']);
|
||||
|
||||
@ -1442,14 +1342,6 @@ class FrameworkExtension extends Extension
|
||||
$propertyAccessDefinition->setArguments(array(0, false));
|
||||
}
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\Component\Cache\Adapter\ApcuAdapter',
|
||||
'Symfony\Component\Cache\Adapter\FilesystemAdapter',
|
||||
'Symfony\Component\Cache\CacheItem',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,18 +25,6 @@
|
||||
<argument type="collection" />
|
||||
</service>
|
||||
|
||||
<service id="kernel.class_cache.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\ClassCacheCacheWarmer" public="true">
|
||||
<argument type="collection">
|
||||
<argument>Symfony\Component\HttpFoundation\ParameterBag</argument>
|
||||
<argument>Symfony\Component\HttpFoundation\HeaderBag</argument>
|
||||
<argument>Symfony\Component\HttpFoundation\FileBag</argument>
|
||||
<argument>Symfony\Component\HttpFoundation\ServerBag</argument>
|
||||
<argument>Symfony\Component\HttpFoundation\Request</argument>
|
||||
<argument>Symfony\Component\HttpKernel\Kernel</argument>
|
||||
</argument>
|
||||
<deprecated>The "%service_id%" option is deprecated since version 3.3, to be removed in 4.0.</deprecated>
|
||||
</service>
|
||||
|
||||
<service id="cache_clearer" class="Symfony\Component\HttpKernel\CacheClearer\ChainCacheClearer" public="true">
|
||||
<argument type="collection" />
|
||||
</service>
|
||||
|
@ -1,51 +0,0 @@
|
||||
<?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\Bundle\FrameworkBundle\Tests\CacheWarmer;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\CacheWarmer\ClassCacheCacheWarmer;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\DeclaredClass;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\WarmedClass;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
class ClassCacheCacheWarmerTest extends TestCase
|
||||
{
|
||||
public function testWithDeclaredClasses()
|
||||
{
|
||||
$this->assertTrue(class_exists(WarmedClass::class, true));
|
||||
|
||||
$dir = sys_get_temp_dir();
|
||||
@unlink($dir.'/classes.php');
|
||||
file_put_contents($dir.'/classes.map', sprintf('<?php return %s;', var_export(array(WarmedClass::class), true)));
|
||||
|
||||
$warmer = new ClassCacheCacheWarmer(array(DeclaredClass::class));
|
||||
|
||||
$warmer->warmUp($dir);
|
||||
|
||||
$this->assertSame(<<<'EOTXT'
|
||||
<?php
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures
|
||||
{
|
||||
class WarmedClass extends DeclaredClass
|
||||
{
|
||||
}
|
||||
}
|
||||
EOTXT
|
||||
, file_get_contents($dir.'/classes.php')
|
||||
);
|
||||
|
||||
@unlink($dir.'/classes.map');
|
||||
@unlink($dir.'/classes.php');
|
||||
}
|
||||
}
|
@ -112,22 +112,6 @@ class SecurityExtension extends Extension
|
||||
|
||||
$container->registerForAutoconfiguration(VoterInterface::class)
|
||||
->addTag('security.voter');
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
// add some required classes for compilation
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\Component\Security\Http\Firewall',
|
||||
'Symfony\Component\Security\Core\User\UserProviderInterface',
|
||||
'Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager',
|
||||
'Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage',
|
||||
'Symfony\Component\Security\Core\Authorization\AccessDecisionManager',
|
||||
'Symfony\Component\Security\Core\Authorization\AuthorizationChecker',
|
||||
'Symfony\Component\Security\Core\Authorization\Voter\VoterInterface',
|
||||
'Symfony\Bundle\SecurityBundle\Security\FirewallConfig',
|
||||
'Symfony\Bundle\SecurityBundle\Security\FirewallContext',
|
||||
'Symfony\Component\HttpFoundation\RequestMatcher',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private function aclLoad($config, ContainerBuilder $container)
|
||||
@ -204,12 +188,6 @@ class SecurityExtension extends Extension
|
||||
return;
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Component\\Security\\Http\\AccessMap',
|
||||
));
|
||||
}
|
||||
|
||||
foreach ($config['access_control'] as $access) {
|
||||
$matcher = $this->createRequestMatcher(
|
||||
$container,
|
||||
|
@ -148,19 +148,6 @@ class TwigExtension extends Extension
|
||||
->addTag('twig.extension');
|
||||
$container->registerForAutoconfiguration(\Twig_LoaderInterface::class)
|
||||
->addTag('twig.loader');
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
$this->addClassesToCompile(array(
|
||||
'Twig_Environment',
|
||||
'Twig_Extension',
|
||||
'Twig_Extension_Core',
|
||||
'Twig_Extension_Escaper',
|
||||
'Twig_Extension_Optimizer',
|
||||
'Twig_LoaderInterface',
|
||||
'Twig_Markup',
|
||||
'Twig_Template',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private function getBundleHierarchy(ContainerBuilder $container)
|
||||
|
@ -1,450 +0,0 @@
|
||||
<?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\ClassLoader;
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
@trigger_error('The '.__NAMESPACE__.'\ClassCollectionLoader class is deprecated since version 3.3 and will be removed in 4.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ClassCollectionLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
class ClassCollectionLoader
|
||||
{
|
||||
private static $loaded;
|
||||
private static $seen;
|
||||
private static $useTokenizer = true;
|
||||
|
||||
/**
|
||||
* Loads a list of classes and caches them in one big file.
|
||||
*
|
||||
* @param array $classes An array of classes to load
|
||||
* @param string $cacheDir A cache directory
|
||||
* @param string $name The cache name prefix
|
||||
* @param bool $autoReload Whether to flush the cache when the cache is stale or not
|
||||
* @param bool $adaptive Whether to remove already declared classes or not
|
||||
* @param string $extension File extension of the resulting file
|
||||
*
|
||||
* @throws \InvalidArgumentException When class can't be loaded
|
||||
*/
|
||||
public static function load($classes, $cacheDir, $name, $autoReload, $adaptive = false, $extension = '.php')
|
||||
{
|
||||
// each $name can only be loaded once per PHP process
|
||||
if (isset(self::$loaded[$name])) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$loaded[$name] = true;
|
||||
|
||||
if ($adaptive) {
|
||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
||||
|
||||
// don't include already declared classes
|
||||
$classes = array_diff($classes, $declared);
|
||||
|
||||
// the cache is different depending on which classes are already declared
|
||||
$name = $name.'-'.substr(hash('sha256', implode('|', $classes)), 0, 5);
|
||||
}
|
||||
|
||||
$classes = array_unique($classes);
|
||||
|
||||
// cache the core classes
|
||||
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
|
||||
throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir));
|
||||
}
|
||||
$cacheDir = rtrim(realpath($cacheDir) ?: $cacheDir, '/'.DIRECTORY_SEPARATOR);
|
||||
$cache = $cacheDir.'/'.$name.$extension;
|
||||
|
||||
// auto-reload
|
||||
$reload = false;
|
||||
if ($autoReload) {
|
||||
$metadata = $cache.'.meta';
|
||||
if (!is_file($metadata) || !is_file($cache)) {
|
||||
$reload = true;
|
||||
} else {
|
||||
$time = filemtime($cache);
|
||||
$meta = unserialize(file_get_contents($metadata));
|
||||
|
||||
sort($meta[1]);
|
||||
sort($classes);
|
||||
|
||||
if ($meta[1] != $classes) {
|
||||
$reload = true;
|
||||
} else {
|
||||
foreach ($meta[0] as $resource) {
|
||||
if (!is_file($resource) || filemtime($resource) > $time) {
|
||||
$reload = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$reload && file_exists($cache)) {
|
||||
require_once $cache;
|
||||
|
||||
return;
|
||||
}
|
||||
if (!$adaptive) {
|
||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
||||
}
|
||||
|
||||
$files = self::inline($classes, $cache, $declared);
|
||||
|
||||
if ($autoReload) {
|
||||
// save the resources
|
||||
self::writeCacheFile($metadata, serialize(array(array_values($files), $classes)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a file where classes and their parents are inlined.
|
||||
*
|
||||
* @param array $classes An array of classes to load
|
||||
* @param string $cache The file where classes are inlined
|
||||
* @param array $excluded An array of classes that won't be inlined
|
||||
*
|
||||
* @return array The source map of inlined classes, with classes as keys and files as values
|
||||
*
|
||||
* @throws \RuntimeException When class can't be loaded
|
||||
*/
|
||||
public static function inline($classes, $cache, array $excluded)
|
||||
{
|
||||
$declared = array();
|
||||
foreach (self::getOrderedClasses($excluded) as $class) {
|
||||
$declared[$class->getName()] = true;
|
||||
}
|
||||
|
||||
// cache the core classes
|
||||
$cacheDir = dirname($cache);
|
||||
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
|
||||
throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir));
|
||||
}
|
||||
|
||||
$spacesRegex = '(?:\s*+(?:(?:\#|//)[^\n]*+\n|/\*(?:(?<!\*/).)++)?+)*+';
|
||||
$dontInlineRegex = <<<REGEX
|
||||
'(?:
|
||||
^<\?php\s.declare.\(.strict_types.=.1.\).;
|
||||
| \b__halt_compiler.\(.\)
|
||||
| \b__(?:DIR|FILE)__\b
|
||||
)'isx
|
||||
REGEX;
|
||||
$dontInlineRegex = str_replace('.', $spacesRegex, $dontInlineRegex);
|
||||
|
||||
$cacheDir = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $cacheDir));
|
||||
$files = array();
|
||||
$content = '';
|
||||
foreach (self::getOrderedClasses($classes) as $class) {
|
||||
if (isset($declared[$class->getName()])) {
|
||||
continue;
|
||||
}
|
||||
$declared[$class->getName()] = true;
|
||||
|
||||
$files[$class->getName()] = $file = $class->getFileName();
|
||||
$c = file_get_contents($file);
|
||||
|
||||
if (preg_match($dontInlineRegex, $c)) {
|
||||
$file = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $file));
|
||||
|
||||
for ($i = 0; isset($file[$i], $cacheDir[$i]); ++$i) {
|
||||
if ($file[$i] !== $cacheDir[$i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (1 >= $i) {
|
||||
$file = var_export(implode('/', $file), true);
|
||||
} else {
|
||||
$file = array_slice($file, $i);
|
||||
$file = str_repeat('../', count($cacheDir) - $i).implode('/', $file);
|
||||
$file = '__DIR__.'.var_export('/'.$file, true);
|
||||
}
|
||||
|
||||
$c = "\nnamespace {require $file;}";
|
||||
} else {
|
||||
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', $c);
|
||||
|
||||
// fakes namespace declaration for global code
|
||||
if (!$class->inNamespace()) {
|
||||
$c = "\nnamespace\n{\n".$c."\n}\n";
|
||||
}
|
||||
|
||||
$c = self::fixNamespaceDeclarations('<?php '.$c);
|
||||
$c = preg_replace('/^\s*<\?php/', '', $c);
|
||||
}
|
||||
|
||||
$content .= $c;
|
||||
}
|
||||
self::writeCacheFile($cache, '<?php '.$content);
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds brackets around each namespace if it's not already the case.
|
||||
*
|
||||
* @param string $source Namespace string
|
||||
*
|
||||
* @return string Namespaces with brackets
|
||||
*/
|
||||
public static function fixNamespaceDeclarations($source)
|
||||
{
|
||||
if (!function_exists('token_get_all') || !self::$useTokenizer) {
|
||||
if (preg_match('/(^|\s)namespace(.*?)\s*;/', $source)) {
|
||||
$source = preg_replace('/(^|\s)namespace(.*?)\s*;/', "$1namespace$2\n{", $source)."}\n";
|
||||
}
|
||||
|
||||
return $source;
|
||||
}
|
||||
|
||||
$rawChunk = '';
|
||||
$output = '';
|
||||
$inNamespace = false;
|
||||
$tokens = token_get_all($source);
|
||||
|
||||
for ($i = 0; isset($tokens[$i]); ++$i) {
|
||||
$token = $tokens[$i];
|
||||
if (!isset($token[1]) || 'b"' === $token) {
|
||||
$rawChunk .= $token;
|
||||
} elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
|
||||
// strip comments
|
||||
continue;
|
||||
} elseif (T_NAMESPACE === $token[0]) {
|
||||
if ($inNamespace) {
|
||||
$rawChunk .= "}\n";
|
||||
}
|
||||
$rawChunk .= $token[1];
|
||||
|
||||
// namespace name and whitespaces
|
||||
while (isset($tokens[++$i][1]) && in_array($tokens[$i][0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) {
|
||||
$rawChunk .= $tokens[$i][1];
|
||||
}
|
||||
if ('{' === $tokens[$i]) {
|
||||
$inNamespace = false;
|
||||
--$i;
|
||||
} else {
|
||||
$rawChunk = rtrim($rawChunk)."\n{";
|
||||
$inNamespace = true;
|
||||
}
|
||||
} elseif (T_START_HEREDOC === $token[0]) {
|
||||
$output .= self::compressCode($rawChunk).$token[1];
|
||||
do {
|
||||
$token = $tokens[++$i];
|
||||
$output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token;
|
||||
} while ($token[0] !== T_END_HEREDOC);
|
||||
$output .= "\n";
|
||||
$rawChunk = '';
|
||||
} elseif (T_CONSTANT_ENCAPSED_STRING === $token[0]) {
|
||||
$output .= self::compressCode($rawChunk).$token[1];
|
||||
$rawChunk = '';
|
||||
} else {
|
||||
$rawChunk .= $token[1];
|
||||
}
|
||||
}
|
||||
|
||||
if ($inNamespace) {
|
||||
$rawChunk .= "}\n";
|
||||
}
|
||||
|
||||
$output .= self::compressCode($rawChunk);
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
|
||||
unset($tokens, $rawChunk);
|
||||
gc_mem_caches();
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only useful for testing.
|
||||
*/
|
||||
public static function enableTokenizer($bool)
|
||||
{
|
||||
self::$useTokenizer = (bool) $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips leading & trailing ws, multiple EOL, multiple ws.
|
||||
*
|
||||
* @param string $code Original PHP code
|
||||
*
|
||||
* @return string compressed code
|
||||
*/
|
||||
private static function compressCode($code)
|
||||
{
|
||||
return preg_replace(
|
||||
array('/^\s+/m', '/\s+$/m', '/([\n\r]+ *[\n\r]+)+/', '/[ \t]+/'),
|
||||
array('', '', "\n", ' '),
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a cache file.
|
||||
*
|
||||
* @param string $file Filename
|
||||
* @param string $content Temporary file content
|
||||
*
|
||||
* @throws \RuntimeException when a cache file cannot be written
|
||||
*/
|
||||
private static function writeCacheFile($file, $content)
|
||||
{
|
||||
$dir = dirname($file);
|
||||
if (!is_writable($dir)) {
|
||||
throw new \RuntimeException(sprintf('Cache directory "%s" is not writable.', $dir));
|
||||
}
|
||||
|
||||
$tmpFile = tempnam($dir, basename($file));
|
||||
|
||||
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
|
||||
@chmod($file, 0666 & ~umask());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an ordered array of passed classes including all their dependencies.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return \ReflectionClass[] An array of sorted \ReflectionClass instances (dependencies added if needed)
|
||||
*
|
||||
* @throws \InvalidArgumentException When a class can't be loaded
|
||||
*/
|
||||
private static function getOrderedClasses(array $classes)
|
||||
{
|
||||
$map = array();
|
||||
self::$seen = array();
|
||||
foreach ($classes as $class) {
|
||||
try {
|
||||
$reflectionClass = new \ReflectionClass($class);
|
||||
} catch (\ReflectionException $e) {
|
||||
throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class));
|
||||
}
|
||||
|
||||
$map = array_merge($map, self::getClassHierarchy($reflectionClass));
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
private static function getClassHierarchy(\ReflectionClass $class)
|
||||
{
|
||||
if (isset(self::$seen[$class->getName()])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
self::$seen[$class->getName()] = true;
|
||||
|
||||
$classes = array($class);
|
||||
$parent = $class;
|
||||
while (($parent = $parent->getParentClass()) && $parent->isUserDefined() && !isset(self::$seen[$parent->getName()])) {
|
||||
self::$seen[$parent->getName()] = true;
|
||||
|
||||
array_unshift($classes, $parent);
|
||||
}
|
||||
|
||||
$traits = array();
|
||||
|
||||
foreach ($classes as $c) {
|
||||
foreach (self::resolveDependencies(self::computeTraitDeps($c), $c) as $trait) {
|
||||
if ($trait !== $c) {
|
||||
$traits[] = $trait;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge(self::getInterfaces($class), $traits, $classes);
|
||||
}
|
||||
|
||||
private static function getInterfaces(\ReflectionClass $class)
|
||||
{
|
||||
$classes = array();
|
||||
|
||||
foreach ($class->getInterfaces() as $interface) {
|
||||
$classes = array_merge($classes, self::getInterfaces($interface));
|
||||
}
|
||||
|
||||
if ($class->isUserDefined() && $class->isInterface() && !isset(self::$seen[$class->getName()])) {
|
||||
self::$seen[$class->getName()] = true;
|
||||
|
||||
$classes[] = $class;
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
private static function computeTraitDeps(\ReflectionClass $class)
|
||||
{
|
||||
$traits = $class->getTraits();
|
||||
$deps = array($class->getName() => $traits);
|
||||
while ($trait = array_pop($traits)) {
|
||||
if ($trait->isUserDefined() && !isset(self::$seen[$trait->getName()])) {
|
||||
self::$seen[$trait->getName()] = true;
|
||||
$traitDeps = $trait->getTraits();
|
||||
$deps[$trait->getName()] = $traitDeps;
|
||||
$traits = array_merge($traits, $traitDeps);
|
||||
}
|
||||
}
|
||||
|
||||
return $deps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependencies resolution.
|
||||
*
|
||||
* This function does not check for circular dependencies as it should never
|
||||
* occur with PHP traits.
|
||||
*
|
||||
* @param array $tree The dependency tree
|
||||
* @param \ReflectionClass $node The node
|
||||
* @param \ArrayObject $resolved An array of already resolved dependencies
|
||||
* @param \ArrayObject $unresolved An array of dependencies to be resolved
|
||||
*
|
||||
* @return \ArrayObject The dependencies for the given node
|
||||
*
|
||||
* @throws \RuntimeException if a circular dependency is detected
|
||||
*/
|
||||
private static function resolveDependencies(array $tree, $node, \ArrayObject $resolved = null, \ArrayObject $unresolved = null)
|
||||
{
|
||||
if (null === $resolved) {
|
||||
$resolved = new \ArrayObject();
|
||||
}
|
||||
if (null === $unresolved) {
|
||||
$unresolved = new \ArrayObject();
|
||||
}
|
||||
$nodeName = $node->getName();
|
||||
|
||||
if (isset($tree[$nodeName])) {
|
||||
$unresolved[$nodeName] = $node;
|
||||
foreach ($tree[$nodeName] as $dependency) {
|
||||
if (!$resolved->offsetExists($dependency->getName())) {
|
||||
self::resolveDependencies($tree, $dependency, $resolved, $unresolved);
|
||||
}
|
||||
}
|
||||
$resolved[$nodeName] = $node;
|
||||
unset($unresolved[$nodeName]);
|
||||
}
|
||||
|
||||
return $resolved;
|
||||
}
|
||||
}
|
@ -1,319 +0,0 @@
|
||||
<?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\ClassLoader\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\ClassLoader\ClassCollectionLoader;
|
||||
use Symfony\Component\ClassLoader\Tests\Fixtures\DeclaredClass;
|
||||
use Symfony\Component\ClassLoader\Tests\Fixtures\WarmedClass;
|
||||
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/GInterface.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/CInterface.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/B.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/A.php';
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
class ClassCollectionLoaderTest extends TestCase
|
||||
{
|
||||
public function testTraitDependencies()
|
||||
{
|
||||
require_once __DIR__.'/Fixtures/deps/traits.php';
|
||||
|
||||
$r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke(null, array('CTFoo'));
|
||||
|
||||
$this->assertEquals(
|
||||
array('TD', 'TC', 'TB', 'TA', 'TZ', 'CTFoo'),
|
||||
array_map(function ($class) { return $class->getName(); }, $ordered)
|
||||
);
|
||||
|
||||
$ordered = $m->invoke(null, array('CTBar'));
|
||||
|
||||
$this->assertEquals(
|
||||
array('TD', 'TZ', 'TC', 'TB', 'TA', 'CTBar'),
|
||||
array_map(function ($class) { return $class->getName(); }, $ordered)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getDifferentOrders
|
||||
*/
|
||||
public function testClassReordering(array $classes)
|
||||
{
|
||||
$expected = array(
|
||||
'ClassesWithParents\\GInterface',
|
||||
'ClassesWithParents\\CInterface',
|
||||
'ClassesWithParents\\B',
|
||||
'ClassesWithParents\\A',
|
||||
);
|
||||
|
||||
$r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke(null, $classes);
|
||||
|
||||
$this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
|
||||
}
|
||||
|
||||
public function getDifferentOrders()
|
||||
{
|
||||
return array(
|
||||
array(array(
|
||||
'ClassesWithParents\\A',
|
||||
'ClassesWithParents\\CInterface',
|
||||
'ClassesWithParents\\GInterface',
|
||||
'ClassesWithParents\\B',
|
||||
)),
|
||||
array(array(
|
||||
'ClassesWithParents\\B',
|
||||
'ClassesWithParents\\A',
|
||||
'ClassesWithParents\\CInterface',
|
||||
)),
|
||||
array(array(
|
||||
'ClassesWithParents\\CInterface',
|
||||
'ClassesWithParents\\B',
|
||||
'ClassesWithParents\\A',
|
||||
)),
|
||||
array(array(
|
||||
'ClassesWithParents\\A',
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getDifferentOrdersForTraits
|
||||
*/
|
||||
public function testClassWithTraitsReordering(array $classes)
|
||||
{
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/ATrait.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/BTrait.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/CTrait.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/D.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/E.php';
|
||||
|
||||
$expected = array(
|
||||
'ClassesWithParents\\GInterface',
|
||||
'ClassesWithParents\\CInterface',
|
||||
'ClassesWithParents\\ATrait',
|
||||
'ClassesWithParents\\BTrait',
|
||||
'ClassesWithParents\\CTrait',
|
||||
'ClassesWithParents\\B',
|
||||
'ClassesWithParents\\A',
|
||||
'ClassesWithParents\\D',
|
||||
'ClassesWithParents\\E',
|
||||
);
|
||||
|
||||
$r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke(null, $classes);
|
||||
|
||||
$this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
|
||||
}
|
||||
|
||||
public function getDifferentOrdersForTraits()
|
||||
{
|
||||
return array(
|
||||
array(array(
|
||||
'ClassesWithParents\\E',
|
||||
'ClassesWithParents\\ATrait',
|
||||
)),
|
||||
array(array(
|
||||
'ClassesWithParents\\E',
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
public function testFixClassWithTraitsOrdering()
|
||||
{
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/CTrait.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/F.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/G.php';
|
||||
|
||||
$classes = array(
|
||||
'ClassesWithParents\\F',
|
||||
'ClassesWithParents\\G',
|
||||
);
|
||||
|
||||
$expected = array(
|
||||
'ClassesWithParents\\CTrait',
|
||||
'ClassesWithParents\\F',
|
||||
'ClassesWithParents\\G',
|
||||
);
|
||||
|
||||
$r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke(null, $classes);
|
||||
|
||||
$this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getFixNamespaceDeclarationsData
|
||||
*/
|
||||
public function testFixNamespaceDeclarations($source, $expected)
|
||||
{
|
||||
$this->assertEquals('<?php '.$expected, ClassCollectionLoader::fixNamespaceDeclarations('<?php '.$source));
|
||||
}
|
||||
|
||||
public function getFixNamespaceDeclarationsData()
|
||||
{
|
||||
return array(
|
||||
array("namespace;\nclass Foo {}\n", "namespace\n{\nclass Foo {}\n}"),
|
||||
array("namespace Foo;\nclass Foo {}\n", "namespace Foo\n{\nclass Foo {}\n}"),
|
||||
array("namespace Bar ;\nclass Foo {}\n", "namespace Bar\n{\nclass Foo {}\n}"),
|
||||
array("namespace Foo\Bar;\nclass Foo {}\n", "namespace Foo\Bar\n{\nclass Foo {}\n}"),
|
||||
array("namespace Foo\Bar\Bar\n{\nclass Foo {}\n}\n", "namespace Foo\Bar\Bar\n{\nclass Foo {}\n}"),
|
||||
array("namespace\n{\nclass Foo {}\n}\n", "namespace\n{\nclass Foo {}\n}"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getFixNamespaceDeclarationsDataWithoutTokenizer
|
||||
*/
|
||||
public function testFixNamespaceDeclarationsWithoutTokenizer($source, $expected)
|
||||
{
|
||||
ClassCollectionLoader::enableTokenizer(false);
|
||||
$this->assertEquals('<?php '.$expected, ClassCollectionLoader::fixNamespaceDeclarations('<?php '.$source));
|
||||
ClassCollectionLoader::enableTokenizer(true);
|
||||
}
|
||||
|
||||
public function getFixNamespaceDeclarationsDataWithoutTokenizer()
|
||||
{
|
||||
return array(
|
||||
array("namespace;\nclass Foo {}\n", "namespace\n{\nclass Foo {}\n}\n"),
|
||||
array("namespace Foo;\nclass Foo {}\n", "namespace Foo\n{\nclass Foo {}\n}\n"),
|
||||
array("namespace Bar ;\nclass Foo {}\n", "namespace Bar\n{\nclass Foo {}\n}\n"),
|
||||
array("namespace Foo\Bar;\nclass Foo {}\n", "namespace Foo\Bar\n{\nclass Foo {}\n}\n"),
|
||||
array("namespace Foo\Bar\Bar\n{\nclass Foo {}\n}\n", "namespace Foo\Bar\Bar\n{\nclass Foo {}\n}\n"),
|
||||
array("\nnamespace\n{\nclass Foo {}\n\$namespace=123;}\n", "\nnamespace\n{\nclass Foo {}\n\$namespace=123;}\n"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testUnableToLoadClassException()
|
||||
{
|
||||
if (is_file($file = sys_get_temp_dir().'/foo.php')) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
ClassCollectionLoader::load(array('SomeNotExistingClass'), sys_get_temp_dir(), 'foo', false);
|
||||
}
|
||||
|
||||
public function testCommentStripping()
|
||||
{
|
||||
if (is_file($file = __DIR__.'/bar.php')) {
|
||||
unlink($file);
|
||||
}
|
||||
spl_autoload_register($r = function ($class) {
|
||||
if (0 === strpos($class, 'Namespaced') || 0 === strpos($class, 'Pearlike_')) {
|
||||
@require_once __DIR__.'/Fixtures/'.str_replace(array('\\', '_'), '/', $class).'.php';
|
||||
}
|
||||
});
|
||||
|
||||
$strictTypes = defined('HHVM_VERSION') ? '' : "\nnamespace {require __DIR__.'/Fixtures/Namespaced/WithStrictTypes.php';}";
|
||||
|
||||
ClassCollectionLoader::load(
|
||||
array('Namespaced\\WithComments', 'Pearlike_WithComments', 'Namespaced\\WithDirMagic', 'Namespaced\\WithFileMagic', 'Namespaced\\WithHaltCompiler', $strictTypes ? 'Namespaced\\WithStrictTypes' : 'Namespaced\\WithComments'),
|
||||
__DIR__,
|
||||
'bar',
|
||||
false
|
||||
);
|
||||
|
||||
spl_autoload_unregister($r);
|
||||
|
||||
$this->assertEquals(<<<'EOF'
|
||||
namespace Namespaced
|
||||
{
|
||||
class WithComments
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
$string ='string should not be modified {$string}';
|
||||
$heredoc = (<<<HD
|
||||
|
||||
|
||||
Heredoc should not be modified {$string}
|
||||
|
||||
|
||||
HD
|
||||
);
|
||||
$nowdoc =<<<'ND'
|
||||
|
||||
|
||||
Nowdoc should not be modified {$string}
|
||||
|
||||
|
||||
ND
|
||||
;
|
||||
}
|
||||
namespace
|
||||
{
|
||||
class Pearlike_WithComments
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
}
|
||||
namespace {require __DIR__.'/Fixtures/Namespaced/WithDirMagic.php';}
|
||||
namespace {require __DIR__.'/Fixtures/Namespaced/WithFileMagic.php';}
|
||||
namespace {require __DIR__.'/Fixtures/Namespaced/WithHaltCompiler.php';}
|
||||
EOF
|
||||
.$strictTypes,
|
||||
str_replace(array("<?php \n", '\\\\'), array('', '/'), file_get_contents($file))
|
||||
);
|
||||
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
public function testInline()
|
||||
{
|
||||
$this->assertTrue(class_exists(WarmedClass::class, true));
|
||||
|
||||
@unlink($cache = sys_get_temp_dir().'/inline.php');
|
||||
|
||||
$classes = array(WarmedClass::class);
|
||||
$excluded = array(DeclaredClass::class);
|
||||
|
||||
ClassCollectionLoader::inline($classes, $cache, $excluded);
|
||||
|
||||
$this->assertSame(<<<'EOTXT'
|
||||
<?php
|
||||
namespace Symfony\Component\ClassLoader\Tests\Fixtures
|
||||
{
|
||||
interface WarmedInterface
|
||||
{
|
||||
}
|
||||
}
|
||||
namespace Symfony\Component\ClassLoader\Tests\Fixtures
|
||||
{
|
||||
class WarmedClass extends DeclaredClass implements WarmedInterface
|
||||
{
|
||||
}
|
||||
}
|
||||
EOTXT
|
||||
, file_get_contents($cache)
|
||||
);
|
||||
|
||||
unlink($cache);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
class A extends B
|
||||
{
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
trait ATrait
|
||||
{
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
class B implements CInterface
|
||||
{
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
trait BTrait
|
||||
{
|
||||
use ATrait;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
interface CInterface extends GInterface
|
||||
{
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
trait CTrait
|
||||
{
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
class D extends A
|
||||
{
|
||||
use BTrait;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
class E extends D
|
||||
{
|
||||
use CTrait;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
class F
|
||||
{
|
||||
use CTrait;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
class G
|
||||
{
|
||||
use CTrait;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ClassesWithParents;
|
||||
|
||||
interface GInterface
|
||||
{
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
trait TD
|
||||
{
|
||||
}
|
||||
|
||||
trait TZ
|
||||
{
|
||||
use TD;
|
||||
}
|
||||
|
||||
trait TC
|
||||
{
|
||||
use TD;
|
||||
}
|
||||
|
||||
trait TB
|
||||
{
|
||||
use TC;
|
||||
}
|
||||
|
||||
trait TA
|
||||
{
|
||||
use TB;
|
||||
}
|
||||
|
||||
class CTFoo
|
||||
{
|
||||
use TA;
|
||||
use TZ;
|
||||
}
|
||||
|
||||
class CTBar
|
||||
{
|
||||
use TZ;
|
||||
use TA;
|
||||
}
|
@ -10,6 +10,8 @@ CHANGELOG
|
||||
* removed the `argument_resolver` service dependency from the `debug.controller_resolver`
|
||||
* removed `LazyLoadingFragmentHandler::addRendererService()`
|
||||
* removed `Psr6CacheClearer::addPool()`
|
||||
* removed `Extension::addClassesToCompile()` and `Extension::getClassesToCompile()`
|
||||
* removed `Kernel::loadClassCache()`, `Kernel::doLoadClassCache()` and `Kernel::setClassCache()`
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
@ -36,23 +36,15 @@ class AddAnnotatedClassesToCachePass implements CompilerPassInterface
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
<?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;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\AddClassesToCachePass class is deprecated since version 3.3 and will be removed in 4.0.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Sets the classes to compile in the cache for the container.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
class AddClassesToCachePass extends AddAnnotatedClassesToCachePass
|
||||
{
|
||||
}
|
@ -20,19 +20,8 @@ use Symfony\Component\DependencyInjection\Extension\Extension as BaseExtension;
|
||||
*/
|
||||
abstract class Extension extends BaseExtension
|
||||
{
|
||||
private $classes = array();
|
||||
private $annotatedClasses = array();
|
||||
|
||||
/**
|
||||
* Gets the classes to cache.
|
||||
*
|
||||
* @return array An array of classes
|
||||
*/
|
||||
public function getClassesToCompile()
|
||||
{
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annotated classes to cache.
|
||||
*
|
||||
@ -43,22 +32,6 @@ abstract class Extension extends BaseExtension
|
||||
return $this->annotatedClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds classes to the class cache.
|
||||
*
|
||||
* @param array $classes An array of class patterns
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function addClassesToCompile(array $classes)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
@trigger_error(__METHOD__.'() is deprecated since version 3.3, to be removed in 4.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->classes = array_merge($this->classes, $classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds annotated classes to the class cache.
|
||||
*
|
||||
|
@ -33,7 +33,6 @@ use Symfony\Component\Config\Loader\GlobFileLoader;
|
||||
use Symfony\Component\Config\Loader\LoaderResolver;
|
||||
use Symfony\Component\Config\Loader\DelegatingLoader;
|
||||
use Symfony\Component\Config\ConfigCache;
|
||||
use Symfony\Component\ClassLoader\ClassCollectionLoader;
|
||||
|
||||
/**
|
||||
* The Kernel is the heart of the Symfony system.
|
||||
@ -57,7 +56,6 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
protected $booted = false;
|
||||
protected $name;
|
||||
protected $startTime;
|
||||
protected $loadClassCache;
|
||||
|
||||
private $projectDir;
|
||||
|
||||
@ -109,10 +107,6 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->loadClassCache) {
|
||||
$this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]);
|
||||
}
|
||||
|
||||
// init bundles
|
||||
$this->initializeBundles();
|
||||
|
||||
@ -339,43 +333,6 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the PHP class cache.
|
||||
*
|
||||
* This methods only registers the fact that you want to load the cache classes.
|
||||
* The cache will actually only be loaded when the Kernel is booted.
|
||||
*
|
||||
* That optimization is mainly useful when using the HttpCache class in which
|
||||
* case the class cache is not loaded if the Response is in the cache.
|
||||
*
|
||||
* @param string $name The cache name prefix
|
||||
* @param string $extension File extension of the resulting file
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function loadClassCache($name = 'classes', $extension = '.php')
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
@trigger_error(__METHOD__.'() is deprecated since version 3.3, to be removed in 4.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->loadClassCache = array($name, $extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function setClassCache(array $classes)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
@trigger_error(__METHOD__.'() is deprecated since version 3.3, to be removed in 4.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
file_put_contents($this->getCacheDir().'/classes.map', sprintf('<?php return %s;', var_export($classes, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@ -416,20 +373,6 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
protected function doLoadClassCache($name, $extension)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
@trigger_error(__METHOD__.'() is deprecated since version 3.3, to be removed in 4.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!$this->booted && is_file($this->getCacheDir().'/classes.map')) {
|
||||
ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the data structures related to the bundle management.
|
||||
*
|
||||
|
@ -87,20 +87,6 @@ class KernelTest extends TestCase
|
||||
$this->assertTrue($kernel->isBooted());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testClassCacheIsLoaded()
|
||||
{
|
||||
$kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
|
||||
$kernel->loadClassCache('name', '.extension');
|
||||
$kernel->expects($this->once())
|
||||
->method('doLoadClassCache')
|
||||
->with('name', '.extension');
|
||||
|
||||
$kernel->boot();
|
||||
}
|
||||
|
||||
public function testClassCacheIsNotLoadedByDefault()
|
||||
{
|
||||
$kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
|
||||
@ -110,17 +96,6 @@ class KernelTest extends TestCase
|
||||
$kernel->boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testClassCacheIsNotLoadedWhenKernelIsNotBooted()
|
||||
{
|
||||
$kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
|
||||
$kernel->loadClassCache();
|
||||
$kernel->expects($this->never())
|
||||
->method('doLoadClassCache');
|
||||
}
|
||||
|
||||
public function testEnvParametersResourceIsAdded()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
Reference in New Issue
Block a user