Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

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: 01.05.2026, 11:26 - 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