Yaffs site version 1.1
[yaffs-website] / vendor / symfony / event-dispatcher / EventDispatcher.php
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  * @author Jordan Alliot <jordan.alliot@gmail.com>
27  */
28 class EventDispatcher implements EventDispatcherInterface
29 {
30     private $listeners = array();
31     private $sorted = array();
32
33     /**
34      * {@inheritdoc}
35      */
36     public function dispatch($eventName, Event $event = null)
37     {
38         if (null === $event) {
39             $event = new Event();
40         }
41
42         $event->setDispatcher($this);
43         $event->setName($eventName);
44
45         if ($listeners = $this->getListeners($eventName)) {
46             $this->doDispatch($listeners, $eventName, $event);
47         }
48
49         return $event;
50     }
51
52     /**
53      * {@inheritdoc}
54      */
55     public function getListeners($eventName = null)
56     {
57         if (null !== $eventName) {
58             if (!isset($this->listeners[$eventName])) {
59                 return array();
60             }
61
62             if (!isset($this->sorted[$eventName])) {
63                 $this->sortListeners($eventName);
64             }
65
66             return $this->sorted[$eventName];
67         }
68
69         foreach ($this->listeners as $eventName => $eventListeners) {
70             if (!isset($this->sorted[$eventName])) {
71                 $this->sortListeners($eventName);
72             }
73         }
74
75         return array_filter($this->sorted);
76     }
77
78     /**
79      * Gets the listener priority for a specific event.
80      *
81      * Returns null if the event or the listener does not exist.
82      *
83      * @param string   $eventName The name of the event
84      * @param callable $listener  The listener
85      *
86      * @return int|null The event listener priority
87      */
88     public function getListenerPriority($eventName, $listener)
89     {
90         if (!isset($this->listeners[$eventName])) {
91             return;
92         }
93
94         foreach ($this->listeners[$eventName] as $priority => $listeners) {
95             if (false !== in_array($listener, $listeners, true)) {
96                 return $priority;
97             }
98         }
99     }
100
101     /**
102      * {@inheritdoc}
103      */
104     public function hasListeners($eventName = null)
105     {
106         return (bool) $this->getListeners($eventName);
107     }
108
109     /**
110      * {@inheritdoc}
111      */
112     public function addListener($eventName, $listener, $priority = 0)
113     {
114         $this->listeners[$eventName][$priority][] = $listener;
115         unset($this->sorted[$eventName]);
116     }
117
118     /**
119      * {@inheritdoc}
120      */
121     public function removeListener($eventName, $listener)
122     {
123         if (!isset($this->listeners[$eventName])) {
124             return;
125         }
126
127         foreach ($this->listeners[$eventName] as $priority => $listeners) {
128             if (false !== ($key = array_search($listener, $listeners, true))) {
129                 unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
130             }
131         }
132     }
133
134     /**
135      * {@inheritdoc}
136      */
137     public function addSubscriber(EventSubscriberInterface $subscriber)
138     {
139         foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
140             if (is_string($params)) {
141                 $this->addListener($eventName, array($subscriber, $params));
142             } elseif (is_string($params[0])) {
143                 $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
144             } else {
145                 foreach ($params as $listener) {
146                     $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
147                 }
148             }
149         }
150     }
151
152     /**
153      * {@inheritdoc}
154      */
155     public function removeSubscriber(EventSubscriberInterface $subscriber)
156     {
157         foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
158             if (is_array($params) && is_array($params[0])) {
159                 foreach ($params as $listener) {
160                     $this->removeListener($eventName, array($subscriber, $listener[0]));
161                 }
162             } else {
163                 $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0]));
164             }
165         }
166     }
167
168     /**
169      * Triggers the listeners of an event.
170      *
171      * This method can be overridden to add functionality that is executed
172      * for each listener.
173      *
174      * @param callable[] $listeners The event listeners
175      * @param string     $eventName The name of the event to dispatch
176      * @param Event      $event     The event object to pass to the event handlers/listeners
177      */
178     protected function doDispatch($listeners, $eventName, Event $event)
179     {
180         foreach ($listeners as $listener) {
181             if ($event->isPropagationStopped()) {
182                 break;
183             }
184             call_user_func($listener, $event, $eventName, $this);
185         }
186     }
187
188     /**
189      * Sorts the internal list of listeners for the given event by priority.
190      *
191      * @param string $eventName The name of the event
192      */
193     private function sortListeners($eventName)
194     {
195         krsort($this->listeners[$eventName]);
196         $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
197     }
198 }