vendor/symfony/doctrine-bridge/ContainerAwareEventManager.php line 66

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\Bridge\Doctrine;
  11. use Doctrine\Common\EventArgs;
  12. use Doctrine\Common\EventManager;
  13. use Doctrine\Common\EventSubscriber;
  14. use Psr\Container\ContainerInterface;
  15. /**
  16.  * Allows lazy loading of listener and subscriber services.
  17.  *
  18.  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  19.  */
  20. class ContainerAwareEventManager extends EventManager
  21. {
  22.     /**
  23.      * Map of registered listeners.
  24.      *
  25.      * <event> => <listeners>
  26.      */
  27.     private array $listeners = [];
  28.     private array $subscribers;
  29.     private array $initialized = [];
  30.     private bool $initializedSubscribers false;
  31.     private array $methods = [];
  32.     private $container;
  33.     /**
  34.      * @param list<string|EventSubscriber|array{string[], string|object}> $subscriberIds List of subscribers, subscriber ids, or [events, listener] tuples
  35.      */
  36.     public function __construct(ContainerInterface $container, array $subscriberIds = [])
  37.     {
  38.         $this->container $container;
  39.         $this->subscribers $subscriberIds;
  40.     }
  41.     /**
  42.      * {@inheritdoc}
  43.      */
  44.     public function dispatchEvent($eventNameEventArgs $eventArgs null): void
  45.     {
  46.         if (!$this->initializedSubscribers) {
  47.             $this->initializeSubscribers();
  48.         }
  49.         if (!isset($this->listeners[$eventName])) {
  50.             return;
  51.         }
  52.         $eventArgs $eventArgs ?? EventArgs::getEmptyInstance();
  53.         if (!isset($this->initialized[$eventName])) {
  54.             $this->initializeListeners($eventName);
  55.         }
  56.         foreach ($this->listeners[$eventName] as $hash => $listener) {
  57.             $listener->{$this->methods[$eventName][$hash]}($eventArgs);
  58.         }
  59.     }
  60.     /**
  61.      * {@inheritdoc}
  62.      *
  63.      * @return object[][]
  64.      */
  65.     public function getListeners($event null): array
  66.     {
  67.         if (null === $event) {
  68.             return $this->getAllListeners();
  69.         }
  70.         if (!$this->initializedSubscribers) {
  71.             $this->initializeSubscribers();
  72.         }
  73.         if (!isset($this->initialized[$event])) {
  74.             $this->initializeListeners($event);
  75.         }
  76.         return $this->listeners[$event];
  77.     }
  78.     public function getAllListeners(): array
  79.     {
  80.         if (!$this->initializedSubscribers) {
  81.             $this->initializeSubscribers();
  82.         }
  83.         foreach ($this->listeners as $event => $listeners) {
  84.             if (!isset($this->initialized[$event])) {
  85.                 $this->initializeListeners($event);
  86.             }
  87.         }
  88.         return $this->listeners;
  89.     }
  90.     /**
  91.      * {@inheritdoc}
  92.      */
  93.     public function hasListeners($event): bool
  94.     {
  95.         if (!$this->initializedSubscribers) {
  96.             $this->initializeSubscribers();
  97.         }
  98.         return isset($this->listeners[$event]) && $this->listeners[$event];
  99.     }
  100.     /**
  101.      * {@inheritdoc}
  102.      */
  103.     public function addEventListener($events$listener): void
  104.     {
  105.         if (!$this->initializedSubscribers) {
  106.             $this->initializeSubscribers();
  107.         }
  108.         $hash $this->getHash($listener);
  109.         foreach ((array) $events as $event) {
  110.             // Overrides listener if a previous one was associated already
  111.             // Prevents duplicate listeners on same event (same instance only)
  112.             $this->listeners[$event][$hash] = $listener;
  113.             if (\is_string($listener)) {
  114.                 unset($this->initialized[$event]);
  115.             } else {
  116.                 $this->methods[$event][$hash] = $this->getMethod($listener$event);
  117.             }
  118.         }
  119.     }
  120.     /**
  121.      * {@inheritdoc}
  122.      */
  123.     public function removeEventListener($events$listener): void
  124.     {
  125.         if (!$this->initializedSubscribers) {
  126.             $this->initializeSubscribers();
  127.         }
  128.         $hash $this->getHash($listener);
  129.         foreach ((array) $events as $event) {
  130.             // Check if we actually have this listener associated
  131.             if (isset($this->listeners[$event][$hash])) {
  132.                 unset($this->listeners[$event][$hash]);
  133.             }
  134.             if (isset($this->methods[$event][$hash])) {
  135.                 unset($this->methods[$event][$hash]);
  136.             }
  137.         }
  138.     }
  139.     public function addEventSubscriber(EventSubscriber $subscriber): void
  140.     {
  141.         if (!$this->initializedSubscribers) {
  142.             $this->initializeSubscribers();
  143.         }
  144.         parent::addEventSubscriber($subscriber);
  145.     }
  146.     public function removeEventSubscriber(EventSubscriber $subscriber): void
  147.     {
  148.         if (!$this->initializedSubscribers) {
  149.             $this->initializeSubscribers();
  150.         }
  151.         parent::removeEventSubscriber($subscriber);
  152.     }
  153.     private function initializeListeners(string $eventName)
  154.     {
  155.         $this->initialized[$eventName] = true;
  156.         foreach ($this->listeners[$eventName] as $hash => $listener) {
  157.             if (\is_string($listener)) {
  158.                 $this->listeners[$eventName][$hash] = $listener $this->container->get($listener);
  159.                 $this->methods[$eventName][$hash] = $this->getMethod($listener$eventName);
  160.             }
  161.         }
  162.     }
  163.     private function initializeSubscribers()
  164.     {
  165.         $this->initializedSubscribers true;
  166.         foreach ($this->subscribers as $subscriber) {
  167.             if (\is_array($subscriber)) {
  168.                 $this->addEventListener(...$subscriber);
  169.                 continue;
  170.             }
  171.             if (\is_string($subscriber)) {
  172.                 $subscriber $this->container->get($subscriber);
  173.             }
  174.             parent::addEventSubscriber($subscriber);
  175.         }
  176.         $this->subscribers = [];
  177.     }
  178.     private function getHash(string|object $listener): string
  179.     {
  180.         if (\is_string($listener)) {
  181.             return '_service_'.$listener;
  182.         }
  183.         return spl_object_hash($listener);
  184.     }
  185.     private function getMethod(object $listenerstring $event): string
  186.     {
  187.         if (!method_exists($listener$event) && method_exists($listener'__invoke')) {
  188.             return '__invoke';
  189.         }
  190.         return $event;
  191.     }
  192. }