diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index a5a28bba..44737db4 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -12,4 +12,4 @@ on: jobs: coding-standards: name: "Coding Standards" - uses: "doctrine/.github/.github/workflows/coding-standards.yml@12.1.0" + uses: "doctrine/.github/.github/workflows/coding-standards.yml@13.1.0" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index bb318e00..68544aa8 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -12,7 +12,7 @@ on: jobs: phpunit: name: "PHPUnit" - uses: "doctrine/.github/.github/workflows/continuous-integration.yml@12.1.0" + uses: "doctrine/.github/.github/workflows/continuous-integration.yml@13.1.0" with: php-versions: '["8.4", "8.5"]' phpunit-options-lowest: "--do-not-fail-on-deprecation" diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 90c54d67..2d63d1e5 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -17,4 +17,4 @@ on: jobs: documentation: name: "Documentation" - uses: "doctrine/.github/.github/workflows/documentation.yml@12.2.0" + uses: "doctrine/.github/.github/workflows/documentation.yml@13.1.0" diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index 89dba39e..b82f876e 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -8,7 +8,7 @@ on: jobs: release: name: "Git tag, release & create merge-up PR" - uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@12.1.0" + uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@13.1.0" secrets: GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }} GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }} diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 355099da..645c3b07 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -12,4 +12,4 @@ on: jobs: static-analysis: name: "Static Analysis" - uses: "doctrine/.github/.github/workflows/phpstan.yml@12.1.0" + uses: "doctrine/.github/.github/workflows/phpstan.yml@13.1.0" diff --git a/UPGRADE.md b/UPGRADE.md index 29f3eed5..3121c9e2 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -56,6 +56,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/composer.json b/composer.json index 4d1e4f3c..972ab51a 100644 --- a/composer.json +++ b/composer.json @@ -31,8 +31,8 @@ "phpstan/phpstan-strict-rules": "^2", "doctrine/coding-standard": "^14", "phpunit/phpunit": "^10.5.58 || ^12", - "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0", - "symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0" + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0", + "symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0" }, "autoload": { "psr-4": { diff --git a/docs/en/reference/index.rst b/docs/en/reference/index.rst index e17eca8f..f9646a6d 100644 --- a/docs/en/reference/index.rst +++ b/docs/en/reference/index.rst @@ -149,10 +149,12 @@ your mapped PHP classes. public function getAllMetadata(); public function getMetadataFor($className); public function hasMetadataFor($className); - public function setMetadataFor($className, $class); + public function setMetadataFor($className, $class); // Deprecated public function isTransient($className); } +The method ``setMetadataFor()`` is deprecated and should not be used. + Mapping Driver ============== diff --git a/src/AbstractManagerRegistry.php b/src/AbstractManagerRegistry.php index 407eb1b8..23ce6854 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|null $proxyInterfaceName + * @phpstan-param class-string|null $proxyInterfaceName Set to null when native lazy objects are used. */ public function __construct( private readonly string $name, diff --git a/src/Mapping/AbstractClassMetadataFactory.php b/src/Mapping/AbstractClassMetadataFactory.php index 99c41a7e..fd4f8cc7 100644 --- a/src/Mapping/AbstractClassMetadataFactory.php +++ b/src/Mapping/AbstractClassMetadataFactory.php @@ -233,7 +233,7 @@ public function hasMetadataFor(string $className): bool /** * Sets the metadata descriptor for a specific class. * - * NOTE: This is only useful in very special cases, like when generating proxy classes. + * @deprecated Since 4.2, use a custom ClassMetadataFactory implementation if you need to set metadata manually. * * @phpstan-param class-string $className * @phpstan-param CMTemplate $class diff --git a/src/Mapping/ClassMetadataFactory.php b/src/Mapping/ClassMetadataFactory.php index 68e4595b..6b3c2ae8 100644 --- a/src/Mapping/ClassMetadataFactory.php +++ b/src/Mapping/ClassMetadataFactory.php @@ -41,6 +41,8 @@ public function hasMetadataFor(string $className): bool; /** * Sets the metadata descriptor for a specific class. * + * @deprecated Since 4.2, use a custom ClassMetadataFactory implementation if you need to set metadata manually. + * * @param class-string $className * @phpstan-param T $class */ 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;