Skip to content
Snippets Groups Projects
Commit 14e5cdb0 authored by catch's avatar catch
Browse files

Issue #1989468 by plopesc, yched, Wim Leers, effulgentsia: Weird messing with...

Issue #1989468 by plopesc, yched, Wim Leers, effulgentsia: Weird messing with 'default_value_function' in date widgets.
parent 0a96230d
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
......@@ -9,15 +9,10 @@ field.datetime.settings:
label: 'Date type'
field.datetime.instance_settings:
type: mapping
label: 'Datetime settings'
mapping:
default_value:
type: string
label: 'Default date'
user_register_form:
type: boolean
label: 'Display on user registration form.'
type: sequence
label: 'Settings'
sequence:
- type: string
field.datetime.value:
type: sequence
......
......@@ -167,48 +167,6 @@ function datetime_datelist_widget_validate(&$element, &$form_state) {
}
}
/**
* Sets a default value for an empty date field.
*
* Callback for $instance['default_value_function'], as implemented by
* Drupal\datetime\Plugin\Field\FieldWidget\DateTimeDatepicker.
*
* @param $entity_type
*
* @param $entity
*
* @param array $field
*
* @param array $instance
*
* @param $langcode
*
*
* @return array
*
*/
function datetime_default_value($entity, $field, $instance, $langcode) {
$value = '';
$date = '';
if ($instance->getSetting('default_value') == 'now') {
// A default value should be in the format and timezone used for date
// storage.
$date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE);
$storage_format = $field->getSetting('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.
// Otherwise, there is no way to clear out unwanted values on multiple value
// fields.
$item = array();
$item[0]['value'] = $value;
$item[0]['date'] = $date;
return $item;
}
/**
* Sets a consistent time on a date without time.
*
......
<?php
/**
* @file
* Contains \Drupal\datetime\Plugin\Field\FieldType\DateTimeFieldItemList.
*/
namespace Drupal\datetime\Plugin\Field\FieldType;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\ConfigFieldItemList;
/**
* Represents a configurable entity datetime field.
*/
class DateTimeFieldItemList extends ConfigFieldItemList {
/**
* Defines the default value as now.
*/
const DEFAULT_VALUE_NOW = 'now';
/**
* {@inheritdoc}
*/
public function defaultValuesForm(array &$form, array &$form_state) {
if (empty($this->getFieldDefinition()->default_value_function)) {
$default_value = $this->getFieldDefinition()->default_value;
$element = array(
'#parents' => array('default_value_input'),
'default_date' => 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')),
'#empty_value' => '',
)
);
return $element;
}
}
/**
* {@inheritdoc}
*/
public function defaultValuesFormValidate(array $element, array &$form, array &$form_state) { }
/**
* {@inheritdoc}
*/
public function defaultValuesFormSubmit(array $element, array &$form, array &$form_state) {
if ($form_state['values']['default_value_input']['default_date']) {
return array($form_state['values']['default_value_input']);
}
return array();
}
/**
* {@inheritdoc}
*/
public function getDefaultValue() {
$default_value = parent::getDefaultValue();
if (isset($default_value[0]['default_date']) && $default_value[0]['default_date'] == static::DEFAULT_VALUE_NOW) {
// A default value should be in the format and timezone used for date
// storage.
$date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE);
$storage_format = $this->getFieldDefinition()->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.
// Otherwise, there is no way to clear out unwanted values on multiple value
// fields.
$default_value = array(
array(
'value' => $value,
'date' => $date,
)
);
}
return $default_value;
}
}
......@@ -23,15 +23,23 @@
* settings = {
* "datetime_type" = "datetime"
* },
* instance_settings = {
* "default_value" = "now"
* },
* default_widget = "datetime_default",
* default_formatter = "datetime_default"
* default_formatter = "datetime_default",
* list_class = "\Drupal\datetime\Plugin\Field\FieldType\DateTimeFieldItemList"
* )
*/
class DateTimeItem extends ConfigFieldItemBase implements PrepareCacheInterface {
/**
* Value for the 'datetime_type' setting: store only a date.
*/
const DATETIME_TYPE_DATE = 'date';
/**
* Value for the 'datetime_type' setting: store a date and time.
*/
const DATETIME_TYPE_DATETIME = 'datetime';
/**
* Field definitions of the contained properties.
*
......@@ -89,32 +97,14 @@ public function settingsForm(array $form, array &$form_state, $has_data) {
'#description' => t('Choose the type of date to create.'),
'#default_value' => $this->getFieldSetting('datetime_type'),
'#options' => array(
'datetime' => t('Date and time'),
'date' => t('Date only'),
static::DATETIME_TYPE_DATETIME => t('Date and time'),
static::DATETIME_TYPE_DATE => t('Date only'),
),
);
return $element;
}
/**
* {@inheritdoc}
*/
public function instanceSettingsForm(array $form, array &$form_state) {
$element = array();
$element['default_value'] = array(
'#type' => 'select',
'#title' => t('Default date'),
'#description' => t('Set a default value for this date.'),
'#default_value' => $this->getFieldSetting('default_value'),
'#options' => array('blank' => t('No default value'), 'now' => t('The current date')),
'#weight' => 1,
);
return $element;
}
/**
* {@inheritdoc}
*/
......
......@@ -8,9 +8,7 @@
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\field\FieldInstanceInterface;
use Drupal\datetime\DateHelper;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
/**
* Plugin implementation of the 'datetime_datelist' widget.
......@@ -30,29 +28,6 @@
*/
class DateTimeDatelistWidget extends WidgetBase {
/**
* {@inheritdoc}
*/
public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
// Identify the function used to set the default value.
// @todo Make this work for both configurable and nonconfigurable fields:
// https://drupal.org/node/1989468.
if ($field_definition instanceof FieldInstanceInterface) {
$field_definition->default_value_function = $this->defaultValueFunction();
}
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
}
/**
* Returns the callback used to set a date default value.
*
* @return string
* The name of the callback to use when setting a default date value.
*/
public function defaultValueFunction() {
return 'datetime_default_value';
}
/**
* {@inheritdoc}
*/
......@@ -74,7 +49,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
// Identify the type of date and time elements to use.
switch ($this->getFieldSetting('datetime_type')) {
case 'date':
case DateTimeItem::DATETIME_TYPE_DATE:
$storage_format = DATETIME_DATE_STORAGE_FORMAT;
break;
......
......@@ -9,7 +9,7 @@
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\field\FieldInstanceInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
/**
* Plugin implementation of the 'datetime_default' widget.
......@@ -35,28 +35,12 @@ class DateTimeDefaultWidget extends WidgetBase {
* {@inheritdoc}
*/
public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
// Identify the function used to set the default value.
// @todo Make this work for both configurable and nonconfigurable fields:
// https://drupal.org/node/1989468.
if ($field_definition instanceof FieldInstanceInterface) {
$field_definition->default_value_function = $this->defaultValueFunction();
}
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
// @todo Inject this once https://drupal.org/node/2035317 is in.
$this->dateStorage = \Drupal::entityManager()->getStorageController('date_format');
}
/**
* Return the callback used to set a date default value.
*
* @return string
* The name of the callback to use when setting a default date value.
*/
public function defaultValueFunction() {
return 'datetime_default_value';
}
/**
* {@inheritdoc}
*/
......@@ -75,7 +59,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
// Identify the type of date and time elements to use.
switch ($this->getFieldSetting('datetime_type')) {
case 'date':
case DateTimeItem::DATETIME_TYPE_DATE:
$date_type = 'date';
$time_type = 'none';
$date_format = $this->dateStorage->load('html_date')->getPattern($format_type);
......@@ -117,7 +101,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
// The date was created and verified during field_load(), so it is safe to
// use without further inspection.
$date->setTimezone(new \DateTimeZone($element['value']['#date_timezone']));
if ($this->getFieldSetting('datetime_type') == 'date') {
if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
// A date without time will pick up the current time, use the default
// time.
datetime_date_default_time($date);
......
......@@ -13,7 +13,7 @@
/**
* Tests Datetime field functionality.
*/
class DatetimeFieldTest extends WebTestBase {
class DateTimeFieldTest extends WebTestBase {
/**
* Modules to enable.
......@@ -48,9 +48,11 @@ function setUp() {
parent::setUp();
$web_user = $this->drupalCreateUser(array(
'access content',
'view test entity',
'administer entity_test content',
'administer content types',
'administer node fields',
));
$this->drupalLogin($web_user);
......@@ -66,9 +68,6 @@ function setUp() {
'field_name' => $this->field->name,
'entity_type' => 'entity_test',
'bundle' => 'entity_test',
'settings' => array(
'default_value' => 'blank',
),
));
$this->instance->save();
......@@ -292,40 +291,67 @@ function testDatelistWidget() {
* Test default value functionality.
*/
function testDefaultValue() {
// Create a test content type.
$this->drupalCreateContentType(array('type' => 'date_content'));
// Change the field to a datetime field.
$this->field->settings['datetime_type'] = 'datetime';
$this->field->save();
$field_name = $this->field->name;
// Create a field with settings to validate.
$field = entity_create('field_entity', array(
'name' => drupal_strtolower($this->randomName()),
'entity_type' => 'node',
'type' => 'datetime',
'settings' => array('datetime_type' => 'date'),
));
$field->save();
// Set the default value to 'now'.
$this->instance->settings['default_value'] = 'now';
$this->instance->default_value_function = 'datetime_default_value';
$this->instance->save();
$instance = entity_create('field_instance', array(
'field_name' => $field->name,
'entity_type' => 'node',
'bundle' => 'date_content',
));
$instance->save();
// Display creation form.
$date = new DrupalDateTime();
$date_format = 'Y-m-d';
$this->drupalGet('entity_test/add');
// Set now as default_value.
$instance_edit = array(
'default_value_input[default_date]' => 'now',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field->name, $instance_edit, t('Save settings'));
// See if current date is set. We cannot test for the precise time because
// it may be a few seconds between the time the comparison date is created
// and the form date, so we just test the date and that the time is not
// empty.
$this->assertFieldByName("{$field_name}[0][value][date]", $date->format($date_format), 'Date element found.');
$this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Time element found.');
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field->name);
$this->assertRaw('<option value="now" selected="selected">The current date</option>', 'The default value is selected in instance settings page');
// Set the default value to 'blank'.
$this->instance->settings['default_value'] = 'blank';
$this->instance->default_value_function = 'datetime_default_value';
$this->instance->save();
// Check if default_date has been stored successfully.
$config_entity = $this->container->get('config.factory')->get('field.instance.node.date_content.' . $field->name)->get();
$this->assertEqual($config_entity['default_value'][0]['default_date'], 'now', 'Default value has been stored succesfully');
// Display creation form.
$this->drupalGet('entity_test/add');
// Clean field_info cache in order to avoid stale cache values.
field_info_cache_clear();
// See that no date is set.
$this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.');
$this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.');
// Create a new node to check that datetime field default value is today.
$new_node = entity_create('node', array('type' => 'date_content'));
$expected_date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE);
$this->assertEqual($new_node->get($field->name)->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT));
// Remove default value.
$instance_edit = array(
'default_value_input[default_date]' => '',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field->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->name);
$this->assertRaw('<option value="" selected="selected">' . t('- None -') . '</option>', 'The default value is selected 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->name)->get();
$this->assertTrue(empty($config_entity['default_value']), 'Empty default value has been stored succesfully');
// Clean field_info cache in order to avoid stale cache values.
field_info_cache_clear();
// Create a new node to check that datetime field default value is today.
$new_node = entity_create('node', array('type' => 'date_content'));
$this->assertNull($new_node->get($field->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