Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6c0058a

Browse filesBrowse files
feature #59909 [FrameworkBundle] Add --method option to debug:router command (santysisi)
This PR was merged into the 7.3 branch. Discussion ---------- [FrameworkBundle] Add `--method` option to `debug:router` command | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | Feature #59906 | License | MIT ### Description I have added a new `InputOption` named `method` to the `debug:router` command. This option allows developers to filter the displayed routes by HTTP method (GET, POST, PUT, DELETE, etc.) when running the command. This improvement makes it easier and more efficient to debug routes, especially in large applications. It also aligns the `debug:router` command with the `router:match` command, which already includes a similar option for filtering by HTTP method. ### Changes Made * Added the --method option to the debug:router command. * Routes can now be filtered based on the HTTP method used (GET, POST, PUT, DELETE, etc.). * This enhances debugging capabilities and streamlines the process of working with specific route methods. ### Example Before adding the new InputOption: `php bin/console debug:router` ![Image](https://github.com/user-attachments/assets/c8e4fe51-0ba0-46dc-8369-2bc156873b2d) After adding the new InputOption: `php bin/console debug:router --method=GET` ![Image](https://github.com/user-attachments/assets/5edcee2f-8761-4af9-919a-a741d6024e51) Before adding the new InputOption with the name argument `php bin/console debug:router app_foo` ![Image](https://github.com/user-attachments/assets/16470489-acba-49c2-8fe0-fd856702d052) After adding the method InputOption with the name argument: php bin/console debug:router app_foo --method=DELETE ![Image](https://github.com/user-attachments/assets/419b739f-794b-4427-9c8d-64babaaa4245) Commits ------- 6a98d49 Add 'method' option to debug:router command to filter routes by HTTP method
2 parents 0c11d82 + 6a98d49 commit 6c0058a
Copy full SHA for 6c0058a

13 files changed

+248
-4
lines changed

‎src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ CHANGELOG
1313
* Add `framework.validation.disable_translation` option
1414
* Add support for signal plain name in the `messenger.stop_worker_on_signals` configuration
1515
* Deprecate the `framework.validation.cache` option
16+
* Add `--method` option to the `debug:router` command
1617

1718
7.2
1819
---

‎src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php
+7-3Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ protected function configure(): void
5555
new InputOption('show-aliases', null, InputOption::VALUE_NONE, 'Show aliases in overview'),
5656
new InputOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'),
5757
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw route(s)'),
58+
new InputOption('method', null, InputOption::VALUE_REQUIRED, 'Filter by HTTP method', '', ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']),
5859
])
5960
->setHelp(<<<'EOF'
6061
The <info>%command.name%</info> displays the configured routes:
@@ -76,6 +77,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7677
{
7778
$io = new SymfonyStyle($input, $output);
7879
$name = $input->getArgument('name');
80+
$method = strtoupper($input->getOption('method'));
7981
$helper = new DescriptorHelper($this->fileLinkFormatter);
8082
$routes = $this->router->getRouteCollection();
8183
$container = null;
@@ -85,7 +87,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8587

8688
if ($name) {
8789
$route = $routes->get($name);
88-
$matchingRoutes = $this->findRouteNameContaining($name, $routes);
90+
$matchingRoutes = $this->findRouteNameContaining($name, $routes, $method);
8991

9092
if (!$input->isInteractive() && !$route && \count($matchingRoutes) > 1) {
9193
$helper->describe($io, $this->findRouteContaining($name, $routes), [
@@ -94,6 +96,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9496
'show_controllers' => $input->getOption('show-controllers'),
9597
'show_aliases' => $input->getOption('show-aliases'),
9698
'output' => $io,
99+
'method' => $method,
97100
]);
98101

99102
return 0;
@@ -124,17 +127,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int
124127
'show_aliases' => $input->getOption('show-aliases'),
125128
'output' => $io,
126129
'container' => $container,
130+
'method' => $method,
127131
]);
128132
}
129133

130134
return 0;
131135
}
132136

