1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
productproperty.php
См. документацию.
1<?php
2
3namespace Bitrix\Catalog\Controller;
4
5use Bitrix\Catalog;
6use Bitrix\Iblock\PropertyTable;
7use Bitrix\Main\Engine\Response\DataType\Page;
8use Bitrix\Main\Error;
9use Bitrix\Main\Result;
10use Bitrix\Main\UI\PageNavigation;
11
13{
14 use GetAction; // default getAction realization
15
16 private const LIST_NAME = 'PRODUCT_PROPERTIES';
17
18 private string $customUserType = '';
19
20 protected function getServiceListName(): string
21 {
22 return self::LIST_NAME;
23 }
24
25 // region Actions
26
30 public function getFieldsAction(): array
31 {
32 return [$this->getServiceItemName() => $this->getViewFields()];
33 }
34
43 public function listAction(
44 PageNavigation $pageNavigation,
45 array $select = [],
46 array $filter = [],
47 array $order = [],
48 bool $__calculateTotalCount = true
49 ): Page
50 {
51 if (!isset($filter['IBLOCK_ID']))
52 {
53 $filter['IBLOCK_ID'] = $this->getCatalogIds();
54 }
55 else
56 {
57 $iblockId = (int)($filter['IBLOCK_ID']);
58 if (!$this->isIblockCatalog($iblockId))
59 {
60 return new Page($this->getServiceListName(), [], 0);
61 }
62 }
63
64 return new Page(
65 $this->getServiceListName(),
66 $this->getList($select, $filter, $order, $pageNavigation),
67 $__calculateTotalCount ? $this->count($filter) : 0
68 );
69 }
70
75
80 public function addAction(array $fields): ?array
81 {
82 if (!$this->isIblockCatalog((int)$fields['IBLOCK_ID']))
83 {
84 $this->addError(new Error('The specified iblock is not a product catalog'));
85
86 return null;
87 }
88
89 $iblockPermissionsCheckResult = $this->checkIblockModifyPermission($fields['IBLOCK_ID']);
90 if (!$iblockPermissionsCheckResult->isSuccess())
91 {
92 $this->addErrors($iblockPermissionsCheckResult->getErrors());
93
94 return null;
95 }
96
97 $prepareResult = $this->prepareFieldsForAdd($fields);
98 if (!$prepareResult->isSuccess())
99 {
100 $this->addErrors($prepareResult->getErrors());
101
102 return null;
103 }
104 $fields = $prepareResult->getData();
105 unset($prepareResult);
106
107 $this->processCustomTypesBeforeAdd($fields);
108
109 $property = new \CIBlockProperty();
110 $addResult = $property->Add($fields);
111 if (!$addResult)
112 {
113 $error = $property->getLastError();
114 if ($error !== '')
115 {
116 $this->addError(new Error($error));
117 }
118 else
119 {
120 $this->addError(new Error('Error adding property'));
121 }
122
123 return null;
124 }
125
126 $this->processCustomTypesAfterAdd((int)$addResult);
127
128 return [
129 $this->getServiceItemName() => $this->get($addResult),
130 ];
131 }
132
138 public function updateAction(int $id, array $fields): ?array
139 {
140 $existsResult = $this->exists($id);
141 if (!$existsResult->isSuccess())
142 {
143 $this->addErrors($existsResult->getErrors());
144
145 return null;
146 }
147
148 $prepareResult = $this->prepareFieldsForUpdate($id, $fields);
149 if (!$prepareResult->isSuccess())
150 {
151 $this->addErrors($prepareResult->getErrors());
152
153 return null;
154 }
155 $fields = $prepareResult->getData();
156 unset($prepareResult);
157
158 $property = new \CIBlockProperty();
159 $updateResult = $property->Update($id, $fields);
160 if (!$updateResult)
161 {
162 $error = $property->getLastError();
163 if ($error !== '')
164 {
165 $this->addError(new Error($error));
166 }
167 else
168 {
169 $this->addError(new Error('Error updating product property'));
170 }
171
172 return null;
173 }
174
175 return [
176 $this->getServiceItemName() => $this->get($id),
177 ];
178 }
179
184 public function deleteAction(int $id): ?bool
185 {
186 $existsResult = $this->exists($id);
187 if (!$existsResult->isSuccess())
188 {
189 $this->addErrors($existsResult->getErrors());
190
191 return null;
192 }
193
195 $application->ResetException();
196
197 $deleteResult = \CIBlockProperty::Delete($id);
198 if (!$deleteResult)
199 {
200 $exception = $application->GetException();
201 if ($exception)
202 {
203 $this->addError(new Error($exception->GetString()));
204 }
205 else
206 {
207 $this->addError(new Error('Error deleting product property'));
208 }
209
210 return null;
211 }
212
213 return true;
214 }
215
216 // endregion
217
221 public function getEntityTable()
222 {
223 return PropertyTable::class;
224 }
225
229 protected function exists($id): Result
230 {
231 $result = new Result();
232 $id = (int)$id;
233 if ($id <= 0)
234 {
235 $result->addError($this->getErrorEntityNotExists());
236
237 return $result;
238 }
239
240 $property = PropertyTable::getRow([
241 'select' => [
242 'ID',
243 'IBLOCK_ID',
244 ],
245 'filter' => [
246 '=ID' => $id,
247 ],
248 'cache' => [
249 'ttl' => 86400,
250 ],
251 ]);
252
253 if (!$property)
254 {
255 $result->addError($this->getErrorEntityNotExists());
256
257 return $result;
258 }
259
260 if (!$this->isIblockCatalog((int)$property['IBLOCK_ID']))
261 {
263
264 return $result;
265 }
266
267 return $result;
268 }
269
270 private function processCustomTypesBeforeAdd(array &$fields): void
271 {
272 $this->customUserType = '';
273 if ($this->isPseudoCheckboxPropertyType($fields['PROPERTY_TYPE'], $fields['USER_TYPE']))
274 {
276 $this->customUserType = Enum::PROPERTY_USER_TYPE_BOOL_ENUM;
277 unset($fields['USER_TYPE']);
278 }
279 }
280
281 private function processCustomTypesAfterAdd(int $id): void
282 {
283 if ($this->customUserType === Enum::PROPERTY_USER_TYPE_BOOL_ENUM)
284 {
286 'PROPERTY_ID' => $id,
287 'VALUE' => Catalog\RestView\Product::BOOLEAN_VALUE_YES,
288 ]);
289 }
290 $this->customUserType = '';
291 }
292
293 private function isPseudoCheckboxPropertyType(string $baseType, ?string $userType): bool
294 {
295 return
296 $baseType === PropertyTable::TYPE_LIST
298 ;
299 }
300
302 {
303 $result = new Result();
304
305 $propertyTypeDescr = $this->getPropertyTypeDescription($fields);
306 if ($propertyTypeDescr === null)
307 {
308 $result->addError($this->getErrorPropertyInvalidType());
309
310 return $result;
311 }
312
313 $property = $propertyTypeDescr['PROPERTY'];
314 $fields['PROPERTY_TYPE'] = $propertyTypeDescr['PROPERTY_TYPE'];
315 $fields['USER_TYPE'] = $propertyTypeDescr['USER_TYPE'];
316 if ($fields['USER_TYPE'] === null)
317 {
318 $fields['USER_TYPE'] = false; // for \CIBlockProperty - old api use false as null database field value
319 $fields['USER_TYPE_SETTINGS'] = false;
320 }
321 elseif ($property === null)
322 {
323 $fields['USER_TYPE_SETTINGS'] = false;
324 }
325 else
326 {
327 if (empty($fields['USER_TYPE_SETTINGS']))
328 {
329 $fields['USER_TYPE_SETTINGS'] = false;
330 }
331 elseif (!is_array($fields['USER_TYPE_SETTINGS']))
332 {
333 $result->addError($this->getErrorInvalidCustomTypeSettings());
334
335 return $result;
336 }
337 else
338 {
339 if (!$this->validateUserSettings($fields['USER_TYPE_SETTINGS']))
340 {
341 $result->addError($this->getErrorInvalidCustomTypeSettings());
342
343 return $result;
344 }
345 }
346 }
347
348 $result->setData($fields);
349
350 return $result;
351 }
352
353 protected function prepareFieldsForUpdate(int $id, array $fields): Result
354 {
355 $result = new Result();
356
357 $propertyTypeExists = array_key_exists('PROPERTY_TYPE', $fields);
358 $userTypeExists = array_key_exists('USER_TYPE', $fields);
359 $userTypeSettingsExists = array_key_exists('USER_TYPE_SETTINGS', $fields);
360
361 if (
362 $propertyTypeExists
363 || $userTypeExists
364 || $userTypeSettingsExists
365 )
366 {
367 $compiledPropertyType = $fields;
368 if (
369 !$propertyTypeExists
370 || !$userTypeExists
371 )
372 {
373 $row = $this->getPropertyById($id);
374 if ($row === null)
375 {
376 $result->addError($this->getErrorEntityNotExists());
377
378 return $result;
379 }
380
381 $compiledPropertyType = [
382 'PROPERTY_TYPE' => $fields['PROPERTY_TYPE'] ?? $row['PROPERTY_TYPE'],
383 'USER_TYPE' => $fields['USER_TYPE'] ?? $row['USER_TYPE'],
384 ];
385 unset($row);
386 }
387
388 $propertyTypeDescr = $this->getPropertyTypeDescription($compiledPropertyType);
389 if ($propertyTypeDescr === null)
390 {
391 $result->addError($this->getErrorPropertyInvalidType());
392
393 return $result;
394 }
395
396 $property = $propertyTypeDescr['PROPERTY'];
397 $fields['PROPERTY_TYPE'] = $propertyTypeDescr['PROPERTY_TYPE'];
398 $fields['USER_TYPE'] = $propertyTypeDescr['USER_TYPE'];
399
400 if ($fields['USER_TYPE'] === null)
401 {
402 $fields['USER_TYPE'] = false; // for \CIBlockProperty - old api use false as null database field value
403 $fields['USER_TYPE_SETTINGS'] = false;
404 }
405 elseif ($property === null)
406 {
407 $fields['USER_TYPE_SETTINGS'] = false;
408 }
409 elseif ($userTypeSettingsExists)
410 {
411 if (empty($fields['USER_TYPE_SETTINGS']))
412 {
413 $fields['USER_TYPE_SETTINGS'] = false;
414 }
415 elseif (!is_array($fields['USER_TYPE_SETTINGS']))
416 {
417 $result->addError($this->getErrorInvalidCustomTypeSettings());
418
419 return $result;
420 }
421 else
422 {
423 if (!$this->validateUserSettings($fields['USER_TYPE_SETTINGS']))
424 {
425 $result->addError($this->getErrorInvalidCustomTypeSettings());
426
427 return $result;
428 }
429 }
430 }
431 }
432
433 $result->setData($fields);
434
435 return $result;
436 }
437
439 {
440 $baseTypeList = [
447 ];
448
449 $baseType = $fields['PROPERTY_TYPE'] ?? null;
450 if (!is_string($baseType))
451 {
452 return null;
453 }
454 if (!isset($baseTypeList[$baseType]))
455 {
456 return null;
457 }
458
459 $userType = $fields['USER_TYPE'] ?? null;
460 if ($userType === '' || $userType === false)
461 {
462 $userType = null;
463 }
464 if (!is_string($userType) && $userType !== null)
465 {
466 return null;
467 }
468
469 $property = null;
470 if (
471 $userType !== null
472 && !$this->isPseudoCheckboxPropertyType($baseType, $userType)
473 )
474 {
475 $property = \CIBlockProperty::GetUserType($userType);
476 if (!$property)
477 {
478 return null;
479 }
480
481 if ($property['PROPERTY_TYPE'] !== $baseType)
482 {
483 return null;
484 }
485 }
486
487 return [
488 'PROPERTY_TYPE' => $baseType,
489 'USER_TYPE' => $userType,
490 'PROPERTY' => $property,
491 ];
492 }
493
494 protected function validateUserSettings(array $row): bool
495 {
496 if (empty($row))
497 {
498 return true;
499 }
500
501 $result = true;
502 foreach ($row as $field)
503 {
504 if (is_array($field))
505 {
506 if (!$this->validateUserSettings($field))
507 {
508 $result = false;
509 break;
510 }
511 }
512 elseif (!is_scalar($field) && $field !== null)
513 {
514 $result = false;
515 break;
516 }
517 }
518
519 return $result;
520 }
521
523 {
524 return new Error('Invalid custom property type settings specified');
525 }
526}
static getApplication()
Определения controller.php:56
const PROPERTY_USER_TYPE_BOOL_ENUM
Определения enum.php:18
prepareFieldsForAdd(array $fields)
Определения productproperty.php:301
listAction(PageNavigation $pageNavigation, array $select=[], array $filter=[], array $order=[], bool $__calculateTotalCount=true)
Определения productproperty.php:43
prepareFieldsForUpdate(int $id, array $fields)
Определения productproperty.php:353
getPropertyTypeDescription(array $fields)
Определения productproperty.php:438
updateAction(int $id, array $fields)
Определения productproperty.php:138
const TYPE_ELEMENT
Определения propertytable.php:68
const TYPE_FILE
Определения propertytable.php:67
const TYPE_STRING
Определения propertytable.php:65
const TYPE_LIST
Определения propertytable.php:70
const TYPE_SECTION
Определения propertytable.php:69
const TYPE_NUMBER
Определения propertytable.php:66
Определения error.php:15
static Add($arFields)
Определения iblockpropertyenum.php:127
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$iblockId
Определения iblock_catalog_edit.php:30
$select
Определения iblock_catalog_list.php:194
$filter
Определения iblock_catalog_list.php:54
$application
Определения bitrix.php:23
getList(array $select, array $filter, array $order, PageNavigation $pageNavigation=null)
trait GetAction
Определения getaction.php:8
Определения aliases.php:54
$order
Определения payment.php:8
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$error
Определения subscription_card_product.php:20
$fields
Определения yandex_run.php:501