Completed
Push — master ( 39a9ed...cbad56 )
by Pierre
03:38
created

anonymous//src/App/Component/Pubsub/Dispatcher.php$0   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 55
ccs 0
cts 15
cp 0
rs 10
c 1
b 0
f 0
wmc 6
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 2
    public function subscribeClosure(
65
        Closure $closure,
66
        $resName = self::ANY,
67
        $eventName = self::ANY
68
    ): string {
69 2
        $listener = new ClosureWrapper($closure);
70 2
        $hash = $listener->hash();
71 2
        $this->stack[$resName][$eventName][$hash] = $listener;
72 2
        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 1
    public function publish(EventInterface $event): DispatcherInterface
104
    {
105 1
        $resName = $event->getResourceName();
106 1
        $eventName = $event->getEventName();
107
        $this
108 1
            ->dispatchAllHandlers($event)
109 1
            ->dispatchResourcedHandlers($resName, $event)
110 1
            ->dispatchResourcedEventedHandlers($resName, $eventName, $event);
111 1
        return $this;
112
    }
113
114
    /**
115
     * dispatch to all handlers the wildcard handlers
116
     *
117
     * @param EventInterface $event
118
     * @return void
119
     */
120
    protected function dispatchAllHandlers(
121
        EventInterface $event
122
    ): DispatcherInterface {
123
        if (isset($this->stack[self::ANY][self::ANY])) {
124
            foreach ($this->stack[self::ANY][self::ANY] as $listener) {
125
                $listener->publish($event);
126
            }
127
        }
128
        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
    protected function dispatchResourcedHandlers(
140
        string $resName,
141
        EventInterface $event
142
    ): DispatcherInterface {
143
        if (isset($this->stack[$resName][self::ANY])) {
144
            foreach ($this->stack[$resName][self::ANY] as $listener) {
145
                $listener->publish($event);
146
            }
147
        }
148
        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
    protected function dispatchResourcedEventedHandlers(
159
        string $resName,
160
        string $eventName,
161
        EventInterface $event
162
    ): DispatcherInterface {
163
        if (isset($this->stack[$resName][$eventName])) {
164
            foreach ($this->stack[$resName][$eventName] as $listener) {
165
                $listener->publish($event);
166
            }
167
        }
168
        return $this;
169
    }
170
}
171