Completed
Push — master ( 18f62e...632927 )
by Anton
05:08
created

EventEmitterGlobal::removeListener()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 3
dl 0
loc 11
rs 9.4285
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 propagateClassEvent(Event $evt) {
117
        if (substr($evt->getSourceClass(), 0, 15) === 'class@anonymous') {
118
            return true;
119
        }
120
        if (!($listeners = &self::$classesListeners[$evt->getSourceClass()][$evt->getEventName()] ?? false)) {
121
            return true;
122
        }
123
124
        $res = true;
125
126
        foreach ($listeners as $key => &$listener) {
127
            call_user_func($listener[1], $evt);
128
129
            if ($listener[0]) {
130
                unset($listeners[$key]);
131
            }
132
133
            if (!$evt->isPropagatable()) {
134
                $res = false;
135
                break;
136
            }
137
        }
138
139
        if (!count($listeners)) {
140
            unset($listeners);
141
        }
142
143
        return $res;
144
    }
145
}