diff --git a/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php b/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php index a6755abf2b..f59a3eb66b 100644 --- a/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php +++ b/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php @@ -151,4 +151,27 @@ public function onChange($property_name, $notify = TRUE) { parent::onChange($property_name, $notify); } + /** + * {@inheritdoc} + */ + public function getConstraints() { + $constraint_manager = \Drupal::typedDataManager() + ->getValidationConstraintManager(); + $constraints = parent::getConstraints(); + + if (empty($this->getSetting('optional_end_date'))) { + $label = $this->getFieldDefinition()->getLabel(); + $constraints[] = $constraint_manager + ->create('ComplexData', [ + 'end_value' => [ + 'NotNull' => [ + 'message' => t('The @title end date is required', ['@title' => $label]), + ], + ], + ]); + } + + return $constraints; + } + } diff --git a/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php b/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php index f1f9b2ff4a..772a182462 100644 --- a/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php +++ b/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php @@ -131,17 +131,11 @@ public function validateStartEnd(array &$element, FormStateInterface $form_state $start_date = $element['value']['#value']['object']; $end_date = $element['end_value']['#value']['object']; - if ($start_date instanceof DrupalDateTime) { - if (!$this->getFieldSetting('optional_end_date') && $end_date === NULL) { - $form_state->setError($element['end_value'], $this->t('The @title end date is required', ['@title' => $element['#title']])); - } - - if ($end_date instanceof DrupalDateTime) { - if ($start_date->getTimestamp() !== $end_date->getTimestamp()) { - $interval = $start_date->diff($end_date); - if ($interval->invert === 1) { - $form_state->setError($element, $this->t('The @title end date cannot be before the start date', ['@title' => $element['#title']])); - } + if ($start_date instanceof DrupalDateTime && $end_date instanceof DrupalDateTime) { + if ($start_date->getTimestamp() !== $end_date->getTimestamp()) { + $interval = $start_date->diff($end_date); + if ($interval->invert === 1) { + $form_state->setError($element, $this->t('The @title end date cannot be before the start date', ['@title' => $element['#title']])); } } } diff --git a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php index 658159a8aa..dd0fe93c6b 100644 --- a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php +++ b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php @@ -103,4 +103,41 @@ public function testDateOnly() { $this->assertEquals('12:00:00', $end_date->format('H:i:s')); } + /** + * Test optional end date. + */ + public function testOptionalEndDate() { + $field_name = $this->fieldStorage->getName(); + + $this->fieldStorage->setSettings([ + 'datetime_type' => DateRangeItem::DATETIME_TYPE_DATE, + 'optional_end_date' => FALSE, + ]) + ->save(); + + $value = [ + 'value' => '2016-09-21', + 'end_value' => NULL, + ]; + + // Verify entity without optional_end_date enabled. + $entity = EntityTest::create([ + 'name' => $this->randomString(), + $field_name => $value, + ]); + $this->assertNotEqual(count($entity->validate()), 0); + + // Verify entity with the optional_end_date enabled. + $this->fieldStorage->setSetting('optional_end_date', TRUE) + ->save(); + $entity = EntityTest::create([ + 'name' => $this->randomString(), + $field_name => $value, + ]); + $this->entityValidateAndSave($entity); + + // Verify changing the date value. + $this->assertEqual($entity->{$field_name}->end_value, $value['end_value']); + } + }