Skip to content

Commit 5214050

Browse files
committed
refactor: migrate filter:check as a modern command
1 parent 7b7742f commit 5214050

2 files changed

Lines changed: 78 additions & 129 deletions

File tree

system/Commands/Utilities/FilterCheck.php

Lines changed: 77 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -13,74 +13,41 @@
1313

1414
namespace CodeIgniter\Commands\Utilities;
1515

16-
use CodeIgniter\CLI\BaseCommand;
16+
use CodeIgniter\CLI\AbstractCommand;
17+
use CodeIgniter\CLI\Attributes\Command;
1718
use CodeIgniter\CLI\CLI;
19+
use CodeIgniter\CLI\Input\Argument;
1820
use 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
}

tests/system/Commands/Utilities/FilterCheckTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public function testFilterCheckDefinedRoute(): void
5353
$this->assertStringContainsString(
5454
'Before Filter Classes:
5555
CodeIgniter\Filters\ForceHTTPS → CodeIgniter\Filters\PageCache
56+
5657
After Filter Classes:
5758
CodeIgniter\Filters\PageCache → CodeIgniter\Filters\PerformanceMetrics → CodeIgniter\Filters\DebugToolbar',
5859
(string) preg_replace('/\033\[.+?m/u', '', $this->getBuffer()),

0 commit comments

Comments
 (0)