Dispatcher::dispatchResourcedHandlers()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

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