EventManager::attach()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 3
crap 2
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 8
    public function attach(string $event, callable $callback, int $priority = 0): bool
24
    {
25 8
        if (!isset($this->listenerMapping[$event])) {
26 8
            $this->listenerMapping[$event] = [];
27
        }
28
29 8
        $this->listenerMapping[$event][] = [
30 8
            'priority' => $priority,
31 8
            'callback' => $callback
32
        ];
33
34 8
        return true;
35
    }
36
37
    /**
38
     * @inheritDoc
39
     */
40 2
    public function detach(string $event, callable $callback): bool
41
    {
42 2
        foreach ($this->listenerMapping as $event => $listeners) {
43 2
            foreach ($listeners as $index => $listener) {
44 2
                if ($listener['callback'] === $callback) {
45 2
                    unset($listeners[$index]);
46
                }
47
            }
48 2
            $this->listenerMapping[$event] = array_values($listeners);
49
        }
50
51 2
        return true;
52
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57 2
    public function clearListeners(string $event): void
58
    {
59 2
        if (isset($this->listenerMapping[$event])) {
60 2
            unset($this->listenerMapping[$event]);
61
        }
62 2
    }
63
64
    /**
65
     * @inheritDoc
66
     */
67 8
    public function trigger($event, $target = null, array $argv = [])
68
    {
69 8
        if (is_string($event)) {
70 1
            $event = new Event($event, $target, $argv);
71
        }
72
73 8
        $listeners = $this->getListenersForEvent($event);
74
75 8
        foreach ($listeners as $listener) {
76 6
            call_user_func($listener['callback'], $event);
77 6
            if ($event->isPropagationStopped()) {
78 6
                return;
79
            }
80
        }
81 7
    }
82
83 8
    private function getListenersForEvent(EventInterface $event): array
84
    {
85 8
        $eventName = $event->getName();
86
87 8
        if (!isset($this->listenerMapping[$eventName])) {
88 1
            return [];
89
        }
90
91 7
        $listeners = $this->listenerMapping[$eventName];
92
93
        uasort($listeners, function ($a, $b) {
94 2
            if ($a['priority'] === $b['priority']) {
95 1
                return 0;
96
            }
97 2
            return $a['priority'] < $b['priority'] ? -1 : 1;
98 7
        });
99
100 7
        return $listeners;
101
    }
102
}
103