Security update for Core, with self-updated composer
[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         if ($listeners = $this->getListeners($eventName)) {
43             $this->doDispatch($listeners, $eventName, $event);
44         }
45
46         return $event;
47     }
48
49     /**
50      * {@inheritdoc}
51      */
52     public function getListeners($eventName = null)
53     {
54         if (null !== $eventName) {
55             if (!isset($this->listeners[$eventName])) {
56                 return array();
57             }
58
59             if (!isset($this->sorted[$eventName])) {
60                 $this->sortListeners($eventName);
61             }
62
63             return $this->sorted[$eventName];
64         }
65
66         foreach ($this->listeners as $eventName => $eventListeners) {
67             if (!isset($this->sorted[$eventName])) {
68                 $this->sortListeners($eventName);
69             }
70         }
71
72         return array_filter($this->sorted);
73     }
74
75     /**
76      * {@inheritdoc}
77      */
78     public function getListenerPriority($eventName, $listener)
79     {
80         if (!isset($this->listeners[$eventName])) {
81             return;
82         }
83
84         foreach ($this->listeners[$eventName] as $priority => $listeners) {
85             if (false !== in_array($listener, $listeners, true)) {
86                 return $priority;
87             }
88         }
89     }
90
91     /**
92      * {@inheritdoc}
93      */
94     public function hasListeners($eventName = null)
95     {
96         return (bool) $this->getListeners($eventName);
97     }
98
99     /**
100      * {@inheritdoc}
101      */
102     public function addListener($eventName, $listener, $priority = 0)
103     {
104         $this->listeners[$eventName][$priority][] = $listener;
105         unset($this->sorted[$eventName]);
106     }
107
108     /**
109      * {@inheritdoc}
110      */
111     public function removeListener($eventName, $listener)
112     {
113         if (!isset($this->listeners[$eventName])) {
114             return;
115         }
116
117         foreach ($this->listeners[$eventName] as $priority => $listeners) {
118             if (false !== ($key = array_search($listener, $listeners, true))) {
119                 unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
120             }
121         }
122     }
123
124     /**
125      * {@inheritdoc}
126      */
127     public function addSubscriber(EventSubscriberInterface $subscriber)
128     {
129         foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
130             if (is_string($params)) {
131                 $this->addListener($eventName, array($subscriber, $params));
132             } elseif (is_string($params[0])) {
133                 $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
134             } else {
135                 foreach ($params as $listener) {
136                     $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
137                 }
138             }
139         }
140     }
141
142     /**
143      * {@inheritdoc}
144      */
145     public function removeSubscriber(EventSubscriberInterface $subscriber)
146     {
147         foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
148             if (is_array($params) && is_array($params[0])) {
149                 foreach ($params as $listener) {
150                     $this->removeListener($eventName, array($subscriber, $listener[0]));
151                 }
152             } else {
153                 $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0]));
154             }
155         }
156     }
157
158     /**
159      * Triggers the listeners of an event.
160      *
161      * This method can be overridden to add functionality that is executed
162      * for each listener.
163      *
164      * @param callable[] $listeners The event listeners
165      * @param string     $eventName The name of the event to dispatch
166      * @param Event      $event     The event object to pass to the event handlers/listeners
167      */
168     protected function doDispatch($listeners, $eventName, Event $event)
169     {
170         foreach ($listeners as $listener) {
171             if ($event->isPropagationStopped()) {
172                 break;
173             }
174             call_user_func($listener, $event, $eventName, $this);
175         }
176     }
177
178     /**
179      * Sorts the internal list of listeners for the given event by priority.
180      *
181      * @param string $eventName The name of the event
182      */
183     private function sortListeners($eventName)
184     {
185         krsort($this->listeners[$eventName]);
186         $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
187     }
188 }