vendor/contao/core-bundle/src/Routing/ResponseContext/ResponseContext.php line 94

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of Contao.
  5.  *
  6.  * (c) Leo Feyer
  7.  *
  8.  * @license LGPL-3.0-or-later
  9.  */
  10. namespace Contao\CoreBundle\Routing\ResponseContext;
  11. use Contao\CoreBundle\Event\AbstractResponseContextEvent;
  12. use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
  13. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  14. final class ResponseContext
  15. {
  16.     public const REQUEST_ATTRIBUTE_NAME '_contao_response_context';
  17.     /**
  18.      * @var array
  19.      */
  20.     private $services = [];
  21.     /**
  22.      * @var array
  23.      */
  24.     private $current = [];
  25.     /**
  26.      * @var PartialResponseHeaderBag|null
  27.      */
  28.     private $headerBag;
  29.     public function dispatchEvent(AbstractResponseContextEvent $event): void
  30.     {
  31.         if (!$this->has(EventDispatcherInterface::class)) {
  32.             return;
  33.         }
  34.         $event->setResponseContext($this);
  35.         /** @var EventDispatcherInterface $eventDispatcher */
  36.         $eventDispatcher $this->get(EventDispatcherInterface::class);
  37.         $eventDispatcher->dispatch($event);
  38.     }
  39.     public function add(object $service): self
  40.     {
  41.         $this->registerService(\get_class($service), $service);
  42.         return $this;
  43.     }
  44.     public function addLazy(string $classname, \Closure $factory null): self
  45.     {
  46.         if (null === $factory) {
  47.             $factory = function () use ($classname) {
  48.                 return new $classname($this);
  49.             };
  50.         }
  51.         $this->registerService($classname$factory);
  52.         return $this;
  53.     }
  54.     public function has(string $serviceId): bool
  55.     {
  56.         return isset($this->current[$serviceId]);
  57.     }
  58.     public function isInitialized(string $serviceId): bool
  59.     {
  60.         if (!$this->has($serviceId)) {
  61.             return false;
  62.         }
  63.         return !$this->services[$serviceId] instanceof \Closure;
  64.     }
  65.     /**
  66.      * @template T
  67.      * @psalm-param class-string<T> $serviceId
  68.      * @psalm-return T
  69.      *
  70.      * @throws ServiceNotFoundException
  71.      *
  72.      * @return object
  73.      */
  74.     public function get(string $serviceId)
  75.     {
  76.         if (!$this->has($serviceId)) {
  77.             throw new \InvalidArgumentException(sprintf('Service "%s" does not exist.'$serviceId));
  78.         }
  79.         $serviceId $this->current[$serviceId];
  80.         // Lazy load the ones with factories
  81.         if (!$this->isInitialized($serviceId)) {
  82.             $service $this->services[$serviceId]();
  83.             $this->services[$serviceId] = $service;
  84.         }
  85.         return $this->services[$serviceId];
  86.     }
  87.     public function getHeaderBag(): PartialResponseHeaderBag
  88.     {
  89.         if (null === $this->headerBag) {
  90.             $this->headerBag = new PartialResponseHeaderBag();
  91.         }
  92.         return $this->headerBag;
  93.     }
  94.     /**
  95.      * @param \Closure|object $objectOrFactory
  96.      */
  97.     private function registerService(string $serviceId$objectOrFactory): void
  98.     {
  99.         $this->services[$serviceId] = $objectOrFactory;
  100.         $this->current[$serviceId] = $serviceId;
  101.         foreach ($this->getAliases($serviceId) as $alias) {
  102.             $this->current[$alias] = $serviceId;
  103.         }
  104.     }
  105.     private function getAliases(string $classname): array
  106.     {
  107.         $aliases = [];
  108.         $ref = new \ReflectionClass($classname);
  109.         // Automatically add aliases for all interfaces and parents (last one added automatically wins by overriding here)
  110.         foreach ($ref->getInterfaceNames() as $interfaceName) {
  111.             $aliases[] = $interfaceName;
  112.         }
  113.         while ($ref $ref->getParentClass()) {
  114.             $aliases[] = $ref->getName();
  115.         }
  116.         return $aliases;
  117.     }
  118. }