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 f0f93259d3..f4765d37d5 100644 --- a/core/modules/datetime_range/config/schema/datetime_range.schema.yml +++ b/core/modules/datetime_range/config/schema/datetime_range.schema.yml @@ -5,6 +5,10 @@ field.storage_settings.daterange: type: field.storage_settings.datetime label: 'Date range settings' + mapping: + optional_end_date: + type: boolean + label: 'Optional end date' field.field_settings.daterange: type: field.field_settings.datetime diff --git a/core/modules/datetime_range/src/DateTimeRangeTrait.php b/core/modules/datetime_range/src/DateTimeRangeTrait.php index 3f05b82189..806e93ff98 100644 --- a/core/modules/datetime_range/src/DateTimeRangeTrait.php +++ b/core/modules/datetime_range/src/DateTimeRangeTrait.php @@ -17,13 +17,13 @@ public function viewElements(FieldItemListInterface $items, $langcode) { $separator = $this->getSetting('separator'); foreach ($items as $delta => $item) { - if (!empty($item->start_date) && !empty($item->end_date)) { + if (!empty($item->start_date)) { /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */ $start_date = $item->start_date; /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */ $end_date = $item->end_date; - if ($start_date->getTimestamp() !== $end_date->getTimestamp()) { + if ($end_date !== NULL && $start_date->getTimestamp() !== $end_date->getTimestamp()) { $elements[$delta] = [ 'start_date' => $this->buildDateWithIsoAttribute($start_date), 'separator' => ['#plain_text' => ' ' . $separator . ' '], 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 7c34ed127c..a6755abf2b 100644 --- a/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php +++ b/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php @@ -24,6 +24,15 @@ */ class DateRangeItem extends DateTimeItem { + /** + * {@inheritdoc} + */ + public static function defaultStorageSettings() { + return [ + 'optional_end_date' => FALSE, + ] + parent::defaultStorageSettings(); + } + /** * Value for the 'datetime_type' setting: store a date and time. */ @@ -44,9 +53,10 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel ->setClass(DateTimeComputed::class) ->setSetting('date source', 'value'); + // @todo Write a comment on why we can't use the $field_definition here. $properties['end_value'] = DataDefinition::create('datetime_iso8601') ->setLabel(t('End date value')) - ->setRequired(TRUE); + ->setRequired(FALSE); $properties['end_date'] = DataDefinition::create('any') ->setLabel(t('Computed end date')) @@ -83,6 +93,12 @@ public function storageSettingsForm(array &$form, FormStateInterface $form_state $element['datetime_type']['#options'][static::DATETIME_TYPE_ALLDAY] = $this->t('All Day'); + $element['optional_end_date'] = [ + '#type' => 'checkbox', + '#title' => t('Optional end date'), + '#default_value' => $this->getSetting('optional_end_date'), + ]; + return $element; } @@ -94,6 +110,7 @@ public static function generateSampleValue(FieldDefinitionInterface $field_defin // Just pick a date in the past year. No guidance is provided by this Field // type. + // @todo Do we need to update this? $start = REQUEST_TIME - mt_rand(0, 86400 * 365) - 86400; $end = $start + 86400; if ($type == static::DATETIME_TYPE_DATETIME) { @@ -112,6 +129,10 @@ public static function generateSampleValue(FieldDefinitionInterface $field_defin */ public function isEmpty() { $start_value = $this->get('value')->getValue(); + if ($this->getFieldDefinition()->getFieldStorageDefinition()->getSetting('optional_end_date')) { + return $start_value === NULL || $start_value === ''; + } + $end_value = $this->get('end_value')->getValue(); return ($start_value === NULL || $start_value === '') && ($end_value === NULL || $end_value === ''); } 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 85fda9ba53..996b71c456 100644 --- a/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php +++ b/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php @@ -19,6 +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'); // Wrap all of the select elements with a fieldset. $element['#theme_wrappers'][] = 'fieldset'; @@ -27,9 +28,13 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen $element['value']['#title'] = $this->t('Start date'); $element['end_value'] = [ - '#title' => $this->t('End date'), + '#title' => $optional_end_date ? $this->t('End date (optional)'): $this->t('End date'), ] + $element['value']; + if ($element['#required'] && $optional_end_date) { + $element['end_value']['#required'] = FALSE; + } + if ($items[$delta]->start_date) { /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */ $start_date = $items[$delta]->start_date;