[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Zend Framework (http://framework.zend.com/) 4 * 5 * @link http://github.com/zendframework/zend-eventmanager for the canonical source repository 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 7 * @license https://github.com/zendframework/zend-eventmanager/blob/master/LICENSE.md 8 */ 9 10 namespace Zend\EventManager; 11 12 use ArrayObject; 13 14 /** 15 * Event manager: notification system 16 * 17 * Use the EventManager when you want to create a per-instance notification 18 * system for your objects. 19 */ 20 class EventManager implements EventManagerInterface 21 { 22 /** 23 * Subscribed events and their listeners 24 * 25 * STRUCTURE: 26 * [ 27 * <string name> => [ 28 * <int priority> => [ 29 * 0 => [<callable listener>, ...] 30 * ], 31 * ... 32 * ], 33 * ... 34 * ] 35 * 36 * NOTE: 37 * This structure helps us to reuse the list of listeners 38 * instead of first iterating over it and generating a new one 39 * -> In result it improves performance by up to 25% even if it looks a bit strange 40 * 41 * @var array[] 42 */ 43 protected $events = []; 44 45 /** 46 * @var EventInterface Prototype to use when creating an event at trigger(). 47 */ 48 protected $eventPrototype; 49 50 /** 51 * Identifiers, used to pull shared signals from SharedEventManagerInterface instance 52 * 53 * @var array 54 */ 55 protected $identifiers = []; 56 57 /** 58 * Shared event manager 59 * 60 * @var null|SharedEventManagerInterface 61 */ 62 protected $sharedManager = null; 63 64 /** 65 * Constructor 66 * 67 * Allows optionally specifying identifier(s) to use to pull signals from a 68 * SharedEventManagerInterface. 69 * 70 * @param SharedEventManagerInterface $sharedEventManager 71 * @param array $identifiers 72 */ 73 public function __construct(SharedEventManagerInterface $sharedEventManager = null, array $identifiers = []) 74 { 75 if ($sharedEventManager) { 76 $this->sharedManager = $sharedEventManager; 77 $this->setIdentifiers($identifiers); 78 } 79 80 $this->eventPrototype = new Event(); 81 } 82 83 /** 84 * @inheritDoc 85 */ 86 public function setEventPrototype(EventInterface $prototype) 87 { 88 $this->eventPrototype = $prototype; 89 } 90 91 /** 92 * Retrieve the shared event manager, if composed. 93 * 94 * @return null|SharedEventManagerInterface $sharedEventManager 95 */ 96 public function getSharedManager() 97 { 98 return $this->sharedManager; 99 } 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |