Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / serialization / src / Normalizer / TimeStampItemNormalizerTrait.php
1 <?php
2
3 namespace Drupal\serialization\Normalizer;
4
5 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
6
7 /**
8  * A trait for TimestampItem normalization functionality.
9  */
10 trait TimeStampItemNormalizerTrait {
11
12   /**
13    * Allowed timestamps formats for the denormalizer.
14    *
15    * The denormalizer allows deserialization to timestamps from three
16    * different formats. Validation of the input data and creation of the
17    * numerical timestamp value is handled with \DateTime::createFromFormat().
18    * The list is chosen to be unambiguous and language neutral, but also common
19    * for data interchange.
20    *
21    * @var string[]
22    *
23    * @see http://php.net/manual/en/datetime.createfromformat.php
24    */
25   protected $allowedFormats = [
26     'UNIX timestamp' => 'U',
27     'ISO 8601' => \DateTime::ISO8601,
28     'RFC 3339' => \DateTime::RFC3339,
29   ];
30
31   /**
32    * Processes normalized timestamp values to add a formatted date and format.
33    *
34    * @param array $normalized
35    *   The normalized field data to process.
36    * @return array
37    *   The processed data.
38    */
39   protected function processNormalizedValues(array $normalized) {
40     // Use a RFC 3339 timestamp with the time zone set to UTC to replace the
41     // timestamp value.
42     $date = new \DateTime();
43     $date->setTimestamp($normalized['value']);
44     $date->setTimezone(new \DateTimeZone('UTC'));
45     $normalized['value'] = $date->format(\DateTime::RFC3339);
46     // 'format' is not a property on TimestampItem fields. This is present to
47     // assist consumers of this data.
48     $normalized['format'] = \DateTime::RFC3339;
49
50     return $normalized;
51   }
52
53   /**
54    * {@inheritdoc}
55    */
56   protected function constructValue($data, $context) {
57     // Loop through the allowed formats and create a TimestampItem from the
58     // input data if it matches the defined pattern. Since the formats are
59     // unambiguous (i.e., they reference an absolute time with a defined time
60     // zone), only one will ever match.
61     $timezone = new \DateTimeZone('UTC');
62
63     // First check for a provided format.
64     if (!empty($data['format']) && in_array($data['format'], $this->allowedFormats)) {
65       $date = \DateTime::createFromFormat($data['format'], $data['value'], $timezone);
66       return ['value' => $date->getTimestamp()];
67     }
68     // Otherwise, loop through formats.
69     else {
70       foreach ($this->allowedFormats as $format) {
71         if (($date = \DateTime::createFromFormat($format, $data['value'], $timezone)) !== FALSE) {
72           return ['value' => $date->getTimestamp()];
73         }
74       }
75     }
76
77     $format_strings = [];
78
79     foreach ($this->allowedFormats as $label => $format) {
80       $format_strings[] = "\"$format\" ($label)";
81     }
82
83     $formats = implode(', ', $format_strings);
84     throw new UnexpectedValueException(sprintf('The specified date "%s" is not in an accepted format: %s.', $data['value'], $formats));
85   }
86
87 }