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

EventManager.php

Zuletzt modifiziert: 01.05.2026, 11:26 - Dateigröße: 9.36 KiB


 001  <?php
 002  /**
 003   * Zend Framework (http://framework.zend.com/)
 004   *
 005   * @link      http://github.com/zendframework/zend-eventmanager for the canonical source repository
 006   * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
 007   * @license   https://github.com/zendframework/zend-eventmanager/blob/master/LICENSE.md
 008   */
 009   
 010  namespace Zend\EventManager;
 011   
 012  use ArrayObject;
 013   
 014  /**
 015   * Event manager: notification system
 016   *
 017   * Use the EventManager when you want to create a per-instance notification
 018   * system for your objects.
 019   */
 020  class EventManager implements EventManagerInterface
 021  {
 022      /**
 023       * Subscribed events and their listeners
 024       *
 025       * STRUCTURE:
 026       * [
 027       *     <string name> => [
 028       *         <int priority> => [
 029       *             0 => [<callable listener>, ...]
 030       *         ],
 031       *         ...
 032       *     ],
 033       *     ...
 034       * ]
 035       *
 036       * NOTE:
 037       * This structure helps us to reuse the list of listeners
 038       * instead of first iterating over it and generating a new one
 039       * -> In result it improves performance by up to 25% even if it looks a bit strange
 040       *
 041       * @var array[]
 042       */
 043      protected $events = [];
 044   
 045      /**
 046       * @var EventInterface Prototype to use when creating an event at trigger().
 047       */
 048      protected $eventPrototype;
 049   
 050      /**
 051       * Identifiers, used to pull shared signals from SharedEventManagerInterface instance
 052       *
 053       * @var array
 054       */
 055      protected $identifiers = [];
 056   
 057      /**
 058       * Shared event manager
 059       *
 060       * @var null|SharedEventManagerInterface
 061       */
 062      protected $sharedManager = null;
 063   
 064      /**
 065       * Constructor
 066       *
 067       * Allows optionally specifying identifier(s) to use to pull signals from a
 068       * SharedEventManagerInterface.
 069       *
 070       * @param SharedEventManagerInterface $sharedEventManager
 071       * @param array $identifiers
 072       */
 073      public function __construct(SharedEventManagerInterface $sharedEventManager = null, array $identifiers = [])
 074      {
 075          if ($sharedEventManager) {
 076              $this->sharedManager = $sharedEventManager;
 077              $this->setIdentifiers($identifiers);
 078          }
 079   
 080          $this->eventPrototype = new Event();
 081      }
 082   
 083      /**
 084       * @inheritDoc
 085       */
 086      public function setEventPrototype(EventInterface $prototype)
 087      {
 088          $this->eventPrototype = $prototype;
 089      }
 090   
 091      /**
 092       * Retrieve the shared event manager, if composed.
 093       *
 094       * @return null|SharedEventManagerInterface $sharedEventManager
 095       */
 096      public function getSharedManager()
 097      {
 098          return $this->sharedManager;
 099      }
 100   
 101      /**
 102       * @inheritDoc
 103       */
 104      public function getIdentifiers()
 105      {
 106          return $this->identifiers;
 107      }
 108   
 109      /**
 110       * @inheritDoc
 111       */
 112      public function setIdentifiers(array $identifiers)
 113      {
 114          $this->identifiers = array_unique($identifiers);
 115      }
 116   
 117      /**
 118       * @inheritDoc
 119       */
 120      public function addIdentifiers(array $identifiers)
 121      {
 122          $this->identifiers = array_unique(array_merge(
 123              $this->identifiers,
 124              $identifiers
 125          ));
 126      }
 127   
 128      /**
 129       * @inheritDoc
 130       */
 131      public function trigger($eventName, $target = null, $argv = [])
 132      {
 133          $event = clone $this->eventPrototype;
 134          $event->setName($eventName);
 135   
 136          if ($target !== null) {
 137              $event->setTarget($target);
 138          }
 139   
 140          if ($argv) {
 141              $event->setParams($argv);
 142          }
 143   
 144          return $this->triggerListeners($event);
 145      }
 146   
 147      /**
 148       * @inheritDoc
 149       */
 150      public function triggerUntil(callable $callback, $eventName, $target = null, $argv = [])
 151      {
 152          $event = clone $this->eventPrototype;
 153          $event->setName($eventName);
 154   
 155          if ($target !== null) {
 156              $event->setTarget($target);
 157          }
 158   
 159          if ($argv) {
 160              $event->setParams($argv);
 161          }
 162   
 163          return $this->triggerListeners($event, $callback);
 164      }
 165   
 166      /**
 167       * @inheritDoc
 168       */
 169      public function triggerEvent(EventInterface $event)
 170      {
 171          return $this->triggerListeners($event);
 172      }
 173   
 174      /**
 175       * @inheritDoc
 176       */
 177      public function triggerEventUntil(callable $callback, EventInterface $event)
 178      {
 179          return $this->triggerListeners($event, $callback);
 180      }
 181   
 182      /**
 183       * @inheritDoc
 184       */
 185      public function attach($eventName, callable $listener, $priority = 1)
 186      {
 187          if (! is_string($eventName)) {
 188              throw new Exception\InvalidArgumentException(sprintf(
 189                  '%s expects a string for the event; received %s',
 190                  __METHOD__,
 191                  (is_object($eventName) ? get_class($eventName) : gettype($eventName))
 192              ));
 193          }
 194   
 195          $this->events[$eventName][(int) $priority][0][] = $listener;
 196          return $listener;
 197      }
 198   
 199      /**
 200       * @inheritDoc
 201       * @throws Exception\InvalidArgumentException for invalid event types.
 202       */
 203      public function detach(callable $listener, $eventName = null, $force = false)
 204      {
 205   
 206          // If event is wildcard, we need to iterate through each listeners
 207          if (null === $eventName || ('*' === $eventName && ! $force)) {
 208              foreach (array_keys($this->events) as $eventName) {
 209                  $this->detach($listener, $eventName, true);
 210              }
 211              return;
 212          }
 213   
 214          if (! is_string($eventName)) {
 215              throw new Exception\InvalidArgumentException(sprintf(
 216                  '%s expects a string for the event; received %s',
 217                  __METHOD__,
 218                  (is_object($eventName) ? get_class($eventName) : gettype($eventName))
 219              ));
 220          }
 221   
 222          if (! isset($this->events[$eventName])) {
 223              return;
 224          }
 225   
 226          foreach ($this->events[$eventName] as $priority => $listeners) {
 227              foreach ($listeners[0] as $index => $evaluatedListener) {
 228                  if ($evaluatedListener !== $listener) {
 229                      continue;
 230                  }
 231   
 232                  // Found the listener; remove it.
 233                  unset($this->events[$eventName][$priority][0][$index]);
 234   
 235                  // If the queue for the given priority is empty, remove it.
 236                  if (empty($this->events[$eventName][$priority][0])) {
 237                      unset($this->events[$eventName][$priority]);
 238                      break;
 239                  }
 240              }
 241          }
 242   
 243          // If the queue for the given event is empty, remove it.
 244          if (empty($this->events[$eventName])) {
 245              unset($this->events[$eventName]);
 246          }
 247      }
 248   
 249      /**
 250       * @inheritDoc
 251       */
 252      public function clearListeners($eventName)
 253      {
 254          if (isset($this->events[$eventName])) {
 255              unset($this->events[$eventName]);
 256          }
 257      }
 258   
 259      /**
 260       * Prepare arguments
 261       *
 262       * Use this method if you want to be able to modify arguments from within a
 263       * listener. It returns an ArrayObject of the arguments, which may then be
 264       * passed to trigger().
 265       *
 266       * @param  array $args
 267       * @return ArrayObject
 268       */
 269      public function prepareArgs(array $args)
 270      {
 271          return new ArrayObject($args);
 272      }
 273   
 274      /**
 275       * Trigger listeners
 276       *
 277       * Actual functionality for triggering listeners, to which trigger() delegate.
 278       *
 279       * @param  EventInterface $event
 280       * @param  null|callable $callback
 281       * @return ResponseCollection
 282       */
 283      protected function triggerListeners(EventInterface $event, callable $callback = null)
 284      {
 285          $name = $event->getName();
 286   
 287          if (empty($name)) {
 288              throw new Exception\RuntimeException('Event is missing a name; cannot trigger!');
 289          }
 290   
 291          if (isset($this->events[$name])) {
 292              $listOfListenersByPriority = $this->events[$name];
 293   
 294              if (isset($this->events['*'])) {
 295                  foreach ($this->events['*'] as $priority => $listOfListeners) {
 296                      $listOfListenersByPriority[$priority][] = $listOfListeners[0];
 297                  }
 298              }
 299          } elseif (isset($this->events['*'])) {
 300              $listOfListenersByPriority = $this->events['*'];
 301          } else {
 302              $listOfListenersByPriority = [];
 303          }
 304   
 305          if ($this->sharedManager) {
 306              foreach ($this->sharedManager->getListeners($this->identifiers, $name) as $priority => $listeners) {
 307                  $listOfListenersByPriority[$priority][] = $listeners;
 308              }
 309          }
 310   
 311          // Sort by priority in reverse order
 312          krsort($listOfListenersByPriority);
 313   
 314          // Initial value of stop propagation flag should be false
 315          $event->stopPropagation(false);
 316   
 317          // Execute listeners
 318          $responses = new ResponseCollection();
 319          foreach ($listOfListenersByPriority as $listOfListeners) {
 320              foreach ($listOfListeners as $listeners) {
 321                  foreach ($listeners as $listener) {
 322                      $response = $listener($event);
 323                      $responses->push($response);
 324   
 325                      // If the event was asked to stop propagating, do so
 326                      if ($event->propagationIsStopped()) {
 327                          $responses->setStopped(true);
 328                          return $responses;
 329                      }
 330   
 331                      // If the result causes our validation callback to return true,
 332                      // stop propagation
 333                      if ($callback && $callback($response)) {
 334                          $responses->setStopped(true);
 335                          return $responses;
 336                      }
 337                  }
 338              }
 339          }
 340   
 341          return $responses;
 342      }
 343  }
 344