diff --git a/core/modules/datetime_range/config/schema/datetime_range.schema.yml b/core/modules/datetime_range/config/schema/datetime_range.schema.yml index 921010b2bb74f7279b5b8e8a5e1120d98fe2cc04..7900a35ce5d2f07de4475cc48dcb27701f99f702 100644 --- a/core/modules/datetime_range/config/schema/datetime_range.schema.yml +++ b/core/modules/datetime_range/config/schema/datetime_range.schema.yml @@ -7,12 +7,12 @@ field.storage_settings.daterange: label: 'Date range settings' field.field_settings.daterange: - type: field.field_settings.datetime + type: mapping label: 'Date range settings' mapping: - optional_end_date: - type: boolean - label: 'Optional end date' + optional_values: + type: integer + label: 'Optional values' field.value.daterange: type: mapping 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 9c5184ddcad377ff18c6a1336638f505d0ab2ee3..18bc48834ece8d7f8791327f3975d7d52f5d51c1 100644 --- a/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php +++ b/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php @@ -29,7 +29,7 @@ class DateRangeItem extends DateTimeItem { */ public static function defaultFieldSettings() { return [ - 'optional_end_date' => FALSE, + 'optional_values' => FALSE, ] + parent::defaultFieldSettings(); } @@ -38,6 +38,16 @@ public static function defaultFieldSettings() { */ const DATETIME_TYPE_ALLDAY = 'allday'; + /** + * Optional values setting, require a bounded datetime range. + */ + const OPTIONAL_NONE = 0x01; + + /** + * Optional values setting, do not require an end date. + */ + const OPTIONAL_END = 0x02; + /** * {@inheritdoc} */ @@ -89,11 +99,15 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) */ public function fieldSettingsForm(array $form, FormStateInterface $form_state) { $element = []; - $element['optional_end_date'] = [ - '#type' => 'checkbox', - '#title' => $this->t('Optional end date'), - '#description' => $this->t('Allow end date to be optional opposed to the default behaviour where end date is required when "Required field" is checked.'), - '#default_value' => $this->getSetting('optional_end_date'), + $element['optional_values'] = [ + '#type' => 'radios', + '#title' => $this->t('End date'), + '#description' => $this->t('Applies regardless of whether the whole field is required'), + '#default_value' => $this->getSetting('optional_values'), + '#options' => [ + static::OPTIONAL_NONE => $this->t('Required'), + static::OPTIONAL_END => $this->t('Optional end date'), + ], ]; return $element; @@ -151,19 +165,29 @@ public function getConstraints() { ->getValidationConstraintManager(); $constraints = parent::getConstraints(); - if (!empty($this->getSetting('optional_end_date'))) { - return $constraints; - } - - $label = $this->getFieldDefinition()->getLabel(); - $constraints[] = $constraint_manager - ->create('ComplexData', [ - 'end_value' => [ - 'NotNull' => [ - 'message' => $this->t('The @title end date is required', ['@title' => $label]), + if (!$this->getFieldDefinition()->isRequired()) { + $label = $this->getFieldDefinition()->getLabel(); + // If the end date triggers constraint validation then test the start date. + $constraints[] = $constraint_manager + ->create('ComplexData', [ + 'value' => [ + 'NotNull' => [ + 'message' => $this->t('The @title start date is required', ['@title' => $label]), + ], ], - ], - ]); + ]); + // Testing the end date is only needed if not required and not optional. + if ($this->getSetting('optional_values') == static::OPTIONAL_NONE) { + $constraints[] = $constraint_manager + ->create('ComplexData', [ + 'end_value' => [ + 'NotNull' => [ + 'message' => $this->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 ee894f56da493d7e54c0b5f8e3cb19fdf71df9e6..a5de90790394141abeedd8ee41df91e623950804 100644 --- a/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php +++ b/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php @@ -19,7 +19,7 @@ class DateRangeWidgetBase extends DateTimeWidgetBase { */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $element = parent::formElement($items, $delta, $element, $form, $form_state); - $optional_end_date = $this->getFieldSetting('optional_end_date'); + $optional_values = $this->getFieldSetting('optional_values'); // Wrap all of the select elements with a fieldset. $element['#theme_wrappers'][] = 'fieldset'; @@ -31,7 +31,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#title' => $this->t('End date'), ] + $element['value']; - if ($element['#required'] && $optional_end_date) { + if ($element['#required'] && $optional_values == DateRangeItem::OPTIONAL_END) { $element['end_value']['#required'] = FALSE; $element['#required'] = FALSE; } diff --git a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php index 4a8cb580157930c91714a9e3946ec532942e7b8b..a7e5b174997334aaa8303f29d08659d197250fcf 100644 --- a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php +++ b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php @@ -110,7 +110,7 @@ public function testOptionalEndDate() { $field_name = $this->fieldStorage->getName(); $this->field->setSettings([ - 'optional_end_date' => FALSE, + 'optional_values' => DateRangeItem::OPTIONAL_NONE, ]) ->save(); @@ -126,7 +126,7 @@ public function testOptionalEndDate() { $this->assertNotEquals(count($entity->validate()), 0); // Verify entity with the optional_end_date enabled. - $this->field->setSetting('optional_end_date', TRUE) + $this->field->setSetting('optional_values', DateRangeItem::OPTIONAL_END) ->save(); $entity = EntityTest::create([ 'name' => $this->randomString(),