16

Is it possible to forward a request, passing along all GET/POST params?

I think if I just do

$this->forward('dest') 

I will go to dest without any GET/POST params?

UPDATE

My objective is actually to have a controller action like addSomething that takes checks that the user has the sufficient "items" to add something. Then forward the request to the approperiate controller to continue the actual adding of adding{Type}Something

Or would getting a "checking" service in all controllers that does the checking be more appropriate? Anyways, I think its informative to know how to forward to a controller action with all params

4 Answers 4

31

Easiest solution (and one I'd probably go for) would be to just pass Request class as forward parameter

public function indexAction() { $request = $this->getRequest(); return $this->forward('AcmeBundle:Forward:new', array('request' => $request)); } 

And in forwarded action just use it as method param:

public function testAction($request) { var_dump($request);exit; } 
Sign up to request clarification or add additional context in comments.

3 Comments

BUT... there might be a problem when playing with forms - if both action (the 'forwarding' and the 'forwarded to') have forms with submissions, You will fall into a trap - the 'forwarded to' action sees the $_POST form from the previous controller, so it crashes on CSRF Token (invalid, from the previous form.
@thorinkor Is there a valid way around it? Regenerating it somehow? I tried with service security.csrf.token_manager and getToken() but no luck.
@userfuser the best solution - avoid it :) Maybe You could try to get it from 1st form request and resend it in forwarding method?
17

I don't see any reason here to forward the request back through the kernel. You can go the route of encapsulating this logic in a checker service, as you've suggested, or you may be able to create a kernel.request listener that runs after the router listener and applies the _controller attribute only if your conditions are met.

For example, this routing.yml:

some_route: pattern: /xyz defaults: { _controller_candidate: "FooBundle:Bar:baz" } 

And this listener:

class MyListener { public function onKernelRequest($event) { $request = $event->getRequest(); if (!$controller = $request->attributes->get('_controller_candidiate')) { return; } if (/* your logic... */) { $request->attributes->set('_controller', $controller'); } } } 

Configured to run after the core router listener:

services: my_listener: class: MyListener tags: - name: kernel.event_listener event: kernel.request priority: -10 

The priority of the core router listener is 0 in Symfony 2.0 and 32 in Symfony 2.1. In either case, a priority of -10 should work.

I'm curious to see if this works :)

5 Comments

That looks like it works. Will update whether it works after I try that later. If I want to do the reverse, run something after a controller action, is there a similar event? How do you find out about these seemingly undocumented methods?
Ok, I found my answer symfony.com/doc/2.0/book/internals.html#handling-requests. Wonder which is the right method to use? kernel.response?
Oh I use @Route annotation, how can I modify $request->attributes->get('_controller_candidiate')?
This is not possible with the @Route annotation.
Ok I used $req->attributes->get('_route') instead
15

All POST param are automatically forwarded. No action is needed to have POST param in the target controller. But you have to explicitly pass query (GET) params and path params. The forward method take 2 optionals parameter representing respectively the pathParam and the queryParam arrays. You can just pass all the query param from the current request

public testAction(Request $request){ $pathParam = array(); //Specified path param if you have some $queryParam = $request->query->all(); $response = $this->forward("AcmeBundle:Forward:new", $pathParam, $queryParam); } 

2 Comments

best answer to original question
I don't think so.
1

Forwarding "request attributes" as "path" works for me:

public function indexAction() { $path = $this->getRequest()->attributes->all(); return $this->forward('CompMyBundle:MyController:MyAction', $path); } 

$path['_controller'] will be overwritten in forward() method!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.