@@ -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 = iterator_to_array ($ 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 ('There is %d messages to remove. Do you want to continue? ' , $ idsCount ))) {
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,22 @@ private function removeMessagesById(array $ids, ListableReceiverInterface $recei
119134 }
120135 }
121136
137+ private function getMessageIdsByClassFilter (string $ classFilter , ListableReceiverInterface $ receiver ): iterable
138+ {
139+ $ this ->phpSerializer ?->acceptPhpIncompleteClass();
140+ try {
141+ foreach ($ receiver ->all () as $ envelope ) {
142+ if ($ classFilter !== $ envelope ->getMessage ()::class) {
143+ continue ;
144+ }
145+
146+ yield $ this ->getMessageId ($ envelope );
147+ };
148+ } finally {
149+ $ this ->phpSerializer ?->rejectPhpIncompleteClass();
150+ }
151+ }
152+
122153 private function removeAllMessages (ListableReceiverInterface $ receiver , SymfonyStyle $ io , bool $ shouldForce , bool $ shouldDisplayMessages ): void
123154 {
124155 if (!$ shouldForce ) {
0 commit comments