Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

TraceableEventDispatcher.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 9.65 KiB


001  <?php
002   
003  /*
004   * This file is part of the Symfony package.
005   *
006   * (c) Fabien Potencier <fabien@symfony.com>
007   *
008   * For the full copyright and license information, please view the LICENSE
009   * file that was distributed with this source code.
010   */
011   
012  namespace Symfony\Component\EventDispatcher\Debug;
013   
014  use Psr\Log\LoggerInterface;
015  use Symfony\Component\EventDispatcher\Event;
016  use Symfony\Component\EventDispatcher\EventDispatcherInterface;
017  use Symfony\Component\EventDispatcher\EventSubscriberInterface;
018  use Symfony\Component\Stopwatch\Stopwatch;
019   
020  /**
021   * Collects some data about event listeners.
022   *
023   * This event dispatcher delegates the dispatching to another one.
024   *
025   * @author Fabien Potencier <fabien@symfony.com>
026   */
027  class TraceableEventDispatcher implements TraceableEventDispatcherInterface
028  {
029      protected $logger;
030      protected $stopwatch;
031   
032      private $callStack;
033      private $dispatcher;
034      private $wrappedListeners;
035   
036      public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null)
037      {
038          $this->dispatcher = $dispatcher;
039          $this->stopwatch = $stopwatch;
040          $this->logger = $logger;
041          $this->wrappedListeners = [];
042      }
043   
044      /**
045       * {@inheritdoc}
046       */
047      public function addListener($eventName, $listener, $priority = 0)
048      {
049          $this->dispatcher->addListener($eventName, $listener, $priority);
050      }
051   
052      /**
053       * {@inheritdoc}
054       */
055      public function addSubscriber(EventSubscriberInterface $subscriber)
056      {
057          $this->dispatcher->addSubscriber($subscriber);
058      }
059   
060      /**
061       * {@inheritdoc}
062       */
063      public function removeListener($eventName, $listener)
064      {
065          if (isset($this->wrappedListeners[$eventName])) {
066              foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
067                  if ($wrappedListener->getWrappedListener() === $listener) {
068                      $listener = $wrappedListener;
069                      unset($this->wrappedListeners[$eventName][$index]);
070                      break;
071                  }
072              }
073          }
074   
075          return $this->dispatcher->removeListener($eventName, $listener);
076      }
077   
078      /**
079       * {@inheritdoc}
080       */
081      public function removeSubscriber(EventSubscriberInterface $subscriber)
082      {
083          return $this->dispatcher->removeSubscriber($subscriber);
084      }
085   
086      /**
087       * {@inheritdoc}
088       */
089      public function getListeners($eventName = null)
090      {
091          return $this->dispatcher->getListeners($eventName);
092      }
093   
094      /**
095       * {@inheritdoc}
096       */
097      public function getListenerPriority($eventName, $listener)
098      {
099          // we might have wrapped listeners for the event (if called while dispatching)
100          // in that case get the priority by wrapper
101          if (isset($this->wrappedListeners[$eventName])) {
102              foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
103                  if ($wrappedListener->getWrappedListener() === $listener) {
104                      return $this->dispatcher->getListenerPriority($eventName, $wrappedListener);
105                  }
106              }
107          }
108   
109          return $this->dispatcher->getListenerPriority($eventName, $listener);
110      }
111   
112      /**
113       * {@inheritdoc}
114       */
115      public function hasListeners($eventName = null)
116      {
117          return $this->dispatcher->hasListeners($eventName);
118      }
119   
120      /**
121       * {@inheritdoc}
122       */
123      public function dispatch($eventName, Event $event = null)
124      {
125          if (null === $this->callStack) {
126              $this->callStack = new \SplObjectStorage();
127          }
128   
129          if (null === $event) {
130              $event = new Event();
131          }
132   
133          if (null !== $this->logger && $event->isPropagationStopped()) {
134              $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName));
135          }
136   
137          $this->preProcess($eventName);
138          try {
139              $this->preDispatch($eventName, $event);
140              try {
141                  $e = $this->stopwatch->start($eventName, 'section');
142                  try {
143                      $this->dispatcher->dispatch($eventName, $event);
144                  } finally {
145                      if ($e->isStarted()) {
146                          $e->stop();
147                      }
148                  }
149              } finally {
150                  $this->postDispatch($eventName, $event);
151              }
152          } finally {
153              $this->postProcess($eventName);
154          }
155   
156          return $event;
157      }
158   
159      /**
160       * {@inheritdoc}
161       */
162      public function getCalledListeners()
163      {
164          if (null === $this->callStack) {
165              return [];
166          }
167   
168          $called = [];
169          foreach ($this->callStack as $listener) {
170              list($eventName) = $this->callStack->getInfo();
171   
172              $called[] = $listener->getInfo($eventName);
173          }
174   
175          return $called;
176      }
177   
178      /**
179       * {@inheritdoc}
180       */
181      public function getNotCalledListeners()
182      {
183          try {
184              $allListeners = $this->getListeners();
185          } catch (\Exception $e) {
186              if (null !== $this->logger) {
187                  $this->logger->info('An exception was thrown while getting the uncalled listeners.', ['exception' => $e]);
188              }
189   
190              // unable to retrieve the uncalled listeners
191              return [];
192          }
193   
194          $calledListeners = [];
195   
196          if (null !== $this->callStack) {
197              foreach ($this->callStack as $calledListener) {
198                  $calledListeners[] = $calledListener->getWrappedListener();
199              }
200          }
201   
202          $notCalled = [];
203          foreach ($allListeners as $eventName => $listeners) {
204              foreach ($listeners as $listener) {
205                  if (!\in_array($listener, $calledListeners, true)) {
206                      if (!$listener instanceof WrappedListener) {
207                          $listener = new WrappedListener($listener, null, $this->stopwatch, $this);
208                      }
209                      $notCalled[] = $listener->getInfo($eventName);
210                  }
211              }
212          }
213   
214          uasort($notCalled, [$this, 'sortNotCalledListeners']);
215   
216          return $notCalled;
217      }
218   
219      public function reset()
220      {
221          $this->callStack = null;
222      }
223   
224      /**
225       * Proxies all method calls to the original event dispatcher.
226       *
227       * @param string $method    The method name
228       * @param array  $arguments The method arguments
229       *
230       * @return mixed
231       */
232      public function __call($method, $arguments)
233      {
234          return \call_user_func_array([$this->dispatcher, $method], $arguments);
235      }
236   
237      /**
238       * Called before dispatching the event.
239       *
240       * @param string $eventName The event name
241       * @param Event  $event     The event
242       */
243      protected function preDispatch($eventName, Event $event)
244      {
245      }
246   
247      /**
248       * Called after dispatching the event.
249       *
250       * @param string $eventName The event name
251       * @param Event  $event     The event
252       */
253      protected function postDispatch($eventName, Event $event)
254      {
255      }
256   
257      private function preProcess($eventName)
258      {
259          foreach ($this->dispatcher->getListeners($eventName) as $listener) {
260              $priority = $this->getListenerPriority($eventName, $listener);
261              $wrappedListener = new WrappedListener($listener instanceof WrappedListener ? $listener->getWrappedListener() : $listener, null, $this->stopwatch, $this);
262              $this->wrappedListeners[$eventName][] = $wrappedListener;
263              $this->dispatcher->removeListener($eventName, $listener);
264              $this->dispatcher->addListener($eventName, $wrappedListener, $priority);
265              $this->callStack->attach($wrappedListener, [$eventName]);
266          }
267      }
268   
269      private function postProcess($eventName)
270      {
271          unset($this->wrappedListeners[$eventName]);
272          $skipped = false;
273          foreach ($this->dispatcher->getListeners($eventName) as $listener) {
274              if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch.
275                  continue;
276              }
277              // Unwrap listener
278              $priority = $this->getListenerPriority($eventName, $listener);
279              $this->dispatcher->removeListener($eventName, $listener);
280              $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority);
281   
282              if (null !== $this->logger) {
283                  $context = ['event' => $eventName, 'listener' => $listener->getPretty()];
284              }
285   
286              if ($listener->wasCalled()) {
287                  if (null !== $this->logger) {
288                      $this->logger->debug('Notified event "{event}" to listener "{listener}".', $context);
289                  }
290              } else {
291                  $this->callStack->detach($listener);
292              }
293   
294              if (null !== $this->logger && $skipped) {
295                  $this->logger->debug('Listener "{listener}" was not called for event "{event}".', $context);
296              }
297   
298              if ($listener->stoppedPropagation()) {
299                  if (null !== $this->logger) {
300                      $this->logger->debug('Listener "{listener}" stopped propagation of the event "{event}".', $context);
301                  }
302   
303                  $skipped = true;
304              }
305          }
306      }
307   
308      private function sortNotCalledListeners(array $a, array $b)
309      {
310          if (0 !== $cmp = strcmp($a['event'], $b['event'])) {
311              return $cmp;
312          }
313   
314          if (\is_int($a['priority']) && !\is_int($b['priority'])) {
315              return 1;
316          }
317   
318          if (!\is_int($a['priority']) && \is_int($b['priority'])) {
319              return -1;
320          }
321   
322          if ($a['priority'] === $b['priority']) {
323              return 0;
324          }
325   
326          if ($a['priority'] > $b['priority']) {
327              return -1;
328          }
329   
330          return 1;
331      }
332  }
333