Passed
Push — master ( 564cae...1faa45 )
by Alexander
74:09 queued 70:32
created

LikeConditionBuilder::build()   C

Complexity

Conditions 12
Paths 44

Size

Total Lines 38
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 12

Importance

Changes 0
Metric Value
cc 12
eloc 24
nc 44
nop 2
dl 0
loc 38
ccs 24
cts 24
cp 1
crap 12
rs 6.9666
c 0
b 0
f 0

How to fix   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
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\db\conditions;
9
10
use yii\base\InvalidArgumentException;
11
use yii\db\ExpressionBuilderInterface;
12
use yii\db\ExpressionBuilderTrait;
13
use yii\db\ExpressionInterface;
14
15
/**
16
 * Class LikeConditionBuilder builds objects of [[LikeCondition]]
17
 *
18
 * @author Dmytro Naumenko <[email protected]>
19
 * @since 2.0.14
20
 */
21
class LikeConditionBuilder implements ExpressionBuilderInterface
22
{
23
    use ExpressionBuilderTrait;
24
25
    /**
26
     * @var array map of chars to their replacements in LIKE conditions.
27
     * By default it's configured to escape `%`, `_` and `\` with `\`.
28
     */
29
    protected $escapingReplacements = [
30
        '%' => '\%',
31
        '_' => '\_',
32
        '\\' => '\\\\',
33
    ];
34
    /**
35
     * @var string|null character used to escape special characters in LIKE conditions.
36
     * By default it's assumed to be `\`.
37
     */
38
    protected $escapeCharacter;
39
40
41
    /**
42
     * Method builds the raw SQL from the $expression that will not be additionally
43
     * escaped or quoted.
44
     *
45
     * @param ExpressionInterface|LikeCondition $expression the expression to be built.
46
     * @param array $params the binding parameters.
47
     * @return string the raw SQL that will not be additionally escaped or quoted.
48
     */
49 105
    public function build(ExpressionInterface $expression, array &$params = [])
50
    {
51 105
        $operator = strtoupper($expression->getOperator());
0 ignored issues
show
Bug introduced by
The method getOperator() does not exist on yii\db\ExpressionInterface. It seems like you code against a sub-type of said class. However, the method does not exist in yii\db\JsonExpression or yii\db\ArrayExpression or yii\db\PdoValue or yii\db\conditions\ConditionInterface or yii\db\conditions\HashCondition or yii\db\conditions\NotCondition. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

51
        $operator = strtoupper($expression->/** @scrutinizer ignore-call */ getOperator());
Loading history...
52 105
        $column = $expression->getColumn();
0 ignored issues
show
Bug introduced by
The method getColumn() does not exist on yii\db\ExpressionInterface. It seems like you code against a sub-type of yii\db\ExpressionInterface such as yii\db\Query or yii\db\Expression or yii\db\conditions\InCondition or yii\db\conditions\BetweenCondition or yii\db\conditions\SimpleCondition. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

52
        /** @scrutinizer ignore-call */ 
53
        $column = $expression->getColumn();
Loading history...
53 105
        $values = $expression->getValue();
0 ignored issues
show
Bug introduced by
The method getValue() does not exist on yii\db\ExpressionInterface. It seems like you code against a sub-type of yii\db\ExpressionInterface such as yii\db\JsonExpression or yii\db\Query or yii\db\ArrayExpression or yii\db\PdoValue or yii\db\Expression or yii\db\conditions\BetweenColumnsCondition or yii\db\conditions\SimpleCondition. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
        /** @scrutinizer ignore-call */ 
54
        $values = $expression->getValue();
Loading history...
54 105
        $escape = $expression->getEscapingReplacements();
0 ignored issues
show
Bug introduced by
The method getEscapingReplacements() does not exist on yii\db\ExpressionInterface. It seems like you code against a sub-type of yii\db\ExpressionInterface such as yii\db\Query or yii\db\Expression or yii\db\conditions\LikeCondition. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

54
        /** @scrutinizer ignore-call */ 
55
        $escape = $expression->getEscapingReplacements();
Loading history...
55 105
        if ($escape === null || $escape === []) {
56 102
            $escape = $this->escapingReplacements;
57
        }
58
59 105
        list($andor, $not, $operator) = $this->parseOperator($operator);
60
61 105
        if (!is_array($values)) {
62 49
            $values = [$values];
63
        }
64
65 105
        if (empty($values)) {
66 16
            return $not ? '' : '0=1';
67
        }
68
69 89
        if ($column instanceof ExpressionInterface) {
70 3
            $column = $this->queryBuilder->buildExpression($column, $params);
71 86
        } elseif (is_string($column) && strpos($column, '(') === false) {
72 86
            $column = $this->queryBuilder->db->quoteColumnName($column);
73
        }
74
75 89
        $escapeSql = $this->getEscapeSql();
76 89
        $parts = [];
77 89
        foreach ($values as $value) {
78 89
            if ($value instanceof ExpressionInterface) {
79 48
                $phName = $this->queryBuilder->buildExpression($value, $params);
80
            } else {
81 65
                $phName = $this->queryBuilder->bindParam(empty($escape) ? $value : ('%' . strtr($value, $escape) . '%'), $params);
82
            }
83 89
            $parts[] = "{$column} {$operator} {$phName}{$escapeSql}";
84
        }
85
86 89
        return implode($andor, $parts);
87
    }
88
89
    /**
90
     * @return string
91
     */
92 89
    private function getEscapeSql()
93
    {
94 89
        if ($this->escapeCharacter !== null) {
95 27
            return " ESCAPE '{$this->escapeCharacter}'";
96
        }
97
98 62
        return '';
99
    }
100
101
    /**
102
     * @param string $operator
103
     * @return array
104
     */
105 105
    protected function parseOperator($operator)
106
    {
107 105
        if (!preg_match('/^(AND |OR |)(((NOT |))I?LIKE)/', $operator, $matches)) {
108
            throw new InvalidArgumentException("Invalid operator '$operator'.");
109
        }
110 105
        $andor = ' ' . (!empty($matches[1]) ? $matches[1] : 'AND ');
111 105
        $not = !empty($matches[3]);
112 105
        $operator = $matches[2];
113
114 105
        return [$andor, $not, $operator];
115
    }
116
}
117