Completed
Push — master ( 000ca1...575b16 )
by Pierre
03:18
created

Dispatcher   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 160
ccs 36
cts 36
cp 1
rs 10
wmc 14

7 Methods

Rating   Name   Duplication   Size   Complexity  
A unsubscribe() 0 10 2
A subscribeClosure() 0 9 1
A subscribe() 0 8 1
A publish() 0 9 1
A dispatchAllHandlers() 0 9 3
A dispatchResourcedEventedHandlers() 0 11 3
A dispatchResourcedHandlers() 0 10 3
1
<?php
2
3
namespace App\Component\Pubsub;
4
5
use Closure;
6
use App\Component\Pubsub\EventInterface;
7
use App\Component\Pubsub\ClosureWrapper;
8
9
class Dispatcher implements DispatcherInterface
10
{
11
12
    /**
13
     * listener stack.
14
     * Struct : [resName][event][hash]
15
     *
16
     * @var array
17
     */
18
    protected $stack = array();
19
20
    /**
21
     * Subscribes the listener to the resource's events.
22
     * If $resName is *,
23
     * then the listener will be dispatched when the specified event
24
     * is fired.
25
     * If $event is *,
26
     * then the listener will be dispatched
27
     * for any dispatched event of the specified resource.
28
     * If $resName and $event is *,
29
     * the listener will be dispatched
30
     * for any dispatched event for any resource.
31
     *
32
     * @param ListenerInterface $listener
33
     * @param String $resName
34
     * @param Mixed $event
35
     * @return string
36
     */
37 1
    public function subscribe(
38
        ListenerInterface $listener,
39
        $resName = self::ANY,
40
        $event = self::ANY
41
    ): string {
42 1
        $hash = $listener->hash();
43 1
        $this->stack[$resName][$event][$hash] = $listener;
44 1
        return $hash;
45
    }
46
47
    /**
48
     * Subscribes the listener to the resource's events.
49
     * If $resName is *,
50
     * then the listener will be dispatched when the specified event
51
     * is fired.
52
     * If $event is *,
53
     * then the listener will be dispatched
54
     * for any dispatched event of the specified resource.
55
     * If $resName and $event is *,
56
     * the listener will be dispatched
57
     * for any dispatched event for any resource.
58
     *
59
     * @param Closure $closure
60
     * @param String $resName
61
     * @param Mixed $event
62
     * @return string
63
     */
64 5
    public function subscribeClosure(
65
        Closure $closure,
66
        $resName = self::ANY,
67
        $eventName = self::ANY
68
    ): string {
69 5
        $listener = new ClosureWrapper($closure);
70 5
        $hash = $listener->hash();
71 5
        $this->stack[$resName][$eventName][$hash] = $listener;
72 5
        return $hash;
73
    }
74
75
    /**
76
     * Unsubscribes the listener from the resource's events
77
     *
78
     * @param string $hash
79
     * @param String $resName
80
     * @param Mixed $event
81
     * @return boolean
82
     */
83 3
    public function unsubscribe(
84
        string $hash,
85
        $resName = self::ANY,
86
        $eventName = self::ANY
87
    ): bool {
88 3
        if (isset($this->stack[$resName][$eventName][$hash])) {
89 2
            unset($this->stack[$resName][$eventName][$hash]);
90 2
            return true;
91
        }
92 1
        return false;
93
    }
94
95
    /**
96
     * Publishes an event to all the listeners
97
     * listening to the specified event
98
     * for the specified resource
99
     *
100
     * @param EventInterface $event
101
     * @return Dispatcher
102
     */
103 3
    public function publish(EventInterface $event): DispatcherInterface
104
    {
105 3
        $resName = $event->getResourceName();
106 3
        $eventName = $event->getEventName();
107
        $this
108 3
            ->dispatchAllHandlers($event)
109 3
            ->dispatchResourcedHandlers($resName, $event)
110 3
            ->dispatchResourcedEventedHandlers($resName, $eventName, $event);
111 3
        return $this;
112
    }
113
114
    /**
115
     * dispatch to all handlers the wildcard handlers
116
     *
117
     * @param EventInterface $event
118
     * @return void
119
     */
120 1
    protected function dispatchAllHandlers(
121
        EventInterface $event
122
    ): DispatcherInterface {
123 1
        if (isset($this->stack[self::ANY][self::ANY])) {
124 1
            foreach ($this->stack[self::ANY][self::ANY] as $listener) {
125 1
                $listener->publish($event);
126
            }
127
        }
128 1
        return $this;
129
    }
130
131
    /**
132
     * dispatch to handlers identified by resource name
133
     * despite the event
134
     *
135
     * @param string $resName
136
     * @param EventInterface $event
137
     * @return void
138
     */
139 1
    protected function dispatchResourcedHandlers(
140
        string $resName,
141
        EventInterface $event
142
    ): DispatcherInterface {
143 1
        if (isset($this->stack[$resName][self::ANY])) {
144 1
            foreach ($this->stack[$resName][self::ANY] as $listener) {
145 1
                $listener->publish($event);
146
            }
147
        }
148 1
        return $this;
149
    }
150
151
    /**
152
     * dispatch to handlers identified by resource name and event name
153
     *
154
     * @param string $resName
155
     * @param EventInterface $event
156
     * @return void
157
     */
158 1
    protected function dispatchResourcedEventedHandlers(
159
        string $resName,
160
        string $eventName,
161
        EventInterface $event
162
    ): DispatcherInterface {
163 1
        if (isset($this->stack[$resName][$eventName])) {
164 1
            foreach ($this->stack[$resName][$eventName] as $listener) {
165 1
                $listener->publish($event);
166
            }
167
        }
168 1
        return $this;
169
    }
170
}
171