diff --git a/core/modules/hal/hal.services.yml b/core/modules/hal/hal.services.yml index 7b30432..e817fbf 100644 --- a/core/modules/hal/hal.services.yml +++ b/core/modules/hal/hal.services.yml @@ -4,11 +4,6 @@ services: arguments: ['@rest.link_manager', '@serializer.entity_resolver'] tags: - { name: normalizer, priority: 10 } - serializer.normalizer.timestamp_item.hal: - class: Drupal\hal\Normalizer\TimestampItemNormalizer - arguments: ['@date.formatter', '@config.factory'] - tags: - - { name: normalizer, priority: 10 } serializer.normalizer.field_item.hal: class: Drupal\hal\Normalizer\FieldItemNormalizer tags: diff --git a/core/modules/hal/src/Normalizer/TimestampItemNormalizer.php b/core/modules/hal/src/Normalizer/TimestampItemNormalizer.php deleted file mode 100644 index 8263f2c..0000000 --- a/core/modules/hal/src/Normalizer/TimestampItemNormalizer.php +++ /dev/null @@ -1,80 +0,0 @@ -dateFormatter = $date_formatter; - $this->configFactory = $config_factory; - } - - /** - * {@inheritdoc} - */ - public function normalize($field_item, $format = NULL, array $context = array()) { - /** @var $field_item \Drupal\Core\Field\Plugin\Field\FieldType\TimestampItem */ - $value = $field_item->getValue()['value']; - $field = $field_item->getParent(); - - return [ - $field->getName() => ['value' => $this->dateFormatter->format($value, 'custom', \DateTime::RFC3339, 'UTC')], - ]; - } - - /** - * {@inheritdoc} - */ - protected function constructValue($data, $context) { - $formats = [ - 'U', - \DateTime::ISO8601, - \DateTime::RFC3339, - ]; - $timezone = new \DateTimeZone('UTC'); - - foreach ($formats as $format) { - if (($date = \DateTime::createFromFormat($format, $data, $timezone)) !== FALSE) { - return ['value' => (int) $date->format('U')]; - } - } - - return NULL; - } - -} diff --git a/core/modules/rest/config/install/rest.settings.yml b/core/modules/rest/config/install/rest.settings.yml index 0d9e088..eb3da2d 100644 --- a/core/modules/rest/config/install/rest.settings.yml +++ b/core/modules/rest/config/install/rest.settings.yml @@ -9,11 +9,3 @@ link_domain: ~ # @see rest_update_8203() # @see https://www.drupal.org/node/2664780 bc_entity_resource_permissions: false - -# Before Drupal 8.3, timestamps were always returned as Unix timestamps, which -# are not a universal format for interchance. Instead, RFC3339 timestamps are -# returned. New Drupal installations opt out from this by default (hence this -# is set to false), existing installations opt in to it. -# @see rest_update_8301() -# @see https://www.drupal.org/node/2768651 -bc_timestamp_normalizer: false diff --git a/core/modules/rest/config/schema/rest.schema.yml b/core/modules/rest/config/schema/rest.schema.yml index 7410992..2c255ab 100644 --- a/core/modules/rest/config/schema/rest.schema.yml +++ b/core/modules/rest/config/schema/rest.schema.yml @@ -9,9 +9,6 @@ rest.settings: bc_entity_resource_permissions: type: boolean label: 'Whether the pre Drupal 8.2.x behavior of having permissions for EntityResource is enabled or not.' - bc_timestamp_normalizer: - type: boolean - label: 'Whether the pre Drupal 8.3.x behavior of returning Unix timestamps is enabled or not.' # Method-level granularity of REST resource configuration. rest_resource.method: diff --git a/core/modules/rest/rest.install b/core/modules/rest/rest.install index f5bb99b..af6664e 100644 --- a/core/modules/rest/rest.install +++ b/core/modules/rest/rest.install @@ -94,23 +94,3 @@ function rest_update_8203() { /** * @} End of "defgroup updates-8.1.x-to-8.2.x". */ - -/** - * @defgroup updates-8.2.x-to-8.3.x - * @{ - * Update functions from 8.2.x to 8.3.x. - */ - -/** - * Enable BC for Timestamp: return Unix timestamps. - */ -function rest_update_8301() { - $config_factory = \Drupal::configFactory(); - $rest_settings = $config_factory->getEditable('rest.settings'); - $rest_settings->set('bc_timestamp_normalizer', TRUE) - ->save(TRUE); -} - -/** - * @} End of "defgroup updates-8.2.x-to-8.3.x". - */ diff --git a/core/modules/serialization/config/install/serialization.settings.yml b/core/modules/serialization/config/install/serialization.settings.yml new file mode 100644 index 0000000..3d846ed --- /dev/null +++ b/core/modules/serialization/config/install/serialization.settings.yml @@ -0,0 +1,7 @@ +# Before Drupal 8.3, timestamps were always returned as Unix timestamps, which +# are not a universal format for interchange. Instead, RFC3339 timestamps are +# returned. New Drupal installations opt out from this by default (hence this +# is set to false), existing installations opt in to it. +# @see rest_update_8301() +# @see https://www.drupal.org/node/2768651 +bc_timestamp_normalizer_unix: false diff --git a/core/modules/serialization/config/schema/serialization.schema.yml b/core/modules/serialization/config/schema/serialization.schema.yml new file mode 100644 index 0000000..770e7b7 --- /dev/null +++ b/core/modules/serialization/config/schema/serialization.schema.yml @@ -0,0 +1,8 @@ +# Schema for the configuration files of the Serialization module. +serialization.settings: + type: config_object + label: 'Serialization settings' + mapping: + bc_timestamp_normalizer_unix: + type: boolean + label: 'Whether the pre Drupal 8.3.x behavior of returning Unix timestamps is enabled or not.' diff --git a/core/modules/serialization/serialization.install b/core/modules/serialization/serialization.install new file mode 100644 index 0000000..b78e716 --- /dev/null +++ b/core/modules/serialization/serialization.install @@ -0,0 +1,26 @@ +getEditable('serialization.settings'); + $rest_settings->set('bc_timestamp_normalizer_unix', TRUE) + ->save(TRUE); +} + +/** +* @} End of "defgroup updates-8.2.x-to-8.3.x". +*/ diff --git a/core/modules/serialization/serialization.services.yml b/core/modules/serialization/serialization.services.yml index 8b570c0..6759ad1 100644 --- a/core/modules/serialization/serialization.services.yml +++ b/core/modules/serialization/serialization.services.yml @@ -45,6 +45,11 @@ services: class: Drupal\serialization\Normalizer\TypedDataNormalizer tags: - { name: normalizer } + serializer.normalizer.timestamp_item: + class: Drupal\serialization\Normalizer\TimestampItemNormalizer + arguments: ['@date.formatter', '@config.factory'] + tags: + - { name: normalizer } serializer.encoder.json: class: Drupal\serialization\Encoder\JsonEncoder tags: diff --git a/core/modules/serialization/src/Normalizer/TimestampItemNormalizer.php b/core/modules/serialization/src/Normalizer/TimestampItemNormalizer.php new file mode 100644 index 0000000..2da243b --- /dev/null +++ b/core/modules/serialization/src/Normalizer/TimestampItemNormalizer.php @@ -0,0 +1,113 @@ +dateFormatter = $date_formatter; + $this->configFactory = $config_factory; + } + + /** + * {@inheritdoc} + */ + public function normalize($field_item, $format = NULL, array $context = array()) { + /** @var $field_item \Drupal\Core\Field\Plugin\Field\FieldType\TimestampItem */ + $value = $field_item->getValue()['value']; + $field = $field_item->getParent(); + + // Check for the BC setting. If TRUE, use a Unix timestamp. Otherwise, use + // a RFC 3339 timestamp with the time zone set to UTC. + if ($this->configFactory->get('serialization.settings')->get('bc_timestamp_normalizer_unix')) { + $format = 'U'; + } + else { + $format = \DateTime::RFC3339; + } + + return [ + $field->getName() => ['value' => $this->dateFormatter->format($value, 'custom', $format, 'UTC')], + ]; + } + + /** + * {@inheritdoc} + */ + public function denormalize($data, $class, $format = NULL, array $context = []) { + // Loop through the allowed formats and create a TimestampItem from the + // input data if it matches the defined pattern. Since the formats are + // unambiguous (i.e., they reference an absolute time with a defined time + // zone), only one will ever match. + + $timezone = new \DateTimeZone('UTC'); + foreach ($this->allowedFormats as $format) { + if (($date = \DateTime::createFromFormat($format, $data, $timezone)) !== FALSE) { + $data_definition = DataDefinition::create('timestamp'); + $timestamp_item = TimestampItem::createInstance($data_definition) + ->setValue(['value' => (int) $date->format('U')]); + return $timestamp_item; + } + } + + throw new UnexpectedValueException(sprintf('The specified date "%s" is not in an accepted format.', $data)); + } + +}