8000 [DI][Config] Add & use ReflectionClassResource · symfony/symfony@061a58a · GitHub
[go: up one dir, main page]

Skip to content

Commit 061a58a

Browse files
[DI][Config] Add & use ReflectionClassResource
1 parent b9b6ebd commit 061a58a

22 files changed

+641
-155
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
use Symfony\Component\Finder\Finder;
2929
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
3030
use Symfony\Component\Config\FileLocator;
31-
use Symfony\Component\Config\Resource\ClassExistenceResource;
3231
use Symfony\Component\PropertyAccess\PropertyAccessor;
3332
use Symfony\Component\Serializer\Encoder\YamlEncoder;
3433
use Symfony\Component\Serializer\Encoder\CsvEncoder;
@@ -85,8 +84,7 @@ public function load(array $configs, ContainerBuilder $container)
8584

8685
$loader->load('fragment_renderer.xml');
8786

88-
$container->addResource(new ClassExistenceResource(Application::class));
89-
if (class_exists(Application::class)) {
87+
if ($container->getClassExists(Application::class)) {
9088
$loader->load('console.xml');
9189
}
9290

@@ -525,7 +523,7 @@ private function registerDebugConfiguration(array $config, ContainerBuilder $con
525523
$definition->replaceArgument(4, $debug);
526524
$definition->replaceArgument(6, $debug);
527525

528-
if ($debug && class_exists(DebugProcessor::class)) {
526+
if ($debug && $container->getClassExists(DebugProcessor::class)) {
529527
$definition = new Definition(DebugProcessor::class);
530528
$definition->setPublic(false);
531529
$container->setDefinition('debug.log_processor', $definition);
@@ -1251,7 +1249,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
12511249
$container->getDefinition('serializer.mapping.class_metadata_factory')->replaceArgument(
12521250
1, new Reference($config['cache'])
12531251
);
1254-
} elseif (!$container->getParameter('kernel.debug') && class_exists(CacheClassMetadataFactory::class)) {
1252+
} elseif (!$container->getParameter('kernel.debug') && $container->getClassExists(CacheClassMetadataFactory::class)) {
12551253
$cacheMetadataFactory = new Definition(
12561254
CacheClassMetadataFactory::class,
12571255
array(

src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExceptionListenerPass.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

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

14+
use Symfony\Component\Debug\Exception\FlattenException;
1415
use Symfony\Component\DependencyInjection\ContainerBuilder;
1516
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1618

1719
/**
1820
* Registers the Twig exception listener if Twig is registered as a templating engine.
@@ -28,7 +30,7 @@ public function process(ContainerBuilder $container)
2830
}
2931

3032
// register the exception controller only if Twig is enabled and required dependencies do exist
31-
if (!class_exists('Symfony\Component\Debug\Exception\FlattenException') || !interface_exists('Symfony\Component\EventDispatcher\EventSubscriberInterface')) {
33+
if (!$container->getClassExists(FlattenException::class) || !$container->getClassExists(EventSubscriberInterface::class)) {
3234
$container->removeDefinition('twig.exception_listener');
3335
} elseif ($container->hasParameter('templating.engines')) {
3436
$engines = $container->getParameter('templating.engines');

src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111

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

14-
use Symfony\Component\Config\Resource\ClassExistenceResource;
14+
use Symfony\Component\Asset\Packages;
1515
use Symfony\Component\DependencyInjection\Alias;
1616
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1717
use Symfony\Component\DependencyInjection\ContainerBuilder;
1818
use Symfony\Component\DependencyInjection\Reference;
1919
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
20+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
2021
use Symfony\Component\Stopwatch\Stopwatch;
22+
use Symfony\Component\Translation\TranslatorInterface;
2123
use Symfony\Component\Yaml\Parser as YamlParser;
2224

2325
/**
@@ -27,22 +29,23 @@ class ExtensionPass implements CompilerPassInterface
2729
{
2830
public function process(ContainerBuilder $container)
2931
{
30-
if (!class_exists('Symfony\Component\Asset\Packages')) {
32+
if (!$container->getClassExists(Packages::class)) {
3133
$container->removeDefinition('twig.extension.assets');
3234
}
3335

34-
if (!class_exists('Symfony\Component\ExpressionLanguage\Expression')) {
36+
if (!$container->getClassExists(ExpressionLanguage::class)) {
3537
$container->removeDefinition('twig.extension.expression');
3638
}
3739

38-
if (!interface_exists('Symfony\Component\Routing\Generator\UrlGeneratorInterface')) {
40+
if (!$container->getClassExists(UrlGeneratorInterface::class)) {
3941
$container->removeDefinition('twig.extension.routing');
4042
}
41-
if (!interface_exists('Symfony\Component\Translation\TranslatorInterface')) {
43+
44+
if (!$container->getClassExists(TranslatorInterface::class)) {
4245
$container->removeDefinition('twig.extension.trans');
4346
}
4447

45-
if (!class_exists('Symfony\Component\Yaml\Yaml')) {
48+
if (!$container->getClassExists(YamlParser::class)) {
4649
$container->removeDefinition('twig.extension.yaml');
4750
}
4851

@@ -101,18 +104,15 @@ public function process(ContainerBuilder $container)
101104
$container->getDefinition('twig.extension.assets')->addTag('twig.extension');
102105
}
103106

104-
$container->addResource(new ClassExistenceResource(YamlParser::class));
105-
if (class_exists(YamlParser::class)) {
107+
if ($container->hasDefinition('twig.extension.yaml')) {
106108
$container->getDefinition('twig.extension.yaml')->addTag('twig.extension');
107109
}
108110

109-
$container->addResource(new ClassExistenceResource(Stopwatch::class));
110-
if (class_exists(Stopwatch::class)) {
111+
if ($container->getClassExists(Stopwatch::class)) {
111112
$container->getDefinition('twig.extension.debug.stopwatch')->addTag('twig.extension');
112113
}
113114

114-
$container->addResource(new ClassExistenceResource(ExpressionLanguage::class));
115-
if (class_exists(ExpressionLanguage::class)) {
115+
if ($container->hasDefinition('twig.extension.expression')) {
116116
$container->getDefinition('twig.extension.expression')->addTag('twig.extension');
117117
}
118118
}

src/Symfony/Bundle/TwigBundle/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
],
1818
"require": {
1919
"php": ">=5.5.9",
20-
"symfony/config": "~3.2",
20+
"symfony/config": "~3.3",
2121
"symfony/twig-bridge": "^3.2.1",
2222
"symfony/http-foundation": "~2.8|~3.0",
2323
"symfony/http-kernel": "~2.8.16|~3.1.9|^3.2.2",
@@ -26,7 +26,7 @@
2626
"require-dev": {
2727
"symfony/asset": "~2.8|~3.0",
2828
"symfony/stopwatch": "~2.8|~3.0",
29-
"symfony/dependency-injection": "~2.8|~3.0",
29+
"symfony/dependency-injection": "~3.3",
3030
"symfony/expression-language": "~2.8|~3.0",
3131
"symfony/finder": "~2.8|~3.0",
3232
"symfony/form": "~2.8|~3.0",

src/Symfony/Component/Config/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
CHANGELOG
22
=========
33

4+
3.3.0
5+
-----
6+
7+
* added `ReflectionClassResource` class
8+
* added second `$exists` constructor argument to `ClassExistenceResource`
9+
* made `ClassExistenceResource` also work with interfaces and traits
10+
411
3.0.0
512
-----
613

src/Symfony/Component/Config/Resource/ClassExistenceResource.php

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,27 @@
2121
*/
2222
class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializable
2323
{
24+
const EXISTS_OK = 1;
25+
const EXISTS_KO = 0;
26+
const EXISTS_KO_WITH_THROWING_AUTOLOADER = -1;
27+
2428
private $resource;
2529
private $exists;
2630

31+
private static $checkingLevel = 0;
32+
private static $throwingAutoloader;
33+
private static $existsCache = array();
34+
2735
/**
28-
* @param string $resource The fully-qualified class name
36+
* @param string $resource The fully-qualified class name
37+
* @param int|null $exists One of the self::EXISTS_* const if the existency check has already been done
2938
*/
30-
public function __construct($resource)
39+
public function __construct($resource, $exists = null)
3140
{
3241
$this->resource = $resource;
33-
$this->exists = class_exists($resource);
42+
if (null !== $exists) {
43+
$this->exists = (int) $exists;
44+
}
3445
}
3546

3647
/**
@@ -54,14 +65,46 @@ public function getResource()
5465
*/
5566
public function isFresh($timestamp)
5667
{
57-
return class_exists($this->resource) === $this->exists;
68+
if (null !== $exists = &self::$existsCache[$this->resource]) {
69+
$exists = $exists || class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
70+
} elseif (self::EXISTS_KO_WITH_THROWING_AUTOLOADER === $this->exists) {
71+
if (null === self::$throwingAutoloader) {
72+
$signalingException = new \ReflectionException();
73+
self::$throwingAutoloader = function () use ($signalingException) { throw $signalingException; };
74+
}
75+
if (!self::$checkingLevel++) {
76+
spl_autoload_register(self::$throwingAutoloader);
77+
}
78+
79+
try {
80+
$exists = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
81+
} catch (\ReflectionException $e) {
82+
$exists = false;
83+
} finally {
84+
if (!--self::$checkingLevel) {
85+
spl_autoload_unregister(self::$throwingAutoloader);
86+
}
87+
}
88+
} else {
89+
$exists = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
90+
}
91+
92+
if (null === $this->exists) {
93+
$this->exists = $exists ? self::EXISTS_OK : self::EXISTS_KO;
94+
}
95+
96+
return self::EXISTS_OK === $this->exists xor !$exists;
5897
}
5998

6099
/**
61100
* {@inheritdoc}
62101
*/
63102
public function serialize()
64103
{
104+
if (null === $this->exists) {
105+
$this->isFresh(0);
106+
}
107+
65108
return serialize(array($this->resource, $this->exists));
66109
}
67110

src/Symfony/Component/Config/Resource/FileExistenceResource.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ class FileExistenceResource implements SelfCheckingResourceInterface, \Serializa
3333
public function __construct($resource)
3434
{
3535
$this->resource = (string) $resource;
36-
$this->exists = file_exists($resource);
3736
}
3837

3938
/**
@@ -57,6 +56,10 @@ public function getResource()
5756
*/
5857
public function isFresh($timestamp)
5958
{
59+
if (null === $this->exists) {
60+
$this->exists = file_exists($this->resource);
61+
}
62+
6063
return file_exists($this->resource) === $this->exists;
6164
}
6265

@@ -65,6 +68,10 @@ public function isFresh($timestamp)
6568
*/
6669
public function serialize()
6770
{
71+
if (null === $this->exists) {
72+
$this->exists = file_exists($this->resource);
73+
}
74+
6875
return serialize(array($this->resource, $this->exists));
6976
}
7077

0 commit comments

Comments
 (0)
0