Skip to content

Commit e7eef10

Browse files
committed
Refactoring resolver to be open to metadata resolution without objectManagerLoader
1 parent b6bf1db commit e7eef10

7 files changed

+73
-109
lines changed

src/Reflection/Doctrine/EntityRepositoryClassReflectionExtension.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,16 @@ public function hasMethod(\PHPStan\Reflection\ClassReflection $classReflection,
6060
return false;
6161
}
6262

63-
$objectManager = $this->objectMetadataResolver->getObjectManager();
64-
if ($objectManager === null) {
65-
return false;
66-
}
67-
6863
$classReflection = $entityClassType->getClassReflection();
6964
if ($classReflection === null) {
7065
return false;
7166
}
7267

7368
$fieldName = $this->classify($methodFieldName);
74-
$classMetadata = $objectManager->getClassMetadata($classReflection->getName());
69+
$classMetadata = $this->objectMetadataResolver->getClassMetadata($classReflection->getName());
70+
if ($classMetadata === null) {
71+
return false;
72+
}
7573

7674
return $classMetadata->hasField($fieldName) || $classMetadata->hasAssociation($fieldName);
7775
}

src/Rules/Doctrine/ORM/EntityColumnRule.php

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,9 @@ public function processNode(Node $node, Scope $scope): array
7272
return [];
7373
}
7474

75-
$objectManager = $this->objectMetadataResolver->getObjectManager();
76-
if ($objectManager === null) {
77-
return [];
78-
}
79-
8075
$className = $class->getName();
81-
try {
82-
if ($objectManager->getMetadataFactory()->isTransient($className)) {
83-
return [];
84-
}
85-
} catch (\ReflectionException $e) {
86-
return [];
87-
}
88-
89-
try {
90-
$metadata = $objectManager->getClassMetadata($className);
91-
} catch (\Doctrine\ORM\Mapping\MappingException $e) {
92-
return [];
93-
}
94-
95-
$classMetadataInfo = 'Doctrine\ORM\Mapping\ClassMetadataInfo';
96-
if (!$metadata instanceof $classMetadataInfo) {
76+
$metadata = $this->objectMetadataResolver->getClassMetadata($className);
77+
if ($metadata === null) {
9778
return [];
9879
}
9980

src/Rules/Doctrine/ORM/EntityNotFinalRule.php

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,7 @@ public function processNode(Node $node, Scope $scope): array
3838
return [];
3939
}
4040

41-
$objectManager = $this->objectMetadataResolver->getObjectManager();
42-
if ($objectManager === null) {
43-
return [];
44-
}
45-
46-
try {
47-
if ($objectManager->getMetadataFactory()->isTransient($classReflection->getName())) {
48-
return [];
49-
}
50-
} catch (\ReflectionException $e) {
41+
if ($this->objectMetadataResolver->isTransient($classReflection->getName())) {
5142
return [];
5243
}
5344

src/Rules/Doctrine/ORM/EntityRelationRule.php

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,28 +49,9 @@ public function processNode(Node $node, Scope $scope): array
4949
return [];
5050
}
5151

