Unverified Commit 6c481f74 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3269890 by prudloff, smustgrave, catch, shalini_jha, alexpott, oily:...

Issue #3269890 by prudloff, smustgrave, catch, shalini_jha, alexpott, oily: #date_year_range is not validated server-side

(cherry picked from commit 2558bc86)
parent caef5894
Loading
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -389,8 +389,22 @@ public static function validateDatetime(&$element, FormStateInterface $form_stat
        // If the date is valid, set it.
        $date = $input['object'];
        if ($date instanceof DrupalDateTime && !$date->hasErrors()) {
          $range = static::datetimeRangeYears($element['#date_year_range']);
          $min = DrupalDateTime::createFromArray(['year' => $range[0]], $date->getTimezone());
          $max = DrupalDateTime::createFromArray(['year' => $range[1] + 1], $date->getTimezone());

          // Validate the date. It's valid if it's within the valid year range.
          if ($date->getTimestamp() < $min->getTimestamp() || $date->getTimestamp() >= $max->getTimestamp()) {
            $form_state->setError(
              $element,
              t('The %field date is invalid. Date should be in the %min-%max year range.',
                ['%field' => $title, '%min' => $range[0], '%max' => $range[1]])
            );
          }
          else {
            $form_state->setValueForElement($element, $date);
          }
        }
        // If the date is invalid, set an error. A reminder of the required
        // format in the message provides a good UX.
        else {
+56 −0
Original line number Diff line number Diff line
@@ -99,6 +99,17 @@ public function buildForm(array $form, FormStateInterface $form_state, string $d
      '#date_time_element' => 'HTML Time',
    ];

    // Element with a year range.
    $form['range_datetime_element'] = [
      '#title' => 'range_datetime_element',
      '#type' => 'datetime',
      '#date_date_format' => 'Y-m-d',
      '#date_time_format' => 'H:i:s',
      '#date_date_element' => 'HTML Date',
      '#date_time_element' => 'HTML Time',
      '#date_year_range' => '1850:3000',
    ];

    // Element with #required_error.
    $form['datetime_required_error'] = [
      '#type' => 'datetime',
@@ -223,6 +234,51 @@ public function testTimezoneHandling(): void {
    $this->assertEquals('UTC', $form['datetime_element']['#date_timezone']);
  }

  /**
   * Tests that year range is validated.
   */
  public function testRangeValidate(): void {
    // Tests with a date after maximum.
    $formState = new FormState();
    $formState->setValue(['range_datetime_element', 'date'], '4000-01-01');
    $formState->setValue(['range_datetime_element', 'time'], '10:10');
    $form = \Drupal::formBuilder()->getForm($this);
    \Drupal::formBuilder()->submitForm($this, $formState);
    $this->assertEquals(
      'The range_datetime_element date is invalid. Date should be in the 1850-3000 year range.',
      $formState->getError($form['range_datetime_element'])
    );

    // Tests with a date before minimum.
    $formState = new FormState();
    $formState->setValue(['range_datetime_element', 'date'], '1000-01-01');
    $formState->setValue(['range_datetime_element', 'time'], '10:10');
    $form = \Drupal::formBuilder()->getForm($this);
    \Drupal::formBuilder()->submitForm($this, $formState);
    $this->assertEquals(
      'The range_datetime_element date is invalid. Date should be in the 1850-3000 year range.',
      $formState->getError($form['range_datetime_element'])
    );

    // Tests with a date barely outside range.
    $formState = new FormState();
    $formState->setValue(['range_datetime_element', 'date'], '3001-01-01');
    $formState->setValue(['range_datetime_element', 'time'], '00:00');
    $form = \Drupal::formBuilder()->getForm($this);
    \Drupal::formBuilder()->submitForm($this, $formState);
    $this->assertEquals(
      'The range_datetime_element date is invalid. Date should be in the 1850-3000 year range.',
      $formState->getError($form['range_datetime_element'])
    );

    // Tests with a date inside range.
    $formState = new FormState();
    $formState->setValue(['range_datetime_element', 'date'], '2000-01-01');
    $formState->setValue(['range_datetime_element', 'time'], '10:10');
    \Drupal::formBuilder()->submitForm($this, $formState);
    $this->assertEmpty($formState->getError($form['range_datetime_element']));
  }

  /**
   * {@inheritdoc}
   */