From c5b3b34b51a07e361d0eb3cf44fa8a2e01224329 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Thu, 25 Apr 2019 20:51:40 +0200 Subject: [PATCH] [EventDispatcher] Fix TraceableEventDispatcher FC/BC layer --- .../Debug/TraceableEventDispatcher.php | 5 +++-- .../EventDispatcher/Debug/WrappedListener.php | 6 +++--- .../Component/EventDispatcher/EventDispatcher.php | 6 ++++-- .../{WrappedEvent.php => LegacyEventProxy.php} | 9 +++++++-- .../Tests/Debug/TraceableEventDispatcherTest.php | 14 ++++++++++++++ 5 files changed, 31 insertions(+), 9 deletions(-) rename src/Symfony/Component/EventDispatcher/{WrappedEvent.php => LegacyEventProxy.php} (86%) diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index e5b79276c62c9..7716d8663177e 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -18,6 +18,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy; +use Symfony\Component\EventDispatcher\LegacyEventProxy; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; @@ -295,7 +296,7 @@ public function __call($method, $arguments) */ protected function beforeDispatch(string $eventName, $event) { - $this->preDispatch($eventName, $event); + $this->preDispatch($eventName, $event instanceof Event ? $event : new LegacyEventProxy($event)); } /** @@ -305,7 +306,7 @@ protected function beforeDispatch(string $eventName, $event) */ protected function afterDispatch(string $eventName, $event) { - $this->postDispatch($eventName, $event); + $this->postDispatch($eventName, $event instanceof Event ? $event : new LegacyEventProxy($event)); } /** diff --git a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php index d5c137b94b2ad..34316b54c3429 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php +++ b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php @@ -14,7 +14,7 @@ use Psr\EventDispatcher\StoppableEventInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\WrappedEvent; +use Symfony\Component\EventDispatcher\LegacyEventProxy; use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\VarDumper\Caster\ClassStub; use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; @@ -112,8 +112,8 @@ public function getInfo($eventName) public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher) { - if ($event instanceof WrappedEvent) { - $event = $event->getWrappedEvent(); + if ($event instanceof LegacyEventProxy) { + $event = $event->getEvent(); } $dispatcher = $this->dispatcher ?: $dispatcher; diff --git a/src/Symfony/Component/EventDispatcher/EventDispatcher.php b/src/Symfony/Component/EventDispatcher/EventDispatcher.php index 60283882a8848..e68918c31c680 100644 --- a/src/Symfony/Component/EventDispatcher/EventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/EventDispatcher.php @@ -12,6 +12,7 @@ namespace Symfony\Component\EventDispatcher; use Psr\EventDispatcher\StoppableEventInterface; +use Symfony\Component\EventDispatcher\Debug\WrappedListener; use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; /** @@ -242,7 +243,8 @@ protected function callListeners(iterable $listeners, string $eventName, $event) if ($stoppable && $event->isPropagationStopped()) { break; } - $listener($event instanceof Event ? $event : new WrappedEvent($event), $eventName, $this); + // @deprecated: the ternary operator is part of a BC layer and should be removed in 5.0 + $listener($listener instanceof WrappedListener ? new LegacyEventProxy($event) : $event, $eventName, $this); } } @@ -296,7 +298,7 @@ private function optimizeListeners(string $eventName): array ($closure = \Closure::fromCallable($listener))(...$args); }; } else { - $closure = $listener instanceof \Closure ? $listener : \Closure::fromCallable($listener); + $closure = $listener instanceof \Closure || $listener instanceof WrappedListener ? $listener : \Closure::fromCallable($listener); } } } diff --git a/src/Symfony/Component/EventDispatcher/WrappedEvent.php b/src/Symfony/Component/EventDispatcher/LegacyEventProxy.php similarity index 86% rename from src/Symfony/Component/EventDispatcher/WrappedEvent.php rename to src/Symfony/Component/EventDispatcher/LegacyEventProxy.php index 705d1aeda1596..cad8cfaedb724 100644 --- a/src/Symfony/Component/EventDispatcher/WrappedEvent.php +++ b/src/Symfony/Component/EventDispatcher/LegacyEventProxy.php @@ -17,7 +17,7 @@ /** * @internal to be removed in 5.0. */ -final class WrappedEvent extends Event +final class LegacyEventProxy extends Event { private $event; @@ -32,7 +32,7 @@ public function __construct($event) /** * @return object $event */ - public function getWrappedEvent() + public function getEvent() { return $this->event; } @@ -54,4 +54,9 @@ public function stopPropagation() $this->event->stopPropagation(); } + + public function __call($name, $args) + { + return $this->event->{$name}(...$args); + } } diff --git a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php index 8fd0305b0e423..ea476eee04c8e 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php @@ -18,6 +18,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; class TraceableEventDispatcherTest extends TestCase { @@ -139,6 +140,19 @@ public function testClearCalledListeners() $this->assertEquals([['event' => 'foo', 'pretty' => 'closure', 'priority' => 5]], $listeners); } + public function testDispatchContractsEvent() + { + $expectedEvent = new ContractsEvent(); + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $tdispatcher->addListener('foo', function ($event) use ($expectedEvent) { + $this->assertSame($event, $expectedEvent); + }, 5); + $tdispatcher->dispatch($expectedEvent, 'foo'); + + $listeners = $tdispatcher->getCalledListeners(); + $this->assertArrayHasKey('stub', $listeners[0]); + } + public function testDispatchAfterReset() { $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());