1 | <?php |
||
35 | class QueryExpressionVisitor extends ExpressionVisitor |
||
36 | { |
||
37 | /** |
||
38 | * @var array |
||
39 | */ |
||
40 | private static $operatorMap = array( |
||
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 = array(); |
||
61 | |||
62 | /** |
||
63 | * Constructor |
||
64 | * |
||
65 | * @param array $queryAliases |
||
66 | */ |
||
67 | 32 | public function __construct($queryAliases) |
|
68 | { |
||
69 | 32 | $this->queryAliases = $queryAliases; |
|
70 | 32 | $this->expr = new Expr(); |
|
71 | 32 | } |
|
72 | |||
73 | /** |
||
74 | * Gets bound parameters. |
||
75 | * Filled after {@link dispach()}. |
||
76 | * |
||
77 | * @return \Doctrine\Common\Collections\Collection |
||
78 | */ |
||
79 | 22 | 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) |
|
110 | { |
||
111 | 10 | $expressionList = array(); |
|
112 | |||
113 | 10 | foreach ($expr->getExpressionList() as $child) { |
|
114 | 10 | $expressionList[] = $this->dispatch($child); |
|
115 | } |
||
116 | |||
117 | 10 | switch($expr->getType()) { |
|
118 | 10 | case CompositeExpression::TYPE_AND: |
|
119 | 9 | return new Expr\Andx($expressionList); |
|
120 | |||
121 | 1 | case CompositeExpression::TYPE_OR: |
|
122 | 1 | return new Expr\Orx($expressionList); |
|
123 | |||
124 | default: |
||
125 | throw new \RuntimeException("Unknown composite " . $expr->getType()); |
||
126 | } |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * {@inheritDoc} |
||
131 | */ |
||
132 | 26 | public function walkComparison(Comparison $comparison) |
|
133 | { |
||
134 | |||
135 | 26 | if ( ! isset($this->queryAliases[0])) { |
|
136 | throw new QueryException('No aliases are set before invoking walkComparison().'); |
||
137 | } |
||
138 | |||
139 | 26 | $field = $this->queryAliases[0] . '.' . $comparison->getField(); |
|
140 | |||
141 | 26 | foreach($this->queryAliases as $alias) { |
|
142 | 26 | if(strpos($comparison->getField() . '.', $alias . '.') === 0) { |
|
143 | 5 | $field = $comparison->getField(); |
|
144 | 26 | break; |
|
145 | } |
||
146 | } |
||
147 | |||
148 | 26 | $parameterName = str_replace('.', '_', $comparison->getField()); |
|
149 | |||
150 | 26 | foreach ($this->parameters as $parameter) { |
|
151 | 10 | if ($parameter->getName() === $parameterName) { |
|
152 | 4 | $parameterName .= '_' . count($this->parameters); |
|
153 | 10 | break; |
|
154 | } |
||
155 | } |
||
156 | |||
157 | 26 | $parameter = new Parameter($parameterName, $this->walkValue($comparison->getValue())); |
|
158 | 26 | $placeholder = ':' . $parameterName; |
|
159 | |||
160 | 26 | switch ($comparison->getOperator()) { |
|
161 | 26 | case Comparison::IN: |
|
162 | 1 | $this->parameters[] = $parameter; |
|
163 | |||
164 | 1 | return $this->expr->in($field, $placeholder); |
|
165 | 25 | case Comparison::NIN: |
|
166 | 1 | $this->parameters[] = $parameter; |
|
167 | |||
168 | 1 | return $this->expr->notIn($field, $placeholder); |
|
169 | 24 | case Comparison::EQ: |
|
170 | 14 | 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 | 14 | 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 | 12 | 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 | default: |
||
190 | 11 | $operator = self::convertComparisonOperator($comparison->getOperator()); |
|
191 | 11 | if ($operator) { |
|
|
|||
192 | 11 | $this->parameters[] = $parameter; |
|
193 | |||
194 | 11 | return new Expr\Comparison( |
|
195 | $field, |
||
196 | $operator, |
||
197 | $placeholder |
||
198 | ); |
||
199 | } |
||
200 | |||
201 | throw new \RuntimeException("Unknown comparison operator: " . $comparison->getOperator()); |
||
202 | } |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * {@inheritDoc} |
||
207 | */ |
||
208 | 27 | public function walkValue(Value $value) |
|
212 | } |
||
213 |
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: