Skip to content

Commit b98305d

Browse files
committed
artisan route:list
1 parent ae7f9af commit b98305d

File tree

4 files changed

+292
-9
lines changed

4 files changed

+292
-9
lines changed

core/src/Console/RouteListCommand.php

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
<?php
2+
3+
namespace EvolutionCMS\Console;
4+
5+
use Closure;
6+
use Illuminate\Console\Command;
7+
use Illuminate\Routing\Route;
8+
use Illuminate\Routing\Router;
9+
use Illuminate\Support\Arr;
10+
use Illuminate\Support\Str;
11+
use Symfony\Component\Console\Input\InputOption;
12+
13+
class RouteListCommand extends Command
14+
{
15+
/**
16+
* The console command name.
17+
*
18+
* @var string
19+
*/
20+
protected $name = 'route:list';
21+
22+
/**
23+
* The console command description.
24+
*
25+
* @var string
26+
*/
27+
protected $description = 'List all registered routes';
28+
29+
/**
30+
* The router instance.
31+
*
32+
* @var \Illuminate\Routing\Router
33+
*/
34+
protected $router;
35+
36+
/**
37+
* The table headers for the command.
38+
*
39+
* @var string[]
40+
*/
41+
protected $headers = ['Domain', 'Method', 'URI', 'Name', 'Action', 'Middleware'];
42+
43+
/**
44+
* The columns to display when using the "compact" flag.
45+
*
46+
* @var string[]
47+
*/
48+
protected $compactColumns = ['method', 'uri', 'action'];
49+
50+
/**
51+
* Create a new route command instance.
52+
*
53+
* @param \Illuminate\Routing\Router $router
54+
* @return void
55+
*/
56+
public function __construct(Router $router)
57+
{
58+
parent::__construct();
59+
60+
$this->router = $router;
61+
}
62+
63+
/**
64+
* Execute the console command.
65+
*
66+
* @return void
67+
*/
68+
public function handle()
69+
{
70+
if (empty($this->router->getRoutes())) {
71+
return $this->error("Your application doesn't have any routes.");
72+
}
73+
74+
if (empty($routes = $this->getRoutes())) {
75+
return $this->error("Your application doesn't have any routes matching the given criteria.");
76+
}
77+
78+
$this->displayRoutes($routes);
79+
}
80+
81+
/**
82+
* Compile the routes into a displayable format.
83+
*
84+
* @return array
85+
*/
86+
protected function getRoutes()
87+
{
88+
$routes = collect($this->router->getRoutes())->map(function ($route) {
89+
return $this->getRouteInformation($route);
90+
})->filter()->all();
91+
92+
if ($sort = $this->option('sort')) {
93+
$routes = $this->sortRoutes($sort, $routes);
94+
}
95+
96+
if ($this->option('reverse')) {
97+
$routes = array_reverse($routes);
98+
}
99+
100+
return $this->pluckColumns($routes);
101+
}
102+
103+
/**
104+
* Get the route information for a given route.
105+
*
106+
* @param \Illuminate\Routing\Route $route
107+
* @return array
108+
*/
109+
protected function getRouteInformation(Route $route)
110+
{
111+
return $this->filterRoute([
112+
'domain' => $route->domain(),
113+
'method' => implode('|', $route->methods()),
114+
'uri' => $route->uri(),
115+
'name' => $route->getName(),
116+
'action' => ltrim($route->getActionName(), '\\'),
117+
'middleware' => $this->getMiddleware($route),
118+
]);
119+
}
120+
121+
/**
122+
* Sort the routes by a given element.
123+
*
124+
* @param string $sort
125+
* @param array $routes
126+
* @return array
127+
*/
128+
protected function sortRoutes($sort, array $routes)
129+
{
130+
return Arr::sort($routes, function ($route) use ($sort) {
131+
return $route[$sort];
132+
});
133+
}
134+
135+
/**
136+
* Remove unnecessary columns from the routes.
137+
*
138+
* @param array $routes
139+
* @return array
140+
*/
141+
protected function pluckColumns(array $routes)
142+
{
143+
return array_map(function ($route) {
144+
return Arr::only($route, $this->getColumns());
145+
}, $routes);
146+
}
147+
148+
/**
149+
* Display the route information on the console.
150+
*
151+
* @param array $routes
152+
* @return void
153+
*/
154+
protected function displayRoutes(array $routes)
155+
{
156+
if ($this->option('json')) {
157+
$this->line(json_encode(array_values($routes)));
158+
159+
return;
160+
}
161+
162+
$this->table($this->getHeaders(), $routes);
163+
}
164+
165+
/**
166+
* Get the middleware for the route.
167+
*
168+
* @param \Illuminate\Routing\Route $route
169+
* @return string
170+
*/
171+
protected function getMiddleware($route)
172+
{
173+
return collect($this->router->gatherRouteMiddleware($route))->map(function ($middleware) {
174+
return $middleware instanceof Closure ? 'Closure' : $middleware;
175+
})->implode("\n");
176+
}
177+
178+
/**
179+
* Filter the route by URI and / or name.
180+
*
181+
* @param array $route
182+
* @return array|null
183+
*/
184+
protected function filterRoute(array $route)
185+
{
186+
if (($this->option('name') && ! Str::contains($route['name'], $this->option('name'))) ||
187+
$this->option('path') && ! Str::contains($route['uri'], $this->option('path')) ||
188+
$this->option('method') && ! Str::contains($route['method'], strtoupper($this->option('method')))) {
189+
return;
190+
}
191+
192+
return $route;
193+
}
194+
195+
/**
196+
* Get the table headers for the visible columns.
197+
*
198+
* @return array
199+
*/
200+
protected function getHeaders()
201+
{
202+
return Arr::only($this->headers, array_keys($this->getColumns()));
203+
}
204+
205+
/**
206+
* Get the column names to show (lowercase table headers).
207+
*
208+
* @return array
209+
*/
210+
protected function getColumns()
211+
{
212+
$availableColumns = array_map('strtolower', $this->headers);
213+
214+
if ($this->option('compact')) {
215+
return array_intersect($availableColumns, $this->compactColumns);
216+
}
217+
218+
if ($columns = $this->option('columns')) {
219+
return array_intersect($availableColumns, $this->parseColumns($columns));
220+
}
221+
222+
return $availableColumns;
223+
}
224+
225+
/**
226+
* Parse the column list.
227+
*
228+
* @param array $columns
229+
* @return array
230+
*/
231+
protected function parseColumns(array $columns)
232+
{
233+
$results = [];
234+
235+
foreach ($columns as $i => $column) {
236+
if (Str::contains($column, ',')) {
237+
$results = array_merge($results, explode(',', $column));
238+
} else {
239+
$results[] = $column;
240+
}
241+
}
242+
243+
return array_map('strtolower', $results);
244+
}
245+
246+
/**
247+
* Get the console command options.
248+
*
249+
* @return array
250+
*/
251+
protected function getOptions()
252+
{
253+
return [
254+
['columns', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Columns to include in the route table'],
255+
['compact', 'c', InputOption::VALUE_NONE, 'Only show method, URI and action columns'],
256+
['json', null, InputOption::VALUE_NONE, 'Output the route list as JSON'],
257+
['method', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by method'],
258+
['name', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by name'],
259+
['path', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by path'],
260+
['reverse', 'r', InputOption::VALUE_NONE, 'Reverse the ordering of the routes'],
261+
['sort', null, InputOption::VALUE_OPTIONAL, 'The column (domain, method, uri, name, action, middleware) to sort by', 'uri'],
262+
];
263+
}
264+
}

core/src/Core.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use Illuminate\Routing\Pipeline;
1919
use Illuminate\Support\Arr;
2020
use Illuminate\Support\Facades\Cache;
21-
use Illuminate\Support\Facades\Route;
2221
use Illuminate\Support\Str;
2322
use PHPMailer\PHPMailer\Exception;
2423
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -2682,12 +2681,6 @@ public function processRoutes()
26822681
$this->instance(Request::class, $request);
26832682
$this->alias(Request::class, 'request');
26842683

2685-
if (is_readable(EVO_CORE_PATH . 'custom/routes.php')) {
2686-
include EVO_CORE_PATH . 'custom/routes.php';
2687-
}
2688-
2689-
Route::fallbackToParser();
2690-
26912684
$middleware = array_merge(
26922685
config('app.middleware', []),
26932686
config('middleware.global', [])

core/src/Providers/ArtisanServiceProvider.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class ArtisanServiceProvider extends ServiceProvider
6060
'UpdateTree' => 'command.updatetree',
6161
'SiteUpdate' => 'command.siteupdate',
6262
'Extras' => 'command.extras',
63+
'RouteList' => 'command.route.list',
6364
];
6465

6566
/**
@@ -415,6 +416,18 @@ protected function registerMigrateMakeCommand()
415416
});
416417
}
417418

419+
/**
420+
* Register the command.
421+
*
422+
* @return void
423+
*/
424+
protected function registerRouteListCommand()
425+
{
426+
$this->app->singleton('command.route.list', function ($app) {
427+
return new Console\RouteListCommand($app->router);
428+
});
429+
}
430+
418431
/**
419432
* Get the services provided by the provider.
420433
*
@@ -424,6 +437,4 @@ public function provides()
424437
{
425438
return array_merge(array_values($this->commands), array_values($this->devCommands));
426439
}
427-
428-
429440
}

core/src/Providers/RoutingServiceProvider.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,24 @@
44

55
use EvolutionCMS\Extensions\Router;
66
use Illuminate\Routing\RoutingServiceProvider as IlluminateRoutingServiceProvider;
7+
use Illuminate\Support\Facades\Route;
78

89
class RoutingServiceProvider extends IlluminateRoutingServiceProvider
910
{
11+
/**
12+
* Register the service provider and routes
13+
*/
14+
public function register()
15+
{
16+
parent::register();
17+
18+
if (is_readable(EVO_CORE_PATH . 'custom/routes.php')) {
19+
include EVO_CORE_PATH . 'custom/routes.php';
20+
}
21+
22+
Route::fallbackToParser();
23+
}
24+
1025
/**
1126
* We need to overload provider to register our router
1227
* to use custom route methods

0 commit comments

Comments
 (0)