Skip to content
Snippets Groups Projects
Commit 4192e7d2 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2302047 by plopesc: Added support for relative default dates in Date field .

parent 6cffdfa1
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
......@@ -21,6 +21,8 @@ field.datetime.value:
- type: sequence
label: 'Default value'
sequence:
- type: string
label: 'Type'
- type: string
label: 'Value'
......
......@@ -23,6 +23,11 @@ class DateTimeFieldItemList extends FieldItemList {
*/
const DEFAULT_VALUE_NOW = 'now';
/**
* Defines the default value as relative.
*/
const DEFAULT_VALUE_CUSTOM = 'relative';
/**
* {@inheritdoc}
*/
......@@ -32,13 +37,27 @@ public function defaultValuesForm(array &$form, FormStateInterface $form_state)
$element = array(
'#parents' => array('default_value_input'),
'default_date' => array(
'default_date_type' => array(
'#type' => 'select',
'#title' => t('Default date'),
'#description' => t('Set a default value for this date.'),
'#default_value' => isset($default_value[0]['default_date']) ? $default_value[0]['default_date'] : '',
'#options' => array(static::DEFAULT_VALUE_NOW => t('The current date')),
'#default_value' => isset($default_value[0]['default_date_type']) ? $default_value[0]['default_date_type'] : '',
'#options' => array(
static::DEFAULT_VALUE_NOW => t('Current date'),
static::DEFAULT_VALUE_CUSTOM => t('Relative date'),
),
'#empty_value' => '',
),
'default_date' => array(
'#type' => 'textfield',
'#title' => t('Relative default value'),
'#description' => t("Describe a time by reference to the current day, like '+90 days' (90 days from the day the field is created) or '+1 Saturday' (the next Saturday). See !strtotime for more details.", array('!strtotime' => l('strtotime', 'http://www.php.net/manual/en/function.strtotime.php'))),
'#default_value' => (isset($default_value[0]['default_date_type']) && $default_value[0]['default_date_type'] == static::DEFAULT_VALUE_CUSTOM) ? $default_value[0]['default_date'] : '',
'#states' => array(
'visible' => array(
':input[id="edit-default-value-input-default-date-type"]' => array('value' => static::DEFAULT_VALUE_CUSTOM),
)
)
)
);
......@@ -49,13 +68,23 @@ public function defaultValuesForm(array &$form, FormStateInterface $form_state)
/**
* {@inheritdoc}
*/
public function defaultValuesFormValidate(array $element, array &$form, FormStateInterface $form_state) { }
public function defaultValuesFormValidate(array $element, array &$form, FormStateInterface $form_state) {
if ($form_state['values']['default_value_input']['default_date_type'] == static::DEFAULT_VALUE_CUSTOM) {
$is_strtotime = @strtotime($form_state->getValue(array('default_value_input', 'default_date')));
if (!$is_strtotime) {
$form_state->setErrorByName('default_value_input][default_date', t('The relative date value entered is invalid.'));
}
}
}
/**
* {@inheritdoc}
*/
public function defaultValuesFormSubmit(array $element, array &$form, FormStateInterface $form_state) {
if ($form_state->getValue(array('default_value_input', 'default_date'))) {
if ($form_state->getValue(array('default_value_input', 'default_date_type'))) {
if ($form_state->getValue(array('default_value_input', 'default_date_type')) == static::DEFAULT_VALUE_NOW) {
$form_state->setValueForElement($element['default_date'], static::DEFAULT_VALUE_NOW);
}
return array($form_state->getValue('default_value_input'));
}
return array();
......@@ -67,10 +96,10 @@ public function defaultValuesFormSubmit(array $element, array &$form, FormStateI
public static function processDefaultValue($default_value, ContentEntityInterface $entity, FieldDefinitionInterface $definition) {
$default_value = parent::processDefaultValue($default_value, $entity, $definition);
if (isset($default_value[0]['default_date']) && $default_value[0]['default_date'] == static::DEFAULT_VALUE_NOW) {
if (isset($default_value[0]['default_date_type'])) {
// A default value should be in the format and timezone used for date
// storage.
$date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE);
$date = new DrupalDateTime($default_value[0]['default_date'], DATETIME_STORAGE_TIMEZONE);
$storage_format = $definition->getSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT: DATETIME_DATETIME_STORAGE_FORMAT;
$value = $date->format($storage_format);
// We only provide a default value for the first item, as do all fields.
......
......@@ -305,17 +305,18 @@ function testDefaultValue() {
// Set now as default_value.
$instance_edit = array(
'default_value_input[default_date]' => 'now',
'default_value_input[default_date_type]' => 'now',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_storage->name, $instance_edit, t('Save settings'));
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_storage->name);
$this->assertRaw('<option value="now" selected="selected">The current date</option>', 'The default value is selected in instance settings page');
$this->assertOptionSelected('edit-default-value-input-default-date-type', 'now', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '', 'The relative default value is empty in instance settings page');
// Check if default_date has been stored successfully.
$config_entity = $this->container->get('config.factory')->get('field.instance.node.date_content.' . $field_storage->name)->get();
$this->assertEqual($config_entity['default_value'][0]['default_date'], 'now', 'Default value has been stored successfully');
$this->assertEqual($config_entity['default_value'][0], array('default_date_type' => 'now', 'default_date' => 'now'), 'Default value has been stored successfully');
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
......@@ -325,15 +326,49 @@ function testDefaultValue() {
$expected_date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE);
$this->assertEqual($new_node->get($field_storage->name)->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT));
// Set an invalid relative default_value to test validation.
$instance_edit = array(
'default_value_input[default_date_type]' => 'relative',
'default_value_input[default_date]' => 'invalid date',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_storage->name, $instance_edit, t('Save settings'));
$this->assertText('The relative date value entered is invalid.');
// Set a relative default_value.
$instance_edit = array(
'default_value_input[default_date_type]' => 'relative',
'default_value_input[default_date]' => '+90 days',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_storage->name, $instance_edit, t('Save settings'));
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_storage->name);
$this->assertOptionSelected('edit-default-value-input-default-date-type', 'relative', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '+90 days', 'The relative default value is displayed in instance settings page');
// Check if default_date has been stored successfully.
$config_entity = $this->container->get('config.factory')->get('field.instance.node.date_content.' . $field_storage->name)->get();
$this->assertEqual($config_entity['default_value'][0], array('default_date_type' => 'relative', 'default_date' => '+90 days'), 'Default value has been stored successfully');
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
// Create a new node to check that datetime field default value is +90 days.
$new_node = entity_create('node', array('type' => 'date_content'));
$expected_date = new DrupalDateTime('+90 days', DATETIME_STORAGE_TIMEZONE);
$this->assertEqual($new_node->get($field_storage->name)->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT));
// Remove default value.
$instance_edit = array(
'default_value_input[default_date]' => '',
'default_value_input[default_date_type]' => '',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_storage->name, $instance_edit, t('Save settings'));
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_storage->name);
$this->assertRaw('<option value="" selected="selected">' . t('- None -') . '</option>', 'The default value is selected in instance settings page');
$this->assertOptionSelected('edit-default-value-input-default-date-type', '', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '', 'The relative default value is empty in instance settings page');
// Check if default_date has been stored successfully.
$config_entity = $this->container->get('config.factory')->get('field.instance.node.date_content.' . $field_storage->name)->get();
......@@ -342,7 +377,7 @@ function testDefaultValue() {
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
// Create a new node to check that datetime field default value is today.
// Create a new node to check that datetime field default value is not set.
$new_node = entity_create('node', array('type' => 'date_content'));
$this->assertNull($new_node->get($field_storage->name)->offsetGet(0)->value, 'Default value is not set');
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment