Change record status: 
Project: 
Introduced in branch: 
8.0.x
Description: 

In Drupal 7, default form validate or submit functions were determined by appending _validate and _submit to the form ID.
However, these were not triggered if a custom #validate or #submit handler was used.
In which case, the default handlers needed to be specified manually.

Drupal 7

No custom submit handler

function test_form($form, $form_state) {
  $form['submit'] = array('#type' => 'submit', '#value' => 'Save');
  return $form;
}

function custom_submit_function(&$form, &$form_state) {
  // This would NOT be executed.
}
function test_form_submit(&$form, &$form_state) {
  // This would be executed.
}

Custom submit handler

function test_form($form, $form_state) {
  $form['#submit'][] = 'custom_submit_function';
  $form['submit'] = array('#type' => 'submit', '#value' => 'Save');
  return $form;
}

function custom_submit_function(&$form, &$form_state) {
  // This would be executed.
}
function test_form_submit(&$form, &$form_state) {
  // This would NOT be executed.
}

Custom submit handler and default specified

function test_form($form, $form_state) {
  $form['#submit'][] = 'custom_submit_function';
  $form['#submit'][] = 'test_form_submit';
  $form['submit'] = array('#type' => 'submit', '#value' => 'Save');
  return $form;
}

function custom_submit_function(&$form, &$form_state) {
  // This would be executed.
}
function test_form_submit(&$form, &$form_state) {
  // This would be executed.
}

Drupal 8

No custom submit handler

class TestForm extends FormBase {

  public function buildForm(array $form, array &$form_state) {
    $form['submit'] = array('#type' => 'submit', '#value' => 'Save');
    return $form;
  }

  public function submitForm(array &$form, array &$form_state) {
    // This would be executed.
  }

  public function customSubmitForm(array &$form, array &$form_state) {
    // This would NOT be executed.
  }

Custom submit handler

class TestForm extends FormBase {

  public function buildForm(array $form, array &$form_state) {
    $form['#submit'][] = array($this, 'customSubmitForm');
    $form['submit'] = array('#type' => 'submit', '#value' => 'Save');
    return $form;
  }

  public function submitForm(array &$form, array &$form_state) {
    // This would be executed.
  }

  public function customSubmitForm(array &$form, array &$form_state) {
    // This would be executed.
  }

Custom submit handler and default specified

class TestForm extends FormBase {

  public function buildForm(array $form, array &$form_state) {
    $form['#submit'][] = array($this, 'customSubmitForm');
    // Do not do this.
    $form['#submit'][] = array($this, 'submitForm');
    $form['submit'] = array('#type' => 'submit', '#value' => 'Save');
    return $form;
  }

  public function submitForm(array &$form, array &$form_state) {
    // This would be executed TWICE. Do not specify the default handler.
  }

  public function customSubmitForm(array &$form, array &$form_state) {
    // This would be executed.
  }

Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

Anonymous’s picture

Oh man, this is epic!
Although this record needs the information about the order ie. will the "native" handler be called before or after defined handlers in the form/elements?