Passed
Push — main ( f83e77...eadd2b )
by Dimitri
05:50 queued 01:12
created

EventManager::off()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 6

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 6
eloc 9
nc 4
nop 2
dl 0
loc 18
ccs 6
cts 6
cp 1
crap 6
rs 9.2222
c 2
b 1
f 0
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Event;
13
14
use BlitzPHP\Contracts\Event\EventInterface;
15
use BlitzPHP\Contracts\Event\EventManagerInterface;
16
17
/**
18
 * EventManager
19
 *
20
 * @credit      https://www.phpclasses.org/package/9961-PHP-Manage-events-implementing-PSR-14-interface.html - Kiril Savchev <[email protected]>
21
 */
22
class EventManager implements EventManagerInterface
23
{
24
    /**
25
     * Le nom générique de l'événement
26
     */
27
    public const WILDCARD = '*';
28
29
    /**
30
     * Stocke des informations sur les événements
31
     * pour affichage dans la barre d'outils de débogage.
32
     *
33
     * @var array
34
     */
35
    protected static $performanceLog = [];
36
37
    /**
38
     * Créer un objet gestionnaire d'événements
39
     *
40
     * @param array $listeners Listeners initiaux
41
     */
42
    public function __construct(protected array $listeners = [])
43
    {
44
        if (! array_key_exists(self::WILDCARD, $this->listeners)) {
45
            $this->listeners[self::WILDCARD] = [];
46
        }
47
    }
48
49
    public function getListeners(?string $event = null): array
50
    {
51
        if ($event === null) {
52 2
            return array_filter($this->listeners, static fn ($key) => $key !== self::WILDCARD, ARRAY_FILTER_USE_KEY);
53
        }
54
55
        if (! array_key_exists($event, $this->listeners)) {
56 2
            return [];
57
        }
58
59 2
        return $this->listeners[$event] ?? [];
60
    }
61
62
    /**
63
     * {@inheritDoc}
64
     */
65
    public function clearListeners(?string $event = null): void
66
    {
67
        if ($event === null) {
68 9
            $this->listeners = array_filter($this->listeners, static fn ($key) => $key === self::WILDCARD, ARRAY_FILTER_USE_KEY);
69
        } elseif (array_key_exists($event, $this->listeners)) {
70 2
            unset($this->listeners[$event]);
71
        }
72
    }
73
74
    /**
75
     * {@inheritDoc}
76
     */
77
    public function on(string $event, callable $callback, int $priority = 0): bool
78
    {
79
        if (! array_key_exists($event, $this->listeners)) {
80 8
            $this->listeners[$event] = [];
81
        }
82
        if (! array_key_exists($priority, $this->listeners[$event])) {
83 8
            $this->listeners[$event][$priority] = [];
84
        }
85
86
        if (! in_array($callback, $this->listeners[$event][$priority], true)) {
87 8
            $this->listeners[$event][$priority][] = $callback;
88
89 8
            return true;
90
        }
91
92
        return false;
93
    }
94
95
    /**
96
     * @deprecated use on() instead
97
     */
98
    public function attach(string $event, callable $callback, int $priority = 0): bool
99
    {
100
        return $this->on($event, $callback, $priority);
101
    }
102
103
    /**
104
     * {@inheritDoc}
105
     */
106
    public function off(string $event, callable $callback): bool
107
    {
108
        if (! array_key_exists($event, $this->listeners) || ! $this->listeners[$event]) {
109 2
            return false;
110
        }
111
112 2
        $eventsAgregation = $this->listeners[$event];
113
114
        foreach ($eventsAgregation as $priority => $events) {
115
            if (is_array($events) && in_array($callback, $events, true)) {
116 2
                $key = array_search($callback, $events, true);
117 2
                unset($this->listeners[$event][$priority][$key]);
118
119 2
                return true;
120
            }
121
        }
122
123 2
        return false;
124
    }
125
126
    /**
127
     * @deprecated use off() instead
128
     */
129
    public function detach(string $event, callable $callback): bool
130
    {
131
        return $this->off($event, $callback);
132
    }
133
134
    /**
135
     * {@inheritDoc}
136
     */
137
    public function emit($event, $target = null, $argv = [])
138
    {
139
        if (! ($event instanceof EventInterface)) {
140 8
            $event = new Event($event, $target, $argv);
141
        } else {
142
            if ($target) {
143
                $event->setTarget($target);
144
            }
145
            if ($argv) {
146
                $event->setParams($argv);
147
            }
148
        }
149
150 8
        $eventName = $event->getName();
151
        if (! array_key_exists($eventName, $this->listeners)) {
152 2
            $this->listeners[$eventName] = [];
153
        }
154
155
        // $events = array_merge($this->listeners[self::WILDCARD], $this->listeners[$eventName]);
156 8
        $events = $this->listeners[$eventName];
157 8
        $result = null;
158 8
        ksort($events, SORT_NUMERIC);
159
160
        foreach ($events as $priority) {
161
            if (! is_array($priority)) {
162
                continue;
163
            }
164
165
            foreach ($priority as $callback) {
166
                if ($event->isPropagationStopped() || $result === false) {
167 4
                    break 2;
168
                }
169
170 6
                $start = microtime(true);
171
172 6
                $result = $callback($event);
173
174
                if (BLITZ_DEBUG || on_dev()) {
175
                    static::$performanceLog[] = [
176
                        'start' => $start,
177
                        'end'   => microtime(true),
178
                        'event' => strtolower($eventName),
179 6
                    ];
180
                }
181
            }
182
        }
183
184 8
        return $result;
185
    }
186
187
    /**
188
     * @deprecated use emit() instead
189
     *
190
     * @param mixed      $event
191
     * @param mixed|null $target
192
     * @param mixed      $argv
193
     */
194
    public function trigger($event, $target = null, $argv = [])
195
    {
196 2
        return $this->emit($event, $target, $argv);
197
    }
198
199
    /**
200
     * Getter pour les enregistrements du journal des performances.
201
     */
202
    public static function getPerformanceLogs(): array
203
    {
204
        return static::$performanceLog;
205
    }
206
}
207