@@ -39,6 +39,8 @@ protected function configure(): void
39
39
new InputArgument ('id ' , InputArgument::OPTIONAL , 'Specific message id to show ' ),
40
40
new InputOption ('max ' , null , InputOption::VALUE_REQUIRED , 'Maximum number of messages to list ' , 50 ),
41
41
new InputOption ('transport ' , null , InputOption::VALUE_OPTIONAL , 'Use a specific failure transport ' , self ::DEFAULT_TRANSPORT_OPTION ),
42
+ new InputOption ('stats ' , null , InputOption::VALUE_NONE , 'Display the message count by class ' ),
43
+ new InputOption ('class-filter ' , null , InputOption::VALUE_REQUIRED , 'Filter by a specific class name ' ),
42
44
])
43
45
->setHelp (<<<'EOF'
44
46
The <info>%command.name%</info> shows message that are pending in the failure transport.
@@ -77,23 +79,36 @@ protected function execute(InputInterface $input, OutputInterface $output): int
77
79
throw new RuntimeException (sprintf ('The "%s" receiver does not support listing or showing specific messages. ' , $ failureTransportName ));
78
80
}
79
81
80
- if (null === $ id = $ input ->getArgument ('id ' )) {
81
- $ this ->listMessages ($ failureTransportName , $ io , $ input ->getOption ('max ' ));
82
+ if ($ input ->getOption ('stats ' )) {
83
+ $ this ->listMessagesPerClass ($ failureTransportName , $ io , $ input ->getOption ('max ' ));
84
+ } elseif (null === $ id = $ input ->getArgument ('id ' )) {
85
+ $ this ->listMessages ($ failureTransportName , $ io , $ input ->getOption ('max ' ), $ input ->getOption ('class-filter ' ));
82
86
} else {
83
87
$ this ->showMessage ($ failureTransportName , $ id , $ io );
84
88
}
85
89
86
90
return 0 ;
87
91
}
88
92
89
- private function listMessages (?string $ failedTransportName , SymfonyStyle $ io , int $ max )
93
+ private function listMessages (?string $ failedTransportName , SymfonyStyle $ io , int $ max, string $ classFilter = null )
90
94
{
91
95
/** @var ListableReceiverInterface $receiver */
92
96
$ receiver = $ this ->getReceiver ($ failedTransportName );
93
97
$ envelopes = $ receiver ->all ($ max );
94
98
95
99
$ rows = [];
100
+
101
+ if ($ classFilter ) {
102
+ $ io ->comment (sprintf ('Displaying only \'%s \' messages ' , $ classFilter ));
103
+ }
104
+
96
105
foreach ($ envelopes as $ envelope ) {
106
+ $ currentClassName = \get_class ($ envelope ->getMessage ());
107
+
108
+ if ($ classFilter && $ classFilter !== $ currentClassName ) {
109
+ continue ;
110
+ }
111
+
97
112
/** @var RedeliveryStamp|null $lastRedeliveryStamp */
98
113
$ lastRedeliveryStamp = $ envelope ->last (RedeliveryStamp::class);
99
114
/** @var ErrorDetailsStamp|null $lastErrorDetailsStamp */
@@ -106,27 +121,58 @@ private function listMessages(?string $failedTransportName, SymfonyStyle $io, in
106
121
107
122
$ rows [] = [
108
123
$ this ->getMessageId ($ envelope ),
109
- \get_class ( $ envelope -> getMessage ()) ,
124
+ $ currentClassName ,
110
125
null === $ lastRedeliveryStamp ? '' : $ lastRedeliveryStamp ->getRedeliveredAt ()->format ('Y-m-d H:i:s ' ),
111
126
$ errorMessage ,
112
127
];
113
128
}
114
129
115
- if (0 === \count ($ rows )) {
130
+ $ rowsCount = \count ($ rows );
131
+
132
+ if (0 === $ rowsCount ) {
116
133
$ io ->success ('No failed messages were found. ' );
117
134
118
135
return ;
119
136
}
120
137
121
138
$ io ->table (['Id ' , 'Class ' , 'Failed at ' , 'Error ' ], $ rows );
122
139
123
- if (\count ( $ rows ) === $ max ) {
140
+ if ($ rowsCount === $ max ) {
124
141
$ io ->comment (sprintf ('Showing first %d messages. ' , $ max ));
142
+ } elseif ($ classFilter ) {
143
+ $ io ->comment (sprintf ('Showing %d message(s). ' , $ rowsCount ));
125
144
}
126
145
127
146
$ io ->comment (sprintf ('Run <comment>messenger:failed:show {id} --transport=%s -vv</comment> to see message details. ' , $ failedTransportName ));
128
147
}
129
148
149
+ private function listMessagesPerClass (?string $ failedTransportName , SymfonyStyle $ io , int $ max )
150
+ {
151
+ /** @var ListableReceiverInterface $receiver */
152
+ $ receiver = $ this ->getReceiver ($ failedTransportName );
153
+ $ envelopes = $ receiver ->all ($ max );
154
+
155
+ $ countPerClass = [];
156
+
157
+ foreach ($ envelopes as $ envelope ) {
158
+ $ c = \get_class ($ envelope ->getMessage ());
159
+
160
+ if (!isset ($ countPerClass [$ c ])) {
161
+ $ countPerClass [$ c ] = [$ c , 0 ];
162
+ }
163
+
164
+ ++$ countPerClass [$ c ][1 ];
165
+ }
166
+
167
+ if (0 === \count ($ countPerClass )) {
168
+ $ io ->success ('No failed messages were found. ' );
169
+
170
+ return ;
171
+ }
172
+
173
+ $ io ->table (['Class ' , 'Count ' ], $ countPerClass );
174
+ }
175
+
130
176
private function showMessage (?string $ failedTransportName , string $ id , SymfonyStyle $ io )
131
177
{
132
178
/** @var ListableReceiverInterface $receiver */
0 commit comments