Completed
Push — master ( a1c249...c4799c )
by Taosikai
29:01 queued 16:32
created

Dispatcher::dispatch()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 10
nc 12
nop 2
1
<?php
2
3
/*
4
 * This file is part of the slince/event-dispatcher package.
5
 *
6
 * (c) Slince <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Slince\EventDispatcher;
13
14
use Slince\EventDispatcher\Exception\InvalidArgumentException;
15
16
class Dispatcher implements DispatcherInterface
17
{
18
    /**
19
     * Array of listeners.
20
     *
21
     * @var ListenerPriorityQueue[]
22
     */
23
    protected $listeners = [];
24
25
    /**
26
     * {@inheritdoc}
27
     */
28
    public function dispatch($eventName, EventInterface $event = null)
29
    {
30
        if ($eventName instanceof EventInterface) {
31
            $event = $eventName;
32
        } elseif (is_null($event)) {
33
            $event = new Event($eventName, null);
34
        }
35
        if (isset($this->listeners[$event->getName()])) {
36
            foreach ($this->listeners[$event->getName()] as $listener) {
37
                if ($event->isPropagationStopped()) {
38
                    break;
39
                }
40
                call_user_func([$listener, 'handle'], $event);
41
            }
42
        }
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function addListener($eventName, $listener, $priority = self::PRIORITY_DEFAULT)
49
    {
50
        if (!isset($this->listeners[$eventName])) {
51
            $this->listeners[$eventName] = new ListenerPriorityQueue();
52
        }
53
        if (is_callable($listener)) {
54
            $listener = CallableListener::createFromCallable($listener);
55
        }
56
        if (!$listener instanceof ListenerInterface) {
57
            throw new InvalidArgumentException('The listener should be the implementation of the listenerInterface or callable');
58
        }
59
        $this->listeners[$eventName]->insert($listener, $priority);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function addSubscriber(SubscriberInterface $subscriber)
66
    {
67
        foreach ($subscriber->getSubscribedEvents() as $eventName => $action) {
68
            $this->addListener($eventName, [$subscriber, $action]);
69
        }
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function removeListener($eventName, $listener)
76
    {
77
        if (empty($this->listeners[$eventName])) {
78
            return;
79
        }
80
        if (is_callable($listener) && false === ($listener = CallableListener::findByCallable($listener))) {
81
            return;
82
        }
83
        $this->listeners[$eventName]->detach($listener);
0 ignored issues
show
Documentation introduced by
$listener is of type false|callable, but the function expects a object<Slince\EventDispatcher\ListenerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function removeSubscriber(SubscriberInterface $subscriber)
90
    {
91
        foreach ($subscriber->getSubscribedEvents() as $eventName => $action) {
92
            $this->removeListener($eventName, [$subscriber, $action]);
93
        }
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function removeAllListeners($eventName = null)
100
    {
101
        if (!is_null($eventName) && isset($this->listeners[$eventName])) {
102
            $this->listeners[$eventName]->clear();
103
        } else {
104
            foreach ($this->listeners as $queue) {
105
                $queue->clear();
106
            }
107
        }
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public function hasListener($eventName, $listener)
114
    {
115
        if (!isset($this->listeners[$eventName])) {
116
            return false;
117
        }
118
        if (is_callable($listener)) {
119
            $listener = CallableListener::findByCallable($listener);
120
        }
121
122
        return $this->listeners[$eventName]->contains($listener);
0 ignored issues
show
Security Bug introduced by
It seems like $listener can also be of type false; however, Slince\EventDispatcher\L...iorityQueue::contains() does only seem to accept object<Slince\EventDispatcher\ListenerInterface>, did you maybe forget to handle an error condition?
Loading history...
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function getListeners($eventName = null)
129
    {
130
        if (!is_null($eventName)) {
131
            return isset($this->listeners[$eventName]) ?
132
                $this->listeners[$eventName]->all() : [];
133
        } else {
134
            $listeners = [];
135
            foreach ($this->listeners as $queue) {
136
                $listeners = array_merge($listeners, $queue->all());
137
            }
138
139
            return $listeners;
140
        }
141
    }
142
}
143