1 | <?php |
||
35 | class QueryExpressionVisitor extends ExpressionVisitor |
||
36 | { |
||
37 | /** |
||
38 | * @var array |
||
39 | */ |
||
40 | private static $operatorMap = [ |
||
41 | Comparison::GT => Expr\Comparison::GT, |
||
42 | Comparison::GTE => Expr\Comparison::GTE, |
||
43 | Comparison::LT => Expr\Comparison::LT, |
||
44 | Comparison::LTE => Expr\Comparison::LTE |
||
45 | ]; |
||
46 | |||
47 | /** |
||
48 | * @var array |
||
49 | */ |
||
50 | private $queryAliases; |
||
51 | |||
52 | /** |
||
53 | * @var Expr |
||
54 | */ |
||
55 | private $expr; |
||
56 | |||
57 | /** |
||
58 | * @var array |
||
59 | */ |
||
60 | private $parameters = []; |
||
61 | |||
62 | /** |
||
63 | * Constructor |
||
64 | * |
||
65 | * @param array $queryAliases |
||
66 | */ |
||
67 | 34 | public function __construct($queryAliases) |
|
72 | |||
73 | /** |
||
74 | * Gets bound parameters. |
||
75 | * Filled after {@link dispach()}. |
||
76 | * |
||
77 | * @return \Doctrine\Common\Collections\Collection |
||
78 | */ |
||
79 | 24 | public function getParameters() |
|
83 | |||
84 | /** |
||
85 | * Clears parameters. |
||
86 | * |
||
87 | * @return void |
||
88 | */ |
||
89 | 1 | public function clearParameters() |
|
93 | |||
94 | /** |
||
95 | * Converts Criteria expression to Query one based on static map. |
||
96 | * |
||
97 | * @param string $criteriaOperator |
||
98 | * |
||
99 | * @return string|null |
||
100 | */ |
||
101 | 11 | private static function convertComparisonOperator($criteriaOperator) |
|
105 | |||
106 | /** |
||
107 | * {@inheritDoc} |
||
108 | */ |
||
109 | 10 | public function walkCompositeExpression(CompositeExpression $expr) |
|
128 | |||
129 | /** |
||
130 | * {@inheritDoc} |
||
131 | */ |
||
132 | 28 | public function walkComparison(Comparison $comparison) |
|
133 | { |
||
134 | |||
135 | 28 | if ( ! isset($this->queryAliases[0])) { |
|
136 | throw new QueryException('No aliases are set before invoking walkComparison().'); |
||
137 | } |
||
138 | |||
139 | 28 | $field = $this->queryAliases[0] . '.' . $comparison->getField(); |
|
140 | |||
141 | 28 | foreach($this->queryAliases as $alias) { |
|
142 | 28 | if(strpos($comparison->getField() . '.', $alias . '.') === 0) { |
|
143 | 5 | $field = $comparison->getField(); |
|
144 | 28 | break; |
|
145 | } |
||
146 | } |
||
147 | |||
148 | 28 | $parameterName = str_replace('.', '_', $comparison->getField()); |
|
149 | |||
150 | 28 | foreach ($this->parameters as $parameter) { |
|
151 | 10 | if ($parameter->getName() === $parameterName) { |
|
152 | 4 | $parameterName .= '_' . count($this->parameters); |
|
153 | 10 | break; |
|
154 | } |
||
155 | } |
||
156 | |||
157 | 28 | $parameter = new Parameter($parameterName, $this->walkValue($comparison->getValue())); |
|
158 | 28 | $placeholder = ':' . $parameterName; |
|
159 | |||
160 | 28 | switch ($comparison->getOperator()) { |
|
161 | 28 | case Comparison::IN: |
|
162 | 1 | $this->parameters[] = $parameter; |
|
163 | |||
164 | 1 | return $this->expr->in($field, $placeholder); |
|
165 | 27 | case Comparison::NIN: |
|
166 | 1 | $this->parameters[] = $parameter; |
|
167 | |||
168 | 1 | return $this->expr->notIn($field, $placeholder); |
|
169 | 26 | case Comparison::EQ: |
|
170 | 16 | case Comparison::IS: |
|
171 | 17 | if ($this->walkValue($comparison->getValue()) === null) { |
|
172 | 2 | return $this->expr->isNull($field); |
|
173 | } |
||
174 | 15 | $this->parameters[] = $parameter; |
|
175 | |||
176 | 15 | return $this->expr->eq($field, $placeholder); |
|
177 | 16 | case Comparison::NEQ: |
|
178 | 2 | if ($this->walkValue($comparison->getValue()) === null) { |
|
179 | 1 | return $this->expr->isNotNull($field); |
|
180 | } |
||
181 | 1 | $this->parameters[] = $parameter; |
|
182 | |||
183 | 1 | return $this->expr->neq($field, $placeholder); |
|
184 | 14 | case Comparison::CONTAINS: |
|
185 | 1 | $parameter->setValue('%' . $parameter->getValue() . '%', $parameter->getType()); |
|
186 | 1 | $this->parameters[] = $parameter; |
|
187 | |||
188 | 1 | return $this->expr->like($field, $placeholder); |
|
189 | 13 | case Comparison::STARTS_WITH: |
|
190 | 1 | $parameter->setValue($parameter->getValue() . '%', $parameter->getType()); |
|
191 | 1 | $this->parameters[] = $parameter; |
|
192 | |||
193 | 1 | return $this->expr->like($field, $placeholder); |
|
194 | 12 | case Comparison::ENDS_WITH: |
|
195 | 1 | $parameter->setValue('%' . $parameter->getValue(), $parameter->getType()); |
|
196 | 1 | $this->parameters[] = $parameter; |
|
197 | |||
198 | 1 | return $this->expr->like($field, $placeholder); |
|
199 | default: |
||
200 | 11 | $operator = self::convertComparisonOperator($comparison->getOperator()); |
|
201 | 11 | if ($operator) { |
|
|
|||
202 | 11 | $this->parameters[] = $parameter; |
|
203 | |||
204 | 11 | return new Expr\Comparison( |
|
205 | $field, |
||
206 | $operator, |
||
207 | $placeholder |
||
208 | ); |
||
209 | } |
||
210 | |||
211 | throw new \RuntimeException("Unknown comparison operator: " . $comparison->getOperator()); |
||
212 | } |
||
213 | } |
||
214 | |||
215 | /** |
||
216 | * {@inheritDoc} |
||
217 | */ |
||
218 | 29 | public function walkValue(Value $value) |
|
222 | } |
||
223 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: