By gbmapo


2019-03-12 07:48:49 8 Comments

In a custom module, I have a form that is triggered by an option in a menu.
I'd want this form to be redirected automatically (without action of the user) to a certain node (/node/2) when the user is not authenticated.
In the public function buildForm(array $form, FormStateInterface $form_state) {, I know how to not display the fields of the form for the anonymous user:

$oCurrentUser = \Drupal::currentUser();
if ($oCurrentUser->isAnonymous()) {
} else {

some fields...    

$form['submit'] = [
  '#type' => 'submit',
  '#value' => $this->t('Submit'),
];
return $form;
}

I guess that redirection might be done with $form_state->setRedirect('entity.node.canonical', ['node' => 2]); but I don't know how to make it work...
Any idea?

4 comments

@gbmapo 2019-03-13 10:39:17

Using kiamlaluno's advice, the route for the menu is now associated to /association/showMembership.

association.membership_showMembership:
  path: '/association/showMembership'
  defaults:
    _controller: '\Drupal\association\Controller\MembershipController::showMembership'
    _title: 'Membership'
  requirements:
    _access: 'TRUE'

The controller class uses the following code.

class MembershipController extends ControllerBase {
  public function showMembership() {
    if ($this->currentUser()->isAnonymous()) {
      return $this->redirect('entity.node.canonical', ['node' => 2]);
    }
    return $this->formBuilder()->getForm('Drupal\association\Form\Membership');
  }
}

The Membership form doesn't redirect users in buildForm().

@4k4 2019-03-12 08:42:22

In buildForm() you can return a redirect response the same way as in a controller:

  public function buildForm(array $form, FormStateInterface $form_state) {
    if ($this->currentUser()->isAnonymous()) {
      return $this->redirect('entity.node.canonical', ['node' => 2]);
    }

    // build $form for authenticated users

    return $form;
  }

Use $form_state->setRedirect() if you want to redirect in a form submit handler.


Using buildForm() as controller by specifying _form instead of _controller is documented and widely used (not in FormInterface, but on DO: https://www.drupal.org/docs/8/api/routing-system). It's unlikely core will ask devs to replace it by their own controller.

@kiamlaluno 2019-03-12 12:31:52

The class implementing FormInterface is allowed to return an instance of a class extending the Response class, despite FormInterface::buildForm() not documenting it. See what a comment in the FormBuilder::retrieveForm() code says.

Exceptions should not be used for code flow control. However, the Form API currently allows any form builder functions to return a response.
@see https://www.drupal.org/node/2363189

This means that code similar to the following one would actually work.

public function buildForm(array $form, FormStateInterface $form_state) {
  // Verify the currently logged in user is an anonymous user and redirect.
  if ($this->currentUser()->isAnonymous()) {
    return $this->redirect('entity.node.canonical', ['node' => 2]);
  }
}

Although, since Do not allow form builder functions to return Response objects (the bug report linked in the comment) is open for Drupal 8.8.x, that code could not work anymore, in future.

See also the following comment in the FormBuilder::buildForm() code.

Exceptions should not be used for code flow control. However, the Form API does not integrate with the HTTP Kernel based architecture of Drupal 8. In order to resolve this issue properly it is necessary to completely separate form submission from rendering.
@see https://www.drupal.org/node/2367555

The linked issue is Deprecate EnforcedResponseException support (a task, not a bug report).

A module that works also after the change described in that issue is implemented would:

  • Associate a controller to the route, not a form builder
  • In the controller method associated with the route, redirect the anonymous users to the node page, or render the form for authenticated users

    class RedirectOrFormController extends ControllerBase {
      public function showForm() {
        if ($this->currentUser()->isAnonymous()) {
          return $this->redirect('entity.node.canonical', ['node' => 2]);
        }
    
        return $this->formBuilder()->getForm('Drupal\\locale\\Form\\TranslateEditForm');
      }
    }
    

Replace 'Drupal\\locale\\Form\\TranslateEditForm' with the fully qualified name of the form builder.

@sekharctc 2019-03-12 08:48:41

yes, you are right. you can redirect to the node using the code that you have mentioned. There is another way to set the redirection check the below code.

use the name space :

 
use Symfony\Component\HttpFoundation\RedirectResponse;
$response = new RedirectResponse(node url);
$response->send();
exit(0);

I don't know what you are trying to achieve hope this code may help you.

@Kevin 2019-03-12 12:19:00

exits should not be needed

@kiamlaluno 2019-03-12 12:35:49

@Kevin is correct: exit() should not be used.

@kiamlaluno 2019-03-14 13:38:14

This is also not how redirects are done in a form builder.

Related Questions

Sponsored Content

2 Answered Questions

[SOLVED] How to do a hard redirect when in ajaxified form?

  • 2017-08-11 00:42:21
  • user21641
  • 2263 View
  • 2 Score
  • 2 Answer
  • Tags:   8 forms ajax

1 Answered Questions

[SOLVED] Drupal custom module code working differently for logged in users and anonymous users

  • 2018-09-20 21:32:37
  • user3324848
  • 62 View
  • 1 Score
  • 1 Answer
  • Tags:   8

1 Answered Questions

How can i set the value of first field to the second in same form

  • 2018-03-11 01:01:42
  • Ngatia Frankline
  • 35 View
  • 0 Score
  • 1 Answer
  • Tags:   forms

1 Answered Questions

[SOLVED] Access data from previously submitted values in buildForm in FormBase plugin

  • 2018-03-12 14:37:46
  • Matt
  • 238 View
  • 0 Score
  • 1 Answer
  • Tags:   8 plugins

1 Answered Questions

[SOLVED] How to validate all elements in Custom Widget

  • 2016-08-19 06:18:23
  • Jitha M Saroj
  • 574 View
  • 1 Score
  • 1 Answer
  • Tags:   8

1 Answered Questions

[SOLVED] How can I set a default node owner for anonymous nodes on the node edit form?

  • 2016-11-07 13:52:50
  • UltraBob
  • 105 View
  • 1 Score
  • 1 Answer
  • Tags:   7 forms

1 Answered Questions

How do I check login?

  • 2016-10-06 09:04:58
  • Jitha M Saroj
  • 171 View
  • 0 Score
  • 1 Answer
  • Tags:   8

1 Answered Questions

[SOLVED] URL specific form for anonymous user

0 Answered Questions

How to display the output of a form?

  • 2015-10-13 10:25:59
  • hiba najjar
  • 372 View
  • 1 Score
  • 0 Answer
  • Tags:   forms

2 Answered Questions

[SOLVED] Exposing a form to anonymous users

  • 2013-04-11 04:43:56
  • Robbert
  • 696 View
  • 1 Score
  • 2 Answer
  • Tags:   forms

Sponsored Content