vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php line 183

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\Loader\Configurator;
  11. use Symfony\Component\DependencyInjection\Alias;
  12. use Symfony\Component\DependencyInjection\ChildDefinition;
  13. use Symfony\Component\DependencyInjection\ContainerBuilder;
  14. use Symfony\Component\DependencyInjection\Definition;
  15. use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
  16. use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
  17. use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
  18. /**
  19.  * @author Nicolas Grekas <p@tchwork.com>
  20.  */
  21. class ServicesConfigurator extends AbstractConfigurator
  22. {
  23.     public const FACTORY 'services';
  24.     private $defaults;
  25.     private $container;
  26.     private $loader;
  27.     private $instanceof;
  28.     private $path;
  29.     private $anonymousHash;
  30.     private $anonymousCount;
  31.     public function __construct(ContainerBuilder $containerPhpFileLoader $loader, array &$instanceofstring $path nullint &$anonymousCount 0)
  32.     {
  33.         $this->defaults = new Definition();
  34.         $this->container $container;
  35.         $this->loader $loader;
  36.         $this->instanceof = &$instanceof;
  37.         $this->path $path;
  38.         $this->anonymousHash ContainerBuilder::hash($path ?: mt_rand());
  39.         $this->anonymousCount = &$anonymousCount;
  40.         $instanceof = [];
  41.     }
  42.     /**
  43.      * Defines a set of defaults for following service definitions.
  44.      */
  45.     final public function defaults(): DefaultsConfigurator
  46.     {
  47.         return new DefaultsConfigurator($this$this->defaults = new Definition(), $this->path);
  48.     }
  49.     /**
  50.      * Defines an instanceof-conditional to be applied to following service definitions.
  51.      */
  52.     final public function instanceof(string $fqcn): InstanceofConfigurator
  53.     {
  54.         $this->instanceof[$fqcn] = $definition = new ChildDefinition('');
  55.         return new InstanceofConfigurator($this$definition$fqcn$this->path);
  56.     }
  57.     /**
  58.      * Registers a service.
  59.      *
  60.      * @param string|null $id    The service id, or null to create an anonymous service
  61.      * @param string|null $class The class of the service, or null when $id is also the class name
  62.      */
  63.     final public function set(?string $idstring $class null): ServiceConfigurator
  64.     {
  65.         $defaults $this->defaults;
  66.         $definition = new Definition();
  67.         if (null === $id) {
  68.             if (!$class) {
  69.                 throw new \LogicException('Anonymous services must have a class name.');
  70.             }
  71.             $id sprintf('.%d_%s', ++$this->anonymousCountpreg_replace('/^.*\\\\/'''$class).'~'.$this->anonymousHash);
  72.         } elseif (!$defaults->isPublic() || !$defaults->isPrivate()) {
  73.             $definition->setPublic($defaults->isPublic() && !$defaults->isPrivate());
  74.         }
  75.         $definition->setAutowired($defaults->isAutowired());
  76.         $definition->setAutoconfigured($defaults->isAutoconfigured());
  77.         // deep clone, to avoid multiple process of the same instance in the passes
  78.         $definition->setBindings(unserialize(serialize($defaults->getBindings())));
  79.         $definition->setChanges([]);
  80.         $configurator = new ServiceConfigurator($this->container$this->instanceoftrue$this$definition$id$defaults->getTags(), $this->path);
  81.         return null !== $class $configurator->class($class) : $configurator;
  82.     }
  83.     /**
  84.      * Removes an already defined service definition or alias.
  85.      *
  86.      * @return $this
  87.      */
  88.     final public function remove(string $id): self
  89.     {
  90.         $this->container->removeDefinition($id);
  91.         $this->container->removeAlias($id);
  92.         return $this;
  93.     }
  94.     /**
  95.      * Creates an alias.
  96.      */
  97.     final public function alias(string $idstring $referencedId): AliasConfigurator
  98.     {
  99.         $ref = static::processValue($referencedIdtrue);
  100.         $alias = new Alias((string) $ref);
  101.         if (!$this->defaults->isPublic() || !$this->defaults->isPrivate()) {
  102.             $alias->setPublic($this->defaults->isPublic());
  103.         }
  104.         $this->container->setAlias($id$alias);
  105.         return new AliasConfigurator($this$alias);
  106.     }
  107.     /**
  108.      * Registers a PSR-4 namespace using a glob pattern.
  109.      */
  110.     final public function load(string $namespacestring $resource): PrototypeConfigurator
  111.     {
  112.         return new PrototypeConfigurator($this$this->loader$this->defaults$namespace$resourcetrue);
  113.     }
  114.     /**
  115.      * Gets an already defined service definition.
  116.      *
  117.      * @throws ServiceNotFoundException if the service definition does not exist
  118.      */
  119.     final public function get(string $id): ServiceConfigurator
  120.     {
  121.         $definition $this->container->getDefinition($id);
  122.         return new ServiceConfigurator($this->container$definition->getInstanceofConditionals(), true$this$definition$id, []);
  123.     }
  124.     /**
  125.      * Registers a stack of decorator services.
  126.      *
  127.      * @param InlineServiceConfigurator[]|ReferenceConfigurator[] $services
  128.      */
  129.     final public function stack(string $id, array $services): AliasConfigurator
  130.     {
  131.         foreach ($services as $i => $service) {
  132.             if ($service instanceof InlineServiceConfigurator) {
  133.                 $definition $service->definition->setInstanceofConditionals($this->instanceof);
  134.                 $changes $definition->getChanges();
  135.                 $definition->setAutowired((isset($changes['autowired']) ? $definition $this->defaults)->isAutowired());
  136.                 $definition->setAutoconfigured((isset($changes['autoconfigured']) ? $definition $this->defaults)->isAutoconfigured());
  137.                 $definition->setBindings(array_merge($this->defaults->getBindings(), $definition->getBindings()));
  138.                 $definition->setChanges($changes);
  139.                 $services[$i] = $definition;
  140.             } elseif (!$service instanceof ReferenceConfigurator) {
  141.                 throw new InvalidArgumentException(sprintf('"%s()" expects a list of definitions as returned by "%s()" or "%s()", "%s" given at index "%s" for service "%s".'__METHOD__InlineServiceConfigurator::FACTORYReferenceConfigurator::FACTORY$service instanceof AbstractConfigurator $service::FACTORY.'()' get_debug_type($service), $i$id));
  142.             }
  143.         }
  144.         $alias $this->alias($id'');
  145.         $alias->definition $this->set($id)
  146.             ->parent('')
  147.             ->args($services)
  148.             ->tag('container.stack')
  149.             ->definition;
  150.         return $alias;
  151.     }
  152.     /**
  153.      * Registers a service.
  154.      */
  155.     final public function __invoke(string $idstring $class null): ServiceConfigurator
  156.     {
  157.         return $this->set($id$class);
  158.     }
  159.     public function __destruct()
  160.     {
  161.         $this->loader->registerAliasesForSinglyImplementedInterfaces();
  162.     }
  163. }