Completed
Push — master ( 809d1b...4afa81 )
by n
01:51
created

EventManager   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 16
c 0
b 0
f 0
lcom 1
cbo 2
dl 0
loc 93
ccs 0
cts 55
cp 0
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A attach() 0 11 2
A clearListeners() 0 6 2
A detach() 0 11 4
A trigger() 0 15 4
A getListenersForEvent() 0 19 4
1
<?php
2
declare(strict_types=1);
3
4
namespace N1215\Tsukuyomi\Event;
5
6
class EventManager implements EventManagerInterface
7
{
8
    /**
9
     * @var array
10
     *
11
     * ex)
12
     * [
13
     *     'eventName' => [
14
     *         ['priority' => 1, 'callback' => [self::class, 'methodName']]
15
     *     ],
16
     * ];
17
     */
18
    private $listenerMapping = [];
19
20
    /**
21
     * @inheritDoc
22
     */
23
    public function attach(string $event, callable $callback, int $priority = 0)
24
    {
25
        if (!isset($this->listenerMapping[$event])) {
26
            $this->listenerMapping[$event] = [];
27
        }
28
29
        $this->listenerMapping[$event][] = [
30
            'priority' => $priority,
31
            'callback' => $callback
32
        ];
33
    }
34
35
    /**
36
     * @inheritDoc
37
     */
38
    public function clearListeners(string $event)
39
    {
40
        if (isset($this->listenerMapping[$event])) {
41
            unset($this->listenerMapping[$event]);
42
        }
43
    }
44
45
    /**
46
     * @inheritDoc
47
     */
48
    public function detach(string $event, callable $callback)
49
    {
50
        foreach ($this->listenerMapping as $event => $listeners) {
51
            foreach ($listeners as $index => $listener) {
52
                if ($listeners['callback'] === $callback) {
53
                    unset($listeners[$index]);
54
                }
55
            }
56
            $this->listenerMapping[$event] = array_values($listeners);
57
        }
58
    }
59
60
    /**
61
     * @inheritDoc
62
     */
63
    public function trigger($event, $target = null, array $argv = [])
64
    {
65
        if (is_string($event)) {
66
            $event = new Event($event, $target, $argv);
67
        }
68
69
        $listeners = $this->getListenersForEvent($event);
70
71
        foreach ($listeners as $listener) {
72
            call_user_func($listener['callback'], $event);
73
            if ($event->isPropagationStopped()) {
74
                return;
75
            }
76
        }
77
    }
78
79
    private function getListenersForEvent(EventInterface $event): array
80
    {
81
        $eventName = $event->getName();
82
83
        if (!isset($this->listenerMapping[$eventName])) {
84
            return [];
85
        }
86
87
        $listeners = $this->listenerMapping[$eventName];
88
89
        uasort($listeners, function ($a, $b) {
90
            if ($a['priority'] === $b['priority']) {
91
                return 0;
92
            }
93
            return $a['priority'] < $b['priority'] ? -1 : 1;
94
        });
95
96
        return $listeners;
97
    }
98
}
99