@@ -37,6 +37,7 @@ protected function configure(): void
37
37
new InputOption ('force ' , null , InputOption::VALUE_NONE , 'Force the operation without confirmation ' ),
38
38
new InputOption ('transport ' , null , InputOption::VALUE_OPTIONAL , 'Use a specific failure transport ' , self ::DEFAULT_TRANSPORT_OPTION ),
39
39
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 ' ),
40
41
])
41
42
->setHelp (<<<'EOF'
42
43
The <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
69
70
$ shouldDeleteAllMessages = $ input ->getOption ('all ' );
70
71
71
72
$ 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
+
72
91
if (!$ shouldDeleteAllMessages && !$ idsCount ) {
73
92
throw new RuntimeException ('Please specify at least one message id. If you want to remove all failed messages, use the "--all" option. ' );
74
93
} elseif ($ shouldDeleteAllMessages && $ idsCount ) {
@@ -77,10 +96,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
77
96
78
97
$ shouldDisplayMessages = $ input ->getOption ('show-messages ' ) || 1 === $ idsCount ;
79
98
80
- if (!$ receiver instanceof ListableReceiverInterface) {
81
- throw new RuntimeException (\sprintf ('The "%s" receiver does not support removing specific messages. ' , $ failureTransportName ));
82
- }
83
-
84
99
if ($ shouldDeleteAllMessages ) {
85
100
$ this ->removeAllMessages ($ receiver , $ io , $ shouldForce , $ shouldDisplayMessages );
86
101
} else {
@@ -119,6 +134,22 @@ private function removeMessagesById(array $ids, ListableReceiverInterface $recei
119
134
}
120
135
}
121
136
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
+
122
153
private function removeAllMessages (ListableReceiverInterface $ receiver , SymfonyStyle $ io , bool $ shouldForce , bool $ shouldDisplayMessages ): void
123
154
{
124
155
if (!$ shouldForce ) {
0 commit comments