4.7.x form.inc _form_validate($elements, $form_id = NULL)
5.x form.inc _form_validate($elements, $form_id = NULL)
6.x form.inc _form_validate($elements, &$form_state, $form_id = NULL)
7.x form.inc _form_validate(&$elements, &$form_state, $form_id = NULL)

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_submision'] = $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 from the $form_state using the validate functions defined in a structured form array.

File

includes/form.inc, line 721

Code

function _form_validate($elements, &$form_state, $form_id = NULL) {
  static $complete_form;

  // 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']) {
    if (isset($elements['#needs_validation'])) {
      // Make sure a value is passed when the field is 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.
      if ($elements['#required'] && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0))) {
        form_error($elements, $t('!name field is required.', array('!name' => $elements['#title'])));
      }

      // Verify that the value is not longer than #maxlength.
      if (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 = $elements['#type'] == 'checkboxes' ? array_keys(array_filter($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 (!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);
        }
      }
    }

    // Call user-defined form level validators and store a copy of the full
    // form so that element-specific validators can examine the entire structure
    // if necessary.
    if (isset($form_id)) {
      form_execute_handlers('validate', $elements, $form_state);
      $complete_form = $elements;
    }
    // Call any element-specific validators. These must act on the element
    // #value data.
    elseif (isset($elements['#element_validate'])) {
      foreach ($elements['#element_validate'] as $function) {
        if (function_exists($function)) {
          $function($elements, $form_state, $complete_form);
        }
      }
    }
    $elements['#validated'] = TRUE;
  }
}

Comments

drastik’s picture

Why isn't the !is_array() check done before trying to get strlen on a potential array? I get an error when using Min / Max Views exposed filters that also have a maxlength attribute because of this.

What's wrong with:

if (isset($elements['#maxlength']) && !is_array($elements['#value']) && drupal_strlen($elements['#value']) > $elements['#maxlength']) {

Or going to further measures to handle it even better (iterate and check the array contents strlen)?