diff --git a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php index 3450c1283c..d5c137b94b 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php +++ b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php @@ -14,6 +14,7 @@ namespace Symfony\Component\EventDispatcher\Debug; use Psr\EventDispatcher\StoppableEventInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\WrappedEvent; use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\VarDumper\Caster\ClassStub; use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; @@ -111,6 +112,10 @@ class WrappedListener public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher) { + if ($event instanceof WrappedEvent) { + $event = $event->getWrappedEvent(); + } + $dispatcher = $this->dispatcher ?: $dispatcher; $this->called = true; diff --git a/src/Symfony/Component/EventDispatcher/EventDispatcher.php b/src/Symfony/Component/EventDispatcher/EventDispatcher.php index 92867fdd07..60283882a8 100644 --- a/src/Symfony/Component/EventDispatcher/EventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/EventDispatcher.php @@ -71,7 +71,7 @@ class EventDispatcher implements EventDispatcherInterface } if ($listeners) { - $this->doDispatch($listeners, $eventName, $event); + $this->callListeners($listeners, $eventName, $event); } return $event; @@ -242,7 +242,7 @@ class EventDispatcher implements EventDispatcherInterface if ($stoppable && $event->isPropagationStopped()) { break; } - $listener($event, $eventName, $this); + $listener($event instanceof Event ? $event : new WrappedEvent($event), $eventName, $this); } } diff --git a/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php index cfdc9c137d..b809cd9f51 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; class EventDispatcherTest extends TestCase { @@ -128,6 +129,20 @@ class EventDispatcherTest extends TestCase } public function testDispatch() + { + $this->dispatcher->addListener('pre.foo', [$this->listener, 'preFoo']); + $this->dispatcher->addListener('post.foo', [$this->listener, 'postFoo']); + $this->dispatcher->dispatch(new ContractsEvent(), self::preFoo); + $this->assertTrue($this->listener->preFooInvoked); + $this->assertFalse($this->listener->postFooInvoked); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch(new Event(), 'noevent')); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch(new Event(), self::preFoo)); + $event = new Event(); + $return = $this->dispatcher->dispatch($event, self::preFoo); + $this->assertSame($event, $return); + } + + public function testDispatchContractsEvent() { $this->dispatcher->addListener('pre.foo', [$this->listener, 'preFoo']); $this->dispatcher->addListener('post.foo', [$this->listener, 'postFoo']); @@ -413,12 +428,12 @@ class TestEventListener /* Listener methods */ - public function preFoo(Event $e) + public function preFoo($e) { $this->preFooInvoked = true; } - public function postFoo(Event $e) + public function postFoo($e) { $this->postFooInvoked = true; @@ -433,7 +448,7 @@ class TestWithDispatcher public $name; public $dispatcher; - public function foo(Event $e, $name, $dispatcher) + public function foo($e, $name, $dispatcher) { $this->name = $name; $this->dispatcher = $dispatcher; diff --git a/src/Symfony/Component/EventDispatcher/WrappedEvent.php b/src/Symfony/Component/EventDispatcher/WrappedEvent.php new file mode 100644 index 0000000000..705d1aeda1 --- /dev/null +++ b/src/Symfony/Component/EventDispatcher/WrappedEvent.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +use Psr\EventDispatcher\StoppableEventInterface; +use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; + +/** + * @internal to be removed in 5.0. + */ +final class WrappedEvent extends Event +{ + private $event; + + /** + * @param object $event + */ + public function __construct($event) + { + $this->event = $event; + } + + /** + * @return object $event + */ + public function getWrappedEvent() + { + return $this->event; + } + + public function isPropagationStopped() + { + if (!$this->event instanceof ContractsEvent && !$this->event instanceof StoppableEventInterface) { + return false; + } + + return $this->event->isPropagationStopped(); + } + + public function stopPropagation() + { + if (!$this->event instanceof ContractsEvent) { + return; + } + + $this->event->stopPropagation(); + } +}