Skip to content

Commit 842047b

Browse files
committed
Fix $entityManager->getRepository() with non-classes
1 parent fb0350e commit 842047b

File tree

8 files changed

+52
-7
lines changed

8 files changed

+52
-7
lines changed

src/Type/Doctrine/ObjectMetadataResolver.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
namespace PHPStan\Type\Doctrine;
44

55
use Doctrine\Common\Persistence\ObjectManager;
6+
use PHPStan\Reflection\ReflectionProvider;
67
use function file_exists;
78
use function is_readable;
89

910
final class ObjectMetadataResolver
1011
{
1112

13+
/** @var ReflectionProvider */
14+
private $reflectionProvider;
15+
1216
/** @var string|null */
1317
private $objectManagerLoader;
1418

@@ -21,8 +25,13 @@ final class ObjectMetadataResolver
2125
/** @var string|null */
2226
private $resolvedRepositoryClass;
2327

24-
public function __construct(?string $objectManagerLoader, ?string $repositoryClass)
28+
public function __construct(
29+
ReflectionProvider $reflectionProvider,
30+
?string $objectManagerLoader,
31+
?string $repositoryClass
32+
)
2533
{
34+
$this->reflectionProvider = $reflectionProvider;
2635
$this->objectManagerLoader = $objectManagerLoader;
2736
$this->repositoryClass = $repositoryClass;
2837
}
@@ -83,6 +92,15 @@ public function getRepositoryClass(string $className): string
8392
return $this->getResolvedRepositoryClass();
8493
}
8594

95+
if (!$this->reflectionProvider->hasClass($className)) {
96+
return $this->getResolvedRepositoryClass();
97+
}
98+
99+
$classReflection = $this->reflectionProvider->getClass($className);
100+
if ($classReflection->isInterface() || $classReflection->isTrait()) {
101+
return $this->getResolvedRepositoryClass();
102+
}
103+
86104
$metadata = $objectManager->getClassMetadata($className);
87105

88106
$ormMetadataClass = 'Doctrine\ORM\Mapping\ClassMetadata';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"message": "Parameter #1 $className of method Doctrine\\Persistence\\ObjectManager::getRepository() expects class-string<nonexistentClass>, string given.",
4+
"line": 211,
5+
"ignorable": true
6+
}
7+
]

tests/DoctrineIntegration/ORM/data/entityRepositoryDynamicReturn.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,23 @@ public function doSomething(): void
192192
{
193193
}
194194
}
195+
196+
interface EntityInterface
197+
{
198+
199+
}
200+
201+
class GetRepositoryOnNonClasses
202+
{
203+
204+
public function doFoo(EntityManagerInterface $entityManager): void
205+
{
206+
$entityManager->getRepository(EntityInterface::class);
207+
}
208+
209+
public function doBar(EntityManagerInterface $entityManager): void
210+
{
211+
$entityManager->getRepository('nonexistentClass');
212+
}
213+
214+
}

tests/Rules/Doctrine/ORM/DqlRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class DqlRuleTest extends RuleTestCase
1414

1515
protected function getRule(): Rule
1616
{
17-
return new DqlRule(new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null));
17+
return new DqlRule(new ObjectMetadataResolver($this->createReflectionProvider(), __DIR__ . '/entity-manager.php', null));
1818
}
1919

2020
public function testRule(): void

tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ protected function getRule(): Rule
3636
}
3737

3838
return new EntityColumnRule(
39-
new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null),
39+
new ObjectMetadataResolver($this->createReflectionProvider(), __DIR__ . '/entity-manager.php', null),
4040
new DescriptorRegistry([
4141
new BigIntType(),
4242
new StringType(),

tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class EntityRelationRuleTest extends RuleTestCase
1616
protected function getRule(): Rule
1717
{
1818
return new EntityRelationRule(
19-
new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null)
19+
new ObjectMetadataResolver($this->createReflectionProvider(), __DIR__ . '/entity-manager.php', null)
2020
);
2121
}
2222

tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class QueryBuilderDqlRuleTest extends RuleTestCase
3030

3131
protected function getRule(): Rule
3232
{
33-
return new QueryBuilderDqlRule(new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null), true);
33+
return new QueryBuilderDqlRule(new ObjectMetadataResolver($this->createReflectionProvider(), __DIR__ . '/entity-manager.php', null), true);
3434
}
3535

3636
public function testRule(): void
@@ -168,7 +168,7 @@ public function testBranchingPerformance(): void
168168
*/
169169
public function getDynamicMethodReturnTypeExtensions(): array
170170
{
171-
$objectMetadataResolver = new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null);
171+
$objectMetadataResolver = new ObjectMetadataResolver($this->createReflectionProvider(), __DIR__ . '/entity-manager.php', null);
172172
$argumentsProcessor = new ArgumentsProcessor();
173173

174174
return [

tests/Rules/Doctrine/ORM/RepositoryMethodCallRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class RepositoryMethodCallRuleTest extends RuleTestCase
1414

1515
protected function getRule(): Rule
1616
{
17-
return new RepositoryMethodCallRule(new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null));
17+
return new RepositoryMethodCallRule(new ObjectMetadataResolver($this->createReflectionProvider(), __DIR__ . '/entity-manager.php', null));
1818
}
1919

2020
/**

0 commit comments

Comments
 (0)