Completed
Push — master ( 632927...807d49 )
by Anton
02:47
created

EventEmitterGlobal::getMaxListeners()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @Author : a.zinovyev
4
 * @Package: emittr
5
 * @License: http://www.opensource.org/licenses/mit-license.php
6
 */
7
8
namespace xobotyi\emittr;
9
10
11
final class EventEmitterGlobal extends EventEmitterStatic
12
{
13
    /**
14
     * @var array[]
15
     */
16
    private static $classesListeners = [];
17
18
    public static function loadClassesEventListeners(array $classesListeners) :void {
19
        foreach ($classesListeners as $className => &$listeners) {
20
            if (!isset(self::$classesListeners[$className])) {
21
                self::$classesListeners[$className] = [];
22
            }
23
24
            foreach ($listeners as $eventName => &$callbacks) {
25
                if (self::isValidCallback($callbacks)) {
26
                    self::storeCallback(self::$classesListeners[$className], $eventName, $callbacks);
27
28
                    continue;
29
                }
30
                else if (is_array($callbacks)) {
31
                    foreach ($callbacks as &$callback) {
32
                        self::storeCallback(self::$classesListeners[$className], $eventName, $callback);
33
                    }
34
35
                    continue;
36
                }
37
38
                throw new Exception\EventEmitter("Event callback has to be a callable or an array of two elements representing classname and method to call or array of them");
39
            }
40
        }
41
    }
42
43
    public static function getListeners(?string $className = null, ?string $eventName = null) :array {
44
        return $className ? $eventName ? self::$classesListeners[$className][$eventName] ?? [] : self::$classesListeners[$className] ?? [] : self::$classesListeners;
45
    }
46
47
    public static function __callStatic($name, $arguments) {
48
        throw new \Error('Call to undefined method ' . get_called_class() . '::' . $name . '()');
49
    }
50
51
    public static function on(string $className, string $eventName, $callback) :void {
52
        if (!(self::$classesListeners[$className])) {
53
            self::$classesListeners[$className] = [];
54
        }
55
56
        self::storeCallback(self::$classesListeners[$className], $eventName, $callback, false, false, self::$staticMaxListeners[get_called_class()] ?? 10);
57
    }
58
59
    public static function once(string $className, string $eventName, $callback) :void {
60
        if (!(self::$classesListeners[$className])) {
61
            self::$classesListeners[$className] = [];
62
        }
63
64
        self::storeCallback(self::$classesListeners[$className], $eventName, $callback, true, false, self::$staticMaxListeners[get_called_class()] ?? 10);
65
    }
66
67
    public static function prependListener(string $className, string $eventName, $callback) :void {
68
        if (!(self::$classesListeners[$className])) {
69
            self::$classesListeners[$className] = [];
70
        }
71
72
        self::storeCallback(self::$classesListeners[$className], $eventName, $callback, false, true, self::$staticMaxListeners[get_called_class()] ?? 10);
73
    }
74
75
    public static function prependOnceListener(string $className, string $eventName, $callback) :void {
76
        if (!(self::$classesListeners[$className])) {
77
            self::$classesListeners[$className] = [];
78
        }
79
80
        self::storeCallback(self::$classesListeners[$className], $eventName, $callback, true, true, self::$staticMaxListeners[get_called_class()] ?? 10);
81
    }
82
83
    public static function removeListener(string $className, string $eventName, $callback) :void {
84
        if (!(self::$classesListeners[$className][$eventName] ?? false)) {
85
            return;
86
        }
87
88
        self::$classesListeners[$className][$eventName] = array_filter(self::$classesListeners[$className][$eventName],
89
            function ($item) use (&$callback) { return $item[1] !== $callback; });
90
91
        if (empty(self::$classesListeners[$className][$eventName])) {
92
            unset(self::$classesListeners[$className][$eventName]);
93
            self::$classesListeners[$className] = array_filter(self::$classesListeners[$className], function ($item) { return !empty($item); });
94
        }
95
    }
96
97
    public static function removeAllListeners(string $className, string $eventName) :void {
98
        if (!(self::$classesListeners[$className] ?? false)) {
99
            return;
100
        }
101
102
        if ($eventName) {
103
            if (!(self::$classesListeners[$className][$eventName] ?? false)) {
104
                return;
105
            }
106
107
            unset(self::$classesListeners[$className][$eventName]);
108
            self::$classesListeners[$className] = array_filter(self::$classesListeners[$className], function ($item) { return !empty($item); });
109
110
            return;
111
        }
112
113
        self::$classesListeners[$className] = [];
114
    }
115
116
    public static function getMaxListeners() :int {
117
        return self::$staticMaxListeners[get_called_class()] ?? 10;
118
    }
119
120
    public static function setMaxListeners(int $listenersCount) :void {
121
        if ($listenersCount < 0) {
122
            throw new \InvalidArgumentException('Listeners count must be greater or equal 0, got ' . $listenersCount);
123
        }
124
125
        self::$staticMaxListeners[get_called_class()] = $listenersCount;
126
    }
127
128
    public static function propagateClassEvent(Event $evt) {
129
        if (substr($evt->getSourceClass(), 0, 15) === 'class@anonymous') {
130
            return true;
131
        }
132
        if (!($listeners = &self::$classesListeners[$evt->getSourceClass()][$evt->getEventName()] ?? false)) {
133
            return true;
134
        }
135
136
        $res = true;
137
138
        foreach ($listeners as $key => &$listener) {
139
            call_user_func($listener[1], $evt);
140
141
            if ($listener[0]) {
142
                unset($listeners[$key]);
143
            }
144
145
            if (!$evt->isPropagatable()) {
146
                $res = false;
147
                break;
148
            }
149
        }
150
151
        if (!count($listeners)) {
152
            unset($listeners);
153
        }
154
155
        return $res;
156
    }
157
}