-
Notifications
You must be signed in to change notification settings - Fork 45
/
EventDispatcher.php
113 lines (89 loc) · 3.7 KB
/
EventDispatcher.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
declare(strict_types=1);
namespace League\Event;
use Psr\EventDispatcher\ListenerProviderInterface;
use Psr\EventDispatcher\StoppableEventInterface;
class EventDispatcher implements EventDispatchingListenerRegistry
{
/**
* @var ListenerProviderInterface
*/
protected $listenerProvider;
public function __construct(ListenerProviderInterface $listenerProvider = null)
{
$this->listenerProvider = $listenerProvider instanceof ListenerProviderInterface
? $listenerProvider
: new PrioritizedListenerRegistry();
}
public function dispatch(object $event): object
{
$listeners = $this->listenerProvider->getListenersForEvent($event);
$event instanceof StoppableEventInterface
? $this->dispatchStoppableEvent($listeners, $event)
: $this->dispatchUnstoppableEvent($listeners, $event);
return $event;
}
public function dispatchGeneratedEvents(EventGenerator $generator): void
{
foreach ($generator->releaseEvents() as $event) {
$this->dispatch($event);
}
}
private function dispatchStoppableEvent(iterable $listeners, StoppableEventInterface $event): void
{
foreach ($listeners as $listener) {
if ($event->isPropagationStopped()) {
break;
}
$listener($event);
}
}
private function dispatchUnstoppableEvent(iterable $listeners, object $event): void
{
foreach ($listeners as $listener) {
$listener($event);
}
}
public function subscribeTo(string $event, callable $listener, int $priority = ListenerPriority::NORMAL): void
{
if ( ! $this->listenerProvider instanceof ListenerRegistry) {
throw UnableToSubscribeListener::becauseTheListenerProviderDoesNotAcceptListeners($this->listenerProvider);
}
$this->listenerProvider->subscribeTo($event, $listener, $priority);
}
public function subscribeOnceTo(string $event, callable $listener, int $priority = ListenerPriority::NORMAL): void
{
if ( ! $this->listenerProvider instanceof ListenerRegistry) {
throw UnableToSubscribeListener::becauseTheListenerProviderDoesNotAcceptListeners($this->listenerProvider);
}
$this->listenerProvider->subscribeOnceTo($event, $listener, $priority);
}
public function subscribeListenersFrom(ListenerSubscriber $subscriber): void
{
if ( ! $this->listenerProvider instanceof ListenerRegistry) {
throw UnableToSubscribeListener::becauseTheListenerProviderDoesNotAcceptListeners($this->listenerProvider);
}
$this->listenerProvider->subscribeListenersFrom($subscriber);
}
public function unsubscribeFor(string $event, callable $listener): void
{
if ( ! $this->listenerProvider instanceof ListenerRegistry) {
throw UnableToUnsubscribeListener::becauseTheListenerProviderIsNotARegistry($this->listenerProvider);
}
$this->listenerProvider->unsubscribeFor($event, $listener);
}
public function unsubscribeAllFor(string $event): void
{
if ( ! $this->listenerProvider instanceof ListenerRegistry) {
throw UnableToUnsubscribeListener::becauseTheListenerProviderIsNotARegistry($this->listenerProvider);
}
$this->listenerProvider->unsubscribeAllFor($event);
}
public function unsubscribeAll(callable $listener): void
{
if ( ! $this->listenerProvider instanceof ListenerRegistry) {
throw UnableToUnsubscribeListener::becauseTheListenerProviderIsNotARegistry($this->listenerProvider);
}
$this->listenerProvider->unsubscribeAll($listener);
}
}