PluginProbe
Auto Alt Text / 2.7.0
Auto Alt Text v2.7.0
3.0.3 2.8.2 1.3.1 1.3.2 2.0.0 2.1.0 2.1.1 2.2.0 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.7.0 2.8.0 2.8.1 All 28 releases
auto-alt-text / src / App / Events / SimpleEventDispatcher.php

SimpleEventDispatcher.php in Auto Alt Text 2.7.0, at src/App/Events/SimpleEventDispatcher.php

172 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AATXT\App\Events;
4
5 /**
6 * Simple implementation of the EventDispatcher interface.
7 *
8 * This dispatcher maintains an array of listeners indexed by event class
9 * and calls them in order when events are dispatched.
10 *
11 * Example usage:
12 * ```php
13 * $dispatcher = new SimpleEventDispatcher();
14 *
15 * // Register a listener
16 * $dispatcher->listen(UserCreatedEvent::class, function($event) {
17 * echo "User {$event->getUserId()} was created";
18 * });
19 *
20 * // Dispatch an event
21 * $dispatcher->dispatch(new UserCreatedEvent($userId));
22 * ```
23 *
24 * @package AATXT\App\Events
25 */
26 final class SimpleEventDispatcher implements EventDispatcherInterface
27 {
28 /**
29 * Registered listeners indexed by event class.
30 *
31 * @var array<string, array<callable>>
32 */
33 private $listeners = [];
34
35 /**
36 * Dispatch an event to all registered listeners.
37 *
38 * Listeners are called in the order they were registered.
39 * Each listener receives the event object as its argument.
40 *
41 * @param object $event The event to dispatch
42 * @return object The dispatched event (may be modified by listeners)
43 */
44 public function dispatch(object $event): object
45 {
46 $eventClass = get_class($event);
47
48 // Call listeners registered for the exact class
49 if (isset($this->listeners[$eventClass])) {
50 foreach ($this->listeners[$eventClass] as $listener) {
51 $listener($event);
52 }
53 }
54
55 // Also call listeners registered for parent classes/interfaces
56 foreach ($this->listeners as $registeredClass => $listeners) {
57 if ($registeredClass !== $eventClass && $event instanceof $registeredClass) {
58 foreach ($listeners as $listener) {
59 $listener($event);
60 }
61 }
62 }
63
64 return $event;
65 }
66
67 /**
68 * Register a listener for a specific event class.
69 *
70 * @param string $eventClass The event class to listen for
71 * @param callable $listener The listener callback
72 * @return void
73 */
74 public function listen(string $eventClass, callable $listener): void
75 {
76 if (!isset($this->listeners[$eventClass])) {
77 $this->listeners[$eventClass] = [];
78 }
79
80 $this->listeners[$eventClass][] = $listener;
81 }
82
83 /**
84 * Remove a listener for a specific event class.
85 *
86 * Note: This only works for listeners that can be compared with ===.
87 * Anonymous functions are only equal if they are the same instance.
88 *
89 * @param string $eventClass The event class
90 * @param callable $listener The listener to remove
91 * @return bool True if the listener was found and removed
92 */
93 public function removeListener(string $eventClass, callable $listener): bool
94 {
95 if (!isset($this->listeners[$eventClass])) {
96 return false;
97 }
98
99 $key = array_search($listener, $this->listeners[$eventClass], true);
100
101 if ($key === false) {
102 return false;
103 }
104
105 unset($this->listeners[$eventClass][$key]);
106 $this->listeners[$eventClass] = array_values($this->listeners[$eventClass]);
107
108 return true;
109 }
110
111 /**
112 * Get all listeners for a specific event class.
113 *
114 * @param string $eventClass The event class
115 * @return array<callable> Array of registered listeners
116 */
117 public function getListeners(string $eventClass): array
118 {
119 return $this->listeners[$eventClass] ?? [];
120 }
121
122 /**
123 * Check if there are any listeners for a specific event class.
124 *
125 * @param string $eventClass The event class
126 * @return bool True if there are registered listeners
127 */
128 public function hasListeners(string $eventClass): bool
129 {
130 return !empty($this->listeners[$eventClass]);
131 }
132
133 /**
134 * Remove all listeners for a specific event class.
135 *
136 * @param string $eventClass The event class
137 * @return int The number of listeners removed
138 */
139 public function clearListeners(string $eventClass): int
140 {
141 if (!isset($this->listeners[$eventClass])) {
142 return 0;
143 }
144
145 $count = count($this->listeners[$eventClass]);
146 unset($this->listeners[$eventClass]);
147
148 return $count;
149 }
150
151 /**
152 * Remove all listeners for all event classes.
153 *
154 * @return void
155 */
156 public function clearAllListeners(): void
157 {
158 $this->listeners = [];
159 }
160
161 /**
162 * Get the count of listeners for a specific event class.
163 *
164 * @param string $eventClass The event class
165 * @return int Number of registered listeners
166 */
167 public function getListenerCount(string $eventClass): int
168 {
169 return count($this->listeners[$eventClass] ?? []);
170 }
171 }
172