Skip to content

Commit

Permalink
handle null
Browse files Browse the repository at this point in the history
  • Loading branch information
goetas committed May 3, 2019
1 parent edb07a6 commit 20eb38d
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/DeserializationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class DeserializationContext extends Context
/**
* @var bool
*/
private $deserializeNull = false;
private $deserializeNull = true;

public static function create(): self
{
Expand Down
15 changes: 7 additions & 8 deletions src/GraphNavigator/DeserializationGraphNavigator.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,10 @@ public function accept($data, ?array $type = null)
// If null is explicitly allowed we should skip this
if ($this->visitor instanceof NullAwareVisitorInterface
&& true === $this->visitor->isNull($data)
&& (!empty($type['nullable']) || false === $this->shouldDeserializeNull)
&& true === $this->shouldDeserializeNull
) {
$type = ['name' => 'NULL', 'params' => []];
}

switch ($type['name']) {
case 'NULL':
return $this->visitor->visitNull($data, $type);
Expand Down Expand Up @@ -170,9 +169,11 @@ public function accept($data, ?array $type = null)
// before loading metadata because the type name might not be a class, but
// could also simply be an artifical type.
if (null !== $handler = $this->handlerRegistry->getHandler(GraphNavigatorInterface::DIRECTION_DESERIALIZATION, $type['name'], $this->format)) {
$rs = \call_user_func($handler, $this->visitor, $data, $type, $this->context);
$this->context->decreaseDepth();

try {
$rs = \call_user_func($handler, $this->visitor, $data, $type, $this->context);
} finally {
$this->context->decreaseDepth();
}
return $rs;
}

Expand Down Expand Up @@ -219,9 +220,7 @@ public function accept($data, ?array $type = null)
try {
$v = $this->visitor->visitProperty($propertyMetadata, $data);

if (null !== $v || true === $this->shouldDeserializeNull) {
$this->accessor->setValue($object, $v, $propertyMetadata, $this->context);
}
$this->accessor->setValue($object, $v, $propertyMetadata, $this->context);
} catch (NotAcceptableException $e) {
}
$this->context->popPropertyMetadata();
Expand Down
9 changes: 1 addition & 8 deletions src/JsonDeserializationVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,6 @@ public function visitProperty(PropertyMetadata $metadata, $data)
}

if (true === $metadata->inline) {
if (!$metadata->type) {
throw new RuntimeException(sprintf(
'You must define a type for %s::$%s.',
$metadata->class,
$metadata->name
));
}
return $this->navigator->accept($data, $metadata->type);
}

Expand All @@ -176,7 +169,7 @@ public function visitProperty(PropertyMetadata $metadata, $data)
throw new NotAcceptableException();
}

return null !== $data[$name] ? $this->navigator->accept($data[$name], $metadata->type) : null;
return $this->navigator->accept($data[$name], $metadata->type);
}

/**
Expand Down
10 changes: 8 additions & 2 deletions tests/Fixtures/InitializedBlogPostConstructor.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ class InitializedBlogPostConstructor implements ObjectConstructorInterface
{
private $fallback;

public function __construct()
/**
* @var BlogPost
*/
private $blogPost;

public function __construct(BlogPost $blogPost)
{
$this->fallback = new UnserializeObjectConstructor();
$this->blogPost = $blogPost;
}

public function construct(DeserializationVisitorInterface $visitor, ClassMetadata $metadata, $data, array $type, DeserializationContext $context): ?object
Expand All @@ -25,6 +31,6 @@ public function construct(DeserializationVisitorInterface $visitor, ClassMetadat
return $this->fallback->construct($visitor, $metadata, $data, $type, $context);
}

return new BlogPost('This is a nice title.', new Author('Foo Bar'), new \DateTime('2011-07-30 00:00', new \DateTimeZone('UTC')), new Publisher('Bar Foo'));
return $this->blogPost;
}
}
30 changes: 17 additions & 13 deletions tests/Serializer/BaseSerializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public function testDeserializeNullObjectWithHandler()
$this->markTestSkipped(sprintf('No deserializer available for format `%s`', $this->getFormat()));
}
$ctx = DeserializationContext::create()
->setDeserializeNull(true);
->setDeserializeNull(false);

