bug #22568 [EventDispatcher] fix getting priorities of listeners during dispatch (dmaicher)

This PR was merged into the 3.2 branch.

Discussion
----------

[EventDispatcher] fix getting priorities of listeners during dispatch

| Q             | A
| ------------- | ---
| Branch?       | 3.2
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #22520
| License       | MIT
| Doc PR        | -

The WebProfiler collects listener info during dispatching the `kernel.terminate` event which caused issues while retrieving priorities as the wrappers are registered instead of the real listeners.

Commits
-------

79b71c0 [EventDispatcher] fix getting priorities of listeners during dispatch
This commit is contained in:
Nicolas Grekas 2017-04-28 14:55:39 +02:00
commit c590e85c1b
2 changed files with 25 additions and 1 deletions

View File

@ -104,6 +104,16 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
*/
public function getListenerPriority($eventName, $listener)
{
// we might have wrapped listeners for the event (if called while dispatching)
// in that case get the priority by wrapper
if (isset($this->wrappedListeners[$eventName])) {
foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
if ($wrappedListener->getWrappedListener() === $listener) {
return $this->dispatcher->getListenerPriority($eventName, $wrappedListener);
}
}
}
return $this->dispatcher->getListenerPriority($eventName, $listener);
}

View File

@ -74,6 +74,20 @@ class TraceableEventDispatcherTest extends TestCase
$this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));
}
public function testGetListenerPriorityWhileDispatching()
{
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$priorityWhileDispatching = null;
$listener = function () use ($tdispatcher, &$priorityWhileDispatching, &$listener) {
$priorityWhileDispatching = $tdispatcher->getListenerPriority('bar', $listener);
};
$tdispatcher->addListener('bar', $listener, 5);
$tdispatcher->dispatch('bar');
$this->assertSame(5, $priorityWhileDispatching);
}
public function testAddRemoveSubscriber()
{
$dispatcher = new EventDispatcher();
@ -107,7 +121,7 @@ class TraceableEventDispatcherTest extends TestCase
$listeners = $tdispatcher->getCalledListeners();
$this->assertArrayHasKey('data', $listeners['foo.closure']);
unset($listeners['foo.closure']['data']);
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => null)), $listeners);
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 0)), $listeners);
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
}