Skip to content

Commit 291cf61

Browse files
committed
bug symfony#14633 [2.3][EventDispatcher] make listeners removable from an executed listener (xabbuh)
This PR was merged into the 2.3 branch. Discussion ---------- [2.3][EventDispatcher] make listeners removable from an executed listener | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#13972 | License | MIT | Doc PR | This fixes symfony#13972 for Symfony 2.3. On Symfony 2.6 and higher, this has already been fixed with symfony#14355. Commits ------- 54bb399 [EventDispatcher] make listeners removable from an executed listener
2 parents 52c78b9 + 54bb399 commit 291cf61

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)