From 1225eb791da79562bf75fddc87b606fc08ba69fb Mon Sep 17 00:00:00 2001 From: Attila Szeremi Date: Mon, 22 Jul 2024 10:09:14 +0200 Subject: [PATCH] [Serializer] Support subclasses of `DateTime` and `DateTimeImmutable` --- src/Symfony/Component/Serializer/CHANGELOG.md | 1 + .../Serializer/Normalizer/DateTimeNormalizer.php | 2 +- .../Tests/Normalizer/DateTimeNormalizerTest.php | 13 +++++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 3118834d80175..232c8eda79ab6 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -11,6 +11,7 @@ CHANGELOG * Add `CamelCaseToSnakeCaseNameConverter::REQUIRE_SNAKE_CASE_PROPERTIES` context option * Deprecate `AbstractNormalizerContextBuilder::withDefaultContructorArguments(?array $defaultContructorArguments)`, use `withDefaultConstructorArguments(?array $defaultConstructorArguments)` instead (note the missing `s` character in Contructor word in deprecated method) * Add `XmlEncoder::CDATA_WRAPPING_PATTERN` context option + * Support subclasses of `\DateTime` and `\DateTimeImmutable` for denormalization 7.0 --- diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index 55b2e130e6eb6..dfc498c19f194 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -138,7 +138,7 @@ public function denormalize(mixed $data, string $type, ?string $format = null, a public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool { - return isset(self::SUPPORTED_TYPES[$type]); + return is_a($type, \DateTimeInterface::class, true); } /** diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php index 5dbf36fbe8923..a744325d48d03 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php @@ -232,6 +232,8 @@ public function testSupportsDenormalization() $this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTimeInterface::class)); $this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTime::class)); $this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTimeImmutable::class)); + $this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', DateTimeImmutableChild::class)); + $this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', DateTimeChild::class)); $this->assertFalse($this->normalizer->supportsDenormalization('foo', 'Bar')); } @@ -241,6 +243,10 @@ public function testDenormalize() $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeImmutable::class)); $this->assertEquals(new \DateTime('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTime::class)); $this->assertEquals(new \DateTime('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize(' 2016-01-01T00:00:00+00:00 ', \DateTime::class)); + $this->assertEquals(new DateTimeImmutableChild('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', DateTimeImmutableChild::class)); + $this->assertEquals(new DateTimeImmutableChild('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', DateTimeImmutableChild::class)); + $this->assertEquals(new DateTimeChild('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', DateTimeChild::class)); + $this->assertEquals(new DateTimeChild('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize(' 2016-01-01T00:00:00+00:00 ', DateTimeChild::class)); $this->assertEquals(new \DateTimeImmutable('2023-05-06T17:35:34.000000+0000', new \DateTimeZone('UTC')), $this->normalizer->denormalize(1683394534, \DateTimeImmutable::class, null, [DateTimeNormalizer::FORMAT_KEY => 'U'])); $this->assertEquals(new \DateTimeImmutable('2023-05-06T17:35:34.123400+0000', new \DateTimeZone('UTC')), $this->normalizer->denormalize(1683394534.1234, \DateTimeImmutable::class, null, [DateTimeNormalizer::FORMAT_KEY => 'U.u'])); } @@ -387,3 +393,10 @@ public function testDenormalizeFormatMismatchThrowsException() $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeInterface::class, null, [DateTimeNormalizer::FORMAT_KEY => 'Y-m-d|']); } } + +class DateTimeChild extends \DateTime +{ +} +class DateTimeImmutableChild extends \DateTimeImmutable +{ +}