From 6395ff4dc81000b1ebed9ed5b2c6d12c6ffe532c Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Tue, 8 Oct 2019 14:43:14 +0200 Subject: [PATCH] Fix wrong initialisation of proxies with public properties --- .../ODM/MongoDB/Hydrator/HydratorFactory.php | 15 ++++++++++-- .../ODM/MongoDB/Tests/HydratorTest.php | 23 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php b/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php index e7d514f3be..4c7457165f 100644 --- a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php +++ b/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php @@ -465,8 +465,19 @@ public function hydrate(object $document, array $data, array $hints = []) : arra } } - if ($document instanceof GhostObjectInterface) { - $document->setProxyInitializer(null); + if ($document instanceof GhostObjectInterface && $document->getProxyInitializer() !== null) { + // Inject an empty initialiser to not load any object data + $document->setProxyInitializer(static function ( + GhostObjectInterface $ghostObject, + string $method, // we don't care + array $parameters, // we don't care + &$initializer, + array $properties // we currently do not use this + ) : bool { + $initializer = null; + + return true; + }); } $data = $this->getHydratorFor($metadata->name)->hydrate($document, $data, $hints); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php b/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php index 617b8c1f81..cf489e5076 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php +++ b/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php @@ -40,14 +40,37 @@ public function testHydrator() $this->assertEquals('jon', $user->name); $this->assertInstanceOf(DateTime::class, $user->birthdate); $this->assertInstanceOf(HydrationClosureReferenceOne::class, $user->referenceOne); + $this->assertInstanceOf(GhostObjectInterface::class, $user->referenceOne); $this->assertInstanceOf(PersistentCollection::class, $user->referenceMany); $this->assertInstanceOf(GhostObjectInterface::class, $user->referenceMany[0]); $this->assertInstanceOf(GhostObjectInterface::class, $user->referenceMany[1]); + $this->assertInstanceOf(HydrationClosureEmbedOne::class, $user->embedOne); $this->assertInstanceOf(PersistentCollection::class, $user->embedMany); $this->assertEquals('jon', $user->embedOne->name); $this->assertEquals('jon', $user->embedMany[0]->name); } + public function testHydrateProxyWithMissingAssociations() + { + $user = $this->dm->getReference(HydrationClosureUser::class, 1); + $this->assertInstanceOf(GhostObjectInterface::class, $user); + + $this->dm->getHydratorFactory()->hydrate($user, [ + '_id' => 1, + 'title' => null, + 'name' => 'jon', + ]); + + $this->assertEquals(1, $user->id); + $this->assertNull($user->title); + $this->assertEquals('jon', $user->name); + $this->assertNull($user->birthdate); + $this->assertNull($user->referenceOne); + $this->assertInstanceOf(PersistentCollection::class, $user->referenceMany); + $this->assertNull($user->embedOne); + $this->assertInstanceOf(PersistentCollection::class, $user->embedMany); + } + public function testReadOnly() { $class = $this->dm->getClassMetadata(HydrationClosureUser::class);