@@ -37,6 +37,7 @@ protected function configure(): void
3737 new InputOption ('force ' , null , InputOption::VALUE_NONE , 'Force the operation without confirmation ' ),
3838 new InputOption ('transport ' , null , InputOption::VALUE_OPTIONAL , 'Use a specific failure transport ' , self ::DEFAULT_TRANSPORT_OPTION ),
3939 new InputOption ('show-messages ' , null , InputOption::VALUE_NONE , 'Display messages before removing it (if multiple ids are given) ' ),
40+ new InputOption ('class-filter ' , null , InputOption::VALUE_REQUIRED , 'Filter by a specific class name ' ),
4041 ])
4142 ->setHelp (<<<'EOF'
4243The <info>%command.name%</info> removes given messages that are pending in the failure transport.
@@ -69,6 +70,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6970 $ shouldDeleteAllMessages = $ input ->getOption ('all ' );
7071
7172 $ idsCount = \count ($ ids );
73+
74+ if (!$ receiver instanceof ListableReceiverInterface) {
75+ throw new RuntimeException (\sprintf ('The "%s" receiver does not support removing specific messages. ' , $ failureTransportName ));
76+ }
77+
78+ if (!$ idsCount && null !== $ input ->getOption ('class-filter ' )) {
79+ $ ids = $ this ->getMessageIdsByClassFilter ($ input ->getOption ('class-filter ' ), $ receiver );
80+ $ idsCount = \count ($ ids );
81+
82+ if (!$ idsCount ) {
83+ throw new RuntimeException ('No failed messages were found with this filter. ' );
84+ }
85+
86+ if (!$ io ->confirm (\sprintf ('Can you confirm you want to remove %d message%s? ' , $ idsCount , 1 === $ idsCount ? '' : 's ' ))) {
87+ return 0 ;
88+ }
89+ }
90+
7291 if (!$ shouldDeleteAllMessages && !$ idsCount ) {
7392 throw new RuntimeException ('Please specify at least one message id. If you want to remove all failed messages, use the "--all" option. ' );
7493 } elseif ($ shouldDeleteAllMessages && $ idsCount ) {
@@ -77,10 +96,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7796
7897 $ shouldDisplayMessages = $ input ->getOption ('show-messages ' ) || 1 === $ idsCount ;
7998
80- if (!$ receiver instanceof ListableReceiverInterface) {
81- throw new RuntimeException (\sprintf ('The "%s" receiver does not support removing specific messages. ' , $ failureTransportName ));
82- }
83-
8499 if ($ shouldDeleteAllMessages ) {
85100 $ this ->removeAllMessages ($ receiver , $ io , $ shouldForce , $ shouldDisplayMessages );
86101 } else {
@@ -119,6 +134,26 @@ private function removeMessagesById(array $ids, ListableReceiverInterface $recei
119134 }
120135 }
121136
137+ private function getMessageIdsByClassFilter (string $ classFilter , ListableReceiverInterface $ receiver ): array
138+ {
139+ $ ids = [];
140+
141+ $ this ->phpSerializer ?->acceptPhpIncompleteClass();
142+ try {
143+ foreach ($ receiver ->all () as $ envelope ) {
144+ if ($ classFilter !== $ envelope ->getMessage ()::class) {
145+ continue ;
146+ }
147+
148+ $ ids [] = $ this ->getMessageId ($ envelope );
149+ };
150+ } finally {
151+ $ this ->phpSerializer ?->rejectPhpIncompleteClass();
152+ }
153+
154+ return $ ids ;
155+ }
156+
122157 private function removeAllMessages (ListableReceiverInterface $ receiver , SymfonyStyle $ io , bool $ shouldForce , bool $ shouldDisplayMessages ): void
123158 {
124159 if (!$ shouldForce ) {
0 commit comments