133-
private function findRouteNameContaining(string $name, RouteCollection $routes): array
137+
private function findRouteNameContaining(string $name, RouteCollection $routes, string $method): array
134138
{
135139
$foundRoutesNames = [];
136140
foreach ($routes as $routeName => $route) {
137-
if (false !== stripos($routeName, $name)) {
141+
if (false !== stripos($routeName, $name) && (!$method || !$route->getMethods() || \in_array($method, $route->getMethods(), true))) {
138142
$foundRoutesNames[] = $routeName;
139143
}
140144
}

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php
+17-1Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function describe(OutputInterface $output, mixed $object, array $options
4949
}
5050

5151
match (true) {
52-
$object instanceof RouteCollection => $this->describeRouteCollection($object, $options),
52+
$object instanceof RouteCollection => $this->describeRouteCollection($this->filterRoutesByHttpMethod($object, $options['method'] ?? ''), $options),
5353
$object instanceof Route => $this->describeRoute($object, $options),
5454
$object instanceof ParameterBag => $this->describeContainerParameters($object, $options),
5555
$object instanceof ContainerBuilder && !empty($options['env-vars']) => $this->describeContainerEnvVars($this->getContainerEnvVars($object), $options),
@@ -360,4 +360,20 @@ protected function getServiceEdges(ContainerBuilder $container, string $serviceI
360360
return [];
361361
}
362362
}
363+
364+
private function filterRoutesByHttpMethod(RouteCollection $routes, string $method): RouteCollection
365+
{
366+
if (!$method) {
367+
return $routes;
368+
}
369+
$filteredRoutes = clone $routes;
370+
371+
foreach ($filteredRoutes as $routeName => $route) {
372+
if ($route->getMethods() && !\in_array($method, $route->getMethods(), true)) {
373+
$filteredRoutes->remove($routeName);
374+
}
375+
}
376+
377+
return $filteredRoutes;
378+
}
363379
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTestCase.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTestCase.php
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ public static function getDescribeRouteCollectionTestData(): array
5050
return static::getDescriptionTestData(ObjectsProvider::getRouteCollections());
5151
}
5252

53+
/** @dataProvider getDescribeRouteCollectionWithHttpMethodFilterTestData */
54+
public function testDescribeRouteCollectionWithHttpMethodFilter(string $httpMethod, RouteCollection $routes, $expectedDescription)
55+
{
56+
$this->assertDescription($expectedDescription, $routes, ['method' => $httpMethod]);
57+
}
58+
59+
public static function getDescribeRouteCollectionWithHttpMethodFilterTestData(): iterable
60+
{
61+
foreach (ObjectsProvider::getRouteCollectionsByHttpMethod() as $httpMethod => $routeCollection) {
62+
foreach (static::getDescriptionTestData($routeCollection) as $testData) {
63+
yield [$httpMethod, ...$testData];
64+
}
65+
}
66+
}
67+
5368
/** @dataProvider getDescribeRouteTestData */
5469
public function testDescribeRoute(Route $route, $expectedDescription)
5570
{
@@ -273,6 +288,7 @@ private function assertDescription($expectedDescription, $describedObject, array
273288
$options['is_debug'] = false;
274289
$options['raw_output'] = true;
275290
$options['raw_text'] = true;
291+
$options['method'] ??= null;
276292
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
277293

278294
if ('txt' === $this->getFormat()) {

‎src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php
+32Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,38 @@ public static function getRouteCollections()
3737
return ['route_collection_1' => $collection1];
3838
}
3939

40+
public static function getRouteCollectionsByHttpMethod(): array
41+
{
42+
$collection = new RouteCollection();
43+
foreach (self::getRoutes() as $name => $route) {
44+
$collection->add($name, $route);
45+
}
46+
47+
// Clone the original collection and add a route without any specific method restrictions
48+
$collectionWithRouteWithoutMethodRestriction = clone $collection;
49+
$collectionWithRouteWithoutMethodRestriction->add(
50+
'route_3',
51+
new RouteStub(
52+
'/other/route',
53+
[],
54+
[],
55+
['opt1' => 'val1', 'opt2' => 'val2'],
56+
'localhost',
57+
['http', 'https'],
58+
[],
59+
)
60+
);
61+
62+
return [
63+
'GET' => [
64+
'route_collection_2' => $collectionWithRouteWithoutMethodRestriction,
65+
],
66+
'PUT' => [
67+
'route_collection_3' => $collection,
68+
],
69+
];
70+
}
71+
4072
public static function getRoutes()
4173
{
4274
return [
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"route_1": {
3+
"path": "\/hello\/{name}",
4+
"pathRegex": "#PATH_REGEX#",
5+
"host": "localhost",
6+
"hostRegex": "#HOST_REGEX#",
7+
"scheme": "http|https",
8+
"method": "GET|HEAD",
9+
"class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub",
10+
"defaults": {
11+
"name": "Joseph"
12+
},
13+
"requirements": {
14+
"name": "[a-z]+"
15+
},
16+
"options": {
17+
"compiler_class": "Symfony\\Component\\Routing\\RouteCompiler",
18+
"opt1": "val1",
19+
"opt2": "val2"
20+
}
21+
},
22+
"route_3": {
23+
"path": "\/other\/route",
24+
"pathRegex": "#PATH_REGEX#",
25+
"host": "localhost",
26+
"hostRegex": "#HOST_REGEX#",
27+
"scheme": "http|https",
28+
"method": "ANY",
29+
"class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub",
30+
"defaults": [],
31+
"requirements": "NO CUSTOM",
32+
"options": {
33+
"compiler_class": "Symfony\\Component\\Routing\\RouteCompiler",
34+
"opt1": "val1",
35+
"opt2": "val2"
36+
}
37+
}
38+
}
+37Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
route_1
2+
-------
3+
4+
- Path: /hello/{name}
5+
- Path Regex: #PATH_REGEX#
6+
- Host: localhost
7+
- Host Regex: #HOST_REGEX#
8+
- Scheme: http|https
9+
- Method: GET|HEAD
10+
- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub
11+
- Defaults:
12+
- `name`: Joseph
13+
- Requirements:
14+
- `name`: [a-z]+
15+
- Options:
16+
- `compiler_class`: Symfony\Component\Routing\RouteCompiler
17+
- `opt1`: val1
18+
- `opt2`: val2
19+
20+
21+
route_3
22+
-------
23+
24+
- Path: /other/route
25+
- Path Regex: #PATH_REGEX#
26+
- Host: localhost
27+
- Host Regex: #HOST_REGEX#
28+
- Scheme: http|https
29+
- Method: ANY
30+
- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub
31+
- Defaults: NONE
32+
- Requirements: NO CUSTOM
33+
- Options:
34+
- `compiler_class`: Symfony\Component\Routing\RouteCompiler
35+
- `opt1`: val1
36+
- `opt2`: val2
37+
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--------- ---------- ------------ ----------- ---------------
2+
 Name   Method   Scheme   Host   Path 
3+
--------- ---------- ------------ ----------- ---------------
4+
route_1 GET|HEAD http|https localhost /hello/{name}
5+
route_3 ANY http|https localhost /other/route
6+
--------- ---------- ------------ ----------- ---------------
7+
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<routes>
3+
<route name="route_1" class="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub">
4+
<path regex="#PATH_REGEX#">/hello/{name}</path>
5+
<host regex="#HOST_REGEX#">localhost</host>
6+
<scheme>http</scheme>
7+
<scheme>https</scheme>
8+
<method>GET</method>
9+
<method>HEAD</method>
10+
<defaults>
11+
<default key="name">Joseph</default>
12+
</defaults>
13+
<requirements>
14+
<requirement key="name">[a-z]+</requirement>
15+
</requirements>
16+
<options>
17+
<option key="compiler_class">Symfony\Component\Routing\RouteCompiler</option>
18+
<option key="opt1">val1</option>
19+
<option key="opt2">val2</option>
20+
</options>
21+
</route>
22+
<route name="route_3" class="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub">
23+
<path regex="#PATH_REGEX#">/other/route</path>
24+
<host regex="#HOST_REGEX#">localhost</host>
25+
<scheme>http</scheme>
26+
<scheme>https</scheme>
27+
<options>
28+
<option key="compiler_class">Symfony\Component\Routing\RouteCompiler</option>
29+
<option key="opt1">val1</option>
30+
<option key="opt2">val2</option>
31+
</options>
32+
</route>
33+
</routes>
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"route_2": {
3+
"path": "\/name\/add",
4+
"pathRegex": "#PATH_REGEX#",
5+
"host": "localhost",
6+
"hostRegex": "#HOST_REGEX#",
7+
"scheme": "http|https",
8+
"method": "PUT|POST",
9+
"class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub",
10+
"defaults": [],
11+
"requirements": "NO CUSTOM",
12+
"options": {
13+
"compiler_class": "Symfony\\Component\\Routing\\RouteCompiler",
14+
"opt1": "val1",
15+
"opt2": "val2"
16+
},
17+
"condition": "context.getMethod() in ['GET', 'HEAD', 'POST']"
18+
}
19+
}
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
route_2
2+
-------
3+
4+
- Path: /name/add
5+
- Path Regex: #PATH_REGEX#
6+
- Host: localhost
7+
- Host Regex: #HOST_REGEX#
8+
- Scheme: http|https
9+
- Method: PUT|POST
10+
- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub
11+
- Defaults: NONE
12+
- Requirements: NO CUSTOM
13+
- Options:
14+
- `compiler_class`: Symfony\Component\Routing\RouteCompiler
15+
- `opt1`: val1
16+
- `opt2`: val2
17+
- Condition: context.getMethod() in ['GET', 'HEAD', 'POST']
18+
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
--------- ---------- ------------ ----------- -----------
2+
 Name   Method   Scheme   Host   Path 
3+
--------- ---------- ------------ ----------- -----------
4+
route_2 PUT|POST http|https localhost /name/add
5+
--------- ---------- ------------ ----------- -----------
6+
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<routes>
3+
<route name="route_2" class="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub">
4+
<path regex="#PATH_REGEX#">/name/add</path>
5+
<host regex="#HOST_REGEX#">localhost</host>
6+
<scheme>http</scheme>
7+
<scheme>https</scheme>
8+
<method>PUT</method>
9+
<method>POST</method>
10+
<options>
11+
<option key="compiler_class">Symfony\Component\Routing\RouteCompiler</option>
12+
<option key="opt1">val1</option>
13+
<option key="opt2">val2</option>
14+
</options>
15+
<condition>context.getMethod() in ['GET', 'HEAD', 'POST']</condition>
16+
</route>
17+
</routes>

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.