8000 feature #44971 [Messenger] Resolve handled classes when only method i… · symfony/symfony@e875021 · GitHub
[go: up one dir, main page]

Skip to content

Commit e875021

Browse files
committed
feature #44971 [Messenger] Resolve handled classes when only method in tag is provided (angelov)
This PR was squashed before being merged into the 6.1 branch. Discussion ---------- [Messenger] Resolve handled classes when only method in tag is provided | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | / | License | MIT | Doc PR | / When tagging Messenger handlers, if the `method` attribute is set, the compiler pass does not resolve the message type before handling it - it requires the `handles` attribute to be set as well. With this PR, the message type is being resolved even if method other than `__invoke` is being used. I'm not sure if this is a bug fix or just an improvement :/ Commits ------- 780b7da [Messenger] Resolve handled classes when only method in tag is provided
2 parents 6b9fafb + 780b7da commit e875021

File tree

4 files changed

+66
-9
lines changed

4 files changed

+66
-9
lines changed

src/Symfony/Component/Messenger/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Add `SerializedMessageStamp` to avoid serializing a message when a retry occurs.
8+
* Automatically resolve handled message type when method different from `__invoke` is used as handler.
89

910
6.0
1011
---

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
7878
if (isset($tag['handles'])) {
7979
$handles = isset($tag['method']) ? [$tag['handles'] => $tag['method']] : [$tag['handles']];
8080
} else {
81-
$handles = $this->guessHandledClasses($r, $serviceId);
81+
$handles = $this->guessHandledClasses($r, $serviceId, $tag['method'] ?? '__invoke');
8282
}
8383

8484
$message = null;
@@ -197,25 +197,29 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
197197
}
198198
}
199199

200-
private function guessHandledClasses(\ReflectionClass $handlerClass, string $serviceId): iterable
200+
private function guessHandledClasses(\ReflectionClass $handlerClass, string $serviceId, string $methodName): iterable
201201
{
202202
if ($handlerClass->implementsInterface(MessageSubscriberInterface::class)) {
203203
return $handlerClass->getName()::getHandledMessages();
204204
}
205205

206206
try {
207-
$method = $handlerClass->getMethod('__invoke');
207+
$method = $handlerClass->getMethod($methodName);
208208
} catch (\ReflectionException $e) {
209-
throw new RuntimeException(sprintf('Invalid handler service "%s": class "%s" must have an "__invoke()" method.', $serviceId, $handlerClass->getName()));
209+
throw new RuntimeException(sprintf('Invalid handler service "%s": class "%s" must have an "%s()" method.', $serviceId, $handlerClass->getName(), $methodName));
210210
}
211211

212212
if (0 === $method->getNumberOfRequiredParameters()) {
213-
throw new RuntimeException(sprintf('Invalid handler service "%s": method "%s::__invoke()" requires at least one argument, first one being the message it handles.', $serviceId, $handlerClass->getName()));
213+
throw new RuntimeException(sprintf('Invalid handler service "%s": method "%s::%s()" requires at least one argument, first one being the message it handles.', $serviceId, $handlerClass->getName(), $methodName));
214214
}
215215

216216
$parameters = $method->getParameters();
217-
if (!$type = $parameters[0]->getType()) {
218-
throw new RuntimeException(sprintf('Invalid handler service "%s": argument "$%s" of method "%s::__invoke()" must have a type-hint corresponding to the message class it handles.', $serviceId, $parameters[0]->getName(), $handlerClass->getName()));
217+
218+
/** @var \ReflectionNamedType|\ReflectionUnionType|null */
219+
$type = $parameters[0]->getType();
220+
221+
if (!$type) {
222+
throw new RuntimeException(sprintf('Invalid handler service "%s": argument "$%s" of method "%s::%s()" must have a type-hint corresponding to the message class it handles.', $serviceId, $parameters[0]->getName(), $handlerClass->getName(), $methodName));
219223
}
220224

221225
if ($type instanceof \ReflectionUnionType) {
@@ -232,10 +236,10 @@ private function guessHandledClasses(\ReflectionClass $handlerClass, string $ser
232236
}
233237

234238
if ($type->isBuiltin()) {
235-
throw new RuntimeException(sprintf('Invalid handler service "%s": type-hint of argument "$%s" in method "%s::__invoke()" must be a class , "%s" given.', $serviceId, $parameters[0]->getName(), $handlerClass->getName(), $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type));
239+
throw new RuntimeException(sprintf('Invalid handler service "%s": type-hint of argument "$%s" in method "%s::%s()" must be a class , "%s" given.', $serviceId, $parameters[0]->getName(), $handlerClass->getName(), $methodName, $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type));
236240
}
237241

238-
return [$type->getName()];
242+
return ('__invoke' === $methodName) ? [$type->getName()] : [$type->getName() => $methodName];
239243
}
240244

241245
private function registerReceivers(ContainerBuilder $container, array $busIds)

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
use Symfony\Component\Messenger\Tests\Fixtures\MultipleBusesMessageHandler;
4848
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
4949
use Symfony\Component\Messenger\Tests\Fixtures\TaggedDummyHandler;
50+
use Symfony\Component\Messenger\Tests\Fixtures\TaggedDummyHandlerWithCustomMethods;
5051
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
5152

5253
class MessengerPassTest extends TestCase
@@ -133,6 +134,40 @@ public function testTaggedMessageHandler()
133134
$this->assertHandlerDescriptor($container, $handlerDescriptionMapping, DummyMessage::class, [TaggedDummyHandler::class], [[]]);
134135
}
135136

137+
public function testTaggedMessageHandlerWithGivenMethodAndNotGivenMessageType()
138+
{
139+
$container = $this->getContainerBuilder($busId = 'message_bus');
140+
$container
141+
->register(TaggedDummyHandlerWithCustomMethods::class, TaggedDummyHandlerWithCustomMethods::class)
142+
->setAutoconfigured(true)
143+
->addTag('messenger.message_handler', [
144+
'method' => 'handleDummyMessage',
145+
])
146+
->addTag('messenger.message_handler', [
147+
'method' => 'handleSecondMessage',
148+
]);
149+
150+
(new MessengerPass())->process($container);
151+
152+
$handlersMapping = $container->getDefinition($busId.'.messenger.handlers_locator')->getArgument(0);
153+
154+
$this->assertArrayHasKey(DummyMessage::class, $handlersMapping);
155+
$this->assertHandlerDescriptor(
156+
$container,
157+
$handlersMapping,
158+
DummyMessage::class,
159+
[[TaggedDummyHandlerWithCustomMethods::class, 'handleDummyMessage']]
160+
);
161+
162+
$this->assertArrayHasKey(SecondMessage::class, $handlersMapping);
163+
$this->assertHandlerDescriptor(
164+
$container,
165+
$handlersMapping,
166+
SecondMessage::class,
167+
[[TaggedDummyHandlerWithCustomMethods::class, 'handleSecondMessage']]
168+
);
169+
}
170+
136171
public function testProcessHandlersByBus()
137172
{
138173
$container = $this->getContainerBuilder($commandBusId = 'command_bus');
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Tests\Fixtures;
4+
5+
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
6+
7+
#[AsMessageHandler]
8+
class TaggedDummyHandlerWithCustomMethods
9+
{
10+
public function handleDummyMessage(DummyMessage $message)
11+
{
12+
}
13+
14+
public function handleSecondMessage(SecondMessage $message)
15+
{
16+
}
17+
}

0 commit comments

Comments
 (0)
0