8000 Uses custom method names for handlers · symfony/symfony@f9c1e0d · GitHub
[go: up one dir, main page]

Skip to content

Commit f9c1e0d

Browse files
committed
Uses custom method names for handlers
1 parent 9ae116f commit f9c1e0d

File tree

3 files changed

+108
-4
lines changed

3 files changed

+108
-4
lines changed

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

Lines changed: 26 additions & 4 deletions
+
$definitions[$serviceId = hash('sha1', $messageClass.':'.$messagePriority.':'.$serviceId)] = $wrapperDefinition;
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\Messenger\Handler\ChainHandler;
2222
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
2323
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
24+
use Symfony\Component\Messenger\Handler\MethodOnObjectHandler;
2425

2526
/**
2627
* @author Samuel Roze <samuel.roze@gmail.com>
@@ -60,27 +61,49 @@ public function process(ContainerBuilder $container)
6061

6162
private function registerHandlers(ContainerBuilder $container)
6263
{
64+
$definitions = array();
6365
$handlersByMessage = array();
6466

6567
foreach ($container->findTaggedServiceIds($this->handlerTag, true) as $serviceId => $tags) {
6668
foreach ($tags as $tag) {
67-
$handles = isset($tag['handles']) ? array($tag['handles']) : $this->guessHandledClasses($r = $container->getReflectionClass($container->getDefinition($serviceId)->getClass()), $serviceId);
69+
if (isset($tag['handles'])) {
70+
$handles = isset($tag['method']) ? array($tag['handles'] => $tag['method']) : array($tag['handles']);
71+
} else {
72+
$handles = $this->guessHandledClasses($r = $container->getReflectionClass($container->getDefinition($serviceId)->getClass()), $serviceId);
73+
}
74+
6875
$priority = $tag['priority'] ?? 0;
6976

70-
foreach ($handles as $messageClass) {
77+
foreach ($handles as $messageClass => $method) {
78+
if (is_int($messageClass)) {
79+
$messageClass = $method;
80+
$method = '__invoke';
81+
}
82+
7183
if (\is_array($messageClass)) {
7284
$messagePriority = $messageClass[1];
7385
$messageClass = $messageClass[0];
7486
} else {
7587
$messagePriority = $priority;
7688
}
7789

90+
if (is_array($method)) {
91+
$messagePriority = $method[1];
92+
$method = $method[0];
93+
}
94+
7895
if (!class_exists($messageClass)) {
79-
$messageClassLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : sprintf($r->implementsInterface(MessageHandlerInterface::class) ? 'returned by method "%s::getHandledMessages()"' : 'used as argument type in method "%s::__invoke()"', $r->getName());
96+
$messageClassLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : $r->implementsInterface(MessageHandlerInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method);
8097

8198
throw new RuntimeException(sprintf('Invalid handler service "%s": message class "%s" %s does not exist.', $serviceId, $messageClass, $messageClassLocation));
8299
}
83100

101+
if ('__invoke' !== $method) {
102+
$wrapperDefinition = (new Definition(MethodOnObjectHandler::class))->setArguments(array(new Reference($serviceId), $method));
103+
104
105+
}
106+
84107
$handlersByMessage[$messageClass][$messagePriority][] = new Reference($serviceId);
85108
}
86109
}
@@ -91,7 +114,6 @@ private function registerHandlers(ContainerBuilder $container)
91114
$handlersByMessage[$message] = \call_user_func_array('array_merge', $handlersByMessage[$message]);
92115
}
93116

94-
$definitions = array();
95117
foreach ($handlersByMessage as $message => $handlers) {
96118
if (1 === \count($handlers)) {
97119
$handlersByMessage[$message] = current($handlers);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Handler;
13+
14+
/**
15+
* Used to transform an object and a method to a callable handler.
16+
*
17+
* @author Samuel Roze <samuel.roze@gmail.com>
18+
*/
19+
final class MethodOnObjectHandler
20+
{
21+
private $object;
22+
private $method;
23+
24+
public function __construct($object, string $method)
25+
{
26+
if (!is_object($object)) {
27+
throw new \InvalidArgumentException(sprintf('Expected an object as argument but got %s', gettype($object)));
28+
}
29+
30+
$this->object = $object;
31+
$this->method = $method;
32+
}
33+
34+
public function __invoke($message)
35+
{
36+
return ($this->object)->{$this->method}($message);
37+
}
38+
}

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Messenger\DependencyInjection\MessengerPass;
2323
use Symfony\Component\Messenger\Handler\ChainHandler;
2424
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
25+
use Symfony\Component\Messenger\Handler\MethodOnObjectHandler;
2526
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
2627
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
2728
use Symfony\Component\Messenger\Transport\ReceiverInterface;
@@ -92,6 +93,38 @@ public function testGetClassesFromTheHandlerSubscriberInterface()
9293
$this->assertEquals(array(new Reference(PrioritizedHandler::class), new Reference(HandlerWithMultipleMessages::class)), $definition->getArgument(0));
9394
}
9495

96+
public function testGetClassesAndMethodsAndPrioritiesFromTheSubscriber()
97+
{
98+
$container = $this->getContainerBuilder();
99+
$container
100+
->register(HandlerMappingMethods::class, HandlerMappingMethods::class)
101+
->addTag('messenger.message_handler')
102+
;
103+
$container
104+
->register(PrioritizedHandler::class, PrioritizedHandler::class)
105+
->addTag('messenger.message_handler')
106+
;
107+
108+
(new MessengerPass())->process($container);
109+
110+
$handlerLocatorDefinition = $container->getDefinition($container->getDefinition('messenger.handler_resolver')->getArgument(0));
111+
$handlerMapping = $handlerLocatorDefinition->getArgument(0);
112+
113+
$this->assertArrayHasKey('handler.'.DummyMessage::class, $handlerMapping);
114+
$this->assertArrayHasKey('handler.'.SecondMessage::class, $handlerMapping);
115+
116+
$dummyHandlerReference = (string) $handlerMapping['handler.'.DummyMessage::class]->getValues()[0];
117+
$dummyHandlerDefinition = $container->getDefinition($dummyHandlerReference);
118+
$this->assertSame(MethodOnObjectHandler::class, $dummyHandlerDefinition->getClass());
119+
$this->assertEquals(new Reference(HandlerMappingMethods::class), $dummyHandlerDefinition->getArgument(0));
120+
$this->assertSame('dummyMethod', $dummyHandlerDefinition->getArgument(1));
121+
122+
$secondHandlerReference = (string) $handlerMapping['handler.'.SecondMessage::class]->getValues()[0];
123+
$secondHandlerDefinition = $container->getDefinition($secondHandlerReference);
124+
$this->assertSame(ChainHandler::class, $secondHandlerDefinition->getClass());
125+
$this->assertEquals(new Reference(PrioritizedHandler::class), $secondHandlerDefinition->getArgument(0)[1]);
126+
}
127+
95128
public function testItRegistersReceivers()
96129
{
97130
$container = $this->getContainerBuilder();
@@ -347,6 +380,17 @@ public static function getHandledMessages(): array
347380
}
348381
}
349382

383+
class HandlerMappingMethods implements MessageSubscriberInterface
384+
{
385+
public static function getHandledMessages(): array
386+
{
387+
return array(
388+
DummyMessage::class => 'dummyMethod',
389+
SecondMessage::class => array('secondMessage', 20),
390+
);
391+
}
392+
}
393+
350394
class HandleNoMessageHandler implements MessageSubscriberInterface
351395
{
352396
public static function getHandledMessages(): array

0 commit comments

Comments
 (0)
0