Skip to content

Commit

Permalink
bug #26140 [Serializer] deserialize as a null when inner object canno…
Browse files Browse the repository at this point in the history
…t be created and type hint allows null (kbkk)

This PR was squashed before being merged into the 4.1-dev branch (closes #26140).

Discussion
----------

[Serializer] deserialize as a null when inner object cannot be created and type hint allows null

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT

```php
class ObjectConstructorDummy
{
    protected $foo;
    public $bar;
    private $baz;

    public function __construct($foo, $bar, $baz)
    {
        $this->foo = $foo;
        $this->bar = $bar;
        $this->baz = $baz;
    }
}

class DummyWithNullableConstructorObject
{
    private $id;
    private $inner;

    public function __construct($id, ?ObjectConstructorDummy $inner)
    {
        $this->id = $id;
        $this->inner = $inner;
    }

    public function getId()
    {
        return $this->id;
    }

    public function getInner()
    {
        return $this->inner;
    }
}
```

Trying to deserialize to `DummyWithNullableConstructorObject` with the following data currently fails:
```php
[
    'id' => 10,
    'inner' => null
]
```

With this PR `DummyWithNullableConstructorObject ` would be constructed with `null` passed as `$inner` because of the type hint.

Commits
-------

2fe9eb1 [Serializer] deserialize as a null when inner object cannot be created and type hint allows null
  • Loading branch information
fabpot committed Feb 19, 2018
2 parents 3aa59b6 + 2fe9eb1 commit 3303355
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
Expand Up @@ -351,6 +351,11 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref
}
} catch (\ReflectionException $e) {
throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e);
} catch (MissingConstructorArgumentsException $e) {
if (!$constructorParameter->getType()->allowsNull()) {
throw $e;
}
$parameterData = null;
}

// Don't run set for a parameter passed to the constructor
Expand Down
Expand Up @@ -182,6 +182,23 @@ public function testConstructorWithObjectTypeHintDenormalize()
$this->assertEquals('rab', $obj->getInner()->bar);
}

public function testConstructorWithUnconstructableNullableObjectTypeHintDenormalize()
{
$data = array(
'id' => 10,
'inner' => null,
);

$normalizer = new ObjectNormalizer();
$serializer = new Serializer(array($normalizer));
$normalizer->setSerializer($serializer);

$obj = $normalizer->denormalize($data, DummyWithNullableConstructorObject::class);
$this->assertInstanceOf(DummyWithNullableConstructorObject::class, $obj);
$this->assertEquals(10, $obj->getId());
$this->assertNull($obj->getInner());
}

/**
* @expectedException \Symfony\Component\Serializer\Exception\RuntimeException
* @expectedExceptionMessage Could not determine the class of the parameter "unknown".
Expand Down Expand Up @@ -1109,3 +1126,25 @@ public function getFoo()
return $this->Foo;
}
}

class DummyWithNullableConstructorObject
{
private $id;
private $inner;

public function __construct($id, ?ObjectConstructorDummy $inner)
{
$this->id = $id;
$this->inner = $inner;
}

public function getId()
{
return $this->id;
}

public function getInner()
{
return $this->inner;
}
}

0 comments on commit 3303355

Please sign in to comment.