Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

[Routing] Redirection from route configuration#25145

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed

Conversation

sroze
Copy link
Contributor

@srozesroze commentedNov 24, 2017
edited
Loading

QA
Branch?master
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets#24640
LicenseMIT
Doc PRø

Following@javiereguiluz's proposal (#24640), this PR allows developers to configure the redirection directly in the routing configuration.

app_entrypoint:path:/redirect_to:/homepage

yceruto and sstok reacted with thumbs up emojiro0NL reacted with hooray emoji
@nicolas-grekas
Copy link
Member

PHP-based routing configuration also needs to be patched.

/**
* Common parsing logic between route loaders.
*
* @author Samuel Roze <samuel.roze@gmail.com>

Choose a reason for hiding this comment

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

@internal also

@sroze
Copy link
ContributorAuthor

@nicolas-grekas we did not add thecontroller feature on the PHP loader, so I guessed this was on purpose. I'm not really sure it's a lot valuable to do so.. what do you think?

@nicolas-grekas
Copy link
Member

$defaults['_controller'] = 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction';
$defaults['path'] = $redirect;
} else {
$defaults['_controller'] = 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction';
Copy link
Member

@nicolas-grekasnicolas-grekasNov 24, 2017
edited
Loading

Choose a reason for hiding this comment

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

But there is a big glitch here: this is in theRouting namespace, and it references something inFrameworkBundle.
We have to fix that.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Good point. For the records, here's@javiereguiluz's answer when@stof's said the same thing. I need to think a bit about it.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I see a few options:

  1. A simpleclass_exists check on theRedirectController to have a user-friendly exception. This references the FrameworkBundle, but is not a hard coupling.
  2. We use a_redirect attribute, that will be handled by aControllerResolverInterface implementation within the FrameworkBundle.
  3. We use a_redirect attribute that will be handled by a listener onkernel.request within theHttpKernel component

@nicolas-grekasnicolas-grekas added this to the4.1 milestoneNov 24, 2017
@sroze
Copy link
ContributorAuthor

Right, so you mean we should add aredirect method in theRouteTrait?

private function looksLikeUrl(string $urlOrRouteName): bool
{
foreach (array('/', '//', 'http://', 'https://') as $pattern) {
if (substr($urlOrRouteName, 0, strlen($pattern)) == $pattern) {
Copy link
Member

Choose a reason for hiding this comment

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

should use0 === strpos() instead to be consistent with the codebase (we avoid allocating a new string)

private function redirectToDefaults(string $redirect, bool $permanent = false): array
{
if ($this->looksLikeUrl($redirect)) {
$defaults['_controller'] = 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction';
Copy link
Member

Choose a reason for hiding this comment

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

would be better to write it as$defaults = array(..., ...) instead of assigning in an undefined variable

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Not sure how that happened - well, I know, refactoring.. - , I'd expect PHP to tell me how bad was that.

@@ -239,6 +241,10 @@ private function parseConfigs(\DOMElement $node, $path)
$defaults['_controller'] = $controller;
}

if ($redirectTo = $node->getAttribute('redirect-to')) {
Copy link
Member

Choose a reason for hiding this comment

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

should forbid to put it at the same time than a controller (check for$defaults['_controller'] being configured already)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Done 👍

@@ -239,6 +241,10 @@ private function parseConfigs(\DOMElement $node, $path)
$defaults['_controller'] = $controller;
}

if ($redirectTo = $node->getAttribute('redirect-to')) {
$defaults += $this->redirectToDefaults($redirectTo, $node->getAttribute('redirect-permanent'));
Copy link
Member

Choose a reason for hiding this comment

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

not good. The attribute value will always be a string. It must be parsed into an actual boolean (see the values accepted byparseDefaultNode for the<bool> tag)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

But.. it's working well... not suregetAttribute actually returns onlystrings 🤔

@nicolas-grekas
Copy link
Member

As stated in#24640 (comment) and below, I would do it differently: instead of setting a controller, theredirect_to entry could just set a new entry in "defaults", named eg "_redirect_to" instead of "_controller". Then it'd be up to high level layers to act upon it.

@sroze
Copy link
ContributorAuthor

@nicolas-grekas definitely agree, see myproposed options here.

return $defaults;
}

private function looksLikeUrl(string $urlOrRouteName): bool

Choose a reason for hiding this comment

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

I fear any guessing strategy would be fragile. Instead, what about two defaults:

  • _redirect_to_route
  • _redirect_to_uri

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think this is a valid fear: if the string starts with/ or a[scheme]:// then it's an URL seems enough to me. Having two ways of configuring the "target" reduces the DX.

javiereguiluz reacted with thumbs up emoji

Choose a reason for hiding this comment

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

Moreover, we already do that guessing in other parts of the framework. E.g. thelogin_path option in the always delicate Security component.

@sroze
Copy link
ContributorAuthor

The real question now is: who is going to handle the_redirect (or two_redirects) attributes? HttpKernel or FrameworkBundle? I'd argue for HttpKernel so it can benefit other libraries only using the kernel. If it's HttpKernel, we need to move the logic from FrameworkBundle'sRedirectController to the HttpKernel component.

@nicolas-grekas
Copy link
Member

Adding one more question we need to answer:
what about the "permanent" flag, and the "ignoreAttributes" setting?

@sroze
Copy link
ContributorAuthor

what about the "permanent" flag, and the "ignoreAttributes" setting?

I'd sayredirect_permanent andredirect_ignore_attributes configurations (and their XML equivalents with-s)

@srozesrozeforce-pushed theredirect-from-route-configuration branch 2 times, most recently from0fa3e8e to484121eCompareNovember 25, 2017 13:36
@sroze
Copy link
ContributorAuthor

@stof@nicolas-grekas I've updated the PR to use_redirect_to and_redirect_permanent attributes populated by the loaders inRouting. A new listener inFrameworkBundle adds the_controller onkernel.request when it sees the_redirect_* attributes in theRequest.

@nicolas-grekas
Copy link
Member

@sroze what would be the new way of doing this configuration in yaml? Can we do without a listener (yet another one for this looks like overhead to me...)

@sroze
Copy link
ContributorAuthor

what would be the new way of doing this configuration in yaml?

The one in the PR description :)

Can we do without a listener (yet another one for this looks like overhead to me...)

Well... we could. Do you want me to merge with the existing one or doing something else? 🤔

@srozesrozeforce-pushed theredirect-from-route-configuration branch 2 times, most recently from62e7de8 to5a35a7fCompareDecember 3, 2017 11:45
@srozesrozeforce-pushed theredirect-from-route-configuration branch from8edd537 to50f9243CompareJanuary 4, 2018 16:36
@sroze
Copy link
ContributorAuthor

AppVeyor's failure is not related. It's a network issue. Can somebody restart it?

@sroze
Copy link
ContributorAuthor

ping@Tobion :)

@srozesrozeforce-pushed theredirect-from-route-configuration branch from50f9243 to3266887CompareJanuary 26, 2018 13:52
@nicolas-grekas
Copy link
Member

Now that I know the router a bit better, I'd suggest leveragingRedirectableUrlMatcherInterface::redirect() instead. This also means I'd suggest to remove the permanent/non-permanent flag. Let's make this very simple, and make it a core feature on theRouting component only, since is has everything needed to deal with that standalone.

@sroze
Copy link
ContributorAuthor

I'd suggest leveraging RedirectableUrlMatcherInterface::redirect() instead.

Can you guide me through what you have in mind a little bit more? Maybe one way would be to roughly explain how you'd change this pull-request?

@nicolas-grekas
Copy link
Member

when a_redirect entry is found in the matched route, a redirectable matcher could internally
return $this->redirect($ret['_redirect'], $ret['_route']);

@javiereguiluz
Copy link
Member

I've been thinking about this proposal ... and I propose to make a minor change. Instead of usingredirect_to for redirecting both URLs and routes, we could be more explicit and defineredirect_to andredirect_to_route (this is also consistent with other Symfony parts, where "redirect" is for URLs and routes have a special redirect method). In practice:

# redirect_to for absolute or relative URLsblog_show:path:/blog/{slug}redirect_to:/some-relative-urlpermanent:true# redirect_to_route without route argumentsblog_show:path:/blog/{slug}redirect_to_route:'some-other-route'# this also works, to be consistent with the next case:# redirect_to_route: ['some-other-route']# redirect_to_route with route argumentsblog_show:path:/blog/{slug}redirect_to_route:['some-other-route', { arg1: 'value1', arg2: 'value2' }]
jvasseur reacted with thumbs up emoji

@javiereguiluzjaviereguiluz added the ❄️ Feature FreezeImportant Pull Requests to finish before the next Symfony "feature freeze" labelMar 12, 2018
@javiereguiluz
Copy link
Member

@sroze I know you are very busy and you also have a much more important PR related to the new Message component ... but it'd be great if you could finish this feature before the Symfony 4.1 "feature freeze" starts in 12 days. Thanks!

@sroze
Copy link
ContributorAuthor

@javiereguiluz yep, agree with you, it would be nice. I'll update the PR this week :)

@sroze
Copy link
ContributorAuthor

I've explored the option of moving this logic directly within the router, especiallywithin thePhpMatcherDumper and it worked for theredirect idea. It did not work at all for theredirect_to_route idea because it would require aUrlGeneratorInterface while the dumper matcher is... just a matcher. One way to tackle this would be to have a sort of mini-generator while dumping the matcher but this 1) would duplicate some logic and 2) won't support things like route parameters. This is therefore not a satisfying approach.

The problem with the current implementation is that is it specific to a few details about the routing and is sort of between the Routing component and the FrameworkBundle bundle. Redirection configuration (while allowed by the Routing component) wouldn't work without the FrameworkBundle, which is not what we'd like.

While discussing all of that with@nicolas-grekas, we jumped back to actually... what we are trying to solve: simplifying the YAML configuration. Itmight be that the only issue, for now, is theSymfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction FQCN that we always have to copy/paste. Nico's idea, which might make sense is that instead of redirect-specific configuration, we simply add controller aliases. Therefore, the redirection configuration could look like that:

redirect_to_admin:path:/defaults:_controller:_redirect_pathpath:/adminpermanent:true

What do you all think?

@javiereguiluz
Copy link
Member

javiereguiluz commentedMar 20, 2018
edited
Loading

I haven't looked at the internals ... but from the outside this looks "just" a syntactic sugar that should be "easy" to implement. So, the end-user writes this in YAML:

blog_show:path:/blog/{slug}redirect_to:/some-relative-urlpermanent:true

And Symfony, when parsing that YAML file, transforms it to this transparently:

blog_show:path:/blog/{slug}defaults:_controller:Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectActionpath:/some-relative-urlpermanent:true

So, this feature "just" needs to look for aredirect_to option and then, create thedefaults._controller anddefaults.path options automatically ... and let Symfony take care of the rest. No more changes would be needed because the verbose config already works: this feature "just" transforms concise config to verbose config internally. Would that work?

@sroze
Copy link
ContributorAuthor

@javiereguiluz the real problem is that:

The problem with the current implementation is that is it specific to a few details about the routing and is sort of between the Routing component and the FrameworkBundle bundle. Redirection configuration (while allowed by the Routing component) wouldn't work without the FrameworkBundle, which is not what we'd like.

@javiereguiluz
Copy link
Member

javiereguiluz commentedMar 20, 2018
edited
Loading

@sroze this is how I imagine the implementation of this feature (the code doesn't work, I just invented it to show what I'm asking for):

public function processRoutes($yamlContent){    $routesConfig = Yaml::parse($yamlContent);    foreach ($routesConfig as $routeConfig) {+        if (isset($routeConfig['redirect_to'])) {+           $routeConfig['_defaults']['_controller'] = 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction';+           $routeConfig['_defaults']['path'] = $routeConfig['redirect_to'];+           unset($routeConfig['redirect_to']);+       }        // ...    }    return $routeCollection;}

@sroze
Copy link
ContributorAuthor

Yes, I agree with you. But it would mean the Routing component depends on the FrameworkBundle (at least, the way it is now).

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedMar 20, 2018
edited
Loading

I'm now convinced the aliasing feature is all that is needed at least as a first step. This should be a feature of RouterListener in HttpKernel IMHO (could also be in Routing matchers, but I feel better with RouterListener). So down this path, we would just need aRouterListener::setControllerAliases(array $aliases) and done.

Javier has another goal, which is to move defaults out of the "defaults" nesting level.
This goal is unrelated to redirection to me. Or, if it's for redirections only, then I'm very unsure, as this would just create a new specific case that ppl will need to learn.

All-in-all, the controller aliasing looks like the right next step to me.

@javiereguiluz
Copy link
Member

javiereguiluz commentedMar 22, 2018
edited
Loading

To better compare the alternatives, here is a summary:

Current situation

blog_show:path:/blog/{slug}defaults:_controller:Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectActionpath:/some-relative-urlpermanent:true

Proposal 1

blog_show:path:/blog/{slug}redirect_to:/some-relative-urlpermanent:true

Proposal 2

blog_show:path:/blog/{slug}defaults:_controller:_redirect_pathpath:/some-relative-urlpermanent:true

I think it's OK to create aredirect_to option because we recently moved thedefaults._controller option to justcontroller and people loved it.

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedMar 22, 2018
edited
Loading

I'm 👎 for adding redirect specific root-options because it creates a very specific case people will have to learn, whereas the proposed alternative (2) just leverages existing and new generic knowledge. The redirect-specific entries would also prevent using new or exotic redirection options, because these are specific to the actual redirector implementation.

@sroze
Copy link
ContributorAuthor

The only counter-argument to@nicolas-grekas' PoV I can see is that a redirection is not a "very specific case" of routing.

{
$requestAttributes = $event->getRequest()->attributes;

if (!$requestAttributes->has('_controller') && $redirectTo = $requestAttributes->get('_redirect_to')) {
Copy link
Member

Choose a reason for hiding this comment

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

I would use early returns instead:

if ($requestAttributes->has('_controller')) {return;}if (!$redirectTo =$requestAttributes->get('_redirect_to')) {return;}

HeahDude reacted with thumbs up emoji
);
}

public function onKernelRequest(GetResponseEvent $event)
Copy link
Member

Choose a reason for hiding this comment

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

public function onKernelRequest(GetResponseEvent $event): void

*/
class ResolveRedirectControllerSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
Copy link
Member

