diff --git a/UPGRADE-4.2.md b/UPGRADE-4.2.md index bfc72e947d..01197dd714 100644 --- a/UPGRADE-4.2.md +++ b/UPGRADE-4.2.md @@ -89,6 +89,37 @@ Messenger * `EnvelopeItemInterface` doesn't extend `Serializable` anymore * The `handle` method of the `Symfony\Component\Messenger\Middleware\ValidationMiddleware` and `Symfony\Component\Messenger\Asynchronous\Middleware\SendMessageMiddleware` middlewares now requires an `Envelope` object to be given (because they implement the `EnvelopeAwareInterface`). When using these middleware with the provided `MessageBus`, you will not have to do anything. If you use the middlewares any other way, you can use `Envelope::wrap($message)` to create an envelope for your message. + * `MessageSubscriberInterface::getHandledMessages()` return value has changed. The value of an array item + needs to be an associative array or the method name. + + Before: + ```php + return [ + [FirstMessage::class, 0], + [SecondMessage::class, -10], + ]; + ``` + + After: + ```php + yield FirstMessage::class => ['priority' => 0]; + yield SecondMessage::class => ['priority => -10]; + ``` + + Before: + ```php + return [ + SecondMessage::class => ['secondMessageMethod', 20], + ]; + ``` + + After: + ```php + yield SecondMessage::class => [ + 'method' => 'secondMessageMethod', + 'priority' => 20, + ]; + ``` Security -------- diff --git a/src/Symfony/Component/Messenger/CHANGELOG.md b/src/Symfony/Component/Messenger/CHANGELOG.md index f053eaaf14..934c8e2fe6 100644 --- a/src/Symfony/Component/Messenger/CHANGELOG.md +++ b/src/Symfony/Component/Messenger/CHANGELOG.md @@ -4,6 +4,8 @@ CHANGELOG 4.2.0 ----- + * [BC BREAK] `MessageSubscriberInterface::getHandledMessages()` return value has changed. The value of an array item + needs to be an associative array or the method name. * `ValidationMiddleware::handle()` and `SendMessageMiddleware::handle()` now require an `Envelope` object * `EnvelopeItemInterface` doesn't extend `Serializable` anymore * [BC BREAK] The `ConsumeMessagesCommand` class now takes an instance of `Psr\Container\ContainerInterface` diff --git a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php index b41beb0fa3..a63ac7ae04 100644 --- a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php +++ b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php @@ -111,30 +111,21 @@ class MessengerPass implements CompilerPassInterface } if (\is_array($method)) { - if (isset($method[0]) && isset($method[1])) { - $messagePriority = $method[1]; - $method = $method[0]; - } elseif (isset($method['method']) || isset($method['bus'])) { - if (isset($method['bus'])) { - if (!\in_array($method['bus'], $busIds)) { - $messageClassLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : $r->implementsInterface(MessageSubscriberInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method); + if (isset($method['bus'])) { + if (!\in_array($method['bus'], $busIds)) { + $messageClassLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : $r->implementsInterface(MessageSubscriberInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method); - throw new RuntimeException(sprintf('Invalid configuration %s for message "%s": bus "%s" does not exist.', $messageClassLocation, $messageClass, $method['bus'])); - } - - $buses = array($method['bus']); + throw new RuntimeException(sprintf('Invalid configuration %s for message "%s": bus "%s" does not exist.', $messageClassLocation, $messageClass, $method['bus'])); } - if (isset($method['priority'])) { - $messagePriority = $method['priority']; - } - - $method = $method['method'] ?? '__invoke'; - } else { - $messageClassLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : $r->implementsInterface(MessageSubscriberInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method); - - throw new RuntimeException(sprintf('Invalid configuration %s for message "%s".', $messageClassLocation, $messageClass)); + $buses = array($method['bus']); } + + if (isset($method['priority'])) { + $messagePriority = $method['priority']; + } + + $method = $method['method'] ?? '__invoke'; } if (!\class_exists($messageClass) && !\interface_exists($messageClass)) { diff --git a/src/Symfony/Component/Messenger/Handler/MessageSubscriberInterface.php b/src/Symfony/Component/Messenger/Handler/MessageSubscriberInterface.php index ba4ae3ee79..a349dc5245 100644 --- a/src/Symfony/Component/Messenger/Handler/MessageSubscriberInterface.php +++ b/src/Symfony/Component/Messenger/Handler/MessageSubscriberInterface.php @@ -25,21 +25,24 @@ interface MessageSubscriberInterface extends MessageHandlerInterface * * It returns a list of messages like in the following example: * - * return [MyMessage::class]; + * yield MyMessage::class; * * It can also change the priority per classes. * - * return [ - * [FirstMessage::class, 0], - * [SecondMessage::class, -10], + * yield FirstMessage::class => ['priority' => 0]; + * yield SecondMessage::class => ['priority => -10]; + * + * It can also specify a method, a priority and/or a bus per message: + * + * yield FirstMessage::class => ['method' => 'firstMessageMethod']; + * yield SecondMessage::class => [ + * 'method' => 'secondMessageMethod', + * 'priority' => 20, + * 'bus' => 'my_bus_name', * ]; * - * It can also specify a method and/or a priority per message: - * - * return [ - * FirstMessage::class => 'firstMessageMethod', - * SecondMessage::class => ['secondMessageMethod', 20], - * ]; + * The benefit of using `yield` instead of returning an array is that you can `yield` multiple times the + * same key and therefore subscribe to the same message multiple times with different options. * * The `__invoke` method of the handler will be called as usual with the message to handle. */ diff --git a/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php b/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php index 28b6766efc..d59680e7b4 100644 --- a/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php +++ b/src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php @@ -723,9 +723,7 @@ class PrioritizedHandler implements MessageSubscriberInterface { public static function getHandledMessages(): iterable { - return array( - array(SecondMessage::class, 10), - ); + yield SecondMessage::class => array('priority' => 10); } public function __invoke() @@ -737,10 +735,8 @@ class HandlerMappingMethods implements MessageSubscriberInterface { public static function getHandledMessages(): iterable { - return array( - DummyMessage::class => 'dummyMethod', - SecondMessage::class => array('secondMessage', 20), - ); + yield DummyMessage::class => 'dummyMethod'; + yield SecondMessage::class => array('method' => 'secondMessage', 'priority' => 20); } public function dummyMethod()