/
EventDispatcher.php
160 lines (141 loc) · 4.21 KB
/
EventDispatcher.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<?php
namespace Symfony\Component\EventDispatcher;
/*
* This file is part of the Symfony package.
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* EventDispatcher implements a dispatcher object.
*
* @see http://developer.apple.com/documentation/Cocoa/Conceptual/Notifications/index.html Apple's Cocoa framework
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class EventDispatcher
{
protected $listeners = array();
/**
* Connects a listener to a given event name.
*
* Listeners with a higher priority are executed first.
*
* @param string $name An event name
* @param mixed $listener A PHP callable
* @param integer $priority The priority (between -10 and 10 -- defaults to 0)
*/
public function connect($name, $listener, $priority = 0)
{
if (!isset($this->listeners[$name][$priority])) {
if (!isset($this->listeners[$name])) {
$this->listeners[$name] = array();
}
$this->listeners[$name][$priority] = array();
}
$this->listeners[$name][$priority][] = $listener;
}
/**
* Disconnects one, or all listeners for the given event name.
*
* @param string $name An event name
* @param mixed|null $listener the listener to remove, or null to remove all
* @return void
*/
public function disconnect($name, $listener = null)
{
if (!isset($this->listeners[$name])) {
return false;
}
if (null === $listener) {
unset($this->listeners[$name]);
return;
}
foreach ($this->listeners[$name] as $priority => $callables) {
foreach ($callables as $i => $callable) {
if ($listener === $callable) {
unset($this->listeners[$name][$priority][$i]);
}
}
}
}
/**
* Notifies all listeners of a given event.
*
* @param Event $event An Event instance
*
* @return Event The Event instance
*/
public function notify(Event $event)
{
foreach ($this->getListeners($event->getName()) as $listener) {
call_user_func($listener, $event);
}
return $event;
}
/**
* Notifies all listeners of a given event until one returns a non null value.
*
* @param Event $event An Event instance
*
* @return Event The Event instance
*/
public function notifyUntil(Event $event)
{
foreach ($this->getListeners($event->getName()) as $listener) {
if (call_user_func($listener, $event)) {
$event->setProcessed(true);
break;
}
}
return $event;
}
/**
* Filters a value by calling all listeners of a given event.
*
* @param Event $event An Event instance
* @param mixed $value The value to be filtered
*
* @return Event The Event instance
*/
public function filter(Event $event, $value)
{
foreach ($this->getListeners($event->getName()) as $listener) {
$value = call_user_func($listener, $event, $value);
}
$event->setReturnValue($value);
return $event;
}
/**
* Returns true if the given event name has some listeners.
*
* @param string $name The event name
*
* @return Boolean true if some listeners are connected, false otherwise
*/
public function hasListeners($name)
{
return (Boolean) count($this->getListeners($name));
}
/**
* Returns all listeners associated with a given event name.
*
* @param string $name The event name
*
* @return array An array of listeners
*/
public function getListeners($name)
{
if (!isset($this->listeners[$name])) {
return array();
}
$listeners = array();
$all = $this->listeners[$name];
krsort($all);
foreach ($all as $l) {
$listeners = array_merge($listeners, $l);
}
return $listeners;
}
}