From ac2dd0f4b5def439ebe056c02e333334d99527b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Nowak?= Date: Thu, 10 Jul 2025 14:56:02 +0200 Subject: [PATCH 1/4] handle optional subscriber if exist --- src/Symfony/MessageMapFactory.php | 2 +- tests/Type/Symfony/ExtensionTest.php | 7 ++ .../Symfony/data/messenger_handle_trait.php | 57 --------------- ...messenger_handle_trait_with_subscriber.php | 72 +++++++++++++++++++ 4 files changed, 80 insertions(+), 58 deletions(-) create mode 100644 tests/Type/Symfony/data/messenger_handle_trait_with_subscriber.php diff --git a/src/Symfony/MessageMapFactory.php b/src/Symfony/MessageMapFactory.php index 5c9ef152..bcff16d2 100644 --- a/src/Symfony/MessageMapFactory.php +++ b/src/Symfony/MessageMapFactory.php @@ -91,7 +91,7 @@ public function create(): MessageMap /** @return iterable> */ private function guessHandledMessages(ClassReflection $reflectionClass): iterable { - if ($reflectionClass->implementsInterface(MessageSubscriberInterface::class)) { + if (class_exists(MessageSubscriberInterface::class) && $reflectionClass->implementsInterface(MessageSubscriberInterface::class)) { $className = $reflectionClass->getName(); foreach ($className::getHandledMessages() as $index => $value) { diff --git a/tests/Type/Symfony/ExtensionTest.php b/tests/Type/Symfony/ExtensionTest.php index 40420be0..e541cd5d 100644 --- a/tests/Type/Symfony/ExtensionTest.php +++ b/tests/Type/Symfony/ExtensionTest.php @@ -14,6 +14,13 @@ class ExtensionTest extends TypeInferenceTestCase /** @return mixed[] */ public function dataFileAsserts(): iterable { + if (class_exists('Symfony\Component\Messenger\Handler\MessageSubscriberInterface')) { + // todo temporary check + die('test if case is triggered'); + + yield from $this->gatherAssertTypes(__DIR__ . '/data/messenger_handle_trait_with_subscriber.php'); + } + yield from $this->gatherAssertTypes(__DIR__ . '/data/messenger_handle_trait.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/envelope_all.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/header_bag_get.php'); diff --git a/tests/Type/Symfony/data/messenger_handle_trait.php b/tests/Type/Symfony/data/messenger_handle_trait.php index 7a86d482..10f62a0c 100644 --- a/tests/Type/Symfony/data/messenger_handle_trait.php +++ b/tests/Type/Symfony/data/messenger_handle_trait.php @@ -2,7 +2,6 @@ namespace MessengerHandleTrait; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; use Symfony\Component\Messenger\HandleTrait; use function PHPStan\Testing\assertType; @@ -16,41 +15,6 @@ public function __invoke(RegularQuery $query): RegularQueryResult } } -class BooleanQuery {} -class StringQuery {} -class IntQuery {} -class FloatQuery {} -class MultiQueryHandler implements MessageSubscriberInterface -{ - public static function getHandledMessages(): iterable - { - yield BooleanQuery::class; - yield IntQuery::class => ['method' => 'handleInt']; - yield FloatQuery::class => ['method' => 'handleFloat']; - yield StringQuery::class => ['method' => 'handleString']; - } - - public function __invoke(BooleanQuery $query): bool - { - return true; - } - - public function handleInt(IntQuery $query): int - { - return 0; - } - - public function handleFloat(FloatQuery $query): float - { - return 0.0; - } - - public function handleString(StringQuery $query): string - { - return 'string result'; - } -} - class TaggedQuery {} class TaggedResult {} class TaggedHandler @@ -61,21 +25,6 @@ public function handle(TaggedQuery $query): TaggedResult } } -class MultiHandlesForInTheSameHandlerQuery {} -class MultiHandlesForInTheSameHandler implements MessageSubscriberInterface -{ - public static function getHandledMessages(): iterable - { - yield MultiHandlesForInTheSameHandlerQuery::class; - yield MultiHandlesForInTheSameHandlerQuery::class => ['priority' => '0']; - } - - public function __invoke(MultiHandlesForInTheSameHandlerQuery $query): bool - { - return true; - } -} - class MultiHandlersForTheSameMessageQuery {} class MultiHandlersForTheSameMessageHandler1 { @@ -99,15 +48,9 @@ public function __invoke() { assertType(RegularQueryResult::class, $this->handle(new RegularQuery())); - assertType('bool', $this->handle(new BooleanQuery())); - assertType('int', $this->handle(new IntQuery())); - assertType('float', $this->handle(new FloatQuery())); - assertType('string', $this->handle(new StringQuery())); - assertType(TaggedResult::class, $this->handle(new TaggedQuery())); // HandleTrait will throw exception in fact due to multiple handle methods/handlers per single query - assertType('mixed', $this->handle(new MultiHandlesForInTheSameHandlerQuery())); assertType('mixed', $this->handle(new MultiHandlersForTheSameMessageQuery())); } } diff --git a/tests/Type/Symfony/data/messenger_handle_trait_with_subscriber.php b/tests/Type/Symfony/data/messenger_handle_trait_with_subscriber.php new file mode 100644 index 00000000..03456231 --- /dev/null +++ b/tests/Type/Symfony/data/messenger_handle_trait_with_subscriber.php @@ -0,0 +1,72 @@ + ['method' => 'handleInt']; + yield FloatQuery::class => ['method' => 'handleFloat']; + yield StringQuery::class => ['method' => 'handleString']; + } + + public function __invoke(BooleanQuery $query): bool + { + return true; + } + + public function handleInt(IntQuery $query): int + { + return 0; + } + + public function handleFloat(FloatQuery $query): float + { + return 0.0; + } + + public function handleString(StringQuery $query): string + { + return 'string result'; + } +} + +class MultiHandlesForInTheSameHandlerQuery {} +class MultiHandlesForInTheSameHandler implements MessageSubscriberInterface +{ + public static function getHandledMessages(): iterable + { + yield MultiHandlesForInTheSameHandlerQuery::class; + yield MultiHandlesForInTheSameHandlerQuery::class => ['priority' => '0']; + } + + public function __invoke(MultiHandlesForInTheSameHandlerQuery $query): bool + { + return true; + } +} + +class HandleTraitClass { + use HandleTrait; + + public function __invoke() + { + assertType('bool', $this->handle(new BooleanQuery())); + assertType('int', $this->handle(new IntQuery())); + assertType('float', $this->handle(new FloatQuery())); + assertType('string', $this->handle(new StringQuery())); + + // HandleTrait will throw exception in fact due to multiple handle methods/handlers per single query + assertType('mixed', $this->handle(new MultiHandlesForInTheSameHandlerQuery())); + } +} From 45ce923f265c7d963d716b70886ce6d6ca99af91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Nowak?= Date: Fri, 11 Jul 2025 11:17:11 +0200 Subject: [PATCH 2/4] optional test-case for messenger_handle_trait_with_subscriber.php --- tests/Type/Symfony/ExtensionTest.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/Type/Symfony/ExtensionTest.php b/tests/Type/Symfony/ExtensionTest.php index e541cd5d..0848715e 100644 --- a/tests/Type/Symfony/ExtensionTest.php +++ b/tests/Type/Symfony/ExtensionTest.php @@ -6,6 +6,7 @@ use ReflectionMethod; use Symfony\Component\HttpFoundation\Request; use function class_exists; +use function interface_exists; use function strpos; class ExtensionTest extends TypeInferenceTestCase @@ -14,14 +15,12 @@ class ExtensionTest extends TypeInferenceTestCase /** @return mixed[] */ public function dataFileAsserts(): iterable { - if (class_exists('Symfony\Component\Messenger\Handler\MessageSubscriberInterface')) { - // todo temporary check - die('test if case is triggered'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/messenger_handle_trait.php'); + if (interface_exists('Symfony\Component\Messenger\Handler\MessageSubscriberInterface')) { yield from $this->gatherAssertTypes(__DIR__ . '/data/messenger_handle_trait_with_subscriber.php'); } - yield from $this->gatherAssertTypes(__DIR__ . '/data/messenger_handle_trait.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/envelope_all.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/header_bag_get.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/response_header_bag_get_cookies.php'); From 6031f949ff06036362d7250492a5bc13803aa9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Nowak?= Date: Fri, 11 Jul 2025 11:23:38 +0200 Subject: [PATCH 3/4] fix --- src/Symfony/MessageMapFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/MessageMapFactory.php b/src/Symfony/MessageMapFactory.php index bcff16d2..9ebf0fb4 100644 --- a/src/Symfony/MessageMapFactory.php +++ b/src/Symfony/MessageMapFactory.php @@ -91,7 +91,7 @@ public function create(): MessageMap /** @return iterable> */ private function guessHandledMessages(ClassReflection $reflectionClass): iterable { - if (class_exists(MessageSubscriberInterface::class) && $reflectionClass->implementsInterface(MessageSubscriberInterface::class)) { + if (interface_exists(MessageSubscriberInterface::class) && $reflectionClass->implementsInterface(MessageSubscriberInterface::class)) { $className = $reflectionClass->getName(); foreach ($className::getHandledMessages() as $index => $value) { From 8561caff5be1d074c9fe2aad7f1ef8cd2ba0bf35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Nowak?= Date: Fri, 11 Jul 2025 11:25:13 +0200 Subject: [PATCH 4/4] cs fix --- src/Symfony/MessageMapFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/MessageMapFactory.php b/src/Symfony/MessageMapFactory.php index 9ebf0fb4..d94f046f 100644 --- a/src/Symfony/MessageMapFactory.php +++ b/src/Symfony/MessageMapFactory.php @@ -7,6 +7,7 @@ use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; use function class_exists; use function count; +use function interface_exists; use function is_array; use function is_int; use function is_string;