diff --git a/core/modules/datetime/config/schema/datetime.schema.yml b/core/modules/datetime/config/schema/datetime.schema.yml index 4074ff2..05e9fc8 100644 --- a/core/modules/datetime/config/schema/datetime.schema.yml +++ b/core/modules/datetime/config/schema/datetime.schema.yml @@ -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 diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index 1f0c81e..ccf1a0c 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -168,48 +168,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. * * The default time for a date without time can be anything, so long as it is diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeFieldItemList.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeFieldItemList.php new file mode 100644 index 0000000..46a5625 --- /dev/null +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeFieldItemList.php @@ -0,0 +1,86 @@ +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; + } + +} diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php index 3fbcca1..dc2c201 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php @@ -23,16 +23,24 @@ * 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. * * @var array @@ -89,8 +97,8 @@ 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'), ), ); @@ -100,24 +108,6 @@ public function settingsForm(array $form, array &$form_state, $has_data) { /** * {@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} - */ public function getCacheData() { $data = $this->getValue(); // The function generates a Date object for each field early so that it is diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDatelistWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDatelistWidget.php index 1e8bf0e..cbae23c 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDatelistWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDatelistWidget.php @@ -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. @@ -33,29 +31,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} - */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) { $date_order = $this->getSetting('date_order'); $time_type = $this->getSetting('time_type'); @@ -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; diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDefaultWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDefaultWidget.php index 7f9708a..9389a71 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDefaultWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DatetimeDefaultWidget.php @@ -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,12 +35,6 @@ 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. @@ -48,16 +42,6 @@ public function __construct($plugin_id, array $plugin_definition, FieldDefinitio } /** - * 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} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) { @@ -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); diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeFieldTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeFieldTest.php new file mode 100644 index 0000000..c2ec068 --- /dev/null +++ b/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeFieldTest.php @@ -0,0 +1,467 @@ + 'Datetime Field', + 'description' => 'Tests datetime field functionality.', + 'group' => 'Datetime', + ); + } + + 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); + + // Create a field with settings to validate. + $this->field = entity_create('field_entity', array( + 'name' => drupal_strtolower($this->randomName()), + 'entity_type' => 'entity_test', + 'type' => 'datetime', + 'settings' => array('datetime_type' => 'date'), + )); + $this->field->save(); + $this->instance = entity_create('field_instance', array( + 'field_name' => $this->field->name, + 'entity_type' => 'entity_test', + 'bundle' => 'entity_test', + )); + $this->instance->save(); + + entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default') + ->setComponent($this->field->name, array( + 'type' => 'datetime_default', + )) + ->save(); + + $this->display_options = array( + 'type' => 'datetime_default', + 'label' => 'hidden', + 'settings' => array('format_type' => 'medium'), + ); + entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') + ->setComponent($this->field->name, $this->display_options) + ->save(); + } + + /** + * Tests date field functionality. + */ + function testDateField() { + $field_name = $this->field->name; + + // Display creation form. + $this->drupalGet('entity_test/add'); + $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); + $this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Time element not found.'); + + // Submit a valid date and ensure it is accepted. + $value = '2012-12-31 00:00:00'; + $date = new DrupalDateTime($value); + $format_type = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; + $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); + $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); + + $edit = array( + 'user_id' => 1, + 'name' => $this->randomName(), + "{$field_name}[0][value][date]" => $date->format($date_format), + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + preg_match('|entity_test/manage/(\d+)|', $this->url, $match); + $id = $match[1]; + $this->assertText(t('entity_test @id has been created.', array('@id' => $id))); + $this->assertRaw($date->format($date_format)); + $this->assertNoRaw($date->format($time_format)); + + // The expected values will use the default time. + datetime_date_default_time($date); + + // Verify that the date is output according to the formatter settings. + $options = array( + 'format_type' => array('short', 'medium', 'long'), + ); + foreach ($options as $setting => $values) { + foreach ($values as $new_value) { + // Update the entity display settings. + $this->display_options['settings'] = array($setting => $new_value); + entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') + ->setComponent($field_name, $this->display_options) + ->save(); + + $this->renderTestEntity($id); + switch ($setting) { + case 'format_type': + // Verify that a date is displayed. + $expected = format_date($date->getTimestamp(), $new_value); + $this->renderTestEntity($id); + $this->assertText($expected, format_string('Formatted date field using %value format displayed as %expected.', array('%value' => $new_value, '%expected' => $expected))); + break; + } + } + } + + // Verify that the plain formatter works. + $this->display_options['type'] = 'datetime_plain'; + entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') + ->setComponent($field_name, $this->display_options) + ->save(); + $expected = $date->format(DATETIME_DATE_STORAGE_FORMAT); + $this->renderTestEntity($id); + $this->assertText($expected, format_string('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected))); + } + + /** + * Tests date and time field. + */ + function testDatetimeField() { + $field_name = $this->field->name; + // Change the field to a datetime field. + $this->field->settings['datetime_type'] = 'datetime'; + $this->field->save(); + + // Display creation form. + $this->drupalGet('entity_test/add'); + $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); + $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.'); + + // Submit a valid date and ensure it is accepted. + $value = '2012-12-31 00:00:00'; + $date = new DrupalDateTime($value); + $format_type = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; + $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); + $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); + + $edit = array( + 'user_id' => 1, + 'name' => $this->randomName(), + "{$field_name}[0][value][date]" => $date->format($date_format), + "{$field_name}[0][value][time]" => $date->format($time_format), + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + preg_match('|entity_test/manage/(\d+)|', $this->url, $match); + $id = $match[1]; + $this->assertText(t('entity_test @id has been created.', array('@id' => $id))); + $this->assertRaw($date->format($date_format)); + $this->assertRaw($date->format($time_format)); + + // Verify that the date is output according to the formatter settings. + $options = array( + 'format_type' => array('short', 'medium', 'long'), + ); + foreach ($options as $setting => $values) { + foreach ($values as $new_value) { + // Update the entity display settings. + $this->display_options['settings'] = array($setting => $new_value); + entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') + ->setComponent($field_name, $this->display_options) + ->save(); + + $this->renderTestEntity($id); + switch ($setting) { + case 'format_type': + // Verify that a date is displayed. + $expected = format_date($date->getTimestamp(), $new_value); + $this->renderTestEntity($id); + $this->assertText($expected, format_string('Formatted date field using %value format displayed as %expected.', array('%value' => $new_value, '%expected' => $expected))); + break; + } + } + } + + // Verify that the plain formatter works. + $this->display_options['type'] = 'datetime_plain'; + entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') + ->setComponent($field_name, $this->display_options) + ->save(); + $expected = $date->format(DATETIME_DATETIME_STORAGE_FORMAT); + $this->renderTestEntity($id); + $this->assertText($expected, format_string('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected))); + } + + /** + * Tests Date List Widget functionality. + */ + function testDatelistWidget() { + $field_name = $this->field->name; + // Change the field to a datetime field. + $this->field->settings['datetime_type'] = 'datetime'; + $this->field->save(); + + // Change the widget to a datelist widget. + entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default') + ->setComponent($field_name, array( + 'type' => 'datetime_datelist', + 'settings' => array( + 'increment' => 1, + 'date_order' => 'YMD', + 'time_type' => '12', + ), + )) + ->save(); + field_cache_clear(); + + // Display creation form. + $this->drupalGet('entity_test/add'); + + $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-year\"]", NULL, 'Year element found.'); + $this->assertOptionSelected("edit-$field_name-0-value-year", '', 'No year selected.'); + $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-month\"]", NULL, 'Month element found.'); + $this->assertOptionSelected("edit-$field_name-0-value-month", '', 'No month selected.'); + $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-day\"]", NULL, 'Day element found.'); + $this->assertOptionSelected("edit-$field_name-0-value-day", '', 'No day selected.'); + $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-hour\"]", NULL, 'Hour element found.'); + $this->assertOptionSelected("edit-$field_name-0-value-hour", '', 'No hour selected.'); + $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-minute\"]", NULL, 'Minute element found.'); + $this->assertOptionSelected("edit-$field_name-0-value-minute", '', 'No minute selected.'); + $this->assertNoFieldByXPath("//*[@id=\"edit-$field_name-0-value-second\"]", NULL, 'Second element not found.'); + $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-ampm\"]", NULL, 'AMPM element found.'); + $this->assertOptionSelected("edit-$field_name-0-value-ampm", '', 'No ampm selected.'); + + // Submit a valid date and ensure it is accepted. + $date_value = array('year' => 2012, 'month' => 12, 'day' => 31, 'hour' => 5, 'minute' => 15); + + $edit = array( + 'user_id' => 1, + 'name' => $this->randomName(), + ); + // Add the ampm indicator since we are testing 12 hour time. + $date_value['ampm'] = 'am'; + foreach ($date_value as $part => $value) { + $edit["{$field_name}[0][value][$part]"] = $value; + } + + $this->drupalPostForm(NULL, $edit, t('Save')); + preg_match('|entity_test/manage/(\d+)|', $this->url, $match); + $id = $match[1]; + $this->assertText(t('entity_test @id has been created.', array('@id' => $id))); + + $this->assertOptionSelected("edit-$field_name-0-value-year", '2012', 'Correct year selected.'); + $this->assertOptionSelected("edit-$field_name-0-value-month", '12', 'Correct month selected.'); + $this->assertOptionSelected("edit-$field_name-0-value-day", '31', 'Correct day selected.'); + $this->assertOptionSelected("edit-$field_name-0-value-hour", '5', 'Correct hour selected.'); + $this->assertOptionSelected("edit-$field_name-0-value-minute", '15', 'Correct minute selected.'); + $this->assertOptionSelected("edit-$field_name-0-value-ampm", 'am', 'Correct ampm selected.'); + } + + /** + * Test default value functionality. + */ + function testDefaultValue() { + // Create a test content type. + $this->drupalCreateContentType(array('type' => 'date_content')); + + // 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(); + + $instance = entity_create('field_instance', array( + 'field_name' => $field->name, + 'entity_type' => 'node', + 'bundle' => 'date_content', + )); + $instance->save(); + + // 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')); + + // 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('', '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->assertEqual($config_entity['default_value'][0]['default_date'], 'now', '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')); + $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('', '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'); + } + + /** + * Test that invalid values are caught and marked as invalid. + */ + function testInvalidField() { + + // Change the field to a datetime field. + $this->field->settings['datetime_type'] = 'datetime'; + $this->field->save(); + $field_name = $this->field->name; + + // Display creation form. + $this->drupalGet('entity_test/add'); + $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); + $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.'); + + // Submit invalid dates and ensure they is not accepted. + $date_value = ''; + $edit = array( + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => '12:00:00', + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', 'Empty date value has been caught.'); + + $date_value = 'aaaa-12-01'; + $edit = array( + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => '00:00:00', + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid year value %date has been caught.', array('%date' => $date_value))); + + $date_value = '2012-75-01'; + $edit = array( + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => '00:00:00', + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid month value %date has been caught.', array('%date' => $date_value))); + + $date_value = '2012-12-99'; + $edit = array( + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => '00:00:00', + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid day value %date has been caught.', array('%date' => $date_value))); + + $date_value = '2012-12-01'; + $time_value = ''; + $edit = array( + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => $time_value, + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', 'Empty time value has been caught.'); + + $date_value = '2012-12-01'; + $time_value = '49:00:00'; + $edit = array( + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => $time_value, + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid hour value %time has been caught.', array('%time' => $time_value))); + + $date_value = '2012-12-01'; + $time_value = '12:99:00'; + $edit = array( + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => $time_value, + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid minute value %time has been caught.', array('%time' => $time_value))); + + $date_value = '2012-12-01'; + $time_value = '12:15:99'; + $edit = array( + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => $time_value, + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid second value %time has been caught.', array('%time' => $time_value))); + } + + /** + * Renders a entity_test and sets the output in the internal browser. + * + * @param int $id + * The entity_test ID to render. + * @param string $view_mode + * (optional) The view mode to use for rendering. Defaults to 'full'. + * @param bool $reset + * (optional) Whether to reset the entity_test controller cache. Defaults to + * TRUE to simplify testing. + */ + protected function renderTestEntity($id, $view_mode = 'full', $reset = TRUE) { + if ($reset) { + entity_get_controller('entity_test')->resetCache(array($id)); + } + $entity = entity_load('entity_test', $id); + $display = entity_get_display('entity_test', $entity->bundle(), 'full'); + field_attach_prepare_view('entity_test', array($entity->id() => $entity), array($entity->bundle() => $display), $view_mode); + $entity->content = field_attach_view($entity, $display, $view_mode); + + $output = drupal_render($entity->content); + $this->drupalSetContent($output); + $this->verbose($output); + } + +} diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php deleted file mode 100644 index 5bee2e3..0000000 --- a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php +++ /dev/null @@ -1,441 +0,0 @@ - 'Datetime Field', - 'description' => 'Tests datetime field functionality.', - 'group' => 'Datetime', - ); - } - - function setUp() { - parent::setUp(); - - $web_user = $this->drupalCreateUser(array( - 'view test entity', - 'administer entity_test content', - 'administer content types', - )); - $this->drupalLogin($web_user); - - // Create a field with settings to validate. - $this->field = entity_create('field_entity', array( - 'name' => drupal_strtolower($this->randomName()), - 'entity_type' => 'entity_test', - 'type' => 'datetime', - 'settings' => array('datetime_type' => 'date'), - )); - $this->field->save(); - $this->instance = entity_create('field_instance', array( - 'field_name' => $this->field->name, - 'entity_type' => 'entity_test', - 'bundle' => 'entity_test', - 'settings' => array( - 'default_value' => 'blank', - ), - )); - $this->instance->save(); - - entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default') - ->setComponent($this->field->name, array( - 'type' => 'datetime_default', - )) - ->save(); - - $this->display_options = array( - 'type' => 'datetime_default', - 'label' => 'hidden', - 'settings' => array('format_type' => 'medium'), - ); - entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') - ->setComponent($this->field->name, $this->display_options) - ->save(); - } - - /** - * Tests date field functionality. - */ - function testDateField() { - $field_name = $this->field->name; - - // Display creation form. - $this->drupalGet('entity_test/add'); - $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); - $this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Time element not found.'); - - // Submit a valid date and ensure it is accepted. - $value = '2012-12-31 00:00:00'; - $date = new DrupalDateTime($value); - $format_type = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; - $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); - $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); - - $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - "{$field_name}[0][value][date]" => $date->format($date_format), - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - preg_match('|entity_test/manage/(\d+)|', $this->url, $match); - $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id))); - $this->assertRaw($date->format($date_format)); - $this->assertNoRaw($date->format($time_format)); - - // The expected values will use the default time. - datetime_date_default_time($date); - - // Verify that the date is output according to the formatter settings. - $options = array( - 'format_type' => array('short', 'medium', 'long'), - ); - foreach ($options as $setting => $values) { - foreach ($values as $new_value) { - // Update the entity display settings. - $this->display_options['settings'] = array($setting => $new_value); - entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') - ->setComponent($field_name, $this->display_options) - ->save(); - - $this->renderTestEntity($id); - switch ($setting) { - case 'format_type': - // Verify that a date is displayed. - $expected = format_date($date->getTimestamp(), $new_value); - $this->renderTestEntity($id); - $this->assertText($expected, format_string('Formatted date field using %value format displayed as %expected.', array('%value' => $new_value, '%expected' => $expected))); - break; - } - } - } - - // Verify that the plain formatter works. - $this->display_options['type'] = 'datetime_plain'; - entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') - ->setComponent($field_name, $this->display_options) - ->save(); - $expected = $date->format(DATETIME_DATE_STORAGE_FORMAT); - $this->renderTestEntity($id); - $this->assertText($expected, format_string('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected))); - } - - /** - * Tests date and time field. - */ - function testDatetimeField() { - $field_name = $this->field->name; - // Change the field to a datetime field. - $this->field->settings['datetime_type'] = 'datetime'; - $this->field->save(); - - // Display creation form. - $this->drupalGet('entity_test/add'); - $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); - $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.'); - - // Submit a valid date and ensure it is accepted. - $value = '2012-12-31 00:00:00'; - $date = new DrupalDateTime($value); - $format_type = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; - $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); - $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); - - $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - "{$field_name}[0][value][date]" => $date->format($date_format), - "{$field_name}[0][value][time]" => $date->format($time_format), - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - preg_match('|entity_test/manage/(\d+)|', $this->url, $match); - $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id))); - $this->assertRaw($date->format($date_format)); - $this->assertRaw($date->format($time_format)); - - // Verify that the date is output according to the formatter settings. - $options = array( - 'format_type' => array('short', 'medium', 'long'), - ); - foreach ($options as $setting => $values) { - foreach ($values as $new_value) { - // Update the entity display settings. - $this->display_options['settings'] = array($setting => $new_value); - entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') - ->setComponent($field_name, $this->display_options) - ->save(); - - $this->renderTestEntity($id); - switch ($setting) { - case 'format_type': - // Verify that a date is displayed. - $expected = format_date($date->getTimestamp(), $new_value); - $this->renderTestEntity($id); - $this->assertText($expected, format_string('Formatted date field using %value format displayed as %expected.', array('%value' => $new_value, '%expected' => $expected))); - break; - } - } - } - - // Verify that the plain formatter works. - $this->display_options['type'] = 'datetime_plain'; - entity_get_display($this->instance->entity_type, $this->instance->bundle, 'full') - ->setComponent($field_name, $this->display_options) - ->save(); - $expected = $date->format(DATETIME_DATETIME_STORAGE_FORMAT); - $this->renderTestEntity($id); - $this->assertText($expected, format_string('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected))); - } - - /** - * Tests Date List Widget functionality. - */ - function testDatelistWidget() { - $field_name = $this->field->name; - // Change the field to a datetime field. - $this->field->settings['datetime_type'] = 'datetime'; - $this->field->save(); - - // Change the widget to a datelist widget. - entity_get_form_display($this->instance->entity_type, $this->instance->bundle, 'default') - ->setComponent($field_name, array( - 'type' => 'datetime_datelist', - 'settings' => array( - 'increment' => 1, - 'date_order' => 'YMD', - 'time_type' => '12', - ), - )) - ->save(); - field_cache_clear(); - - // Display creation form. - $this->drupalGet('entity_test/add'); - - $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-year\"]", NULL, 'Year element found.'); - $this->assertOptionSelected("edit-$field_name-0-value-year", '', 'No year selected.'); - $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-month\"]", NULL, 'Month element found.'); - $this->assertOptionSelected("edit-$field_name-0-value-month", '', 'No month selected.'); - $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-day\"]", NULL, 'Day element found.'); - $this->assertOptionSelected("edit-$field_name-0-value-day", '', 'No day selected.'); - $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-hour\"]", NULL, 'Hour element found.'); - $this->assertOptionSelected("edit-$field_name-0-value-hour", '', 'No hour selected.'); - $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-minute\"]", NULL, 'Minute element found.'); - $this->assertOptionSelected("edit-$field_name-0-value-minute", '', 'No minute selected.'); - $this->assertNoFieldByXPath("//*[@id=\"edit-$field_name-0-value-second\"]", NULL, 'Second element not found.'); - $this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-ampm\"]", NULL, 'AMPM element found.'); - $this->assertOptionSelected("edit-$field_name-0-value-ampm", '', 'No ampm selected.'); - - // Submit a valid date and ensure it is accepted. - $date_value = array('year' => 2012, 'month' => 12, 'day' => 31, 'hour' => 5, 'minute' => 15); - - $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - ); - // Add the ampm indicator since we are testing 12 hour time. - $date_value['ampm'] = 'am'; - foreach ($date_value as $part => $value) { - $edit["{$field_name}[0][value][$part]"] = $value; - } - - $this->drupalPostForm(NULL, $edit, t('Save')); - preg_match('|entity_test/manage/(\d+)|', $this->url, $match); - $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id))); - - $this->assertOptionSelected("edit-$field_name-0-value-year", '2012', 'Correct year selected.'); - $this->assertOptionSelected("edit-$field_name-0-value-month", '12', 'Correct month selected.'); - $this->assertOptionSelected("edit-$field_name-0-value-day", '31', 'Correct day selected.'); - $this->assertOptionSelected("edit-$field_name-0-value-hour", '5', 'Correct hour selected.'); - $this->assertOptionSelected("edit-$field_name-0-value-minute", '15', 'Correct minute selected.'); - $this->assertOptionSelected("edit-$field_name-0-value-ampm", 'am', 'Correct ampm selected.'); - } - - /** - * Test default value functionality. - */ - function testDefaultValue() { - - // Change the field to a datetime field. - $this->field->settings['datetime_type'] = 'datetime'; - $this->field->save(); - $field_name = $this->field->name; - - // Set the default value to 'now'. - $this->instance->settings['default_value'] = 'now'; - $this->instance->default_value_function = 'datetime_default_value'; - $this->instance->save(); - - // Display creation form. - $date = new DrupalDateTime(); - $date_format = 'Y-m-d'; - $this->drupalGet('entity_test/add'); - - // 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.'); - - // Set the default value to 'blank'. - $this->instance->settings['default_value'] = 'blank'; - $this->instance->default_value_function = 'datetime_default_value'; - $this->instance->save(); - - // Display creation form. - $this->drupalGet('entity_test/add'); - - // 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.'); - } - - /** - * Test that invalid values are caught and marked as invalid. - */ - function testInvalidField() { - - // Change the field to a datetime field. - $this->field->settings['datetime_type'] = 'datetime'; - $this->field->save(); - $field_name = $this->field->name; - - // Display creation form. - $this->drupalGet('entity_test/add'); - $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); - $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.'); - - // Submit invalid dates and ensure they is not accepted. - $date_value = ''; - $edit = array( - "{$field_name}[0][value][date]" => $date_value, - "{$field_name}[0][value][time]" => '12:00:00', - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('date is invalid', 'Empty date value has been caught.'); - - $date_value = 'aaaa-12-01'; - $edit = array( - "{$field_name}[0][value][date]" => $date_value, - "{$field_name}[0][value][time]" => '00:00:00', - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('date is invalid', format_string('Invalid year value %date has been caught.', array('%date' => $date_value))); - - $date_value = '2012-75-01'; - $edit = array( - "{$field_name}[0][value][date]" => $date_value, - "{$field_name}[0][value][time]" => '00:00:00', - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('date is invalid', format_string('Invalid month value %date has been caught.', array('%date' => $date_value))); - - $date_value = '2012-12-99'; - $edit = array( - "{$field_name}[0][value][date]" => $date_value, - "{$field_name}[0][value][time]" => '00:00:00', - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('date is invalid', format_string('Invalid day value %date has been caught.', array('%date' => $date_value))); - - $date_value = '2012-12-01'; - $time_value = ''; - $edit = array( - "{$field_name}[0][value][date]" => $date_value, - "{$field_name}[0][value][time]" => $time_value, - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('date is invalid', 'Empty time value has been caught.'); - - $date_value = '2012-12-01'; - $time_value = '49:00:00'; - $edit = array( - "{$field_name}[0][value][date]" => $date_value, - "{$field_name}[0][value][time]" => $time_value, - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('date is invalid', format_string('Invalid hour value %time has been caught.', array('%time' => $time_value))); - - $date_value = '2012-12-01'; - $time_value = '12:99:00'; - $edit = array( - "{$field_name}[0][value][date]" => $date_value, - "{$field_name}[0][value][time]" => $time_value, - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('date is invalid', format_string('Invalid minute value %time has been caught.', array('%time' => $time_value))); - - $date_value = '2012-12-01'; - $time_value = '12:15:99'; - $edit = array( - "{$field_name}[0][value][date]" => $date_value, - "{$field_name}[0][value][time]" => $time_value, - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('date is invalid', format_string('Invalid second value %time has been caught.', array('%time' => $time_value))); - } - - /** - * Renders a entity_test and sets the output in the internal browser. - * - * @param int $id - * The entity_test ID to render. - * @param string $view_mode - * (optional) The view mode to use for rendering. Defaults to 'full'. - * @param bool $reset - * (optional) Whether to reset the entity_test controller cache. Defaults to - * TRUE to simplify testing. - */ - protected function renderTestEntity($id, $view_mode = 'full', $reset = TRUE) { - if ($reset) { - entity_get_controller('entity_test')->resetCache(array($id)); - } - $entity = entity_load('entity_test', $id); - $display = entity_get_display('entity_test', $entity->bundle(), 'full'); - field_attach_prepare_view('entity_test', array($entity->id() => $entity), array($entity->bundle() => $display), $view_mode); - $entity->content = field_attach_view($entity, $display, $view_mode); - - $output = drupal_render($entity->content); - $this->drupalSetContent($output); - $this->verbose($output); - } - -}