Skip to content

handle optional MessageSubscriberInterface if exist #448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: 1.4.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Symfony/MessageMapFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -91,7 +92,7 @@ public function create(): MessageMap
/** @return iterable<string, array<string, string>> */
private function guessHandledMessages(ClassReflection $reflectionClass): iterable
{
if ($reflectionClass->implementsInterface(MessageSubscriberInterface::class)) {
if (interface_exists(MessageSubscriberInterface::class) && $reflectionClass->implementsInterface(MessageSubscriberInterface::class)) {
$className = $reflectionClass->getName();

foreach ($className::getHandledMessages() as $index => $value) {
Expand Down
6 changes: 6 additions & 0 deletions tests/Type/Symfony/ExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -15,6 +16,11 @@ class ExtensionTest extends TypeInferenceTestCase
public function dataFileAsserts(): iterable
{
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/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');
Expand Down
57 changes: 0 additions & 57 deletions tests/Type/Symfony/data/messenger_handle_trait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace MessengerHandleTrait;

use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
use Symfony\Component\Messenger\HandleTrait;
use function PHPStan\Testing\assertType;

Expand All @@ -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
Expand All @@ -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
{
Expand All @@ -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()));
}
}
72 changes: 72 additions & 0 deletions tests/Type/Symfony/data/messenger_handle_trait_with_subscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php declare(strict_types = 1);

namespace MessengerHandleTrait;

use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
use Symfony\Component\Messenger\HandleTrait;
use function PHPStan\Testing\assertType;

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 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()));
}
}