Skip to content

[Serializer] When using DiscriminatorMap, order of the mapping matters #37742

Closed
@stephane-lou

Description

@stephane-lou

Symfony version(s) affected: 4.4

Description
When using inheritance, if you have multi-level inheritance, you have to set the DiscriminatorMap in the correct order for the Serializer to find the right class because of the way it tests the class type.

How to reproduce
Create 2 classes to serialize with inheritance:
Foo
Bar extends Foo

Set the DiscriminatorMap like this:

@DiscriminatorMap(typeProperty="type", mapping={
 *   "foo"    = "App\Foo",
 *   "bar"   = "App\Bar"
 * })

If you serialize this, your Bar class will have to "type" set to Foo.

Now, invert the map:

@DiscriminatorMap(typeProperty="type", mapping={
 *   "bar"   = "App\Bar",
 *   "foo"    = "App\Foo"
 * })

The Bar class will have the correct type.

This is because the function that checks the type uses is_a() and then exits the mapping loop if one returns true.

public function getMappedObjectType($object): ?string
    {
        foreach ($this->typesMapping as $type => $typeClass) {
            if (is_a($object, $typeClass)) {
                return $type;
            }
        }

        return null;
    }

Possible Solution
Improve the loop detecting the type and check precedence

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions