Skip to content

Commit 91bd1b1

Browse files
Khartirondrejmirtes
authored andcommitted
add stub for EntityManager::getClassMetadata
1 parent f7e4239 commit 91bd1b1

File tree

4 files changed

+71
-5
lines changed

4 files changed

+71
-5
lines changed

src/Type/Doctrine/Query/QueryResultTypeWalker.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,10 @@ public function walkPathExpression($pathExpr)
244244

245245
case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION:
246246
if (isset($class->associationMappings[$fieldName]['inherited'])) {
247-
assert(is_string($class->associationMappings[$fieldName]['inherited']));
248-
$class = $this->em->getClassMetadata($class->associationMappings[$fieldName]['inherited']);
247+
$newClassName = $class->associationMappings[$fieldName]['inherited'];
248+
assert(is_string($newClassName));
249+
/** @var class-string $newClassName */
250+
$class = $this->em->getClassMetadata($newClassName);
249251
}
250252

251253
$assoc = $class->associationMappings[$fieldName];
@@ -258,9 +260,11 @@ public function walkPathExpression($pathExpr)
258260

259261
$joinColumn = $assoc['joinColumns'][0];
260262
assert(is_array($joinColumn));
261-
assert(is_string($assoc['targetEntity']));
263+
$assocClassName = $assoc['targetEntity'];
264+
assert(is_string($assocClassName));
265+
/** @var class-string $assocClassName */
262266

263-
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
267+
$targetClass = $this->em->getClassMetadata($assocClassName);
264268
$identifierFieldNames = $targetClass->getIdentifierFieldNames();
265269

266270
if (count($identifierFieldNames) !== 1) {
@@ -510,7 +514,9 @@ public function walkFunction($function)
510514
$queryComp = $this->queryComponents[$dqlAlias];
511515
$class = $queryComp['metadata'];
512516
$assoc = $class->associationMappings[$assocField];
513-
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
517+
/** @var class-string $assocClassName */
518+
$assocClassName = $assoc['targetEntity'];
519+
$targetClass = $this->em->getClassMetadata($assocClassName);
514520

515521
if ($function->fieldMapping === null) {
516522
$identifierFieldNames = $targetClass->getIdentifierFieldNames();

stubs/EntityManagerInterface.stub

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ namespace Doctrine\ORM;
44

55
use Doctrine\Persistence\ObjectManager;
66
use Doctrine\Persistence\ObjectRepository;
7+
use Doctrine\ORM\Mapping\ClassMetadata;
78

89
interface EntityManagerInterface extends ObjectManager
910
{
@@ -56,4 +57,11 @@ interface EntityManagerInterface extends ObjectManager
5657
*/
5758
public function copy($entity, $deep = false);
5859

60+
/**
61+
* @template T of object
62+
* @phpstan-param class-string<T> $className
63+
*
64+
* @phpstan-return ClassMetadata<T>
65+
*/
66+
public function getClassMetadata($className);
5967
}

tests/DoctrineIntegration/ORM/EntityManagerIntegrationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public function dataTopics(): array
2222
['customRepositoryUsage'],
2323
['queryBuilder'],
2424
[$hasDbal3 ? 'dbalQueryBuilderExecuteDynamicReturnDbal3' : 'dbalQueryBuilderExecuteDynamicReturn'],
25+
['getClassMetadata'],
2526
];
2627
}
2728

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace PHPStan\DoctrineIntegration\ORM\GetClassMetadata;
4+
5+
use Doctrine\ORM\EntityManagerInterface;
6+
use Doctrine\ORM\EntityRepository;
7+
use Doctrine\ORM\Mapping\ClassMetadata;
8+
use Doctrine\ORM\Mapping as ORM;
9+
10+
/**
11+
* @ORM\Entity(repositoryClass=MyRepository::class)
12+
*/
13+
class MyEntity
14+
{
15+
/**
16+
* @ORM\Id()
17+
* @ORM\GeneratedValue()
18+
* @ORM\Column(type="integer")
19+
*
20+
* @var int
21+
*/
22+
private $id;
23+
}
24+
25+
/**
26+
* @template T of object
27+
* @template-extends EntityRepository<T>
28+
*/
29+
class IntermediateRepository extends EntityRepository
30+
{
31+
/**
32+
* @param ClassMetadata<T> $class
33+
*/
34+
public function __construct(EntityManagerInterface $em, ClassMetadata $class)
35+
{
36+
parent::__construct($em, $class);
37+
}
38+
}
39+
40+
/**
41+
* @extends IntermediateRepository<MyEntity>
42+
*/
43+
class MyRepository extends IntermediateRepository
44+
{
45+
46+
public function __construct(
47+
EntityManagerInterface $manager
48+
) {
49+
parent::__construct($manager, $manager->getClassMetadata(MyEntity::class));
50+
}
51+
}

0 commit comments

Comments
 (0)