1313
1414namespace CodeIgniter \Commands \Utilities ;
1515
16- use CodeIgniter \CLI \BaseCommand ;
16+ use CodeIgniter \CLI \AbstractCommand ;
17+ use CodeIgniter \CLI \Attributes \Command ;
1718use CodeIgniter \CLI \CLI ;
19+ use CodeIgniter \CLI \Input \Argument ;
1820use CodeIgniter \Commands \Utilities \Routes \FilterCollector ;
1921
2022/**
2123 * Check filters for a route.
2224 */
23- class FilterCheck extends BaseCommand
25+ #[Command(name: 'filter:check ' , description: 'Check filters for a route. ' , group: 'CodeIgniter ' )]
26+ class FilterCheck extends AbstractCommand
2427{
25- /**
26- * The group the command is lumped under
27- * when listing commands.
28- *
29- * @var string
30- */
31- protected $ group = 'CodeIgniter ' ;
32-
33- /**
34- * The Command's name
35- *
36- * @var string
37- */
38- protected $ name = 'filter:check ' ;
39-
40- /**
41- * the Command's short description
42- *
43- * @var string
44- */
45- protected $ description = 'Check filters for a route. ' ;
46-
47- /**
48- * the Command's usage
49- *
50- * @var string
51- */
52- protected $ usage = 'filter:check <HTTP method> <route> ' ;
53-
54- /**
55- * the Command's Arguments
56- *
57- * @var array<string, string>
58- */
59- protected $ arguments = [
60- 'method ' => 'The HTTP method. GET, POST, PUT, etc. ' ,
61- 'route ' => 'The route (URI path) to check filters. ' ,
62- ];
63-
64- /**
65- * the Command's Options
66- *
67- * @var array<string, string>
68- */
69- protected $ options = [];
28+ protected function configure (): void
29+ {
30+ $ this
31+ ->addArgument (new Argument (
32+ name: 'method ' ,
33+ description: 'The HTTP method. GET, POST, PUT, etc. ' ,
34+ required: true ,
35+ ))
36+ ->addArgument (new Argument (
37+ name: 'route ' ,
38+ description: 'The route (URI path) to check filters. ' ,
39+ required: true ,
40+ ));
41+ }
7042
71- /**
72- * @return int exit code
73- */
74- public function run (array $ params )
43+ protected function execute (array $ arguments , array $ options ): int
7544 {
76- if (! $ this ->checkParams ($ params )) {
77- return EXIT_ERROR ;
78- }
45+ $ method = $ arguments ['method ' ];
46+ assert (is_string ($ method ));
7947
80- $ method = $ params [ 0 ];
81- $ route = $ params [ 1 ] ;
48+ $ route = $ arguments [ ' route ' ];
49+ assert ( is_string ( $ route)) ;
8250
83- // Load Routes
8451 service ('routes ' )->loadRoutes ();
8552
8653 $ filterCollector = new FilterCollector ();
@@ -89,14 +56,10 @@ public function run(array $params)
8956
9057 // PageNotFoundException
9158 if ($ filters ['before ' ] === ['<unknown> ' ]) {
92- CLI ::error (
93- "Can't find a route: " .
94- CLI ::color (
95- '" ' . strtoupper ($ method ) . ' ' . $ route . '" ' ,
96- 'black ' ,
97- 'light_gray ' ,
98- ),
99- );
59+ CLI ::error (sprintf (
60+ "Can't find a route: %s " ,
61+ CLI ::color (sprintf ('"%s %s" ' , strtoupper ($ method ), $ route ), 'black ' , 'light_gray ' ),
62+ ));
10063
10164 return EXIT_ERROR ;
10265 }
@@ -107,23 +70,6 @@ public function run(array $params)
10770 return EXIT_SUCCESS ;
10871 }
10972
110- /**
111- * @param array<int|string, string|null> $params
112- */
113- private function checkParams (array $ params ): bool
114- {
115- if (! isset ($ params [0 ], $ params [1 ])) {
116- CLI ::error ('You must specify a HTTP verb and a route. ' );
117- CLI ::write (' Usage: ' . $ this ->usage );
118- CLI ::write ('Example: filter:check GET / ' );
119- CLI ::write (' filter:check PUT products/1 ' );
120-
121- return false ;
122- }
123-
124- return true ;
125- }
126-
12773 /**
12874 * @param array{before: list<string>, after: list<string>} $filters
12975 */
@@ -133,67 +79,69 @@ private function showTable(
13379 string $ method ,
13480 string $ route ,
13581 ): void {
136- $ thead = [
137- 'Method ' ,
138- 'Route ' ,
139- 'Before Filters ' ,
140- 'After Filters ' ,
82+ $ merged = $ this ->mergeFilters ($ filterCollector ->getRequiredFilters (), $ filters );
83+
84+ $ thead = ['Method ' , 'Route ' , 'Before Filters ' , 'After Filters ' ];
85+ $ tbody = [
86+ [
87+ strtoupper ($ method ),
88+ $ route ,
89+ implode (' ' , $ merged ['before ' ]),
90+ implode (' ' , $ merged ['after ' ]),
91+ ],
14192 ];
14293
143- $ required = $ filterCollector ->getRequiredFilters ();
94+ CLI ::table ($ tbody , $ thead );
95+ }
14496
145- $ coloredRequired = $ this ->colorItems ($ required );
97+ private function showFilterClasses (
98+ FilterCollector $ filterCollector ,
99+ string $ method ,
100+ string $ route ,
101+ ): void {
102+ $ merged = $ this ->mergeFilters (
103+ $ filterCollector ->getRequiredFilterClasses (),
104+ $ filterCollector ->getClasses ($ method , $ route ),
105+ );
146106
147- $ before = array_merge ($ coloredRequired ['before ' ], $ filters ['before ' ]);
148- $ after = array_merge ($ filters ['after ' ], $ coloredRequired ['after ' ]);
107+ $ lastPosition = array_key_last ($ merged );
149108
150- $ tbody = [];
151- $ tbody [] = [
152- strtoupper ($ method ),
153- $ route ,
154- implode (' ' , $ before ),
155- implode (' ' , $ after ),
156- ];
109+ foreach ($ merged as $ position => $ classes ) {
110+ CLI ::write (sprintf ('%s Filter Classes: ' , ucfirst ($ position )), 'cyan ' );
111+ CLI ::write (implode (' → ' , $ classes ));
157112
158- CLI ::table ($ tbody , $ thead );
113+ if ($ position !== $ lastPosition ) {
114+ CLI ::newLine ();
115+ }
116+ }
159117 }
160118
161119 /**
162- * Color all elements of the array.
120+ * Merges the required filters (highlighted) with the route's filters,
121+ * keeping required-before filters first and required-after filters last.
163122 *
164- * @param array<array-key, mixed> $array
123+ * @param array{before: list<string>, after: list<string>} $required
124+ * @param array{before: list<string>, after: list<string>} $filters
165125 *
166- * @return array<array-key, mixed>
126+ * @return array{before: list<string>, after: list<string>}
167127 */
168- private function colorItems (array $ array ): array
128+ private function mergeFilters (array $ required , array $ filters ): array
169129 {
170- return array_map (function ($ item ): array |string {
171- if (is_array ($ item )) {
172- return $ this ->colorItems ($ item );
173- }
174-
175- return CLI ::color ($ item , 'yellow ' );
176- }, $ array );
177- }
178-
179- private function showFilterClasses (
180- FilterCollector $ filterCollector ,
181- string $ method ,
182- string $ route ,
183- ): void {
184- $ requiredFilterClasses = $ filterCollector ->getRequiredFilterClasses ();
185- $ filterClasses = $ filterCollector ->getClasses ($ method , $ route );
186-
187- $ coloredRequiredFilterClasses = $ this ->colorItems ($ requiredFilterClasses );
188-
189- $ classList = [
190- 'before ' => array_merge ($ coloredRequiredFilterClasses ['before ' ], $ filterClasses ['before ' ]),
191- 'after ' => array_merge ($ filterClasses ['after ' ], $ coloredRequiredFilterClasses ['after ' ]),
130+ return [
131+ 'before ' => array_merge ($ this ->highlight ($ required ['before ' ]), $ filters ['before ' ]),
132+ 'after ' => array_merge ($ filters ['after ' ], $ this ->highlight ($ required ['after ' ])),
192133 ];
134+ }
193135
194- foreach ($ classList as $ position => $ classes ) {
195- CLI ::write (ucfirst ($ position ) . ' Filter Classes: ' , 'cyan ' );
196- CLI ::write (implode (' → ' , $ classes ));
197- }
136+ /**
137+ * Applies the highlight color to the given filter names.
138+ *
139+ * @param list<string> $items
140+ *
141+ * @return list<string>
142+ */
143+ private function highlight (array $ items ): array
144+ {
145+ return array_map (static fn (string $ item ): string => CLI ::color ($ item , 'yellow ' ), $ items );
198146 }
199147}
0 commit comments