vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php line 128

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\Component\EventDispatcher;
  11. use Symfony\Component\DependencyInjection\ContainerInterface;
  12. /**
  13.  * Lazily loads listeners and subscribers from the dependency injection
  14.  * container.
  15.  *
  16.  * @author Fabien Potencier <fabien@symfony.com>
  17.  * @author Bernhard Schussek <bschussek@gmail.com>
  18.  * @author Jordan Alliot <jordan.alliot@gmail.com>
  19.  *
  20.  * @deprecated since 3.3, to be removed in 4.0. Use EventDispatcher with closure factories instead.
  21.  */
  22. class ContainerAwareEventDispatcher extends EventDispatcher
  23. {
  24.     private $container;
  25.     /**
  26.      * The service IDs of the event listeners and subscribers.
  27.      */
  28.     private $listenerIds = [];
  29.     /**
  30.      * The services registered as listeners.
  31.      */
  32.     private $listeners = [];
  33.     public function __construct(ContainerInterface $container)
  34.     {
  35.         $this->container $container;
  36.         $class = \get_class($this);
  37.         if ($this instanceof \PHPUnit_Framework_MockObject_MockObject || $this instanceof \Prophecy\Doubler\DoubleInterface) {
  38.             $class get_parent_class($class);
  39.         }
  40.         if (__CLASS__ !== $class) {
  41.             @trigger_error(sprintf('The %s class is deprecated since Symfony 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.'__CLASS__), E_USER_DEPRECATED);
  42.         }
  43.     }
  44.     /**
  45.      * Adds a service as event listener.
  46.      *
  47.      * @param string $eventName Event for which the listener is added
  48.      * @param array  $callback  The service ID of the listener service & the method
  49.      *                          name that has to be called
  50.      * @param int    $priority  The higher this value, the earlier an event listener
  51.      *                          will be triggered in the chain.
  52.      *                          Defaults to 0.
  53.      *
  54.      * @throws \InvalidArgumentException
  55.      */
  56.     public function addListenerService($eventName$callback$priority 0)
  57.     {
  58.         @trigger_error(sprintf('The %s class is deprecated since Symfony 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.'__CLASS__), E_USER_DEPRECATED);
  59.         if (!\is_array($callback) || !== \count($callback)) {
  60.             throw new \InvalidArgumentException('Expected an ["service", "method"] argument');
  61.         }
  62.         $this->listenerIds[$eventName][] = [$callback[0], $callback[1], $priority];
  63.     }
  64.     public function removeListener($eventName$listener)
  65.     {
  66.         $this->lazyLoad($eventName);
  67.         if (isset($this->listenerIds[$eventName])) {
  68.             foreach ($this->listenerIds[$eventName] as $i => list($serviceId$method)) {
  69.                 $key $serviceId.'.'.$method;
  70.                 if (isset($this->listeners[$eventName][$key]) && $listener === [$this->listeners[$eventName][$key], $method]) {
  71.                     unset($this->listeners[$eventName][$key]);
  72.                     if (empty($this->listeners[$eventName])) {
  73.                         unset($this->listeners[$eventName]);
  74.                     }
  75.                     unset($this->listenerIds[$eventName][$i]);
  76.                     if (empty($this->listenerIds[$eventName])) {
  77.                         unset($this->listenerIds[$eventName]);
  78.                     }
  79.                 }
  80.             }
  81.         }
  82.         parent::removeListener($eventName$listener);
  83.     }
  84.     /**
  85.      * {@inheritdoc}
  86.      */
  87.     public function hasListeners($eventName null)
  88.     {
  89.         if (null === $eventName) {
  90.             return $this->listenerIds || $this->listeners || parent::hasListeners();
  91.         }
  92.         if (isset($this->listenerIds[$eventName])) {
  93.             return true;
  94.         }
  95.         return parent::hasListeners($eventName);
  96.     }
  97.     /**
  98.      * {@inheritdoc}
  99.      */
  100.     public function getListeners($eventName null)
  101.     {
  102.         if (null === $eventName) {
  103.             foreach ($this->listenerIds as $serviceEventName => $args) {
  104.                 $this->lazyLoad($serviceEventName);
  105.             }
  106.         } else {
  107.             $this->lazyLoad($eventName);
  108.         }
  109.         return parent::getListeners($eventName);
  110.     }
  111.     /**
  112.      * {@inheritdoc}
  113.      */
  114.     public function getListenerPriority($eventName$listener)
  115.     {
  116.         $this->lazyLoad($eventName);
  117.         return parent::getListenerPriority($eventName$listener);
  118.     }
  119.     /**
  120.      * Adds a service as event subscriber.
  121.      *
  122.      * @param string $serviceId The service ID of the subscriber service
  123.      * @param string $class     The service's class name (which must implement EventSubscriberInterface)
  124.      */
  125.     public function addSubscriberService($serviceId$class)
  126.     {
  127.         @trigger_error(sprintf('The %s class is deprecated since Symfony 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.'__CLASS__), E_USER_DEPRECATED);
  128.         foreach ($class::getSubscribedEvents() as $eventName => $params) {
  129.             if (\is_string($params)) {
  130.                 $this->listenerIds[$eventName][] = [$serviceId$params0];
  131.             } elseif (\is_string($params[0])) {
  132.                 $this->listenerIds[$eventName][] = [$serviceId$params[0], isset($params[1]) ? $params[1] : 0];
  133.             } else {
  134.                 foreach ($params as $listener) {
  135.                     $this->listenerIds[$eventName][] = [$serviceId$listener[0], isset($listener[1]) ? $listener[1] : 0];
  136.                 }
  137.             }
  138.         }
  139.     }
  140.     public function getContainer()
  141.     {
  142.         @trigger_error('The '.__METHOD__.'() method is deprecated since Symfony 3.3 as its class will be removed in 4.0. Inject the container or the services you need in your listeners/subscribers instead.'E_USER_DEPRECATED);
  143.         return $this->container;
  144.     }
  145.     /**
  146.      * Lazily loads listeners for this event from the dependency injection
  147.      * container.
  148.      *
  149.      * @param string $eventName The name of the event to dispatch. The name of
  150.      *                          the event is the name of the method that is
  151.      *                          invoked on listeners.
  152.      */
  153.     protected function lazyLoad($eventName)
  154.     {
  155.         if (isset($this->listenerIds[$eventName])) {
  156.             foreach ($this->listenerIds[$eventName] as list($serviceId$method$priority)) {
  157.                 $listener $this->container->get($serviceId);
  158.                 $key $serviceId.'.'.$method;
  159.                 if (!isset($this->listeners[$eventName][$key])) {
  160.                     $this->addListener($eventName, [$listener$method], $priority);
  161.                 } elseif ($this->listeners[$eventName][$key] !== $listener) {
  162.                     parent::removeListener($eventName, [$this->listeners[$eventName][$key], $method]);
  163.                     $this->addListener($eventName, [$listener$method], $priority);
  164.                 }
  165.                 $this->listeners[$eventName][$key] = $listener;
  166.             }
  167.         }
  168.     }
  169. }