Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/serializer/Normalizer/DateTimeNormalizer.php @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | 4c8ae668cc8c |
children | 129ea1e6d783 |
comparison
equal
deleted
inserted
replaced
13:5fb285c0d0e3 | 14:1fec387a4317 |
---|---|
10 */ | 10 */ |
11 | 11 |
12 namespace Symfony\Component\Serializer\Normalizer; | 12 namespace Symfony\Component\Serializer\Normalizer; |
13 | 13 |
14 use Symfony\Component\Serializer\Exception\InvalidArgumentException; | 14 use Symfony\Component\Serializer\Exception\InvalidArgumentException; |
15 use Symfony\Component\Serializer\Exception\UnexpectedValueException; | 15 use Symfony\Component\Serializer\Exception\NotNormalizableValueException; |
16 | 16 |
17 /** | 17 /** |
18 * Normalizes an object implementing the {@see \DateTimeInterface} to a date string. | 18 * Normalizes an object implementing the {@see \DateTimeInterface} to a date string. |
19 * Denormalizes a date string to an instance of {@see \DateTime} or {@see \DateTimeImmutable}. | 19 * Denormalizes a date string to an instance of {@see \DateTime} or {@see \DateTimeImmutable}. |
20 * | 20 * |
21 * @author Kévin Dunglas <dunglas@gmail.com> | 21 * @author Kévin Dunglas <dunglas@gmail.com> |
22 */ | 22 */ |
23 class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface | 23 class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface |
24 { | 24 { |
25 const FORMAT_KEY = 'datetime_format'; | 25 const FORMAT_KEY = 'datetime_format'; |
26 const TIMEZONE_KEY = 'datetime_timezone'; | |
27 | |
28 private $format; | |
29 private $timezone; | |
30 | |
31 private static $supportedTypes = array( | |
32 \DateTimeInterface::class => true, | |
33 \DateTimeImmutable::class => true, | |
34 \DateTime::class => true, | |
35 ); | |
26 | 36 |
27 /** | 37 /** |
28 * @var string | 38 * @param string $format |
39 * @param \DateTimeZone|null $timezone | |
29 */ | 40 */ |
30 private $format; | 41 public function __construct($format = \DateTime::RFC3339, \DateTimeZone $timezone = null) |
31 | |
32 /** | |
33 * @param string $format | |
34 */ | |
35 public function __construct($format = \DateTime::RFC3339) | |
36 { | 42 { |
37 $this->format = $format; | 43 $this->format = $format; |
44 $this->timezone = $timezone; | |
38 } | 45 } |
39 | 46 |
40 /** | 47 /** |
41 * {@inheritdoc} | 48 * {@inheritdoc} |
42 * | 49 * |
47 if (!$object instanceof \DateTimeInterface) { | 54 if (!$object instanceof \DateTimeInterface) { |
48 throw new InvalidArgumentException('The object must implement the "\DateTimeInterface".'); | 55 throw new InvalidArgumentException('The object must implement the "\DateTimeInterface".'); |
49 } | 56 } |
50 | 57 |
51 $format = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format; | 58 $format = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format; |
59 $timezone = $this->getTimezone($context); | |
60 | |
61 if (null !== $timezone) { | |
62 $object = (new \DateTimeImmutable('@'.$object->getTimestamp()))->setTimezone($timezone); | |
63 } | |
52 | 64 |
53 return $object->format($format); | 65 return $object->format($format); |
54 } | 66 } |
55 | 67 |
56 /** | 68 /** |
62 } | 74 } |
63 | 75 |
64 /** | 76 /** |
65 * {@inheritdoc} | 77 * {@inheritdoc} |
66 * | 78 * |
67 * @throws UnexpectedValueException | 79 * @throws NotNormalizableValueException |
68 */ | 80 */ |
69 public function denormalize($data, $class, $format = null, array $context = array()) | 81 public function denormalize($data, $class, $format = null, array $context = array()) |
70 { | 82 { |
71 $dateTimeFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : null; | 83 $dateTimeFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : null; |
84 $timezone = $this->getTimezone($context); | |
85 | |
86 if ('' === $data || null === $data) { | |
87 throw new NotNormalizableValueException('The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.'); | |
88 } | |
72 | 89 |
73 if (null !== $dateTimeFormat) { | 90 if (null !== $dateTimeFormat) { |
74 $object = \DateTime::class === $class ? \DateTime::createFromFormat($dateTimeFormat, $data) : \DateTimeImmutable::createFromFormat($dateTimeFormat, $data); | 91 if (null === $timezone && PHP_VERSION_ID < 70000) { |
92 // https://bugs.php.net/bug.php?id=68669 | |
93 $object = \DateTime::class === $class ? \DateTime::createFromFormat($dateTimeFormat, $data) : \DateTimeImmutable::createFromFormat($dateTimeFormat, $data); | |
94 } else { | |
95 $object = \DateTime::class === $class ? \DateTime::createFromFormat($dateTimeFormat, $data, $timezone) : \DateTimeImmutable::createFromFormat($dateTimeFormat, $data, $timezone); | |
96 } | |
75 | 97 |
76 if (false !== $object) { | 98 if (false !== $object) { |
77 return $object; | 99 return $object; |
78 } | 100 } |
79 | 101 |
80 $dateTimeErrors = \DateTime::class === $class ? \DateTime::getLastErrors() : \DateTimeImmutable::getLastErrors(); | 102 $dateTimeErrors = \DateTime::class === $class ? \DateTime::getLastErrors() : \DateTimeImmutable::getLastErrors(); |
81 | 103 |
82 throw new UnexpectedValueException(sprintf( | 104 throw new NotNormalizableValueException(sprintf( |
83 'Parsing datetime string "%s" using format "%s" resulted in %d errors:'."\n".'%s', | 105 'Parsing datetime string "%s" using format "%s" resulted in %d errors:'."\n".'%s', |
84 $data, | 106 $data, |
85 $dateTimeFormat, | 107 $dateTimeFormat, |
86 $dateTimeErrors['error_count'], | 108 $dateTimeErrors['error_count'], |
87 implode("\n", $this->formatDateTimeErrors($dateTimeErrors['errors'])) | 109 implode("\n", $this->formatDateTimeErrors($dateTimeErrors['errors'])) |
88 )); | 110 )); |
89 } | 111 } |
90 | 112 |
91 try { | 113 try { |
92 return \DateTime::class === $class ? new \DateTime($data) : new \DateTimeImmutable($data); | 114 return \DateTime::class === $class ? new \DateTime($data, $timezone) : new \DateTimeImmutable($data, $timezone); |
93 } catch (\Exception $e) { | 115 } catch (\Exception $e) { |
94 throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e); | 116 throw new NotNormalizableValueException($e->getMessage(), $e->getCode(), $e); |
95 } | 117 } |
96 } | 118 } |
97 | 119 |
98 /** | 120 /** |
99 * {@inheritdoc} | 121 * {@inheritdoc} |
100 */ | 122 */ |
101 public function supportsDenormalization($data, $type, $format = null) | 123 public function supportsDenormalization($data, $type, $format = null) |
102 { | 124 { |
103 $supportedTypes = array( | 125 return isset(self::$supportedTypes[$type]); |
104 \DateTimeInterface::class => true, | |
105 \DateTimeImmutable::class => true, | |
106 \DateTime::class => true, | |
107 ); | |
108 | |
109 return isset($supportedTypes[$type]); | |
110 } | 126 } |
111 | 127 |
112 /** | 128 /** |
113 * Formats datetime errors. | 129 * Formats datetime errors. |
114 * | |
115 * @param array $errors | |
116 * | 130 * |
117 * @return string[] | 131 * @return string[] |
118 */ | 132 */ |
119 private function formatDateTimeErrors(array $errors) | 133 private function formatDateTimeErrors(array $errors) |
120 { | 134 { |
124 $formattedErrors[] = sprintf('at position %d: %s', $pos, $message); | 138 $formattedErrors[] = sprintf('at position %d: %s', $pos, $message); |
125 } | 139 } |
126 | 140 |
127 return $formattedErrors; | 141 return $formattedErrors; |
128 } | 142 } |
143 | |
144 private function getTimezone(array $context) | |
145 { | |
146 $dateTimeZone = array_key_exists(self::TIMEZONE_KEY, $context) ? $context[self::TIMEZONE_KEY] : $this->timezone; | |
147 | |
148 if (null === $dateTimeZone) { | |
149 return null; | |
150 } | |
151 | |
152 return $dateTimeZone instanceof \DateTimeZone ? $dateTimeZone : new \DateTimeZone($dateTimeZone); | |
153 } | |
129 } | 154 } |