1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Pinq\Queries\Builders; |
4
|
|
|
|
5
|
|
|
use Pinq\Expressions as O; |
6
|
|
|
use Pinq\PinqException; |
7
|
|
|
use Pinq\Queries; |
8
|
|
|
use Pinq\Queries\Builders\Interpretations\IRequestInterpretation; |
9
|
|
|
|
10
|
|
|
class RequestQueryInterpreter extends QueryInterpreter implements IRequestQueryInterpreter |
11
|
|
|
{ |
12
|
|
|
/** |
13
|
|
|
* @var IRequestInterpretation |
14
|
|
|
*/ |
15
|
|
|
protected $interpretation; |
16
|
|
|
|
17
|
|
|
public function __construct( |
18
|
|
|
IRequestInterpretation $interpretation, |
19
|
|
|
IScopeInterpreter $scopeInterpreter, |
20
|
|
|
O\IEvaluationContext $evaluationContext = null |
21
|
|
|
) { |
22
|
|
|
parent::__construct('request', $scopeInterpreter, $evaluationContext); |
23
|
|
|
|
24
|
|
|
$this->interpretation = $interpretation; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
public function getInterpretation() |
28
|
|
|
{ |
29
|
|
|
return $this->interpretation; |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
public function interpret(O\Expression $expression) |
33
|
|
|
{ |
34
|
|
|
if (($expression instanceof O\MethodCallExpression) |
35
|
|
|
&& method_exists($this, $methodName = 'visit' . $this->getMethodName($expression)) |
36
|
|
|
) { |
37
|
|
|
$this->{$methodName}($expression); |
38
|
|
|
} elseif ($expression instanceof O\IndexExpression) { |
39
|
|
|
$this->{'visitOffsetGet'}($expression); |
40
|
|
|
} elseif ($expression instanceof O\IssetExpression) { |
41
|
|
|
$this->{'visitOffsetExists'}($expression); |
42
|
|
|
} elseif ($expression instanceof O\FunctionCallExpression |
43
|
|
|
&& $expression->getName() instanceof O\ValueExpression |
44
|
|
|
&& strtolower($expression->getName()->getValue()) === 'count' |
45
|
|
|
) { |
46
|
|
|
$this->{'visitCount'}($expression); |
47
|
|
|
} else { |
48
|
|
|
$this->scopeInterpreter->interpretScope($expression); |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
final protected function visitGetIterator(O\MethodCallExpression $expression) |
53
|
|
|
{ |
54
|
|
|
$this->interpretation->interpretGetIterator($this->getId('get-iterator')); |
55
|
|
|
$this->interpretSourceAsScope($expression); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
final protected function visitGetTrueIterator(O\MethodCallExpression $expression) |
59
|
|
|
{ |
60
|
|
|
$this->interpretation->interpretGetTrueIterator($this->getId('get-true-iterator')); |
61
|
|
|
$this->interpretSourceAsScope($expression); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
final protected function visitAsArray(O\MethodCallExpression $expression) |
65
|
|
|
{ |
66
|
|
|
$this->interpretation->interpretAsArray($this->getId('as-array')); |
67
|
|
|
$this->interpretSourceAsScope($expression); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
final protected function visitAsCollection(O\MethodCallExpression $expression) |
71
|
|
|
{ |
72
|
|
|
$this->interpretation->interpretAsCollection($this->getId('as-collection')); |
73
|
|
|
$this->interpretSourceAsScope($expression); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
final protected function visitAsTraversable(O\MethodCallExpression $expression) |
77
|
|
|
{ |
78
|
|
|
$this->interpretation->interpretAsTraversable($this->getId('as-traversable')); |
79
|
|
|
$this->interpretSourceAsScope($expression); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
final protected function visitOffsetGet(O\Expression $expression) |
83
|
|
|
{ |
84
|
|
|
$requestId = $this->getId('offset-get'); |
85
|
|
|
$indexId = $this->getId('offset-get-index'); |
86
|
|
|
|
87
|
|
|
if ($expression instanceof O\MethodCallExpression) { |
88
|
|
|
$this->interpretation->interpretOffsetGet($requestId, $indexId, $this->getArgumentValueAt(0, $expression)); |
89
|
|
|
} elseif ($expression instanceof O\IndexExpression) { |
90
|
|
|
$this->interpretation->interpretOffsetGet( |
91
|
|
|
$requestId, |
92
|
|
|
$indexId, |
93
|
|
|
$this->getValue($expression->getIndex()) |
94
|
|
|
); |
95
|
|
|
} else { |
96
|
|
|
throw new PinqException( |
97
|
|
|
'Cannot interpret offset get request: invalid expression type, expecting %s, %s given', |
98
|
|
|
O\MethodCallExpression::getType() . ' or ' . O\IndexExpression::getType(), |
99
|
|
|
$expression->getType()); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$this->interpretSourceAsScope($expression); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
View Code Duplication |
final protected function visitOffsetExists(O\Expression $expression) |
|
|
|
|
106
|
|
|
{ |
107
|
|
|
$requestId = $this->getId('offset-exists'); |
108
|
|
|
$indexId = $this->getId('offset-exists-index'); |
109
|
|
|
|
110
|
|
|
if ($expression instanceof O\MethodCallExpression) { |
111
|
|
|
$this->interpretation->interpretOffsetExists($requestId, $indexId, $this->getArgumentValueAt(0, $expression)); |
112
|
|
|
$this->interpretSourceAsScope($expression); |
113
|
|
|
|
114
|
|
|
return; |
115
|
|
|
} elseif ($expression instanceof O\IssetExpression) { |
116
|
|
|
$issetArguments = $expression->getValues(); |
117
|
|
|
|
118
|
|
|
if (count($issetArguments) === 1 && $issetArguments[0] instanceof O\IndexExpression) { |
119
|
|
|
$this->interpretation->interpretOffsetExists( |
120
|
|
|
$requestId, |
121
|
|
|
$indexId, |
122
|
|
|
$this->getValue($issetArguments[0]->getIndex()) |
123
|
|
|
); |
124
|
|
|
$this->interpretSourceAsScope($issetArguments[0]); |
125
|
|
|
|
126
|
|
|
return; |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
throw new PinqException( |
131
|
|
|
'Cannot interpret offset exists request: invalid expression type, expecting %s, %s given', |
132
|
|
|
O\MethodCallExpression::getType() . ' or ' . O\IssetExpression::getType( |
133
|
|
|
) . ' with a single parameter index', |
134
|
|
|
$expression->getType()); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
final protected function visitContains(O\MethodCallExpression $expression) |
138
|
|
|
{ |
139
|
|
|
$requestId = $this->getId('contains'); |
140
|
|
|
$valueId = $this->getId('contains-value'); |
141
|
|
|
|
142
|
|
|
$this->interpretation->interpretContains($requestId, $valueId, $this->getArgumentValueAt(0, $expression)); |
143
|
|
|
$this->interpretSourceAsScope($expression); |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
final protected function visitFirst(O\MethodCallExpression $expression) |
147
|
|
|
{ |
148
|
|
|
$this->interpretation->interpretFirst($this->getId('first')); |
149
|
|
|
$this->interpretSourceAsScope($expression); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
final protected function visitLast(O\MethodCallExpression $expression) |
153
|
|
|
{ |
154
|
|
|
$this->interpretation->interpretLast($this->getId('last')); |
155
|
|
|
$this->interpretSourceAsScope($expression); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
final protected function visitCount(O\Expression $expression) |
159
|
|
|
{ |
160
|
|
|
$this->interpretation->interpretCount($this->getId('count')); |
161
|
|
|
|
162
|
|
|
if ($expression instanceof O\MethodCallExpression) { |
163
|
|
|
$this->interpretSourceAsScope($expression); |
164
|
|
|
} elseif ($expression instanceof O\FunctionCallExpression |
165
|
|
|
&& count($expression->getArguments()) > 0 |
166
|
|
|
) { |
167
|
|
|
$this->scopeInterpreter->interpretScope($expression->getArguments()[0]->getValue()); |
168
|
|
|
} else { |
169
|
|
|
throw new PinqException( |
170
|
|
|
'Cannot interpret count request: invalid expression type, expecting %s, %s given', |
171
|
|
|
O\MethodCallExpression::getType() . ' or ' . O\FunctionCallExpression::getType( |
172
|
|
|
) . ' with at least one argument', |
173
|
|
|
$expression->getType()); |
174
|
|
|
} |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
final protected function visitIsEmpty(O\MethodCallExpression $expression) |
178
|
|
|
{ |
179
|
|
|
$this->interpretation->interpretIsEmpty($this->getId('is-empty')); |
180
|
|
|
$this->interpretSourceAsScope($expression); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
final protected function visitAggregate(O\MethodCallExpression $expression) |
184
|
|
|
{ |
185
|
|
|
$this->interpretation->interpretAggregate( |
186
|
|
|
$this->getId('aggregate'), |
187
|
|
|
$this->getFunctionAt('aggregate-function', 0, $expression) |
188
|
|
|
); |
189
|
|
|
$this->interpretSourceAsScope($expression); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
final protected function visitMaximum(O\MethodCallExpression $expression) |
193
|
|
|
{ |
194
|
|
|
$this->interpretation->interpretMaximum( |
195
|
|
|
$this->getId('maximum'), |
196
|
|
|
$this->getOptionalFunctionAt('maximum-function', 0, $expression) |
197
|
|
|
); |
198
|
|
|
$this->interpretSourceAsScope($expression); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
final protected function visitMinimum(O\MethodCallExpression $expression) |
202
|
|
|
{ |
203
|
|
|
$this->interpretation->interpretMinimum( |
204
|
|
|
$this->getId('minimum'), |
205
|
|
|
$this->getOptionalFunctionAt('minimum-function', 0, $expression) |
206
|
|
|
); |
207
|
|
|
$this->interpretSourceAsScope($expression); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
final protected function visitSum(O\MethodCallExpression $expression) |
211
|
|
|
{ |
212
|
|
|
$this->interpretation->interpretSum( |
213
|
|
|
$this->getId('sum'), |
214
|
|
|
$this->getOptionalFunctionAt('sum-function', 0, $expression) |
215
|
|
|
); |
216
|
|
|
$this->interpretSourceAsScope($expression); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
final protected function visitAverage(O\MethodCallExpression $expression) |
220
|
|
|
{ |
221
|
|
|
$this->interpretation->interpretAverage( |
222
|
|
|
$this->getId('average'), |
223
|
|
|
$this->getOptionalFunctionAt('average-function', 0, $expression) |
224
|
|
|
); |
225
|
|
|
$this->interpretSourceAsScope($expression); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
final protected function visitAll(O\MethodCallExpression $expression) |
229
|
|
|
{ |
230
|
|
|
$this->interpretation->interpretAll( |
231
|
|
|
$this->getId('all'), |
232
|
|
|
$this->getOptionalFunctionAt('all-function', 0, $expression) |
233
|
|
|
); |
234
|
|
|
$this->interpretSourceAsScope($expression); |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
final protected function visitAny(O\MethodCallExpression $expression) |
238
|
|
|
{ |
239
|
|
|
$this->interpretation->interpretAny( |
240
|
|
|
$this->getId('any'), |
241
|
|
|
$this->getOptionalFunctionAt('any-function', 0, $expression) |
242
|
|
|
); |
243
|
|
|
$this->interpretSourceAsScope($expression); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
final protected function visitImplode(O\MethodCallExpression $expression) |
247
|
|
|
{ |
248
|
|
|
$this->interpretation->interpretImplode( |
249
|
|
|
$this->getId('implode'), |
250
|
|
|
$this->getId('implode-delimiter'), |
251
|
|
|
$this->getArgumentValueAt(0, $expression), |
252
|
|
|
$this->getOptionalFunctionAt('implode-function', 1, $expression) |
253
|
|
|
); |
254
|
|
|
$this->interpretSourceAsScope($expression); |
255
|
|
|
} |
256
|
|
|
} |
257
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.