Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
43.48% |
10 / 23 |
|
25.00% |
1 / 4 |
CRAP | |
0.00% |
0 / 1 |
EventSubscriberBase | |
43.48% |
10 / 23 |
|
25.00% |
1 / 4 |
28.06 | |
0.00% |
0 / 1 |
initEvents | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
initSubscriber | |
37.50% |
3 / 8 |
|
0.00% |
0 / 1 |
7.91 | |||
registerListenerMethod | |
50.00% |
3 / 6 |
|
0.00% |
0 / 1 |
2.50 | |||
registerListeners | |
37.50% |
3 / 8 |
|
0.00% |
0 / 1 |
5.20 |
1 | <?php |
2 | |
3 | namespace MediaWiki\DomainEvent; |
4 | |
5 | use InvalidArgumentException; |
6 | use LogicException; |
7 | |
8 | /** |
9 | * Base class for classes that implement DomainEventSubscriber. |
10 | * |
11 | * This class provides a default implementation of registerListeners() that will |
12 | * attempt to find listener methods for the events defined in the constructor. |
13 | * Listener methods must have a name based on the event type, following the |
14 | * pattern "handle{$eventType}EventAfterCommit". The "AfterCommit" suffix |
15 | * specifies the dispatch mode. More dispatch modes will be defined in the |
16 | * future. |
17 | * |
18 | * Subclasses can either override registerListeners() and register listeners |
19 | * directly with the given DomainEventSource, or they can rely on the default |
20 | * implementation of registerListeners() which will automatically register |
21 | * method for each event passed to the constructor based on a naming convention. |
22 | * |
23 | * @since 1.44 |
24 | * @unstable until 1.45, should become stable to extend |
25 | */ |
26 | abstract class EventSubscriberBase implements InitializableDomainEventSubscriber { |
27 | |
28 | /** |
29 | * @var string[] |
30 | */ |
31 | private array $eventTypes = []; |
32 | |
33 | /** |
34 | * May be called from the constructor of subclasses that want to |
35 | * directly specify the list of events. |
36 | * |
37 | * @param string[] $events |
38 | */ |
39 | protected function initEvents( array $events ): void { |
40 | $this->initSubscriber( [ 'events' => $events ] ); |
41 | } |
42 | |
43 | /** |
44 | * Called by DomainEventDispatcher to provide access to the list of events to |
45 | * subscribe to and any other relevant information from the extension.json. |
46 | * |
47 | * @param array $options the object spec describing the subscriber, typically |
48 | * from extension.json. |
49 | */ |
50 | public function initSubscriber( array $options ): void { |
51 | if ( !isset( $options['events'] ) ) { |
52 | throw new InvalidArgumentException( '$options must contain the "events" key' ); |
53 | } |
54 | |
55 | if ( $this->eventTypes && $options['events'] != $this->eventTypes ) { |
56 | throw new InvalidArgumentException( |
57 | 'A different set of events was provided previously, ' . |
58 | 'probably by a call to initEvents().' |
59 | ); |
60 | } |
61 | |
62 | $this->eventTypes = $options['events']; |
63 | } |
64 | |
65 | protected function registerListenerMethod( |
66 | DomainEventSource $eventSource, |
67 | string $eventType, |
68 | ?string $method = null |
69 | ) { |
70 | // TODO: use a different prefix, dispatch on dispatch mode |
71 | $method ??= "handle{$eventType}EventAfterCommit"; |
72 | |
73 | if ( !method_exists( $this, $method ) ) { |
74 | throw new LogicException( |
75 | "Missing listener method $method on " . get_class( $this ) |
76 | ); |
77 | } |
78 | |
79 | $eventSource->registerListener( $eventType, [ $this, $method ] ); |
80 | } |
81 | |
82 | /** |
83 | * This default implementation of registerListeners() will automatically |
84 | * register a listener method for each event passed to initEvents() or |
85 | * initSubscriber(). The methods have to start with "handler" followed |
86 | * by the name of the event followed by "Event" followed by an appropriate |
87 | * suffix, e.g. handlePageUpdatedEventAfterCommit(). |
88 | * |
89 | * @stable to override |
90 | */ |
91 | public function registerListeners( DomainEventSource $eventSource ): void { |
92 | if ( !$this->eventTypes ) { |
93 | throw new LogicException( |
94 | 'Subclassed of EventSubscriberBase must either override ' . |
95 | 'registerListeners or provide a list of event types via ' . |
96 | 'initSubscriber() or initEvents().' |
97 | ); |
98 | } |
99 | |
100 | foreach ( $this->eventTypes as $type ) { |
101 | $this->registerListenerMethod( $eventSource, $type ); |
102 | } |
103 | } |
104 | |
105 | } |