DataBuilder   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 22
eloc 76
dl 0
loc 201
ccs 86
cts 86
cp 1
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getBitrixProperties() 0 12 2
A getBitrixFieldEntry() 0 18 3
A assert() 0 4 2
A getBitrixInfoBlock() 0 7 1
A getBitrixPropertyEntry() 0 22 2
A normalizeDateTimeForBitrix() 0 19 5
A getBitrixFields() 0 17 2
A normalizeBooleanForBitrix() 0 18 2
A normalizeValueForBitrix() 0 8 3
1
<?php
2
3
namespace BitrixToolkit\BitrixEntityMapper\Query;
4
5
use Bitrix\Main\Type\DateTime as BitrixDateTime;
6
use CIBlock;
7
use CIBlockProperty;
8
use DateTime;
9
use Exception;
10
use InvalidArgumentException;
11
use BitrixToolkit\BitrixEntityMapper\Annotation\Property\Field;
12
use BitrixToolkit\BitrixEntityMapper\Annotation\Property\Property;
13
use BitrixToolkit\BitrixEntityMapper\Annotation\Property\PropertyAnnotationInterface;
14
use BitrixToolkit\BitrixEntityMapper\Map\EntityMap;
15
use BitrixToolkit\BitrixEntityMapper\Map\PropertyMap;
16
17
class DataBuilder
18
{
19
    /**
20
     * @param EntityMap $entityMap
21
     * @param array $data
22
     * @return array
23
     * @throws InvalidArgumentException
24
     */
25 1
    public static function getBitrixFields(EntityMap $entityMap, array $data)
26
    {
27 1
        $fields = array_filter($entityMap->getProperties(), function (PropertyMap $propertyMap) {
28 1
            return $propertyMap->getAnnotation() instanceof Field;
29 1
        });
30
31 1
        $infoBlockType = $entityMap->getAnnotation()->getType();
32 1
        $infoBlockCode = $entityMap->getAnnotation()->getCode();
33 1
        $infoBlock = self::getBitrixInfoBlock($infoBlockType, $infoBlockCode);
34 1
        self::assert(!empty($infoBlock['ID']), "Не найден инфоблок с кодом $infoBlockCode и типом $infoBlockType.");
35
36 1
        $bitrixFields = ['IBLOCK_ID' => $infoBlock['ID']];
37 1
        foreach ($fields as $field) {
38 1
            $bitrixFields += self::getBitrixFieldEntry($field, $data);
39
        }
40
41 1
        return $bitrixFields;
42
    }
43
44
    /**
45
     * @param string $type
46
     * @param string $code
47
     * @return array
48
     */
49 1
    protected static function getBitrixInfoBlock($type, $code)
50
    {
51 1
        return CIBlock::GetList(null, [
52 1
            'TYPE' => $type,
53 1
            'CODE' => $code,
54 1
            'CHECK_PERMISSIONS' => 'N'
55 1
        ])->Fetch();
56
    }
57
58
    /**
59
     * @param mixed $term
60
     * @param string $msg
61
     * @throws InvalidArgumentException
62
     */
63 5
    protected static function assert($term, $msg)
64
    {
65 5
        if (!$term) {
66 1
            throw new InvalidArgumentException($msg);
67
        }
68
    }
69
70
    /**
71
     * @param PropertyMap $propertyMap
72
     * @param array $data
73
     * @return array
74
     * @throws InvalidArgumentException
75
     */
76 2
    public static function getBitrixFieldEntry(PropertyMap $propertyMap, array $data)
77
    {
78 2
        self::assert(
79 2
            $propertyMap->getAnnotation() instanceof Field,
80 2
            'Аннотация свойства должна быть экземпляром ' . Field::class . '.'
81 2
        );
82
83 2
        $key = $propertyMap->getAnnotation()->getCode();
84
85 2
        $valueKey = $propertyMap->getReflection()->getName();
86 2
        self::assert(array_key_exists($valueKey, $data), "Ключ $valueKey не найден в массиве.");
87 2
        $value = $data[$valueKey];
88
89 2
        if ($propertyMap->getAnnotation()->getType() === PropertyAnnotationInterface::TYPE_BOOLEAN) {
90 2
            $value = $value ? 'Y' : 'N';
91
        }
92
93 2
        return [$key => $value];
94
    }
95
96
    /**
97
     * @param EntityMap $entityMap
98
     * @param array $data
99
     * @param int $infoBlockId
100
     * @return array
101
     * @throws Exception
102
     */
103 1
    public static function getBitrixProperties(EntityMap $entityMap, array $data, $infoBlockId)
104
    {
105 1
        $properties = array_filter($entityMap->getProperties(), function (PropertyMap $propertyMap) {
106 1
            return $propertyMap->getAnnotation() instanceof Property;
107 1
        });
108
109 1
        $bitrixProperties = [];
110 1
        foreach ($properties as $property) {
111 1
            $bitrixProperties += self::getBitrixPropertyEntry($property, $data, $infoBlockId);
112
        }
113
114 1
        return $bitrixProperties;
115
    }
116
117
    /**
118
     * @param PropertyMap $propertyMap
119
     * @param array $data
120
     * @param int $infoBlockId
121
     * @return array
122
     * @throws InvalidArgumentException
123
     * @throws Exception
124
     */
125 4
    public static function getBitrixPropertyEntry(PropertyMap $propertyMap, array $data, $infoBlockId)
126
    {
127 4
        self::assert(
128 4
            $propertyMap->getAnnotation() instanceof Property,
129 4
            'Аннотация свойства должна быть экземпляром ' . Property::class . '.'
130 4
        );
131
132 4
        $key = $propertyMap->getAnnotation()->getCode();
133
134 4
        $valueKey = $propertyMap->getReflection()->getName();
135 4
        self::assert(array_key_exists($valueKey, $data), "Ключ $valueKey не найден в массиве.");
136 4
        $value = $data[$valueKey];
137
138 4
        if ($propertyMap->getAnnotation()->isMultiple()) {
139 2
            $value = array_map(function ($value) use ($propertyMap, $infoBlockId) {
140 2
                return self::normalizeValueForBitrix($propertyMap, $value, $infoBlockId);
141 2
            }, (array)$value);
142
        } else {
143 4
            $value = self::normalizeValueForBitrix($propertyMap, $value, $infoBlockId);
144
        }
145
146 4
        return [$key => $value];
147
    }
148
149
    /**
150
     * @param PropertyMap $propertyMap
151
     * @param mixed $value
152
     * @param int $infoBlockId
153
     * @return mixed
154
     * @throws Exception
155
     */
156 4
    protected static function normalizeValueForBitrix(PropertyMap $propertyMap, $value, $infoBlockId)
157
    {
158 4
        if ($propertyMap->getAnnotation()->getType() === Property::TYPE_BOOLEAN) {
159 2
            return self::normalizeBooleanForBitrix($propertyMap->getAnnotation()->getCode(), $value, $infoBlockId);
160 4
        } elseif ($propertyMap->getAnnotation()->getType() === Property::TYPE_DATETIME) {
161 3
            return self::normalizeDateTimeForBitrix($value);
162
        } else {
163 3
            return $value;
164
        }
165
    }
166
167
    /**
168
     * @param string $code
169
     * @param mixed $value
170
     * @param int $infoBlockId
171
     * @return bool
172
     * @throws InvalidArgumentException
173
     */
174 2
    protected static function normalizeBooleanForBitrix($code, $value, $infoBlockId)
175
    {
176 2
        if (!$value) {
177 1
            return false;
178
        }
179
180 1
        $yesEnum = CIBlockProperty::GetPropertyEnum($code, null, [
181 1
            'IBLOCK_ID' => $infoBlockId,
182 1
            'XML_ID' => 'Y',
183 1
            'VALUE' => 'Y'
184 1
        ])->Fetch();
185
186 1
        self::assert(
187 1
            !empty($yesEnum['ID']),
188 1
            'Не найден ID варианта ответа Y для булевого значения свойства ' . $code . '.'
189 1
        );
190
191 1
        return $yesEnum['ID'];
192
    }
193
194
    /**
195
     * @param mixed $value
196
     * @return BitrixDateTime|bool
197
     * @throws Exception
198
     */
199 3
    protected static function normalizeDateTimeForBitrix($value)
200
    {
201 3
        if (!$value) {
202 1
            return false;
203
        }
204
205 3
        if ($value instanceof BitrixDateTime) {
206 1
            return $value;
207
        }
208
209 3
        if ($value instanceof DateTime) {
210 2
            $dateTime = BitrixDateTime::createFromTimestamp($value->getTimestamp());
211 1
        } elseif (preg_match('/^-?\d+$/us', (string)$value)) {
212 1
            $dateTime = BitrixDateTime::createFromTimestamp($value);
213
        } else {
214 1
            $dateTime = BitrixDateTime::createFromPhp(new DateTime($value));
215
        }
216
217 3
        return $dateTime;
218
    }
219
}