FilterBuilder   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 29
eloc 58
dl 0
loc 172
ccs 61
cts 61
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A assert() 0 4 2
A getPropertyFilterKey() 0 6 2
A getFilterRow() 0 11 2
B getPropertyFilterValue() 0 12 8
A toDateTime() 0 15 4
A getPropertyFilterRow() 0 5 1
A getFieldFilterRow() 0 10 6
A __construct() 0 5 1
A getInfoBlockFilter() 0 13 1
A getFilter() 0 12 2
1
<?php
2
3
namespace BitrixToolkit\BitrixEntityMapper\Query;
4
5
use Bitrix\Main\Type\DateTime as BitrixDateTime;
6
use CIBlock;
7
use DateTime;
8
use Exception;
9
use InvalidArgumentException;
10
use BitrixToolkit\BitrixEntityMapper\Annotation\Property\Field;
11
use BitrixToolkit\BitrixEntityMapper\Annotation\Property\Property;
12
use BitrixToolkit\BitrixEntityMapper\Map\EntityMap;
13
14
class FilterBuilder
15
{
16
    protected $entityMap;
17
    protected $where = [];
18
    protected $whereRaw = [];
19
20 20
    public function __construct(EntityMap $entityMap, array $where, array $whereRaw)
21
    {
22 20
        $this->entityMap = $entityMap;
23 20
        $this->where = $where;
24 20
        $this->whereRaw = $whereRaw;
25
    }
26
27
    /**
28
     * @return array
29
     * @throws Exception
30
     */
31 20
    public function getFilter()
32
    {
33 20
        $filter = $this->getInfoBlockFilter();
34
35 19
        foreach ($this->where as $entry) {
36 10
            list($property, $operator, $value) = $entry;
37 10
            $filter += $this->getFilterRow($property, $operator, $value);
38
        }
39
40 19
        $filter = array_merge($filter, $this->whereRaw);
41
42 19
        return $filter;
43
    }
44
45
    /**
46
     * @return array
47
     * @throws InvalidArgumentException
48
     */
49 20
    protected function getInfoBlockFilter()
50
    {
51 20
        $infoBlockType = $this->entityMap->getAnnotation()->getType();
52 20
        $infoBlockCode = $this->entityMap->getAnnotation()->getCode();
53 20
        $infoBlock = CIBlock::GetList(null, [
54 20
            'TYPE' => $infoBlockType,
55 20
            'CODE' => $infoBlockCode,
56 20
            'CHECK_PERMISSIONS' => 'N'
57 20
        ])->Fetch();
58
59 20
        self::assert(!empty($infoBlock['ID']), "Инфоблок с кодом $infoBlockCode и типом $infoBlockType не найден.");
60
61 19
        return ['=IBLOCK_ID' => $infoBlock['ID']];
62
    }
63
64
    /**
65
     * @param mixed $term
66
     * @param string $msg
67
     */
68 20
    protected static function assert($term, $msg)
69
    {
70 20
        if (!$term) {
71 1
            throw new InvalidArgumentException($msg);
72
        }
73
    }
74
75
    /**
76
     * @param string $property
77
     * @param string $operator
78
     * @param mixed $value
79
     * @return array|null
80
     * @throws InvalidArgumentException
81
     * @throws Exception
82
     */
83 10
    protected function getFilterRow($property, $operator, $value)
84
    {
85 10
        $propertyMap = $this->entityMap->getProperty($property);
86 10
        $propertyAnnotation = $propertyMap->getAnnotation();
87 10
        $type = $propertyAnnotation->getType();
88 10
        $code = $propertyAnnotation->getCode();
89
90 10
        if ($propertyAnnotation instanceof Field) {
91 9
            return $this->getFieldFilterRow($type, $code, $operator, $value);
92
        } else {
93 3
            return $this->getPropertyFilterRow($type, $code, $operator, $value);
94
        }
95
    }
96
97
    /**
98
     * @param string $type
99
     * @param string $code
100
     * @param string $operator
101
     * @param mixed $value
102
     * @return array
103
     */
104 9
    protected static function getFieldFilterRow($type, $code, $operator, $value)
105
    {
106 9
        $k = $operator . $code;
107 9
        if ($type === Field::TYPE_BOOLEAN) {
108 1
            $v = $value && $value !== 'N' ? 'Y' : 'N';
109
        } else {
110 8
            $v = $value !== '' && $value !== null ? $value : false;
111
        }
112
113 9
        return [$k => $v];
114
    }
115
116
    /**
117
     * @param string $type
118
     * @param string $code
119
     * @param string $operator
120
     * @param mixed $value
121
     * @return array
122
     * @throws Exception
123
     */
124 3
    protected static function getPropertyFilterRow($type, $code, $operator, $value)
125
    {
126 3
        $k = self::getPropertyFilterKey($type, $code, $operator);
127 3
        $v = self::getPropertyFilterValue($type, $value);
128 3
        return [$k => $v];
129
    }
130
131
    /**
132
     * @param string $type
133
     * @param string $code
134
     * @param string $operator
135
     * @return string
136
     */
137 3
    protected static function getPropertyFilterKey($type, $code, $operator)
138
    {
139 3
        if ($type === Property::TYPE_BOOLEAN) {
140 1
            return "{$operator}PROPERTY_{$code}_VALUE";
141
        } else {
142 2
            return "{$operator}PROPERTY_{$code}";
143
        }
144
    }
145
146
    /**
147
     * @param string $type
148
     * @param mixed $value
149
     * @return mixed
150
     * @throws Exception
151
     */
152 3
    protected static function getPropertyFilterValue($type, $value)
153
    {
154 3
        if ($type === Property::TYPE_BOOLEAN) {
155 1
            return $value && $value !== 'N' ? 'Y' : false;
156
        }
157
158 2
        if ($type === Property::TYPE_DATETIME) {
159 1
            $dateTime = self::toDateTime($value);
160 1
            return $dateTime instanceof DateTime ? $dateTime->format('Y-m-d H:i:s') : false;
161
        }
162
163 1
        return ($value === '' || $value === null) ? false : $value;
164
    }
165
166
    /**
167
     * @param mixed $value
168
     * @return DateTime|false|null
169
     * @throws Exception
170
     */
171 1
    protected static function toDateTime($value)
172
    {
173 1
        if (!$value) {
174 1
            return null;
175
        }
176
177 1
        if ($value instanceof DateTime) {
178 1
            return $value;
179
        }
180
181 1
        if ($value instanceof BitrixDateTime) {
182 1
            return DateTime::createFromFormat('Y-m-d H:i:s', $value->format('Y-m-d H:i:s'));
183
        }
184
185 1
        return new DateTime($value);
186
    }
187
}