Skip to content

Commit

Permalink
Merge branch '4.4' into 5.4
Browse files Browse the repository at this point in the history
* 4.4:
  [Console] Better required argument check in InputArgument
  [EventDispatcher] Fix removing listeners when using first-class callable syntax
  • Loading branch information
nicolas-grekas committed May 5, 2022
2 parents dec8a9f + 708e761 commit 8e6ce1c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
6 changes: 3 additions & 3 deletions Debug/TraceableEventDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function removeListener(string $eventName, $listener)
{
if (isset($this->wrappedListeners[$eventName])) {
foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
if ($wrappedListener->getWrappedListener() === $listener) {
if ($wrappedListener->getWrappedListener() === $listener || ($listener instanceof \Closure && $wrappedListener->getWrappedListener() == $listener)) {
$listener = $wrappedListener;
unset($this->wrappedListeners[$eventName][$index]);
break;
Expand Down Expand Up @@ -110,8 +110,8 @@ public function getListenerPriority(string $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) {
foreach ($this->wrappedListeners[$eventName] as $wrappedListener) {
if ($wrappedListener->getWrappedListener() === $listener || ($listener instanceof \Closure && $wrappedListener->getWrappedListener() == $listener)) {
return $this->dispatcher->getListenerPriority($eventName, $wrappedListener);
}
}
Expand Down
4 changes: 2 additions & 2 deletions EventDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public function getListenerPriority(string $eventName, $listener)
$v[0] = $v[0]();
$v[1] = $v[1] ?? '__invoke';
}
if ($v === $listener) {
if ($v === $listener || ($listener instanceof \Closure && $v == $listener)) {
return $priority;
}
}
Expand Down Expand Up @@ -164,7 +164,7 @@ public function removeListener(string $eventName, $listener)
$v[0] = $v[0]();
$v[1] = $v[1] ?? '__invoke';
}
if ($v === $listener) {
if ($v === $listener || ($listener instanceof \Closure && $v == $listener)) {
unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]);
}
}
Expand Down
29 changes: 29 additions & 0 deletions Tests/EventDispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,35 @@ public function testMutatingWhilePropagationIsStopped()

$this->assertTrue($testLoaded);
}

/**
* @requires PHP 8.1
*/
public function testNamedClosures()
{
$listener = new TestEventListener();

$callback1 = \Closure::fromCallable($listener);
$callback2 = \Closure::fromCallable($listener);
$callback3 = \Closure::fromCallable(new TestEventListener());

$this->assertNotSame($callback1, $callback2);
$this->assertNotSame($callback1, $callback3);
$this->assertNotSame($callback2, $callback3);
$this->assertTrue($callback1 == $callback2);
$this->assertFalse($callback1 == $callback3);

$this->dispatcher->addListener('foo', $callback1, 3);
$this->dispatcher->addListener('foo', $callback2, 2);
$this->dispatcher->addListener('foo', $callback3, 1);

$this->assertSame(3, $this->dispatcher->getListenerPriority('foo', $callback1));
$this->assertSame(3, $this->dispatcher->getListenerPriority('foo', $callback2));

$this->dispatcher->removeListener('foo', $callback1);

$this->assertSame(['foo' => [$callback3]], $this->dispatcher->getListeners());
}
}

class CallableClass
Expand Down

0 comments on commit 8e6ce1c

Please sign in to comment.