Passed
Branch master (bf85d9)
by Johannes
05:40
created

EventDispatcher::addSubscriber()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 6.0493

Importance

Changes 0
Metric Value
cc 6
eloc 8
nc 10
nop 1
dl 0
loc 12
ccs 8
cts 9
cp 0.8889
crap 6.0493
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * Copyright 2016 Johannes M. Schmitt <[email protected]>
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace JMS\Serializer\EventDispatcher;
20
21
use JMS\Serializer\Exception\InvalidArgumentException;
22
23
/**
24
 * Light-weight event dispatcher.
25
 *
26
 * This implementation focuses primarily on performance, and dispatching
27
 * events for certain classes. It is not a general purpose event dispatcher.
28
 *
29
 * @author Johannes M. Schmitt <[email protected]>
30
 */
31
class EventDispatcher implements EventDispatcherInterface
32
{
33
    private $listeners = array();
34
    private $classListeners = array();
35
36 3
    public static function getDefaultMethodName($eventName)
37
    {
38 3
        return 'on' . str_replace(array('_', '.'), '', $eventName);
39
    }
40
41
    /**
42
     * Sets the listeners.
43
     *
44
     * @param array $listeners
45
     */
46
    public function setListeners(array $listeners)
47
    {
48
        $this->listeners = $listeners;
49
        $this->classListeners = array();
50
    }
51
52 19
    public function addListener($eventName, $callable, $class = null, $format = null)
53
    {
54 19
        $this->listeners[$eventName][] = array($callable, null === $class ? null : $class, $format);
55 19
        unset($this->classListeners[$eventName]);
56 19
    }
57
58 301
    public function addSubscriber(EventSubscriberInterface $subscriber)
59
    {
60 301
        foreach ($subscriber->getSubscribedEvents() as $eventData) {
61 301
            if (!isset($eventData['event'])) {
62
                throw new InvalidArgumentException(sprintf('Each event must have a "event" key.'));
63
            }
64
65 301
            $method = isset($eventData['method']) ? $eventData['method'] : self::getDefaultMethodName($eventData['event']);
66 301
            $class = isset($eventData['class']) ? $eventData['class'] : null;
67 301
            $format = isset($eventData['format']) ? $eventData['format'] : null;
68 301
            $this->listeners[$eventData['event']][] = array(array($subscriber, $method), $class, $format);
69 301
            unset($this->classListeners[$eventData['event']]);
70
        }
71 301
    }
72
73 207
    public function hasListeners($eventName, $class, $format)
74
    {
75 207
        if (!isset($this->listeners[$eventName])) {
76 179
            return false;
77
        }
78
79 184
        if (!isset($this->classListeners[$eventName][$class][$format])) {
80 184
            $this->classListeners[$eventName][$class][$format] = $this->initializeListeners($eventName, $class, $format);
81
        }
82
83 184
        return !!$this->classListeners[$eventName][$class][$format];
84
    }
85
86 193
    public function dispatch($eventName, $class, $format, Event $event)
87
    {
88 193
        if (!isset($this->listeners[$eventName])) {
89 5
            return;
90
        }
91
92 193
        if (!isset($this->classListeners[$eventName][$class][$format])) {
93 19
            $this->classListeners[$eventName][$class][$format] = $this->initializeListeners($eventName, $class, $format);
94
        }
95
96 193
        foreach ($this->classListeners[$eventName][$class][$format] as $listener) {
97
98 193
            if ($event->isPropagationStopped()) {
99 10
                break;
100
            }
101
102 193
            \call_user_func($listener, $event, $eventName, $class, $format, $this);
103
        }
104 193
    }
105
106
    /**
107
     * @param string $eventName
108
     * @param string $loweredClass
109
     * @param string $format
110
     *
111
     * @return array An array of listeners
112
     */
113 198
    protected function initializeListeners($eventName, $loweredClass, $format)
114
    {
115 198
        $listeners = array();
116 198
        foreach ($this->listeners[$eventName] as $listener) {
117 198
            if (null !== $listener[1] && $loweredClass !== $listener[1]) {
118 10
                continue;
119
            }
120 198
            if (null !== $listener[2] && $format !== $listener[2]) {
121 3
                continue;
122
            }
123
124 198
            $listeners[] = $listener[0];
125
        }
126
127 198
        return $listeners;
128
    }
129
}
130