ExpressionLanguage   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 82.93%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 5
dl 0
loc 70
ccs 34
cts 41
cp 0.8293
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getFunctionCompiler() 0 6 2
B __construct() 0 32 5
B iteratorExpression() 0 15 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\Cache\Adapter\NullAdapter;
11
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
12
use Symfony\Component\ExpressionLanguage\Node\GetAttrNode;
13
use Symfony\Component\ExpressionLanguage\Node\NameNode;
14
15
class ExpressionLanguage extends \Symfony\Component\ExpressionLanguage\ExpressionLanguage {
16 86
    public function __construct() {
17 86
        parent::__construct(new NullAdapter());
18
19 86
        $this->registerNodeFunction(GetAttrNode::class, function (\Symfony\Component\ExpressionLanguage\Compiler $compiler, GetAttrNode $node) {
20 11
                switch ($node->attributes['type']) {
21 11
                    case GetAttrNode::METHOD_CALL:
22
                        $compiler
23
                            ->compile($node->nodes['node'])
24
                            ->raw('->')
25
                            ->raw($node->nodes['attribute']->attributes['value'])
26
                            ->raw('(')
27
                            ->compile($node->nodes['arguments'])
28
                            ->raw(')')
29
                        ;
30
                        break;
31
32 11
                    case GetAttrNode::PROPERTY_CALL:
33 11
                    case GetAttrNode::ARRAY_CALL:
34 11
                        $itExpr = $this->iteratorExpression($node);
35
36 11
                        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...
37 1
                            $compiler->raw($itExpr);
38 1
                        } else {
39
                            $compiler
40 10
                                ->compile($node->nodes['node'])
41 10
                                ->raw('[')
42 10
                                ->compile($node->nodes['attribute'])->raw(']');
43
                        }
44 11
                        break;
45 11
                }
46 86
        });
47 86
    }
48
49
    /**
50
     * Look for a specific iterator expression.
51
     *
52
     * Iterator expressions are one of the following:
53
     *
54
     * - i123.index
55
     * - i123.first
56
     * - i123.last
57
     * - i123.count
58
     *
59
     * @param GetAttrNode $node The node to inspect.
60
     * @return null|string Returns the appropriate variable or **null** if the node isn't an iterator expression.
61
     */
62 11
    private function iteratorExpression(GetAttrNode $node) {
63 11
        if (empty($node->nodes['node'])
64 11
            || !($node->nodes['node'] instanceof NameNode)
65 11
            || !preg_match('`^i(\d+)$`', $node->nodes['node']->attributes['name'], $m)
66 11
            || empty($node->nodes['attribute'])
67 1
            || !($node->nodes['attribute'] instanceof ConstantNode)
68 1
            || !in_array($node->nodes['attribute']->attributes['value'], ['index', 'first', 'last', 'count'], true)
69 11
        ) {
70
71 10
            return null;
72
        }
73 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...
74 1
        $field = $node->nodes['attribute']->attributes['value'];
75 1
        return "\${$field}{$i}";
76
    }
77
78 41
    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...
79 41
        if (isset($this->functions[$name])) {
80 17
            return $this->functions[$name]['compiler'];
81
        }
82 41
        return null;
83
    }
84
}
85