Skip to content

Commit 324ad95

Browse files
committed
[Serializer] Support multiple levels of discriminator mapping
1 parent 3619661 commit 324ad95

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,9 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref
230230
throw new RuntimeException(sprintf('The type "%s" has no mapped class for the abstract object "%s".', $type, $class));
231231
}
232232

233-
$class = $mappedClass;
234-
$reflectionClass = new \ReflectionClass($class);
233+
if ($mappedClass !== $class) {
234+
return $this->instantiateObject($data, $mappedClass, $context, new \ReflectionClass($mappedClass), $allowedAttributes, $format);
235+
}
235236
}
236237

237238
return parent::instantiateObject($data, $class, $context, $reflectionClass, $allowedAttributes, $format);

src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
2020
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
2121
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
22+
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorResolverInterface;
2223
use Symfony\Component\Serializer\Mapping\ClassMetadata;
2324
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
2425
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
@@ -235,6 +236,43 @@ public function hasMetadataFor($value): bool
235236
$this->assertInstanceOf(DummySecondChildQuux::class, $normalizedData->quux);
236237
}
237238

239+
public function testDenormalizeWithNestedDiscriminatorMap()
240+
{
241+
$classDiscriminatorResolver = new class() implements ClassDiscriminatorResolverInterface {
242+
public function getMappingForClass(string $class): ?ClassDiscriminatorMapping
243+
{
244+
switch ($class) {
245+
case AbstractDummy::class:
246+
return new ClassDiscriminatorMapping('type', [
247+
'foo' => AbstractDummyFirstChild::class,
248+
]);
249+
case AbstractDummyFirstChild::class:
250+
return new ClassDiscriminatorMapping('nested_type', [
251+
'bar' => AbstractDummySecondChild::class,
252+
]);
253+
default:
254+
return null;
255+
}
256+
}
257+
258+
public function getMappingForMappedObject($object): ?ClassDiscriminatorMapping
259+
{
260+
return null;
261+
}
262+
263+
public function getTypeForMappedObject($object): ?string
264+
{
265+
return null;
266+
}
267+
};
268+
269+
$normalizer = new AbstractObjectNormalizerDummy(null, null, null, $classDiscriminatorResolver);
270+
271+
$denormalizedData = $normalizer->denormalize(['type' => 'foo', 'nested_type' => 'bar'], AbstractDummy::class);
272+
273+
$this->assertInstanceOf(AbstractDummySecondChild::class, $denormalizedData);
274+
}
275+
238276
/**
239277
* Test that additional attributes throw an exception if no metadata factory is specified.
240278
*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy