diff --git a/src/Symfony/Component/Messenger/Command/FailedMessagesRemoveCommand.php b/src/Symfony/Component/Messenger/Command/FailedMessagesRemoveCommand.php index 52a93f5519..0c6a87cf4f 100644 --- a/src/Symfony/Component/Messenger/Command/FailedMessagesRemoveCommand.php +++ b/src/Symfony/Component/Messenger/Command/FailedMessagesRemoveCommand.php @@ -35,16 +35,17 @@ class FailedMessagesRemoveCommand extends AbstractFailedMessagesCommand { $this ->setDefinition([ - new InputArgument('id', InputArgument::REQUIRED, 'Specific message id to remove'), + new InputArgument('id', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Specific message id(s) to remove'), new InputOption('force', null, InputOption::VALUE_NONE, 'Force the operation without confirmation'), + new InputOption('show-messages', null, InputOption::VALUE_NONE, 'Display messages before removing it (if multiple ids are given)'), ]) - ->setDescription('Remove a message from the failure transport.') + ->setDescription('Remove given messages from the failure transport.') ->setHelp(<<<'EOF' -The %command.name% removes a message that is pending in the failure transport. +The %command.name% removes given messages that are pending in the failure transport. - php %command.full_name% {id} + php %command.full_name% {id1} [{id2} ...] -The specific id can be found via the messenger:failed:show command. +The specific ids can be found via the messenger:failed:show command. EOF ) ; @@ -60,29 +61,37 @@ EOF $receiver = $this->getReceiver(); $shouldForce = $input->getOption('force'); - $this->removeSingleMessage($input->getArgument('id'), $receiver, $io, $shouldForce); + $ids = $input->getArgument('id'); + $shouldDisplayMessages = $input->getOption('show-messages') || 1 === \count($ids); + $this->removeMessages($ids, $receiver, $io, $shouldForce, $shouldDisplayMessages); return 0; } - private function removeSingleMessage(string $id, ReceiverInterface $receiver, SymfonyStyle $io, bool $shouldForce) + private function removeMessages(array $ids, ReceiverInterface $receiver, SymfonyStyle $io, bool $shouldForce, bool $shouldDisplayMessages): void { if (!$receiver instanceof ListableReceiverInterface) { throw new RuntimeException(sprintf('The "%s" receiver does not support removing specific messages.', $this->getReceiverName())); } - $envelope = $receiver->find($id); - if (null === $envelope) { - throw new RuntimeException(sprintf('The message with id "%s" was not found.', $id)); - } - $this->displaySingleMessage($envelope, $io); + foreach ($ids as $id) { + $envelope = $receiver->find($id); + if (null === $envelope) { + $io->error(sprintf('The message with id "%s" was not found.', $id)); + continue; + } - if ($shouldForce || $io->confirm('Do you want to permanently remove this message?', false)) { - $receiver->reject($envelope); + if ($shouldDisplayMessages) { + $this->displaySingleMessage($envelope, $io); + } - $io->success('Message removed.'); - } else { - $io->note('Message not removed.'); + if ($shouldForce || $io->confirm('Do you want to permanently remove this message?', false)) { + $receiver->reject($envelope); + + $io->success(sprintf('Message with id %s removed.', $id)); + } else { + $io->note(sprintf('Message with id %s not removed.', $id)); + } } } } diff --git a/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRemoveCommandTest.php b/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRemoveCommandTest.php index 3856f1b073..d3de8733ee 100644 --- a/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRemoveCommandTest.php +++ b/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRemoveCommandTest.php @@ -19,7 +19,7 @@ use Symfony\Component\Messenger\Transport\Receiver\ListableReceiverInterface; class FailedMessagesRemoveCommandTest extends TestCase { - public function testBasicRun() + public function testRemoveUniqueMessage() { $receiver = $this->createMock(ListableReceiverInterface::class); $receiver->expects($this->once())->method('find')->with(20)->willReturn(new Envelope(new \stdClass())); @@ -30,8 +30,53 @@ class FailedMessagesRemoveCommandTest extends TestCase ); $tester = new CommandTester($command); - $tester->execute(['id' => 20, '--force' => true]); + $tester->execute(['id' => [20], '--force' => true]); - $this->assertStringContainsString('Message removed.', $tester->getDisplay()); + $this->assertStringContainsString('Failed Message Details', $tester->getDisplay()); + $this->assertStringContainsString('Message with id 20 removed.', $tester->getDisplay()); + } + + public function testRemoveMultipleMessages() + { + $receiver = $this->createMock(ListableReceiverInterface::class); + $receiver->expects($this->exactly(3))->method('find')->withConsecutive([20], [30], [40])->willReturnOnConsecutiveCalls( + new Envelope(new \stdClass()), + null, + new Envelope(new \stdClass()) + ); + + $command = new FailedMessagesRemoveCommand( + 'failure_receiver', + $receiver + ); + + $tester = new CommandTester($command); + $tester->execute(['id' => [20, 30, 40], '--force' => true]); + + $this->assertStringNotContainsString('Failed Message Details', $tester->getDisplay()); + $this->assertStringContainsString('Message with id 20 removed.', $tester->getDisplay()); + $this->assertStringContainsString('The message with id "30" was not found.', $tester->getDisplay()); + $this->assertStringContainsString('Message with id 40 removed.', $tester->getDisplay()); + } + + public function testRemoveMultipleMessagesAndDisplayMessages() + { + $receiver = $this->createMock(ListableReceiverInterface::class); + $receiver->expects($this->exactly(2))->method('find')->withConsecutive([20], [30])->willReturnOnConsecutiveCalls( + new Envelope(new \stdClass()), + new Envelope(new \stdClass()) + ); + + $command = new FailedMessagesRemoveCommand( + 'failure_receiver', + $receiver + ); + + $tester = new CommandTester($command); + $tester->execute(['id' => [20, 30], '--force' => true, '--show-messages' => true]); + + $this->assertStringContainsString('Failed Message Details', $tester->getDisplay()); + $this->assertStringContainsString('Message with id 20 removed.', $tester->getDisplay()); + $this->assertStringContainsString('Message with id 30 removed.', $tester->getDisplay()); } }