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

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 $listeners = [];
  28.     private $subscribers;
  29.     private $initialized = [];
  30.     private $initializedSubscribers false;
  31.     private $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.      * @return void
  45.      */
  46.     public function dispatchEvent($eventNameEventArgs $eventArgs null)
  47.     {
  48.         if (!$this->initializedSubscribers) {
  49.             $this->initializeSubscribers();
  50.         }
  51.         if (!isset($this->listeners[$eventName])) {
  52.             return;
  53.         }
  54.         $eventArgs $eventArgs ?? EventArgs::getEmptyInstance();
  55.         if (!isset($this->initialized[$eventName])) {
  56.             $this->initializeListeners($eventName);
  57.         }
  58.         foreach ($this->listeners[$eventName] as $hash => $listener) {
  59.             $listener->{$this->methods[$eventName][$hash]}($eventArgs);
  60.         }
  61.     }
  62.     /**
  63.      * {@inheritdoc}
  64.      *
  65.      * @return object[][]
  66.      */
  67.     public function getListeners($event null)
  68.     {
  69.         if (null === $event) {
  70.             return $this->getAllListeners();
  71.         }
  72.         if (!$this->initializedSubscribers) {
  73.             $this->initializeSubscribers();
  74.         }
  75.         if (!isset($this->initialized[$event])) {
  76.             $this->initializeListeners($event);
  77.         }
  78.         return $this->listeners[$event];
  79.     }
  80.     public function getAllListeners(): array
  81.     {
  82.         if (!$this->initializedSubscribers) {
  83.             $this->initializeSubscribers();
  84.         }
  85.         foreach ($this->listeners as $event => $listeners) {
  86.             if (!isset($this->initialized[$event])) {
  87.                 $this->initializeListeners($event);
  88.             }
  89.         }
  90.         return $this->listeners;
  91.     }
  92.     /**
  93.      * {@inheritdoc}
  94.      *
  95.      * @return bool
  96.      */
  97.     public function hasListeners($event)
  98.     {
  99.         if (!$this->initializedSubscribers) {
  100.             $this->initializeSubscribers();
  101.         }
  102.         return isset($this->listeners[$event]) && $this->listeners[$event];
  103.     }
  104.     /**
  105.      * {@inheritdoc}
  106.      *
  107.      * @return void
  108.      */
  109.     public function addEventListener($events$listener)
  110.     {
  111.         if (!$this->initializedSubscribers) {
  112.             $this->initializeSubscribers();
  113.         }
  114.         $hash $this->getHash($listener);
  115.         foreach ((array) $events as $event) {
  116.             // Overrides listener if a previous one was associated already
  117.             // Prevents duplicate listeners on same event (same instance only)
  118.             $this->listeners[$event][$hash] = $listener;
  119.             if (\is_string($listener)) {
  120.                 unset($this->initialized[$event]);
  121.             } else {
  122.                 $this->methods[$event][$hash] = $this->getMethod($listener$event);
  123.             }
  124.         }
  125.     }
  126.     /**
  127.      * {@inheritdoc}
  128.      *
  129.      * @return void
  130.      */
  131.     public function removeEventListener($events$listener)
  132.     {
  133.         if (!$this->initializedSubscribers) {
  134.             $this->initializeSubscribers();
  135.         }
  136.         $hash $this->getHash($listener);
  137.         foreach ((array) $events as $event) {
  138.             // Check if we actually have this listener associated
  139.             if (isset($this->listeners[$event][$hash])) {
  140.                 unset($this->listeners[$event][$hash]);
  141.             }
  142.             if (isset($this->methods[$event][$hash])) {
  143.                 unset($this->methods[$event][$hash]);
  144.             }
  145.         }
  146.     }
  147.     public function addEventSubscriber(EventSubscriber $subscriber): void
  148.     {
  149.         if (!$this->initializedSubscribers) {
  150.             $this->initializeSubscribers();
  151.         }
  152.         parent::addEventSubscriber($subscriber);
  153.     }
  154.     public function removeEventSubscriber(EventSubscriber $subscriber): void
  155.     {
  156.         if (!$this->initializedSubscribers) {
  157.             $this->initializeSubscribers();
  158.         }
  159.         parent::removeEventSubscriber($subscriber);
  160.     }
  161.     private function initializeListeners(string $eventName)
  162.     {
  163.         $this->initialized[$eventName] = true;
  164.         foreach ($this->listeners[$eventName] as $hash => $listener) {
  165.             if (\is_string($listener)) {
  166.                 $this->listeners[$eventName][$hash] = $listener $this->container->get($listener);
  167.                 $this->methods[$eventName][$hash] = $this->getMethod($listener$eventName);
  168.             }
  169.         }
  170.     }
  171.     private function initializeSubscribers()
  172.     {
  173.         $this->initializedSubscribers true;
  174.         foreach ($this->subscribers as $subscriber) {
  175.             if (\is_array($subscriber)) {
  176.                 $this->addEventListener(...$subscriber);
  177.                 continue;
  178.             }
  179.             if (\is_string($subscriber)) {
  180.                 $subscriber $this->container->get($subscriber);
  181.             }
  182.             parent::addEventSubscriber($subscriber);
  183.         }
  184.         $this->subscribers = [];
  185.     }
  186.     /**
  187.      * @param string|object $listener
  188.      */
  189.     private function getHash($listener): string
  190.     {
  191.         if (\is_string($listener)) {
  192.             return '_service_'.$listener;
  193.         }
  194.         return spl_object_hash($listener);
  195.     }
  196.     private function getMethod(object $listenerstring $event): string
  197.     {
  198.         if (!method_exists($listener$event) && method_exists($listener'__invoke')) {
  199.             return '__invoke';
  200.         }
  201.         return $event;
  202.     }
  203. }