Skip to content

Commit bb8e028

Browse files
authored
feat: fixes errors on complex where statements and tests required (#349)
1 parent eabf392 commit bb8e028

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed

src/Knp/Component/Pager/Event/Subscriber/Filtration/Doctrine/ORM/Query/WhereWalker.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,11 @@ private function primaryContainsFilter(ConditionalPrimary $node, array $filterEx
221221
return $this->isExpressionInFilterExpressions($node->simpleConditionalExpression, $filterExpressions);
222222
}
223223
if ($node->isConditionalExpression()) {
224-
return $this->expressionContainsFilter($node->conditionalExpression, $filterExpressions);
224+
if ($node->conditionalExpression instanceof ConditionalExpression) {
225+
return $this->expressionContainsFilter($node->conditionalExpression, $filterExpressions);
226+
} elseif ($node->conditionalExpression instanceof ConditionalTerm) {
227+
return $this->termContainsFilter($node->conditionalExpression, $filterExpressions);
228+
}
225229
}
226230

227231
return false;
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
namespace Knp\Component\Pager\Event\Subscriber\Filtration\Doctrine\ORM\Query;
4+
5+
use Doctrine\ORM\Query;
6+
use Doctrine\ORM\Query\AST\ComparisonExpression;
7+
use Doctrine\ORM\Query\AST\ConditionalExpression;
8+
use Doctrine\ORM\Query\AST\ConditionalFactor;
9+
use Doctrine\ORM\Query\AST\ConditionalPrimary;
10+
use Doctrine\ORM\Query\AST\ConditionalTerm;
11+
use Doctrine\ORM\Query\AST\FromClause;
12+
use Doctrine\ORM\Query\AST\IdentificationVariableDeclaration;
13+
use Doctrine\ORM\Query\AST\InputParameter;
14+
use Doctrine\ORM\Query\AST\Literal;
15+
use Doctrine\ORM\Query\AST\PathExpression;
16+
use Doctrine\ORM\Query\AST\RangeVariableDeclaration;
17+
use Doctrine\ORM\Query\AST\SelectClause;
18+
use Doctrine\ORM\Query\AST\SelectStatement;
19+
use Doctrine\ORM\Query\AST\WhereClause;
20+
use Doctrine\ORM\Query\ParserResult;
21+
use PHPUnit\Framework\TestCase;
22+
23+
class WhereWalkerTest extends TestCase
24+
{
25+
private Query $query;
26+
private ParserResult $parserResult;
27+
private array $queryComponents;
28+
29+
protected function setUp(): void
30+
{
31+
// Mock Doctrine Query and ParserResult
32+
$this->query = $this->createMock(Query::class);
33+
$this->parserResult = $this->createMock(ParserResult::class);
34+
35+
// Set up query hints
36+
$this->query->method('getHint')
37+
->willReturnMap([
38+
[WhereWalker::HINT_PAGINATOR_FILTER_VALUE, 'test'],
39+
[WhereWalker::HINT_PAGINATOR_FILTER_COLUMNS, ['tdf.name']],
40+
[WhereWalker::HINT_PAGINATOR_FILTER_CASE_INSENSITIVE, false],
41+
]);
42+
43+
// Mock query components
44+
$this->queryComponents = [
45+
'tdf' => [
46+
'metadata' => $this->createMock(\Doctrine\ORM\Mapping\ClassMetadata::class),
47+
],
48+
];
49+
$this->queryComponents['tdf']['metadata']->method('hasField')->willReturn(true);
50+
$this->queryComponents['tdf']['metadata']->method('getTypeOfField')->willReturn('string');
51+
}
52+
53+
public function testWalkSelectStatementWithComplexConditionalTerm(): void
54+
{
55+
// Create a complex WHERE clause AST
56+
$conditionalPrimary = new ConditionalPrimary();
57+
$conditionalPrimary->simpleConditionalExpression = new ComparisonExpression(
58+
new PathExpression(PathExpression::TYPE_STATE_FIELD, 'tdf.objects', 'tdf.objects'),
59+
'MEMBER OF',
60+
new InputParameter(':object')
61+
);
62+
63+
$conditionalFactor = new ConditionalFactor($conditionalPrimary);
64+
$conditionalTerm = new ConditionalTerm([$conditionalFactor]);
65+
66+
$conditionalPrimary2 = new ConditionalPrimary();
67+
$conditionalPrimary2->simpleConditionalExpression = new ComparisonExpression(
68+
new PathExpression(PathExpression::TYPE_STATE_FIELD, 'oacc_obj_res.read', 'oacc_obj_res.read'),
69+
'=',
70+
new Literal(Literal::NUMERIC, '1')
71+
);
72+
73+
$conditionalFactor2 = new ConditionalFactor($conditionalPrimary2);
74+
$conditionalTerm2 = new ConditionalTerm([$conditionalFactor2]);
75+
76+
$conditionalExpression = new ConditionalExpression([$conditionalTerm, $conditionalTerm2]);
77+
78+
// Create SelectStatement with WhereClause
79+
$selectClause = new SelectClause([], false);
80+
$fromClause = new FromClause([
81+
new IdentificationVariableDeclaration(
82+
new RangeVariableDeclaration('Entity', 'tdf'),
83+
null,
84+
[]
85+
),
86+
]);
87+
$whereClause = new WhereClause($conditionalExpression);
88+
$selectStatement = new SelectStatement($selectClause, $fromClause);
89+
$selectStatement->whereClause = $whereClause;
90+
91+
// Create WhereWalker instance
92+
$whereWalker = new WhereWalker($this->query, $this->parserResult, $this->queryComponents);
93+
94+
// Invoke walkSelectStatement
95+
$whereWalker->walkSelectStatement($selectStatement);
96+
97+
// Assert that the whereClause is still present and contains a ConditionalExpression
98+
$this->assertInstanceOf(WhereClause::class, $selectStatement->whereClause);
99+
$this->assertInstanceOf(ConditionalTerm::class, $selectStatement->whereClause->conditionalExpression); // The expression contains the ConditionalTerms
100+
$this->assertGreaterThanOrEqual(2, count($selectStatement->whereClause->conditionalExpression->conditionalFactors)); // ConditionalTerm->conditionalFactors
101+
}
102+
103+
public function testWalkSelectStatementWithConditionalFactor(): void
104+
{
105+
// Create a simple WHERE clause with a filter parameter
106+
$conditionalPrimary = new ConditionalPrimary();
107+
$conditionalPrimary->simpleConditionalExpression = new ComparisonExpression(
108+
new PathExpression(PathExpression::TYPE_STATE_FIELD, 'tdf.name', 'tdf.name'),
109+
'=',
110+
new InputParameter(':knp_filter')
111+
);
112+
113+
$conditionalFactor = new ConditionalFactor($conditionalPrimary);
114+
$conditionalTerm = new ConditionalTerm([$conditionalFactor]);
115+
$conditionalExpression = new ConditionalExpression([$conditionalTerm]);
116+
117+
// Create SelectStatement with WhereClause
118+
$selectClause = new SelectClause([], false);
119+
$fromClause = new FromClause([
120+
new IdentificationVariableDeclaration(
121+
new RangeVariableDeclaration('Entity', 'tdf'),
122+
null,
123+
[]
124+
),
125+
]);
126+
$whereClause = new WhereClause($conditionalExpression);
127+
$selectStatement = new SelectStatement($selectClause, $fromClause);
128+
$selectStatement->whereClause = $whereClause;
129+
130+
// Create WhereWalker instance
131+
$whereWalker = new WhereWalker($this->query, $this->parserResult, $this->queryComponents);
132+
133+
// Invoke walkSelectStatement
134+
$whereWalker->walkSelectStatement($selectStatement);
135+
136+
// Assert that the whereClause is still present and contains a ConditionalExpression with an additional factor
137+
$this->assertInstanceOf(WhereClause::class, $selectStatement->whereClause);
138+
$this->assertInstanceOf(ConditionalTerm::class, $selectStatement->whereClause->conditionalExpression); // The expression contains the ConditionalTerms
139+
$this->assertGreaterThanOrEqual(2, count($selectStatement->whereClause->conditionalExpression->conditionalFactors));
140+
}
141+
}

0 commit comments

Comments
 (0)