Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CHANGELOG
* Deprecate making `cache.app` adapter taggable, use the `cache.app.taggable` adapter instead
* Enable `json_decode_detailed_errors` in the default serializer context in debug mode by default when `seld/jsonlint` is installed
* Register `Symfony\Component\Serializer\NameConverter\SnakeCaseToCamelCaseNameConverter` as a service named `serializer.name_converter.snake_case_to_camel_case` if available
* Add flag to sort `debug:router` output in alphabetical order, according to column name

7.1
---
Expand Down
61 changes: 61 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ protected function configure(): void
new InputOption('show-aliases', null, InputOption::VALUE_NONE, 'Show aliases in overview'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw route(s)'),
new InputOption('sort', null, InputOption::VALUE_REQUIRED, 'Sort by column name'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the list of possible values as last parameter, for bash completion.

Suggested change
new InputOption('sort', null, InputOption::VALUE_REQUIRED, 'Sort by column name'),
new InputOption('sort', null, InputOption::VALUE_REQUIRED, 'Sort by column name', null, ['name', 'method', 'scheme', 'host', 'path']),

])
->setHelp(<<<'EOF'
The <info>%command.name%</info> displays the configured routes:
Expand Down Expand Up @@ -117,9 +118,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
'container' => $container,
]);
} else {
$sortBy = $input->getOption('sort');
if ($sortBy) {
$routes = $this->sortBy($routes, \strtolower($sortBy));
}
$helper->describe($io, $routes, [
'format' => $input->getOption('format'),
'raw_text' => $input->getOption('raw'),
'sort' => $input->getOption('sort'),
'show_controllers' => $input->getOption('show-controllers'),
'show_aliases' => $input->getOption('show-aliases'),
'output' => $io,
Expand Down Expand Up @@ -172,4 +178,59 @@ private function getAvailableFormatOptions(): array
{
return (new DescriptorHelper())->getFormats();
}

private function sortBy(RouteCollection $routeCollection, string $column): RouteCollection
{
$routesArray = $routeCollection->all();
$sortedRoutes = new RouteCollection();

if ('name' === $column) {
\ksort($routesArray);
foreach ($routesArray as $name => $route) {
$sortedRoutes->add($name, $route);
$sortedRoutes->addAlias($route->getDefault('_controller'), $name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get why you add an alias to the controller for every routes.

Not all routes have a controller. Example: _logout_main.

Symfony\Component\Routing\RouteCollection::addAlias(): Argument #1 ($name) must be of type string, null given, called in src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php on line 192

}

return $sortedRoutes;
}

$helperArray = [];

if ('method' === $column) {
foreach ($routesArray as $name => $route) {
$methods = empty($route->getMethods()) ? 'ANY' : \implode('|', $route->getMethods());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the logic for formatting a list of methods is in the descriptors, it would make sense to move the sorting method into Symfony\Bundle\FrameworkBundle\Console\Descriptor\Descriptor. The method describeRouteCollection has an $options array that could be used to pass the desired sort key.
That would make unit testing a lot easier.

$helperArray[$methods][$name] = $route;
}
}

if ('scheme' === $column) {
foreach ($routesArray as $name => $route) {
$scheme = empty($route->getSchemes()) ? 'ANY' : \implode('|', $route->getSchemes());
$helperArray[$scheme][$name] = $route;
}
}

if ('host' === $column) {
foreach ($routesArray as $name => $route) {
$helperArray[$route->getHost()][$name] = $route;

}
}

if ('path' === $column) {
foreach ($routesArray as $name => $route) {
$helperArray[$route->getPath()][$name] = $route;
}
}

\ksort($helperArray);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of creating an array and using ksort, you can use usort with a callback that compare the sort key of routes 2-by-2. It think there would be less array variables involved.

foreach ($helperArray as $array) {
foreach ($array as $name => $route) {
$sortedRoutes->add($name, $route);
$sortedRoutes->addAlias($route->getDefault('_controller'), $name);
}
}

return $sortedRoutes;
}
}