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

EventManager::emit()   C

Complexity

Conditions 12
Paths 40

Size

Total Lines 48
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 13.4171

Importance

Changes 4
Bugs 1 Features 0
Metric Value
cc 12
eloc 27
c 4
b 1
f 0
nc 40
nop 3
dl 0
loc 48
ccs 11
cts 14
cp 0.7856
crap 13.4171
rs 6.9666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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