@@ -28,11 +28,9 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
28
28
{
29
29
protected $ logger ;
30
30
protected $ stopwatch ;
31
- private $ called = array ();
31
+
32
+ private $ called ;
32
33
private $ dispatcher ;
33
- private $ wrappedListeners = array ();
34
- private $ firstCalledEvent = array ();
35
- private $ lastEventId = 0 ;
36
34
37
35
/**
38
36
* Constructor.
@@ -46,6 +44,7 @@ public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $sto
46
44
$ this ->dispatcher = $ dispatcher ;
47
45
$ this ->stopwatch = $ stopwatch ;
48
46
$ this ->logger = $ logger ;
47
+ $ this ->called = array ();
49
48
}
50
49
51
50
/**
@@ -105,47 +104,19 @@ public function dispatch($eventName, Event $event = null)
105
104
$ event = new Event ();
106
105
}
107
106
108
- $ eventId = ++$ this ->lastEventId ;
109
-
110
- // Wrap all listeners before they are called
111
- $ this ->wrappedListeners [$ eventId ] = new \SplObjectStorage ();
112
-
113
- $ listeners = $ this ->dispatcher ->getListeners ($ eventName );
114
-
115
- foreach ($ listeners as $ listener ) {
116
- $ this ->dispatcher ->removeListener ($ eventName , $ listener );
117
- $ wrapped = $ this ->wrapListener ($ eventName , $ eventId , $ listener );
118
- $ this ->wrappedListeners [$ eventId ][$ wrapped ] = $ listener ;
119
- $ this ->dispatcher ->addListener ($ eventName , $ wrapped );
120
- }
121
-
107
+ $ this ->preProcess ($ eventName );
122
108
$ this ->preDispatch ($ eventName , $ event );
123
109
124
110
$ e = $ this ->stopwatch ->start ($ eventName , 'section ' );
125
111
126
- $ this ->firstCalledEvent [$ eventName ] = $ this ->stopwatch ->start ($ eventName .'.loading ' , 'event_listener_loading ' );
127
-
128
- if (!$ this ->dispatcher ->hasListeners ($ eventName )) {
129
- $ this ->firstCalledEvent [$ eventName ]->stop ();
130
- }
131
-
132
112
$ this ->dispatcher ->dispatch ($ eventName , $ event );
133
113
134
- unset($ this ->firstCalledEvent [$ eventName ]);
135
-
136
114
if ($ e ->isStarted ()) {
137
115
$ e ->stop ();
138
116
}
139
117
140
118
$ this ->postDispatch ($ eventName , $ event );
141
-
142
- // Unwrap all listeners after they are called
143
- foreach ($ this ->wrappedListeners [$ eventId ] as $ wrapped ) {
144
- $ this ->dispatcher ->removeListener ($ eventName , $ wrapped );
145
- $ this ->dispatcher ->addListener ($ eventName , $ this ->wrappedListeners [$ eventId ][$ wrapped ]);
146
- }
147
-
148
- unset($ this ->wrappedListeners [$ eventId ]);
119
+ $ this ->postProcess ($ eventName );
149
120
150
121
return $ event ;
151
122
}
@@ -155,7 +126,15 @@ public function dispatch($eventName, Event $event = null)
155
126
*/
156
127
public function getCalledListeners ()
157
128
{
158
- return $ this ->called ;
129
+ $ called = array ();
130
+ foreach ($ this ->called as $ eventName => $ listeners ) {
131
+ foreach ($ listeners as $ listener ) {
132
+ $ info = $ this ->getListenerInfo ($ listener ->getWrappedListener (), $ eventName );
133
+ $ called [$ eventName .'. ' .$ info ['pretty ' ]] = $ info ;
134
+ }
135
+ }
136
+
137
+ return $ called ;
159
138
}
160
139
161
140
/**
@@ -164,12 +143,22 @@ public function getCalledListeners()
164
143
public function getNotCalledListeners ()
165
144
{
166
145
$ notCalled = array ();
167
-
168
- foreach ($ this ->getListeners () as $ name => $ listeners ) {
146
+ foreach ($ this ->getListeners () as $ eventName => $ listeners ) {
169
147
foreach ($ listeners as $ listener ) {
170
- $ info = $ this ->getListenerInfo ($ listener , $ name , null );
171
- if (!isset ($ this ->call
10000
ed [$ name .'. ' .$ info ['pretty ' ]])) {
172
- $ notCalled [$ name .'. ' .$ info ['pretty ' ]] = $ info ;
148
+ $ called = false ;
149
+ if (isset ($ this ->called [$ eventName ])) {
150
+ foreach ($ this ->called [$ eventName ] as $ l ) {
151
+ if ($ l ->getWrappedListener () === $ listener ) {
152
+ $ called = true ;
153
+
154
+ break ;
155
+ }
156
+ }
157
+ }
158
+
159
+ if (!$ called ) {
160
+ $ info = $ this ->getListenerInfo ($ listener , $ eventName );
161
+ $ notCalled [$ eventName .'. ' .$ info ['pretty ' ]] = $ info ;
173
162
}
174
163
}
175
164
}
@@ -191,64 +180,68 @@ public function __call($method, $arguments)
191
180
}
192
181
193
182
/**
194
- * This is a private method and must not be used .
183
+ * Called before dispatching the event .
195
184
*
196
- * This method is public because it is used in a closure.
197
- * Whenever Symfony will require PHP 5.4, this could be changed
198
- * to a proper private method.
185
+ * @param string $eventName The event name
186
+ * @param Event $event The event
199
187
*/
200
- public function logSkippedListeners ($ eventName , $ eventId , Event $ event, $ listener )
188
+ protected function preDispatch ($ eventName , Event $ event )
201
189
{
202
- if (null === $ this ->logger ) {
203
- return ;
204
- }
205
-
206
- $ info = $ this ->getListenerInfo ($ listener , $ eventName , $ eventId );
207
-
208
- $ this ->logger ->debug (sprintf ('Listener "%s" stopped propagation of the event "%s". ' , $ info ['pretty ' ], $ eventName ));
209
-
210
- $ skippedListeners = $ this ->getListeners ($ eventName );
211
- $ skipped = false ;
212
-
213
- foreach ($ skippedListeners as $ skippedListener ) {
214
- $ skippedListener = $ this ->unwrapListener ($ skippedListener , $ eventId );
215
-
216
- if ($ skipped ) {
217
- $ info = $ this ->getListenerInfo ($ skippedListener , $ eventName , $ eventId );
218
- $ this ->logger ->debug (sprintf ('Listener "%s" was not called for event "%s". ' , $ info ['pretty ' ], $ eventName ));
219
- }
220
-
221
- if ($ skippedListener === $ listener ) {
222
- $ skipped = true ;
223
- }
224
- }
225
190
}
226
191
227
192
/**
228
- * This is a private method .
193
+ * Called after dispatching the event .
229
194
*
230
- * This method is public because it is used in a closure.
231
- * Whenever Symfony will require PHP 5.4, this could be changed
232
- * to a proper private method.
195
+ * @param string $eventName The event name
196
+ * @param Event $event The event
233
197
*/
234
- public function preListenerCall ($ eventName , $ eventId , $ listener )
198
+ protected function postDispatch ($ eventName , Event $ event )
235
199
{
236
- // is it the first called listener?
237
- if (isset ($ this ->firstCalledEvent [$ eventName ])) {
238
- $ this ->firstCalledEvent [$ eventName ]->stop ();
200
+ }
239
201
240
- unset($ this ->firstCalledEvent [$ eventName ]);
202
+ private function preProcess ($ eventName )
203
+ {
204
+ foreach ($ this ->dispatcher ->getListeners ($ eventName ) as $ listener ) {
205
+ $ this ->dispatcher ->removeListener ($ eventName , $ listener );
206
+ $ info = $ this ->getListenerInfo ($ listener , $ eventName );
207
+ $ name = isset ($ info ['class ' ]) ? $ info ['class ' ] : $ info ['type ' ];
208
+ $ this ->dispatcher ->addListener ($ eventName , new WrappedListener ($ listener , $ name , $ this ->stopwatch ));
241
209
}
210
+ }
242
211
243
- $ info = $ this ->getListenerInfo ($ listener , $ eventName , $ eventId );
212
+ private function postProcess ($ eventName )
213
+ {
214
+ $ skipped = false ;
215
+ foreach ($ this ->dispatcher ->getListeners ($ eventName ) as $ listener ) {
216
+ // Unwrap listener
217
+ $ this ->dispatcher ->removeListener ($ eventName , $ listener );
218
+ $ this ->dispatcher ->addListener ($ eventName , $ listener ->getWrappedListener ());
244
219
245
- if (null !== $ this ->logger ) {
246
- $ this ->logger ->debug (sprintf ('Notified event "%s" to listener "%s". ' , $ eventName , $ info ['pretty ' ]));
247
- }
220
+ $ info = $ this ->getListenerInfo ($ listener ->getWrappedListener (), $ eventName );
221
+ if ($ listener ->wasCalled ()) {
222
+ if (null !== $ this ->logger ) {
223
+ $ this ->logger ->debug (sprintf ('Notified event "%s" to listener "%s". ' , $ eventName , $ info ['pretty ' ]));
224
+ }
225
+
226
+ if (!isset ($ this ->called [$ eventName ])) {
227
+ $ this ->called [$ eventName ] = new \SplObjectStorage ();
228
+ }
248
229
249
- $ this ->called [$ eventName .'. ' .$ info ['pretty ' ]] = $ info ;
230
+ $ this ->called [$ eventName ]->attach ($ listener );
231
+ }
232
+
233
+ if (null !== $ this ->logger && $ skipped ) {
234
+ $ this ->logger ->debug (sprintf ('Listener "%s" was not called for event "%s". ' , $ info ['pretty ' ], $ eventName ));
235
+ }
250
236
251
- return $ this ->stopwatch ->start (isset ($ info ['class ' ]) ? $ info ['class ' ] : $ info ['type ' ], 'event_listener ' );
237
+ if ($ listener ->stoppedPropagation ()) {
238
+ if (null !== $ this ->logger ) {
239
+ $ this ->logger ->debug (sprintf ('Listener "%s" stopped propagation of the event "%s". ' , $ info ['pretty ' ], $ eventName ));
240
+ }
241
+
242
+ $ skipped = true ;
243
+ }
244
+ }
252
245
}
253
246
254
247
/**
@@ -259,10 +252,8 @@ public function preListenerCall($eventName, $eventId, $listener)
259
252
*
260
253
* @return array Information about the listener
261
254
*/
262
- private function getListenerInfo ($ listener , $ eventName, $ eventId )
255
+ private function getListenerInfo ($ listener , $ eventName )
263
256
{
264
- $ listener = $ this ->unwrapListener ($ listener , $ eventId );
265
-
266
257
$ info = array (
267
258
'event ' => $ eventName ,
268
259
);
@@ -312,61 +303,4 @@ private function getListenerInfo($listener, $eventName, $eventId)
312
303
313
304
return $ info ;
314
305
}
315
-
316
- /**
317
- * Called before dispatching the event.
318
- *
319
- * @param string $eventName The event name
320
- * @param Event $event The event
321
- */
322
- protected function preDispatch ($ eventName , Event $ event )
323
- {
324
- }
325
-
326
- /**
327
- * Called after dispatching the event.
328
- *
329
- * @param string $eventName The event name
330
- * @param Event $event The event
331
- */
332
- protected function postDispatch ($ eventName , Event $ event )
333
- {
334
- }
335
-
336
- private function wrapListener ($ eventName , $ eventId , $ listener )
337
- {
338
- $ self = $ this ;
339
-
340
- return function (Event $ event ) use ($ self , $ eventName , $ eventId , $ listener ) {
341
- $ e = $ self ->preListenerCall ($ eventName , $ eventId , $ listener );
342
-
343
- call_user_func ($ listener , $ event , $ eventName , $ self );
344
-
345
- if ($ e ->isStarted ()) {
346
- $ e ->stop ();
347
- }
348
-
349
- if ($ event ->isPropagationStopped ()) {
350
- $ self ->logSkippedListeners ($ eventName , $ eventId , $ event , $ listener );
351
- }
352
- };
353
- }
354
-
355
- private function unwrapListener ($ listener , $ eventId )
356
- {
357
- // get the original listener
358
- if (is_object ($ listener )) {
359
- if (null === $ eventId ) {
360
- foreach (array_keys ($ this ->wrappedListeners ) as $ eventId ) {
361
- if (isset ($ this ->wrappedListeners [$ eventId ][$ listener ])) {
362
- return $ this ->wrappedListeners [$ eventId ][$ listener ];
363
- }
364
- }
365
- } elseif (isset ($ this ->wrappedListeners [$ eventId ][$ listener ])) {
366
- return $ this ->wrappedListeners [$ eventId ][$ listener ];
367
- }
368
- }
369
-
370
- return $ listener ;
371
- }
372
306
}
0 commit comments