bug #37860 [Serializer][ClassDiscriminatorMapping] Fix getMappedObjectType() when a discriminator child extends another one (fancyweb)

This PR was merged into the 4.4 branch.

Discussion
----------

[Serializer][ClassDiscriminatorMapping] Fix getMappedObjectType() when a discriminator child extends another one

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | https://github.com/symfony/symfony/issues/37742
| License       | MIT
| Doc PR        | -

The strategy is to sort the passed classes from the "bottom" one in the hierarchy to the "top" one so that the first `is_a` in `getMappedObjectType()` is right.

Commits
-------

c16a192473 [Serializer][ClassDiscriminatorMapping] Fix getMappedObjectType() when a discriminator child extends another one
This commit is contained in:
Fabien Potencier 2020-08-18 09:29:41 +02:00
commit 7f7b447b0b
5 changed files with 35 additions and 1 deletions

View File

@ -23,6 +23,18 @@ class ClassDiscriminatorMapping
{
$this->typeProperty = $typeProperty;
$this->typesMapping = $typesMapping;
uasort($this->typesMapping, static function (string $a, string $b): int {
if (is_a($a, $b, true)) {
return -1;
}
if (is_a($b, $a, true)) {
return 1;
}
return 0;
});
}
public function getTypeProperty(): string

View File

@ -16,7 +16,8 @@ use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
/**
* @DiscriminatorMap(typeProperty="type", mapping={
* "first"="Symfony\Component\Serializer\Tests\Fixtures\AbstractDummyFirstChild",
* "second"="Symfony\Component\Serializer\Tests\Fixtures\AbstractDummySecondChild"
* "second"="Symfony\Component\Serializer\Tests\Fixtures\AbstractDummySecondChild",
* "third"="Symfony\Component\Serializer\Tests\Fixtures\AbstractDummyThirdChild",
* })
*/
abstract class AbstractDummy

View File

@ -0,0 +1,16 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\Tests\Fixtures;
final class AbstractDummyThirdChild extends AbstractDummyFirstChild
{
}

View File

@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractDummyFirstChild;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractDummySecondChild;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractDummyThirdChild;
/**
* @author Samuel Roze <samuel.roze@gmail.com>
@ -35,9 +36,11 @@ class ClassDiscriminatorMappingTest extends TestCase
{
$mapping = new ClassDiscriminatorMapping('type', [
'first' => AbstractDummyFirstChild::class,
'third' => AbstractDummyThirdChild::class,
]);
$this->assertEquals('first', $mapping->getMappedObjectType(new AbstractDummyFirstChild()));
$this->assertNull($mapping->getMappedObjectType(new AbstractDummySecondChild()));
$this->assertSame('third', $mapping->getMappedObjectType(new AbstractDummyThirdChild()));
}
}

View File

@ -20,6 +20,7 @@ use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractDummy;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractDummyFirstChild;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractDummySecondChild;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractDummyThirdChild;
use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
/**
@ -65,6 +66,7 @@ class AnnotationLoaderTest extends TestCase
$expected = new ClassMetadata(AbstractDummy::class, new ClassDiscriminatorMapping('type', [
'first' => AbstractDummyFirstChild::class,
'second' => AbstractDummySecondChild::class,
'third' => AbstractDummyThirdChild::class,
]));
$expected->addAttributeMetadata(new AttributeMetadata('foo'));