[Serializer] Support multiple levels of discriminator mapping
This commit is contained in:
parent
3619661d65
commit
324ad95fee
|
@ -230,8 +230,9 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||
throw new RuntimeException(sprintf('The type "%s" has no mapped class for the abstract object "%s".', $type, $class));
|
||||
}
|
||||
|
||||
$class = $mappedClass;
|
||||
$reflectionClass = new \ReflectionClass($class);
|
||||
if ($mappedClass !== $class) {
|
||||
return $this->instantiateObject($data, $mappedClass, $context, new \ReflectionClass($mappedClass), $allowedAttributes, $format);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::instantiateObject($data, $class, $context, $reflectionClass, $allowedAttributes, $format);
|
||||
|
|
|
@ -19,6 +19,7 @@ use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
|||
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
|
||||
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
|
||||
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorResolverInterface;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
|
||||
|
@ -235,6 +236,43 @@ class AbstractObjectNormalizerTest extends TestCase
|
|||
$this->assertInstanceOf(DummySecondChildQuux::class, $normalizedData->quux);
|
||||
}
|
||||
|
||||
public function testDenormalizeWithNestedDiscriminatorMap()
|
||||
{
|
||||
$classDiscriminatorResolver = new class() implements ClassDiscriminatorResolverInterface {
|
||||
public function getMappingForClass(string $class): ?ClassDiscriminatorMapping
|
||||
{
|
||||
switch ($class) {
|
||||
case AbstractDummy::class:
|
||||
return new ClassDiscriminatorMapping('type', [
|
||||
'foo' => AbstractDummyFirstChild::class,
|
||||
]);
|
||||
case AbstractDummyFirstChild::class:
|
||||
return new ClassDiscriminatorMapping('nested_type', [
|
||||
'bar' => AbstractDummySecondChild::class,
|
||||
]);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getMappingForMappedObject($object): ?ClassDiscriminatorMapping
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getTypeForMappedObject($object): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
$normalizer = new AbstractObjectNormalizerDummy(null, null, null, $classDiscriminatorResolver);
|
||||
|
||||
$denormalizedData = $normalizer->denormalize(['type' => 'foo', 'nested_type' => 'bar'], AbstractDummy::class);
|
||||
|
||||
$this->assertInstanceOf(AbstractDummySecondChild::class, $denormalizedData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that additional attributes throw an exception if no metadata factory is specified.
|
||||
*/
|
||||
|
|
Reference in New Issue