52-
$objectManager = $this->objectMetadataResolver->getObjectManager();
53-
if ($objectManager === null) {
54-
return [];
55-
}
56-
5752
$className = $class->getName();
58-
try {
59-
if ($objectManager->getMetadataFactory()->isTransient($className)) {
60-
return [];
61-
}
62-
} catch (\ReflectionException $e) {
63-
return [];
64-
}
65-
66-
try {
67-
$metadata = $objectManager->getClassMetadata($className);
68-
} catch (\Doctrine\ORM\Mapping\MappingException $e) {
69-
return [];
70-
}
71-
72-
$classMetadataInfo = 'Doctrine\ORM\Mapping\ClassMetadataInfo';
73-
if (!$metadata instanceof $classMetadataInfo) {
53+
$metadata = $this->objectMetadataResolver->getClassMetadata($className);
54+
if ($metadata === null) {
7455
return [];
7556
}
7657

src/Rules/Doctrine/ORM/PropertiesExtension.php

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,52 +20,19 @@ public function __construct(ObjectMetadataResolver $objectMetadataResolver)
2020
public function isAlwaysRead(PropertyReflection $property, string $propertyName): bool
2121
{
2222
$className = $property->getDeclaringClass()->getName();
23-
$metadata = $this->findMetadata($className);
23+
$metadata = $this->objectMetadataResolver->getClassMetadata($className);
2424
if ($metadata === null) {
2525
return false;
2626
}
2727

2828
return $metadata->hasField($propertyName) || $metadata->hasAssociation($propertyName);
2929
}
3030

31-
/**
32-
* @param class-string $className
33-
* @return \Doctrine\ORM\Mapping\ClassMetadataInfo<object>
34-
*/
35-
private function findMetadata(string $className): ?\Doctrine\ORM\Mapping\ClassMetadataInfo
36-
{
37-
$objectManager = $this->objectMetadataResolver->getObjectManager();
38-
if ($objectManager === null) {
39-
return null;
40-
}
41-
42-
try {
43-
if ($objectManager->getMetadataFactory()->isTransient($className)) {
44-
return null;
45-
}
46-
} catch (\ReflectionException $e) {
47-
return null;
48-
}
49-
50-
try {
51-
$metadata = $objectManager->getClassMetadata($className);
52-
} catch (\Doctrine\ORM\Mapping\MappingException $e) {
53-
return null;
54-
}
55-
56-
$classMetadataInfo = 'Doctrine\ORM\Mapping\ClassMetadataInfo';
57-
if (!$metadata instanceof $classMetadataInfo) {
58-
return null;
59-
}
60-
61-
return $metadata;
62-
}
63-
6431
public function isAlwaysWritten(PropertyReflection $property, string $propertyName): bool
6532
{
6633
$declaringClass = $property->getDeclaringClass();
6734
$className = $declaringClass->getName();
68-
$metadata = $this->findMetadata($className);
35+
$metadata = $this->objectMetadataResolver->getClassMetadata($className);
6936
if ($metadata === null) {
7037
return false;
7138
}
@@ -100,7 +67,7 @@ public function isInitialized(PropertyReflection $property, string $propertyName
10067
{
10168
$declaringClass = $property->getDeclaringClass();
10269
$className = $declaringClass->getName();
103-
$metadata = $this->findMetadata($className);
70+
$metadata = $this->objectMetadataResolver->getClassMetadata($className);
10471
if ($metadata === null) {
10572
return false;
10673
}

src/Rules/Doctrine/ORM/RepositoryMethodCallRule.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,11 @@ public function processNode(Node $node, Scope $scope): array
7777
return [];
7878
}
7979

80-
$objectManager = $this->objectMetadataResolver->getObjectManager();
81-
if ($objectManager === null) {
80+
$classMetadata = $this->objectMetadataResolver->getClassMetadata($entityClassReflection->getName());
81+
if ($classMetadata === null) {
8282
return [];
8383
}
8484

85-
$classMetadata = $objectManager->getClassMetadata($entityClassReflection->getName());
86-
8785
$messages = [];
8886
foreach ($argType->getKeyTypes() as $keyType) {
8987
if (!$keyType instanceof ConstantStringType) {

src/Type/Doctrine/ObjectMetadataResolver.php

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine;
44

5+
use Doctrine\ORM\Mapping\ClassMetadataInfo;
56
use Doctrine\Persistence\ObjectManager;
67
use PHPStan\Reflection\ReflectionProvider;
78
use function is_file;
@@ -58,6 +59,56 @@ public function getObjectManager(): ?ObjectManager
5859
return $this->objectManager;
5960
}
6061

62+
/**
63+
* @param class-string $className
64+
* @return bool
65+
*/
66+
public function isTransient(string $className): bool
67+
{
68+
$objectManager = $this->getObjectManager();
69+
if ($objectManager === null) {
70+
return true;
71+
}
72+
73+
try {
74+
return $objectManager->getMetadataFactory()->isTransient($className);
75+
} catch (\ReflectionException $e) {
76+
return true;
77+
}
78+
}
79+
80+
/**
81+
* @template T of object
82+
* @param class-string<T> $className
83+
* @return ClassMetadataInfo<T>|null
84+
*/
85+
public function getClassMetadata(string $className): ?ClassMetadataInfo
86+
{
87+
$objectManager = $this->getObjectManager();
88+
if ($objectManager === null) {
89+
return null;
90+
}
91+
92+
if ($this->isTransient($className)) {
93+
return null;
94+
}
95+
96+
try {
97+
$metadata = $objectManager->getClassMetadata($className);
98+
} catch (\Doctrine\ORM\Mapping\MappingException $e) {
99+
return null;
100+
}
101+
102+
if (!$metadata instanceof ClassMetadataInfo) {
103+
return null;
104+
}
105+
106+
/** @var \Doctrine\ORM\Mapping\ClassMetadataInfo<T> $ormMetadata */
107+
$ormMetadata = $metadata;
108+
109+
return $ormMetadata;
110+
}
111+
61112
private function loadObjectManager(string $objectManagerLoader): ?ObjectManager
62113
{
63114
if (!is_file($objectManagerLoader)) {
@@ -97,11 +148,6 @@ public function getResolvedRepositoryClass(): string
97148

98149
public function getRepositoryClass(string $className): string
99150
{
100-
$objectManager = $this->getObjectManager();
101-
if ($objectManager === null) {
102-
return $this->getResolvedRepositoryClass();
103-
}
104-
105151
if (!$this->reflectionProvider->hasClass($className)) {
106152
return $this->getResolvedRepositoryClass();
107153
}
@@ -111,15 +157,17 @@ public function getRepositoryClass(string $className): string
111157
return $this->getResolvedRepositoryClass();
112158
}
113159

114-
$metadata = $objectManager->getClassMetadata($classReflection->getName());
160+
$metadata = $this->getClassMetadata($classReflection->getName());
161+
if ($metadata !== null) {
162+
return $metadata->customRepositoryClassName ?? $this->getResolvedRepositoryClass();
163+
}
115164

116-
$ormMetadataClass = 'Doctrine\ORM\Mapping\ClassMetadata';
117-
if ($metadata instanceof $ormMetadataClass) {
118-
/** @var \Doctrine\ORM\Mapping\ClassMetadata<object> $ormMetadata */
119-
$ormMetadata = $metadata;
120-
return $ormMetadata->customRepositoryClassName ?? $this->getResolvedRepositoryClass();
165+
$objectManager = $this->getObjectManager();
166+
if ($objectManager === null) {
167+
return $this->getResolvedRepositoryClass();
121168
}
122169

170+
$metadata = $objectManager->getClassMetadata($classReflection->getName());
123171
$odmMetadataClass = 'Doctrine\ODM\MongoDB\Mapping\ClassMetadata';
124172
if ($metadata instanceof $odmMetadataClass) {
125173
/** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadata<object> $odmMetadata */

0 commit comments

Comments
 (0)