Choose a reason for hiding this comment

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

public static function getSubscribedEvents(): array

@fabpot
Copy link
Member

fabpot commentedMar 23, 2018
edited
Loading

From a user PoV, I like theredirect_to option from Javier. Looks neat to me. That does not work well as it would not allow for specific HTTP status code, ...

@sroze
Copy link
ContributorAuthor

Let's close this one, as this direction is a dead end :)

@srozesroze closed thisApr 4, 2018
@srozesroze deleted the redirect-from-route-configuration branchApril 4, 2018 16:01
nicolas-grekas added a commit that referenced this pull requestFeb 9, 2020
…le template and redirect controllers (HeahDude)This PR was merged into the 5.1-dev branch.Discussion----------[FrameworkBundle][Routing] added Configurators to handle template and redirect controllers| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | yes| BC breaks?    | no| Deprecations? | no| Tests pass?   | let's see| Fixed tickets | partially#24640,#25145| License       | MIT| Doc PR        |symfony/symfony-docs#11120While working onsymfony/symfony-docs#11085, I felt bad about the long notations required for simple [redirects](https://symfony.com/doc/current/routing/redirect_in_config.html) and [templates rendering](https://symfony.com/doc/current/templating/render_without_controller.html) template actions, but I love and use those features since always. Then I gave it a try yesterday night and now I realised I missed#24640 and that#25145 has been closed x).So here we go, here's my WIP. WDYT of this implementation? ping@javiereguiluz?I'm going to open the PR in the docs so we can discuss the DX changes there too, and keep focus on the code here.Cheers!EDIT----This PR now only update PHP-DSL configurators.______________TODO:- [x] gather reviews- ~[x] fix xml schema~- [x] add some tests- ~[ ] handle xsd auto discovery~- [x] rebase on top of#30507- [x] ~add shortcuts for#30514~Commits-------de74794 [FrameworkBundle][Routing] added Configurators to handle template and redirect controllers
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@javiereguiluzjaviereguiluzjaviereguiluz left review comments

@nicolas-grekasnicolas-grekasnicolas-grekas left review comments

@ro0NLro0NLro0NL left review comments

@xabbuhxabbuhxabbuh left review comments

@stofstofstof requested changes

Assignees
No one assigned
Labels
FeatureRouting❄️ Feature FreezeImportant Pull Requests to finish before the next Symfony "feature freeze"Status: Needs Review
Projects
None yet
Milestone
4.1
Development

Successfully merging this pull request may close these issues.

8 participants
@sroze@nicolas-grekas@javiereguiluz@fabpot@stof@ro0NL@xabbuh@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp