Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c86271e

Browse files
minor #34027 [EventDispatcher] handle lazy-callable invokable (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [EventDispatcher] handle lazy-callable invokable | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - Extracted from #34013, for consistency mostly. Commits ------- 9df4c7d [EventDispatcher] handle lazy-callable invokable
2 parents a721a50 + 9df4c7d commit c86271e

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

src/Symfony/Component/EventDispatcher/EventDispatcher.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,16 @@ public function getListenerPriority($eventName, $listener)
111111
return null;
112112
}
113113

114-
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
114+
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) {
115115
$listener[0] = $listener[0]();
116+
$listener[1] = $listener[1] ?? '__invoke';
116117
}
117118

118119
foreach ($this->listeners[$eventName] as $priority => &$listeners) {
119120
foreach ($listeners as &$v) {
120-
if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) {
121+
if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure && 2 >= \count($v)) {
121122
$v[0] = $v[0]();
123+
$v[1] = $v[1] ?? '__invoke';
122124
}
123125
if ($v === $listener) {
124126
return $priority;
@@ -165,14 +167,16 @@ public function removeListener($eventName, $listener)
165167
return;
166168
}
167169

168-
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
170+
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) {
169171
$listener[0] = $listener[0]();
172+
$listener[1] = $listener[1] ?? '__invoke';
170173
}
171174

172175
foreach ($this->listeners[$eventName] as $priority => &$listeners) {
173176
foreach ($listeners as $k => &$v) {
174-
if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) {
177+
if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure && 2 >= \count($v)) {
175178
$v[0] = $v[0]();
179+
$v[1] = $v[1] ?? '__invoke';
176180
}
177181
if ($v === $listener) {
178182
unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]);
@@ -271,8 +275,9 @@ private function sortListeners(string $eventName)
271275

272276
foreach ($this->listeners[$eventName] as &$listeners) {
273277
foreach ($listeners as $k => $listener) {
274-
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
278+
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) {
275279
$listener[0] = $listener[0]();
280+
$listener[1] = $listener[1] ?? '__invoke';
276281
}
277282
$this->sorted[$eventName][] = $listener;
278283
}
@@ -290,10 +295,11 @@ private function optimizeListeners(string $eventName): array
290295
foreach ($this->listeners[$eventName] as &$listeners) {
291296
foreach ($listeners as &$listener) {
292297
$closure = &$this->optimized[$eventName][];
293-
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
298+
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) {
294299
$closure = static function (...$args) use (&$listener, &$closure) {
295300
if ($listener[0] instanceof \Closure) {
296301
$listener[0] = $listener[0]();
302+
$listener[1] = $listener[1] ?? '__invoke';
297303
}
298304
($closure = \Closure::fromCallable($listener))(...$args);
299305
};

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,17 +334,26 @@ public function testHasListenersIsLazy()
334334

335335
public function testDispatchLazyListener()
336336
{
337+
$dispatcher = new TestWithDispatcher();
337338
$called = 0;
338-
$factory = function () use (&$called) {
339+
$factory = function () use (&$called, $dispatcher) {
339340
++$called;
340341

341-
return new TestWithDispatcher();
342+
return $dispatcher;
342343
};
343344
$this->dispatcher->addListener('foo', [$factory, 'foo']);
344345
$this->assertSame(0, $called);
345346
$this->dispatcher->dispatch(new Event(), 'foo');
347+
$this->assertFalse($dispatcher->invoked);
346348
$this->dispatcher->dispatch(new Event(), 'foo');
347349
$this->assertSame(1, $called);
350+
351+
$this->dispatcher->addListener('bar', [$factory]);
352+
$this->assertSame(1, $called);
353+
$this->dispatcher->dispatch(new Event(), 'bar');
354+
$this->assertTrue($dispatcher->invoked);
355+
$this->dispatcher->dispatch(new Event(), 'bar');
356+
$this->assertSame(2, $called);
348357
}
349358

350359
public function testRemoveFindsLazyListeners()
@@ -472,12 +481,20 @@ class TestWithDispatcher
472481
{
473482
public $name;
474483
public $dispatcher;
484+
public $invoked = false;
475485

476486
public function foo($e, $name, $dispatcher)
477487
{
478488
$this->name = $name;
479489
$this->dispatcher = $dispatcher;
480490
}
491+
492+
public function __invoke($e, $name, $dispatcher)
493+
{
494+
$this->name = $name;
495+
$this->dispatcher = $dispatcher;
496+
$this->invoked = true;
497+
}
481498
}
482499

483500
class TestEventSubscriber implements EventSubscriberInterface

0 commit comments

Comments
 (0)