6

I'm in the process of porting my modules from D7 to D8. No real problems so far, but...

I have a multistep form from where I need to redirect to /node/add/xyz in the last step. (All required input form data is stored in D8 TempStore before the redirect). In d7 I used the simple and functional drupal_goto('node/add/xyz') function which is gone in D8 for whatever reason.

I looked into core modules to see how it is done in the D8 way and it seems RedirectResponse() from the Symfony routing system is the way to go. However doing something like this:

return new RedirectResponse(url('node/add/xyz', array('absolute' => TRUE)));

But this is silently ignored, no error, nothing. I read that doing RedirectResponse from somewhere in the code may not work. So my next idea of doing it was to use a form redirect in this way:

$form_state['redirect_route'] = array(
  'route_name' => 'node.add',
  'route_parameters' => array(
    'node_type' => 'xyz',
  ),
);

even without any effect. I'm out of ideas and wish drupal_goto() back. Hopefully someone out there can help me out!

Thanks in advance bzrudi

9
  • Welcome to Drupal Answers :) Where exactly are you placing the return code?
    – Clive
    Commented Nov 25, 2013 at 13:55
  • 3
    @Mołot No way to know if this is a bug until we know where the code is being used. I haven't seen a problem with Symfony's RedirectResponse yet in Drupal 8 so this is likely to be a bug in the OP's code.
    – Clive
    Commented Nov 25, 2013 at 13:57
  • @Clive The redirect is within the submitForm() method of my form.
    – bzrudi
    Commented Nov 25, 2013 at 13:59
  • Does this answer your question?
    – Clive
    Commented Nov 25, 2013 at 14:00
  • @Clive yes! I had an unneeded $form_state['rebuild'] = TRUE; within the last form step ;-) I searched hours within the D8 API and missed that one. However you helped me within minutes with my first DrupalAnswers question. Perfect - thanks a lot for your support!
    – bzrudi
    Commented Nov 25, 2013 at 14:08

3 Answers 3

2

Form redirects haven't changed between Drupal 7 and 8; you still need to use $form_state['redirect'] (incidentally drupal_goto() shouldn't be used within form submissions in Drupal 7, it can mess things up).

Within your form class's submitForm() method, you can use

$form_state['redirect'] = 'node';

Or

$form_state['redirect'] = array(
  'node/123',
  array(
    'query' => array(
      'foo' => 'bar',
    ),
    'fragment' => 'baz',
  ),
);

Full info can be found in the FormBuilder::redirectForm() docs

5
  • Actually, it has changed, you should use redirect_route now, see drupal.org/node/2105661. But yes, response objects can only be returned from non-form controllers.
    – Berdir
    Commented Nov 26, 2013 at 7:53
  • Thanks @Berdir, hadn't seen that one. Looking at the code for FormBuilder::redirectForm() now, it would also be acceptable to use $form_state['redirect'] = new RedirectResponse('/foo');...have I got that right or do you know will that change?
    – Clive
    Commented Nov 26, 2013 at 9:03
  • Apparently yes. But I think using the route is the preferred method.
    – Berdir
    Commented Nov 26, 2013 at 12:18
  • 1
    If you use a redirect response object ensure that you generate an absolute URL. In general as berdir said using route name + parameters is the preferred way of doing it. Commented Nov 30, 2013 at 10:23
  • @Berdir Just re-visiting this...the docs for redirectForm() still don't have an example using a redirect_route, do you happen to know where I can find docs for that?
    – Clive
    Commented May 30, 2014 at 16:49
2

In Drupal 8, you redirect a form in its submitForm() method by calling $form_state->setRedirect().

This is the code used from UserLoginForm::submitForm(), which redirects the user to user/$uid.

  // A destination was set, probably on an exception controller,
  if (!$this->getRequest()->request->has('destination')) {
    $form_state->setRedirect(
    'entity.user.canonical', 
    array('user' => $account->id())
    );
  }
1

Due to caching, you can't modify the form_state from hook_form_alter() anymore. Instead, in order to set or alter the redirect destination of a form, you need to attach a #submit handler to any action buttons available on the form, e.g.:

$form['actions']['submit']['#submit'][] = 'mymodule_form_submit';

and set the redirect destination in there:

function mymodule_form_submit($form, FormStateInterface $form_state) {
  $form_state->setRedirect('user.page');
}

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.