0

In my controller I am loading a form and including one custom submit handler. However the submit function is not called. I think that it's either not found or not accessible as it is inside the controller class:

class MyController extends ControllerBase {

  //...

  public function myProfile() {
    $user = User::load($this->currentUser->id());
    $form = $this->entityFormBuilder()->getForm($user);

    $form['actions']['submit']['#submit'][] = '::_custom_submit_form';
  }

  protected function _custom_submit_form(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) { 
    $form_state->setRedirect('<front>');
  }

}

If I use hook_form_alter it works, but I don't want to use a hook as I can directly manipulate the form.

  • I'd say this submit function needs to be public. public function _custom_submit_form. – leymannx Jun 26 '18 at 21:45
  • doesn't work with public – Miguel Jun 26 '18 at 22:01
4

To understand why your code is not working, you need to understand how the form API works:

  1. The form definition is called
  2. Any form alter hooks are executed, altering the form
  3. The render array is cached
  4. The form is rendered as HTML and sent to the browser
  5. The user submits the form
  6. Drupal checks that the submitted values match the cached form. If values do not match, the values are rejected by Drupal's security system

When you call this code:

$form = $this->entityFormBuilder()->getForm($user);

The caching mentioned in step 3 above has already happened. So when you do this after that line of code:

$form['actions']['submit']['#submit'][] = '::_custom_submit_form';

The submit handler is never called, since the form was cached before this line of code, and therefore your submit handler does not make it into the cache.

To add a submit handler to a form, you need to implement hook_form_alter() (or a variation), which will add the handler before the caching happens. Or, you can extend the form class you are working with, add your own ::submitForm() handler, then call the parent submit from that.

  • thank you for the very good and comprehensible explanation. It's a pitty that these kind of things are not documented in this way. – Miguel Jun 27 '18 at 8:21
  • so if I don't want the custom submit handler added always to the form but only in one special case, the only possibility is to extend the form class? – Miguel Jun 27 '18 at 8:31
  • Or you can use hook_form_alter() and add a logic check. – Jaypan Jun 27 '18 at 8:45
  • Thanks @Jaypan! – aserww106 Apr 3 at 3:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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