Skip to content

Commit 3318782

Browse files
committed
ManagerRegistry::getRepository returns correct EntityRepository
1 parent 77a6f9e commit 3318782

File tree

5 files changed

+139
-0
lines changed

5 files changed

+139
-0
lines changed

extension.neon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,9 @@ services:
3232
class: PHPStan\Type\Doctrine\ObjectRepositoryDynamicReturnTypeExtension
3333
tags:
3434
- phpstan.broker.dynamicMethodReturnTypeExtension
35+
-
36+
class: PHPStan\Type\Doctrine\ManagerRegistryGetRepositoryDynamicReturnTypeExtension
37+
arguments:
38+
repositoryClass: %doctrine.repositoryClass%
39+
tags:
40+
- phpstan.broker.dynamicMethodReturnTypeExtension
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Doctrine;
4+
5+
use PhpParser\Node\Expr\MethodCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Reflection\MethodReflection;
8+
use PHPStan\Reflection\ParametersAcceptorSelector;
9+
use PHPStan\Type\Constant\ConstantStringType;
10+
use PHPStan\Type\MixedType;
11+
use PHPStan\Type\Type;
12+
13+
class ManagerRegistryGetRepositoryDynamicReturnTypeExtension implements \PHPStan\Type\DynamicMethodReturnTypeExtension
14+
{
15+
16+
/** @var string */
17+
private $repositoryClass;
18+
19+
public function __construct(string $repositoryClass)
20+
{
21+
$this->repositoryClass = $repositoryClass;
22+
}
23+
24+
public function getClass(): string
25+
{
26+
return 'Doctrine\Common\Persistence\ManagerRegistry';
27+
}
28+
29+
public function isMethodSupported(MethodReflection $methodReflection): bool
30+
{
31+
return $methodReflection->getName() === 'getRepository';
32+
}
33+
34+
public function getTypeFromMethodCall(
35+
MethodReflection $methodReflection,
36+
MethodCall $methodCall,
37+
Scope $scope
38+
): Type
39+
{
40+
if (count($methodCall->args) === 0) {
41+
return ParametersAcceptorSelector::selectSingle(
42+
$methodReflection->getVariants()
43+
)->getReturnType();
44+
}
45+
$argType = $scope->getType($methodCall->args[0]->value);
46+
if (!$argType instanceof ConstantStringType) {
47+
return new MixedType();
48+
}
49+
50+
return new ObjectRepositoryType($argType->getValue(), $this->repositoryClass);
51+
}
52+
53+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\DoctrineIntegration\Persistence;
4+
5+
use PHPStan\Testing\LevelsTestCase;
6+
7+
final class ManagerRegistryIntegrationTest extends LevelsTestCase
8+
{
9+
10+
/**
11+
* @return string[][]
12+
*/
13+
public function dataTopics(): array
14+
{
15+
return [
16+
['managerRegistryDynamicReturn'],
17+
];
18+
}
19+
20+
public function getDataPath(): string
21+
{
22+
return __DIR__ . '/data';
23+
}
24+
25+
public function getPhpStanExecutablePath(): string
26+
{
27+
return __DIR__ . '/../../../vendor/bin/phpstan';
28+
}
29+
30+
public function getPhpStanConfigPath(): ?string
31+
{
32+
return __DIR__ . '/phpstan.neon';
33+
}
34+
35+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\DoctrineIntegration\Persistence\ManagerRegistryDynamicReturn;
4+
5+
use Doctrine\Common\Persistence\ManagerRegistry;
6+
use Doctrine\ORM\EntityManagerInterface;
7+
use Doctrine\ORM\Mapping as ORM;
8+
use RuntimeException;
9+
10+
class Example
11+
{
12+
/**
13+
* @var ManagerRegistry
14+
*/
15+
private $managerRegistry;
16+
17+
public function __construct(ManagerRegistry $managerRegistry)
18+
{
19+
$this->managerRegistry = $managerRegistry;
20+
}
21+
22+
public function findDynamicType(): void
23+
{
24+
$test = $this->managerRegistry->getRepository(MyEntity::class)->createQueryBuilder('e');
25+
26+
$test->getQuery();
27+
}
28+
}
29+
30+
/**
31+
* @ORM\Entity()
32+
*/
33+
class MyEntity
34+
{
35+
/**
36+
* @ORM\Id()
37+
* @ORM\GeneratedValue()
38+
* @ORM\Column(type="integer")
39+
*
40+
* @var int
41+
*/
42+
private $id;
43+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
includes:
2+
- ../../../extension.neon

0 commit comments

Comments
 (0)