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