You are here

function date_repeat_field_widget_validate in Date 8

Same name and namespace in other branches
  1. 7.3 date_repeat_field/date_repeat_field.module \date_repeat_field_widget_validate()
  2. 7.2 date_repeat_field/date_repeat_field.module \date_repeat_field_widget_validate()

Validation for date repeat form element.

Create multiple values from the RRULE results. Lots more work needed here.

1 string reference to 'date_repeat_field_widget_validate'
date_repeat_field_field_widget_form_alter in date_repeat_field/date_repeat_field.module
Implements hook_field_widget_form_alter().

File

date_repeat_field/date_repeat_field.module, line 288
Creates the option of Repeating date fields and manages Date fields that use the Date Repeat API.

Code

function date_repeat_field_widget_validate($element, &$form_state) {
  $field = field_widget_field($element, $form_state);
  if (empty($field['settings']['repeat'])) {
    return;
  }
  $field_name = $element['#field_name'];
  $delta = $element['#delta'];
  $langcode = $element['#language'];

  // If the widget has been hidden by #access, the RRULE will still be in its
  // original string form here. Nothing to process.
  if (date_hidden_element($element)) {

    // If this was a hidden repeating date, we lost all the repeating values in the widget processing.
    // Add them back here if that happened since we are skipping the re-creation of those values.
    if (!empty($form_state['storage']['date_items'][$field_name])) {
      array_pop($element['#parents']);
      form_set_value($element, $form_state['storage']['date_items'][$field_name][$langcode], $form_state);
    }
    return;
  }
  module_load_include('inc', 'date_repeat', 'date_repeat_form');
  $instance = field_widget_instance($element, $form_state);

  // Here 'values' returns an array of input values, which includes the original RRULE, as a string.
  // and 'input' returns an array of the form elements created by the repeating date widget, with
  // RRULE values as an array of the selected elements and their chosen values.
  $item = drupal_array_get_nested_value($form_state['values'], $element['#parents'], $input_exists);
  $input = drupal_array_get_nested_value($form_state['input'], $element['#parents'], $input_exists);
  $rrule_values = date_repeat_merge($input['rrule'], $element['rrule']);

  // If no repeat information was set, treat this as a normal, non-repeating value.
  if ($rrule_values['FREQ'] == 'NONE' || empty($input['show_repeat_settings'])) {
    $item['rrule'] = NULL;
    form_set_value($element, $item, $form_state);
    return;
  }

  // If no start date was set, clean up the form and return.
  if (empty($item['value'])) {
    form_set_value($element, NULL, $form_state);
    return;
  }

  // Require the UNTIL date for now.
  // The RRULE has already been created by this point, so go back
  // to the posted values to see if this was filled out.
  $error_field_base = implode('][', $element['#parents']);
  $error_field_until = $error_field_base . '][rrule][until_child][datetime][';
  if (!empty($item['rrule']) && $rrule_values['range_of_repeat'] === 'UNTIL' && empty($rrule_values['UNTIL']['datetime'])) {
    switch ($instance['widget']['type']) {
      case 'date_popup':
        form_set_error($error_field_until . 'date', t("Missing value in 'Range of repeat'. (UNTIL).", array(), array(
          'context' => 'Date repeat',
        )));
        break;
      case 'date_select':
        form_set_error($error_field_until . 'year', t("Missing value in 'Range of repeat': Year (UNTIL)", array(), array(
          'context' => 'Date repeat',
        )));
        form_set_error($error_field_until . 'month', t("Missing value in 'Range of repeat': Month (UNTIL)", array(), array(
          'context' => 'Date repeat',
        )));
        form_set_error($error_field_until . 'day', t("Missing value in 'Range of repeat': Day (UNTIL)", array(), array(
          'context' => 'Date repeat',
        )));
        break;
    }
  }
  $error_field_count = $error_field_base . '][rrule][count_child';
  if (!empty($item['rrule']) && $rrule_values['range_of_repeat'] === 'COUNT' && empty($rrule_values['COUNT'])) {
    form_set_error($error_field_count, t("Missing value in 'Range of repeat'. (COUNT).", array(), array(
      'context' => 'Date repeat',
    )));
  }
  if (form_get_errors()) {
    return;
  }

  // If the rule, the start date, or the end date have changed, re-calculate
  // the repeating dates, wipe out the previous values, and populate the
  // field with the new values.
  $rrule = $item['rrule'];
  if (!empty($rrule)) {

    // Avoid undefined index problems on dates that don't have all parts.
    $possible_items = array(
      'value',
      'value2',
      'timezone',
      'offset',
      'offset2',
    );
    foreach ($possible_items as $key) {
      if (empty($item[$key])) {
        $item[$key] = '';
      }
    }

    // We only collect a date for UNTIL, but we need it to be inclusive,
    // so force it to a full datetime element at the last possible second of the day.
    if (!empty($rrule_values['UNTIL'])) {
      $rrule_values['UNTIL']['datetime'] .= ' 23:59:59';
      $rrule_values['UNTIL']['granularity'] = serialize(drupal_map_assoc(array(
        'year',
        'month',
        'day',
        'hour',
        'minute',
        'second',
      )));
      $rrule_values['UNTIL']['all_day'] = 0;
    }
    $value = date_repeat_build_dates($rrule, $rrule_values, $field, $item);

    // Unset the delta value of the parents.
    array_pop($element['#parents']);

    // Set the new delta values for this item to the array of values returned by the repeat rule.
    form_set_value($element, $value, $form_state);
  }
}