Skip to content

Commit 8d9b176

Browse files
authored
Merge pull request #7653 from kenjis/refactor-extract-DefinedRouteCollector
refactor: extract DefinedRouteCollector
2 parents 6c09f35 + f5a2841 commit 8d9b176

File tree

4 files changed

+187
-49
lines changed

4 files changed

+187
-49
lines changed

system/Commands/Utilities/Routes.php

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use CodeIgniter\Commands\Utilities\Routes\AutoRouterImproved\AutoRouteCollector as AutoRouteCollectorImproved;
1919
use CodeIgniter\Commands\Utilities\Routes\FilterCollector;
2020
use CodeIgniter\Commands\Utilities\Routes\SampleURIGenerator;
21+
use CodeIgniter\Router\DefinedRouteCollector;
2122
use Config\Feature;
2223
use Config\Routing;
2324
use Config\Services;
@@ -115,29 +116,23 @@ public function run(array $params)
115116
$uriGenerator = new SampleURIGenerator();
116117
$filterCollector = new FilterCollector();
117118

118-
foreach ($methods as $method) {
119-
$routes = $collection->getRoutes($method);
119+
$definedRouteCollector = new DefinedRouteCollector($collection);
120120

121-
foreach ($routes as $route => $handler) {
122-
if (is_string($handler) || $handler instanceof Closure) {
123-
$sampleUri = $uriGenerator->get($route);
124-
$filters = $filterCollector->get($method, $sampleUri);
121+
foreach ($definedRouteCollector->collect() as $route) {
122+
if (is_string($route['handler']) || $route['handler'] instanceof Closure) {
123+
$sampleUri = $uriGenerator->get($route['route']);
124+
$filters = $filterCollector->get($route['method'], $sampleUri);
125125

126-
if ($handler instanceof Closure) {
127-
$handler = '(Closure)';
128-
}
129-
130-
$routeName = $collection->getRoutesOptions($route)['as'] ?? '»';
126+
$routeName = ($route['route'] === $route['name']) ? '»' : $route['name'];
131127

132-
$tbody[] = [
133-
strtoupper($method),
134-
$route,
135-
$routeName,
136-
$handler,
137-
implode(' ', array_map('class_basename', $filters['before'])),
138-
implode(' ', array_map('class_basename', $filters['after'])),
139-
];
140-
}
128+
$tbody[] = [
129+
strtoupper($route['method']),
130+
$route['route'],
131+
$routeName,
132+
$route['handler'],
133+
implode(' ', array_map('class_basename', $filters['before'])),
134+
implode(' ', array_map('class_basename', $filters['after'])),
135+
];
141136
}
142137
}
143138

system/Debug/Toolbar/Collectors/Routes.php

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace CodeIgniter\Debug\Toolbar\Collectors;
1313

14+
use CodeIgniter\Router\DefinedRouteCollector;
1415
use Config\Services;
1516
use ReflectionException;
1617
use ReflectionFunction;
@@ -55,9 +56,6 @@ public function display(): array
5556
$rawRoutes = Services::routes(true);
5657
$router = Services::router(null, null, true);
5758

58-
// Matched Route
59-
$route = $router->getMatchedRoute();
60-
6159
// Get our parameters
6260
// Closure routes
6361
if (is_callable($router->controllerName())) {
@@ -100,32 +98,18 @@ public function display(): array
10098
];
10199

102100
// Defined Routes
103-
$routes = [];
104-
$methods = [
105-
'get',
106-
'head',
107-
'post',
108-
'patch',
109-
'put',
110-
'delete',
111-
'options',
112-
'trace',
113-
'connect',
114-
'cli',
115-
];
116-
117-
foreach ($methods as $method) {
118-
$raw = $rawRoutes->getRoutes($method);
119-
120-
foreach ($raw as $route => $handler) {
121-
// filter for strings, as callbacks aren't displayable
122-
if (is_string($handler)) {
123-
$routes[] = [
124-
'method' => strtoupper($method),
125-
'route' => $route,
126-
'handler' => $handler,
127-
];
128-
}
101+
$routes = [];
102+
103+
$definedRouteCollector = new DefinedRouteCollector($rawRoutes);
104+
105+
foreach ($definedRouteCollector->collect() as $route) {
106+
// filter for strings, as callbacks aren't displayable
107+
if ($route['handler'] !== '(Closure)') {
108+
$routes[] = [
109+
'method' => strtoupper($route['method']),
110+
'route' => $route['route'],
111+
'handler' => $route['handler'],
112+
];
129113
}
130114
}
131115

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\Router;
13+
14+
use Closure;
15+
use Generator;
16+
17+
/**
18+
* Collect all defined routes for display.
19+
*/
20+
final class DefinedRouteCollector
21+
{
22+
private RouteCollection $routeCollection;
23+
24+
public function __construct(RouteCollection $routes)
25+
{
26+
$this->routeCollection = $routes;
27+
}
28+
29+
/**
30+
* @phpstan-return Generator<array{method: string, route: string, name: string, handler: string}>
31+
*/
32+
public function collect(): Generator
33+
{
34+
$methods = [
35+
'get',
36+
'head',
37+
'post',
38+
'patch',
39+
'put',
40+
'delete',
41+
'options',
42+
'trace',
43+
'connect',
44+
'cli',
45+
];
46+
47+
foreach ($methods as $method) {
48+
$routes = $this->routeCollection->getRoutes($method);
49+
50+
foreach ($routes as $route => $handler) {
51+
if (is_string($handler) || $handler instanceof Closure) {
52+
53+
if ($handler instanceof Closure) {
54+
$handler = '(Closure)';
55+
}
56+
57+
$routeName = $this->routeCollection->getRoutesOptions($route)['as'] ?? $route;
58+
59+
yield [
60+
'method' => $method,
61+
'route' => $route,
62+
'name' => $routeName,
63+
'handler' => $handler,
64+
];
65+
}
66+
}
67+
}
68+
}
69+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\Router;
13+
14+
use CodeIgniter\Config\Services;
15+
use CodeIgniter\Test\CIUnitTestCase;
16+
use Config\Modules;
17+
use Config\Routing;
18+
19+
/**
20+
* @internal
21+
*
22+
* @group Others
23+
*/
24+
final class DefinedRouteCollectorTest extends CIUnitTestCase
25+
{
26+
private function createRouteCollection(array $config = [], $moduleConfig = null): RouteCollection
27+
{
28+
$defaults = [
29+
'Config' => APPPATH . 'Config',
30+
'App' => APPPATH,
31+
];
32+
$config = array_merge($config, $defaults);
33+
34+
Services::autoloader()->addNamespace($config);
35+
36+
$loader = Services::locator();
37+
38+
if ($moduleConfig === null) {
39+
$moduleConfig = new Modules();
40+
$moduleConfig->enabled = false;
41+
}
42+
43+
return (new RouteCollection($loader, $moduleConfig, new Routing()))->setHTTPVerb('get');
44+
}
45+
46+
public function testCollect()
47+
{
48+
$routes = $this->createRouteCollection();
49+
$routes->get('journals', 'Blogs');
50+
$routes->get('product/(:num)', 'Catalog::productLookupByID/$1');
51+
$routes->get('feed', static fn () => 'A Closure route.');
52+
$routes->view('about', 'pages/about');
53+
54+
$collector = new DefinedRouteCollector($routes);
55+
56+
$definedRoutes = [];
57+
58+
foreach ($collector->collect() as $route) {
59+
$definedRoutes[] = $route;
60+
}
61+
62+
$expected = [
63+
[
64+
'method' => 'get',
65+
'route' => 'journals',
66+
'name' => 'journals',
67+
'handler' => '\App\Controllers\Blogs',
68+
],
69+
[
70+
'method' => 'get',
71+
'route' => 'product/([0-9]+)',
72+
'name' => 'product/([0-9]+)',
73+
'handler' => '\App\Controllers\Catalog::productLookupByID/$1',
74+
],
75+
[
76+
'method' => 'get',
77+
'route' => 'feed',
78+
'name' => 'feed',
79+
'handler' => '(Closure)',
80+
],
81+
[
82+
'method' => 'get',
83+
'route' => 'about',
84+
'name' => 'about',
85+
'handler' => '(Closure)',
86+
],
87+
];
88+
$this->assertSame($expected, $definedRoutes);
89+
}
90+
}

0 commit comments

Comments
 (0)