Skip to content
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

the route name "app.request.attributes.get('_route')" #5804

Closed
arffak opened this issue Oct 21, 2012 · 16 comments
Closed

the route name "app.request.attributes.get('_route')" #5804

arffak opened this issue Oct 21, 2012 · 16 comments

Comments

@arffak
Copy link

arffak commented Oct 21, 2012

When i use the forward request in my "action" the route name "app.request.attributes.get('_route')" is empty is that normal?

@stof
Copy link
Member

stof commented Oct 21, 2012

it is, as you are not relying on the routing in your forwarded request but setting the controller directly.

@arffak
Copy link
Author

arffak commented Oct 21, 2012

exactly, so what is the method to retrieve this information in the template without changing my action

@stof
Copy link
Member

stof commented Oct 21, 2012

Well, if your subrequest needs to know some informations about the main request, you need to pass them explicitly. they are separate requests

@arffak
Copy link
Author

arffak commented Oct 21, 2012

oki thx;

@arffak arffak closed this as completed Oct 21, 2012
@rivaros
Copy link

rivaros commented May 2, 2013

Very interesting.

User enters "http://www.mysite.com/path1", controller makes a forward, and route is lost.

{{ app.request.get('_route') }} shows nothing, though in browser address we see "http://www.mysite.com/path1"

Language switchers stop working
{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'en'})) }}
{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'nl'})) }}

In my opinion - bug. Forward returns a Response, therefore preserving _route and get parameters is necessary.

@stof
Copy link
Member

stof commented May 2, 2013

Well, a forward is a subrequest. And your subrequest receive the Request object of the subrequest, not of the master request. There is no reason to have the route of the master request in the subrequest object.
If your forward is done using the controller name, there is indeed no routing in the subrequest.

@rivaros
Copy link

rivaros commented May 2, 2013

deleted - see comments below

@stof
Copy link
Member

stof commented May 2, 2013

@rivaros did you read the last sentence of my message ?

@rivaros
Copy link

rivaros commented May 2, 2013

Christophe, definitely.

I was a little misleading in my comments, but what I really mean is:

  1. Routing is not involved in forwarding - agree.
  2. Forwarding is done by duplicating the original request (Symfony\Bundle\FrameworkBundle\Controller\Controler.php):
    public function forward($controller, array $path = array(), array $query = array())
    {
        $path['_controller'] = $controller;
        $subRequest = $this->container->get('request')->duplicate($query, null, $path);

        return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
    }

It duplicates the POST parameters, and also GET parameters, if they are not specified in forward call.
Cloned request gets POST & GET, cookie and session of the parent request.
Do you agree on this point?

Now point 3:

    public function forward($controller, array $path = array(), array $query = array())
    {
        $path['_controller'] = $controller;
    +    $path['_route'] = $this->container->get('request')->attributes->get('_route');
    +   $path['_route_params'] = $this->container->get('request')->attributes->get('_route_params');
        $subRequest = $this->container->get('request')->duplicate($query, null, $path);

        return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
    }

By adding 2 lines of code you can solve
the problem of not working language selectors (which i mention above)
It does not give any overhead, and seems logical for me.

These are attributes, no routing really involved.

@rivaros
Copy link

rivaros commented May 2, 2013

When using forwarding end-user still sees the URL of parent request in his browser.
Therefore, if in twig template displayed, we are doing anything with app.request.get('_route') or app.request.get('_route_params'), it would deal with parent url, which is logical from usability.

@stof
Copy link
Member

stof commented May 2, 2013

@rivaros subrequest are not done by the browser, be it when using forwarding or when using the FragmentHandler. The browser does not even know about subrequests.

@rivaros
Copy link

rivaros commented May 3, 2013

Christophe, where did i say they're done by browser?

For those who need to solve issue with forward, a workaround

return $this->forward('Yourbundle:Controller:action',
array(
... your parameters...,
'_route' => $this->getRequest()->attributes->get('_route'),
'_route_params' => $this->getRequest()->attributes->get('_route_params');
));

)

@stof
Copy link
Member

stof commented May 4, 2013

When using forwarding end-user still sees the URL of parent request in his browser.

What the user sees is not relevant for the sub-request. the client of the sub-request is not the browser. It is your PHP code handling the master request.

@mekras
Copy link

mekras commented Jan 15, 2015

@rivaros, thanks for workaround!

@hbksagar
Copy link

@rivaros, thanks for the solution.

@bizbink
Copy link

bizbink commented Oct 14, 2015

Another workaround is to extend the controller containing the route be forwarded and use the keyword parent to call up the method.

class FirstController extends SecondController {
    function indexAction (Request $request) {
        parent::indexAction($request);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants