Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialization of nested array of objects using constructor denormalization #28081

Closed
sadokmtir opened this issue Jul 27, 2018 · 3 comments
Closed

Comments

@sadokmtir
Copy link

sadokmtir commented Jul 27, 2018

Symfony version(s) affected: 4.0.6

Description
So, let's say I have a JSON data corresponding to a class Child that has an attribute games that is an array of objects of class Game. So when using the serialisation using setters I get and the end a Child Object with an attribute games that is an array of several Game instances.
However for design reasons it is not possible to use the setters so I had to use the serialisation through the constructor, hence on my constructor I have someting like:


class Child
{

/**
     * @var Game[]
     */
    private $games;

   /**
     * Child constructor.
     *
     * @param Game[] $games
     */
    public function __construct(
        array $games,
    ) {
        $this->games = $games;
    }
 }

setter denormalization

The problem here is that the denormalizer could not figure out that the games is an array of objects from the class Game and then I get instead of an object an array have the same attributes defined on the Game class which is not the same when I add a setter for the games.

When I debug it the code fro both setter serialization and constructor serialization I can see the difference between both methods getting into action.

  • For the first case of the setter denormalization the function validateAndDenormalize from the AbstractObjectNormalizer is handling the normalization and there is the code there is a check on the collection type if ($type->isCollection() && null !== ($collectionValueType = $type->getCollectionValueType()) && Type::BUILTIN_TYPE_OBJECT === $collectionValueType->getBuiltinType()) which can determine if the array has objects from a defined class.

Adding a setter like that is enough to get the right denormalization:

      /**
      * @param Game[] $games
      * @return Child
     */
     public function setGames(array $games): Child
     {
         $this->games = $games;
        return $this;
     }

constructor denormalization

  • However for the other case: the constructor denormalization: the function instatiateObject from the AbstractNormalizer class is being executed and there there are no check on the type collection $params[] = $parameterData; ==> that line exactly is responsible of giving me back an array of attributes instead of creating an object from the class Game which I really found a bad behaviour and mis-leading.

How to reproduce
Just setting a Child class with an attribute games which is an array of Game objects. And a class Game with some attributes. And then A Json Object that represents a child objects with a related array of games is enough to reproduces this behaviour.
A hint for the JSON:

{
	"name": "test-boy",
	"age": 12,
	"games": [{
		"name": "Age of Empire",
		"genre": "Strategy"
	}]

}

Possible Solution
The possible solution is to implement a collection verification as it is implemented on the first case (setter denormalization) would be enough I guess to fix this behaviour.

@sadokmtir sadokmtir changed the title Serialisation of nested array of objects using constructor denormalization Serialization of nested array of objects using constructor denormalization Aug 2, 2018
@msolhao
Copy link

msolhao commented Aug 31, 2018

Symfony Serializer v4.1 is also affected.

@rdavaillaud
Copy link
Contributor

maybe a duplicate of #25524

@Simperfit
Copy link
Contributor

@xabbuh I think this is a dupplicate of #25524

@xabbuh xabbuh closed this as completed Apr 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants