From abc61a9f63ba088aaea5b3c64d2db3316887061e Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Mon, 8 Feb 2021 11:34:19 +0100 Subject: [PATCH] Fix the legacy dispatcher argument order Signed-off-by: Christoph Wurst --- .../EventDispatcher/SymfonyAdapter.php | 30 ++++++++++++++++ .../EventDispatcher/SymfonyAdapterTest.php | 36 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/lib/private/EventDispatcher/SymfonyAdapter.php b/lib/private/EventDispatcher/SymfonyAdapter.php index 3bd74e719fb..39985cb112c 100644 --- a/lib/private/EventDispatcher/SymfonyAdapter.php +++ b/lib/private/EventDispatcher/SymfonyAdapter.php @@ -35,6 +35,8 @@ use OCP\EventDispatcher\Event; use OCP\ILogger; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use function is_object; +use function is_string; /** * @deprecated 20.0.0 use \OCP\EventDispatcher\IEventDispatcher @@ -54,6 +56,28 @@ class SymfonyAdapter implements EventDispatcherInterface { $this->logger = $logger; } + private static function detectEventAndName($a, $b) { + if (is_object($a) && (is_string($b) || $b === null)) { + // a is the event, the other one is the optional name + return [$a, $b]; + } + if (is_object($b) && (is_string($a) || $a === null)) { + // b is the event, the other one is the optional name + return [$b, $a]; + } + if (is_string($a) && $b === null) { + // a is a payload-less event + return [null, $a]; + } + if (is_string($b) && $a === null) { + // b is a payload-less event + return [null, $b]; + } + + // Anything else we can't detect + return [$a, $b]; + } + /** * Dispatches an event to all registered listeners. * @@ -67,7 +91,13 @@ class SymfonyAdapter implements EventDispatcherInterface { * @deprecated 20.0.0 */ public function dispatch($eventName, $event = null): object { + [$event, $eventName] = self::detectEventAndName($event, $eventName); + // type hinting is not possible, due to usage of GenericEvent + if ($event instanceof Event && $eventName === null) { + $this->eventDispatcher->dispatchTyped($event); + return $event; + } if ($event instanceof Event) { $this->eventDispatcher->dispatch($eventName, $event); return $event; diff --git a/tests/lib/EventDispatcher/SymfonyAdapterTest.php b/tests/lib/EventDispatcher/SymfonyAdapterTest.php index b1d43bf2661..5e2803624af 100644 --- a/tests/lib/EventDispatcher/SymfonyAdapterTest.php +++ b/tests/lib/EventDispatcher/SymfonyAdapterTest.php @@ -100,6 +100,26 @@ class SymfonyAdapterTest extends TestCase { self::assertEquals($result, $wrapped); } + public function testDispatchOldSymfonyEventWithFlippedArgumentOrder(): void { + $event = new SymfonyEvent(); + $eventName = 'symfony'; + $symfonyDispatcher = $this->createMock(SymfonyDispatcher::class); + $this->eventDispatcher->expects(self::once()) + ->method('getSymfonyDispatcher') + ->willReturn($symfonyDispatcher); + $symfonyDispatcher->expects(self::once()) + ->method('dispatch') + ->with( + $event, + $eventName + ) + ->willReturnArgument(0); + + $result = $this->adapter->dispatch($event, $eventName); + + self::assertSame($result, $event); + } + public function testDispatchOldSymfonyEvent(): void { $event = new SymfonyEvent(); $eventName = 'symfony'; @@ -120,6 +140,22 @@ class SymfonyAdapterTest extends TestCase { self::assertSame($result, $event); } + public function testDispatchCustomGenericEventWithFlippedArgumentOrder(): void { + $event = new GenericEvent(); + $eventName = 'symfony'; + $this->eventDispatcher->expects(self::once()) + ->method('dispatch') + ->with( + $eventName, + $event + ) + ->willReturnArgument(0); + + $result = $this->adapter->dispatch($event, $eventName); + + self::assertSame($result, $event); + } + public function testDispatchCustomGenericEvent(): void { $event = new GenericEvent(); $eventName = 'symfony';