1 date.elements.inc date_html5_element_validate(array $element, array &$form_state)

Element validation callback for the HTML5 widget.

This runs once over the whole value array.

Parameters

array $element: Form element structure.

array $form_state: The form state of this form submission.

File

core/modules/date/date.elements.inc, line 1850
Date forms and form themes and validation.

Code

function date_html5_element_validate(array $element, array &$form_state) {
  $field_name = $element['#field_name'];

  if (!empty(backdrop_array_get_nested_value($form_state['values'], $element['#parents']))) {
    $values = array();
    $trimmed_parents = array_slice($element['#parents'], 0, -1);
    $items = backdrop_array_get_nested_value($form_state['values'], $trimmed_parents);
    $field_type = $element['#field_type'];
    $field_label = $element['#field_label'];

    foreach ($items as $delta => $date_values) {
      if (is_string($date_values)) {
        // "Add another" or something else, unusable.
        continue;
      }
      array_pop($element['#parents']);
      array_push($element['#parents'], $delta);
      $item_parents = implode('][', $element['#parents']);
      $multi_value = (count($items) > 1);

      $date_only = (is_string($date_values['value']) && strlen($date_values['value']) == 10);
      if ($date_only) {
        $start = $date_values['value'];
        $date_values['value'] = array(
          'date' => $start,
        );
      }

      if (empty($date_values['value']['date'])) {
        if (!empty($element['value']['#required']) && $delta < 1) {
          if ($multi_value) {
            form_set_error($item_parents . '][value', t('A start date for value #1 is required in %field.', array(
              '%field' => $field_label,
            )));
          }
          else {
            form_set_error($item_parents . '][value', t('A start date is required in %field.', array(
              '%field' => $field_label,
            )));
          }
        }
        // Value has been emptied.
        continue;
      }

      // Timezone from submission or fallback to default value.
      $timezone = $element['value']['#date_timezone'];
      $timezone_db = $element['value']['#timezone_db'];
      if (!empty($date_values['timezone'])) {
        // @see Core bfad032030, where the same problem strikes.
        if (is_array($date_values['timezone'])) {
          $timezone = $date_values['timezone']['timezone'];
        }
        else {
          $timezone = $date_values['timezone'];
        }
      }
      // Also save timezone to db.
      $values[$delta]['timezone'] = $timezone;

      $string = implode(' ', array_values($date_values['value']));
      // The validation of inner form items has happened, so we can rely on the
      // given values to construct a valid date.
      $date = new BackdropDateTime($string, $timezone);

      // Build dates with the same timezone and compare to limit range.
      if (!empty($element['value']['#min'])) {
        $min_date = new BackdropDateTime($element['value']['#min'], $timezone);
        if ($date < $min_date) {
          if ($multi_value) {
            form_set_error($item_parents . '][value', t('The date of value #!delta in %field may not be before @date.', array(
              '!delta' => $delta + 1,
              '%field' => $field_label,
              '@date' => $element['value']['#min'],
            )));
          }
          else {
            form_set_error($item_parents . '][value', t('The date in %field may not be before @date.', array(
              '%field' => $field_label,
              '@date' => $element['value']['#min'],
            )));
          }
        }
      }
      if (!empty($element['value']['#max'])) {
        $max_date = new BackdropDateTime($element['value']['#max'], $timezone);
        if ($date > $max_date) {
          if ($multi_value) {
            form_set_error($item_parents . '][value', t('The date of value #!delta in %field may not be after @date.', array(
              '!delta' => $delta + 1,
              '%field' => $field_label,
              '@date' => $element['value']['#max'],
            )));
          }
          else {
            form_set_error($item_parents . '][value', t('The date in %field may not be after @date.', array(
              '%field' => $field_label,
              '@date' => $element['value']['#max'],
            )));
          }
        }
      }

      $values[$delta]['offset'] = $date->getOffset();
      // We captured the offset, now we switch to the timezone the date field
      // expects.
      $date->setTimezone(new DateTimeZone($timezone_db));
      $values[$delta]['value'] = _date_html5_format_value_db($date, $field_type);

      if (!empty($date_values['value2']) && $date_only) {
        $end = $date_values['value2'];
        $date_values['value2'] = array(
          'date' => $end,
        );
      }
      if (!empty($date_values['value2']['date'])) {
        $string2 = implode(' ', array_values($date_values['value2']));
        $date2 = new BackdropDateTime($string2, $timezone);
        // Compare to limit range, if set.
        if (isset($min_date) && $date2 < $min_date) {
          if ($multi_value) {
            form_set_error($item_parents . '][value2', t('The end date of value #!delta in %field may not be before @date.', array(
              '!delta' => $delta + 1,
              '%field' => $field_label,
              '@date' => $element['value']['#min'],
            )));
          }
          else {
            form_set_error($item_parents . '][value2', t('The end date in %field may not be before @date.', array(
              '%field' => $field_label,
              '@date' => $element['value']['#min'],
            )));
          }
        }
        if (isset($max_date) && $date2 > $max_date) {
          if ($multi_value) {
            form_set_error($item_parents . '][value2', t('The end date of value #!delta in %field may not be after @date.', array(
              '!delta' => $delta + 1,
              '%field' => $field_label,
              '@date' => $element['value']['#max'],
            )));
          }
          else {
            form_set_error($item_parents . '][value2', t('The end date in %field may not be after @date.', array(
              '%field' => $field_label,
              '@date' => $element['value']['#max'],
            )));
          }
        }
        $values[$delta]['offset2'] = $date2->getOffset();
        $date2->setTimezone(new DateTimeZone($timezone_db));
        $values[$delta]['value2'] = _date_html5_format_value_db($date2, $field_type);
        if ($date2 <= $date) {
          if ($multi_value) {
            form_set_error($item_parents . '][value2', t('The end date of value #!delta in %field must be greater than the start date.', array(
              '!delta' => ($delta + 1),
              '%field' => $field_label,
            )));
          }
          else {
            form_set_error($item_parents . '][value2', t('The end date in %field must be greater than the start date.', array(
              '%field' => $field_label,
            )));
          }
        }
      }
      else {
        if (!empty($element['value2']['#required']) && $delta < 1) {
          if ($multi_value) {
            form_set_error($item_parents . '][value2', t('An end date for value #1 is required in %field.', array(
              '%field' => $field_label,
            )));
          }
          else {
            form_set_error($item_parents . '][value2', t('An end date is required in %field.', array(
              '%field' => $field_label,
            )));
          }
        }
        // Function date_field_validate chokes otherwise.
        $values[$delta]['value2'] = NULL;
      }
    }

    // Override the value to what date fields expect.
    backdrop_array_set_nested_value($form_state['values'], $trimmed_parents, $values);
  }
}