You are here

public static function DateRecurModularOscarWidget::validateModularWidget in Recurring Date Field Modular Widgets 3.x

Same name and namespace in other branches
  1. 8 src/Plugin/Field/FieldWidget/DateRecurModularOscarWidget.php \Drupal\date_recur_modular\Plugin\Field\FieldWidget\DateRecurModularOscarWidget::validateModularWidget()
  2. 2.x src/Plugin/Field/FieldWidget/DateRecurModularOscarWidget.php \Drupal\date_recur_modular\Plugin\Field\FieldWidget\DateRecurModularOscarWidget::validateModularWidget()

Validates the widget.

Parameters

array $element: The element.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

array $complete_form: The complete form structure.

File

src/Plugin/Field/FieldWidget/DateRecurModularOscarWidget.php, line 322

Class

DateRecurModularOscarWidget
Date recur opening hours widget.

Namespace

Drupal\date_recur_modular\Plugin\Field\FieldWidget

Code

public static function validateModularWidget(array &$element, FormStateInterface $form_state, array &$complete_form) : void {

  /** @var string|null $dayStartString */
  $dayStartString = $form_state
    ->getValue(array_merge($element['#parents'], [
    'day_start',
  ]));
  $timeStartString = $form_state
    ->getValue(array_merge($element['#parents'], [
    'times',
    'time_start',
  ]), '');
  $timeEndString = $form_state
    ->getValue(array_merge($element['#parents'], [
    'times',
    'time_end',
  ]), '');
  $hasAnyDateTimeInput = !empty($dayStartString) || !empty($timeStartString) || !empty($timeEndString);
  if (!$hasAnyDateTimeInput) {

    // Skip if all of date and times are empty.
    $form_state
      ->setValueForElement($element['day_start'], NULL);
    $form_state
      ->setValueForElement($element['times']['time_start'], NULL);
    $form_state
      ->setValueForElement($element['times']['time_end'], NULL);
    return;
  }

  /** @var string|null $timeZone */
  $timeZone = $form_state
    ->getValue(array_merge($element['#parents'], [
    'time_zone',
  ]));
  if (empty($timeZone)) {
    $form_state
      ->setError($element['end'], \t('Time zone must be set.'));
    return;
  }

  // Create base day object.
  try {
    $baseDay = DrupalDateTime::createFromFormat('Y-m-d', $dayStartString, $timeZone);
    $baseDay
      ->setTime(0, 0, 0);
    $baseDayParts = explode('-', $baseDay
      ->format('Y-n-j'));
  } catch (\Exception $e) {
    $form_state
      ->setError($element['day_start'], \t('Invalid start day.'));
    return;
  }
  $isAllDay = $form_state
    ->getValue(array_merge($element['#parents'], [
    'is_all_day',
  ])) === static::IS_ALL_DAY_ALL;
  if ($isAllDay) {
    $startDate = (clone $baseDay)
      ->setTime(0, 0, 0);
    $endDate = (clone $baseDay)
      ->setTime(23, 59, 59);
  }
  else {

    // When time is POST'ed with 00 seconds, the entire part is missing.
    // Restore it here.
    $fixTime = function (string $time) : string {

      // See also \Drupal\Core\Datetime\Element\Datetime::valueCallback.
      // Seconds will be omitted in a post in case there's no entry.
      if (!empty($time) && strlen($time) == 5) {
        $time .= ':00';
      }
      return $time;
    };
    try {
      $timeStartString = $fixTime($timeStartString);
      $startDate = DrupalDateTime::createFromFormat(static::HTML_TIME_FORMAT, $timeStartString, $timeZone);
      $startDate
        ->setDate(...$baseDayParts);
    } catch (\Exception $e) {
      $form_state
        ->setValueForElement($element['times']['time_start'], NULL);
      $form_state
        ->setError($element['times']['time_start'], \t('Invalid start time.'));
      return;
    }
    try {
      $timeEndString = $fixTime($timeEndString);
      $endDate = DrupalDateTime::createFromFormat(static::HTML_TIME_FORMAT, $timeEndString, $timeZone);
      $endDate
        ->setDate(...$baseDayParts);
    } catch (\Exception $e) {
      $form_state
        ->setValueForElement($element['times']['time_end'], NULL);
      $form_state
        ->setError($element['times']['time_end'], \t('Invalid end time.'));
      return;
    }
  }
  if ($endDate
    ->getPhpDateTime() < $startDate
    ->getPhpDateTime()) {
    $form_state
      ->setError($element['times']['time_end'], 'End time must be after start time.');
  }
  $form_state
    ->setValueForElement($element['times']['time_start'], $startDate);
  $form_state
    ->setValueForElement($element['times']['time_end'], $endDate);
}