function FormBuilder::processForm

Same name in other branches
  1. 9 core/lib/Drupal/Core/Form/FormBuilder.php \Drupal\Core\Form\FormBuilder::processForm()
  2. 8.9.x core/lib/Drupal/Core/Form/FormBuilder.php \Drupal\Core\Form\FormBuilder::processForm()
  3. 10 core/lib/Drupal/Core/Form/FormBuilder.php \Drupal\Core\Form\FormBuilder::processForm()

Overrides FormBuilderInterface::processForm

2 calls to FormBuilder::processForm()
FormBuilder::buildForm in core/lib/Drupal/Core/Form/FormBuilder.php
Builds and processes a form for a given form ID.
FormBuilder::submitForm in core/lib/Drupal/Core/Form/FormBuilder.php
Retrieves, populates, and processes a form.

File

core/lib/Drupal/Core/Form/FormBuilder.php, line 548

Class

FormBuilder
Provides form building and processing.

Namespace

Drupal\Core\Form

Code

public function processForm($form_id, &$form, FormStateInterface &$form_state) {
    $form_state->setValues([]);
    // With GET, these forms are always submitted if requested.
    if ($form_state->isMethodType('get') && $form_state->getAlwaysProcess()) {
        $input = $form_state->getUserInput();
        if (!isset($input['form_build_id'])) {
            $input['form_build_id'] = $form['#build_id'];
        }
        if (!isset($input['form_id'])) {
            $input['form_id'] = $form_id;
        }
        if (!isset($input['form_token']) && isset($form['#token'])) {
            $input['form_token'] = $this->csrfToken
                ->get($form['#token']);
        }
        $form_state->setUserInput($input);
    }
    // self::doBuildForm() finishes building the form by calling element
    // #process functions and mapping user input, if any, to #value properties,
    // and also storing the values in $form_state->getValues(). We need to
    // retain the unprocessed $form in case it needs to be cached.
    $unprocessed_form = $form;
    $form = $this->doBuildForm($form_id, $form, $form_state);
    // Only process the input if we have a correct form submission.
    if ($form_state->isProcessingInput()) {
        // Form values for programmed form submissions typically do not include a
        // value for the submit button. But without a triggering element, a
        // potentially existing #limit_validation_errors property on the primary
        // submit button is not taken account. Therefore, check whether there is
        // exactly one submit button in the form, and if so, automatically use it
        // as triggering_element.
        $buttons = $form_state->getButtons();
        if ($form_state->isProgrammed() && !$form_state->getTriggeringElement() && count($buttons) == 1) {
            $form_state->setTriggeringElement(reset($buttons));
        }
        $this->formValidator
            ->validateForm($form_id, $form, $form_state);
        // If there are no errors and the form is not rebuilding, submit the form.
        if (!$form_state->isRebuilding() && !FormState::hasAnyErrors()) {
            $submit_response = $this->formSubmitter
                ->doSubmitForm($form, $form_state);
            // If this form was cached, delete it from the cache after submission.
            if ($form_state->isCached()) {
                $this->deleteCache($form['#build_id']);
            }
            // If the form submission directly returned a response, return it now.
            if ($submit_response) {
                return $submit_response;
            }
        }
        // Don't rebuild or cache form submissions invoked via self::submitForm().
        if ($form_state->isProgrammed()) {
            return;
        }
        // If $form_state->isRebuilding() has been set and input has been
        // processed without validation errors, we are in a multi-step workflow
        // that is not yet complete. A new $form needs to be constructed based on
        // the changes made to $form_state during this request. Normally, a submit
        // handler sets $form_state->isRebuilding() if a fully executed form
        // requires another step. However, for forms that have not been fully
        // executed (e.g., Ajax submissions triggered by non-buttons), there is no
        // submit handler to set $form_state->isRebuilding(). It would not make
        // sense to redisplay the identical form without an error for the user to
        // correct, so we also rebuild error-free non-executed forms, regardless
        // of $form_state->isRebuilding().
        // @todo Simplify this logic; considering Ajax and non-HTML front-ends,
        //   along with element-level #submit properties, it makes no sense to
        //   have divergent form execution based on whether the triggering element
        //   has #executes_submit_callback set to TRUE.
        if (($form_state->isRebuilding() || !$form_state->isExecuted()) && !FormState::hasAnyErrors()) {
            // Form building functions (e.g., self::handleInputElement()) may use
            // $form_state->isRebuilding() to determine if they are running in the
            // context of a rebuild, so ensure it is set.
            $form_state->setRebuild();
            $form = $this->rebuildForm($form_id, $form_state, $form);
        }
    }
    // After processing the form, the form builder or a #process callback may
    // have called $form_state->setCached() to indicate that the form and form
    // state shall be cached. But the form may only be cached if
    // $form_state->disableCache() is not called. Only cache $form as it was
    // prior to self::doBuildForm(), because self::doBuildForm() must run for
    // each request to accommodate new user input. Rebuilt forms are not cached
    // here, because self::rebuildForm() already takes care of that.
    if (!$form_state->isRebuilding() && $form_state->isCached()) {
        $this->setCache($form['#build_id'], $unprocessed_form, $form_state);
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.