Completed
Push — master ( 8c259e...a3e53b )
by Guilherme
27:10 queued 12:02
created

QueryExpressionVisitor::walkComparison()   C

Complexity

Conditions 17
Paths 118

Size

Total Lines 80
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 42
CRAP Score 17.0272

Importance

Changes 0
Metric Value
cc 17
eloc 54
c 0
b 0
f 0
nc 118
nop 1
dl 0
loc 80
ccs 42
cts 44
cp 0.9545
crap 17.0272
rs 5.0666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Query;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Doctrine\Common\Collections\Collection;
9
use Doctrine\Common\Collections\Expr\Comparison;
10
use Doctrine\Common\Collections\Expr\CompositeExpression;
11
use Doctrine\Common\Collections\Expr\ExpressionVisitor;
12
use Doctrine\Common\Collections\Expr\Value;
13
use RuntimeException;
14
use function count;
15
use function str_replace;
16
use function strpos;
17
18
/**
19
 * Converts Collection expressions to Query expressions.
20
 */
21
class QueryExpressionVisitor extends ExpressionVisitor
22
{
23
    /** @var string[] */
24
    private static $operatorMap = [
25
        Comparison::GT => Expr\Comparison::GT,
26
        Comparison::GTE => Expr\Comparison::GTE,
27
        Comparison::LT  => Expr\Comparison::LT,
28
        Comparison::LTE => Expr\Comparison::LTE,
29
    ];
30
31
    /** @var string[] */
32
    private $queryAliases;
33
34
    /** @var Expr */
35
    private $expr;
36
37
    /** @var mixed[] */
38
    private $parameters = [];
39
40
    /**
41
     * @param string[] $queryAliases
42
     */
43 34
    public function __construct($queryAliases)
44
    {
45 34
        $this->queryAliases = $queryAliases;
46 34
        $this->expr         = new Expr();
47 34
    }
48
49
    /**
50
     * Gets bound parameters.
51
     * Filled after {@link dispach()}.
52
     *
53
     * @return Collection|mixed[]
54
     */
55 24
    public function getParameters()
56
    {
57 24
        return new ArrayCollection($this->parameters);
58
    }
59
60
    /**
61
     * Clears parameters.
62
     */
63 1
    public function clearParameters()
64
    {
65 1
        $this->parameters = [];
66 1
    }
67
68
    /**
69
     * Converts Criteria expression to Query one based on static map.
70
     *
71
     * @param string $criteriaOperator
72
     *
73
     * @return string|null
74
     */
75 11
    private static function convertComparisonOperator($criteriaOperator)
76
    {
77 11
        return self::$operatorMap[$criteriaOperator] ?? null;
78
    }
79
80
    /**
81
     * {@inheritDoc}
82
     */
83 10
    public function walkCompositeExpression(CompositeExpression $expr)
84
    {
85 10
        $expressionList = [];
86
87 10
        foreach ($expr->getExpressionList() as $child) {
88 10
            $expressionList[] = $this->dispatch($child);
89
        }
90
91 10
        switch ($expr->getType()) {
92
            case CompositeExpression::TYPE_AND:
93 9
                return new Expr\Andx($expressionList);
94
            case CompositeExpression::TYPE_OR:
95 1
                return new Expr\Orx($expressionList);
96
            default:
97
                throw new RuntimeException('Unknown composite ' . $expr->getType());
98
        }
99
    }
100
101
    /**
102
     * {@inheritDoc}
103
     */
104 28
    public function walkComparison(Comparison $comparison)
105
    {
106 28
        if (! isset($this->queryAliases[0])) {
107
            throw new QueryException('No aliases are set before invoking walkComparison().');
108
        }
109
110 28
        $field = $this->queryAliases[0] . '.' . $comparison->getField();
111
112 28
        foreach ($this->queryAliases as $alias) {
113 28
            if (strpos($comparison->getField() . '.', $alias . '.') === 0) {
114 5
                $field = $comparison->getField();
115 5
                break;
116
            }
117
        }
118
119 28
        $parameterName  = str_replace('.', '_', $comparison->getField());
120 28
        $parameterCount = count($this->parameters);
121
122 28
        foreach ($this->parameters as $parameter) {
123 10
            if ($parameter->getName() === $parameterName) {
124 4
                $parameterName .= '_' . $parameterCount;
125 4
                break;
126
            }
127
        }
128
129 28
        $parameter   = new Parameter($parameterName, $this->walkValue($comparison->getValue()));
130 28
        $placeholder = ':' . $parameterName;
131
132 28
        switch ($comparison->getOperator()) {
133
            case Comparison::IN:
134 1
                $this->parameters[] = $parameter;
135
136 1
                return $this->expr->in($field, $placeholder);
137
            case Comparison::NIN:
138 1
                $this->parameters[] = $parameter;
139
140 1
                return $this->expr->notIn($field, $placeholder);
141
            case Comparison::EQ:
142
            case Comparison::IS:
143 17
                if ($this->walkValue($comparison->getValue()) === null) {
144 2
                    return $this->expr->isNull($field);
145
                }
146 15
                $this->parameters[] = $parameter;
147
148 15
                return $this->expr->eq($field, $placeholder);
149
            case Comparison::NEQ:
150 2
                if ($this->walkValue($comparison->getValue()) === null) {
151 1
                    return $this->expr->isNotNull($field);
152
                }
153 1
                $this->parameters[] = $parameter;
154
155 1
                return $this->expr->neq($field, $placeholder);
156
            case Comparison::CONTAINS:
157 1
                $parameter->setValue('%' . $parameter->getValue() . '%', $parameter->getType());
158 1
                $this->parameters[] = $parameter;
159
160 1
                return $this->expr->like($field, $placeholder);
161
            case Comparison::STARTS_WITH:
162 1
                $parameter->setValue($parameter->getValue() . '%', $parameter->getType());
163 1
                $this->parameters[] = $parameter;
164
165 1
                return $this->expr->like($field, $placeholder);
166
            case Comparison::ENDS_WITH:
167 1
                $parameter->setValue('%' . $parameter->getValue(), $parameter->getType());
168 1
                $this->parameters[] = $parameter;
169
170 1
                return $this->expr->like($field, $placeholder);
171
            default:
172 11
                $operator = self::convertComparisonOperator($comparison->getOperator());
173 11
                if ($operator) {
174 11
                    $this->parameters[] = $parameter;
175
176 11
                    return new Expr\Comparison(
177 11
                        $field,
178
                        $operator,
179
                        $placeholder
180
                    );
181
                }
182
183
                throw new RuntimeException('Unknown comparison operator: ' . $comparison->getOperator());
184
        }
185
    }
186
187
    /**
188
     * {@inheritDoc}
189
     */
190 29
    public function walkValue(Value $value)
191
    {
192 29
        return $value->getValue();
193
    }
194
}
195