diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml index 90813e5..e4821c4 100644 --- a/core/config/schema/core.entity.schema.yml +++ b/core/config/schema/core.entity.schema.yml @@ -304,9 +304,33 @@ field.formatter.settings.uri_link: type: mapping label: 'URI as link display format settings' +field.formatter.settings.timestamp: + type: mapping + label: 'Timestamp display format settings' + mapping: + date_format: + type: string + label: 'Date format' + custom_date_format: + type: string + label: 'Custom date format' + timezone: + type: string + label: 'Timezone' + field.formatter.settings.timestamp_ago: type: mapping label: 'Timestamp ago display format settings' + mapping: + future_format: + type: string + label: 'Future format' + past_format: + type: string + label: 'Past format' + granularity: + type: integer + label: 'Granularity' field.formatter.settings.entity_reference_entity_view: type: mapping diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php index 30dae80..556e4cb 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php @@ -7,12 +7,15 @@ namespace Drupal\Core\Field\Plugin\Field\FieldFormatter; +use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Datetime\DateFormatter; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\FormatterBase; +use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; /** * Plugin implementation of the 'timestamp' formatter as time ago. @@ -37,6 +40,13 @@ class TimestampAgoFormatter extends FormatterBase implements ContainerFactoryPlu protected $dateFormatter; /** + * The current Request object. + * + * @var \Symfony\Component\HttpFoundation\Request + */ + protected $request; + + /** * Constructs a TimestampAgoFormatter object. * * @param string $plugin_id @@ -55,11 +65,14 @@ class TimestampAgoFormatter extends FormatterBase implements ContainerFactoryPlu * Any third party settings. * @param \Drupal\Core\Datetime\DateFormatter $date_formatter * The date formatter service. + * @param \Symfony\Component\HttpFoundation\Request $request + * The current request. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter) { + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, Request $request) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); $this->dateFormatter = $date_formatter; + $this->request = $request; } /** @@ -75,19 +88,77 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], - $container->get('date.formatter') + $container->get('date.formatter'), + $container->get('request_stack')->getCurrentRequest() ); } /** * {@inheritdoc} */ + public static function defaultSettings() { + return array( + 'future_format' => '@time hence', + 'past_format' => '@time ago', + 'granularity' => 2, + ) + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $elements = parent::settingsForm($form, $form_state); + + $form['future_format'] = array( + '#type' => 'textfield', + '#title' => $this->t('Future format'), + '#default_value' => $this->getSetting('future_format'), + '#description' => $this->t('The format for timestamps in the future. Use @time where you want the time to appear.'), + ); + + $form['past_format'] = array( + '#type' => 'textfield', + '#title' => $this->t('Past format'), + '#default_value' => $this->getSetting('past_format'), + '#description' => $this->t('The format for timestamps in the past. Use @time where you want the time to appear.'), + ); + + $elements['granularity'] = array( + '#type' => 'number', + '#title' => $this->t('Granularity'), + '#description' => $this->t('How many time units should be shown in the formatted output.'), + '#default_value' => $this->getSetting('granularity') ?: 2, + '#min' => 1, + '#max' => 6, + ); + + return $elements; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = parent::settingsSummary(); + + $future_date = strtotime('1 year 1 month 1 week 1 day 1 hour 1 minute'); + $past_date = strtotime('-1 year -1 month -1 week -1 day -1 hour -1 minute'); + $summary[] = t('Future date: %display', array('%display' => $this->formatTimestamp($future_date))); + $summary[] = t('Past date: %display', array('%display' => $this->formatTimestamp($past_date))); + + return $summary; + } + + /** + * {@inheritdoc} + */ public function viewElements(FieldItemListInterface $items) { $elements = array(); foreach ($items as $delta => $item) { if ($item->value) { - $updated = $this->t('@time ago', array('@time' => $this->dateFormatter->formatTimeDiffSince($item->value))); + $updated = $this->formatTimestamp($item->value); } else { $updated = $this->t('never'); @@ -99,4 +170,26 @@ public function viewElements(FieldItemListInterface $items) { return $elements; } + /** + * Creates a formatted timestamp value as a string. + * + * @param int $timestamp + * A UNIX timestamp to format. + * + * @return string + * The formatted timestamp string using the past or future format setting. + */ + protected function formatTimestamp($timestamp) { + $granularity = $this->getSetting('granularity'); + $options = ['granularity' => $granularity]; + $interval = $this->request->server->get('REQUEST_TIME') - $timestamp; + + if ($interval > 0) { + return SafeMarkup::format($this->getSetting('past_format'), ['@time' => $this->dateFormatter->formatTimeDiffSince($timestamp, $options)]); + } + else { + return SafeMarkup::format($this->getSetting('future_format'), ['@time' => $this->dateFormatter->formatTimeDiffUntil($timestamp, $options)]); + } + } + } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php index cb28315..bfd9f55 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php @@ -7,8 +7,14 @@ namespace Drupal\Core\Field\Plugin\Field\FieldFormatter; -use Drupal\Core\Field\FormatterBase; +use Drupal\Core\Datetime\DateFormatter; +use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Field\FormatterBase; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Plugin implementation of the 'timestamp' formatter. @@ -23,7 +29,138 @@ * } * ) */ -class TimestampFormatter extends FormatterBase { +class TimestampFormatter extends FormatterBase implements ContainerFactoryPluginInterface { + + /** + * The date formatter service. + * + * @var \Drupal\Core\Datetime\DateFormatter + */ + protected $dateFormatter; + + /** + * The date format entity storage. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $dateFormatStorage; + + /** + * Constructs a new TimestampFormatter. + * + * @param string $plugin_id + * The plugin_id for the formatter. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition + * The definition of the field to which the formatter is associated. + * @param array $settings + * The formatter settings. + * @param string $label + * The formatter label display setting. + * @param string $view_mode + * The view mode. + * @param array $third_party_settings + * Third party settings. + * @param \Drupal\Core\Datetime\DateFormatter $date_formatter + * The date formatter service. + * @param \Drupal\Core\Entity\EntityStorageInterface $date_format_storage + * The date storage. + */ + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, EntityStorageInterface $date_format_storage) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + + $this->dateFormatter = $date_formatter; + $this->dateFormatStorage = $date_format_storage; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $plugin_id, + $plugin_definition, + $configuration['field_definition'], + $configuration['settings'], + $configuration['label'], + $configuration['view_mode'], + $configuration['third_party_settings'], + $container->get('date.formatter'), + $container->get('entity.manager')->getStorage('date_format') + ); + } + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + return array( + 'date_format' => 'medium', + 'custom_date_format' => '', + 'timezone' => '', + ) + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $elements = parent::settingsForm($form, $form_state); + + $date_formats = array(); + + foreach ($this->dateFormatStorage->loadMultiple() as $machine_name => $value) { + $date_formats[$machine_name] = $this->t('@name format: @date', array('@name' => $value->label(), '@date' => $this->dateFormatter->format(REQUEST_TIME, $machine_name))); + } + + $date_formats['custom'] = $this->t('Custom'); + + $elements['date_format'] = array( + '#type' => 'select', + '#title' => $this->t('Date format'), + '#options' => $date_formats, + '#default_value' => $this->getSetting('date_format') ?: 'medium', + ); + + $elements['custom_date_format'] = array( + '#type' => 'textfield', + '#title' => $this->t('Custom date format'), + '#description' => $this->t('If "Custom", see the PHP docs for date formats. Otherwise, enter the number of different time units to display, which defaults to 2.'), + '#default_value' => $this->getSetting('custom_date_format') ?: '', + ); + + $elements['custom_date_format']['#states']['visible'][] = array( + ':input[name="options[settings][date_format]"]' => array('value' => 'custom'), + ); + + $elements['timezone'] = array( + '#type' => 'select', + '#title' => $this->t('Time zone'), + '#description' => $this->t('Time zone to be used for date output.'), + '#options' => array('' => $this->t('- Default site/user time zone -')) + system_time_zones(FALSE), + '#default_value' => $this->getSetting('timezone'), + ); + + return $elements; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = parent::settingsSummary(); + + $summary[] = $this->t('Date format: @date_format', array('@date_format' => $this->getSetting('date_format'))); + if ($custom_date_format = $this->getSetting('custom_date_format')) { + $summary[] = $this->t('Custom date format: @custom_date_format', array('@custom_date_format' => $custom_date_format)); + } + if ($timezone = $this->getSetting('timezone')) { + $summary[] = $this->t('Time zone: @timezone', array('@timezone' => $timezone)); + } + + return $summary; + } /** * {@inheritdoc} @@ -31,6 +168,17 @@ class TimestampFormatter extends FormatterBase { public function viewElements(FieldItemListInterface $items) { $elements = array(); + $date_format = $this->getSetting('date_format'); + $custom_date_format = ''; + $timezone = $this->getSetting('timezone') ?: NULL; + $langcode = NULL; + + // If an RFC2822 date format is requested, then the month and day have to + // be in English. @see http://www.faqs.org/rfcs/rfc2822.html + if ($date_format === 'custom' && ($custom_date_format = $this->getSetting('custom_date_format')) === 'r') { + $langcode = 'en'; + } + foreach ($items as $delta => $item) { $elements[$delta] = [ '#cache' => [ @@ -38,7 +186,7 @@ public function viewElements(FieldItemListInterface $items) { 'timezone', ], ], - '#markup' => format_date($item->value) + '#markup' => $this->dateFormatter->format($item->value, $date_format, $custom_date_format, $timezone, $langcode), ]; } diff --git a/core/modules/datetime/config/schema/datetime.schema.yml b/core/modules/datetime/config/schema/datetime.schema.yml index 0718e04..406a2fd 100644 --- a/core/modules/datetime/config/schema/datetime.schema.yml +++ b/core/modules/datetime/config/schema/datetime.schema.yml @@ -23,8 +23,15 @@ field.value.datetime: type: string label: 'Default date value' -field.formatter.settings.datetime_default: +field.formatter.settings.datetime_base: type: mapping + mapping: + timezone_override: + type: string + label: 'Time zone override' + +field.formatter.settings.datetime_default: + type: field.formatter.settings.datetime_base label: 'Datetime default display format settings' mapping: format_type: @@ -32,9 +39,33 @@ field.formatter.settings.datetime_default: label: 'Date format' field.formatter.settings.datetime_plain: - type: mapping + type: field.formatter.settings.datetime_base label: 'Datetime plain display format settings' +field.formatter.settings.datetime_custom: + type: field.formatter.settings.datetime_base + label: 'Datetime custom display format settings' + mapping: + date_format: + type: string + label: 'Date/time format' + translatable: true + translation context: 'PHP date format' + +field.formatter.settings.datetime_time_ago: + type: mapping + label: 'Datetime time ago display format settings' + mapping: + future_format: + type: string + label: 'Future format' + past_format: + type: string + label: 'Past format' + granularity: + type: integer + label: 'Granularity' + field.widget.settings.datetime_datelist: type: mapping label: 'Datetime select list display format settings' diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeCustomFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeCustomFormatter.php new file mode 100644 index 0000000..4115c33 --- /dev/null +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeCustomFormatter.php @@ -0,0 +1,98 @@ + DATETIME_DATETIME_STORAGE_FORMAT, + ) + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function viewElements(FieldItemListInterface $items) { + $elements = array(); + + foreach ($items as $delta => $item) { + $output = ''; + if (!empty($item->date)) { + /** @var \Drupal\Core\Datetime\DrupalDateTime $date */ + $date = $item->date; + + if ($this->getFieldSetting('datetime_type') == 'date') { + // A date without time will pick up the current time, use the default. + datetime_date_default_time($date); + } + $this->setTimeZone($date); + + $output = $date->format($this->getSetting('date_format'), $this->getFormatSettings()); + } + $elements[$delta] = [ + '#markup' => $output, + '#cache' => [ + 'contexts' => [ + 'timezone', + ], + ], + ]; + } + + return $elements; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + + $form['date_format'] = array( + '#type' => 'textfield', + '#title' => $this->t('Date/time format'), + '#description' => $this->t('A user-defined date/time format. See the PHP manual for available options.', array('@url' => 'http://php.net/manual/function.date.php')), + '#default_value' => $this->getSetting('date_format'), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = parent::settingsSummary(); + + $date = new DrupalDateTime(); + $this->setTimeZone($date); + $summary[] = $date->format($this->getSetting('date_format'), $this->getFormatSettings()); + + return $summary; + } + +} diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php index 0f30d5c..8e85e88 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php @@ -14,11 +14,10 @@ use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\Core\Field\FormatterBase; use Symfony\Component\DependencyInjection\ContainerInterface; /** - * Plugin implementation of the 'datetime_default' formatter. + * Plugin implementation of the 'Default' formatter for 'datetime' fields. * * @FieldFormatter( * id = "datetime_default", @@ -28,7 +27,7 @@ * } * ) */ -class DateTimeDefaultFormatter extends FormatterBase implements ContainerFactoryPluginInterface { +class DateTimeDefaultFormatter extends DateTimeFormatterBase implements ContainerFactoryPluginInterface { /** * {@inheritdoc} @@ -47,11 +46,11 @@ public static function defaultSettings() { protected $dateFormatter; /** - * The date storage. + * The date format entity storage. * * @var \Drupal\Core\Entity\EntityStorageInterface */ - protected $dateStorage; + protected $dateFormatStorage; /** * Constructs a new DateTimeDefaultFormatter. @@ -72,14 +71,14 @@ public static function defaultSettings() { * Third party settings. * @param \Drupal\Core\Datetime\DateFormatter $date_formatter * The date formatter service. - * @param \Drupal\Core\Entity\EntityStorageInterface $date_storage - * The date storage. + * @param \Drupal\Core\Entity\EntityStorageInterface $date_format_storage + * The date format entity storage. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, EntityStorageInterface $date_storage) { + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, EntityStorageInterface $date_format_storage) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); $this->dateFormatter = $date_formatter; - $this->dateStorage = $date_storage; + $this->dateFormatStorage = $date_format_storage; } /** @@ -103,26 +102,25 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items) { - $elements = array(); foreach ($items as $delta => $item) { - - $formatted_date = ''; + $output = ''; $iso_date = ''; if ($item->date) { + /** @var \Drupal\Core\Datetime\DrupalDateTime $date */ $date = $item->date; // Create the ISO date in Universal Time. $iso_date = $date->format("Y-m-d\TH:i:s") . 'Z'; - // The formatted output will be in local time. - $date->setTimeZone(timezone_open(drupal_get_user_timezone())); if ($this->getFieldSetting('datetime_type') == 'date') { // A date without time will pick up the current time, use the default. datetime_date_default_time($date); } - $formatted_date = $this->dateFormat($date); + $this->setTimeZone($date); + + $output = $this->formatDate($date, $this->getFormatSettings()); } // Display the date using theme datetime. @@ -133,7 +131,8 @@ public function viewElements(FieldItemListInterface $items) { ], ], '#theme' => 'time', - '#text' => $formatted_date, + '#text' => $output, + '#html' => FALSE, '#attributes' => array( 'datetime' => $iso_date, ), @@ -159,23 +158,27 @@ public function viewElements(FieldItemListInterface $items) { * @return string * A formatted date string using the chosen format. */ - function dateFormat($date) { + protected function formatDate($date) { $format_type = $this->getSetting('format_type'); - return $this->dateFormatter->format($date->getTimestamp(), $format_type); + $timezone = $this->getSetting('timezone_override'); + return $this->dateFormatter->format($date->getTimestamp(), $format_type, '', $timezone != '' ? $timezone : null); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + $time = new DrupalDateTime(); $format_types = $this->dateStorage->loadMultiple(); + $options = []; foreach ($format_types as $type => $type_info) { $format = $this->dateFormatter->format($time->format('U'), $type); $options[$type] = $type_info->label() . ' (' . $format . ')'; } - $elements['format_type'] = array( + $form['format_type'] = array( '#type' => 'select', '#title' => t('Date format'), '#description' => t("Choose a format for displaying the date. Be sure to set a format appropriate for the field, i.e. omitting time for a field that only has a date."), @@ -183,16 +186,18 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#default_value' => $this->getSetting('format_type'), ); - return $elements; + return $form; } /** * {@inheritdoc} */ public function settingsSummary() { - $summary = array(); + $summary = parent::settingsSummary(); + $date = new DrupalDateTime(); - $summary[] = t('Format: @display', array('@display' => $this->dateFormat($date, FALSE))); + $summary[] = t('Format: @display', array('@display' => $this->formatDate($date, $this->getFormatSettings()))); + return $summary; } diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php new file mode 100644 index 0000000..fefd065 --- /dev/null +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php @@ -0,0 +1,85 @@ + '', + ) + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + + $form['timezone_override'] = array( + '#type' => 'select', + '#title' => $this->t('Time zone override'), + '#description' => $this->t('The time zone selected here will always be used'), + '#options' => system_time_zones(TRUE), + '#default_value' => $this->getSetting('timezone_override'), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = parent::settingsSummary(); + + if ($override = $this->getSetting('timezone_override')) { + $summary[] = $this->t('Time zone: @timezone', array('@timezone' => $override)); + } + + return $summary; + } + + /** + * Sets the current user's or overridden time zone on a DrupalDateTime object. + * + * @param \Drupal\Core\Datetime\DrupalDateTime $date + * A DrupalDateTime object. + */ + protected function setTimeZone(DrupalDateTime $date) { + $date->setTimeZone(timezone_open(drupal_get_user_timezone())); + } + + /** + * Gets a settings array suitable for DrupalDateTime::format(). + * + * @return array + * The settings array that can be passed to DrupalDateTime::format(). + */ + protected function getFormatSettings() { + $settings = []; + + if ($this->getSetting('timezone_override') != '') { + $settings['timezone'] = $this->getSetting('timezone_override'); + } + + return $settings; + } + +} diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimePlainFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimePlainFormatter.php index 3f68a7f..79e3270 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimePlainFormatter.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimePlainFormatter.php @@ -7,11 +7,10 @@ namespace Drupal\datetime\Plugin\Field\FieldFormatter; -use Drupal\Core\Field\FormatterBase; use Drupal\Core\Field\FieldItemListInterface; /** - * Plugin implementation of the 'datetime_plain' formatter. + * Plugin implementation of the 'Plain' formatter for 'datetime' fields. * * @FieldFormatter( * id = "datetime_plain", @@ -21,30 +20,31 @@ * } *) */ -class DateTimePlainFormatter extends FormatterBase { +class DateTimePlainFormatter extends DateTimeFormatterBase { /** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items) { - $elements = array(); foreach ($items as $delta => $item) { - $output = ''; if (!empty($item->date)) { - // The date was created and verified during field_load(), so it is safe - // to use without further inspection. + /** @var \Drupal\Core\Datetime\DrupalDateTime $date */ $date = $item->date; - $date->setTimeZone(timezone_open(drupal_get_user_timezone())); - $format = DATETIME_DATETIME_STORAGE_FORMAT; + if ($this->getFieldSetting('datetime_type') == 'date') { // A date without time will pick up the current time, use the default. datetime_date_default_time($date); $format = DATETIME_DATE_STORAGE_FORMAT; } - $output = $date->format($format); + else { + $format = DATETIME_DATETIME_STORAGE_FORMAT; + } + $this->setTimeZone($date); + + $output = $date->format($format, $this->getFormatSettings()); } $elements[$delta] = [ '#cache' => [ diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php new file mode 100644 index 0000000..6bc2639 --- /dev/null +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php @@ -0,0 +1,196 @@ +dateFormatter = $date_formatter; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + $settings = array( + 'future_format' => '@time hence', + 'past_format' => '@time ago', + 'granularity' => 2, + ) + parent::defaultSettings(); + + return $settings; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $plugin_id, + $plugin_definition, + $configuration['field_definition'], + $configuration['settings'], + $configuration['label'], + $configuration['view_mode'], + $configuration['third_party_settings'], + $container->get('date.formatter'), + $container->get('request_stack')->getCurrentRequest() + ); + } + + /** + * {@inheritdoc} + */ + public function viewElements(FieldItemListInterface $items) { + $elements = array(); + + foreach ($items as $delta => $item) { + $date = $item->date; + $output = ''; + if (!empty($item->date)) { + if ($this->getFieldSetting('datetime_type') == 'date') { + // A date without time will pick up the current time, use the default. + datetime_date_default_time($date); + } + $output = $this->formatDate($date); + } + $elements[$delta] = array('#markup' => $output); + } + + return $elements; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + + $form['future_format'] = array( + '#type' => 'textfield', + '#title' => $this->t('Future format'), + '#default_value' => $this->getSetting('future_format'), + '#description' => $this->t('The format for dates in the future. Use @time where you want the time to appear.'), + ); + + $form['past_format'] = array( + '#type' => 'textfield', + '#title' => $this->t('Past format'), + '#default_value' => $this->getSetting('past_format'), + '#description' => $this->t('The format for dates in the past. Use @time where you want the time to appear.'), + ); + + $form['granularity'] = array( + '#type' => 'number', + '#title' => 'Interval', + '#default_value' => $this->getSetting('granularity'), + '#description' => $this->t('How many time units should be shown in the formatted output.'), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = parent::settingsSummary(); + + $future_date = new DrupalDateTime('1 year 1 month 1 week 1 day 1 hour 1 minute'); + $past_date = new DrupalDateTime('-1 year -1 month -1 week -1 day -1 hour -1 minute'); + $summary[] = t('Future date: %display', array('%display' => $this->formatDate($future_date))); + $summary[] = t('Past date: %display', array('%display' => $this->formatDate($past_date))); + + return $summary; + } + + /** + * Creates a formatted date value as a string. + * + * @param \Drupal\Core\Datetime\DrupalDateTime|object $date + * A date/time object. + * + * @return string + * The formatted date/time string using the past or future format setting. + */ + protected function formatDate(DrupalDateTime $date) { + $granularity = $this->getSetting('granularity'); + $timestamp = $date->getTimestamp(); + $options = ['granularity' => $granularity]; + $interval = $this->request->server->get('REQUEST_TIME') - $timestamp; + + if ($interval > 0) { + return SafeMarkup::format($this->getSetting('past_format'), ['@time' => $this->dateFormatter->formatTimeDiffSince($timestamp, $options)]); + } + else { + return SafeMarkup::format($this->getSetting('future_format'), ['@time' => $this->dateFormatter->formatTimeDiffUntil($timestamp, $options)]); + } + } + +} diff --git a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeWidgetBase.php b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeWidgetBase.php index 32d3668..dfe750e 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeWidgetBase.php +++ b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeWidgetBase.php @@ -43,12 +43,12 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen $date = $items[$delta]->date; // 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') == DateTimeItem::DATETIME_TYPE_DATE) { // A date without time will pick up the current time, use the default // time. datetime_date_default_time($date); } + $date->setTimezone(new \DateTimeZone($element['value']['#date_timezone'])); $element['value']['#default_value'] = $date; } diff --git a/core/modules/datetime/src/Tests/DateTimeFieldTest.php b/core/modules/datetime/src/Tests/DateTimeFieldTest.php index f3fcae1..0cb226b 100644 --- a/core/modules/datetime/src/Tests/DateTimeFieldTest.php +++ b/core/modules/datetime/src/Tests/DateTimeFieldTest.php @@ -7,6 +7,7 @@ namespace Drupal\datetime\Tests; +use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\Unicode; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\Core\Datetime\DrupalDateTime; @@ -27,6 +28,11 @@ class DateTimeFieldTest extends WebTestBase { public static $modules = array('node', 'entity_test', 'datetime', 'field_ui'); /** + * The default display settings to use for the formatters. + */ + protected $defaultSettings; + + /** * An array of display options to pass to entity_get_display() * * @var array @@ -47,9 +53,18 @@ class DateTimeFieldTest extends WebTestBase { */ protected $field; + /** + * {@inheritdoc} + */ protected function setUp() { parent::setUp(); + // Set an explicit site timezone, and disallow per-user timezones. + $this->config('system.date') + ->set('timezone.user.configurable', 0) + ->set('timezone.default', 'Asia/Tokyo') + ->save(); + $web_user = $this->drupalCreateUser(array( 'access content', 'view test entity', @@ -81,10 +96,14 @@ protected function setUp() { )) ->save(); + $this->defaultSettings = array( + 'timezone_override' => '', + ); + $this->displayOptions = array( 'type' => 'datetime_default', 'label' => 'hidden', - 'settings' => array('format_type' => 'medium'), + 'settings' => array('format_type' => 'medium') + $this->defaultSettings, ); entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') ->setComponent($field_name, $this->displayOptions) @@ -103,9 +122,17 @@ function testDateField() { $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/h4[contains(@class, "form-required")]', TRUE, 'Required markup found'); $this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Time element not found.'); - // Submit a valid date and ensure it is accepted. + // Build up a date in the UTC timezone. $value = '2012-12-31 00:00:00'; - $date = new DrupalDateTime($value); + $date = new DrupalDateTime($value, 'UTC'); + + // The expected values will use the default time. + datetime_date_default_time($date); + + // Update the timezone to the system default. + $date->setTimezone(timezone_open(drupal_get_user_timezone())); + + // Submit a valid date and ensure it is accepted. $date_format = entity_load('date_format', 'html_date')->getPattern(); $time_format = entity_load('date_format', 'html_time')->getPattern(); @@ -119,9 +146,6 @@ function testDateField() { $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'), @@ -129,7 +153,7 @@ function testDateField() { foreach ($options as $setting => $values) { foreach ($values as $new_value) { // Update the entity display settings. - $this->displayOptions['settings'] = array($setting => $new_value); + $this->displayOptions['settings'] = array($setting => $new_value) + $this->defaultSettings; entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') ->setComponent($field_name, $this->displayOptions) ->save(); @@ -140,7 +164,7 @@ function testDateField() { // 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))); + $this->assertText($expected, SafeMarkup::format('Formatted date field using %value format displayed as %expected.', array('%value' => $new_value, '%expected' => $expected))); break; } } @@ -148,13 +172,65 @@ function testDateField() { // Verify that the plain formatter works. $this->displayOptions['type'] = 'datetime_plain'; - $this->displayOptions['settings'] = array(); + $this->displayOptions['settings'] = $this->defaultSettings; entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') ->setComponent($field_name, $this->displayOptions) ->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))); + $this->assertText($expected, SafeMarkup::format('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected))); + + // Verify that the 'datetime_custom' formatter works. + $this->displayOptions['type'] = 'datetime_custom'; + $this->displayOptions['settings'] = array('date_format' => 'm/d/Y') + $this->defaultSettings; + entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') + ->setComponent($field_name, $this->displayOptions) + ->save(); + $expected = $date->format($this->displayOptions['settings']['date_format']); + $this->renderTestEntity($id); + $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_custom format displayed as %expected.', array('%expected' => $expected))); + + // Verify that the 'datetime_time_ago' formatter works for intervals in the + // past. First update the test entity so that the date difference always + // has the same interval. Since the database always stores UTC, and the + // interval will use this, force the test date to use UTC and not the local + // or user timezome. + $entity = entity_load('entity_test', $id); + $field_name = $this->fieldStorage->getName(); + $date = DrupalDateTime::createFromTimestamp(REQUEST_TIME - 87654321, 'UTC'); + $entity->{$field_name}->value = $date->format($date_format); + $entity->save(); + + $this->displayOptions['type'] = 'datetime_time_ago'; + $this->displayOptions['settings'] = array( + 'future_format' => '@time in the future', + 'past_format' => '@time in the past', + 'granularity' => 3, + ); + entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') + ->setComponent($field_name, $this->displayOptions) + ->save(); + $expected = '2 years 9 months 1 week in the past'; + $this->renderTestEntity($id); + $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_time_ago format displayed as %expected.', array('%expected' => $expected))); + + // Verify that the 'datetime_time_ago' formatter works for intervals in the + // future. First update the test entity so that the date difference always + // has the same interval. Since the database always stores UTC, and the + // interval will use this, force the test date to use UTC and not the local + // or user timezome. + $entity = entity_load('entity_test', $id); + $field_name = $this->fieldStorage->getName(); + $date = DrupalDateTime::createFromTimestamp(REQUEST_TIME + 87654321, 'UTC'); + $entity->{$field_name}->value = $date->format($date_format); + $entity->save(); + + entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') + ->setComponent($field_name, $this->displayOptions) + ->save(); + $expected = '2 years 9 months 1 week in the future'; + $this->renderTestEntity($id); + $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_time_ago format displayed as %expected.', array('%expected' => $expected))); } /** @@ -171,9 +247,14 @@ function testDatetimeField() { $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. + // Build up a date in the UTC timezone. $value = '2012-12-31 00:00:00'; - $date = new DrupalDateTime($value); + $date = new DrupalDateTime($value, 'UTC'); + + // Update the timezone to the system default. + $date->setTimezone(timezone_open(drupal_get_user_timezone())); + + // Submit a valid date and ensure it is accepted. $date_format = entity_load('date_format', 'html_date')->getPattern(); $time_format = entity_load('date_format', 'html_time')->getPattern(); @@ -195,7 +276,7 @@ function testDatetimeField() { foreach ($options as $setting => $values) { foreach ($values as $new_value) { // Update the entity display settings. - $this->displayOptions['settings'] = array($setting => $new_value); + $this->displayOptions['settings'] = array($setting => $new_value) + $this->defaultSettings; entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') ->setComponent($field_name, $this->displayOptions) ->save(); @@ -206,7 +287,7 @@ function testDatetimeField() { // 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))); + $this->assertText($expected, SafeMarkup::format('Formatted date field using %value format displayed as %expected.', array('%value' => $new_value, '%expected' => $expected))); break; } } @@ -214,13 +295,75 @@ function testDatetimeField() { // Verify that the plain formatter works. $this->displayOptions['type'] = 'datetime_plain'; - $this->displayOptions['settings'] = array(); + $this->displayOptions['settings'] = $this->defaultSettings; entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') ->setComponent($field_name, $this->displayOptions) ->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))); + $this->assertText($expected, SafeMarkup::format('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected))); + + // Verify that the 'datetime_custom' formatter works. + $this->displayOptions['type'] = 'datetime_custom'; + $this->displayOptions['settings'] = array('date_format' => 'm/d/Y g:i:s A') + $this->defaultSettings; + entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') + ->setComponent($field_name, $this->displayOptions) + ->save(); + $expected = $date->format($this->displayOptions['settings']['date_format']); + $this->renderTestEntity($id); + $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_custom format displayed as %expected.', array('%expected' => $expected))); + + // Verify that the 'timezone_override' setting works. + $this->displayOptions['type'] = 'datetime_custom'; + $this->displayOptions['settings'] = array('date_format' => 'm/d/Y g:i:s A', 'timezone_override' => 'America/New_York') + $this->defaultSettings; + entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') + ->setComponent($field_name, $this->displayOptions) + ->save(); + $expected = $date->format($this->displayOptions['settings']['date_format'], array('timezone' => 'America/New_York')); + $this->renderTestEntity($id); + $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_custom format displayed as %expected.', array('%expected' => $expected))); + + // Verify that the 'datetime_time_ago' formatter works for intervals in the + // past. First update the test entity so that the date difference always + // has the same interval. Since the database always stores UTC, and the + // interval will use this, force the test date to use UTC and not the local + // or user timezome. + $entity = entity_load('entity_test', $id); + $field_name = $this->fieldStorage->getName(); + $date = DrupalDateTime::createFromTimestamp(REQUEST_TIME - 87654321, 'UTC'); + $entity->{$field_name}->value = $date->format(DATETIME_DATETIME_STORAGE_FORMAT); + $entity->save(); + + $this->displayOptions['type'] = 'datetime_time_ago'; + $this->displayOptions['settings'] = array( + 'future_format' => '@time from now', + 'past_format' => '@time earlier', + 'granularity' => 3, + ); + entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') + ->setComponent($field_name, $this->displayOptions) + ->save(); + $expected = '2 years 9 months 1 week earlier'; + $this->renderTestEntity($id); + $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_time_ago format displayed as %expected.', array('%expected' => $expected))); + + // Verify that the 'datetime_time_ago' formatter works for intervals in the + // future. First update the test entity so that the date difference always + // has the same interval. Since the database always stores UTC, and the + // interval will use this, force the test date to use UTC and not the local + // or user timezome. + $entity = entity_load('entity_test', $id); + $field_name = $this->fieldStorage->getName(); + $date = DrupalDateTime::createFromTimestamp(REQUEST_TIME + 87654321, 'UTC'); + $entity->{$field_name}->value = $date->format(DATETIME_DATETIME_STORAGE_FORMAT); + $entity->save(); + + entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') + ->setComponent($field_name, $this->displayOptions) + ->save(); + $expected = '2 years 9 months 1 week from now'; + $this->renderTestEntity($id); + $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_time_ago format displayed as %expected.', array('%expected' => $expected))); } /** @@ -391,7 +534,6 @@ function testDefaultValue() { * Test that invalid values are caught and marked as invalid. */ function testInvalidField() { - // Change the field to a datetime field. $this->fieldStorage->setSetting('datetime_type', 'datetime'); $this->fieldStorage->save(); diff --git a/core/modules/field/src/Tests/Timestamp/TimestampFormatterTest.php b/core/modules/field/src/Tests/Timestamp/TimestampFormatterTest.php new file mode 100644 index 0000000..6aa1588 --- /dev/null +++ b/core/modules/field/src/Tests/Timestamp/TimestampFormatterTest.php @@ -0,0 +1,194 @@ +installConfig(['system']); + $this->installConfig(['field']); + $this->installEntitySchema('entity_test'); + + $this->entityType = 'entity_test'; + $this->bundle = $this->entityType; + $this->fieldName = Unicode::strtolower($this->randomMachineName()); + + $field_storage = FieldStorageConfig::create([ + 'field_name' => $this->fieldName, + 'entity_type' => $this->entityType, + 'type' => 'timestamp', + ]); + $field_storage->save(); + + $instance = FieldConfig::create([ + 'field_storage' => $field_storage, + 'bundle' => $this->bundle, + 'label' => $this->randomMachineName(), + ]); + $instance->save(); + + $this->display = entity_get_display($this->entityType, $this->bundle, 'default') + ->setComponent($this->fieldName, [ + 'type' => 'boolean', + 'settings' => [], + ]); + $this->display->save(); + } + + /** + * Renders fields of a given entity with a given display. + * + * @param \Drupal\Core\Entity\FieldableEntityInterface $entity + * The entity object with attached fields to render. + * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display + * The display to render the fields in. + * + * @return string + * The rendered entity fields. + */ + protected function renderEntityFields(FieldableEntityInterface $entity, EntityViewDisplayInterface $display) { + $content = $display->build($entity); + $content = $this->render($content); + return $content; + } + + /** + * Tests TimestampFormatter. + */ + protected function testTimestampFormatter() { + $data = []; + + // Test standard formats. + $date_formats = array_keys(\Drupal::entityManager()->getStorage('date_format')->loadMultiple()); + + foreach ($date_formats as $date_format) { + $data[] = ['date_format' => $date_format, 'custom_date_format' => '', 'timezone' => '']; + } + + $data[] = ['date_format' => 'custom', 'custom_date_format' => 'r', 'timezone' => '']; + $data[] = ['date_format' => 'custom', 'custom_date_format' => 'e', 'timezone' => 'Asia/Tokyo']; + + foreach ($data as $settings) { + list($date_format, $custom_date_format, $timezone) = array_values($settings); + if (empty($timezone)) { + $timezone = NULL; + } + + $value = REQUEST_TIME - 87654321; + $expected = \Drupal::service('date.formatter')->format($value, $date_format, $custom_date_format, $timezone); + + $component = $this->display->getComponent($this->fieldName); + $component['type'] = 'timestamp'; + $component['settings'] = $settings; + $this->display->setComponent($this->fieldName, $component); + + $entity = EntityTest::create([]); + $entity->{$this->fieldName}->value = $value; + + $this->renderEntityFields($entity, $this->display); + $this->assertRaw($expected); + } + } + + /** + * Tests TimestampAgoFormatter. + */ + protected function testTimestampAgoFormatter() { + $data = []; + + foreach (array(1,2,3,4,5,6) as $granularity) { + $data[] = [ + 'future_format' => '@time hence', + 'past_format' => '@time ago', + 'granularity' => $granularity, + ]; + } + + foreach ($data as $settings) { + $future_format = $settings['future_format']; + $past_format = $settings['past_format']; + $granularity = $settings['granularity']; + $request_time = \Drupal::requestStack()->getCurrentRequest()->server->get('REQUEST_TIME'); + + // Test a timestamp in the past + $value = $request_time - 87654321; + $expected = SafeMarkup::format($past_format, ['@time' => \Drupal::service('date.formatter')->formatTimeDiffSince($value, ['granularity' => $granularity])]); + + $component = $this->display->getComponent($this->fieldName); + $component['type'] = 'timestamp_ago'; + $component['settings'] = $settings; + $this->display->setComponent($this->fieldName, $component); + + $entity = EntityTest::create([]); + $entity->{$this->fieldName}->value = $value; + + $this->renderEntityFields($entity, $this->display); + $this->assertRaw($expected); + + // Test a timestamp in the future + $value = $request_time + 87654321; + $expected = SafeMarkup::format($future_format, ['@time' => \Drupal::service('date.formatter')->formatTimeDiffUntil($value, ['granularity' => $granularity])]); + + $component = $this->display->getComponent($this->fieldName); + $component['type'] = 'timestamp_ago'; + $component['settings'] = $settings; + $this->display->setComponent($this->fieldName, $component); + + $entity = EntityTest::create([]); + $entity->{$this->fieldName}->value = $value; + + $this->renderEntityFields($entity, $this->display); + $this->assertRaw($expected); + } + } + +} diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_field_formatter_settings.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_field_formatter_settings.yml index c5165b3..594ff4b 100644 --- a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_field_formatter_settings.yml +++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_field_formatter_settings.yml @@ -231,14 +231,19 @@ process: date: default: format_type: fallback + timezone_override: '' format_interval: format_type: fallback + timezone_override: '' long: format_type: long + timezone_override: '' medium: format_type: medium + timezone_override: '' short: format_type: short + timezone_override: '' text: trimmed: trim_length: 600 diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldFormatterSettingsTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldFormatterSettingsTest.php index eb26f9c..7780b2c 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldFormatterSettingsTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldFormatterSettingsTest.php @@ -196,9 +196,10 @@ public function testEntityDisplaySettings() { $this->assertIdentical($expected, $component); // Test date field. + $defaults = array('format_type' => 'fallback', 'timezone_override' => '',); $expected['weight'] = 10; $expected['type'] = 'datetime_default'; - $expected['settings'] = array('format_type' => 'fallback'); + $expected['settings'] = array('format_type' => 'fallback') + $defaults; $component = $display->getComponent('field_test_date'); $this->assertIdentical($expected, $component); $display = entity_load('entity_view_display', 'node.story.default'); @@ -212,13 +213,13 @@ public function testEntityDisplaySettings() { $component = $display->getComponent('field_test_datestamp'); $this->assertIdentical($expected, $component); $display = entity_load('entity_view_display', 'node.story.teaser'); - $expected['settings'] = array('format_type' => 'medium'); + $expected['settings'] = array('format_type' => 'medium') + $defaults; $component = $display->getComponent('field_test_datestamp'); $this->assertIdentical($expected, $component); // Test datetime field. $expected['weight'] = 12; - $expected['settings'] = array('format_type' => 'short'); + $expected['settings'] = array('format_type' => 'short') + $defaults; $component = $display->getComponent('field_test_datetime'); $this->assertIdentical($expected, $component); $display = entity_load('entity_view_display', 'node.story.default');