Completed
Push — master ( 010cd6...22a8dd )
by Todd
11s
created

ExpressionLanguage::iteratorExpression()   B

Complexity

Conditions 7
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 11
cts 11
cp 1
rs 8.2222
c 0
b 0
f 0
cc 7
eloc 11
nc 2
nop 1
crap 7
1
<?php
2
/**
3
 * @author Todd Burry <[email protected]>
4
 * @copyright 2009-2017 Vanilla Forums Inc.
5
 * @license MIT
6
 */
7
8
namespace Ebi;
9
10
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
11
use Symfony\Component\ExpressionLanguage\Node\GetAttrNode;
12
use Symfony\Component\ExpressionLanguage\Node\NameNode;
13
14
class ExpressionLanguage extends \Symfony\Component\ExpressionLanguage\ExpressionLanguage {
15 77
    public function __construct() {
16 77
        parent::__construct();
17
18 77
        $this->registerNodeFunction(GetAttrNode::class, function (\Symfony\Component\ExpressionLanguage\Compiler $compiler, GetAttrNode $node) {
19 10
                switch ($node->attributes['type']) {
20 10
                    case GetAttrNode::METHOD_CALL:
21
                        $compiler
22
                            ->compile($node->nodes['node'])
23
                            ->raw('->')
24
                            ->raw($node->nodes['attribute']->attributes['value'])
25
                            ->raw('(')
26
                            ->compile($node->nodes['arguments'])
27
                            ->raw(')')
28
                        ;
29
                        break;
30
31 10
                    case GetAttrNode::PROPERTY_CALL:
32
                    case GetAttrNode::ARRAY_CALL:
33 10
                        $itExpr = $this->iteratorExpression($node);
34
35 10
                        if ($itExpr) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $itExpr of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch 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:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
36 1
                            $compiler->raw($itExpr);
37
                        } else {
38
                            $compiler
39 9
                                ->compile($node->nodes['node'])
40 9
                                ->raw('[')
41 9
                                ->compile($node->nodes['attribute'])->raw(']');
42
                        }
43 10
                        break;
44
                }
45 77
        });
46 77
    }
47
48
    /**
49
     * Look for a specific iterator expression.
50
     *
51
     * Iterator expressions are one of the following:
52
     *
53
     * - i123.index
54
     * - i123.first
55
     * - i123.last
56
     * - i123.count
57
     *
58
     * @param GetAttrNode $node The node to inspect.
59
     * @return null|string Returns the appropriate variable or **null** if the node isn't an iterator expression.
60
     */
61 10
    private function iteratorExpression(GetAttrNode $node) {
62 10
        if (empty($node->nodes['node'])
63 10
            || !($node->nodes['node'] instanceof NameNode)
64 10
            || !preg_match('`^i(\d+)$`', $node->nodes['node']->attributes['name'], $m)
65 1
            || empty($node->nodes['attribute'])
66 1
            || !($node->nodes['attribute'] instanceof ConstantNode)
67 10
            || !in_array($node->nodes['attribute']->attributes['value'], ['index', 'first', 'last', 'count'], true)
68
        ) {
69
70 9
            return null;
71
        }
72 1
        $i = $m[1];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
73 1
        $field = $node->nodes['attribute']->attributes['value'];
74 1
        return "\${$field}{$i}";
75
    }
76
77 32
    public function getFunctionCompiler($name) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
78 32
        if (isset($this->functions[$name])) {
79 9
            return $this->functions[$name]['compiler'];
80
        }
81 32
        return null;
82
    }
83
}
84