Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
70 / 70
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Routes
100.00% covered (success)
100.00%
70 / 70
100.00% covered (success)
100.00%
4 / 4
21
100.00% covered (success)
100.00%
1 / 1
 run
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
7
 showCollectionsSet
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 writeHeader
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 collectData
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
1 / 1
9
1<?php declare(strict_types=1);
2/*
3 * This file is part of Aplus Framework Dev Commands Library.
4 *
5 * (c) Natan Felles <natanfelles@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10namespace Framework\CLI\Commands;
11
12use Framework\CLI\CLI;
13use Framework\CLI\Command;
14use Framework\MVC\App;
15
16/**
17 * Class Routes.
18 *
19 * @package dev-commands
20 */
21class Routes extends Command
22{
23    protected string $name = 'routes';
24    protected string $description = 'Shows routes list.';
25    protected string $usage = 'routes [options]';
26    protected string $routerInstance = 'default';
27
28    public function run() : void
29    {
30        $instance = $this->console->getArgument(0);
31        if ($instance !== null) {
32            $this->routerInstance = $instance;
33        }
34        CLI::write(
35            CLI::style('Router Instance:', CLI::FG_YELLOW, formats: [CLI::FM_BOLD])
36            . ' ' . $this->routerInstance
37        );
38        CLI::newLine();
39        $data = $this->collectData();
40        $count = \count($data);
41        $this->showCollectionsSet($count);
42        foreach ($data as $index => $collection) {
43            CLI::write(CLI::style('Route Collection ' . ($index + 1), CLI::FG_YELLOW, formats: [CLI::FM_BOLD]));
44            $this->writeHeader('Origin', $collection['origin']);
45            if (isset($collection['name'])) {
46                $this->writeHeader('Name', $collection['name']);
47            }
48            $this->writeHeader('Routes Count', (string) $collection['count']);
49            if (isset($collection['notFound'])) {
50                $this->writeHeader('Route Not Found', $collection['notFound']);
51            }
52            if ($collection['routes']) {
53                CLI::table(
54                    $collection['routes'],
55                    ['#', 'Method', 'Path', 'Action', 'Name', 'Has Options']
56                );
57            }
58            if ($index + 1 < $count) {
59                CLI::newLine();
60            }
61        }
62    }
63
64    protected function showCollectionsSet(int $count) : void
65    {
66        if ($count === 0) {
67            CLI::write('No Route Collection has been set.', CLI::FG_RED);
68            return;
69        }
70        $plural = $count > 1;
71        CLI::write(
72            'There ' . ($plural ? 'are' : 'is') . ' ' . $count
73            . ' Route Collection' . ($plural ? 's' : '') . ' set:',
74            CLI::FG_GREEN
75        );
76        CLI::newLine();
77    }
78
79    protected function writeHeader(string $field, string $value) : void
80    {
81        CLI::write(CLI::style($field . ':', formats: [CLI::FM_BOLD]) . ' ' . $value);
82    }
83
84    /**
85     * @return array<int,mixed>
86     */
87    protected function collectData() : array
88    {
89        $data = [];
90        foreach (App::router($this->routerInstance)->getCollections() as $index => $collection) {
91            $data[$index]['origin'] = $collection->origin;
92            $data[$index]['name'] = $collection->name;
93            $data[$index]['count'] = $collection->count();
94            $notFound = null;
95            if (isset($collection->notFoundAction)) {
96                $notFound = \is_string($collection->notFoundAction) // @phpstan-ignore-line
97                    ? $collection->notFoundAction // @phpstan-ignore-line
98                    : 'Closure';
99            }
100            $data[$index]['notFound'] = $notFound;
101            $data[$index]['routes'] = [];
102            foreach ($collection->routes as $method => $routes) {
103                foreach ($routes as $route) {
104                    $action = $route->getAction();
105                    $action = \is_string($action) ? $action : 'Closure';
106                    $data[$index]['routes'][] = [
107                        'method' => $method,
108                        'path' => $route->getPath(),
109                        'action' => $action,
110                        'name' => $route->getName(),
111                        'hasOptions' => $route->getOptions() ? 'Yes' : 'No',
112                    ];
113                }
114                \usort($data[$index]['routes'], static function ($route1, $route2) {
115                    return \strcmp($route1['method'], $route2['method']);
116                });
117            }
118            $count = 0;
119            foreach ($data[$index]['routes'] as &$route) {
120                $route = \array_reverse($route);
121                $route['#'] = ++$count;
122                $route = \array_reverse($route);
123            }
124            unset($route);
125        }
126        return $data;
127    }
128}