annotate vendor/symfony/event-dispatcher/EventDispatcher.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\EventDispatcher;
Chris@0 13
Chris@0 14 /**
Chris@0 15 * The EventDispatcherInterface is the central point of Symfony's event listener system.
Chris@0 16 *
Chris@0 17 * Listeners are registered on the manager and events are dispatched through the
Chris@0 18 * manager.
Chris@0 19 *
Chris@0 20 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
Chris@0 21 * @author Jonathan Wage <jonwage@gmail.com>
Chris@0 22 * @author Roman Borschel <roman@code-factory.org>
Chris@0 23 * @author Bernhard Schussek <bschussek@gmail.com>
Chris@0 24 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 25 * @author Jordi Boggiano <j.boggiano@seld.be>
Chris@0 26 * @author Jordan Alliot <jordan.alliot@gmail.com>
Chris@14 27 * @author Nicolas Grekas <p@tchwork.com>
Chris@0 28 */
Chris@0 29 class EventDispatcher implements EventDispatcherInterface
Chris@0 30 {
Chris@17 31 private $listeners = [];
Chris@17 32 private $sorted = [];
Chris@0 33
Chris@0 34 /**
Chris@0 35 * {@inheritdoc}
Chris@0 36 */
Chris@0 37 public function dispatch($eventName, Event $event = null)
Chris@0 38 {
Chris@0 39 if (null === $event) {
Chris@0 40 $event = new Event();
Chris@0 41 }
Chris@0 42
Chris@0 43 if ($listeners = $this->getListeners($eventName)) {
Chris@0 44 $this->doDispatch($listeners, $eventName, $event);
Chris@0 45 }
Chris@0 46
Chris@0 47 return $event;
Chris@0 48 }
Chris@0 49
Chris@0 50 /**
Chris@0 51 * {@inheritdoc}
Chris@0 52 */
Chris@0 53 public function getListeners($eventName = null)
Chris@0 54 {
Chris@0 55 if (null !== $eventName) {
Chris@14 56 if (empty($this->listeners[$eventName])) {
Chris@17 57 return [];
Chris@0 58 }
Chris@0 59
Chris@0 60 if (!isset($this->sorted[$eventName])) {
Chris@0 61 $this->sortListeners($eventName);
Chris@0 62 }
Chris@0 63
Chris@0 64 return $this->sorted[$eventName];
Chris@0 65 }
Chris@0 66
Chris@0 67 foreach ($this->listeners as $eventName => $eventListeners) {
Chris@0 68 if (!isset($this->sorted[$eventName])) {
Chris@0 69 $this->sortListeners($eventName);
Chris@0 70 }
Chris@0 71 }
Chris@0 72
Chris@0 73 return array_filter($this->sorted);
Chris@0 74 }
Chris@0 75
Chris@0 76 /**
Chris@0 77 * {@inheritdoc}
Chris@0 78 */
Chris@0 79 public function getListenerPriority($eventName, $listener)
Chris@0 80 {
Chris@14 81 if (empty($this->listeners[$eventName])) {
Chris@0 82 return;
Chris@0 83 }
Chris@0 84
Chris@17 85 if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
Chris@14 86 $listener[0] = $listener[0]();
Chris@14 87 }
Chris@14 88
Chris@0 89 foreach ($this->listeners[$eventName] as $priority => $listeners) {
Chris@14 90 foreach ($listeners as $k => $v) {
Chris@17 91 if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) {
Chris@14 92 $v[0] = $v[0]();
Chris@14 93 $this->listeners[$eventName][$priority][$k] = $v;
Chris@14 94 }
Chris@14 95 if ($v === $listener) {
Chris@14 96 return $priority;
Chris@14 97 }
Chris@0 98 }
Chris@0 99 }
Chris@0 100 }
Chris@0 101
Chris@0 102 /**
Chris@0 103 * {@inheritdoc}
Chris@0 104 */
Chris@0 105 public function hasListeners($eventName = null)
Chris@0 106 {
Chris@14 107 if (null !== $eventName) {
Chris@14 108 return !empty($this->listeners[$eventName]);
Chris@14 109 }
Chris@14 110
Chris@14 111 foreach ($this->listeners as $eventListeners) {
Chris@14 112 if ($eventListeners) {
Chris@14 113 return true;
Chris@14 114 }
Chris@14 115 }
Chris@14 116
Chris@14 117 return false;
Chris@0 118 }
Chris@0 119
Chris@0 120 /**
Chris@0 121 * {@inheritdoc}
Chris@0 122 */
Chris@0 123 public function addListener($eventName, $listener, $priority = 0)
Chris@0 124 {
Chris@0 125 $this->listeners[$eventName][$priority][] = $listener;
Chris@0 126 unset($this->sorted[$eventName]);
Chris@0 127 }
Chris@0 128
Chris@0 129 /**
Chris@0 130 * {@inheritdoc}
Chris@0 131 */
Chris@0 132 public function removeListener($eventName, $listener)
Chris@0 133 {
Chris@14 134 if (empty($this->listeners[$eventName])) {
Chris@0 135 return;
Chris@0 136 }
Chris@0 137
Chris@17 138 if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
Chris@14 139 $listener[0] = $listener[0]();
Chris@14 140 }
Chris@14 141
Chris@0 142 foreach ($this->listeners[$eventName] as $priority => $listeners) {
Chris@14 143 foreach ($listeners as $k => $v) {
Chris@17 144 if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) {
Chris@14 145 $v[0] = $v[0]();
Chris@14 146 }
Chris@14 147 if ($v === $listener) {
Chris@14 148 unset($listeners[$k], $this->sorted[$eventName]);
Chris@14 149 } else {
Chris@14 150 $listeners[$k] = $v;
Chris@14 151 }
Chris@14 152 }
Chris@14 153
Chris@14 154 if ($listeners) {
Chris@14 155 $this->listeners[$eventName][$priority] = $listeners;
Chris@14 156 } else {
Chris@14 157 unset($this->listeners[$eventName][$priority]);
Chris@0 158 }
Chris@0 159 }
Chris@0 160 }
Chris@0 161
Chris@0 162 /**
Chris@0 163 * {@inheritdoc}
Chris@0 164 */
Chris@0 165 public function addSubscriber(EventSubscriberInterface $subscriber)
Chris@0 166 {
Chris@0 167 foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
Chris@17 168 if (\is_string($params)) {
Chris@17 169 $this->addListener($eventName, [$subscriber, $params]);
Chris@17 170 } elseif (\is_string($params[0])) {
Chris@17 171 $this->addListener($eventName, [$subscriber, $params[0]], isset($params[1]) ? $params[1] : 0);
Chris@0 172 } else {
Chris@0 173 foreach ($params as $listener) {
Chris@17 174 $this->addListener($eventName, [$subscriber, $listener[0]], isset($listener[1]) ? $listener[1] : 0);
Chris@0 175 }
Chris@0 176 }
Chris@0 177 }
Chris@0 178 }
Chris@0 179
Chris@0 180 /**
Chris@0 181 * {@inheritdoc}
Chris@0 182 */
Chris@0 183 public function removeSubscriber(EventSubscriberInterface $subscriber)
Chris@0 184 {
Chris@0 185 foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
Chris@17 186 if (\is_array($params) && \is_array($params[0])) {
Chris@0 187 foreach ($params as $listener) {
Chris@17 188 $this->removeListener($eventName, [$subscriber, $listener[0]]);
Chris@0 189 }
Chris@0 190 } else {
Chris@17 191 $this->removeListener($eventName, [$subscriber, \is_string($params) ? $params : $params[0]]);
Chris@0 192 }
Chris@0 193 }
Chris@0 194 }
Chris@0 195
Chris@0 196 /**
Chris@0 197 * Triggers the listeners of an event.
Chris@0 198 *
Chris@0 199 * This method can be overridden to add functionality that is executed
Chris@0 200 * for each listener.
Chris@0 201 *
Chris@0 202 * @param callable[] $listeners The event listeners
Chris@0 203 * @param string $eventName The name of the event to dispatch
Chris@0 204 * @param Event $event The event object to pass to the event handlers/listeners
Chris@0 205 */
Chris@0 206 protected function doDispatch($listeners, $eventName, Event $event)
Chris@0 207 {
Chris@0 208 foreach ($listeners as $listener) {
Chris@0 209 if ($event->isPropagationStopped()) {
Chris@0 210 break;
Chris@0 211 }
Chris@14 212 \call_user_func($listener, $event, $eventName, $this);
Chris@0 213 }
Chris@0 214 }
Chris@0 215
Chris@0 216 /**
Chris@0 217 * Sorts the internal list of listeners for the given event by priority.
Chris@0 218 *
Chris@0 219 * @param string $eventName The name of the event
Chris@0 220 */
Chris@0 221 private function sortListeners($eventName)
Chris@0 222 {
Chris@0 223 krsort($this->listeners[$eventName]);
Chris@17 224 $this->sorted[$eventName] = [];
Chris@14 225
Chris@14 226 foreach ($this->listeners[$eventName] as $priority => $listeners) {
Chris@14 227 foreach ($listeners as $k => $listener) {
Chris@14 228 if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
Chris@14 229 $listener[0] = $listener[0]();
Chris@14 230 $this->listeners[$eventName][$priority][$k] = $listener;
Chris@14 231 }
Chris@14 232 $this->sorted[$eventName][] = $listener;
Chris@14 233 }
Chris@14 234 }
Chris@0 235 }
Chris@0 236 }