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

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.         foreach ($container->getDefinitions() as $id => $definition) {
  30.             if ($this->accept($definition) && $class $container->getReflectionClass($definition->getClass(), false)) {
  31.                 $this->processClass($container$class);
  32.             }
  33.         }
  34.     }
  35.     public function accept(Definition $definition): bool
  36.     {
  37.         return $definition->isAutoconfigured() && !$definition->hasTag('container.ignore_attributes');
  38.     }
  39.     public function processClass(ContainerBuilder $container\ReflectionClass $class)
  40.     {
  41.         foreach ($class->getAttributes(Autoconfigure::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
  42.             self::registerForAutoconfiguration($container$class$attribute);
  43.         }
  44.     }
  45.     private static function registerForAutoconfiguration(ContainerBuilder $container\ReflectionClass $class\ReflectionAttribute $attribute)
  46.     {
  47.         if (self::$registerForAutoconfiguration) {
  48.             return (self::$registerForAutoconfiguration)($container$class$attribute);
  49.         }
  50.         $parseDefinitions = new \ReflectionMethod(YamlFileLoader::class, 'parseDefinitions');
  51.         $yamlLoader $parseDefinitions->getDeclaringClass()->newInstanceWithoutConstructor();
  52.         self::$registerForAutoconfiguration = static function (ContainerBuilder $container\ReflectionClass $class\ReflectionAttribute $attribute) use ($parseDefinitions$yamlLoader) {
  53.             $attribute = (array) $attribute->newInstance();
  54.             foreach ($attribute['tags'] ?? [] as $i => $tag) {
  55.                 if (\is_array($tag) && [0] === array_keys($tag)) {
  56.                     $attribute['tags'][$i] = [$class->name => $tag[0]];
  57.                 }
  58.             }
  59.             $parseDefinitions->invoke(
  60.                 $yamlLoader,
  61.                 [
  62.                     'services' => [
  63.                         '_instanceof' => [
  64.                             $class->name => [$container->registerForAutoconfiguration($class->name)] + $attribute,
  65.                         ],
  66.                     ],
  67.                 ],
  68.                 $class->getFileName(),
  69.                 false
  70.             );
  71.         };
  72.         return (self::$registerForAutoconfiguration)($container$class$attribute);
  73.     }
  74. }