Skip to content

Commit d6bde21

Browse files
committed
bug symfony#47227 [Messenger] Support for custom handler method containing a Union type tagged with #[AsMessageHandler] (ArchitectNate)
This PR was squashed before being merged into the 6.1 branch. Discussion ---------- [Messenger] Support for custom handler method containing a Union type tagged with #[AsMessageHandler] | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix symfony#47206 | License | MIT | Doc PR | No When Union Types were implemented for the #[AsMessageHandler] attribute, it wasn't designed with non `__invoke` methods in mind. This fix detects if we are using `__invoke` or not and constructs the return to match the rest of the logic, mainly it allows for a `type => methodName` map if `__invoke` is not being used. Commits ------- f38d8f8 [Messenger] Support for custom handler method containing a Union type tagged with #[AsMessageHandler]
2 parents bc2f554 + f38d8f8 commit d6bde21

File tree

5 files changed

+93
-1
lines changed

5 files changed

+93
-1
lines changed

src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ private function guessHandledClasses(\ReflectionClass $handlerClass, string $ser
231231
}
232232

233233
if ($types) {
234-
return $types;
234+
return ('__invoke' === $methodName) ? $types : array_fill_keys($types, $methodName);
235235
}
236236
}
237237

src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php

+51
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
use Symfony\Component\Messenger\Tests\Fixtures\MultipleBusesMessageHandler;
5050
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
5151
use Symfony\Component\Messenger\Tests\Fixtures\TaggedDummyHandler;
52+
use Symfony\Component\Messenger\Tests\Fixtures\TaggedDummyHandlerWithUnionTypes;
53+
use Symfony\Component\Messenger\Tests\Fixtures\UnionTypeOneMessage;
54+
use Symfony\Component\Messenger\Tests\Fixtures\UnionTypeTwoMessage;
5255
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
5356

5457
class MessengerPassTest extends TestCase
@@ -180,6 +183,54 @@ public function testTaggedMessageHandler()
180183
);
181184
}
182185

186+
public function testTaggedMessageHandlerWithUnionTypes()
187+
{
188+
$container = $this->getContainerBuilder($busId = 'message_bus');
189+
$container->registerAttributeForAutoconfiguration(AsMessageHandler::class, static function (ChildDefinition $definition, AsMessageHandler $attribute, \ReflectionClass|\ReflectionMethod $reflector): void {
190+
$tagAttributes = get_object_vars($attribute);
191+
$tagAttributes['from_transport'] = $tagAttributes['fromTransport'];
192+
unset($tagAttributes['fromTransport']);
193+
if ($reflector instanceof \ReflectionMethod) {
194+
if (isset($tagAttributes['method'])) {
195+
throw new LogicException(sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name));
196+
}
197+
$tagAttributes['method'] = $reflector->getName();
198+
}
199+
200+
$definition->addTag('messenger.message_handler', $tagAttributes);
201+
});
202+
$container
203+
->register(TaggedDummyHandlerWithUnionTypes::class, TaggedDummyHandlerWithUnionTypes::class)
204+
->setAutoconfigured(true)
205+
;
206+
207+
(new AttributeAutoconfigurationPass())->process($container);
208+
(new ResolveInstanceofConditionalsPass())->process($container);
209+
(new MessengerPass())->process($container);
210+
211+
$handlersLocatorDefinition = $container->getDefinition($busId.'.messenger.handlers_locator');
212+
$this->assertSame(HandlersLocator::class, $handlersLocatorDefinition->getClass());
213+
214+
$handlerDescriptionMapping = $handlersLocatorDefinition->getArgument(0);
215+
216+
$this->assertCount(4, $handlerDescriptionMapping);
217+
218+
$this->assertHandlerDescriptor($container, $handlerDescriptionMapping, DummyMessage::class, [TaggedDummyHandlerWithUnionTypes::class], [[]]);
219+
$this->assertHandlerDescriptor($container, $handlerDescriptionMapping, SecondMessage::class, [TaggedDummyHandlerWithUnionTypes::class], [[]]);
220+
$this->assertHandlerDescriptor(
221+
$container,
222+
$handlerDescriptionMapping,
223+
UnionTypeOneMessage::class,
224+
[[TaggedDummyHandlerWithUnionTypes::class, 'handleUnionTypeMessage']]
225+
);
226+
$this->assertHandlerDescriptor(
227+
$container,
228+
$handlerDescriptionMapping,
229+
UnionTypeTwoMessage::class,
230+
[[TaggedDummyHandlerWithUnionTypes::class, 'handleUnionTypeMessage']]
231+
);
232+
}
233+
183234
public function testProcessHandlersByBus()
184235
{
185236
$container = $this->getContainerBuilder($commandBusId = 'command_bus');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Tests\Fixtures;
13+
14+
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
15+
16+
#[AsMessageHandler]
17+
class TaggedDummyHandlerWithUnionTypes
18+
{
19+
public function __invoke(DummyMessage|SecondMessage $message)
20+
{
21+
}
22+
23+
#[AsMessageHandler]
24+
public function handleUnionTypeMessage(UnionTypeOneMessage|UnionTypeTwoMessage $message)
25+
{
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Tests\Fixtures;
4+
5+
class UnionTypeOneMessage
6+
{
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Tests\Fixtures;
4+
5+
class UnionTypeTwoMessage
6+
{
7+
}

0 commit comments

Comments
 (0)