function _form_validate

Performs validation on form elements.

First ensures required fields are completed, #maxlength is not exceeded, and selected options were in the list of options given to the user. Then calls user-defined validators.

Parameters

$elements: An associative array containing the structure of the form.

$form_state: A keyed array containing the current state of the form. The current user-submitted data is stored in $form_state['values'], though form validation functions are passed an explicit copy of the values for the sake of simplicity. Validation handlers can also $form_state to pass information on to submit handlers. For example: $form_state['data_for_submission'] = $data; This technique is useful when validation requires file parsing, web service requests, or other expensive requests that should not be repeated in the submission step.

$form_id: A unique string identifying the form for validation, submission, theming, and hook_form_alter functions.

Related topics

1 call to _form_validate()
drupal_validate_form in includes/form.inc
Validates user-submitted form data in the $form_state array.

File

includes/form.inc, line 1348

Code

function _form_validate(&$elements, &$form_state, $form_id = NULL) {
    // Also used in the installer, pre-database setup.
    $t = get_t();
    // Recurse through all children.
    foreach (element_children($elements) as $key) {
        if (isset($elements[$key]) && $elements[$key]) {
            _form_validate($elements[$key], $form_state);
        }
    }
    // Validate the current input.
    if (!isset($elements['#validated']) || !$elements['#validated']) {
        // The following errors are always shown.
        if (isset($elements['#needs_validation'])) {
            // Verify that the value is not longer than #maxlength.
            if (isset($elements['#maxlength']) && (isset($elements['#value']) && !is_scalar($elements['#value']))) {
                form_error($elements, $t('An illegal value has been detected. Please contact the site administrator.'));
            }
            elseif (isset($elements['#maxlength']) && drupal_strlen($elements['#value']) > $elements['#maxlength']) {
                form_error($elements, $t('!name cannot be longer than %max characters but is currently %length characters long.', array(
                    '!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'],
                    '%max' => $elements['#maxlength'],
                    '%length' => drupal_strlen($elements['#value']),
                )));
            }
            if (isset($elements['#options']) && isset($elements['#value'])) {
                if ($elements['#type'] == 'select') {
                    $options = form_options_flatten($elements['#options']);
                }
                else {
                    $options = $elements['#options'];
                }
                if (is_array($elements['#value'])) {
                    $value = in_array($elements['#type'], array(
                        'checkboxes',
                        'tableselect',
                    )) ? array_keys($elements['#value']) : $elements['#value'];
                    foreach ($value as $v) {
                        if (!isset($options[$v])) {
                            form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));
                            watchdog('form', 'Illegal choice %choice in !name element.', array(
                                '%choice' => $v,
                                '!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'],
                            ), WATCHDOG_ERROR);
                        }
                    }
                }
                elseif ($elements['#type'] == 'select' && $elements['#required'] && (!array_key_exists('#multiple', $elements) || !$elements['#multiple']) && !isset($elements['#default_value']) && $elements['#value'] === $elements['#empty_value']) {
                    $elements['#value'] = NULL;
                    form_set_value($elements, NULL, $form_state);
                }
                elseif (!isset($options[$elements['#value']])) {
                    form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));
                    watchdog('form', 'Illegal choice %choice in %name element.', array(
                        '%choice' => $elements['#value'],
                        '%name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'],
                    ), WATCHDOG_ERROR);
                }
            }
        }
        // While this element is being validated, it may be desired that some calls
        // to form_set_error() be suppressed and not result in a form error, so
        // that a button that implements low-risk functionality (such as "Previous"
        // or "Add more") that doesn't require all user input to be valid can still
        // have its submit handlers triggered. The triggering element's
        // #limit_validation_errors property contains the information for which
        // errors are needed, and all other errors are to be suppressed. The
        // #limit_validation_errors property is ignored if submit handlers will run,
        // but the element doesn't have a #submit property, because it's too large a
        // security risk to have any invalid user input when executing form-level
        // submit handlers.
        if (isset($form_state['triggering_element']['#limit_validation_errors']) && $form_state['triggering_element']['#limit_validation_errors'] !== FALSE && !($form_state['submitted'] && !isset($form_state['triggering_element']['#submit']))) {
            form_set_error(NULL, '', $form_state['triggering_element']['#limit_validation_errors']);
        }
        elseif (isset($form_state['triggering_element']) && !isset($form_state['triggering_element']['#limit_validation_errors']) && !$form_state['submitted']) {
            form_set_error(NULL, '', array());
        }
        else {
            drupal_static_reset('form_set_error:limit_validation_errors');
        }
        // Make sure a value is passed when the field is required.
        if (isset($elements['#needs_validation']) && $elements['#required']) {
            // A simple call to empty() will not cut it here as some fields, like
            // checkboxes, can return a valid value of '0'. Instead, check the
            // length if it's a string, and the item count if it's an array.
            // An unchecked checkbox has a #value of integer 0, different than string
            // '0', which could be a valid value.
            $is_countable = is_array($elements['#value']) || $elements['#value'] instanceof Countable;
            $is_empty_multiple = $is_countable && count($elements['#value']) == 0;
            $is_empty_string = is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0;
            $is_empty_value = $elements['#value'] === 0;
            $is_empty_null = is_null($elements['#value']);
            if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_null) {
                // Although discouraged, a #title is not mandatory for form elements. In
                // case there is no #title, we cannot set a form error message.
                // Instead of setting no #title, form constructors are encouraged to set
                // #title_display to 'invisible' to improve accessibility.
                if (isset($elements['#title'])) {
                    form_error($elements, $t('!name field is required.', array(
                        '!name' => $elements['#title'],
                    )));
                }
                else {
                    form_error($elements);
                }
            }
        }
        // Call user-defined form level validators.
        if (isset($form_id)) {
            form_execute_handlers('validate', $elements, $form_state);
        }
        elseif (isset($elements['#element_validate'])) {
            foreach ($elements['#element_validate'] as $function) {
                $function($elements, $form_state, $form_state['complete form']);
            }
        }
        $elements['#validated'] = TRUE;
    }
    // Done validating this element, so turn off error suppression.
    // _form_validate() turns it on again when starting on the next element, if
    // it's still appropriate to do so.
    drupal_static_reset('form_set_error:limit_validation_errors');
}

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