Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | 1fec387a4317 |
children | af1871eacc83 |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
9 * file that was distributed with this source code. | 9 * file that was distributed with this source code. |
10 */ | 10 */ |
11 | 11 |
12 namespace Symfony\Component\EventDispatcher\Debug; | 12 namespace Symfony\Component\EventDispatcher\Debug; |
13 | 13 |
14 use Psr\Log\LoggerInterface; | |
15 use Symfony\Component\EventDispatcher\Event; | |
14 use Symfony\Component\EventDispatcher\EventDispatcherInterface; | 16 use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
15 use Symfony\Component\EventDispatcher\EventSubscriberInterface; | 17 use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
16 use Symfony\Component\EventDispatcher\Event; | |
17 use Symfony\Component\Stopwatch\Stopwatch; | 18 use Symfony\Component\Stopwatch\Stopwatch; |
18 use Psr\Log\LoggerInterface; | |
19 | 19 |
20 /** | 20 /** |
21 * Collects some data about event listeners. | 21 * Collects some data about event listeners. |
22 * | 22 * |
23 * This event dispatcher delegates the dispatching to another one. | 23 * This event dispatcher delegates the dispatching to another one. |
27 class TraceableEventDispatcher implements TraceableEventDispatcherInterface | 27 class TraceableEventDispatcher implements TraceableEventDispatcherInterface |
28 { | 28 { |
29 protected $logger; | 29 protected $logger; |
30 protected $stopwatch; | 30 protected $stopwatch; |
31 | 31 |
32 private $called; | 32 private $callStack; |
33 private $dispatcher; | 33 private $dispatcher; |
34 private $wrappedListeners; | 34 private $wrappedListeners; |
35 | 35 |
36 public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null) | 36 public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null) |
37 { | 37 { |
38 $this->dispatcher = $dispatcher; | 38 $this->dispatcher = $dispatcher; |
39 $this->stopwatch = $stopwatch; | 39 $this->stopwatch = $stopwatch; |
40 $this->logger = $logger; | 40 $this->logger = $logger; |
41 $this->called = array(); | 41 $this->wrappedListeners = []; |
42 $this->wrappedListeners = array(); | |
43 } | 42 } |
44 | 43 |
45 /** | 44 /** |
46 * {@inheritdoc} | 45 * {@inheritdoc} |
47 */ | 46 */ |
121 /** | 120 /** |
122 * {@inheritdoc} | 121 * {@inheritdoc} |
123 */ | 122 */ |
124 public function dispatch($eventName, Event $event = null) | 123 public function dispatch($eventName, Event $event = null) |
125 { | 124 { |
125 if (null === $this->callStack) { | |
126 $this->callStack = new \SplObjectStorage(); | |
127 } | |
128 | |
126 if (null === $event) { | 129 if (null === $event) { |
127 $event = new Event(); | 130 $event = new Event(); |
128 } | 131 } |
129 | 132 |
130 if (null !== $this->logger && $event->isPropagationStopped()) { | 133 if (null !== $this->logger && $event->isPropagationStopped()) { |
131 $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName)); | 134 $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName)); |
132 } | 135 } |
133 | 136 |
134 $this->preProcess($eventName); | 137 $this->preProcess($eventName); |
135 $this->preDispatch($eventName, $event); | 138 try { |
136 | 139 $this->preDispatch($eventName, $event); |
137 $e = $this->stopwatch->start($eventName, 'section'); | 140 try { |
138 | 141 $e = $this->stopwatch->start($eventName, 'section'); |
139 $this->dispatcher->dispatch($eventName, $event); | 142 try { |
140 | 143 $this->dispatcher->dispatch($eventName, $event); |
141 if ($e->isStarted()) { | 144 } finally { |
142 $e->stop(); | 145 if ($e->isStarted()) { |
143 } | 146 $e->stop(); |
144 | 147 } |
145 $this->postDispatch($eventName, $event); | 148 } |
146 $this->postProcess($eventName); | 149 } finally { |
150 $this->postDispatch($eventName, $event); | |
151 } | |
152 } finally { | |
153 $this->postProcess($eventName); | |
154 } | |
147 | 155 |
148 return $event; | 156 return $event; |
149 } | 157 } |
150 | 158 |
151 /** | 159 /** |
152 * {@inheritdoc} | 160 * {@inheritdoc} |
153 */ | 161 */ |
154 public function getCalledListeners() | 162 public function getCalledListeners() |
155 { | 163 { |
156 $called = array(); | 164 if (null === $this->callStack) { |
157 foreach ($this->called as $eventName => $listeners) { | 165 return []; |
158 foreach ($listeners as $listener) { | 166 } |
159 $called[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName); | 167 |
160 } | 168 $called = []; |
169 foreach ($this->callStack as $listener) { | |
170 list($eventName) = $this->callStack->getInfo(); | |
171 | |
172 $called[] = $listener->getInfo($eventName); | |
161 } | 173 } |
162 | 174 |
163 return $called; | 175 return $called; |
164 } | 176 } |
165 | 177 |
170 { | 182 { |
171 try { | 183 try { |
172 $allListeners = $this->getListeners(); | 184 $allListeners = $this->getListeners(); |
173 } catch (\Exception $e) { | 185 } catch (\Exception $e) { |
174 if (null !== $this->logger) { | 186 if (null !== $this->logger) { |
175 $this->logger->info('An exception was thrown while getting the uncalled listeners.', array('exception' => $e)); | 187 $this->logger->info('An exception was thrown while getting the uncalled listeners.', ['exception' => $e]); |
176 } | 188 } |
177 | 189 |
178 // unable to retrieve the uncalled listeners | 190 // unable to retrieve the uncalled listeners |
179 return array(); | 191 return []; |
180 } | 192 } |
181 | 193 |
182 $notCalled = array(); | 194 $notCalled = []; |
183 foreach ($allListeners as $eventName => $listeners) { | 195 foreach ($allListeners as $eventName => $listeners) { |
184 foreach ($listeners as $listener) { | 196 foreach ($listeners as $listener) { |
185 $called = false; | 197 $called = false; |
186 if (isset($this->called[$eventName])) { | 198 if (null !== $this->callStack) { |
187 foreach ($this->called[$eventName] as $l) { | 199 foreach ($this->callStack as $calledListener) { |
188 if ($l->getWrappedListener() === $listener) { | 200 if ($calledListener->getWrappedListener() === $listener) { |
189 $called = true; | 201 $called = true; |
190 | 202 |
191 break; | 203 break; |
192 } | 204 } |
193 } | 205 } |
195 | 207 |
196 if (!$called) { | 208 if (!$called) { |
197 if (!$listener instanceof WrappedListener) { | 209 if (!$listener instanceof WrappedListener) { |
198 $listener = new WrappedListener($listener, null, $this->stopwatch, $this); | 210 $listener = new WrappedListener($listener, null, $this->stopwatch, $this); |
199 } | 211 } |
200 $notCalled[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName); | 212 $notCalled[] = $listener->getInfo($eventName); |
201 } | 213 } |
202 } | 214 } |
203 } | 215 } |
204 | 216 |
205 uasort($notCalled, array($this, 'sortListenersByPriority')); | 217 uasort($notCalled, [$this, 'sortNotCalledListeners']); |
206 | 218 |
207 return $notCalled; | 219 return $notCalled; |
208 } | 220 } |
209 | 221 |
210 public function reset() | 222 public function reset() |
211 { | 223 { |
212 $this->called = array(); | 224 $this->callStack = null; |
213 } | 225 } |
214 | 226 |
215 /** | 227 /** |
216 * Proxies all method calls to the original event dispatcher. | 228 * Proxies all method calls to the original event dispatcher. |
217 * | 229 * |
220 * | 232 * |
221 * @return mixed | 233 * @return mixed |
222 */ | 234 */ |
223 public function __call($method, $arguments) | 235 public function __call($method, $arguments) |
224 { | 236 { |
225 return call_user_func_array(array($this->dispatcher, $method), $arguments); | 237 return \call_user_func_array([$this->dispatcher, $method], $arguments); |
226 } | 238 } |
227 | 239 |
228 /** | 240 /** |
229 * Called before dispatching the event. | 241 * Called before dispatching the event. |
230 * | 242 * |
247 | 259 |
248 private function preProcess($eventName) | 260 private function preProcess($eventName) |
249 { | 261 { |
250 foreach ($this->dispatcher->getListeners($eventName) as $listener) { | 262 foreach ($this->dispatcher->getListeners($eventName) as $listener) { |
251 $priority = $this->getListenerPriority($eventName, $listener); | 263 $priority = $this->getListenerPriority($eventName, $listener); |
252 $wrappedListener = new WrappedListener($listener, null, $this->stopwatch, $this); | 264 $wrappedListener = new WrappedListener($listener instanceof WrappedListener ? $listener->getWrappedListener() : $listener, null, $this->stopwatch, $this); |
253 $this->wrappedListeners[$eventName][] = $wrappedListener; | 265 $this->wrappedListeners[$eventName][] = $wrappedListener; |
254 $this->dispatcher->removeListener($eventName, $listener); | 266 $this->dispatcher->removeListener($eventName, $listener); |
255 $this->dispatcher->addListener($eventName, $wrappedListener, $priority); | 267 $this->dispatcher->addListener($eventName, $wrappedListener, $priority); |
268 $this->callStack->attach($wrappedListener, [$eventName]); | |
256 } | 269 } |
257 } | 270 } |
258 | 271 |
259 private function postProcess($eventName) | 272 private function postProcess($eventName) |
260 { | 273 { |
268 $priority = $this->getListenerPriority($eventName, $listener); | 281 $priority = $this->getListenerPriority($eventName, $listener); |
269 $this->dispatcher->removeListener($eventName, $listener); | 282 $this->dispatcher->removeListener($eventName, $listener); |
270 $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority); | 283 $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority); |
271 | 284 |
272 if (null !== $this->logger) { | 285 if (null !== $this->logger) { |
273 $context = array('event' => $eventName, 'listener' => $listener->getPretty()); | 286 $context = ['event' => $eventName, 'listener' => $listener->getPretty()]; |
274 } | 287 } |
275 | 288 |
276 if ($listener->wasCalled()) { | 289 if ($listener->wasCalled()) { |
277 if (null !== $this->logger) { | 290 if (null !== $this->logger) { |
278 $this->logger->debug('Notified event "{event}" to listener "{listener}".', $context); | 291 $this->logger->debug('Notified event "{event}" to listener "{listener}".', $context); |
279 } | 292 } |
280 | 293 |
281 if (!isset($this->called[$eventName])) { | 294 if (!isset($this->called[$eventName])) { |
282 $this->called[$eventName] = new \SplObjectStorage(); | 295 $this->called[$eventName] = new \SplObjectStorage(); |
283 } | 296 } |
284 | 297 } else { |
285 $this->called[$eventName]->attach($listener); | 298 $this->callStack->detach($listener); |
286 } | 299 } |
287 | 300 |
288 if (null !== $this->logger && $skipped) { | 301 if (null !== $this->logger && $skipped) { |
289 $this->logger->debug('Listener "{listener}" was not called for event "{event}".', $context); | 302 $this->logger->debug('Listener "{listener}" was not called for event "{event}".', $context); |
290 } | 303 } |
297 $skipped = true; | 310 $skipped = true; |
298 } | 311 } |
299 } | 312 } |
300 } | 313 } |
301 | 314 |
302 private function sortListenersByPriority($a, $b) | 315 private function sortNotCalledListeners(array $a, array $b) |
303 { | 316 { |
304 if (is_int($a['priority']) && !is_int($b['priority'])) { | 317 if (0 !== $cmp = strcmp($a['event'], $b['event'])) { |
318 return $cmp; | |
319 } | |
320 | |
321 if (\is_int($a['priority']) && !\is_int($b['priority'])) { | |
305 return 1; | 322 return 1; |
306 } | 323 } |
307 | 324 |
308 if (!is_int($a['priority']) && is_int($b['priority'])) { | 325 if (!\is_int($a['priority']) && \is_int($b['priority'])) { |
309 return -1; | 326 return -1; |
310 } | 327 } |
311 | 328 |
312 if ($a['priority'] === $b['priority']) { | 329 if ($a['priority'] === $b['priority']) { |
313 return 0; | 330 return 0; |