diff --git a/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php index 5a95296fca..3e3e288d96 100644 --- a/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php @@ -88,6 +88,18 @@ class TraceableEventDispatcher implements EventDispatcherInterface, TraceableEve */ public function removeListener($eventName, $listener) { + if (isset($this->wrappedListeners[$this->lastEventId])) { + foreach ($this->wrappedListeners[$this->lastEventId] as $wrappedListener) { + $originalListener = $this->wrappedListeners[$this->lastEventId][$wrappedListener]; + + if ($originalListener === $listener) { + unset($this->wrappedListeners[$this->lastEventId][$wrappedListener]); + + return $this->dispatcher->removeListener($eventName, $wrappedListener); + } + } + } + return $this->dispatcher->removeListener($eventName, $listener); } diff --git a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php index c7a3edb890..89f181b4fc 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php @@ -223,6 +223,19 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $kernel->handle($request); } + public function testListenerCanRemoveItselfWhenExecuted() + { + $eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $listener1 = function () use ($eventDispatcher, &$listener1) { + $eventDispatcher->removeListener('foo', $listener1); + }; + $eventDispatcher->addListener('foo', $listener1); + $eventDispatcher->addListener('foo', function () {}); + $eventDispatcher->dispatch('foo'); + + $this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed'); + } + protected function getHttpKernel($dispatcher, $controller) { $resolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface');