8000 feature #50084 [Routing] Add FQCN and FQCN::method aliases when appli… · symfony/routing@cb08b9a · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit cb08b9a

Browse files
committed
feature #50084 [Routing] Add FQCN and FQCN::method aliases when applicable (fancyweb)
This PR was merged into the 6.4 branch. Discussion ---------- [Routing] Add FQCN and FQCN::method aliases when applicable | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | symfony/symfony#49981 | License | MIT | Doc PR | - See symfony/symfony#49981, I think it's a great idea 😃 * We add an FQCN alias only if the target class has an `__invoke` method that adds a route AND if the target class added 1 route exactly. * We add a FQCN::method alias for every method that defines only one route. Commits ------- 9fa5bae407 [Routing] Add FQCN and FQCN::method aliases when applicable
2 parents 1342e2f + d24a022 commit cb08b9a

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Add FQCN and FQCN::method aliases for routes loaded from attributes/annotations when applicable
8+
49
6.2
510
---
611

Loader/AnnotationClassLoader.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,36 @@ public function load(mixed $class, string $type = null): RouteCollection
125125
return $collection;
126126
}
127127

128+
$fqcnAlias = false;
128129
foreach ($class->getMethods() as $method) {
129130
$this->defaultRouteIndex = 0;
131+
$routeNamesBefore = array_keys($collection->all());
130132
foreach ($this->getAnnotations($method) as $annot) {
131133
$this->addRoute($collection, $annot, $globals, $class, $method);
134+
if ('__invoke' === $method->name) {
135+
$fqcnAlias = true;
136+
}
137+
}
138+
139+
if (1 === $collection->count() - \count($routeNamesBefore)) {
140+
$newRouteName = current(array_diff(array_keys($collection->all()), $routeNamesBefore));
141+
$collection->addAlias(sprintf('%s::%s', $class->name, $method->name), $newRouteName);
132142
}
133143
}
134144

135145
if (0 === $collection->count() && $class->hasMethod('__invoke')) {
136146
$globals = $this->resetGlobals();
137147
foreach ($this->getAnnotations($class) as $annot) {
138148
$this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
149+
$fqcnAlias = true;
139150
}
140151
}
141152

153+
if ($fqcnAlias && 1 === $collection->count()) {
154+
$collection->addAlias($class->name, $invokeRouteName = key($collection->all()));
155+
$collection->addAlias(sprintf('%s::__invoke', $class->name), $invokeRouteName);
156+
}
157+
142158
return $collection;
143159
}
144160

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
4+
5+
use Symfony\Component\Routing\Annotation\Route;
6+
7+
class InvokableMethodController
8+
{
9+
/**
10+
* @Route("/here", name="lol", methods={"GET", "POST"}, schemes={"https"})
11+
*/
12+
public function __invoke()
13+
{
14+
}
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures;
4+
5+
use Symfony\Component\Routing\Annotation\Route;
6+
7+
class InvokableMethodController
8+
{
9+
#[Route(path: '/here', name: 'lol', methods: ["GET", "POST"], schemes: ['https'])]
10+
public function __invoke()
11+
{
12+
}
13+
}

Tests/Loader/AnnotationClassLoaderTestCase.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Routing\Tests\Loader;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Routing\Alias;
1516
use Symfony\Component\Routing\Loader\AnnotationClassLoader;
1617
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\AbstractClassController;
1718

@@ -55,6 +56,7 @@ public function testSimplePathRoute()
5556
$routes = $this->loader->load($this->getNamespace().'\ActionPathController');
5657
$this->assertCount(1, $routes);
5758
$this->assertEquals('/path', $routes->get('action')->getPath());
59+
$this->assertEquals(new Alias('action'), $routes->getAlias($this->getNamespace().'\ActionPathController::action'));
5860
}
5961

6062
public function testRequirementsWithoutPlaceholderName()
@@ -72,6 +74,19 @@ public function testInvokableControllerLoader()
7274
$this->assertEquals('/here', $routes->get('lol')->getPath());
7375
$this->assertEquals(['GET', 'POST'], $routes->get('lol')->getMethods());
7476
$this->assertEquals(['https'], $routes->get('lol')->getSchemes());
77+
$this->assertEquals(new Alias('lol'), $routes->getAlias($this->getNamespace().'\InvokableController'));
78+
$this->assertEquals(new Alias('lol'), $routes->getAlias($this->getNamespace().'\InvokableController::__invoke'));
79+
}
80+
81+
public function testInvokableMethodControllerLoader()
82+
{
83+
$routes = $this->loader->load($this->getNamespace().'\InvokableMethodController');
84+
$this->assertCount(1, $routes);
85+
$this->assertEquals('/here', $routes->get('lol')->getPath());
86+
$this->assertEquals(['GET', 'POST'], $routes->get('lol')->getMethods());
87+
$this->assertEquals(['https'], $routes->get('lol')->getSchemes());
88+
$this->assertEquals(new Alias('lol'), $routes->getAlias($this->getNamespace().'\InvokableMethodController'));
89+
$this->assertEquals(new Alias('lol'), $routes->getAlias($this->getNamespace().'\InvokableMethodController::__invoke'));
7590
}
7691

7792
public function testInvokableLocalizedControllerLoading()
@@ -119,6 +134,8 @@ public function testMethodActionControllers()
119134
$this->assertSame(['put', 'post'], array_keys($routes->all()));
120135
$this->assertEquals('/the/path', $routes->get('put')->getPath());
121136
$this->assertEquals('/the/path', $routes->get('post')->getPath());
137+
$this->assertEquals(new Alias('post'), $routes->getAlias($this->getNamespace().'\MethodActionControllers::post'));
138+
$this->assertEquals(new Alias('put'), $routes->getAlias($this->getNamespace().'\MethodActionControllers::put'));
122139
}
123140

124141
public function testInvokableClassRouteLoadWithMethodAnnotation()

0 commit comments

Comments
 (0)
0