Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cf09781

Browse filesBrowse files
Merge branch '5.4' into 6.0
* 5.4: [Console] Better required argument check in InputArgument [EventDispatcher] Fix removing listeners when using first-class callable syntax
2 parents 60b1a2a + 0dc07cd commit cf09781
Copy full SHA for cf09781

File tree

Expand file treeCollapse file tree

7 files changed

+80
-6
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+80
-6
lines changed

‎src/Symfony/Component/Console/Input/InputArgument.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Input/InputArgument.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public function isArray(): bool
8888
*/
8989
public function setDefault(string|bool|int|float|array $default = null)
9090
{
91-
if (self::REQUIRED === $this->mode && null !== $default) {
91+
if ($this->isRequired() && null !== $default) {
9292
throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
9393
}
9494

‎src/Symfony/Component/Console/Tests/Input/InputArgumentTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/Input/InputArgumentTest.php
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ public function testSetDefaultWithRequiredArgument()
8888
$argument->setDefault('default');
8989
}
9090

91+
public function testSetDefaultWithRequiredArrayArgument()
92+
{
93+
$this->expectException(\LogicException::class);
94+
$this->expectExceptionMessage('Cannot set a default value except for InputArgument::OPTIONAL mode.');
95+
$argument = new InputArgument('foo', InputArgument::REQUIRED | InputArgument::IS_ARRAY);
96+
$argument->setDefault([]);
97+
}
98+
9199
public function testSetDefaultWithArrayArgument()
92100
{
93101
$this->expectException(\LogicException::class);

‎src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function removeListener(string $eventName, callable|array $listener)
7373
{
7474
if (isset($this->wrappedListeners[$eventName])) {
7575
foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
76-
if ($wrappedListener->getWrappedListener() === $listener) {
76+
if ($wrappedListener->getWrappedListener() === $listener || ($listener instanceof \Closure && $wrappedListener->getWrappedListener() == $listener)) {
7777
$listener = $wrappedListener;
7878
unset($this->wrappedListeners[$eventName][$index]);
7979
break;
@@ -108,8 +108,8 @@ public function getListenerPriority(string $eventName, callable|array $listener)
108108
// we might have wrapped listeners for the event (if called while dispatching)
109109
// in that case get the priority by wrapper
110110
if (isset($this->wrappedListeners[$eventName])) {
111-
foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
112-
if ($wrappedListener->getWrappedListener() === $listener) {
111+
foreach ($this->wrappedListeners[$eventName] as $wrappedListener) {
112+
if ($wrappedListener->getWrappedListener() === $listener || ($listener instanceof \Closure && $wrappedListener->getWrappedListener() == $listener)) {
113113
return $this->dispatcher->getListenerPriority($eventName, $wrappedListener);
114114
}
115115
}

‎src/Symfony/Component/EventDispatcher/EventDispatcher.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/EventDispatcher/EventDispatcher.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public function getListenerPriority(string $eventName, callable|array $listener)
108108
$v[0] = $v[0]();
109109
$v[1] = $v[1] ?? '__invoke';
110110
}
111-
if ($v === $listener) {
111+
if ($v === $listener || ($listener instanceof \Closure && $v == $listener)) {
112112
return $priority;
113113
}
114114
}
@@ -164,7 +164,7 @@ public function removeListener(string $eventName, callable|array $listener)
164164
$v[0] = $v[0]();
165165
$v[1] = $v[1] ?? '__invoke';
166166
}
167-
if ($v === $listener) {
167+
if ($v === $listener || ($listener instanceof \Closure && $v == $listener)) {
168168
unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]);
169169
}
170170
}

‎src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,35 @@ public function testMutatingWhilePropagationIsStopped()
405405

406406
$this->assertTrue($testLoaded);
407407
}
408+
409+
/**
410+
* @requires PHP 8.1
411+
*/
412+
public function testNamedClosures()
413+
{
414+
$listener = new TestEventListener();
415+
416+
$callback1 = \Closure::fromCallable($listener);
417+
$callback2 = \Closure::fromCallable($listener);
418+
$callback3 = \Closure::fromCallable(new TestEventListener());
419+
420+
$this->assertNotSame($callback1, $callback2);
421+
$this->assertNotSame($callback1, $callback3);
422+
$this->assertNotSame($callback2, $callback3);
423+
$this->assertTrue($callback1 == $callback2);
424+
$this->assertFalse($callback1 == $callback3);
425+
426+
$this->dispatcher->addListener('foo', $callback1, 3);
427+
$this->dispatcher->addListener('foo', $callback2, 2);
428+
$this->dispatcher->addListener('foo', $callback3, 1);
429+
430+
$this->assertSame(3, $this->dispatcher->getListenerPriority('foo', $callback1));
431+
$this->assertSame(3, $this->dispatcher->getListenerPriority('foo', $callback2));
432+
433+
$this->dispatcher->removeListener('foo', $callback1);
434+
435+
$this->assertSame(['foo' => [$callback3]], $this->dispatcher->getListeners());
436+
}
408437
}
409438

410439
class CallableClass

‎src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,30 @@ public function testSessionIsNotReported()
322322
$listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST));
323323
}
324324

325+
public function testOnKernelResponseRemoveListener()
326+
{
327+
$tokenStorage = new TokenStorage();
328+
$tokenStorage->setToken(new UsernamePasswordToken(new InMemoryUser('test1', 'pass1'), 'phpunit', ['ROLE_USER']));
329+
330+
$request = new Request();
331+
$request->attributes->set('_security_firewall_run', '_security_session');
332+
333+
$session = new Session(new MockArraySessionStorage());
334+
$request->setSession($session);
335+
336+
$dispatcher = new EventDispatcher();
337+
$httpKernel = $this->createMock(HttpKernelInterface::class);
338+
339+
$listener = new ContextListener($tokenStorage, [], 'session', null, $dispatcher, null, \Closure::fromCallable([$tokenStorage, 'getToken']));
340+
$this->assertEmpty($dispatcher->getListeners());
341+
342+
$listener(new RequestEvent($httpKernel, $request, HttpKernelInterface::MASTER_REQUEST));
343+
$this->assertNotEmpty($dispatcher->getListeners());
344+
345+
$listener->onKernelResponse(new ResponseEvent($httpKernel, $request, HttpKernelInterface::MASTER_REQUEST, new Response()));
346+
$this->assertEmpty($dispatcher->getListeners());
347+
}
348+
325349
protected function runSessionOnKernelResponse($newToken, $original = null)
326350
{
327351
$session = new Session(new MockArraySessionStorage());

‎src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Security\Http\Tests\Firewall;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\EventDispatcher\EventDispatcher;
1516
use Symfony\Component\HttpFoundation\Request;
1617
use Symfony\Component\HttpFoundation\Response;
1718
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
@@ -179,6 +180,18 @@ public function testLogoutException()
179180
$this->assertEquals(403, $event->getThrowable()->getStatusCode());
180181
}
181182

183+
public function testUnregister()
184+
{
185+
$listener = $this->createExceptionListener();
186+
$dispatcher = new EventDispatcher();
187+
188+
$listener->register($dispatcher);
189+
$this->assertNotEmpty($dispatcher->getListeners());
190+
191+
$listener->unregister($dispatcher);
192+
$this->assertEmpty($dispatcher->getListeners());
193+
}
194+
182195
public function getAccessDeniedExceptionProvider()
183196
{
184197
return [

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.