1<?php 2namespace Doctrine\Common; 3 4use function spl_object_hash; 5 6/** 7 * The EventManager is the central point of Doctrine's event listener system. 8 * Listeners are registered on the manager and events are dispatched through the 9 * manager. 10 */ 11class EventManager 12{ 13 /** 14 * Map of registered listeners. 15 * <event> => <listeners> 16 * 17 * @var object[][] 18 */ 19 private $_listeners = []; 20 21 /** 22 * Dispatches an event to all registered listeners. 23 * 24 * @param string $eventName The name of the event to dispatch. The name of the event is 25 * the name of the method that is invoked on listeners. 26 * @param EventArgs|null $eventArgs The event arguments to pass to the event handlers/listeners. 27 * If not supplied, the single empty EventArgs instance is used. 28 * 29 * @return void 30 */ 31 public function dispatchEvent($eventName, ?EventArgs $eventArgs = null) 32 { 33 if (! isset($this->_listeners[$eventName])) { 34 return; 35 } 36 37 $eventArgs = $eventArgs ?? EventArgs::getEmptyInstance(); 38 39 foreach ($this->_listeners[$eventName] as $listener) { 40 $listener->$eventName($eventArgs); 41 } 42 } 43 44 /** 45 * Gets the listeners of a specific event or all listeners. 46 * 47 * @param string|null $event The name of the event. 48 * 49 * @return object[]|object[][] The event listeners for the specified event, or all event listeners. 50 */ 51 public function getListeners($event = null) 52 { 53 return $event ? $this->_listeners[$event] : $this->_listeners; 54 } 55 56 /** 57 * Checks whether an event has any registered listeners. 58 * 59 * @param string $event 60 * 61 * @return bool TRUE if the specified event has any listeners, FALSE otherwise. 62 */ 63 public function hasListeners($event) 64 { 65 return ! empty($this->_listeners[$event]); 66 } 67 68 /** 69 * Adds an event listener that listens on the specified events. 70 * 71 * @param string|string[] $events The event(s) to listen on. 72 * @param object $listener The listener object. 73 * 74 * @return void 75 */ 76 public function addEventListener($events, $listener) 77 { 78 // Picks the hash code related to that listener 79 $hash = spl_object_hash($listener); 80 81 foreach ((array) $events as $event) { 82 // Overrides listener if a previous one was associated already 83 // Prevents duplicate listeners on same event (same instance only) 84 $this->_listeners[$event][$hash] = $listener; 85 } 86 } 87 88 /** 89 * Removes an event listener from the specified events. 90 * 91 * @param string|string[] $events 92 * @param object $listener 93 * 94 * @return void 95 */ 96 public function removeEventListener($events, $listener) 97 { 98 // Picks the hash code related to that listener 99 $hash = spl_object_hash($listener); 100 101 foreach ((array) $events as $event) { 102 unset($this->_listeners[$event][$hash]); 103 } 104 } 105 106 /** 107 * Adds an EventSubscriber. The subscriber is asked for all the events it is 108 * interested in and added as a listener for these events. 109 * 110 * @param EventSubscriber $subscriber The subscriber. 111 * 112 * @return void 113 */ 114 public function addEventSubscriber(EventSubscriber $subscriber) 115 { 116 $this->addEventListener($subscriber->getSubscribedEvents(), $subscriber); 117 } 118 119 /** 120 * Removes an EventSubscriber. The subscriber is asked for all the events it is 121 * interested in and removed as a listener for these events. 122 * 123 * @param EventSubscriber $subscriber The subscriber. 124 * 125 * @return void 126 */ 127 public function removeEventSubscriber(EventSubscriber $subscriber) 128 { 129 $this->removeEventListener($subscriber->getSubscribedEvents(), $subscriber); 130 } 131} 132