/** @var ObjectWithNullObject $dObj */
$dObj = $this->serializer->deserialize(
Expand Down Expand Up @@ -750,14 +750,13 @@ public function testBlogPost()

public function testDeserializingNull()
{
$objectConstructor = new InitializedBlogPostConstructor();
$post = new BlogPost('This is a nice title.', $author = new Author('Foo Bar'), new \DateTime('2011-07-30 00:00', new \DateTimeZone('UTC')), new Publisher('Bar Foo'));
$objectConstructor = new InitializedBlogPostConstructor($post);

$builder = SerializerBuilder::create();
$builder->setObjectConstructor($objectConstructor);
$this->serializer = $builder->build();

$post = new BlogPost('This is a nice title.', $author = new Author('Foo Bar'), new \DateTime('2011-07-30 00:00', new \DateTimeZone('UTC')), new Publisher('Bar Foo'));

$this->setField($post, 'author', null);
$this->setField($post, 'publisher', null);

Expand All @@ -771,37 +770,42 @@ public function testDeserializingNull()
self::assertAttributeSame(false, 'published', $deserialized);
self::assertAttributeSame(false, 'reviewed', $deserialized);
self::assertAttributeEquals(new ArrayCollection(), 'comments', $deserialized);
self::assertAttributeEquals(null, 'author', $deserialized);
self::assertAttributeSame(null, 'author', $deserialized);
self::assertAttributeSame(null, 'tag', $deserialized);
}
}

public function testDeserializingNullAllowed()
{
$objectConstructor = new InitializedBlogPostConstructor();
$savedPost = new BlogPost('This is a nice title.', $author = new Author('Foo Bar'), new \DateTime('2011-07-30 00:00', new \DateTimeZone('UTC')), $publisher = new Publisher('Bar Foo'));
$savedPost->addTag(new Tag('foo'));
$initialTag = $this->getField($savedPost, 'tag');

$objectConstructor = new InitializedBlogPostConstructor($savedPost);

$builder = SerializerBuilder::create();
$builder->setObjectConstructor($objectConstructor);
$this->serializer = $builder->build();

$post = new BlogPost('This is a nice title.', $author = new Author('Foo Bar'), new \DateTime('2011-07-30 00:00', new \DateTimeZone('UTC')), new Publisher('Bar Foo'));

$post = clone $savedPost;
$this->setField($post, 'author', null);
$this->setField($post, 'publisher', null);

self::assertEquals($this->getContent('blog_post_unauthored'), $this->serialize($post, SerializationContext::create()->setSerializeNull(true)));
$this->setField($post, 'tag', null);

if ($this->hasDeserializer()) {
$ctx = DeserializationContext::create();
$ctx->setDeserializeNull(true);
$ctx->setDeserializeNull(false);

$deserialized = $this->deserialize($this->getContent('blog_post_unauthored'), get_class($post), $ctx);
$deserialized = $this->deserialize($this->serialize($post), get_class($post), $ctx);

self::assertEquals('2011-07-30T00:00:00+00:00', $this->getField($deserialized, 'createdAt')->format(\DateTime::ATOM));
self::assertAttributeEquals('This is a nice title.', 'title', $deserialized);
self::assertAttributeSame(false, 'published', $deserialized);
self::assertAttributeSame(false, 'reviewed', $deserialized);
self::assertAttributeEquals(new ArrayCollection(), 'comments', $deserialized);
self::assertEquals(null, $this->getField($deserialized, 'author'));
self::assertAttributeEquals($author, 'author', $deserialized);
self::assertAttributeEquals($publisher, 'publisher', $deserialized);
self::assertAttributeEquals($initialTag, 'tag', $deserialized);
}
}

Expand Down

0 comments on commit 20eb38d

Please sign in to comment.