|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Event; |
|
4
|
|
|
|
|
5
|
|
|
use Psr\EventManager\EventManagerInterface; |
|
6
|
|
|
use Psr\EventManager\EventInterface; |
|
7
|
|
|
use Event\Event; |
|
8
|
|
|
use Event\ListenerQueue; |
|
9
|
|
|
|
|
10
|
|
|
class EventManager implements EventManagerInterface |
|
11
|
|
|
{ |
|
12
|
|
|
private $listenersHeap = []; |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* Attaches a listener to an event |
|
16
|
|
|
* |
|
17
|
|
|
* @param string $event the event to attach too |
|
18
|
|
|
* @param callable $callback a callable function |
|
19
|
|
|
* @param int $priority the priority at which the $callback executed |
|
20
|
|
|
* @return bool true on success false on failure |
|
21
|
|
|
*/ |
|
22
|
|
|
public function attach($event, $callback, $priority = 0) |
|
23
|
|
|
{ |
|
24
|
|
|
if (is_string($event) |
|
25
|
|
|
&& is_callable($callback) |
|
26
|
|
|
&& is_integer($priority)) { |
|
27
|
|
|
if (!array_key_exists($event, $this->listenersHeap)) { |
|
28
|
|
|
$this->listenersHeap[$event] = new ListenerQueue; |
|
29
|
|
|
} |
|
30
|
|
|
|
|
31
|
|
|
$this->listenersHeap[$event]->add($callback, $priority); |
|
32
|
|
|
|
|
33
|
|
|
return true; |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
return false; |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* Detaches a listener from an event |
|
41
|
|
|
* |
|
42
|
|
|
* @param string $event the event to attach too |
|
43
|
|
|
* @param callable $callback a callable function |
|
44
|
|
|
* @return bool true on success false on failure |
|
45
|
|
|
*/ |
|
46
|
|
|
public function detach($event, $callback) |
|
47
|
|
|
{ |
|
48
|
|
|
if (is_string($event) && is_callable($callback)) { |
|
49
|
|
|
if (array_key_exists($event, $this->listenersHeap)) { |
|
50
|
|
|
$this->listenersHeap[$event]->eject($callback); |
|
51
|
|
|
} |
|
52
|
|
|
|
|
53
|
|
|
return true; |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
return false; |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* Clear all listeners for a given event |
|
61
|
|
|
* |
|
62
|
|
|
* @param string $event |
|
63
|
|
|
* @return bool true on success false on failure |
|
64
|
|
|
*/ |
|
65
|
|
View Code Duplication |
public function clearListeners($event) |
|
|
|
|
|
|
66
|
|
|
{ |
|
67
|
|
|
if (is_string($event)) |
|
68
|
|
|
{ |
|
69
|
|
|
$this->listenersHeap[$event] = null; |
|
70
|
|
|
|
|
71
|
|
|
return true; |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
return false; |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
/** |
|
78
|
|
|
* Trigger an event |
|
79
|
|
|
* |
|
80
|
|
|
* Can accept an EventInterface or will create one if not passed |
|
81
|
|
|
* |
|
82
|
|
|
* @param string|EventInterface $event |
|
83
|
|
|
* @param object|string $target |
|
84
|
|
|
* @param array|object $argv - arguments for listener callback |
|
85
|
|
|
* @return mixed |
|
86
|
|
|
*/ |
|
87
|
|
|
public function trigger($event, $target = null, $argv = []) |
|
88
|
|
|
{ |
|
89
|
|
|
$result = false; |
|
90
|
|
|
|
|
91
|
|
|
if (is_string($event) || (is_object($event) && $event instanceof EventInterface) |
|
92
|
|
|
&& (is_string($target) || is_object($target)) |
|
93
|
|
|
&& (is_array($argv) || is_object($argv))) { |
|
94
|
|
|
if (is_string($event)) { |
|
95
|
|
|
$event = new Event($event); |
|
96
|
|
|
} |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
if ($event->isPropagationStopped()) { |
|
100
|
|
|
return; |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
$event = $event->getName(); |
|
104
|
|
|
|
|
105
|
|
|
$listeners = $this->listenersHeap[$event]->get(); |
|
106
|
|
|
|
|
107
|
|
|
foreach ($listeners as $listener) { |
|
108
|
|
|
call_user_func_array( |
|
109
|
|
|
$listener['callback'], |
|
110
|
|
|
$argv |
|
111
|
|
|
); |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
return $result; |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
/** |
|
118
|
|
|
* Custom method for check event listeners |
|
119
|
|
|
* |
|
120
|
|
|
* @param string $event |
|
121
|
|
|
* @return bool true on success false on failure |
|
122
|
|
|
*/ |
|
123
|
|
View Code Duplication |
public function isExistListeners($event) |
|
|
|
|
|
|
124
|
|
|
{ |
|
125
|
|
|
if (is_string($event)) { |
|
126
|
|
|
if (is_null($this->listenersHeap[$event])) { |
|
127
|
|
|
return false; |
|
128
|
|
|
} |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
|
|
return true; |
|
132
|
|
|
} |
|
133
|
|
|
} |
|
134
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.