29
29
class EventDispatcher implements EventDispatcherInterface
30
30
{
31
31
private $ listeners = array ();
32
+ private $ factories = array ();
32
33
private $ sorted = array ();
33
34
34
35
/**
@@ -53,19 +54,24 @@ public function dispatch($eventName, Event $event = null)
53
54
public function getListeners ($ eventName = null )
54
55
{
55
56
if (null !== $ eventName ) {
57
+ if (!empty ($ this ->factories [$ eventName ])) {
58
+ $ this ->registerLazyListeners ($ eventName );
59
+ }
60
+
56
61
if (empty ($ this ->listeners [$ eventName ])) {
57
62
return array ();
58
63
}
59
64
60
- if (!isset ($ this ->sorted [$ eventName ])) {
65
+ if (!isset ($ this ->sorted [$ eventName ]) && ! empty ( $ this -> listeners [ $ eventName ]) ) {
61
66
$ this ->sortListeners ($ eventName );
62
67
}
63
68
64
69
return $ this ->sorted [$ eventName ];
65
70
}
66
71
72
+ $ this ->registerLazyListeners ();
67
73
foreach ($ this ->listeners as $ eventName => $ eventListeners ) {
68
- if (!isset ($ this ->sorted [$ eventName ])) {
74
+ if (!isset ($ this ->sorted [$ eventName ]) && ! empty ( $ this -> listeners [ $ eventName ]) ) {
69
75
$ this ->sortListeners ($ eventName );
70
76
}
71
77
}
@@ -78,6 +84,10 @@ public function getListeners($eventName = null)
78
84
*/
79
85
public function getListenerPriority ($ eventName , $ listener )
80
86
{
87
+ if (!empty ($ this ->factories [$ eventName ])) {
88
+ $ this ->registerLazyListeners ($ eventName );
89
+ }
90
+
81
91
if (empty ($ this ->listeners [$ eventName ])) {
82
92
return ;
83
93
}
@@ -88,10 +98,6 @@ public function getListenerPriority($eventName, $listener)
88
98
89
99
foreach ($ this ->listeners [$ eventName ] as $ priority => $ listeners ) {
90
100
foreach ($ listeners as $ k => $ v ) {
91
- if ($ v !== $ listener && is_array ($ v ) && isset ($ v [0 ]) && $ v [0 ] instanceof \Closure) {
92
- $ v [0 ] = $ v [0 ]();
93
- $ this ->listeners [$ eventName ][$ priority ][$ k ] = $ v ;
94
- }
95
101
if ($ v === $ listener ) {
96
102
return $ priority ;
97
103
}
@@ -105,7 +111,7 @@ public function getListenerPriority($eventName, $listener)
105
111
public function hasListeners ($ eventName = null )
106
112
{
107
113
if (null !== $ eventName ) {
108
- return !empty ($ this ->listeners [$ eventName ]);
114
+ return !empty ($ this ->listeners [$ eventName ]) || ! empty ( $ this -> factories [ $ eventName ]) ;
109
115
}
110
116
111
117
foreach ($ this ->listeners as $ eventListeners ) {
@@ -114,6 +120,12 @@ public function hasListeners($eventName = null)
114
120
}
115
121
}
116
122
123
+ foreach ($ this ->factories as $ eventListeners ) {
124
+ if ($ eventListeners ) {
125
+ return true ;
126
+ }
127
+ }
128
+
117
129
return false ;
118
130
}
119
131
@@ -122,6 +134,12 @@ public function hasListeners($eventName = null)
122
134
*/
123
135
public function addListener ($ eventName , $ listener , $ priority = 0 )
124
136
{
137
+ if (is_array ($ listener ) && isset ($ listener [0 ]) && $ listener [0 ] instanceof \Closure) {
138
+ $ this ->factories [$ eventName ][] = array ($ listener [0 ], $ listener [1 ], $ priority );
139
+
140
+ return ;
141
+ }
142
+
125
143
$ this ->listeners [$ eventName ][$ priority ][] = $ listener ;
126
144
unset($ this ->sorted [$ eventName ]);
127
145
}
@@ -131,6 +149,10 @@ public function addListener($eventName, $listener, $priority = 0)
131
149
*/
132
150
public function removeListener ($ eventName , $ listener )
133
151
{
152
+ if (!empty ($ this ->factories [$ eventName ])) {
153
+ $ this ->registerLazyListeners ($ eventName );
154
+ }
155
+
134
156
if (empty ($ this ->listeners [$ eventName ])) {
135
157
return ;
136
158
}
@@ -141,9 +163,6 @@ public function removeListener($eventName, $listener)
141
163
142
164
foreach ($ this ->listeners [$ eventName ] as $ priority => $ listeners ) {
143
165
foreach ($ listeners as $ k => $ v ) {
144
- if ($ v !== $ listener && is_array ($ v ) && isset ($ v [0 ]) && $ v [0 ] instanceof \Closure) {
145
- $ v [0 ] = $ v [0 ]();
146
- }
147
166
if ($ v === $ listener ) {
148
167
unset($ listeners [$ k ], $ this ->sorted [$ eventName ]);
149
168
} else {
@@ -221,16 +240,28 @@ protected function doDispatch($listeners, $eventName, Event $event)
221
240
private function sortListeners ($ eventName )
222
241
{
223
242
krsort ($ this ->listeners [$ eventName ]);
224
- $ this ->sorted [$ eventName ] = array ();
243
+ $ this ->sorted [$ eventName ] = call_user_func_array ('array_merge ' , $ this ->listeners [$ eventName ]);
244
+ }
225
245
226
- foreach ($ this ->listeners [$ eventName ] as $ priority => $ listeners ) {
227
- foreach ($ listeners as $ k => $ listener ) {
228
- if (is_array ($ listener ) && isset ($ listener [0 ]) && $ listener [0 ] instanceof \Closure) {
229
- $ listener [0 ] = $ listener [0 ]();
230
- $ this ->listeners [$ eventName ][$ priority ][$ k ] = $ listener ;
231
- }
232
- $ this ->sorted [$ eventName ][] = $ listener ;
246
+ private function registerLazyListeners ($ eventName = null )
247
+ {
248
+ if (null !== $ eventName ) {
249
+ foreach ($ this ->factories [$ eventName ] as list ($ factory , $ method , $ priority )) {
250
+ $ this ->listeners [$ eventName ][$ priority ][] = array ($ factory (), $ method );
233
251
}
252
+ unset($ this ->factories [$ eventName ]);
253
+ unset($ this ->sorted [$ eventName ]);
254
+
255
+ return ;
234
256
}
257
+
258
+ foreach ($ this ->factories as $ event => $ factories ) {
259
+ foreach ($ factories as list ($ factory , $ method , $ priority )) {
260
+ $ this ->listeners [$ event ][$ priority ][] = array ($ factory (), $ method );
261
+ }
262
+ }
263
+
264
+ $ this ->sorted = array ();
265
+ $ this ->factories = array ();
235
266
}
236
267
}
0 commit comments