Skip to content

Commit b0e0c32

Browse files
janedbalondrejmirtes
authored andcommitted
QueryBuilderDqlRule: check also other methods if enabled
1 parent fdca50f commit b0e0c32

File tree

4 files changed

+35
-11
lines changed

4 files changed

+35
-11
lines changed

rules.neon

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ services:
3535
class: PHPStan\Rules\Doctrine\ORM\QueryBuilderDqlRule
3636
arguments:
3737
reportDynamicQueryBuilders: %doctrine.reportDynamicQueryBuilders%
38+
searchOtherMethodsForQueryBuilderBeginning: %doctrine.searchOtherMethodsForQueryBuilderBeginning%
3839
tags:
3940
- phpstan.rules.rule
4041
-

src/Rules/Doctrine/ORM/QueryBuilderDqlRule.php

+20-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPStan\Rules\RuleErrorBuilder;
1313
use PHPStan\Type\Doctrine\DoctrineTypeUtils;
1414
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
15+
use PHPStan\Type\Doctrine\QueryBuilder\OtherMethodQueryBuilderParser;
1516
use PHPStan\Type\ObjectType;
1617
use PHPStan\Type\TypeUtils;
1718
use Throwable;
@@ -31,13 +32,23 @@ class QueryBuilderDqlRule implements Rule
3132
/** @var bool */
3233
private $reportDynamicQueryBuilders;
3334

35+
/** @var OtherMethodQueryBuilderParser */
36+
private $otherMethodQueryBuilderParser;
37+
38+
/** @var bool */
39+
private $searchOtherMethodsForQueryBuilderBeginning;
40+
3441
public function __construct(
3542
ObjectMetadataResolver $objectMetadataResolver,
36-
bool $reportDynamicQueryBuilders
43+
OtherMethodQueryBuilderParser $otherMethodQueryBuilderParser,
44+
bool $reportDynamicQueryBuilders,
45+
bool $searchOtherMethodsForQueryBuilderBeginning
3746
)
3847
{
3948
$this->objectMetadataResolver = $objectMetadataResolver;
49+
$this->otherMethodQueryBuilderParser = $otherMethodQueryBuilderParser;
4050
$this->reportDynamicQueryBuilders = $reportDynamicQueryBuilders;
51+
$this->searchOtherMethodsForQueryBuilderBeginning = $searchOtherMethodsForQueryBuilderBeginning;
4152
}
4253

4354
public function getNodeType(): string
@@ -58,6 +69,14 @@ public function processNode(Node $node, Scope $scope): array
5869
$calledOnType = $scope->getType($node->var);
5970
$queryBuilderTypes = DoctrineTypeUtils::getQueryBuilderTypes($calledOnType);
6071
if (count($queryBuilderTypes) === 0) {
72+
73+
if ($this->searchOtherMethodsForQueryBuilderBeginning) {
74+
$queryBuilderTypes = $this->otherMethodQueryBuilderParser->getQueryBuilderTypes($scope, $node);
75+
if (count($queryBuilderTypes) !== 0) {
76+
return [];
77+
}
78+
}
79+
6180
if (
6281
$this->reportDynamicQueryBuilders
6382
&& (new ObjectType('Doctrine\ORM\QueryBuilder'))->isSuperTypeOf($calledOnType)->yes()

tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleSlowTest.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Rules\Rule;
66
use PHPStan\Testing\RuleTestCase;
77
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
8+
use PHPStan\Type\Doctrine\QueryBuilder\OtherMethodQueryBuilderParser;
89

910
/**
1011
* @extends RuleTestCase<QueryBuilderDqlRule>
@@ -14,7 +15,12 @@ class QueryBuilderDqlRuleSlowTest extends RuleTestCase
1415

1516
protected function getRule(): Rule
1617
{
17-
return new QueryBuilderDqlRule(new ObjectMetadataResolver(__DIR__ . '/entity-manager.php'), true);
18+
return new QueryBuilderDqlRule(
19+
new ObjectMetadataResolver(__DIR__ . '/entity-manager.php'),
20+
self::getContainer()->getByType(OtherMethodQueryBuilderParser::class),
21+
true,
22+
true
23+
);
1824
}
1925

2026
public function testRule(): void
@@ -40,10 +46,6 @@ public function testRule(): void
4046
'QueryBuilder: [Semantical Error] line 0, col 14 near \'Foo e\': Error: Class \'Foo\' is not defined.',
4147
71,
4248
],
43-
[
44-
'Could not analyse QueryBuilder with unknown beginning.',
45-
89,
46-
],
4749
[
4850
'Could not analyse QueryBuilder with dynamic arguments.',
4951
99,

tests/Rules/Doctrine/ORM/QueryBuilderDqlRuleTest.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Rules\Rule;
66
use PHPStan\Testing\RuleTestCase;
77
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
8+
use PHPStan\Type\Doctrine\QueryBuilder\OtherMethodQueryBuilderParser;
89

910
/**
1011
* @extends RuleTestCase<QueryBuilderDqlRule>
@@ -14,7 +15,12 @@ class QueryBuilderDqlRuleTest extends RuleTestCase
1415

1516
protected function getRule(): Rule
1617
{
17-
return new QueryBuilderDqlRule(new ObjectMetadataResolver(__DIR__ . '/entity-manager.php'), true);
18+
return new QueryBuilderDqlRule(
19+
new ObjectMetadataResolver(__DIR__ . '/entity-manager.php'),
20+
self::getContainer()->getByType(OtherMethodQueryBuilderParser::class),
21+
true,
22+
true
23+
);
1824
}
1925

2026
public function testRule(): void
@@ -40,10 +46,6 @@ public function testRule(): void
4046
'QueryBuilder: [Semantical Error] line 0, col 14 near \'Foo e\': Error: Class \'Foo\' is not defined.',
4147
71,
4248
],
43-
[
44-
'Could not analyse QueryBuilder with unknown beginning.',
45-
89,
46-
],
4749
[
4850
'Could not analyse QueryBuilder with dynamic arguments.',
4951
99,

0 commit comments

Comments
 (0)