Completed
Push — master ( 639c65...497f34 )
by Maxim
06:00
created

ConditionDbParser   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 122
rs 10
c 0
b 0
f 0
wmc 27

6 Methods

Rating   Name   Duplication   Size   Complexity  
A parseBetweenCondition() 0 4 1
C parseConditions() 0 37 12
A parseSimpleCondition() 0 3 1
A parseLikeCondition() 0 6 3
A parseInCondition() 0 13 4
B parse() 0 17 6
1
<?php
2
3
namespace WebComplete\core\condition;
4
5
use Doctrine\DBAL\Query\QueryBuilder;
6
7
class ConditionDbParser
8
{
9
10
    /**
11
     * @param QueryBuilder $queryBuilder
12
     * @param Condition|null $condition
13
     */
14
    public function parse(QueryBuilder $queryBuilder, Condition $condition = null)
15
    {
16
        if ($condition === null) {
17
            return;
18
        }
19
        $this->parseConditions($queryBuilder, $condition);
20
21
        foreach ($condition->getSort() as $field => $direction) {
22
            $queryBuilder->orderBy($field, $direction === \SORT_DESC ? 'desc' : 'asc');
23
        }
24
25
        if ($offset = (int)$condition->getOffset()) {
26
            $queryBuilder->setFirstResult($offset);
27
        }
28
29
        if ($limit = (int)$condition->getLimit()) {
30
            $queryBuilder->setMaxResults($limit);
31
        }
32
    }
33
34
    /**
35
     * @param QueryBuilder $queryBuilder
36
     * @param Condition $condition
37
     */
38
    protected function parseConditions(QueryBuilder $queryBuilder, Condition $condition)
39
    {
40
        foreach ($condition->getConditions() as $cond) {
41
            if (!\is_array($cond)) {
42
                continue;
43
            }
44
45
            $cond = \array_values($cond);
46
            $type = \array_shift($cond);
47
            switch ($type) {
48
                case Condition::EQUALS:
49
                    $this->parseSimpleCondition('=', $queryBuilder, $cond);
50
                    break;
51
                case Condition::NOT_EQUALS:
52
                    $this->parseSimpleCondition('<>', $queryBuilder, $cond);
53
                    break;
54
                case Condition::LESS_THAN:
55
                    $this->parseSimpleCondition('<', $queryBuilder, $cond);
56
                    break;
57
                case Condition::GREATER_THAN:
58
                    $this->parseSimpleCondition('>', $queryBuilder, $cond);
59
                    break;
60
                case Condition::LESS_OR_EQUALS:
61
                    $this->parseSimpleCondition('<=', $queryBuilder, $cond);
62
                    break;
63
                case Condition::GREATER_OR_EQUALS:
64
                    $this->parseSimpleCondition('>=', $queryBuilder, $cond);
65
                    break;
66
                case Condition::BETWEEN:
67
                    $this->parseBetweenCondition($queryBuilder, $cond);
68
                    break;
69
                case Condition::LIKE:
70
                    $this->parseLikeCondition($queryBuilder, $cond);
71
                    break;
72
                case Condition::IN:
73
                    $this->parseInCondition($queryBuilder, $cond);
74
                    break;
75
            }
76
        }
77
    }
78
79
    /**
80
     * @param QueryBuilder $queryBuilder
81
     * @param $cond
82
     */
83
    protected function parseLikeCondition(QueryBuilder $queryBuilder, $cond)
84
    {
85
        $value = $cond[2] ? '%' : '';
86
        $value .= $cond[1];
87
        $value .= $cond[3] ? '%' : '';
88
        $queryBuilder->andWhere("{$cond[0]} LIKE " . $queryBuilder->createNamedParameter($value));
89
    }
90
91
    /**
92
     * @param QueryBuilder $queryBuilder
93
     * @param $cond
94
     */
95
    protected function parseInCondition(QueryBuilder $queryBuilder, $cond)
96
    {
97
        if ($cond[1]) {
98
            $isNumeric = $cond[2];
99
            $sql = '';
100
            /** @var array $values */
101
            $values = $cond[1];
102
            foreach ($values as $v) {
103
                $sql .= ($isNumeric ? (float)$v : $queryBuilder->createNamedParameter($v)) . ',';
104
            }
105
            $queryBuilder->andWhere("{$cond[0]} IN (" . \rtrim($sql, ',') . ')');
106
        } else {
107
            $queryBuilder->andWhere('1 = 2'); // IN empty array is always false
108
        }
109
    }
110
111
    /**
112
     * @param QueryBuilder $queryBuilder
113
     * @param $cond
114
     */
115
    protected function parseBetweenCondition(QueryBuilder $queryBuilder, $cond)
116
    {
117
        $queryBuilder->andWhere("{$cond[0]} BETWEEN " . $queryBuilder->createNamedParameter($cond[1])
118
            . ' AND ' . $queryBuilder->createNamedParameter($cond[2]));
119
    }
120
121
    /**
122
     * @param string $exp
123
     * @param QueryBuilder $queryBuilder
124
     * @param $cond
125
     */
126
    protected function parseSimpleCondition(string $exp, QueryBuilder $queryBuilder, $cond)
127
    {
128
        $queryBuilder->andWhere("{$cond[0]} $exp " . $queryBuilder->createNamedParameter($cond[1]));
129
    }
130
}
131