1

I've got a search form with some select boxes. I render it in the headnavi on every page using ebedded controllers. (http://symfony.com/doc/current/book/templating.html#embedding-controllers) I want to use the form output to redirect to my list-view page like this:

/list-view/{city}/{category}?q=searchQuery

My form and the request is working well when I call the controller through a route, but unfortunately when I embed the controller, I'm stumblig over two problems. Like I've read here (Symfony 2 - Layout embed "no entity/class form" validation isn't working) my request isn't handeled by my form because of the sub-request. There is a solution in the answer, but its not very detailed. The other problem, after fixing the first one, will be that I can't do a redirect from an embedded controller (Redirect from embedded controller). Maybe anyone has an easier solution for having a form on every page that lets me do a redirect to its data?

Many thanks and greetings Raphael

1 Answer 1

1

The answer of Symfony 2 - Layout embed "no entity/class form" validation isn't working is 100% correct, but we use contexts and isolate them, so an action which always uses the master request would break the rules. You have all requests (one master and zero or more subrequests) in the request_stack. Injecting Request $request into your controller action is the current request which is the subrequest with only max=3 (injecting the Request is deprecated now). Thus you have to use the 'correct' request.

Performing a redirection can be done in many ways, like return some JS script code to redirect (which is quite ugly imho). I would not use subrequests from twig because it's too late to start a redirection then, but make the subrequest in the action. I didn't test the code, but it should work. Controller::forward is your friend, since it duplicatest the current request for performing a subrequest.

Controller.php (just to see the implementation).

/**
 * Forwards the request to another controller.
 *
 * @param string $controller The controller name (a string like BlogBundle:Post:index)
 * @param array  $path       An array of path parameters
 * @param array  $query      An array of query parameters
 *
 * @return Response A Response instance
 */
protected function forward($controller, array $path = array(), array $query = array())
{
    $path['_controller'] = $controller;
    $subRequest = $this->container->get('request_stack')->getCurrentRequest()->duplicate($query, null, $path);
    return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
}

YourController.php

public function pageAction() {
  $formResponse = $this->forward('...:...:form'); // e.g. formAction()
  if($formResponse->isRedirection()) {
    return $formResponse; // just the redirection, no content
  }
  $this->render('...:...:your.html.twig', [
    'form_response' => $formResponse
  ]);
}

public function formAction() {
  $requestStack = $this->get('request_stack');
  /* @var $requestStack RequestStack */

  $masterRequest = $requestStack->getCurrentRequest();
  \assert(!\is_null($masterRequest));

  $form = ...;
  $form->handleRequest($masterRequest);

  if($form->isValid()) {
    return $this->redirect(...); // success
  }

  return $this->render('...:...:form.html.twig', [
    'form' => $form->createView()
  ]);
}

your.html.twig

{{ form_response.content | raw }}
Sign up to request clarification or add additional context in comments.

8 Comments

Hey Aitch, thanks for your detailed answer and code example! I did everything like you said, and render 'pageAction' on my base template. Now im getting this error: Variable "form" does not exist in ControllerViews/Renders/form.html.twig at line 1
as you can see from formAction we pass the form in render() and you can use it in form.html.twig. In your.html.twig in the pageAction you pass form_response which is HTML and you can just use it in twig. Please double-check that there is no form variable in your.html.twig and just try to understand what's going on in the controller actions to find the problem.
Ok I found the problem. In pageAction I rendered form.html.twig instead of your.html.twig. Now I'm getting the form, but it's still not working. I think it's still a problem with the request, because after submitting the form, the URL changes like this --> ?form[search]=Test&form[category]=&form[type]=&form[location]=&form[send]=&form[_token]=nQCbivIi7IppDpaWtmEesLOOVEoPL7njJCPpXPlxxPg
Look in the source HTML. is the method attribute of the form GET or empty? that's wrong, create your forms with form_start, etc. twig functions
<form name="form" method="post" action="">
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.