-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Routing] Add support for aliasing routes #38464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@stof Still WIP but I've made some changes to make deprecated aliases a thing as pointed out in #38389 (comment). WDYT ? |
Ready for review finally. |
src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Routing/Generator/Dumper/CompiledUrlGeneratorDumper.php
Show resolved
Hide resolved
src/Symfony/Component/Routing/Loader/Configurator/AliasConfigurator.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php
Outdated
Show resolved
Hide resolved
@jderusse I adressed all your comments except the ones where I left a comment indicating otherwise. |
Hope this gets merged! |
I don't promise anything but I'll try to come back to this in the next weeks. |
AppVeyor's failure is unrelated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for moving this PR.
last few comment for my side.
src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php
Outdated
Show resolved
Hide resolved
final public function alias(string $name, string $alias): AliasConfigurator | ||
{ | ||
return new AliasConfigurator( | ||
$this->collection->addAlias($name, $alias) | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use the collection
to build AliasConfigurator
, I wonder if this method should'nt be part of CollectionConfigurator
instead of RoutingConfigurator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, from DX point of view, I would expect to be able to define alias directly from a RoutingConfigurator
instance, to match DI's side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks really nice. Here are some nitpicking.
|
||
use Symfony\Component\Routing\Exception\InvalidArgumentException; | ||
|
||
final class Alias |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should remove the final
here
$this->id = $id; | ||
} | ||
|
||
public function redirect(string $id): self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
withId
could be less confusing, this doesn't redirect in the http meaning
|
||
/** | ||
* Whether this alias is deprecated, that means it should not be referenced | ||
* anymore. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be merged with the previous line
$this->deprecation = [ | ||
'package' => $package, | ||
'version' => $version, | ||
'message' => $message ?: 'The "%alias%" route alias is deprecated. You should stop using it, as it will be removed in the future.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
%alias_id%
?
|
||
public function isDeprecated(): bool | ||
{ | ||
return [] !== $this->deprecation; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return (bool) $this->deprecation;
if we keep taking inspiration from Alias in DI
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; | ||
use Symfony\Component\Routing\Alias; | ||
|
||
final class AliasConfigurator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should not be final
@@ -60,6 +60,13 @@ final public function collection(string $name = ''): CollectionConfigurator | |||
return new CollectionConfigurator($this->collection, $name); | |||
} | |||
|
|||
final public function alias(string $name, string $alias): AliasConfigurator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be on AddTrait
?
/** | ||
* @param array $config A resource config | ||
* @param string $name The config key | ||
* @param string $path The loaded file path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all 3 above lines could be removed imho
* @throws \InvalidArgumentException If one of the provided config keys is not supported, | ||
* something is missing or the combination is nonsense | ||
*/ | ||
private function validateAlias($config, string $name, string $path): void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
array $config
} | ||
$this->generator = new $this->options['generator_class']($routes, $this->context, $this->logger, $this->defaultLocale); | ||
$this->generator = new $this->options['generator_class']( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please keep this on one line
|
||
$deprecations[] = $deprecation; | ||
|
||
trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is indeed wrong. Dumping the URL generator should not trigger a deprecation. It should only be triggered when generating the url.
The only compile-time deprecation should be when a non-deprecated alias targets a deprecated one.
@nicolas-grekas @stof I believe I adressed all your comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last round of review
@@ -116,6 +126,10 @@ public function all() | |||
*/ | |||
public function get(string $name) | |||
{ | |||
while ($this->hasAlias($name)) { | |||
$name = $this->getAlias($name)->getId(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this loop detect circular refs + trigger a deprecation?
why do we need this logic btw? don't we always resolve the aliases before calling the method?
alternatively, shouldn't we move the logic in CompiledUrlGeneratorDumper and UrlGenerator here?
@@ -42,6 +43,13 @@ public function add(string $name, $path): RouteConfigurator | |||
return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes); | |||
} | |||
|
|||
final public function alias(string $name, string $alias): AliasConfigurator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for final
@@ -42,6 +43,13 @@ public function add(string $name, $path): RouteConfigurator | |||
return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes); | |||
} | |||
|
|||
final public function alias(string $name, string $alias): AliasConfigurator | |||
{ | |||
return new AliasConfigurator( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be on one line
@@ -50,7 +50,11 @@ public function generate(string $name, array $parameters = [], int $referenceTyp | |||
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name)); | |||
} | |||
|
|||
[$variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes] = $this->compiledRoutes[$name]; | |||
[$variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes, $deprecations] = $this->compiledRoutes[$name]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be safer to add + [6 => []]
at the end of the expression in case the compiled routes come from a previous version of Routing. This might help with upgrading.
@nicolas-grekas all done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really cool :)
@@ -118,6 +129,24 @@ public function all() | |||
*/ | |||
public function get(string $name) | |||
{ | |||
$visited = []; | |||
while (null !== $alias = $this->aliases[$name] ?? null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved this loop from UrlGenerator to RouteCollection
return $this->aliases; | ||
} | ||
|
||
public function getAlias(string $name): ?Alias |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed hasAlias()
and made getAlias()
nullable instead, for consistency with get()
Thank you @Lctrs. |
Thank you for taking care of the last polishing @nicolas-grekas |
Thank you for the great feature |
Continuation of #38389