From 22f966117af42436fd346b41b586158bd4b5e1da Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Sat, 18 Dec 2021 13:35:24 +0100 Subject: [PATCH] Discover repository class from `#[Entity]` attribute on PHP 8 By doing it like this, we don't need to instantiate the object manager at all. --- attribute-errors.neon | 6 ++++++ ignore-by-php-version.neon.php | 15 +++++++++++++++ phpstan.neon | 1 + src/Type/Doctrine/ObjectMetadataResolver.php | 12 ++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 attribute-errors.neon create mode 100644 ignore-by-php-version.neon.php diff --git a/attribute-errors.neon b/attribute-errors.neon new file mode 100644 index 00000000..26463f90 --- /dev/null +++ b/attribute-errors.neon @@ -0,0 +1,6 @@ +parameters: + ignoreErrors: + - + message: "#^Call to an undefined method ReflectionClass::getAttributes\\(\\)\\.$#" + count: 1 + path: src/Type/Doctrine/ObjectMetadataResolver.php diff --git a/ignore-by-php-version.neon.php b/ignore-by-php-version.neon.php new file mode 100644 index 00000000..70da741e --- /dev/null +++ b/ignore-by-php-version.neon.php @@ -0,0 +1,15 @@ +load(__DIR__ . '/attribute-errors.neon')); +} + +$config['parameters']['phpVersion'] = PHP_VERSION_ID; + +return $config; diff --git a/phpstan.neon b/phpstan.neon index a8cde690..ba1e8811 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,7 @@ includes: - extension.neon - rules.neon + - ignore-by-php-version.neon.php - vendor/phpstan/phpstan-strict-rules/rules.neon - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/phpstan/phpstan-phpunit/rules.neon diff --git a/src/Type/Doctrine/ObjectMetadataResolver.php b/src/Type/Doctrine/ObjectMetadataResolver.php index 79cd1a56..e1406239 100644 --- a/src/Type/Doctrine/ObjectMetadataResolver.php +++ b/src/Type/Doctrine/ObjectMetadataResolver.php @@ -2,6 +2,7 @@ namespace PHPStan\Type\Doctrine; +use Doctrine\ORM\Mapping\Entity; use Doctrine\Persistence\ObjectManager; use PHPStan\Reflection\ReflectionProvider; use function is_file; @@ -97,6 +98,17 @@ public function getResolvedRepositoryClass(): string public function getRepositoryClass(string $className): string { + if (PHP_MAJOR_VERSION >= 8 && $this->reflectionProvider->hasClass($className)) { + $classReflection = $this->reflectionProvider->getClass($className)->getNativeReflection(); + $attribute = $classReflection->getAttributes(Entity::class)[0] ?? null; + if ($attribute !== null) { + $attributeInstance = $attribute->newInstance(); + if ($attributeInstance->repositoryClass !== null) { + return $attributeInstance->repositoryClass; + } + } + } + $objectManager = $this->getObjectManager(); if ($objectManager === null) { return $this->getResolvedRepositoryClass();