From e163124bbdeb8d8718bc3a6f0cb7ece5c264a2a2 Mon Sep 17 00:00:00 2001 From: Percy Downing Date: Tue, 9 May 2023 10:22:00 +0200 Subject: [PATCH 1/3] =?UTF-8?q?cast=20integer=20to=20string=20in=20case=20?= =?UTF-8?q?date=20time=20format=20is=20=E2=80=9EU=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case the date time format is „U“, the data comes as a integer (timestamp in seconds). To keep the „data is string“-condition, the integer is casted to a string. --- .../Component/Serializer/Normalizer/DateTimeNormalizer.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index aa7988d37ed55..807ae54bd45b1 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -96,6 +96,8 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $dateTimeFormat = $context[self::FORMAT_KEY] ?? null; $timezone = $this->getTimezone($context); + if ( "U" === $dateTimeFormat && "integer" === gettype($data)) $data = (string) $data; + if (null === $data || !\is_string($data) || '' === trim($data)) { throw NotNormalizableValueException::createForUnexpectedDataType('The data is either not an string, an empty string, or null; you should pass a string that can be parsed with the passed format or a valid DateTime string.', $data, [Type::BUILTIN_TYPE_STRING], $context['deserialization_path'] ?? null, true); } From e11d8da6e110f9948a32e6142610003ce2fb3af9 Mon Sep 17 00:00:00 2001 From: Percy Downing Date: Tue, 9 May 2023 16:14:25 +0200 Subject: [PATCH 2/3] =?UTF-8?q?allow=20string=20or=20integer=20with=20date?= =?UTF-8?q?TimeFormat=20=E2=80=9EU=E2=80=9C=20in=20type=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $data can come as an integer, when date time format is „U“. Updated type check, so in that case no exception is thrown. --- .../Serializer/Normalizer/DateTimeNormalizer.php | 4 +--- .../Tests/Normalizer/DateTimeNormalizerTest.php | 9 +++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index 807ae54bd45b1..dd87c6368dbf6 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -96,9 +96,7 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $dateTimeFormat = $context[self::FORMAT_KEY] ?? null; $timezone = $this->getTimezone($context); - if ( "U" === $dateTimeFormat && "integer" === gettype($data)) $data = (string) $data; - - if (null === $data || !\is_string($data) || '' === trim($data)) { + if (null === $data || (!\is_string($data) && !(\is_int($data) && "U" === $dateTimeFormat) ) || '' === trim($data)) { throw NotNormalizableValueException::createForUnexpectedDataType('The data is either not an string, an empty string, or null; you should pass a string that can be parsed with the passed format or a valid DateTime string.', $data, [Type::BUILTIN_TYPE_STRING], $context['deserialization_path'] ?? null, true); } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php index 674dfaab5382d..824c4861ac115 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; +use DateTime; +use DateTimeImmutable; use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Exception\UnexpectedValueException; @@ -305,4 +307,11 @@ public function testDenormalizeFormatMismatchThrowsException() $this->expectException(UnexpectedValueException::class); $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeInterface::class, null, [DateTimeNormalizer::FORMAT_KEY => 'Y-m-d|']); } + + public function testDenormalizeDateTimeIntegerWithTimestampFormat() + { + $timestamp = time(); + $denormalizedDate = $this->normalizer->denormalize($timestamp, \DateTimeImmutable::class, null, [DateTimeNormalizer::FORMAT_KEY => "U"]); + $this->assertSame($timestamp, $denormalizedDate->getTimestamp()); + } } From e225132052572c1381b4cb4efa0e477b42dadd21 Mon Sep 17 00:00:00 2001 From: Percy Downing Date: Tue, 9 May 2023 16:16:31 +0200 Subject: [PATCH 3/3] fix coding standard --- .../Serializer/Normalizer/DateTimeNormalizer.php | 8 +------- .../Tests/Normalizer/DateTimeNormalizerTest.php | 4 +--- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index dd87c6368dbf6..3a926d0ae6c5f 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -80,9 +80,6 @@ public function normalize(mixed $object, string $format = null, array $context = return $object->format($dateTimeFormat); } - /** - * @param array $context - */ public function supportsNormalization(mixed $data, string $format = null /* , array $context = [] */): bool { return $data instanceof \DateTimeInterface; @@ -96,7 +93,7 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $dateTimeFormat = $context[self::FORMAT_KEY] ?? null; $timezone = $this->getTimezone($context); - if (null === $data || (!\is_string($data) && !(\is_int($data) && "U" === $dateTimeFormat) ) || '' === trim($data)) { + if (null === $data || (!\is_string($data) && !(\is_int($data) && 'U' === $dateTimeFormat)) || '' === trim($data)) { throw NotNormalizableValueException::createForUnexpectedDataType('The data is either not an string, an empty string, or null; you should pass a string that can be parsed with the passed format or a valid DateTime string.', $data, [Type::BUILTIN_TYPE_STRING], $context['deserialization_path'] ?? null, true); } @@ -131,9 +128,6 @@ public function denormalize(mixed $data, string $type, string $format = null, ar } } - /** - * @param array $context - */ public function supportsDenormalization(mixed $data, string $type, string $format = null /* , array $context = [] */): bool { return isset(self::SUPPORTED_TYPES[$type]); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php index 824c4861ac115..fcd4694dd3988 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; -use DateTime; -use DateTimeImmutable; use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Exception\UnexpectedValueException; @@ -311,7 +309,7 @@ public function testDenormalizeFormatMismatchThrowsException() public function testDenormalizeDateTimeIntegerWithTimestampFormat() { $timestamp = time(); - $denormalizedDate = $this->normalizer->denormalize($timestamp, \DateTimeImmutable::class, null, [DateTimeNormalizer::FORMAT_KEY => "U"]); + $denormalizedDate = $this->normalizer->denormalize($timestamp, \DateTimeImmutable::class, null, [DateTimeNormalizer::FORMAT_KEY => 'U']); $this->assertSame($timestamp, $denormalizedDate->getTimestamp()); } }