You are here

class ContainerAwareEventDispatcher in Zircon Profile 8

Same name in this branch
  1. 8 vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php \Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher
  2. 8 core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
Same name and namespace in other branches
  1. 8.0 vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php \Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher

Lazily loads listeners and subscribers from the dependency injection container.

@author Fabien Potencier <fabien@symfony.com> @author Bernhard Schussek <bschussek@gmail.com> @author Jordan Alliot <jordan.alliot@gmail.com>

Hierarchy

Expanded class hierarchy of ContainerAwareEventDispatcher

1 file declares its use of ContainerAwareEventDispatcher
ContainerAwareEventDispatcherTest.php in vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php

File

vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php, line 24

Namespace

Symfony\Component\EventDispatcher
View source
class ContainerAwareEventDispatcher extends EventDispatcher {

  /**
   * The container from where services are loaded.
   *
   * @var ContainerInterface
   */
  private $container;

  /**
   * The service IDs of the event listeners and subscribers.
   *
   * @var array
   */
  private $listenerIds = array();

  /**
   * The services registered as listeners.
   *
   * @var array
   */
  private $listeners = array();

  /**
   * Constructor.
   *
   * @param ContainerInterface $container A ContainerInterface instance
   */
  public function __construct(ContainerInterface $container) {
    $this->container = $container;
  }

  /**
   * Adds a service as event listener.
   *
   * @param string $eventName Event for which the listener is added
   * @param array  $callback  The service ID of the listener service & the method
   *                          name that has to be called
   * @param int    $priority  The higher this value, the earlier an event listener
   *                          will be triggered in the chain.
   *                          Defaults to 0.
   *
   * @throws \InvalidArgumentException
   */
  public function addListenerService($eventName, $callback, $priority = 0) {
    if (!is_array($callback) || 2 !== count($callback)) {
      throw new \InvalidArgumentException('Expected an array("service", "method") argument');
    }
    $this->listenerIds[$eventName][] = array(
      $callback[0],
      $callback[1],
      $priority,
    );
  }
  public function removeListener($eventName, $listener) {
    $this
      ->lazyLoad($eventName);
    if (isset($this->listenerIds[$eventName])) {
      foreach ($this->listenerIds[$eventName] as $i => $args) {
        list($serviceId, $method, $priority) = $args;
        $key = $serviceId . '.' . $method;
        if (isset($this->listeners[$eventName][$key]) && $listener === array(
          $this->listeners[$eventName][$key],
          $method,
        )) {
          unset($this->listeners[$eventName][$key]);
          if (empty($this->listeners[$eventName])) {
            unset($this->listeners[$eventName]);
          }
          unset($this->listenerIds[$eventName][$i]);
          if (empty($this->listenerIds[$eventName])) {
            unset($this->listenerIds[$eventName]);
          }
        }
      }
    }
    parent::removeListener($eventName, $listener);
  }

  /**
   * {@inheritdoc}
   */
  public function hasListeners($eventName = null) {
    if (null === $eventName) {
      return (bool) count($this->listenerIds) || (bool) count($this->listeners);
    }
    if (isset($this->listenerIds[$eventName])) {
      return true;
    }
    return parent::hasListeners($eventName);
  }

  /**
   * {@inheritdoc}
   */
  public function getListeners($eventName = null) {
    if (null === $eventName) {
      foreach ($this->listenerIds as $serviceEventName => $args) {
        $this
          ->lazyLoad($serviceEventName);
      }
    }
    else {
      $this
        ->lazyLoad($eventName);
    }
    return parent::getListeners($eventName);
  }

  /**
   * Adds a service as event subscriber.
   *
   * @param string $serviceId The service ID of the subscriber service
   * @param string $class     The service's class name (which must implement EventSubscriberInterface)
   */
  public function addSubscriberService($serviceId, $class) {
    foreach ($class::getSubscribedEvents() as $eventName => $params) {
      if (is_string($params)) {
        $this->listenerIds[$eventName][] = array(
          $serviceId,
          $params,
          0,
        );
      }
      elseif (is_string($params[0])) {
        $this->listenerIds[$eventName][] = array(
          $serviceId,
          $params[0],
          isset($params[1]) ? $params[1] : 0,
        );
      }
      else {
        foreach ($params as $listener) {
          $this->listenerIds[$eventName][] = array(
            $serviceId,
            $listener[0],
            isset($listener[1]) ? $listener[1] : 0,
          );
        }
      }
    }
  }
  public function getContainer() {
    return $this->container;
  }

  /**
   * Lazily loads listeners for this event from the dependency injection
   * container.
   *
   * @param string $eventName The name of the event to dispatch. The name of
   *                          the event is the name of the method that is
   *                          invoked on listeners.
   */
  protected function lazyLoad($eventName) {
    if (isset($this->listenerIds[$eventName])) {
      foreach ($this->listenerIds[$eventName] as $args) {
        list($serviceId, $method, $priority) = $args;
        $listener = $this->container
          ->get($serviceId);
        $key = $serviceId . '.' . $method;
        if (!isset($this->listeners[$eventName][$key])) {
          $this
            ->addListener($eventName, array(
            $listener,
            $method,
          ), $priority);
        }
        elseif ($listener !== $this->listeners[$eventName][$key]) {
          parent::removeListener($eventName, array(
            $this->listeners[$eventName][$key],
            $method,
          ));
          $this
            ->addListener($eventName, array(
            $listener,
            $method,
          ), $priority);
        }
        $this->listeners[$eventName][$key] = $listener;
      }
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ContainerAwareEventDispatcher::$container private property The container from where services are loaded.
ContainerAwareEventDispatcher::$listenerIds private property The service IDs of the event listeners and subscribers.
ContainerAwareEventDispatcher::$listeners private property The services registered as listeners. Overrides EventDispatcher::$listeners
ContainerAwareEventDispatcher::addListenerService public function Adds a service as event listener.
ContainerAwareEventDispatcher::addSubscriberService public function Adds a service as event subscriber.
ContainerAwareEventDispatcher::getContainer public function
ContainerAwareEventDispatcher::getListeners public function Gets the listeners of a specific event or all listeners sorted by descending priority. Overrides EventDispatcher::getListeners
ContainerAwareEventDispatcher::hasListeners public function Checks whether an event has any registered listeners. Overrides EventDispatcher::hasListeners
ContainerAwareEventDispatcher::lazyLoad protected function Lazily loads listeners for this event from the dependency injection container.
ContainerAwareEventDispatcher::removeListener public function Removes an event listener from the specified events. Overrides EventDispatcher::removeListener
ContainerAwareEventDispatcher::__construct public function Constructor.
EventDispatcher::$sorted private property
EventDispatcher::addListener public function Adds an event listener that listens on the specified events. Overrides EventDispatcherInterface::addListener
EventDispatcher::addSubscriber public function Adds an event subscriber. Overrides EventDispatcherInterface::addSubscriber
EventDispatcher::dispatch public function Dispatches an event to all registered listeners. Overrides EventDispatcherInterface::dispatch
EventDispatcher::doDispatch protected function Triggers the listeners of an event.
EventDispatcher::removeSubscriber public function Removes an event subscriber. Overrides EventDispatcherInterface::removeSubscriber
EventDispatcher::sortListeners private function Sorts the internal list of listeners for the given event by priority.