Skip to content

Commit 54bb399

Browse files
committed
[EventDispatcher] make listeners removable from an executed listener
1 parent 5d428b7 commit 54bb399

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ public function addSubscriber(EventSubscriberInterface $subscriber)
8888
*/
8989
public function removeListener($eventName, $listener)
9090
{
91+
if (isset($this->wrappedListeners[$this->lastEventId])) {
92+
foreach ($this->wrappedListeners[$this->lastEventId] as $wrappedListener) {
93+
$originalListener = $this->wrappedListeners[$this->lastEventId][$wrappedListener];
94+
95+
if ($originalListener === $listener) {
96+
unset($this->wrappedListeners[$this->lastEventId][$wrappedListener]);
97+
98+
return $this->dispatcher->removeListener($eventName, $wrappedListener);
99+
}
100+
}
101+
}
102+
91103
return $this->dispatcher->removeListener($eventName, $listener);
92104
}
93105

src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,19 @@ public function testStopwatchStopControllerOnRequestEvent()
223223
$kernel->handle($request);
224224
}
225225

226+
public function testListenerCanRemoveItselfWhenExecuted()
227+
{
228+
$eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
229+
$listener1 = function () use ($eventDispatcher, &$listener1) {
230+
$eventDispatcher->removeListener('foo', $listener1);
231+
};
232+
$eventDispatcher->addListener('foo', $listener1);
233+
$eventDispatcher->addListener('foo', function () {});
234+
$eventDispatcher->dispatch('foo');
235+
236+
$this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
237+
}
238+
226239
protected function getHttpKernel($dispatcher, $controller)
227240
{
228241
$resolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface');

0 commit comments

Comments
 (0)