Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Allow arrays being denormalized in AbstractObjectNormalizer  #19545

Copy link
Copy link
Closed
@hensoko

Description

@hensoko
Issue body actions

Heyho,

I currently work on a problem when using the ObjectNormalizer with an multidimensional array as input. My array looks like this:

[
    'base_property1' => 'value123',
    'nested_resources' => [
        [
            'nested_property' => 'value1234'
        ],
        [
            'nested_property' => 'value2345'
        ],
    ]
]

I defined the following classes the data of this array should be passed to:

class Resource {
    /**
     * @var string
     */
    private $baseProperty1;

    /**
     * @var nestedResource[]|ArrayCollection
     */
    private $nestedResources;

    public function getBaseProperty1() {
        return $this->baseProperty1;
    }

    public function setBaseProperty1($baseProperty1) {
        $this->baseProperty1 = $baseProperty1;
        return $this;
    }

    public function getNestedResources() {
        return $this->nestedResources;
    }

    public function setNestedResources($nestedResources) {
        $this->nestedResources = $nestedResources;
        return $this;
    }
}

class NestedResource {
     /**
     * @var string
     */
    private $nestedProperty;

    public function getNestedProperty() {
        return $this->nestedProperty;
    }

    public function setNestedProperty($nestedProperty) {
        $this->nestedProperty = $nestedProperty;
        return $this;
    }
}

When using the Serializer-Component of Symfony to denormalize the input-array I expected to get the following result:

   Resource {
        -baseProperty1: "value123"
        -nestedResources: array:2 [
            0 => NestedResource {
                -nestedProperty: 'value1234'
            }
            2 => NestedResource {
                -nestedProperty: 'value2345'
            }
        ]
   }

but instead I get the following:

   Resource {
        -baseProperty1: "value123"
        -nestedResources: array:2 [
            0 => array [
                nestedProperty => 'value1234'
            }
            1 => array [
                nestedProperty => 'value2345'
            }
        ]
   }

I defined the following services to get a serializer-service using the ReflectionExtrator:

services:
    name_converter.camel_case_to_sneak_case_name:
        class: Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter

    property_accessor.reflection:
        class: Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor

    denormalizer.array:
        class: Symfony\Component\Serializer\Normalizer\ArrayDenormalizer

    normalizer.object:
        class: Symfony\Component\Serializer\Normalizer\ObjectNormalizer
        arguments:
            -
            - "@name_converter.camel_case_to_sneak_case_name"
            -
            - "@property_accessor.reflection"

    encoder.json:
        class: Symfony\Component\Serializer\Encoder\JsonEncoder

    serializer:
        class: Symfony\Component\Serializer\Serializer
        arguments:
            - ["@normalizer.object", "@denormalizer.array"]
            - ["@encoder.json"]

I tested it with latest Symfony 3.1.3. I think the issue occures because of a missing check for a collection in class AbstractObjectNormalizer in line 255 to 263. It is only checked for an object, but if $type is an collection this is not honored. I get a correct result if I add the following check just before line 255, but I think this is not a nice solution because of the need to add brackets after the class-name:

if ($type->isCollection() && $type->getCollectionValueType()->getBuiltinType() === Type::BUILTIN_TYPE_OBJECT) {
    $class = $type->getCollectionValueType()->getClassName() . '[]';
    $builtinType = $type->getCollectionValueType()->getBuiltinType();
}

I get the same result with PhpDocExtractor.

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

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.