PHPExpressionProvider::clear()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 0
c 0
b 0
f 0
dl 0
loc 1
ccs 0
cts 1
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace POData\Providers\Expression;
4
5
use POData\Providers\Expression\IExpressionProvider;
6
use POData\Providers\Metadata\ResourceType;
7
use POData\UriProcessor\QueryProcessor\ExpressionParser\Expressions\ExpressionType;
8
use POData\Providers\Metadata\Type\IType;
9
use POData\Common\ODataConstants;
10
use POData\UriProcessor\QueryProcessor\FunctionDescription;
11
use POData\UriProcessor\QueryProcessor\ExpressionParser\Expressions\PropertyAccessExpression;
12
13
/**
14
 * Class PHPExpressionProvider
15
 * @package POData\UriProcessor\QueryProcessor\ExpressionParser
16
 */
17
class PHPExpressionProvider implements IExpressionProvider
18
{
19
    const ADD                   = '+';
20
    const CLOSE_BRACKET         = ')';
21
    const COMMA                 = ',';
22
    const DIVIDE                = '/';
23
    const SUBTRACT              = '-';
24
    const EQUAL                 = '==';
25
    const GREATER_THAN          = '>';
26
    const GREATER_THAN_OR_EQUAL = '>=';
27
    const LESS_THAN             = '<';
28
    const LESS_THAN_OR_EQUAL    = '<=';
29
    const LOGICAL_AND           = '&&';
30
    const LOGICAL_NOT           = '!';
31
    const LOGICAL_OR            = '||';
32
    const MEMBER_ACCESS         = '->';
33
    const MODULO                = '%';
34
    const MULTIPLY              = '*';
35
    const NEGATE                = '-';
36
    const NOT_EQUAL             = '!=';
37
    const OPEN_BRACKET          = '(';
38
    const TYPE_NAMESPACE        = 'POData\\Providers\\Metadata\\Type\\';
39
40
    /**
41
     * The name of iterator
42
     * 
43
     * @var string
44
     */
45
    private $iteratorName;
46
47
    /**
48
     * The type of the resource pointed by the resource path segment
49
     * 
50
     * @var ResourceType
51
     */
52
    private $_resourceType;
53
54
    /**
55
     * @param string $iteratorName The name of the iterator
56
     */
57 7
    public function __construct($iteratorName)
58
    {
59 7
        $this->iteratorName = $iteratorName;
60
    }
61
62
    /**
63
     * Get the name of the iterator
64
     * 
65
     * @return string
66
     */
67 6
    public function getIteratorName()
68
    {
69 6
        return $this->iteratorName;
70
    }
71
72
    /**
73
     * call-back for setting the resource type.
74
     *
75
     * @param ResourceType $resourceType The resource type on which the filter
76
     *                                   is going to be applied.
77
     *
78
     * @return void
79
     */
80 1
    public function setResourceType(ResourceType $resourceType)
81
    {
82 1
        $this->_resourceType = $resourceType;
83
    }
84
85
    /**
86
     * Call-back for logical expression
87
     * 
88
     * @param ExpressionType $expressionType The type of logical expression.
89
     * @param string         $left           The left expression.
90
     * @param string         $right          The left expression.
91
     * 
92
     * @return string
93
     */
94 6
    public function onLogicalExpression($expressionType, $left, $right)
95
    {
96
        switch ($expressionType) {
97
            case ExpressionType::AND_LOGICAL:
98 6
                return $this->_prepareBinaryExpression(self::LOGICAL_AND, $left, $right);
99
100
            case ExpressionType::OR_LOGICAL:
101 2
                return $this->_prepareBinaryExpression(self::LOGICAL_OR, $left, $right);
102
103
            default:
104
                throw new \InvalidArgumentException('onLogicalExpression');
105
        }
106
    }
107
108
    /**
109
     * Call-back for arithmetic expression
110
     * 
111
     * @param ExpressionType $expressionType The type of arithmetic expression.
112
     * @param string         $left           The left expression.
113
     * @param string         $right          The left expression.
114
     * 
115
     * @return string
116
     */
117 3
    public function onArithmeticExpression($expressionType, $left, $right)
118
    {
119
        switch ($expressionType) {
120
            case ExpressionType::MULTIPLY:
121 1
                return $this->_prepareBinaryExpression(self::MULTIPLY, $left, $right);
122
123
            case ExpressionType::DIVIDE:
124
                return $this->_prepareBinaryExpression(self::DIVIDE, $left, $right);
125
126
            case ExpressionType::MODULO:
127
                return $this->_prepareBinaryExpression(self::MODULO, $left, $right);
128
129
            case ExpressionType::ADD:
130 3
                return $this->_prepareBinaryExpression(self::ADD, $left, $right);
131
132
            case ExpressionType::SUBTRACT:
133 1
                return $this->_prepareBinaryExpression(self::SUBTRACT, $left, $right);
134
135
            default:
136
                throw new \InvalidArgumentException('onArithmeticExpression');
137
        }
138
    }
139
140
    /**
141
     * Call-back for relational expression
142
     * 
143
     * @param ExpressionType $expressionType The type of relation expression
144
     * @param string         $left           The left expression
145
     * @param string         $right          The left expression
146
     * 
147
     * @return string
148
     */
149 6
    public function onRelationalExpression($expressionType, $left, $right)
150
    {
151
        switch ($expressionType) {
152
            case ExpressionType::GREATERTHAN:
153 2
                return $this->_prepareBinaryExpression(self::GREATER_THAN, $left, $right);
154
155
            case ExpressionType::GREATERTHAN_OR_EQUAL:
156 2
                return $this->_prepareBinaryExpression(self::GREATER_THAN_OR_EQUAL, $left, $right);
157
158
            case ExpressionType::LESSTHAN:
159
                return $this->_prepareBinaryExpression(self::LESS_THAN, $left, $right);
160
161
            case ExpressionType::LESSTHAN_OR_EQUAL:
162 1
                return $this->_prepareBinaryExpression(self::LESS_THAN_OR_EQUAL, $left, $right);
163
164
            case ExpressionType::EQUAL:
165 6
                return $this->_prepareBinaryExpression(self::EQUAL, $left, $right);
166
167
            case ExpressionType::NOTEQUAL:
168 2
                return $this->_prepareBinaryExpression(self::NOT_EQUAL, $left, $right);
169
170
            default:
171
                throw new \InvalidArgumentException('onArithmeticExpression');
172
        }
173
    }
174
175
    /**
176
     * Call-back for unary expression
177
     * 
178
     * @param ExpressionType $expressionType The type of unary expression
179
     * @param string         $child          The child expression
180
     * 
181
     * @return string
182
     */
183 6
    public function onUnaryExpression($expressionType, $child)
184
    {
185
        switch ($expressionType) {
186
            case ExpressionType::NEGATE:
187
                return $this->_prepareUnaryExpression(self::NEGATE, $child);
188
189
            case ExpressionType::NOT_LOGICAL:
190 6
                return $this->_prepareUnaryExpression(self::LOGICAL_NOT, $child);
191
192
            default:
193
                throw new \InvalidArgumentException('onUnaryExpression');
194
        }
195
    }
196
197
    /**
198
     * Call-back for constant expression
199
     * 
200
     * @param IType  $type  The type of constant
201
     * @param mixed $value The value of the constant
202
     * 
203
     * @return string
204
     */
205 6
    public function onConstantExpression(IType $type, $value)
206
    {
207 6
        if (is_bool($value)) {
208 1
            return var_export($value, true);
209 6
        } else if (is_null($value)) {
210
            return var_export(null, true);
211
        }
212
        
213 6
        return $value;
214
    }
215
216
    /**
217
     * Call-back for property access expression
218
     * 
219
     * @param PropertyAccessExpression $expression The property access expression
220
     * 
221
     * @return string
222
     */
223 6
    public function onPropertyAccessExpression($expression)
224
    {
225 6
        $parent = $expression;
226 6
        $variable = null;
227
        
228
        do {
229 6
            $variable = $parent->getResourceProperty()->getName() . self::MEMBER_ACCESS . $variable;
230 6
            $parent = $parent->getParent();
231 6
        } while ($parent != null);
232
 
233 6
        $variable = rtrim($variable, self::MEMBER_ACCESS);
234 6
        $variable = $this->getIteratorName() . self::MEMBER_ACCESS . $variable;
235 6
        return $variable;
236
    }
237
238
    /**
239
     * Call-back for function call expression
240
     * 
241
     * @param \POData\UriProcessor\QueryProcessor\FunctionDescription $functionDescription Description of the function.
242
     * @param array<string>       $params              Paameters to the function.
243
     * 
244
     * @return string
245
     */
246 6
    public function onFunctionCallExpression($functionDescription, $params)
247
    {
248 6
        switch ($functionDescription->name) {
249
            case ODataConstants::STRFUN_COMPARE:
250 1
                return "strcmp($params[0], $params[1])";
251
252
            case ODataConstants::STRFUN_ENDSWITH:
253 1
                return "(strcmp(substr($params[0], strlen($params[0]) - strlen($params[1])), $params[1]) === 0)";
254
255
            case ODataConstants::STRFUN_INDEXOF:
256 1
                return "strpos($params[0], $params[1])";
257
258
            case ODataConstants::STRFUN_REPLACE:
259 2
                return "str_replace($params[1], $params[2], $params[0])";
260
261
            case ODataConstants::STRFUN_STARTSWITH:
262 1
                return "(strpos($params[0], $params[1]) === 0)";
263
264
            case ODataConstants::STRFUN_TOLOWER:
265 1
                return "strtolower($params[0])";
266
267
            case ODataConstants::STRFUN_TOUPPER:
268 1
                return "strtoupper($params[0])";
269
270
            case ODataConstants::STRFUN_TRIM:
271 1
                return "trim($params[0])";
272
273
            case ODataConstants::STRFUN_SUBSTRING:
274 1
                return count($params) == 3 ?
275 1
                    "substr($params[0], $params[1], $params[2])" : "substr($params[0], $params[1])";
276
277
            case ODataConstants::STRFUN_SUBSTRINGOF:
278 1
                return "(strpos($params[1], $params[0]) !== false)";
279
280
            case ODataConstants::STRFUN_CONCAT:
281
                return $params[0] . ' . ' . $params[1];
282
283
            case ODataConstants::STRFUN_LENGTH:
284 1
                return "strlen($params[0])";
285
286
            case ODataConstants::GUIDFUN_EQUAL:
287 1
                return self::TYPE_NAMESPACE . "Guid::guidEqual($params[0], $params[1])";
288
289
            case ODataConstants::DATETIME_COMPARE:
290
                return self::TYPE_NAMESPACE . "DateTime::dateTimeCmp($params[0], $params[1])";
291
292
            case ODataConstants::DATETIME_YEAR:
293 1
                return self::TYPE_NAMESPACE . "DateTime::year($params[0])";
294
295
            case ODataConstants::DATETIME_MONTH:
296 1
                return self::TYPE_NAMESPACE . "DateTime::month($params[0])";
297
298
            case ODataConstants::DATETIME_DAY:
299 1
                return self::TYPE_NAMESPACE . "DateTime::day($params[0])";
300
301
            case ODataConstants::DATETIME_HOUR:
302
                return self::TYPE_NAMESPACE . "DateTime::hour($params[0])";
303
304
            case ODataConstants::DATETIME_MINUTE:
305
                return self::TYPE_NAMESPACE . "DateTime::minute($params[0])";
306
307
            case ODataConstants::DATETIME_SECOND:
308
                return self::TYPE_NAMESPACE . "DateTime::second($params[0])";
309
310
            case ODataConstants::MATHFUN_ROUND:
311 1
                return "round($params[0])";
312
313
            case ODataConstants::MATHFUN_CEILING:
314 1
                return "ceil($params[0])";
315
316
            case ODataConstants::MATHFUN_FLOOR:
317 1
                return "floor($params[0])";
318
319
            case ODataConstants::BINFUL_EQUAL:
320
                return self::TYPE_NAMESPACE . "Binary::binaryEqual($params[0], $params[1])";
321
322 6
            case 'is_null':
323 6
                return "is_null($params[0])";
324
325
            default:
326
                throw new \InvalidArgumentException('onFunctionCallExpression');
327
        }
328
    }
329
330
    /**
331
     * To format binary expression
332
     * 
333
     * @param string $operator The binary operator.
334
     * @param string $left     The left operand.
335
     * @param string $right    The right operand.
336
     * 
337
     * @return string
338
     */
339 6
    private function _prepareBinaryExpression($operator, $left, $right)
340
    {
341 6
        return 
342 6
            self::OPEN_BRACKET . $left . ' ' . $operator . ' ' . $right . self::CLOSE_BRACKET;
343
    }
344
345
    /**
346
     * To format unary expression
347
     * 
348
     * @param string $operator The unary operator.
349
     * @param string $child    The operand.
350
     * 
351
     * @return string
352
     */
353 6
    private function _prepareUnaryExpression($operator, $child)
354
    {
355 6
        return $operator . self::OPEN_BRACKET . $child . self::CLOSE_BRACKET;
356
    }
357
358
	public function clear() {}
359
}