Passed
Pull Request — master (#6)
by Daniel
04:15
created

EventDispatcher::removeListener()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
namespace Jellyfish\Event;
4
5
use Jellyfish\Event\Exception\NotSupportedTypeException;
6
7
class EventDispatcher implements EventDispatcherInterface
8
{
9
    /**
10
     * @var \Jellyfish\Event\EventQueueProducerInterface
11
     */
12
    protected $eventQueueProducer;
13
14
    /**
15
     * @var array
16
     */
17
    protected $listeners = [
18
        EventListenerInterface::TYPE_SYNC => [],
19
        EventListenerInterface::TYPE_ASYNC => []
20
    ];
21
22
23
    /**
24
     * @param \Jellyfish\Event\EventQueueProducerInterface $eventQueueProducer
25
     */
26
    public function __construct(
27
        EventQueueProducerInterface $eventQueueProducer
28
    ) {
29
        $this->eventQueueProducer = $eventQueueProducer;
30
    }
31
32
    /**
33
     * @param string $eventName
34
     * @param \Jellyfish\Event\EventListenerInterface $listener
35
     *
36
     * @return \Jellyfish\Event\EventDispatcherInterface
37
     */
38
    public function addListener(string $eventName, EventListenerInterface $listener): EventDispatcherInterface
39
    {
40
        $type = $listener->getType();
41
42
        if (!\array_key_exists($eventName, $this->listeners[$type])) {
43
            $this->listeners[$type][$eventName] = [];
44
        }
45
46
        $this->listeners[$type][$eventName][$listener->getIdentifier()] = $listener;
47
48
        return $this;
49
    }
50
51
    /**
52
     * @param string $eventName
53
     * @param \Jellyfish\Event\EventListenerInterface $listener
54
     *
55
     * @return \Jellyfish\Event\EventDispatcherInterface
56
     */
57
    public function removeListener(string $eventName, EventListenerInterface $listener): EventDispatcherInterface
58
    {
59
        $type = $listener->getType();
60
        $listenerIdentifier = $listener->getIdentifier();
61
62
        if (!$this->hasListener($type, $eventName, $listenerIdentifier)) {
63
            return $this;
64
        }
65
66
        unset($this->listeners[$type][$eventName][$listenerIdentifier]);
67
68
        return $this;
69
    }
70
71
    /**
72
     * @param string $eventName
73
     * @param \Jellyfish\Event\EventInterface $event
74
     *
75
     * @return \Jellyfish\Event\EventDispatcherInterface
76
     */
77
    public function dispatch(string $eventName, EventInterface $event): EventDispatcherInterface
78
    {
79
        $this->dispatchSync($eventName, $event);
80
        $this->dispatchAsync($eventName, $event);
81
82
        return $this;
83
    }
84
85
    /**
86
     * @param string $eventName
87
     * @param \Jellyfish\Event\EventInterface $event
88
     *
89
     * @return \Jellyfish\Event\EventDispatcherInterface
90
     */
91
    protected function dispatchSync(string $eventName, EventInterface $event): EventDispatcherInterface
92
    {
93
        $type = EventListenerInterface::TYPE_SYNC;
94
95
        if (!\array_key_exists($eventName, $this->listeners[$type])) {
96
            return $this;
97
        }
98
99
        foreach ($this->listeners[$type][$eventName] as $listener) {
100
            /** @var \Jellyfish\Event\EventListenerInterface $listener */
101
            $listener->handle($event);
102
        }
103
104
        return $this;
105
    }
106
107
    /**
108
     * @param string $eventName
109
     * @param \Jellyfish\Event\EventInterface $event
110
     *
111
     * @return \Jellyfish\Event\EventDispatcherInterface
112
     */
113
    protected function dispatchAsync(string $eventName, EventInterface $event): EventDispatcherInterface
114
    {
115
        $type = EventListenerInterface::TYPE_ASYNC;
116
117
        if (!\array_key_exists($eventName, $this->listeners[$type])) {
118
            return $this;
119
        }
120
121
        foreach ($this->listeners[$type][$eventName] as $listener) {
122
            $this->eventQueueProducer->enqueueEvent($eventName, $event, $listener);
123
        }
124
125
        return $this;
126
    }
127
128
    /**
129
     * @param string|null $type
130
     *
131
     * @return array
132
     *
133
     * @throws \Jellyfish\Event\Exception\NotSupportedTypeException
134
     */
135
    public function getListeners(string $type = null): array
136
    {
137
        if ($type === null) {
138
            return $this->listeners;
139
        }
140
141
        if (!\array_key_exists($type, $this->listeners)) {
142
            throw new NotSupportedTypeException(\sprintf('Given type "%s" is not supported', $type));
143
        }
144
145
        return $this->listeners[$type];
146
    }
147
148
    /**
149
     * @param string $type
150
     * @param string $eventName
151
     * @param string $listenerIdentifier
152
     *
153
     * @return \Jellyfish\Event\EventListenerInterface|null
154
     */
155
    public function getListener(string $type, string $eventName, string $listenerIdentifier): ?EventListenerInterface
156
    {
157
        if (!$this->hasListener($type, $eventName, $listenerIdentifier)) {
158
            return null;
159
        }
160
161
        return $this->listeners[$type][$eventName][$listenerIdentifier];
162
    }
163
164
    /**
165
     * @param string $type
166
     * @param string $eventName
167
     * @param string $listenerIdentifier
168
     *
169
     * @return bool
170
     */
171
    public function hasListener(string $type, string $eventName, string $listenerIdentifier): bool
172
    {
173
        return \array_key_exists($eventName, $this->listeners[$type])
174
            && \array_key_exists($listenerIdentifier, $this->listeners[$type][$eventName]);
175
    }
176
}
177