Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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: 09.10.2024, 12:56 - Dateigröße: 11.17 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 Symfony\Component\EventDispatcher\EventDispatcherInterface;
 015  use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 016  use Symfony\Component\EventDispatcher\Event;
 017  use Symfony\Component\Stopwatch\Stopwatch;
 018  use Psr\Log\LoggerInterface;
 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 $called;
 033      private $dispatcher;
 034      private $wrappedListeners;
 035   
 036      /**
 037       * Constructor.
 038       *
 039       * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
 040       * @param Stopwatch                $stopwatch  A Stopwatch instance
 041       * @param LoggerInterface          $logger     A LoggerInterface instance
 042       */
 043      public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null)
 044      {
 045          $this->dispatcher = $dispatcher;
 046          $this->stopwatch = $stopwatch;
 047          $this->logger = $logger;
 048          $this->called = array();
 049          $this->wrappedListeners = array();
 050      }
 051   
 052      /**
 053       * {@inheritdoc}
 054       */
 055      public function addListener($eventName, $listener, $priority = 0)
 056      {
 057          $this->dispatcher->addListener($eventName, $listener, $priority);
 058      }
 059   
 060      /**
 061       * {@inheritdoc}
 062       */
 063      public function addSubscriber(EventSubscriberInterface $subscriber)
 064      {
 065          $this->dispatcher->addSubscriber($subscriber);
 066      }
 067   
 068      /**
 069       * {@inheritdoc}
 070       */
 071      public function removeListener($eventName, $listener)
 072      {
 073          if (isset($this->wrappedListeners[$eventName])) {
 074              foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
 075                  if ($wrappedListener->getWrappedListener() === $listener) {
 076                      $listener = $wrappedListener;
 077                      unset($this->wrappedListeners[$eventName][$index]);
 078                      break;
 079                  }
 080              }
 081          }
 082   
 083          return $this->dispatcher->removeListener($eventName, $listener);
 084      }
 085   
 086      /**
 087       * {@inheritdoc}
 088       */
 089      public function removeSubscriber(EventSubscriberInterface $subscriber)
 090      {
 091          return $this->dispatcher->removeSubscriber($subscriber);
 092      }
 093   
 094      /**
 095       * {@inheritdoc}
 096       */
 097      public function getListeners($eventName = null)
 098      {
 099          return $this->dispatcher->getListeners($eventName);
 100      }
 101   
 102      /**
 103       * {@inheritdoc}
 104       */
 105      public function getListenerPriority($eventName, $listener)
 106      {
 107          if (!method_exists($this->dispatcher, 'getListenerPriority')) {
 108              return 0;
 109          }
 110   
 111          return $this->dispatcher->getListenerPriority($eventName, $listener);
 112      }
 113   
 114      /**
 115       * {@inheritdoc}
 116       */
 117      public function hasListeners($eventName = null)
 118      {
 119          return $this->dispatcher->hasListeners($eventName);
 120      }
 121   
 122      /**
 123       * {@inheritdoc}
 124       */
 125      public function dispatch($eventName, Event $event = null)
 126      {
 127          if (null === $event) {
 128              $event = new Event();
 129          }
 130   
 131          if (null !== $this->logger && $event->isPropagationStopped()) {
 132              $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName));
 133          }
 134   
 135          $this->preProcess($eventName);
 136          $this->preDispatch($eventName, $event);
 137   
 138          $e = $this->stopwatch->start($eventName, 'section');
 139   
 140          $this->dispatcher->dispatch($eventName, $event);
 141   
 142          if ($e->isStarted()) {
 143              $e->stop();
 144          }
 145   
 146          $this->postDispatch($eventName, $event);
 147          $this->postProcess($eventName);
 148   
 149          return $event;
 150      }
 151   
 152      /**
 153       * {@inheritdoc}
 154       */
 155      public function getCalledListeners()
 156      {
 157          $called = array();
 158          foreach ($this->called as $eventName => $listeners) {
 159              foreach ($listeners as $listener) {
 160                  $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName);
 161                  $called[$eventName.'.'.$info['pretty']] = $info;
 162              }
 163          }
 164   
 165          return $called;
 166      }
 167   
 168      /**
 169       * {@inheritdoc}
 170       */
 171      public function getNotCalledListeners()
 172      {
 173          try {
 174              $allListeners = $this->getListeners();
 175          } catch (\Exception $e) {
 176              if (null !== $this->logger) {
 177                  $this->logger->info('An exception was thrown while getting the uncalled listeners.', array('exception' => $e));
 178              }
 179   
 180              // unable to retrieve the uncalled listeners
 181              return array();
 182          }
 183   
 184          $notCalled = array();
 185          foreach ($allListeners as $eventName => $listeners) {
 186              foreach ($listeners as $listener) {
 187                  $called = false;
 188                  if (isset($this->called[$eventName])) {
 189                      foreach ($this->called[$eventName] as $l) {
 190                          if ($l->getWrappedListener() === $listener) {
 191                              $called = true;
 192   
 193                              break;
 194                          }
 195                      }
 196                  }
 197   
 198                  if (!$called) {
 199                      $info = $this->getListenerInfo($listener, $eventName);
 200                      $notCalled[$eventName.'.'.$info['pretty']] = $info;
 201                  }
 202              }
 203          }
 204   
 205          uasort($notCalled, array($this, 'sortListenersByPriority'));
 206   
 207          return $notCalled;
 208      }
 209   
 210      /**
 211       * Proxies all method calls to the original event dispatcher.
 212       *
 213       * @param string $method    The method name
 214       * @param array  $arguments The method arguments
 215       *
 216       * @return mixed
 217       */
 218      public function __call($method, $arguments)
 219      {
 220          return call_user_func_array(array($this->dispatcher, $method), $arguments);
 221      }
 222   
 223      /**
 224       * Called before dispatching the event.
 225       *
 226       * @param string $eventName The event name
 227       * @param Event  $event     The event
 228       */
 229      protected function preDispatch($eventName, Event $event)
 230      {
 231      }
 232   
 233      /**
 234       * Called after dispatching the event.
 235       *
 236       * @param string $eventName The event name
 237       * @param Event  $event     The event
 238       */
 239      protected function postDispatch($eventName, Event $event)
 240      {
 241      }
 242   
 243      private function preProcess($eventName)
 244      {
 245          foreach ($this->dispatcher->getListeners($eventName) as $listener) {
 246              $info = $this->getListenerInfo($listener, $eventName);
 247              $name = isset($info['class']) ? $info['class'] : $info['type'];
 248              $wrappedListener = new WrappedListener($listener, $name, $this->stopwatch, $this);
 249              $this->wrappedListeners[$eventName][] = $wrappedListener;
 250              $this->dispatcher->removeListener($eventName, $listener);
 251              $this->dispatcher->addListener($eventName, $wrappedListener, $info['priority']);
 252          }
 253      }
 254   
 255      private function postProcess($eventName)
 256      {
 257          unset($this->wrappedListeners[$eventName]);
 258          $skipped = false;
 259          foreach ($this->dispatcher->getListeners($eventName) as $listener) {
 260              if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch.
 261                  continue;
 262              }
 263              // Unwrap listener
 264              $priority = $this->getListenerPriority($eventName, $listener);
 265              $this->dispatcher->removeListener($eventName, $listener);
 266              $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority);
 267   
 268              $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName);
 269              if ($listener->wasCalled()) {
 270                  if (null !== $this->logger) {
 271                      $this->logger->debug(sprintf('Notified event "%s" to listener "%s".', $eventName, $info['pretty']));
 272                  }
 273   
 274                  if (!isset($this->called[$eventName])) {
 275                      $this->called[$eventName] = new \SplObjectStorage();
 276                  }
 277   
 278                  $this->called[$eventName]->attach($listener);
 279              }
 280   
 281              if (null !== $this->logger && $skipped) {
 282                  $this->logger->debug(sprintf('Listener "%s" was not called for event "%s".', $info['pretty'], $eventName));
 283              }
 284   
 285              if ($listener->stoppedPropagation()) {
 286                  if (null !== $this->logger) {
 287                      $this->logger->debug(sprintf('Listener "%s" stopped propagation of the event "%s".', $info['pretty'], $eventName));
 288                  }
 289   
 290                  $skipped = true;
 291              }
 292          }
 293      }
 294   
 295      /**
 296       * Returns information about the listener.
 297       *
 298       * @param object $listener  The listener
 299       * @param string $eventName The event name
 300       *
 301       * @return array Information about the listener
 302       */
 303      private function getListenerInfo($listener, $eventName)
 304      {
 305          $info = array(
 306              'event' => $eventName,
 307              'priority' => $this->getListenerPriority($eventName, $listener),
 308          );
 309          if ($listener instanceof \Closure) {
 310              $info += array(
 311                  'type' => 'Closure',
 312                  'pretty' => 'closure',
 313              );
 314          } elseif (is_string($listener)) {
 315              try {
 316                  $r = new \ReflectionFunction($listener);
 317                  $file = $r->getFileName();
 318                  $line = $r->getStartLine();
 319              } catch (\ReflectionException $e) {
 320                  $file = null;
 321                  $line = null;
 322              }
 323              $info += array(
 324                  'type' => 'Function',
 325                  'function' => $listener,
 326                  'file' => $file,
 327                  'line' => $line,
 328                  'pretty' => $listener,
 329              );
 330          } elseif (is_array($listener) || (is_object($listener) && is_callable($listener))) {
 331              if (!is_array($listener)) {
 332                  $listener = array($listener, '__invoke');
 333              }
 334              $class = is_object($listener[0]) ? get_class($listener[0]) : $listener[0];
 335              try {
 336                  $r = new \ReflectionMethod($class, $listener[1]);
 337                  $file = $r->getFileName();
 338                  $line = $r->getStartLine();
 339              } catch (\ReflectionException $e) {
 340                  $file = null;
 341                  $line = null;
 342              }
 343              $info += array(
 344                  'type' => 'Method',
 345                  'class' => $class,
 346                  'method' => $listener[1],
 347                  'file' => $file,
 348                  'line' => $line,
 349                  'pretty' => $class.'::'.$listener[1],
 350              );
 351          }
 352   
 353          return $info;
 354      }
 355   
 356      private function sortListenersByPriority($a, $b)
 357      {
 358          if (is_int($a['priority']) && !is_int($b['priority'])) {
 359              return 1;
 360          }
 361   
 362          if (!is_int($a['priority']) && is_int($b['priority'])) {
 363              return -1;
 364          }
 365   
 366          if ($a['priority'] === $b['priority']) {
 367              return 0;
 368          }
 369   
 370          if ($a['priority'] > $b['priority']) {
 371              return -1;
 372          }
 373   
 374          return 1;
 375      }
 376  }
 377