PrioritizedListenersForEvent::addListener()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Event;
6
7
use const SORT_NUMERIC;
8
9
/**
10
 * @internal
11
 */
12
class PrioritizedListenersForEvent
13
{
14
    /** @var array<int, array<int,callable>> */
15
    private $listeners = [];
16
    /** @var array<int,callable> */
17
    private $sortedListeners = [];
18
    /** @var bool */
19
    private $isSorted = false;
20
    /** @var bool */
21
    private $containsOneTimeListener = false;
22
23
    public function addListener(callable $listener, int $priority): void
24
    {
25
        $this->isSorted = false;
26
        $this->listeners[$priority][] = $listener;
27
28
        if ($listener instanceof OneTimeListener) {
29
            $this->containsOneTimeListener = true;
30
        }
31
    }
32
33
    public function getListeners(): iterable
34
    {
35
        if ($this->isSorted === false) {
36
            $this->sortListeners();
37
        }
38
39
        $listeners = $this->sortedListeners;
40
41
        if ($this->containsOneTimeListener) {
42
            $this->removeOneTimeListeners();
43
        }
44
45
        return $listeners;
46
    }
47
48
    private function sortListeners(): void
49
    {
50
        $this->isSorted = true;
51
        krsort($this->listeners, SORT_NUMERIC);
52
53
        foreach ($this->listeners as $group) {
54
            foreach ($group as $listener) {
55
                $this->sortedListeners[] = $listener;
56
            }
57
        }
58
    }
59
60
    private function removeOneTimeListeners(): void
61
    {
62
        $filter = static function ($listener): bool {
63
            return $listener instanceof OneTimeListener === false;
64
        };
65
66
        $this->sortedListeners = array_filter($this->sortedListeners, $filter);
67
68
        foreach ($this->listeners as $priority => $listeners) {
69
            $this->listeners[$priority] = array_filter($this->sortedListeners, $filter);
70
        }
71
    }
72
}
73