diff --git a/src/Symfony/Component/Serializer/Normalizer/UidNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/UidNormalizer.php index 009d334895ee8..52d1e76552198 100644 --- a/src/Symfony/Component/Serializer/Normalizer/UidNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/UidNormalizer.php @@ -14,7 +14,6 @@ use Symfony\Component\Serializer\Exception\LogicException; use Symfony\Component\Serializer\Exception\NotNormalizableValueException; use Symfony\Component\Uid\AbstractUid; -use Symfony\Component\Uid\Ulid; use Symfony\Component\Uid\Uuid; final class UidNormalizer implements NormalizerInterface, DenormalizerInterface, CacheableSupportsMethodInterface @@ -70,9 +69,15 @@ public function supportsNormalization($data, string $format = null) public function denormalize($data, string $type, string $format = null, array $context = []) { try { - return Ulid::class === $type ? Ulid::fromString($data) : Uuid::fromString($data); + return AbstractUid::class !== $type ? $type::fromString($data) : Uuid::fromString($data); } catch (\InvalidArgumentException $exception) { throw new NotNormalizableValueException(sprintf('The data is not a valid "%s" string representation.', $type)); + } catch (\Error $e) { + if (str_starts_with($e->getMessage(), 'Cannot instantiate abstract class')) { + return $this->denormalize($data, AbstractUid::class, $format, $context); + } + + throw $e; } } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/UidNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/UidNormalizerTest.php index fc2f55bbee2e1..14fa108668811 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/UidNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/UidNormalizerTest.php @@ -116,8 +116,8 @@ public function dataProvider() ['4126dbc1-488e-4f6e-aadd-775dcbac482e', UuidV4::class], ['18cdf3d3-ea1b-5b23-a9c5-40abd0e2df22', UuidV5::class], ['1ea6ecef-eb9a-66fe-b62b-957b45f17e43', UuidV6::class], - ['1ea6ecef-eb9a-66fe-b62b-957b45f17e43', AbstractUid::class], ['01E4BYF64YZ97MDV6RH0HAMN6X', Ulid::class], + ['01FPT3YXZXJ1J437FES7CR5BCB', TestCustomUid::class], ]; } @@ -134,16 +134,32 @@ public function testSupportsDenormalizationForNonUid() $this->assertFalse($this->normalizer->supportsDenormalization('foo', \stdClass::class)); } + public function testSupportOurAbstractUid() + { + $this->assertTrue($this->normalizer->supportsDenormalization('1ea6ecef-eb9a-66fe-b62b-957b45f17e43', AbstractUid::class)); + } + + public function testSupportCustomAbstractUid() + { + $this->assertTrue($this->normalizer->supportsDenormalization('ccc', TestAbstractCustomUid::class)); + } + /** * @dataProvider dataProvider */ public function testDenormalize($uuidString, $class) { - if (Ulid::class === $class) { - $this->assertEquals(new Ulid($uuidString), $this->normalizer->denormalize($uuidString, $class)); - } else { - $this->assertEquals(Uuid::fromString($uuidString), $this->normalizer->denormalize($uuidString, $class)); - } + $this->assertEquals($class::fromString($uuidString), $this->normalizer->denormalize($uuidString, $class)); + } + + public function testDenormalizeOurAbstractUid() + { + $this->assertEquals(Uuid::fromString($uuidString = '1ea6ecef-eb9a-66fe-b62b-957b45f17e43'), $this->normalizer->denormalize($uuidString, AbstractUid::class)); + } + + public function testDenormalizeCustomAbstractUid() + { + $this->assertEquals(Uuid::fromString($uuidString = '1ea6ecef-eb9a-66fe-b62b-957b45f17e43'), $this->normalizer->denormalize($uuidString, TestAbstractCustomUid::class)); } public function testNormalizeWithNormalizationFormatPassedInConstructor() @@ -169,3 +185,11 @@ public function testNormalizeWithNormalizationFormatNotValid() ]); } } + +class TestCustomUid extends Ulid +{ +} + +abstract class TestAbstractCustomUid extends Ulid +{ +}