vendor/symfony/dependency-injection/Compiler/RegisterAutoconfigureAttributesPass.php line 52

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\DependencyInjection\Compiler;
  11. use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
  12. use Symfony\Component\DependencyInjection\ContainerBuilder;
  13. use Symfony\Component\DependencyInjection\Definition;
  14. use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
  15. /**
  16.  * Reads #[Autoconfigure] attributes on definitions that are autoconfigured
  17.  * and don't have the "container.ignore_attributes" tag.
  18.  *
  19.  * @author Nicolas Grekas <p@tchwork.com>
  20.  */
  21. final class RegisterAutoconfigureAttributesPass implements CompilerPassInterface
  22. {
  23.     private static $registerForAutoconfiguration;
  24.     /**
  25.      * {@inheritdoc}
  26.      */
  27.     public function process(ContainerBuilder $container)
  28.     {
  29.         if (80000 \PHP_VERSION_ID) {
  30.             return;
  31.         }
  32.         foreach ($container->getDefinitions() as $id => $definition) {
  33.             if ($this->accept($definition) && $class $container->getReflectionClass($definition->getClass(), false)) {
  34.                 $this->processClass($container$class);
  35.             }
  36.         }
  37.     }
  38.     public function accept(Definition $definition): bool
  39.     {
  40.         return 80000 <= \PHP_VERSION_ID && $definition->isAutoconfigured() && !$definition->hasTag('container.ignore_attributes');
  41.     }
  42.     public function processClass(ContainerBuilder $container\ReflectionClass $class)
  43.     {
  44.         foreach ($class->getAttributes(Autoconfigure::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
  45.             self::registerForAutoconfiguration($container$class$attribute);
  46.         }
  47.     }
  48.     private static function registerForAutoconfiguration(ContainerBuilder $container\ReflectionClass $class\ReflectionAttribute $attribute)
  49.     {
  50.         if (self::$registerForAutoconfiguration) {
  51.             return (self::$registerForAutoconfiguration)($container$class$attribute);
  52.         }
  53.         $parseDefinitions = new \ReflectionMethod(YamlFileLoader::class, 'parseDefinitions');
  54.         $parseDefinitions->setAccessible(true);
  55.         $yamlLoader $parseDefinitions->getDeclaringClass()->newInstanceWithoutConstructor();
  56.         self::$registerForAutoconfiguration = static function (ContainerBuilder $container\ReflectionClass $class\ReflectionAttribute $attribute) use ($parseDefinitions$yamlLoader) {
  57.             $attribute = (array) $attribute->newInstance();
  58.             foreach ($attribute['tags'] ?? [] as $i => $tag) {
  59.                 if (\is_array($tag) && [0] === array_keys($tag)) {
  60.                     $attribute['tags'][$i] = [$class->name => $tag[0]];
  61.                 }
  62.             }
  63.             $parseDefinitions->invoke(
  64.                 $yamlLoader,
  65.                 [
  66.                     'services' => [
  67.                         '_instanceof' => [
  68.                             $class->name => [$container->registerForAutoconfiguration($class->name)] + $attribute,
  69.                         ],
  70.                     ],
  71.                 ],
  72.                 $class->getFileName(),
  73.                 false
  74.             );
  75.         };
  76.         return (self::$registerForAutoconfiguration)($container$class$attribute);
  77.     }
  78. }