From 0550eefaf41248e91d3db2fb5a62002026898e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 29 Oct 2025 17:26:54 +0100 Subject: [PATCH] Make AbstractManagerRegistry::$proxyInterfaceName nullable --- UPGRADE.md | 5 ++++ src/AbstractManagerRegistry.php | 26 ++++++++-------- tests/ManagerRegistryTest.php | 53 +++++++++++++++++++++++++++++++-- 3 files changed, 70 insertions(+), 14 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index ca89d1bc..d3a5078b 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -41,6 +41,11 @@ return function (ClassMetadata $metadata): void { }; ``` +## Do not pass any proxy interface to `AbstractManagerRegistry` when using native proxies + +With PHP 8.4 native lazy objects, you don't need to pass any proxy interface to +`AbstractManagerRegistry`. The class of the lazy objects is the class being mapped. + # Upgrade to 4.0 ## BC Break: Removed `StaticReflectionService` diff --git a/src/AbstractManagerRegistry.php b/src/AbstractManagerRegistry.php index 68049cce..351848ba 100644 --- a/src/AbstractManagerRegistry.php +++ b/src/AbstractManagerRegistry.php @@ -18,7 +18,7 @@ abstract class AbstractManagerRegistry implements ManagerRegistry /** * @param array $connections * @param array $managers - * @phpstan-param class-string $proxyInterfaceName + * @phpstan-param class-string|null $proxyInterfaceName Set to null when native lazy objects are used. */ public function __construct( private readonly string $name, @@ -26,7 +26,7 @@ public function __construct( private array $managers, private readonly string $defaultConnection, private readonly string $defaultManager, - private readonly string $proxyInterfaceName, + private readonly string|null $proxyInterfaceName = null, ) { } @@ -127,19 +127,21 @@ public function getManager(string|null $name = null): ObjectManager public function getManagerForClass(string $class): ObjectManager|null { - $proxyClass = new ReflectionClass($class); - if ($proxyClass->isAnonymous()) { - return null; - } - - if ($proxyClass->implementsInterface($this->proxyInterfaceName)) { - $parentClass = $proxyClass->getParentClass(); - - if ($parentClass === false) { + if ($this->proxyInterfaceName !== null) { + $proxyClass = new ReflectionClass($class); + if ($proxyClass->isAnonymous()) { return null; } - $class = $parentClass->getName(); + if ($proxyClass->implementsInterface($this->proxyInterfaceName)) { + $parentClass = $proxyClass->getParentClass(); + + if ($parentClass === false) { + return null; + } + + $class = $parentClass->getName(); + } } foreach ($this->managers as $id) { diff --git a/tests/ManagerRegistryTest.php b/tests/ManagerRegistryTest.php index a32dcc4a..c796d658 100644 --- a/tests/ManagerRegistryTest.php +++ b/tests/ManagerRegistryTest.php @@ -45,6 +45,22 @@ public function testGetManagerForClass(): void ); } + public function testGetManagerForClassAnonymous(): void + { + $anonymousClass = new class extends TestObject implements Proxy { + public function __isInitialized(): bool + { + return true; + } + + public function __load(): void + { + } + }; + + self::assertNull($this->mr->getManagerForClass($anonymousClass::class)); + } + public function testGetManagerForProxiedClass(): void { self::assertInstanceOf( @@ -64,6 +80,39 @@ public function testGetManagerForAnonymousClass(): void })::class)); } + public function testGetManagerForWithoutProxyInterface(): void + { + $mr = new TestManagerRegistry( + 'ORM', + ['default' => 'default_connection'], + ['default' => 'default_manager'], + 'default', + 'default', + null, + $this->getManagerFactory(), + ); + + self::assertInstanceOf( + ObjectManager::class, + $mr->getManagerForClass(TestObject::class), + ); + + self::assertNull($mr->getManagerForClass(TestObjectProxy::class)); + + $anonymousClass = new class extends TestObject implements Proxy { + public function __isInitialized(): bool + { + return true; + } + + public function __load(): void + { + } + }; + + self::assertNull($mr->getManagerForClass($anonymousClass::class)); + } + public function testResetManager(): void { $manager = $this->mr->getManager(); @@ -179,7 +228,7 @@ class TestManagerRegistry extends AbstractManagerRegistry /** * {@inheritDoc} * - * @phpstan-param class-string $proxyInterfaceName + * @phpstan-param class-string|null $proxyInterfaceName */ public function __construct( string $name, @@ -187,7 +236,7 @@ public function __construct( array $managers, string $defaultConnection, string $defaultManager, - string $proxyInterfaceName, + string|null $proxyInterfaceName, callable $managerFactory, ) { $this->managerFactory = $managerFactory;