upgrades core to 8.4.2
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
name: 'Datetime Range'
|
||||
type: module
|
||||
description: 'Provides the ability to store end dates.'
|
||||
package: Core (Experimental)
|
||||
package: Field types
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
dependencies:
|
||||
- datetime
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
namespace Drupal\datetime_range;
|
||||
|
||||
use Drupal\Core\Datetime\DrupalDateTime;
|
||||
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
|
||||
/**
|
||||
* Provides friendly methods for datetime range.
|
||||
@@ -11,68 +10,40 @@ use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
|
||||
trait DateTimeRangeTrait {
|
||||
|
||||
/**
|
||||
* Creates a render array from a date object.
|
||||
*
|
||||
* @param \Drupal\Core\Datetime\DrupalDateTime $date
|
||||
* A date object.
|
||||
*
|
||||
* @return array
|
||||
* A render array.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildDate(DrupalDateTime $date) {
|
||||
if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
|
||||
// A date without time will pick up the current time, use the default.
|
||||
datetime_date_default_time($date);
|
||||
}
|
||||
$this->setTimeZone($date);
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = [];
|
||||
$separator = $this->getSetting('separator');
|
||||
|
||||
$build = [
|
||||
'#plain_text' => $this->formatDate($date),
|
||||
'#cache' => [
|
||||
'contexts' => [
|
||||
'timezone',
|
||||
],
|
||||
],
|
||||
];
|
||||
foreach ($items as $delta => $item) {
|
||||
if (!empty($item->start_date) && !empty($item->end_date)) {
|
||||
/** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
|
||||
$start_date = $item->start_date;
|
||||
/** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
|
||||
$end_date = $item->end_date;
|
||||
|
||||
return $build;
|
||||
}
|
||||
if ($start_date->getTimestamp() !== $end_date->getTimestamp()) {
|
||||
$elements[$delta] = [
|
||||
'start_date' => $this->buildDateWithIsoAttribute($start_date),
|
||||
'separator' => ['#plain_text' => ' ' . $separator . ' '],
|
||||
'end_date' => $this->buildDateWithIsoAttribute($end_date),
|
||||
];
|
||||
}
|
||||
else {
|
||||
$elements[$delta] = $this->buildDateWithIsoAttribute($start_date);
|
||||
|
||||
/**
|
||||
* Creates a render array from a date object with ISO date attribute.
|
||||
*
|
||||
* @param \Drupal\Core\Datetime\DrupalDateTime $date
|
||||
* A date object.
|
||||
*
|
||||
* @return array
|
||||
* A render array.
|
||||
*/
|
||||
protected function buildDateWithIsoAttribute(DrupalDateTime $date) {
|
||||
if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
|
||||
// A date without time will pick up the current time, use the default.
|
||||
datetime_date_default_time($date);
|
||||
if (!empty($item->_attributes)) {
|
||||
$elements[$delta]['#attributes'] += $item->_attributes;
|
||||
// Unset field item attributes since they have been included in the
|
||||
// formatter output and should not be rendered in the field template.
|
||||
unset($item->_attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the ISO date in Universal Time.
|
||||
$iso_date = $date->format("Y-m-d\TH:i:s") . 'Z';
|
||||
|
||||
$this->setTimeZone($date);
|
||||
|
||||
$build = [
|
||||
'#theme' => 'time',
|
||||
'#text' => $this->formatDate($date),
|
||||
'#html' => FALSE,
|
||||
'#attributes' => [
|
||||
'datetime' => $iso_date,
|
||||
],
|
||||
'#cache' => [
|
||||
'contexts' => [
|
||||
'timezone',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return $build;
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
@@ -38,6 +38,9 @@ class DateRangeCustomFormatter extends DateTimeCustomFormatter {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
// @todo Evaluate removing this method in
|
||||
// https://www.drupal.org/node/2793143 to determine if the behavior and
|
||||
// markup in the base class implementation can be used instead.
|
||||
$elements = [];
|
||||
$separator = $this->getSetting('separator');
|
||||
|
||||
|
||||
-37
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\datetime_range\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\datetime\Plugin\Field\FieldFormatter\DateTimeDefaultFormatter;
|
||||
use Drupal\datetime_range\DateTimeRangeTrait;
|
||||
@@ -35,42 +34,6 @@ class DateRangeDefaultFormatter extends DateTimeDefaultFormatter {
|
||||
] + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = [];
|
||||
$separator = $this->getSetting('separator');
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
if (!empty($item->start_date) && !empty($item->end_date)) {
|
||||
/** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
|
||||
$start_date = $item->start_date;
|
||||
/** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
|
||||
$end_date = $item->end_date;
|
||||
|
||||
if ($start_date->getTimestamp() !== $end_date->getTimestamp()) {
|
||||
$elements[$delta] = [
|
||||
'start_date' => $this->buildDateWithIsoAttribute($start_date),
|
||||
'separator' => ['#plain_text' => ' ' . $separator . ' '],
|
||||
'end_date' => $this->buildDateWithIsoAttribute($end_date),
|
||||
];
|
||||
}
|
||||
else {
|
||||
$elements[$delta] = $this->buildDateWithIsoAttribute($start_date);
|
||||
if (!empty($item->_attributes)) {
|
||||
$elements[$delta]['#attributes'] += $item->_attributes;
|
||||
// Unset field item attributes since they have been included in the
|
||||
// formatter output and should not be rendered in the field template.
|
||||
unset($item->_attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
+7
@@ -57,6 +57,13 @@ class DateRangePlainFormatter extends DateTimePlainFormatter {
|
||||
}
|
||||
else {
|
||||
$elements[$delta] = $this->buildDate($start_date);
|
||||
|
||||
if (!empty($item->_attributes)) {
|
||||
$elements[$delta]['#attributes'] += $item->_attributes;
|
||||
// Unset field item attributes since they have been included in the
|
||||
// formatter output and should not be rendered in the field template.
|
||||
unset($item->_attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +46,14 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
*/
|
||||
public function testDateRangeField() {
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
$field_label = $this->field->label();
|
||||
|
||||
// Loop through defined timezones to test that date-only fields work at the
|
||||
// extremes.
|
||||
foreach (static::$timezones as $timezone) {
|
||||
|
||||
$this->setSiteTimezone($timezone);
|
||||
$this->assertEquals($timezone, $this->config('system.date')->get('timezone.default'), 'Time zone set to ' . $timezone);
|
||||
|
||||
// Ensure field is set to a date-only field.
|
||||
$this->fieldStorage->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_DATE);
|
||||
@@ -64,7 +66,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
$this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]//label[contains(@class, "js-form-required")]', TRUE, 'Required markup found');
|
||||
$this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Start time element not found.');
|
||||
$this->assertNoFieldByName("{$field_name}[0][end_value][time]", '', 'End time element not found.');
|
||||
$this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_name, 'Fieldset and label found');
|
||||
$this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
|
||||
$this->assertFieldByXPath('//fieldset[@aria-describedby="edit-' . $field_name . '-0--description"]', NULL, 'ARIA described-by found');
|
||||
$this->assertFieldByXPath('//div[@id="edit-' . $field_name . '-0--description"]', NULL, 'ARIA description found');
|
||||
|
||||
@@ -133,15 +135,17 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
$end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', DATETIME_STORAGE_TIMEZONE);
|
||||
$end_expected_markup = '<time datetime="' . $end_expected_iso . '" class="datetime">' . $end_expected . '</time>';
|
||||
$output = $this->renderTestEntity($id);
|
||||
$this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', [
|
||||
$this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute in %timezone.', [
|
||||
'%value' => 'long',
|
||||
'%expected' => $start_expected,
|
||||
'%expected_iso' => $start_expected_iso,
|
||||
'%timezone' => $timezone,
|
||||
]));
|
||||
$this->assertContains($end_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', [
|
||||
$this->assertContains($end_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute in %timezone.', [
|
||||
'%value' => 'long',
|
||||
'%expected' => $end_expected,
|
||||
'%expected_iso' => $end_expected_iso,
|
||||
'%timezone' => $timezone,
|
||||
]));
|
||||
$this->assertContains(' THESEPARATOR ', $output, 'Found proper separator');
|
||||
|
||||
@@ -158,7 +162,10 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
->save();
|
||||
$expected = $start_date->format(DATETIME_DATE_STORAGE_FORMAT) . ' - ' . $end_date->format(DATETIME_DATE_STORAGE_FORMAT);
|
||||
$output = $this->renderTestEntity($id);
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using plain format displayed as %expected.', ['%expected' => $expected]));
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using plain format displayed as %expected in %timezone.', [
|
||||
'%expected' => $expected,
|
||||
'%timezone' => $timezone,
|
||||
]));
|
||||
|
||||
// Verify that the custom formatter works.
|
||||
$this->displayOptions['type'] = 'daterange_custom';
|
||||
@@ -168,7 +175,23 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
->save();
|
||||
$expected = $start_date->format($this->displayOptions['settings']['date_format']) . ' - ' . $end_date->format($this->displayOptions['settings']['date_format']);
|
||||
$output = $this->renderTestEntity($id);
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected.', ['%expected' => $expected]));
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected in %timezone.', [
|
||||
'%expected' => $expected,
|
||||
'%timezone' => $timezone,
|
||||
]));
|
||||
|
||||
// Test that allowed markup in custom format is preserved and XSS is
|
||||
// removed.
|
||||
$this->displayOptions['settings']['date_format'] = '\\<\\s\\t\\r\\o\\n\\g\\>m/d/Y\\<\\/\\s\\t\\r\\o\\n\\g\\>\\<\\s\\c\\r\\i\\p\\t\\>\\a\\l\\e\\r\\t\\(\\S\\t\\r\\i\\n\\g\\.\\f\\r\\o\\m\\C\\h\\a\\r\\C\\o\\d\\e\\(\\8\\8\\,\\8\\3\\,\\8\\3\\)\\)\\<\\/\\s\\c\\r\\i\\p\\t\\>';
|
||||
entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')
|
||||
->setComponent($field_name, $this->displayOptions)
|
||||
->save();
|
||||
$expected = '<strong>' . $start_date->format('m/d/Y') . '</strong>alert(String.fromCharCode(88,83,83)) - <strong>' . $end_date->format('m/d/Y') . '</strong>alert(String.fromCharCode(88,83,83))';
|
||||
$output = $this->renderTestEntity($id);
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected in %timezone.', [
|
||||
'%expected' => $expected,
|
||||
'%timezone' => $timezone,
|
||||
]));
|
||||
|
||||
// Test formatters when start date and end date are the same
|
||||
$this->drupalGet('entity_test/add');
|
||||
@@ -207,12 +230,13 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
$start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', DATETIME_STORAGE_TIMEZONE);
|
||||
$start_expected_markup = '<time datetime="' . $start_expected_iso . '" class="datetime">' . $start_expected . '</time>';
|
||||
$output = $this->renderTestEntity($id);
|
||||
$this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', [
|
||||
$this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute in %timezone.', [
|
||||
'%value' => 'long',
|
||||
'%expected' => $start_expected,
|
||||
'%expected_iso' => $start_expected_iso,
|
||||
'%timezone' => $timezone,
|
||||
]));
|
||||
$this->assertNotContains(' THESEPARATOR ', $output, 'Separator not found on page');
|
||||
$this->assertNotContains(' THESEPARATOR ', $output, 'Separator not found on page in ' . $timezone);
|
||||
|
||||
// Verify that hook_entity_prepare_view can add attributes.
|
||||
// @see entity_test_entity_prepare_view()
|
||||
@@ -226,7 +250,10 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
->save();
|
||||
$expected = $start_date->format(DATETIME_DATE_STORAGE_FORMAT);
|
||||
$output = $this->renderTestEntity($id);
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using plain format displayed as %expected.', ['%expected' => $expected]));
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using plain format displayed as %expected in %timezone.', [
|
||||
'%expected' => $expected,
|
||||
'%timezone' => $timezone,
|
||||
]));
|
||||
$this->assertNotContains(' THESEPARATOR ', $output, 'Separator not found on page');
|
||||
|
||||
$this->displayOptions['type'] = 'daterange_custom';
|
||||
@@ -236,7 +263,10 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
->save();
|
||||
$expected = $start_date->format($this->displayOptions['settings']['date_format']);
|
||||
$output = $this->renderTestEntity($id);
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected.', ['%expected' => $expected]));
|
||||
$this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected in %timezone.', [
|
||||
'%expected' => $expected,
|
||||
'%timezone' => $timezone,
|
||||
]));
|
||||
$this->assertNotContains(' THESEPARATOR ', $output, 'Separator not found on page');
|
||||
}
|
||||
}
|
||||
@@ -246,6 +276,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
*/
|
||||
public function testDatetimeRangeField() {
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
$field_label = $this->field->label();
|
||||
|
||||
// Ensure the field to a datetime field.
|
||||
$this->fieldStorage->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_DATETIME);
|
||||
@@ -257,7 +288,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
$this->assertFieldByName("{$field_name}[0][value][time]", '', 'Start time element found.');
|
||||
$this->assertFieldByName("{$field_name}[0][end_value][date]", '', 'End date element found.');
|
||||
$this->assertFieldByName("{$field_name}[0][end_value][time]", '', 'End time element found.');
|
||||
$this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_name, 'Fieldset and label found');
|
||||
$this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
|
||||
$this->assertFieldByXPath('//fieldset[@aria-describedby="edit-' . $field_name . '-0--description"]', NULL, 'ARIA described-by found');
|
||||
$this->assertFieldByXPath('//div[@id="edit-' . $field_name . '-0--description"]', NULL, 'ARIA description found');
|
||||
|
||||
@@ -418,6 +449,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
*/
|
||||
public function testAlldayRangeField() {
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
$field_label = $this->field->label();
|
||||
|
||||
// Ensure field is set to a all-day field.
|
||||
$this->fieldStorage->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_ALLDAY);
|
||||
@@ -430,7 +462,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
$this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]//label[contains(@class, "js-form-required")]', TRUE, 'Required markup found');
|
||||
$this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Start time element not found.');
|
||||
$this->assertNoFieldByName("{$field_name}[0][end_value][time]", '', 'End time element not found.');
|
||||
$this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_name, 'Fieldset and label found');
|
||||
$this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
|
||||
$this->assertFieldByXPath('//fieldset[@aria-describedby="edit-' . $field_name . '-0--description"]', NULL, 'ARIA described-by found');
|
||||
$this->assertFieldByXPath('//div[@id="edit-' . $field_name . '-0--description"]', NULL, 'ARIA description found');
|
||||
|
||||
@@ -588,6 +620,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
*/
|
||||
public function testDatelistWidget() {
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
$field_label = $this->field->label();
|
||||
|
||||
// Ensure field is set to a date only field.
|
||||
$this->fieldStorage->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_DATE);
|
||||
@@ -606,7 +639,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_name, 'Fieldset and label found');
|
||||
$this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
|
||||
$this->assertFieldByXPath('//fieldset[@aria-describedby="edit-' . $field_name . '-0--description"]', NULL, 'ARIA described-by found');
|
||||
$this->assertFieldByXPath('//div[@id="edit-' . $field_name . '-0--description"]', NULL, 'ARIA description found');
|
||||
|
||||
@@ -1111,6 +1144,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
$this->fieldStorage->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_DATETIME);
|
||||
$this->fieldStorage->save();
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
$field_label = $this->field->label();
|
||||
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[0][value][date]", '', 'Start date element found.');
|
||||
@@ -1289,7 +1323,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
"{$field_name}[0][end_value][time]" => '12:00:00',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertText(new FormattableMarkup('The @title end date cannot be before the start date', ['@title' => $field_name]), 'End date before start date has been caught.');
|
||||
$this->assertText(new FormattableMarkup('The @title end date cannot be before the start date', ['@title' => $field_label]), 'End date before start date has been caught.');
|
||||
|
||||
$edit = [
|
||||
"{$field_name}[0][value][date]" => '2012-12-01',
|
||||
@@ -1298,7 +1332,7 @@ class DateRangeFieldTest extends DateTestBase {
|
||||
"{$field_name}[0][end_value][time]" => '11:00:00',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertText(new FormattableMarkup('The @title end date cannot be before the start date', ['@title' => $field_name]), 'End time before start time has been caught.');
|
||||
$this->assertText(new FormattableMarkup('The @title end date cannot be before the start date', ['@title' => $field_label]), 'End time before start time has been caught.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user