23 private array $productFieldNames = [];
31 $this->loadFieldNames();
33 return array_merge($this->getFieldsIBlockElement(), $this->getFieldsCatalogProduct());
43 $r = parent::prepareFieldAttributs($info, $attributs);
45 $r[
'NAME'] = $info[
'NAME'];
46 if ($info[
'TYPE'] === DataType::TYPE_PRODUCT_PROPERTY)
48 $r[
'IS_DYNAMIC'] =
true;
49 $r[
'IS_MULTIPLE'] = in_array(Attributes::MULTIPLE, $attributs,
true);
50 $r[
'PROPERTY_TYPE'] = $info[
'PROPERTY_TYPE'];
51 $r[
'USER_TYPE'] = $info[
'USER_TYPE'];
52 if (isset($info[
'VALUES']))
54 $r[
'VALUES'] = $info[
'VALUES'];
64 private function getFieldsIBlockElement(): array
68 'TYPE' => DataType::TYPE_INT,
74 'TYPE' => DataType::TYPE_INT,
77 'TYPE' => DataType::TYPE_DATETIME,
80 'TYPE' => DataType::TYPE_INT,
83 'TYPE' => DataType::TYPE_DATETIME,
89 'TYPE' => DataType::TYPE_CHAR,
91 'DATE_ACTIVE_FROM' => [
92 'TYPE' => DataType::TYPE_DATETIME,
95 'TYPE' => DataType::TYPE_DATETIME,
98 'TYPE' => DataType::TYPE_STRING,
100 Attributes::REQUIRED_ADD,
104 'TYPE' => DataType::TYPE_STRING,
107 'TYPE' => DataType::TYPE_INT,
110 'TYPE' => DataType::TYPE_STRING,
112 'PREVIEW_TEXT_TYPE' => [
113 'TYPE' => DataType::TYPE_STRING,
115 'PREVIEW_PICTURE' => [
116 'TYPE' => DataType::TYPE_FILE,
119 'TYPE' => DataType::TYPE_STRING,
121 'DETAIL_TEXT_TYPE' => [
122 'TYPE' => DataType::TYPE_STRING,
124 'DETAIL_PICTURE' => [
125 'TYPE' => DataType::TYPE_FILE,
128 'TYPE' => DataType::TYPE_INT,
130 Attributes::REQUIRED,
131 Attributes::IMMUTABLE,
134 'IBLOCK_SECTION_ID' => [
135 'TYPE' => DataType::TYPE_INT,
138 'TYPE' => DataType::TYPE_STRING,
142 return $this->fillFieldNames($fieldList);
149 private function getFieldsIBlockPropertyValuesByFilter(array $filter):
Result
154 $iblockId = (int)($filter[
'IBLOCK_ID'] ?? 0);
158 $result->addError(
new Error(
'parameter - iblockId is empty'));
161 if ($result->isSuccess())
163 $catalogInfo = \CCatalogSku::GetInfoByOfferIBlock($iblockId);
164 $skuPropertyId = $catalogInfo[
'SKU_PROPERTY_ID'] ??
null;
167 $allowedTypes = array_fill_keys(self::getUserType(),
true);
173 $iterator = PropertyTable::getList([
187 '=IBLOCK_ID' => $iblockId,
196 while ($property = $iterator->fetch())
198 $property[
'ID'] = (int)$property[
'ID'];
199 $userType = (string)$property[
'USER_TYPE'];
202 && !isset($allowedTypes[$property[
'PROPERTY_TYPE'] .
':' . $userType])
209 'TYPE' => DataType::TYPE_PRODUCT_PROPERTY,
210 'PROPERTY_TYPE' => $property[
'PROPERTY_TYPE'],
211 'USER_TYPE' => $property[
'USER_TYPE'],
212 'ATTRIBUTES' => [Attributes::DYNAMIC],
213 'NAME' => $property[
'NAME'],
216 if ($property[
'MULTIPLE'] ===
'Y')
218 $info[
'ATTRIBUTES'][] = Attributes::MULTIPLE;
220 if ($property[
'IS_REQUIRED'] ===
'Y')
222 $info[
'ATTRIBUTES'][] = Attributes::REQUIRED;
226 $property[
'PROPERTY_TYPE'] === PropertyTable::TYPE_LIST
228 && $property[
'MULTIPLE'] ===
'N'
232 '=PROPERTY_ID' => $property[
'ID'],
234 if (Iblock\PropertyEnumerationTable::getCount($enumFilter, $cache) === 1)
236 $variant = Iblock\PropertyEnumerationTable::getRow([
242 'filter' => $enumFilter,
245 $info[
'BOOLEAN_VALUE_YES'] = [
246 'ID' => $variant[
'ID'],
247 'VALUE' => $variant[
'VALUE'],
252 if ($this->isPropertyBoolean($info))
254 $info[
'USER_TYPE'] = Catalog\Controller\Enum::PROPERTY_USER_TYPE_BOOL_ENUM;
257 $canonicalName =
'PROPERTY_' . $property[
'ID'];
258 if ($property[
'ID'] === $skuPropertyId)
260 $info[
'CANONICAL_NAME'] = $canonicalName;
261 $fieldsInfo[
'PARENT_ID'] = $info;
265 $fieldsInfo[$canonicalName] = $info;
267 unset($canonicalName);
269 unset($property, $iterator);
271 $fieldsInfo[
'PROPERTY_*'] = [
272 'TYPE' => DataType::TYPE_PRODUCT_PROPERTY,
274 Attributes::READONLY,
279 $result->setData($fieldsInfo);
288 private function getFieldsCatalogProductCommonFields(): array
292 'TYPE' => DataType::TYPE_INT,
294 Attributes::READONLY,
298 'TYPE' => DataType::TYPE_DATETIME,
301 'TYPE' => DataType::TYPE_CHAR,
304 'TYPE' => DataType::TYPE_INT,
306 Attributes::READONLY,
310 'TYPE' => DataType::TYPE_CHAR,
312 Attributes::READONLY,
317 return $this->fillFieldNames($fieldList);
324 $iblockData = \CCatalogSku::GetInfoByIBlock($iblockId);
325 if (empty($iblockData))
327 $result->addError(
new Error(
'iblock is not catalog'));
331 $allowedTypes = self::getProductTypes($iblockData[
'CATALOG_TYPE']);
333 if (!isset($allowedTypes[$productTypeId]))
335 $result->addError(
new Error(
'productType is not allowed for this catalog'));
346 private function getFieldsCatalogProductByFilter(array $filter):
Result
350 $iblockId = (int)($filter[
'IBLOCK_ID'] ?? 0);
351 $productTypeId = (int)($filter[
'PRODUCT_TYPE'] ?? 0);
355 $result->addError(
new Error(
'parameter - iblockId is empty'));
358 if ($productTypeId <= 0)
360 $result->addError(
new Error(
'parameter - productType is empty'));
363 if ($result->isSuccess())
365 $r = $this->isAllowedProductTypeByIBlockId($productTypeId, $iblockId);
368 $result->setData($this->getFieldsCatalogProductByType($productTypeId));
372 $result->addErrors($r->getErrors());
382 private function getFieldsCatalogProduct(): array
386 'TYPE' => DataType::TYPE_INT,
388 Attributes::READONLY,
392 'TYPE' => DataType::TYPE_CHAR,
394 Attributes::READONLY,
398 'TYPE' => DataType::TYPE_CHAR,
400 Attributes::READONLY,
404 'TYPE' => DataType::TYPE_FLOAT,
406 'QUANTITY_RESERVED' => [
407 'TYPE' => DataType::TYPE_FLOAT,
409 'QUANTITY_TRACE' => [
410 'TYPE' => DataType::TYPE_CHAR,
413 'TYPE' => DataType::TYPE_CHAR,
416 'TYPE' => DataType::TYPE_CHAR,
419 'TYPE' => DataType::TYPE_INT,
422 'TYPE' => DataType::TYPE_CHAR,
424 'PURCHASING_PRICE' => [
425 'TYPE' => DataType::TYPE_FLOAT,
427 'PURCHASING_CURRENCY' => [
428 'TYPE' => DataType::TYPE_STRING,
431 'TYPE' => DataType::TYPE_CHAR,
434 'TYPE' => DataType::TYPE_FLOAT,
437 'TYPE' => DataType::TYPE_FLOAT,
440 'TYPE' => DataType::TYPE_FLOAT,
443 'TYPE' => DataType::TYPE_FLOAT,
446 'TYPE' => DataType::TYPE_INT,
448 'RECUR_SCHEME_LENGTH' => [
449 'TYPE' => DataType::TYPE_INT,
451 'RECUR_SCHEME_TYPE' => [
452 'TYPE' => DataType::TYPE_CHAR,
454 'TRIAL_PRICE_ID' => [
455 'TYPE' => DataType::TYPE_INT,
458 'TYPE' => DataType::TYPE_CHAR,
462 if (Catalog\
Config\State::isUsedInventoryManagement())
468 'PURCHASING_CURRENCY',
471 foreach ($lockFields as $fieldName)
473 if (!isset($fieldList[$fieldName][
'ATTRIBUTES']))
475 $fieldList[$fieldName][
'ATTRIBUTES'] = [
476 Attributes::READONLY,
481 $fieldList[$fieldName][
'ATTRIBUTES'][] = Attributes::READONLY;
482 $fieldList[$fieldName][
'ATTRIBUTES'] = array_unique($fieldList[$fieldName][
'ATTRIBUTES']);
487 return $this->fillFieldNames($fieldList);
494 private function getFieldsCatalogProductByType(
int $id): array
499 $r = $this->getFieldsCatalogProductByTypeService();
502 $r = $this->getFieldsCatalogProductByTypeProduct();
505 $r = $this->getFieldsCatalogProductByTypeSet();
509 $r = $this->getFieldsCatalogProductByTypeSKU();
513 $r = $this->getFieldsCatalogProductByTypeOffer();
526 private function getFieldsCatalogProductByTypeService(): array
530 'TYPE' => DataType::TYPE_CHAR,
534 return $this->fillFieldNames($fieldList);
540 private function getFieldsCatalogProductByTypeProduct(): array
544 'TYPE' => DataType::TYPE_CHAR,
546 Attributes::READONLY,
549 'PURCHASING_PRICE' => [
550 'TYPE' => DataType::TYPE_STRING,
552 'PURCHASING_CURRENCY' => [
553 'TYPE' => DataType::TYPE_STRING,
556 'TYPE' => DataType::TYPE_INT,
559 'TYPE' => DataType::TYPE_CHAR,
562 'TYPE' => DataType::TYPE_FLOAT,
564 'QUANTITY_RESERVED' => [
565 'TYPE' => DataType::TYPE_FLOAT,
568 'TYPE' => DataType::TYPE_INT,
570 'QUANTITY_TRACE' => [
571 'TYPE' => DataType::TYPE_CHAR,
574 'TYPE' => DataType::TYPE_CHAR,
576 'NEGATIVE_AMOUNT_TRACE' => [
577 'TYPE' => DataType::TYPE_CHAR,
579 Attributes::READONLY,
583 'TYPE' => DataType::TYPE_CHAR,
586 'TYPE' => DataType::TYPE_FLOAT,
589 'TYPE' => DataType::TYPE_FLOAT,
592 'TYPE' => DataType::TYPE_FLOAT,
595 'TYPE' => DataType::TYPE_FLOAT,
599 return $this->fillFieldNames($fieldList);
605 private function getFieldsCatalogProductByTypeSKU(): array
609 'TYPE' => DataType::TYPE_CHAR,
611 Attributes::READONLY,
616 return $this->fillFieldNames($fieldList);
622 private function getFieldsCatalogProductByTypeOffer(): array
624 return $this->getFieldsCatalogProductByTypeProduct();
630 private function getFieldsCatalogProductByTypeSet(): array
634 'TYPE' => DataType::TYPE_CHAR,
636 Attributes::READONLY,
639 'PURCHASING_PRICE' => [
640 'TYPE' => DataType::TYPE_STRING,
642 'PURCHASING_CURRENCY' => [
643 'TYPE' => DataType::TYPE_STRING,
646 'TYPE' => DataType::TYPE_INT,
649 'TYPE' => DataType::TYPE_CHAR,
652 'TYPE' => DataType::TYPE_FLOAT,
654 Attributes::READONLY,
658 'TYPE' => DataType::TYPE_INT,
660 Attributes::READONLY,
663 'QUANTITY_TRACE' => [
664 'TYPE' => DataType::TYPE_CHAR,
666 Attributes::READONLY,
670 'TYPE' => DataType::TYPE_CHAR,
672 Attributes::READONLY,
675 'NEGATIVE_AMOUNT_TRACE' => [
676 'TYPE' => DataType::TYPE_CHAR,
678 Attributes::READONLY,
682 'TYPE' => DataType::TYPE_CHAR,
685 'TYPE' => DataType::TYPE_FLOAT,
687 Attributes::READONLY,
691 'TYPE' => DataType::TYPE_FLOAT,
694 'TYPE' => DataType::TYPE_FLOAT,
697 'TYPE' => DataType::TYPE_FLOAT,
701 return $this->fillFieldNames($fieldList);
712 $iblockId = (int)($filter[
'IBLOCK_ID'] ?? 0);
713 $productTypeId = (int)($filter[
'PRODUCT_TYPE'] ?? 0);
716 $result->addError(
new Error(
'parameter - iblockId is empty'));
719 if ($productTypeId <= 0)
721 $result->addError(
new Error(
'parameter - productType is empty'));
724 if ($result->isSuccess())
726 $this->loadFieldNames();
731 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter([
'IBLOCK_ID' => $iblockId]);
733 if ($propertyValues->isSuccess())
735 $properties = $propertyValues->getData();
736 unset($properties[
'PROPERTY_*']);
738 unset($propertyValues);
741 $this->getFieldsIBlockElement(),
743 $this->getFieldsCatalogProductCommonFields(),
744 $this->getFieldsCatalogProductByType($productTypeId)
751 $result->addErrors($r->getErrors());
762 private static function getProductTypes($catalogType): array
765 switch ($catalogType)
767 case \CCatalogSku::TYPE_CATALOG:
774 case \CCatalogSku::TYPE_OFFERS:
780 case \CCatalogSku::TYPE_FULL:
789 case \CCatalogSku::TYPE_PRODUCT:
806 private static function getUserType(): array
809 PropertyTable::TYPE_STRING .
':' . PROPERTYTable::USER_TYPE_DATE,
810 PropertyTable::TYPE_STRING .
':' . PropertyTable::USER_TYPE_DATETIME,
811 PropertyTable::TYPE_STRING .
':' . PropertyTable::USER_TYPE_HTML,
812 PropertyTable::TYPE_STRING .
':' . PropertyTable::USER_TYPE_XML_ID,
813 PropertyTable::TYPE_STRING .
':' . PropertyTable::USER_TYPE_DIRECTORY,
814 PropertyTable::TYPE_STRING .
':Money',
815 PropertyTable::TYPE_STRING .
':map_yandex',
816 PropertyTable::TYPE_STRING .
':map_google',
817 PropertyTable::TYPE_STRING .
':employee',
818 PropertyTable::TYPE_STRING .
':ECrm',
819 PropertyTable::TYPE_STRING .
':UserID',
821 PropertyTable::TYPE_NUMBER .
':' . PropertyTable::USER_TYPE_SEQUENCE,
823 PropertyTable::TYPE_ELEMENT .
':' . PropertyTable::USER_TYPE_ELEMENT_LIST,
824 PropertyTable::TYPE_ELEMENT .
':' . PropertyTable::USER_TYPE_ELEMENT_AUTOCOMPLETE,
825 PropertyTable::TYPE_ELEMENT .
':' . PropertyTable::USER_TYPE_SKU,
827 PropertyTable::TYPE_SECTION .
':' . PropertyTable::USER_TYPE_SECTION_AUTOCOMPLETE,
840 $iblockId = (int)($arguments[
'filter'][
'IBLOCK_ID'] ?? 0);
842 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter([
'IBLOCK_ID' => $iblockId]);
843 $fieldsInfo = array_merge(
845 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
847 unset($propertyValues);
849 return parent::internalizeFieldsList($arguments, $fieldsInfo);
855 $iblockId = (int)($fields[
'IBLOCK_ID'] ?? 0);
857 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter([
'IBLOCK_ID' => $iblockId]);
858 $fieldsInfo = array_merge(
860 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
862 unset($propertyValues);
864 return parent::internalizeFieldsAdd($fields, $fieldsInfo);
870 $iblockId = (int)($fields[
'IBLOCK_ID'] ?? 0);
872 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter([
'IBLOCK_ID' => $iblockId]);
873 $fieldsInfo = array_merge(
875 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
877 unset($propertyValues);
879 return parent::internalizeFieldsUpdate($fields, $fieldsInfo);
888 $date = $this->internalizeDate($value);
890 if ($date instanceof
Date)
892 $value = $date->format(
'd.m.Y');
896 $r->addError(
new Error(
'Wrong type data'));
901 $r->setData([$value]);
913 $date = $this->internalizeDateTime($value);
916 $value = $date->format(
'd.m.Y H:i:s');
920 $r->addError(
new Error(
'Wrong type datetime'));
925 $r->setData([$value]);
937 $date = $this->internalizeDate($value);
939 if ($date instanceof
Date)
941 $value = $date->format(
'Y-m-d');
945 $r->addError(
new Error(
'Wrong type data'));
950 $r->setData([$value]);
962 $date = $this->internalizeDateTime($value);
965 $value = $date->format(
'Y-m-d H:i:s');
969 $r->addError(
new Error(
'Wrong type datetime'));
974 $r->setData([$value]);
984 $type = $info[
'TYPE'] ??
'';
986 if ($type === DataType::TYPE_PRODUCT_PROPERTY)
988 $propertyType = $info[
'PROPERTY_TYPE'] ??
'';
989 $userType = $info[
'USER_TYPE'] ??
'';
991 $attrs = $info[
'ATTRIBUTES'] ?? [];
992 $isMultiple = in_array(Attributes::MULTIPLE, $attrs,
true);
998 $value = $isMultiple ? $value : [$value];
1000 if ($propertyType === PropertyTable::TYPE_STRING && $userType === PropertyTable::USER_TYPE_DATE)
1002 array_walk($value,
function(&$item) use ($r)
1005 if ($date->isSuccess())
1007 $item[
'VALUE'] = $date->getData()[0];
1011 $r->addErrors($date->getErrors());
1015 elseif ($propertyType === PropertyTable::TYPE_STRING && $userType === PropertyTable::USER_TYPE_DATETIME)
1017 array_walk($value,
function(&$item) use ($r)
1020 if ($date->isSuccess())
1022 $item[
'VALUE'] = $date->getData()[0];
1026 $r->addErrors($date->getErrors());
1030 elseif ($propertyType === PropertyTable::TYPE_FILE && empty($userType))
1032 array_walk($value,
function(&$item) use ($r)
1034 $date = $this->internalizeFileValue($item[
'VALUE']);
1037 $item[
'VALUE'] = $date;
1041 $r->addError(
new Error(
'Wrong file date'));
1045 elseif ($this->isPropertyBoolean($info))
1047 $booleanValue = $value[0][
'VALUE'];
1048 if ($booleanValue === self::BOOLEAN_VALUE_YES)
1050 $value[0][
'VALUE'] = $info[
'BOOLEAN_VALUE_YES'][
'ID'];
1052 elseif ($booleanValue === self::BOOLEAN_VALUE_NO)
1054 $value[0][
'VALUE'] =
null;
1059 $value = $isMultiple? $value: $value[0];
1063 if ($r->isSuccess())
1065 $r->setData([$value]);
1074 $name ===
'getfieldsbyfilter'
1075 || $name ===
'download'
1082 return parent::internalizeArguments($name, $arguments);
1087 $fieldInfo = $fieldsInfo[$name] ?? [];
1088 if ($this->isPropertyBoolean($fieldInfo))
1090 return self::BOOLEAN_VALUE_NO;
1093 return parent::externalizeEmptyValue($name, $value, $fields, $fieldsInfo);
1099 $iblockId = (int)($fields[
'IBLOCK_ID'] ?? 0);
1100 $productType = (int)($fields[
'TYPE'] ?? 0);
1102 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter([
'IBLOCK_ID' => $iblockId]);
1103 $product = $this->getFieldsCatalogProductByFilter([
'IBLOCK_ID' => $iblockId,
'PRODUCT_TYPE' => $productType]);
1105 if ($product->isSuccess())
1107 $fieldsInfo = array_merge(
1108 $this->getFieldsIBlockElement(),
1109 ($propertyValues->isSuccess() ? $propertyValues->getData() : []),
1110 $this->getFieldsCatalogProductCommonFields(),
1119 $fieldsInfo = array_merge(
1121 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
1124 unset($product, $propertyValues);
1126 return parent::externalizeFieldsGet($fields, $fieldsInfo);
1132 $iblockId = (int)($list[0][
'IBLOCK_ID'] ?? 0);
1134 $propertyValues = $this->getFieldsIBlockPropertyValuesByFilter([
'IBLOCK_ID' => $iblockId]);
1135 $fieldsInfo = array_merge(
1137 ($propertyValues->isSuccess() ? $propertyValues->getData() : [])
1139 unset($propertyValues);
1141 return parent::externalizeListFields($list, $fieldsInfo);
1147 $name ===
'getfieldsbyfilter'
1148 || $name ===
'download'
1155 return parent::externalizeResult($name, $fields);
1160 if ($name ===
'getfieldsbyfilter')
1162 if (isset($arguments[
'filter']))
1164 $filter = $arguments[
'filter'];
1165 if (!empty($filter))
1167 $arguments[
'filter'] = $this->convertKeysToSnakeCaseFilter($filter);
1171 elseif ($name ===
'download')
1173 if (isset($arguments[
'fields']))
1175 $fields = $arguments[
'fields'];
1176 if (!empty($fields))
1180 | Converter::TO_SNAKE
1181 | Converter::TO_SNAKE_DIGIT
1182 | Converter::TO_UPPER
1186 | Converter::TO_SNAKE
1187 | Converter::TO_SNAKE_DIGIT
1188 | Converter::TO_UPPER
1192 foreach ($converter->process($fields) as $key => $value)
1194 $result[$converterForKey->process($key)] = $value;
1196 $arguments[
'fields'] = $result;
1202 parent::convertKeysToSnakeCaseArguments($name, $arguments);
1212 $select = $arguments[
'select'] ?? [];
1213 if (!is_array($select))
1219 if (!in_array(
'ID', $select))
1223 if (!in_array(
'IBLOCK_ID', $select))
1225 $error[] =
'iblockId';
1230 $r->addError(
new Error(
'Required select fields: ' . implode(
', ', $error)));
1233 if (!isset($arguments[
'filter'][
'IBLOCK_ID']))
1235 $r->addError(
new Error(
'Required filter fields: iblockId'));
1243 if ($name ===
'download')
1245 $fields = $arguments[
'fields'];
1250 return parent::checkArguments($name, $arguments);
1260 if (!isset($fields[
'FIELD_NAME']))
1262 $emptyFields[] =
'fieldName';
1265 if (!isset($fields[
'FILE_ID']))
1267 $emptyFields[] =
'fileId';
1270 if (!isset($fields[
'PRODUCT_ID']))
1272 $emptyFields[] =
'productId';
1275 if (!empty($emptyFields))
1277 $r->addError(
new Error(
'Required fields: '.implode(
', ', $emptyFields)));
1285 return '/rest/catalog.product.download';
1290 $productId = ($fields[
'ID'] ?? 0);
1294 'fieldName' => Converter::toJson()
1298 'productId' => $productId,
1306 'URL' => new \Bitrix\Main\Engine\Response\DataType\ContentUri(
1307 $uri->addParams($data)
1317 $info = $fieldsInfo[$name] ?? [];
1318 $type = $info[
'TYPE'] ??
'';
1320 if ($type === DataType::TYPE_PRODUCT_PROPERTY)
1322 $attrs = $info[
'ATTRIBUTES'] ?? [];
1323 $isMultiple = in_array(Attributes::MULTIPLE, $attrs,
true);
1325 $propertyType = $info[
'PROPERTY_TYPE'] ??
'';
1326 $userType = $info[
'USER_TYPE'] ??
'';
1328 $value = $isMultiple? $value: [$value];
1330 if ($propertyType === PropertyTable::TYPE_STRING && $userType === PropertyTable::USER_TYPE_DATE)
1332 array_walk($value,
function(&$item)use($r)
1334 $date = $this->externalizeDateValue($item[
'VALUE']);
1335 if ($date->isSuccess())
1337 $item[
'VALUE'] = $date->getData()[0];
1341 $r->addErrors($date->getErrors());
1345 elseif ($propertyType === PropertyTable::TYPE_STRING && $userType === PropertyTable::USER_TYPE_DATETIME)
1347 array_walk($value,
function(&$item) use($r)
1349 $date = $this->externalizeDateTimeValue($item[
'VALUE']);
1350 if ($date->isSuccess())
1352 $item[
'VALUE'] = $date->getData()[0];
1356 $r->addErrors($date->getErrors());
1360 elseif ($propertyType === PropertyTable::TYPE_FILE && empty($userType))
1362 array_walk($value,
function(&$item) use ($fields, $name)
1364 $item[
'VALUE'] = $this->
externalizeFileValue($name, $item[
'VALUE'], [
'PRODUCT_ID' => $fields[
'ID']]);
1367 elseif ($this->isPropertyBoolean($info))
1371 $value = self::BOOLEAN_VALUE_YES;
1375 $value = self::BOOLEAN_VALUE_NO;
1379 $value = $isMultiple? $value: $value[0];
1382 if ($r->isSuccess())
1384 $r->setData([$value]);
1395 private function loadFieldNames(): void
1397 if (!empty($this->productFieldNames))
1412 private function loadEntityFieldNames(array $fieldList)
1415 foreach ($fieldList as $field)
1417 if ($field instanceof ScalarField)
1419 $name = $field->getName();
1420 $title = $field->getTitle();
1422 $this->productFieldNames[$name] = $title ?: $name;
1433 private function fillFieldNames(array $fieldList): array
1435 foreach (array_keys($fieldList) as $id)
1437 $fieldList[$id][
'NAME'] = $this->productFieldNames[$id] ?? $id;
1443 private function isPropertyBoolean(array $property): bool
1445 if (($property[
'PROPERTY_TYPE'] ??
'') !== PropertyTable::TYPE_LIST)
1449 $attributes = $property[
'ATTRIBUTES'] ?? [];
1450 if (!is_array($attributes))
1454 if (in_array(Attributes::MULTIPLE, $attributes,
true))
1458 $userType = (string)($property[
'USER_TYPE'] ??
'');
1463 return (!empty($property[
'BOOLEAN_VALUE_YES']) && is_array($property[
'BOOLEAN_VALUE_YES']));
1473 : $r->addError(
new Error(
'For type Multiple field - value must be an Indexed array'))
1479 if (!is_array($ary))
1484 $keys = array_keys($ary);
1485 foreach ($keys as $k)