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

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