vendor/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Component\EventDispatcher;
       
    13 
       
    14 /**
       
    15  * The EventDispatcherInterface is the central point of Symfony's event listener system.
       
    16  *
       
    17  * Listeners are registered on the manager and events are dispatched through the
       
    18  * manager.
       
    19  *
       
    20  * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
       
    21  * @author  Jonathan Wage <jonwage@gmail.com>
       
    22  * @author  Roman Borschel <roman@code-factory.org>
       
    23  * @author  Bernhard Schussek <bschussek@gmail.com>
       
    24  * @author  Fabien Potencier <fabien@symfony.com>
       
    25  * @author  Jordi Boggiano <j.boggiano@seld.be>
       
    26  *
       
    27  * @api
       
    28  */
       
    29 class EventDispatcher implements EventDispatcherInterface
       
    30 {
       
    31     private $listeners = array();
       
    32     private $sorted = array();
       
    33 
       
    34     /**
       
    35      * @see EventDispatcherInterface::dispatch
       
    36      *
       
    37      * @api
       
    38      */
       
    39     public function dispatch($eventName, Event $event = null)
       
    40     {
       
    41         if (!isset($this->listeners[$eventName])) {
       
    42             return;
       
    43         }
       
    44 
       
    45         if (null === $event) {
       
    46             $event = new Event();
       
    47         }
       
    48 
       
    49         $this->doDispatch($this->getListeners($eventName), $eventName, $event);
       
    50     }
       
    51 
       
    52     /**
       
    53      * @see EventDispatcherInterface::getListeners
       
    54      */
       
    55     public function getListeners($eventName = null)
       
    56     {
       
    57         if (null !== $eventName) {
       
    58             if (!isset($this->sorted[$eventName])) {
       
    59                 $this->sortListeners($eventName);
       
    60             }
       
    61 
       
    62             return $this->sorted[$eventName];
       
    63         }
       
    64 
       
    65         foreach (array_keys($this->listeners) as $eventName) {
       
    66             if (!isset($this->sorted[$eventName])) {
       
    67                 $this->sortListeners($eventName);
       
    68             }
       
    69         }
       
    70 
       
    71         return $this->sorted;
       
    72     }
       
    73 
       
    74     /**
       
    75      * @see EventDispatcherInterface::hasListeners
       
    76      */
       
    77     public function hasListeners($eventName = null)
       
    78     {
       
    79         return (Boolean) count($this->getListeners($eventName));
       
    80     }
       
    81 
       
    82     /**
       
    83      * @see EventDispatcherInterface::addListener
       
    84      *
       
    85      * @api
       
    86      */
       
    87     public function addListener($eventName, $listener, $priority = 0)
       
    88     {
       
    89         $this->listeners[$eventName][$priority][] = $listener;
       
    90         unset($this->sorted[$eventName]);
       
    91     }
       
    92 
       
    93     /**
       
    94      * @see EventDispatcherInterface::removeListener
       
    95      */
       
    96     public function removeListener($eventName, $listener)
       
    97     {
       
    98         if (!isset($this->listeners[$eventName])) {
       
    99             return;
       
   100         }
       
   101 
       
   102         foreach ($this->listeners[$eventName] as $priority => $listeners) {
       
   103             if (false !== ($key = array_search($listener, $listeners))) {
       
   104                 unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
       
   105             }
       
   106         }
       
   107     }
       
   108 
       
   109     /**
       
   110      * @see EventDispatcherInterface::addSubscriber
       
   111      *
       
   112      * @api
       
   113      */
       
   114     public function addSubscriber(EventSubscriberInterface $subscriber)
       
   115     {
       
   116         foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
       
   117             if (is_string($params)) {
       
   118                 $this->addListener($eventName, array($subscriber, $params));
       
   119             } else {
       
   120                 $this->addListener($eventName, array($subscriber, $params[0]), $params[1]);
       
   121             }
       
   122         }
       
   123     }
       
   124 
       
   125     /**
       
   126      * @see EventDispatcherInterface::removeSubscriber
       
   127      */
       
   128     public function removeSubscriber(EventSubscriberInterface $subscriber)
       
   129     {
       
   130         foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
       
   131             $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0]));
       
   132         }
       
   133     }
       
   134 
       
   135     /**
       
   136      * Triggers the listeners of an event.
       
   137      *
       
   138      * This method can be overridden to add functionality that is executed
       
   139      * for each listener.
       
   140      *
       
   141      * @param array[callback] $listeners The event listeners.
       
   142      * @param string $eventName The name of the event to dispatch.
       
   143      * @param Event $event The event object to pass to the event handlers/listeners.
       
   144      */
       
   145     protected function doDispatch($listeners, $eventName, Event $event)
       
   146     {
       
   147         foreach ($listeners as $listener) {
       
   148             call_user_func($listener, $event);
       
   149             if ($event->isPropagationStopped()) {
       
   150                 break;
       
   151             }
       
   152         }
       
   153     }
       
   154 
       
   155     /**
       
   156      * Sorts the internal list of listeners for the given event by priority.
       
   157      *
       
   158      * @param string $eventName The name of the event.
       
   159      */
       
   160     private function sortListeners($eventName)
       
   161     {
       
   162         $this->sorted[$eventName] = array();
       
   163 
       
   164         if (isset($this->listeners[$eventName])) {
       
   165             krsort($this->listeners[$eventName]);
       
   166             $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
       
   167         }
       
   168     }
       
   169 }