Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
SaveAction.php
1<?php
2
4
13use CIBlockProperty;
14use CIBlockRights;
15
19final class SaveAction extends Action
20{
30 public function run(int $propertyId, int $iblockId, array $fields): ?array
31 {
32 if (!$this->checkWritePermissions($iblockId))
33 {
34 $this->errorCollection->setError(
35 new Error(Loc::getMessage('IBLOCK_CONTROLLER_PROPERTY_ACTION_SAVE_ERROR_ACCESS_DENIED'))
36 );
37
38 return null;
39 }
40
41 $fields = $this->cleanEntityFields($fields);
42 if (empty($fields))
43 {
44 $this->errorCollection->setError(
45 new Error(Loc::getMessage('IBLOCK_CONTROLLER_PROPERTY_ACTION_SAVE_ERROR_EMPTY_REQUEST'))
46 );
47
48 return null;
49 }
50
51 $oldFields = null;
52 if ($propertyId > 0)
53 {
54 $oldFields = $this->getPropertyFields($propertyId, $iblockId);
55 if (!$oldFields)
56 {
57 $this->errorCollection->setError(
58 new Error(Loc::getMessage('IBLOCK_CONTROLLER_PROPERTY_ACTION_SAVE_ERROR_NOT_FOUND'))
59 );
60
61 return null;
62 }
63 }
64
65 $fields['IBLOCK_ID'] = $iblockId;
66 $fields = $this->processUserTypeSettingsFields($fields, $oldFields);
67 $fields = $this->processFeatureFields($fields, $oldFields);
68 $fields = $this->processEnumFields($fields, $oldFields);
69
70 if (\CIBlock::GetArrayByID($iblockId, 'SECTION_PROPERTY') !== 'Y')
71 {
72 if (($fields['SMART_FILTER'] ?? 'N') === 'Y')
73 {
74 $iblock = new \CIBlock;
75 $iblock->Update($iblockId, ['SECTION_PROPERTY' => 'Y']);
76 unset($iblock);
77 }
78 }
79
80 $entity = new CIBlockProperty();
81 if ($propertyId > 0)
82 {
83 $result = $entity->Update($propertyId, $fields);
84 }
85 else
86 {
87 $result = $entity->Add($fields);
88 if ($result !== false)
89 {
90 $propertyId = (int)$result;
91 }
92 }
93
94 if (!$result)
95 {
96 if ($entity->LAST_ERROR)
97 {
98 $this->errorCollection->setError(
99 new Error($entity->LAST_ERROR)
100 );
101 }
102
103 return null;
104 }
105
106 return [
107 'id' => $propertyId,
108 ];
109 }
110
118 private function checkWritePermissions(int $iblockId): bool
119 {
120 return CIBlockRights::UserHasRightTo($iblockId, $iblockId, 'iblock_edit');
121 }
122
130 private function convertPublicFeature(array $fields): array
131 {
133 {
134 return $fields;
135 }
136
137 $features = $fields['FEATURES'] ?? [];
138 if (!is_array($features))
139 {
140 $features = [];
141 }
142
143 $listIndex = PropertyFeature::getIndex([
144 'MODULE_ID' => 'iblock',
146 ]);
147 $detailIndex = PropertyFeature::getIndex([
148 'MODULE_ID' => 'iblock',
150 ]);
151
152 $features[$listIndex] = $fields[FriendlyPropertyProvider::FEATURE_PUBLIC_PROPERTY];
153 $features[$detailIndex] = $fields[FriendlyPropertyProvider::FEATURE_PUBLIC_PROPERTY];
155
156 $fields['FEATURES'] = $features;
157
158 return $fields;
159 }
160
169 private function processFeatureFields(array $fields, ?array $oldFields): array
170 {
171 $fields = $this->convertPublicFeature($fields);
172
173 $features = $fields['FEATURES'] ?? null;
174 if (!isset($features) || !is_array($features))
175 {
176 return $fields;
177 }
178
179 $result = [];
180
181 $currentFeatures = [];
182 if (isset($oldFields['FEATURES']))
183 {
184 foreach ($oldFields['FEATURES'] as $index => $isEnabled)
185 {
186 $currentFeatures[$index] = $isEnabled;
187 }
188 }
189
190 foreach ($features as $index => $isEnabled)
191 {
192 if (isset($currentFeatures[$index]))
193 {
194 unset($currentFeatures[$index]);
195 }
196
197 $feature = PropertyFeature::parseIndex((string)$index);
198 if (isset($feature))
199 {
200 $feature['IS_ENABLED'] = $isEnabled === 'Y' ? 'Y' : 'N';
201 $result[] = $feature;
202 }
203 }
204
205 foreach ($currentFeatures as $index => $isEnabled)
206 {
207 $feature = PropertyFeature::parseIndex($index);
208 if (isset($feature))
209 {
210 $feature['IS_ENABLED'] = $isEnabled === 'Y' ? 'Y' : 'N';
211 $result[] = $feature;
212 }
213 }
214
215 $fields['FEATURES'] = $result;
216
217 return $fields;
218 }
219
228 private function processUserTypeSettingsFields(array $fields, ?array $oldFields): array
229 {
230 $fields = $this->parseUserType($fields);
231
232 if (!isset($fields['PROPERTY_TYPE']) && isset($oldFields))
233 {
234 $fields['USER_TYPE'] = $oldFields['USER_TYPE'];
235 $fields['PROPERTY_TYPE'] = $oldFields['PROPERTY_TYPE'];
236 }
237
238 if (empty($fields['USER_TYPE']))
239 {
240 $fields['USER_TYPE_SETTINGS'] = false;
241 }
242 // append other settings
243 elseif (
244 isset($fields['USER_TYPE_SETTINGS'], $oldFields['USER_TYPE_SETTINGS'])
245 && is_array($fields['USER_TYPE_SETTINGS'])
246 )
247 {
248 $fields['USER_TYPE_SETTINGS'] += $oldFields['USER_TYPE_SETTINGS'];
249 }
250
251 return $fields;
252 }
253
261 private function processEnumFields(array $fields): array
262 {
263 // set one DEF value
264 if (
265 $fields['PROPERTY_TYPE'] === PropertyTable::TYPE_LIST
266 && isset($fields['VALUES'])
267 && is_array($fields['VALUES'])
268 )
269 {
270 $existDef = false;
271 foreach ($fields['VALUES'] as &$item)
272 {
273 if (isset($item['DEF']) && $item['DEF'] === 'Y')
274 {
275 if ($existDef)
276 {
277 $item['DEF'] = 'N';
278 }
279 else
280 {
281 $existDef = true;
282 }
283 }
284 }
285 unset($item);
286 }
287
288 return $fields;
289 }
290
298 private function parseUserType(array $fields): array
299 {
300 if (isset($fields['PROPERTY_TYPE']))
301 {
302 $parts = explode(':', $fields['PROPERTY_TYPE']);
303 if (count($parts) === 2)
304 {
305 $fields['PROPERTY_TYPE'] = $parts[0];
306 $fields['USER_TYPE'] = $parts[1];
307 }
308 else
309 {
310 $fields['USER_TYPE'] = false; // `NULL` for old $DB
311 }
312 }
313
314 return $fields;
315 }
316
324 private function cleanEntityFields(array $fields): array
325 {
326 $availableFields = array_fill_keys([
327 'PROPERTY_TYPE',
328 'ACTIVE',
329 'SORT',
330 'NAME',
331 'CODE',
332 'MULTIPLE',
333 'IS_REQUIRED',
334 'SEARCHABLE',
335 'FILTRABLE',
336 'WITH_DESCRIPTION',
337 'MULTIPLE_CNT',
338 'HINT',
339 'SECTION_PROPERTY',
340 'SMART_FILTER',
341 'DISPLAY_TYPE',
342 'DISPLAY_EXPANDED',
343 'FILTER_HINT',
344 'ROW_COUNT',
345 'COL_COUNT',
346 'FILE_TYPE',
347 'LINK_IBLOCK_ID',
348 'LIST_TYPE',
349 'DEFAULT_VALUE',
350 'XML_ID',
351 'VALUES',
352 'FEATURES',
353 'USER_TYPE_SETTINGS',
354 'IS_PUBLIC',
355 ], true);
356
357 return array_intersect_key($fields, $availableFields);
358 }
359
368 private function getPropertyFields(int $propertyId, int $iblockId): ?array
369 {
370 $fields = PropertyTable::getRow([
371 'filter' => [
372 '=ID' => $propertyId,
373 '=IBLOCK_ID' => $iblockId,
374 ],
375 ]);
376 if (!$fields)
377 {
378 return null;
379 }
380
381 // arrayable user settings
382 $fields['USER_TYPE_SETTINGS'] = $fields['USER_TYPE_SETTINGS_LIST'];
383 unset($fields['USER_TYPE_SETTINGS_LIST']);
384
385 // append section link
386 $sectionProperty = SectionPropertyTable::getRow([
387 'select' => [
388 'SMART_FILTER',
389 'DISPLAY_TYPE',
390 'DISPLAY_EXPANDED',
391 'FILTER_HINT',
392 ],
393 'filter' => [
394 '=IBLOCK_ID' => $iblockId,
395 '=PROPERTY_ID' => $propertyId,
396 ],
397 ]);
398 if (is_array($sectionProperty))
399 {
400 $fields += $sectionProperty;
401 }
402
403 // append features
404 $fields['FEATURES'] = [];
406 'select' => [
407 'ID',
408 'MODULE_ID',
409 'FEATURE_ID',
410 'IS_ENABLED',
411 ],
412 'filter' => [
413 '=PROPERTY_ID' => $propertyId,
414 ]
415 ]);
416 foreach ($rows as $row)
417 {
418 $index = PropertyFeature::getIndex($row);
419 $fields["FEATURES"][$index] = $row['IS_ENABLED'];
420 }
421
422 return $fields;
423 }
424}
run(int $propertyId, int $iblockId, array $fields)
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getRow(array $parameters)
static getList(array $parameters=array())