From f72bd175d3f589eb846618a2c115dcbd369681b5 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Fri, 5 Jul 2024 14:55:18 +0200 Subject: [PATCH] Fix the initialization of lazy-ghost proxies with postLoad listeners PostLoad listeners might initialize values for transient properties, so the proxy should not skip initialization when using transient properties. --- src/Proxy/ProxyFactory.php | 2 +- tests/Tests/Models/GH11524/GH11524Entity.php | 31 +++++++++++ .../Tests/Models/GH11524/GH11524Listener.php | 21 ++++++++ .../Tests/Models/GH11524/GH11524Relation.php | 50 ++++++++++++++++++ .../ORM/Functional/Ticket/GH11524Test.php | 51 +++++++++++++++++++ 5 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 tests/Tests/Models/GH11524/GH11524Entity.php create mode 100644 tests/Tests/Models/GH11524/GH11524Listener.php create mode 100644 tests/Tests/Models/GH11524/GH11524Relation.php create mode 100644 tests/Tests/ORM/Functional/Ticket/GH11524Test.php diff --git a/src/Proxy/ProxyFactory.php b/src/Proxy/ProxyFactory.php index dc8a72bfcea..12023176106 100644 --- a/src/Proxy/ProxyFactory.php +++ b/src/Proxy/ProxyFactory.php @@ -447,7 +447,7 @@ private function getProxyFactory(string $className): Closure foreach ($reflector->getProperties($filter) as $property) { $name = $property->name; - if ($property->isStatic() || (($class->hasField($name) || $class->hasAssociation($name)) && ! isset($identifiers[$name]))) { + if ($property->isStatic() || ! isset($identifiers[$name])) { continue; } diff --git a/tests/Tests/Models/GH11524/GH11524Entity.php b/tests/Tests/Models/GH11524/GH11524Entity.php new file mode 100644 index 00000000000..175c8e77a3b --- /dev/null +++ b/tests/Tests/Models/GH11524/GH11524Entity.php @@ -0,0 +1,31 @@ +getObject(); + + if (!$object instanceof GH11524Relation) { + return; + } + + $object->setCurrentLocale('en'); + } +} diff --git a/tests/Tests/Models/GH11524/GH11524Relation.php b/tests/Tests/Models/GH11524/GH11524Relation.php new file mode 100644 index 00000000000..ae028a5f7cf --- /dev/null +++ b/tests/Tests/Models/GH11524/GH11524Relation.php @@ -0,0 +1,50 @@ +currentLocale = $locale; + } + + public function getTranslation(): string + { + if ($this->currentLocale === null) { + throw new LogicException('The current locale must be set to retrieve translation.'); + } + + return 'fake'; + } +} diff --git a/tests/Tests/ORM/Functional/Ticket/GH11524Test.php b/tests/Tests/ORM/Functional/Ticket/GH11524Test.php new file mode 100644 index 00000000000..9eeb09b25c4 --- /dev/null +++ b/tests/Tests/ORM/Functional/Ticket/GH11524Test.php @@ -0,0 +1,51 @@ +createSchemaForModels( + GH11524Entity::class, + GH11524Relation::class + ); + + $this->_em->getEventManager()->addEventListener(Events::postLoad, new GH11524Listener()); + } + + public function testPostLoadCalledOnProxy(): void + { + $relation = new GH11524Relation(); + $relation->name = 'test'; + $this->_em->persist($relation); + + $entity = new GH11524Entity(); + $entity->relation = $relation; + + $this->_em->persist($entity); + $this->_em->flush(); + + $this->_em->clear(); + + $reloadedEntity = $this->_em->find(GH11524Entity::class, $entity->id); + + $reloadedRelation = $reloadedEntity->relation; + + $this->assertInstanceOf(Proxy::class, $reloadedRelation, 'The reloaded relation must be a proxy'); + $this->assertFalse($reloadedRelation->__isInitialized()); + + $this->assertSame('fake', $reloadedRelation->getTranslation(), 'The property set by the postLoad listener must get initialized on usage.'); + } +}