Skip to content

Commit 2ce6752

Browse files
roverwolfondrejmirtes
authored andcommitted
do not error if a non-field findByX method exists
Do not generate an error if a custom findByX method exists but X is not a field in the entity class.
1 parent 977df27 commit 2ce6752

File tree

5 files changed

+78
-6
lines changed

5 files changed

+78
-6
lines changed

src/Rules/Doctrine/ORM/MagicRepositoryMethodCallRule.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
7+
use PHPStan\Broker\Broker;
78
use PHPStan\Rules\Rule;
89
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
910
use PHPStan\Type\Doctrine\ObjectRepositoryType;
@@ -15,9 +16,13 @@ class MagicRepositoryMethodCallRule implements Rule
1516
/** @var ObjectMetadataResolver */
1617
private $objectMetadataResolver;
1718

18-
public function __construct(ObjectMetadataResolver $objectMetadataResolver)
19+
/** @var Broker */
20+
private $broker;
21+
22+
public function __construct(ObjectMetadataResolver $objectMetadataResolver, Broker $broker)
1923
{
2024
$this->objectMetadataResolver = $objectMetadataResolver;
25+
$this->broker = $broker;
2126
}
2227

2328
public function getNodeType(): string
@@ -78,6 +83,11 @@ public function processNode(Node $node, Scope $scope): array
7883
return [];
7984
}
8085

86+
$repositoryReflectionClass = $this->broker->getClass($calledOnType->getClassName());
87+
if ($repositoryReflectionClass->hasNativeMethod($methodName)) {
88+
return [];
89+
}
90+
8191
return [sprintf(
8292
'Call to method %s::%s() - entity %s does not have a field named $%s.',
8393
$calledOnType->describe(VerbosityLevel::typeOnly()),

tests/Rules/Doctrine/ORM/MagicRepositoryMethodCallRuleTest.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ class MagicRepositoryMethodCallRuleTest extends RuleTestCase
1212

1313
protected function getRule(): Rule
1414
{
15-
return new MagicRepositoryMethodCallRule(new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null));
15+
$broker = $this->createBroker();
16+
17+
return new MagicRepositoryMethodCallRule(new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null), $broker);
1618
}
1719

1820
public function testRule(): void
@@ -26,21 +28,33 @@ public function testRule(): void
2628
'Call to method Doctrine\ORM\EntityRepository<PHPStan\Rules\Doctrine\ORM\MyEntity>::findByNonexistent() - entity PHPStan\Rules\Doctrine\ORM\MyEntity does not have a field named $nonexistent.',
2729
25,
2830
],
31+
[
32+
'Call to method Doctrine\ORM\EntityRepository<PHPStan\Rules\Doctrine\ORM\MyEntity>::findByCustomMethod() - entity PHPStan\Rules\Doctrine\ORM\MyEntity does not have a field named $customMethod.',
33+
26,
34+
],
2935
[
3036
'Call to method Doctrine\ORM\EntityRepository<PHPStan\Rules\Doctrine\ORM\MyEntity>::findOneByTransient() - entity PHPStan\Rules\Doctrine\ORM\MyEntity does not have a field named $transient.',
31-
34,
37+
35,
3238
],
3339
[
3440
'Call to method Doctrine\ORM\EntityRepository<PHPStan\Rules\Doctrine\ORM\MyEntity>::findOneByNonexistent() - entity PHPStan\Rules\Doctrine\ORM\MyEntity does not have a field named $nonexistent.',
35-
35,
41+
36,
3642
],
3743
[
3844
'Call to method Doctrine\ORM\EntityRepository<PHPStan\Rules\Doctrine\ORM\MyEntity>::countByTransient() - entity PHPStan\Rules\Doctrine\ORM\MyEntity does not have a field named $transient.',
39-
44,
45+
45,
4046
],
4147
[
4248
'Call to method Doctrine\ORM\EntityRepository<PHPStan\Rules\Doctrine\ORM\MyEntity>::countByNonexistent() - entity PHPStan\Rules\Doctrine\ORM\MyEntity does not have a field named $nonexistent.',
43-
45,
49+
46,
50+
],
51+
[
52+
'Call to method PHPStan\Rules\Doctrine\ORM\TestRepository<PHPStan\Rules\Doctrine\ORM\MySecondEntity>::findByTransient() - entity PHPStan\Rules\Doctrine\ORM\MySecondEntity does not have a field named $transient.',
53+
55,
54+
],
55+
[
56+
'Call to method PHPStan\Rules\Doctrine\ORM\TestRepository<PHPStan\Rules\Doctrine\ORM\MySecondEntity>::findByNonexistent() - entity PHPStan\Rules\Doctrine\ORM\MySecondEntity does not have a field named $nonexistent.',
57+
56,
4458
],
4559
]);
4660
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Doctrine\ORM;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
/**
8+
* @ORM\Entity(repositoryClass="PHPStan\Rules\Doctrine\ORM\TestRepository")
9+
*/
10+
class MySecondEntity
11+
{
12+
/**
13+
* @ORM\Id()
14+
* @ORM\GeneratedValue()
15+
* @ORM\Column(type="integer")
16+
*
17+
* @var int
18+
*/
19+
private $id;
20+
21+
/**
22+
* @var string
23+
* @ORM\Column(type="string")
24+
*/
25+
private $title;
26+
27+
/**
28+
* @var string
29+
*/
30+
private $transient;
31+
32+
}

tests/Rules/Doctrine/ORM/data/dql.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,9 @@ public function nowdoc(): void
6262
)->getResult();
6363
}
6464

65+
public function findByCustomMethod(): array
66+
{
67+
return [];
68+
}
69+
6570
}

tests/Rules/Doctrine/ORM/data/magic-repository.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public function doFindBy(): void
2323
$entityRepository->findByTitle('test');
2424
$entityRepository->findByTransient('test');
2525
$entityRepository->findByNonexistent('test');
26+
$entityRepository->findByCustomMethod();
2627
}
2728

2829
public function doFindOneBy(): void
@@ -45,4 +46,14 @@ public function doCountBy(): void
4546
$entityRepository->countByNonexistent('test');
4647
}
4748

49+
public function doFindByWithRepository(): void
50+
{
51+
$entityRepository = $this->entityManager->getRepository(MySecondEntity::class);
52+
$entityRepository->findBy(['id' => 1]);
53+
$entityRepository->findById(1);
54+
$entityRepository->findByTitle('test');
55+
$entityRepository->findByTransient('test');
56+
$entityRepository->findByNonexistent('test');
57+
$entityRepository->findByCustomMethod();
58+
}
4859
}

0 commit comments

Comments
 (0)