You are here

function _webform_client_form_validate in Webform 7.4

Same name and namespace in other branches
  1. 6.3 webform.module \_webform_client_form_validate()
  2. 7.3 webform.module \_webform_client_form_validate()

Recursive validation function to trigger normal Drupal validation.

This function imitates _form_validate in Drupal's form.inc, only it sets a different property to ensure that validation has occurred.

1 call to _webform_client_form_validate()
webform_client_form_validate in ./webform.module
Form API #validate handler for the webform_client_form() form.

File

./webform.module, line 3045
This module provides a simple way to create forms and questionnaires.

Code

function _webform_client_form_validate(&$elements, &$form_state, $form_id = NULL, $input_values = NULL) {
  if (isset($input_values) && isset($elements['#webform_component'])) {
    $sorter = webform_get_conditional_sorter($form_state['complete form']['#node']);
    $cid = $elements['#webform_component']['cid'];
    $page_num = $form_state['values']['details']['page_num'];

    // Webform-specific enhancements:
    // 1. Only validate the field if it was used in this submission.
    //    This both skips validation on the field and sets the value of the
    //    field to NULL, preventing any dangerous input. Short-circuit
    //    validation for a hidden component (hidden by rules dependent upon
    //    component on previous pages), or a component this is dependent upon
    //    values on the current page, but is hidden based upon their current
    //    values.
    // 2. Only validate if the field has not been set by conditionals.
    //    The user will be unable to fix the validation without surmising the
    //    logic and changing the trigger for the conditional. Also, it isn't
    //    possible to set $element['#value'] without component-specific
    //    knowledge of how the data is stored because $input_values is already
    //    webform-normalized to contain values in arrays.
    if ($sorter
      ->componentVisibility($cid, $page_num) != WebformConditionals::componentShown) {
      form_set_value($elements, NULL, $form_state);
      return;
    }
    if ($sorter
      ->componentSet($cid, $page_num)) {
      $component = $elements['#webform_component'];
      $value = $input_values[$cid];
      $value = is_array($value) ? $value[0] : $value;

      // webform_component_invoke cannot be called with reference arguments.
      // Call directly.
      // webform_component_invoke($component['type'], 'action_set', $component,
      // $elements, $form_state, $value);.
      $function = '_webform_action_set_' . $component['type'];
      $function($component, $elements, $form_state, $value);
    }

    // Check for changes in required status made by conditionals.
    $required = $sorter
      ->componentRequired($cid, $page_num);
    if (isset($required)) {
      $elements['#required'] = $required;

      // Some components, for example, grids, have nested sub-elements. Extend
      // required to any sub-components.
      foreach (element_children($elements) as $key) {
        if (isset($elements[$key]) && $elements[$key] && !isset($elements[$key]['#webform_component'])) {

          // Child is *not* a component.
          $elements[$key]['#required'] = $required;
        }
      }
    }
  }

  // Recurse through all children.
  foreach (element_children($elements) as $key) {
    if (isset($elements[$key]) && $elements[$key]) {
      _webform_client_form_validate($elements[$key], $form_state, NULL, $input_values);
    }
  }

  // Validate the current input.
  if (isset($elements['#webform_validated']) && !$elements['#webform_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 if it's an array whether it is empty. For
      // radios, FALSE means that no value was submitted, so check that too.
      $value_is_empty_string = is_string($elements['#value']) && strlen(trim($elements['#value'])) === 0;
      $value_is_empty_array = is_array($elements['#value']) && !$elements['#value'];
      if ($elements['#required'] && ($value_is_empty_string || $value_is_empty_array || $elements['#value'] === FALSE || $elements['#value'] === NULL)) {
        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']),
        )));
      }

      // Verify that the value is not shorter than #minlength. The value may
      // still be empty (required is a separate validation option).
      if (isset($elements['#minlength'])) {
        $length = drupal_strlen($elements['#value']);
        if ($length > 0 && $length < $elements['#minlength']) {
          form_error($elements, t('!name cannot be shorter than %min characters but is currently %length characters long.', array(
            '!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'],
            '%min' => $elements['#minlength'],
            '%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 ($elements['#value'] !== '' && !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.
    if (isset($form_id)) {
      form_execute_handlers('validate', $elements, $form_state);
    }
    elseif (isset($elements['#element_validate'])) {
      foreach ($elements['#element_validate'] as $function) {
        if (is_callable($function)) {
          $function($elements, $form_state, $form_state['complete form']);
        }
      }
    }
    $elements['#webform_validated'] = TRUE;
  }
}