56 private const USER_TYPE_METHOD =
'GetUIEntityEditorProperty';
57 private const USER_TYPE_GET_VIEW_METHOD =
'GetUIEntityEditorPropertyViewHtml';
58 private const USER_TYPE_GET_EDIT_METHOD =
'GetUIEntityEditorPropertyEditHtml';
59 private const USER_TYPE_FORMAT_VALUE_METHOD =
'getFormattedValue';
91 $this->crmIncluded = Loader::includeModule(
'crm');
92 $this->accessController = AccessController::getCurrent();
101 $allowedBuilderTypes = [
102 Url\ShopBuilder::TYPE_ID,
103 Url\InventoryBuilder::TYPE_ID,
105 $allowedScopeList = [
108 if ($this->crmIncluded)
110 $allowedBuilderTypes[] = Crm\Product\Url\ProductBuilder::TYPE_ID;
114 $params[
'BUILDER_CONTEXT'] = (string)(
$params[
'BUILDER_CONTEXT'] ??
'');
115 if (!in_array(
$params[
'BUILDER_CONTEXT'], $allowedBuilderTypes,
true))
117 $params[
'BUILDER_CONTEXT'] = Url\ShopBuilder::TYPE_ID;
126 if (!in_array(
$params[
'SCOPE'], $allowedScopeList))
132 if (
$params[
'MODE'] !== self::CREATION_MODE &&
$params[
'MODE'] !== self::EDIT_MODE)
150 if (strncmp($currentPath,
'/shop/', 6) === 0)
154 elseif ($this->crmIncluded)
156 if (strncmp($currentPath,
'/crm/', 5) === 0)
167 $this->urlBuilder = BuilderManager::getInstance()->getBuilder($this->params[
'BUILDER_CONTEXT']);
168 $this->urlBuilder->setIblockId($this->entity->getIblockId());
173 switch ($this->params[
'SCOPE'])
176 $result = \Bitrix\Catalog\Config\State::isProductCardSliderEnabled();
180 if ($this->crmIncluded)
182 $result = Crm\Settings\LayoutSettings::getCurrent()->isFullCatalogEnabled();
196 !$this->accessController->check(ActionDictionary::ACTION_PRODUCT_CARD_EDIT)
205 return $this->accessController->check(ActionDictionary::ACTION_PRODUCT_ADD);
208 return $this->accessController->check(ActionDictionary::ACTION_PRODUCT_EDIT);
213 return $this->accessController->check(ActionDictionary::ACTION_PRODUCT_CARD_EDIT);
218 return $this->accessController->check(ActionDictionary::ACTION_PRODUCT_CARD_SETTINGS_FOR_USERS_SET);
225 $this->accessController->check(ActionDictionary::ACTION_PRICE_EDIT)
226 || $this->isEntityCreationForm()
234 return $this->accessController->check(ActionDictionary::ACTION_PRODUCT_PURCHASE_INFO_VIEW);
240 $this->accessController->check(ActionDictionary::ACTION_PRODUCT_PUBLIC_VISIBILITY_SET)
247 return $this->accessController->check(ActionDictionary::ACTION_INVENTORY_MANAGEMENT_ACCESS);
259 'name' =>
'FIELD_CONFIGURATOR_CONTROLLER',
260 'type' =>
'field_configurator',
264 'name' =>
'GOOGLE_MAP_CONTROLLER',
265 'type' =>
'google_map',
269 'name' =>
'EMPLOYEE_CONTROLLER',
270 'type' =>
'employee',
274 'name' =>
'VARIATION_LINK_CONTROLLER',
275 'type' =>
'variation_link',
279 'name' =>
'USER_CONTROLLER',
284 'name' =>
'CRM_CONTROLLER',
285 'type' =>
'binding_to_crm_element',
289 'name' =>
'IBLOCK_ELEMENT_CONTROLLER',
290 'type' =>
'iblock_element',
304 if ($allowDefaultValues)
309 ?? $field[
'defaultValue']
317 $values[$field[
'name']] = $this->
getFieldValue($field) ??
'';
323 if (!empty($additionalValues))
325 $values = array_merge($values, $additionalValues);
333 $iblockInfo = ServiceContainer::getIblockInfo($this->entity->getIblockId());
337 return 'catalog-product-variation-grid-' . $iblockInfo->getProductIblockId();
340 return 'catalog-product-variation-grid';
345 return GridVariationForm::class;
350 return 'BX.Catalog.VariationGrid';
357 $activeSettings = [];
359 $allUsedColumns = $options->getUsedColumns();
360 if (!empty($allUsedColumns))
362 foreach ($gridColumnSettings as $setting => $columns)
364 if (empty(array_diff($columns[
'ITEMS'], $allUsedColumns)))
366 $activeSettings[] = $setting;
372 if (!empty($config[
'CATALOG_PARAMETERS']))
374 $activeSettings[] =
'CATALOG_PARAMETERS';
378 $settingList = array_keys($gridColumnSettings);
381 $settingList = array_merge(
384 'CATALOG_PARAMETERS',
388 foreach ($settingList as $setting)
392 'checked' => in_array($setting, $activeSettings,
true),
393 'title' => $gridColumnSettings[$setting][
'TITLE'] ??
Loc::getMessage(
'CATALOG_C_F_VARIATION_SETTINGS_' . $setting .
'_TITLE'),
394 'desc' => $gridColumnSettings[$setting][
'DESCRIPTION'] ??
Loc::getMessage(
'CATALOG_C_F_VARIATION_SETTINGS_' . $setting .
'_DESC'),
395 'action' => isset($gridColumnSettings[$setting]) ?
'grid' :
'card',
396 'columns' => $gridColumnSettings[$setting] ??
null,
402 'title' =>
Loc::getMessage(
'CATALOG_C_F_VARIATION_SETTINGS_SEO_TITLE'),
404 'disabledCheckbox' =>
true,
407 'action' =>
'slider',
410 if ($this->entity->getId())
412 $seoLink[
'url'] = $this->urlBuilder->getElementSeoUrl($this->entity->getId());
432 $iblockInfo = ServiceContainer::getIblockInfo($this->entity->getIblockId());
436 return 'catalog-entity-card-config-' . $iblockInfo->getProductIblockId();
439 return 'catalog-entity-card-config';
444 return \CUserOptions::getOption(
'catalog', $this->
getCardConfigId(), []);
449 return \CUserOptions::setOption(
'catalog', $this->
getCardConfigId(), $config);
454 $iblockInfo = ServiceContainer::getIblockInfo($this->entity->getIblockId());
458 return (
int)$iblockInfo->getSkuIblockId() ?: $iblockInfo->getProductIblockId();
466 $additionalValues = [];
470 if (!isset($description[
'type']) || !in_array($description[
'type'], [
'custom',
'money',
'multimoney',
'user'],
true))
475 $value = $values[$description[
'name']] ??
null;
476 $descriptionData = $description[
'data'] ?? [];
478 if (!empty($description[
'settings'][
'USER_TYPE']))
480 $description[
'settings'][
'PROPERTY_USER_TYPE'] = \CIBlockProperty::GetUserType(
481 $description[
'settings'][
'USER_TYPE']
485 $propertySettings = $description[
'settings'] ?? [];
487 if ($description[
'type'] ===
'custom')
489 if ($this->isCustomLinkProperty($propertySettings))
492 'SETTINGS' => $propertySettings,
494 'FIELD_NAME' => $description[
'name'],
495 'ELEMENT_ID' => $this->entity->getId() ? (string)$this->entity->getId() :
'n' . mt_rand(),
498 $paramsSingle[
'SETTINGS'][
'MULTIPLE'] =
'N';
500 $paramsMultiple[
'SETTINGS'][
'MULTIPLE'] =
'Y';
502 $viewMethod = $propertySettings[
'PROPERTY_USER_TYPE'][self::USER_TYPE_GET_VIEW_METHOD] ??
null;
503 if ($viewMethod && is_callable($viewMethod))
505 $additionalValues[$descriptionData[
'view']] = $viewMethod(
$params);
508 $editMethod = $propertySettings[
'PROPERTY_USER_TYPE'][self::USER_TYPE_GET_EDIT_METHOD] ??
null;
509 if ($editMethod && is_callable($editMethod))
511 $additionalValues[$descriptionData[
'edit']] = $editMethod(
$params);
512 $additionalValues[$descriptionData[
'editList']][
'SINGLE'] = $editMethod($paramsSingle);
513 $additionalValues[$descriptionData[
'editList']][
'MULTIPLE'] = $editMethod($paramsMultiple);
516 elseif ($propertySettings[
'PROPERTY_TYPE'] === PropertyTable::TYPE_ELEMENT)
519 Main\Type\Collection::normalizeArrayValuesByInt($value,
false);
522 $elementData = ElementTable::getList([
523 'select' => [
'NAME'],
524 'filter' => [
'ID' => $value],
526 while ($element = $elementData->fetch())
528 $namesList[] = $element[
'NAME'];
530 unset($element, $elementData);
532 $viewValue = implode(
', ', $namesList);
534 $paramsSingle = $propertySettings;
535 $paramsSingle[
'MULTIPLE'] =
'N';
536 $paramsMultiple = $propertySettings;
537 $paramsMultiple[
'MULTIPLE'] =
'Y';
539 'FIELD_NAME' => $description[
'name'],
541 'onChangeIblockElement',
544 $additionalValues[$descriptionData[
'edit']] = Iblock\UI\Input\Element::renderSelector(
549 $additionalValues[$descriptionData[
'editList']][
'SINGLE'] = Iblock\UI\Input\Element::renderSelector(
554 $additionalValues[$descriptionData[
'editList']][
'MULTIPLE'] = Iblock\UI\Input\Element::renderSelector(
560 elseif ($propertySettings[
'PROPERTY_TYPE'] === PropertyTable::TYPE_SECTION)
563 Main\Type\Collection::normalizeArrayValuesByInt($value,
false);
566 $elementData = Iblock\SectionTable::getList([
567 'select' => [
'NAME'],
568 'filter' => [
'ID' => $value],
570 while ($element = $elementData->fetch())
572 $namesList[] = $element[
'NAME'];
574 unset($element, $elementData);
576 $viewValue = implode(
', ', $namesList);
578 $paramsSingle = $propertySettings;
579 $paramsSingle[
'MULTIPLE'] =
'N';
580 $paramsMultiple = $propertySettings;
581 $paramsMultiple[
'MULTIPLE'] =
'Y';
583 'FIELD_NAME' => $description[
'name'],
585 'onChangeIblockElement',
588 $additionalValues[$descriptionData[
'edit']] = Iblock\UI\Input\Section::renderSelector(
593 $additionalValues[$descriptionData[
'editList']][
'SINGLE'] = Iblock\UI\Input\Section::renderSelector(
598 $additionalValues[$descriptionData[
'editList']][
'MULTIPLE'] = Iblock\UI\Input\Section::renderSelector(
604 elseif ($propertySettings[
'PROPERTY_TYPE'] === PropertyTable::TYPE_FILE)
606 if ($description[
'propertyCode'] === self::MORE_PHOTO)
608 $value = $this->getEntityViewPictureValues($this->entity);
609 $editValue = $this->getEntityEditPictureValues($this->entity);
611 if (!$description[
'multiple'])
614 $editValue = $editValue[0];
624 $descriptionSingle = $description;
625 $descriptionSingle[
'settings'][
'MULTIPLE'] =
false;
626 $descriptionMultiple = $description;
627 $descriptionMultiple[
'settings'][
'MULTIPLE'] =
true;
632 $additionalValues[$descriptionData[
'viewList']][
'SINGLE'] = $this->
getImagePropertyViewHtml(is_array($value) ? $value[0] ??
null : $value);
633 $additionalValues[$descriptionData[
'viewList']][
'MULTIPLE'] = $this->
getImagePropertyViewHtml(is_array($value) ? $value : [$value]);
634 $additionalValues[$descriptionData[
'edit']] = $this->getImagePropertyEditHtml($description, $editValue);
635 $additionalValues[$descriptionData[
'editList']][
'SINGLE'] = $this->getImagePropertyEditHtml($descriptionSingle, is_array($editValue) ? $editValue[0] ??
null : $editValue);
636 $additionalValues[$descriptionData[
'editList']][
'MULTIPLE'] = $this->getImagePropertyEditHtml($descriptionMultiple, is_array($editValue) ? $editValue : [$editValue]);
641 $entityId = $this->entity->getId() ?? uniqid();
642 $controlId = $description[
'name'] .
'_uploader_' . $entityId;
644 $additionalValues[$descriptionData[
'view']] =
'';
645 $additionalValues[$descriptionData[
'viewList']][
'SINGLE'] =
'';
646 $additionalValues[$descriptionData[
'viewList']][
'MULTIPLE'] =
'';
650 $additionalValues[$descriptionData[
'view']] = $this->getFilePropertyViewHtml($description, $value, $controlId);
651 $additionalValues[$descriptionData[
'viewList']][
'SINGLE'] = $this->getFilePropertyViewHtml($description, is_array($value) ? $value[0] ??
null : $value, $controlId,
false);
652 $additionalValues[$descriptionData[
'viewList']][
'MULTIPLE'] = $this->getFilePropertyViewHtml($description, is_array($value) ? $value : [$value], $controlId,
true);
655 $additionalValues[$descriptionData[
'edit']] = $this->getFilePropertyEditHtml($description, $value, $controlId);
656 $additionalValues[$descriptionData[
'editList']][
'SINGLE'] = $this->getFilePropertyEditHtml($description, is_array($value) ? $value[0] ??
null : $value, $controlId,
false);
657 $additionalValues[$descriptionData[
'editList']][
'MULTIPLE'] = $this->getFilePropertyEditHtml($description, is_array($value) ? $value : [$value], $controlId,
true);
663 $propertySettings[
'USER_TYPE'] ===
'FileMan'
664 || $propertySettings[
'USER_TYPE'] ===
'DiskFile'
674 'SETTINGS' => $propertySettings,
676 'FIELD_NAME' => $description[
'name'],
677 'ELEMENT_ID' => $this->entity->getId() ? (string)$this->entity->getId() :
'n' . mt_rand(),
680 if ($propertySettings[
'USER_TYPE'] ===
'map_google')
687 if ($description[
'multiple'])
689 $paramsSingle[
'VALUE'] = $value[0] ??
'';
693 $paramsSingle[
'VALUE'] = $value;
695 $paramsSingle[
'SETTINGS'][
'MULTIPLE'] =
'N';
698 $singleValueToMultiple = [];
702 $singleValueToMultiple = [$value];
705 $paramsMultiple[
'VALUE'] = $description[
'multiple'] ? $value : $singleValueToMultiple;
706 $paramsMultiple[
'SETTINGS'][
'MULTIPLE'] =
'Y';
708 $viewMethod = $propertySettings[
'PROPERTY_USER_TYPE'][self::USER_TYPE_GET_VIEW_METHOD] ??
null;
709 if ($viewMethod && is_callable($viewMethod))
711 $additionalValues[$descriptionData[
'viewList']][
'SINGLE'] = $viewMethod($paramsSingle);
712 $additionalValues[$descriptionData[
'viewList']][
'MULTIPLE'] = $viewMethod($paramsMultiple);
713 $additionalValues[$descriptionData[
'view']] = $viewMethod(
$params);
716 $editMethod = $propertySettings[
'PROPERTY_USER_TYPE'][self::USER_TYPE_GET_EDIT_METHOD] ??
null;
717 if ($editMethod && is_callable($editMethod))
719 $additionalValues[$descriptionData[
'editList']][
'SINGLE'] = $editMethod($paramsSingle);
720 $additionalValues[$descriptionData[
'editList']][
'MULTIPLE'] = $editMethod($paramsMultiple);
721 $additionalValues[$descriptionData[
'edit']] = $editMethod(
$params);
725 elseif (in_array($description[
'type'], [
'money',
'multimoney'],
true) && Loader::includeModule(
'currency'))
727 $formatMethod = $propertySettings[
'PROPERTY_USER_TYPE'][self::USER_TYPE_FORMAT_VALUE_METHOD] ??
null;
728 if ($formatMethod && is_callable($formatMethod))
730 if ($description[
'type'] ===
'money')
732 $additionalMoneyValues = $this->getAdditionalMoneyValues($value, $formatMethod);
734 $additionalValues[$descriptionData[
'currencyCode']] = $additionalMoneyValues[
'currencyCode'];
735 $additionalValues[$descriptionData[
'amount']] = $additionalMoneyValues[
'amount'];
736 $additionalValues[$descriptionData[
'formatted']] = $additionalMoneyValues[
'formatted'];
737 $additionalValues[$descriptionData[
'formattedWithCurrency']] = $additionalMoneyValues[
'formattedWithCurrency'];
741 foreach ($value as $currentValueElement)
743 $additionalMoneyValues = $this->getAdditionalMoneyValues($currentValueElement, $formatMethod);
745 $additionalValues[$descriptionData[
'currencyCode']][] = $additionalMoneyValues[
'currencyCode'];
746 $additionalValues[$descriptionData[
'amount']][] = $additionalMoneyValues[
'amount'];
747 $additionalValues[$descriptionData[
'formatted']][] = $additionalMoneyValues[
'formatted'];
748 $additionalValues[$descriptionData[
'formattedWithCurrency']][] = $additionalMoneyValues[
'formattedWithCurrency'];
753 elseif ($description[
'type'] ===
'user')
755 $userData = \Bitrix\Main\UserTable::getList([
756 'filter' => [
'=ID' => $value],
758 'ID',
'LOGIN',
'PERSONAL_PHOTO',
759 'NAME',
'SECOND_NAME',
'LAST_NAME',
765 if ($user = $userData->fetch())
767 $pathToProfile = $this->params[
'PATH_TO'][
'USER_PROFILE'];
770 $additionalValues[
'PATH_TO_USER_PROFILE'] = $pathToProfile;
771 $additionalValues[
'PATH_TO_' . $description[
'name']] = \CComponentEngine::MakePathFromTemplate(
773 [
'user_id' => $user[
'ID']]
776 $additionalValues[$description[
'name'] .
'_PERSONAL_PHOTO'] = $user[
'PERSONAL_PHOTO'];
777 $additionalValues[$description[
'name'] .
'_WORK_POSITION'] = $user[
'WORK_POSITION'];
779 $additionalValues[$description[
'name'] .
'_FORMATTED_NAME'] = \CUser::FormatName(
780 \CSite::GetNameFormat(
false),
782 'LOGIN' => $user[
'LOGIN'],
783 'NAME' => $user[
'NAME'],
784 'LAST_NAME' => $user[
'LAST_NAME'],
785 'SECOND_NAME' => $user[
'SECOND_NAME'],
791 if ((
int)$user[
'PERSONAL_PHOTO'] > 0)
793 $file = new \CFile();
794 $fileInfo = $file->ResizeImageGet(
795 (
int)$user[
'PERSONAL_PHOTO'],
796 [
'width' => 60,
'height' => 60],
797 BX_RESIZE_IMAGE_EXACT
799 if (is_array($fileInfo) && isset($fileInfo[
'src']))
801 $additionalValues[$description[
'name'] .
'_PHOTO_URL'] = $fileInfo[
'src'];
808 return $additionalValues;
813 $fileTypes = (string)$propertySettings[
'FILE_TYPE'];
814 $imageExtensions = explode(
',', \CFile::GetImageExtensions());
815 $fileExtensions = explode(
',', $fileTypes);
816 $fileExtensions = array_map(
'trim', $fileExtensions);
818 $diffExtensions = array_diff($fileExtensions, $imageExtensions);
819 return empty($diffExtensions);
822 private function isCustomLinkProperty(array $property): bool
824 if (!isset($property[
'USER_TYPE']))
830 PropertyTable::USER_TYPE_XML_ID =>
true,
831 PropertyTable::USER_TYPE_ELEMENT_AUTOCOMPLETE =>
true,
833 PropertyTable::USER_TYPE_SKU =>
true,
836 return isset($userTypes[$property[
'USER_TYPE']]);
839 private function getAdditionalMoneyValues(
string $value, callable $formatMethod): array
841 $additionalValues = [];
843 $formattedValues = $formatMethod($value);
844 $amount = $formattedValues[
'AMOUNT'];
845 if ($formattedValues[
'AMOUNT'] !==
'' && $formattedValues[
'DECIMALS'] !==
'')
847 $amount .=
'.' . $formattedValues[
'DECIMALS'];
849 $currency = $formattedValues[
'CURRENCY'];
851 $additionalValues[
'currencyCode'] = $currency;
852 $additionalValues[
'amount'] = $amount;
853 $additionalValues[
'formatted'] = \CCurrencyLang::CurrencyFormat($amount, $currency,
false);
854 $additionalValues[
'formattedWithCurrency'] = \CCurrencyLang::CurrencyFormat($amount, $currency,
true);
856 return $additionalValues;
859 private function getImageValuesForEntity(BaseIblockElementEntity
$entity): array
863 if (
$entity instanceof HasPropertyCollection)
865 $morePhotoProperty =
$entity->getPropertyCollection()->findByCode(self::MORE_PHOTO);
866 if ($morePhotoProperty)
868 $morePhotoValues = $morePhotoProperty->getPropertyValueCollection()->getValues();
869 if (!empty($morePhotoValues))
871 if (!is_array($morePhotoValues))
873 $morePhotoValues = [$morePhotoValues];
875 $values = array_merge($values, $morePhotoValues);
880 $previewPicture =
$entity->getField(
'PREVIEW_PICTURE');
883 $values = array_merge([$previewPicture], $values);
886 $detailPicture =
$entity->getField(
'DETAIL_PICTURE');
889 $values = array_merge([$detailPicture], $values);
895 private function getEntityEditPictureValues(BaseIblockElementEntity
$entity): array
897 return $this->getImageValuesForEntity(
$entity);
900 private function getEntityViewPictureValues(BaseIblockElementEntity
$entity): array
902 return $this->getImageValuesForEntity(
$entity);
907 if ($field[
'entity'] ===
'product')
909 return $this->getProductFieldValue($field);
912 if ($field[
'entity'] ===
'property')
914 return $this->getPropertyFieldValue($field);
924 foreach ($config as &$column)
928 static function ($a, $b)
930 $sortA = $a[
'sort'] ?? PHP_INT_MAX;
931 $sortB = $b[
'sort'] ?? PHP_INT_MAX;
933 return $sortA <=> $sortB;
938 return array_values($config);
950 $hiddenFields[] =
'QUANTITY_TRACE';
953 return $hiddenFields;
961 $isQuantityTraceExplicitlyDisabled = $this->entity->getField(
'QUANTITY_TRACE') ===
'N';
962 $isWithOrdersMode = Loader::includeModule(
'crm') && \CCrmSaleHelper::isWithOrdersMode();
965 return (!$isWithOrdersMode && !$isInventoryManagementUsed)
966 || ($isInventoryManagementUsed && !$isQuantityTraceExplicitlyDisabled);
978 'width' => $leftWidth,
987 'isRemovable' =>
false,
992 'name' =>
'properties',
997 'isRemovable' =>
false,
1007 'width' => 100 - $leftWidth,
1014 if (!empty($catalogParameters))
1016 $result[
'right'][
'elements'][] = $catalogParameters;
1026 [
'name' =>
'NAME-CODE'],
1027 [
'name' =>
'DETAIL_TEXT'],
1029 Product\SystemField::getFieldsByRestrictions(
1031 'TYPE' => $this->entity->getType(),
1032 'IBLOCK_ID' => $this->entity->getIblockId(),
1035 'RESULT_MODE' =>
Product\SystemField::DESCRIPTION_MODE_UI_FORM_EDITOR,
1043 $catalogParameters = [
1044 [
'name' =>
'QUANTITY_TRACE'],
1045 [
'name' =>
'CAN_BUY_ZERO'],
1046 [
'name' =>
'SUBSCRIBE'],
1051 array_shift($catalogParameters);
1055 'name' =>
'catalog_parameters',
1057 'type' =>
'section',
1058 'elements' => $catalogParameters,
1060 'isRemovable' =>
false,
1068 if ($this->descriptions ===
null)
1086 return array_merge(...$fieldBlocks);
1092 unset($elementTableMap[
'NAME'], $elementTableMap[
'CODE']);
1094 return $elementTableMap;
1101 'entity' =>
'product',
1102 'name' =>
'NAME-CODE',
1103 'originalName' =>
'NAME-CODE',
1105 'type' =>
'name-code',
1107 'required' =>
'true',
1111 'defaultValue' =>
null,
1117 private function getTableDescriptions(array $tableMap): array
1121 $allowedFields = $this->getTableElementsWhiteList();
1124 foreach ($tableMap as $field)
1126 $fieldName = $field->getName();
1128 if (!isset($allowedFields[$fieldName]))
1134 'entity' =>
'product',
1136 'originalName' => $fieldName,
1137 'title' => $field->getTitle(),
1138 'type' => $this->getFieldTypeByObject($field),
1139 'editable' => $this->isEditableField($field),
1140 'required' => $this->isRequiredField($field),
1141 'placeholders' => $this->getFieldPlaceholders($field),
1142 'defaultValue' => $field->getDefaultValue(),
1148 if ($this->isSpecificCatalogField($fieldName))
1154 $items = $this->getCommonEnumFields($field);
1157 $description[
'data'][
'items'] = $items;
1160 if ($description[
'type'] ===
'custom')
1162 $description[
'data'] += $this->getCustomControlParameters($description[
'name']);
1164 elseif ($description[
'type'] ===
'user')
1166 $description[
'data'] = [
1167 'enableEditInView' =>
false,
1168 'formated' => $description[
'name'] .
'_FORMATTED_NAME',
1169 'position' => $description[
'name'] .
'_WORK_POSITION',
1170 'photoUrl' => $description[
'name'] .
'_PHOTO_URL',
1171 'showUrl' =>
'PATH_TO_' . $description[
'name'],
1172 'pathToProfile' =>
'PATH_TO_USER_PROFILE',
1175 elseif ($fieldName ===
'MEASURE')
1178 $defaultMeasure =
null;
1180 foreach ($this->getMeasures() as $measure)
1182 $measureId = (int)$measure[
'ID'];
1183 $measureTitle = $measure[
'MEASURE_TITLE'];
1185 if (empty($measureTitle))
1187 $measureTitle = \CCatalogMeasureClassifier::getMeasureTitle($measure[
'CODE']);
1192 'VALUE' => $measureId,
1195 if ($measure[
'IS_DEFAULT'] ===
'Y')
1197 $defaultMeasure = $measureId;
1201 $description[
'defaultValue'] = $defaultMeasure;
1202 $description[
'data'][
'items'] = $measureList;
1203 $description[
'type'] =
'list';
1205 elseif ($fieldName ===
'VAT_ID')
1207 $defaultVat = $this->getDefaultVat();
1208 $description[
'defaultValue'] = $defaultVat[
'ID'];
1211 'VALUE' => $defaultVat[
'ID'],
1212 'NAME' => $defaultVat[
'NAME'],
1215 if ($defaultVat[
'ID'] !== self::NOT_SELECTED_VAT_ID_VALUE && !Loader::includeModule(
'bitrix24'))
1219 'NAME' =>
Loc::getMessage(
"CATALOG_PRODUCT_CARD_VARIATION_GRID_NOT_SELECTED"),
1223 foreach ($this->getVats() as $vat)
1225 if ($vat[
'RATE'] === $defaultVat[
'RATE'] && $vat[
'EXCLUDE_VAT'] === $defaultVat[
'EXCLUDE_VAT'])
1231 'VALUE' => $vat[
'ID'],
1232 'NAME' => htmlspecialcharsbx($vat[
'NAME']),
1236 $description[
'data'][
'items'] = $vatList;
1237 $description[
'type'] =
'list';
1239 elseif ($fieldName ===
'VAT_INCLUDED')
1241 if (Option::get(
'catalog',
'default_product_vat_included') ===
'Y')
1253 private function getTableElementsWhiteList(): array
1255 static $whiteList =
null;
1257 if ($whiteList ===
null)
1268 $whiteList = array_merge($whiteList, $this->getSpecificCatalogFieldsList());
1273 $whiteList = array_diff($whiteList, [
'WEIGHT',
'WIDTH',
'LENGTH',
'HEIGHT']);
1274 $whiteList = array_merge($whiteList, $this->getSubscribeCatalogFieldList());
1277 $whiteList = array_fill_keys($whiteList,
true);
1317 'QUANTITY_RESERVED',
1340 private function getSpecificCatalogFieldsList(): array
1349 private function getFieldTypeByObject(
ScalarField $field): string
1351 $fieldName = $field->
getName();
1353 if ($fieldName ===
'PREVIEW_PICTURE' || $fieldName ===
'DETAIL_PICTURE')
1358 if ($fieldName ===
'PREVIEW_TEXT' || $fieldName ===
'DETAIL_TEXT')
1363 if ($fieldName ===
'MODIFIED_BY' || $fieldName ===
'CREATED_BY')
1368 switch (get_class($field))
1370 case IntegerField::class:
1371 case FloatField::class:
1372 $fieldType =
'number';
1375 case BooleanField::class:
1376 $fieldType =
'boolean';
1379 case EnumField::class:
1380 $fieldType =
'list';
1383 case DateField::class:
1384 case DatetimeField::class:
1385 $fieldType =
'datetime';
1388 case TextField::class:
1389 $fieldType =
'textarea';
1392 case StringField::class:
1394 $fieldType =
'text';
1400 private function isEditableField(ScalarField $field): bool
1423 if (in_array($field->getName(), [
'QUANTITY',
'QUANTITY_RESERVED'],
true) && State::isUsedInventoryManagement())
1428 return !$field->isPrimary() && !$field->isAutocomplete();
1431 private function isRequiredField(ScalarField $field): bool
1433 if ($field->getName() ===
'IBLOCK_ID')
1438 return $field->isRequired();
1441 private function getFieldPlaceholders(ScalarField $field): ?array
1443 if ($field->getName() ===
'NAME')
1455 $iblockInfo = ServiceContainer::getIblockInfo($this->entity->getIblockId());
1459 return $iblockInfo->hasSubscription();
1465 private function getSubscribeCatalogFieldList(): array
1469 'RECUR_SCHEME_LENGTH',
1470 'RECUR_SCHEME_TYPE',
1476 private function isSpecificCatalogField(
string $fieldName): bool
1478 static $catalogEnumFields =
null;
1480 if ($catalogEnumFields ===
null)
1482 $catalogEnumFields = array_fill_keys(
1483 $this->getSpecificCatalogFieldsList(),
1488 return isset($catalogEnumFields[$fieldName]);
1493 $defaultValue =
null;
1497 case 'QUANTITY_TRACE':
1498 $defaultValue = Option::get(
'catalog',
'default_quantity_trace') ===
'Y';
1501 case 'CAN_BUY_ZERO':
1502 $defaultValue = Option::get(
'catalog',
'default_can_buy_zero') ===
'Y';
1506 $defaultValue = Option::get(
'catalog',
'default_subscribe') ===
'Y';
1513 'CATALOG_C_F_DEFAULT',
1515 '#VALUE#' => $defaultValue
1533 private function getCommonEnumFields(
EnumField $field): array
1537 foreach ((array)$field->
getValues() as $value)
1550 return Product\SystemField::getUiDescriptions([
1551 'TYPE' => $this->entity->getType(),
1552 'IBLOCK_ID' => $this->entity->getIblockId(),
1561 $allSystemFields = Product\SystemField::getFieldNamesByRestrictions([]);
1562 if (!empty($allSystemFields))
1564 $filter[
'!@FIELD_NAME'] = $allSystemFields;
1568 $iterator = UserFieldTable::getList([
1569 'select' => array_merge(
1573 'filter' => $filter,
1582 while ($row = $iterator->fetch())
1585 'entity' =>
'product',
1586 'name' => $row[
'FIELD_NAME'],
1587 'originalName' => $row[
'FIELD_NAME'],
1588 'title' => $row[
'EDIT_FORM_LABEL'] ?? $row[
'FIELD_NAME'],
1589 'hint' => $row[
'HELP_MESSAGE'],
1590 'type' => $this->getUserFieldType($row),
1592 'required' => $row[
'MANDATORY'] ===
'Y',
1593 'multiple' => $row[
'MULTIPLE'] ===
'Y',
1594 'placeholders' =>
null,
1595 'defaultValue' => $row[
'SETTINGS'][
'DEFAULT_VALUE'] ??
'',
1598 'showCode' =>
'true',
1603 switch ($description[
'type'])
1605 case Control\Type::CUSTOM:
1606 $description[
'data'] += $this->getCustomControlParameters($description[
'name']);
1608 case Control\Type::MULTI_LIST:
1609 case Control\Type::LIST:
1610 $description[
'data'] += $this->getUserFieldListItems($row);
1614 $result[] = $description;
1620 private function getUserFieldListItems(array $userField): array
1622 if ($userField[
'USER_TYPE_ID'] === UserField\
Types\EnumType::USER_TYPE_ID)
1624 return $this->getUserFieldEnumItems($userField);
1627 Loader::includeModule(
'highloadblock')
1628 && $userField[
'USER_TYPE_ID'] === \CUserTypeHlblock::USER_TYPE_ID
1631 return $this->getUserFieldHighloadblockItems($userField);
1637 private function getUserFieldEnumItems(array $userField): array
1642 $userField[
'MANDATORY'] !==
'Y'
1644 $userField[
'SETTINGS'][
'SHOW_NO_VALUE'] !==
'N'
1651 $userField[
'SETTINGS'][
'DISPLAY'] !==
'CHECKBOX'
1653 $userField[
'MULTIPLE'] !==
'Y'
1660 'NAME' =>
Loc::getMessage(
'CATALOG_PRODUCT_CARD_USERFIELD_MESS_EMPTY_VALUE')
1664 $iterator = UserField\Types\EnumType::getList($userField);
1665 while ($value = $iterator->Fetch())
1668 'ID' => $value[
'ID'],
1669 'VALUE' => $value[
'ID'],
1670 'NAME' => $value[
'VALUE'],
1673 unset($value, $iterator);
1675 return (!empty($list) ? [
'items' => $list] : []);
1678 private function getUserFieldHighloadblockItems(array $userField): array
1682 $userField[
'MANDATORY'] ===
'N'
1683 && $userField[
'MULTIPLE'] ===
'N'
1689 'NAME' =>
Loc::getMessage(
'CATALOG_PRODUCT_CARD_USERFIELD_MESS_EMPTY_VALUE')
1693 $entity = Highload\HighloadBlockTable::compileEntity($userField[
'SETTINGS'][
'HLBLOCK_ID']);
1694 $fieldsList =
$entity->getFields();
1695 if (isset($fieldsList[
'ID']) && isset($fieldsList[
'UF_NAME']))
1697 $entityDataClass =
$entity->getDataClass();
1698 $iterator = $entityDataClass::getList([
1707 while ($value = $iterator->fetch())
1710 'ID' => $value[
'ID'],
1711 'VALUE' => $value[
'ID'],
1712 'NAME' => $value[
'UF_NAME'],
1715 unset($value, $iterator);
1716 unset($entityDataClass,
$entity);
1719 return (!empty($list) ? [
'items' => $list] : []);
1724 if ($this->propertyDescriptions ===
null)
1737 foreach ($this->entity->getPropertyCollection() as $property)
1739 if (in_array($property->getUserType(), $unavailableUserTypes,
true))
1743 if ($property->isActive())
1757 PropertyTable::USER_TYPE_SKU,
1763 return self::PROPERTY_FIELD_PREFIX . $name;
1770 return static::preparePropertyName($name);
1776 'entity' =>
'property',
1777 'name' => static::preparePropertyNameFromProperty($property),
1778 'propertyId' => $property->
getId(),
1779 'propertyCode' => $property->
getCode(),
1780 'title' => $property->
getName(),
1785 'settings' => $property->getSettings(),
1791 $userTypeSettings = $property->getSetting(
'USER_TYPE_SETTINGS');
1792 $description[
'editable'] = $userTypeSettings[
'write'] ===
'Y';
1795 $nonEditableUserTypes = [
1799 if (in_array($property->
getUserType(), $nonEditableUserTypes,
true))
1801 $description[
'editable'] =
false;
1804 if ($description[
'propertyCode'] === self::MORE_PHOTO)
1806 $description[
'optionFlags'] = 1;
1809 if ($description[
'multiple'] && !is_array($description[
'defaultValue']))
1811 $description[
'defaultValue'] = $description[
'defaultValue'] ===
null ? [] : [$description[
'defaultValue']];
1817 Asset::getInstance()->addJs(
'/bitrix/js/main/utils.js');
1829 $specificDescription[
'data'][
'isPublic'] = $property->
isPublic();
1833 unset($specificDescription[
'editable']);
1834 $description[
'editable'] =
false;
1837 return array_merge($description, $specificDescription);
1840 private function getPropertyType(
Property $property): string
1844 case PropertyTable::TYPE_STRING:
1850 if ((
int)$property->getSetting(
'ROW_COUNT') > 1)
1852 $fieldType =
'textarea';
1856 $fieldType = $property->
isMultiple() ?
'multitext' :
'text';
1861 case PropertyTable::TYPE_NUMBER:
1863 $fieldType = $property->
isMultiple() ?
'multinumber' :
'number';
1866 case PropertyTable::TYPE_LIST:
1867 $fieldType = $property->
isMultiple() ?
'multilist' :
'list';
1874 case PropertyTable::TYPE_ELEMENT:
1875 case PropertyTable::TYPE_FILE:
1876 case PropertyTable::TYPE_SECTION:
1877 $fieldType =
'custom';
1881 $fieldType =
'text';
1896 foreach ($this->entity->getPropertyCollection() as $property)
1898 if (isset($hiddenCodesMap[$property->getCode()]))
1904 'name' => static::preparePropertyNameFromProperty($property),
1913 $type = $this->getPropertyType($property);
1918 'isProductProperty' =>
true,
1922 if ($type ===
'custom')
1924 $name = static::preparePropertyNameFromProperty($property);
1925 $description[
'data'] += $this->getCustomControlParameters($name);
1928 if ($type ===
'textarea')
1930 $description[
'lineCount'] = (int)($property->getSetting(
'ROW_COUNT') ?? 1);
1935 $description[
'data'][
'enableEmptyItem'] =
true;
1936 $description[
'data'][
'items'] = [];
1938 $propertyEnumIterator = \CIBlockProperty::GetPropertyEnum(
1946 while ($enum = $propertyEnumIterator->fetch())
1948 $description[
'data'][
'items'][] = [
1949 'NAME' => $enum[
'VALUE'],
1950 'VALUE' => $enum[
'ID'],
1951 'ID' => $enum[
'ID'],
1955 if (count($description[
'data'][
'items']) === 1
1956 && $description[
'data'][
'items'][0][
'NAME'] ===
'Y')
1958 $description[
'type'] =
'boolean';
1959 $description[
'data'][
'value'] = $description[
'data'][
'items'][0][
'VALUE'];
1963 return $description;
1972 && $property->
getUserType() === PropertyTable::USER_TYPE_HTML
1981 foreach ($defaultValue as &$item)
1983 $item = $item[
'TEXT'] ??
null;
1988 $defaultValue = $defaultValue[
'TEXT'] ??
null;
1994 'defaultValue' => $defaultValue,
1998 $userTypeMethod = $propertySettings[
'PROPERTY_USER_TYPE'][self::USER_TYPE_METHOD] ??
null;
1999 if ($userTypeMethod && is_callable($userTypeMethod))
2002 $description = $userTypeMethod($propertySettings, $values);
2004 if ($property->
getCode() ===
'CML2_LINK')
2006 $description[
'editable'] =
false;
2009 $specialTypes = [
'custom',
'money',
'multimoney'];
2010 if (in_array($description[
'type'], $specialTypes,
true))
2012 $name = static::preparePropertyNameFromProperty($property);
2013 $descriptionData = $description[
'data'] ?? [];
2015 if ($description[
'type'] ===
'custom')
2017 $descriptionData += $this->getCustomControlParameters($name);
2019 elseif ($description[
'type'] ===
'money' || $description[
'type'] ===
'multimoney')
2021 $descriptionData[
'affectedFields'] = [
2022 $name .
'[CURRENCY]',
2025 $descriptionData[
'currency'] = [
2026 'name' => $name .
'[CURRENCY]',
2029 $descriptionData[
'amount'] = $name .
'[AMOUNT]';
2030 $descriptionData[
'currencyCode'] = $name .
'[CURRENCY]';
2031 $descriptionData[
'formatted'] = $name .
'[FORMATTED_AMOUNT]';
2032 $descriptionData[
'formattedWithCurrency'] = $name .
'[FORMATTED_AMOUNT_WITH_CURRENCY]';
2035 $description[
'data'] = $descriptionData;
2038 if (empty($description[
'data']))
2040 $description[
'data'] = [];
2043 $description[
'data'][
'isProductProperty'] =
true;
2045 return $description;
2053 static $currencyList =
null;
2055 if ($currencyList ===
null)
2059 foreach (CurrencyManager::getNameList() as $code => $name)
2063 'NAME' => htmlspecialcharsbx($name),
2068 return $currencyList;
2073 $propertySettings = $property->getSettings();
2075 if (!empty($propertySettings[
'USER_TYPE']))
2077 $propertySettings[
'PROPERTY_USER_TYPE'] = \CIBlockProperty::GetUserType($propertySettings[
'USER_TYPE']);
2080 return $propertySettings;
2088 if (!empty($value) && !is_array($value))
2093 if (is_array($value))
2095 $fileCount = min(count($value), 3);
2096 $value = reset($value);
2103 $image = \CFile::GetFileArray($value);
2106 $imageSrc = $image[
'SRC'];
2113 $multipleClass =
' ui-image-input-img-block-multiple';
2117 $multipleClass =
' ui-image-input-img-block-double';
2121 $multipleClass =
' ui-image-input-img-block-empty';
2126 $multipleClass =
'';
2132 $imageSrc =
" src=\"{$imageSrc}\"";
2135 <div
class=
"ui-image-input-img-block{$multipleClass}">
2136 <div
class=
"ui-image-input-img-block-inner">
2137 <div
class=
"ui-image-input-img-item">
2138 <img
class=
"ui-image-input-img"{$imageSrc}>
2151 protected function getApplication(): \CMain
2153 global $APPLICATION;
2155 return $APPLICATION;
2158 protected function getImageComponent(array
$params): string
2162 $this->getApplication()->includeComponent(
'bitrix:ui.image.input',
'',
$params);
2164 return ob_get_clean();
2167 protected function getFilePropertyEditHtml($description, $value, $controlId,
bool $multipleForList =
null): string
2169 if ($multipleForList ===
null)
2171 $multiple = $description[
'settings'][
'MULTIPLE'];
2175 $multiple = $multipleForList ?
'Y' :
'N';
2180 $this->getApplication()->IncludeComponent(
2181 'bitrix:main.file.input',
2184 'INPUT_NAME' => $description[
'name'],
2185 'INPUT_NAME_UNSAVED' => $description[
'name'] .
'_tmp',
2186 'INPUT_VALUE' => $value,
2187 'MULTIPLE' => $multiple,
2188 'MODULE_ID' =>
'catalog',
2189 'ALLOW_UPLOAD' =>
'F',
2190 'ALLOW_UPLOAD_EXT' => $description[
'settings'][
'FILE_TYPE'],
2191 'MAX_FILE_SIZE' =>
Ini::unformatInt((
string)ini_get(
'upload_max_filesize')),
2192 'CONTROL_ID' => $controlId,
2196 return ob_get_clean();
2199 protected function getFilePropertyViewHtml($description, $value, $controlId,
bool $multipleForList =
null)
2202 $signer = new \Bitrix\Main\Security\Sign\Signer();
2203 $signature = $signer->getSignature($cid,
'main.file.input');
2204 if (is_array($value))
2206 foreach ($value as $elementOfValue)
2216 if ($multipleForList ===
null)
2218 $multiple = $description[
'settings'][
'MULTIPLE'];
2222 $multiple = $multipleForList ?
'Y' :
'N';
2227 $this->getApplication()->IncludeComponent(
2228 'bitrix:main.field.file',
2232 'ID' => $description[
'settings'][
'ID'],
2234 'USER_TYPE_ID' =>
'file',
2235 'MULTIPLE' => $multiple,
2237 'additionalParameters' => [
2238 'mode' =>
'main.view',
2239 'CONTEXT' =>
'UI_EDITOR',
2240 'URL_TEMPLATE' =>
'/bitrix/components/bitrix/main.file.input/ajax.php?'
2242 .
'&fileID=#file_id#'
2244 .
'&sessid=' . bitrix_sessid()
2245 .
'&s=' . $signature,
2250 return ob_get_clean();
2253 protected function getImagePropertyEditHtml(array $property, $value): string
2255 $inputName = $this->getFilePropertyInputName($property);
2257 if ($value && !is_array($value))
2264 if (!empty($value) && is_array($value))
2266 foreach ($value as $valueItem)
2268 if (is_array($valueItem))
2270 $fileId = $valueItem[
'ID'];
2274 $fileId = $valueItem;
2276 $propName = str_replace(
'n#IND#', $fileId, $inputName);
2277 $fileValues[$propName] = $fileId;
2281 $fileType = $property[
'settings'][
'FILE_TYPE'] ??
null;
2284 'name' => $inputName,
2285 'id' => $inputName .
'_' . random_int(1, 1000000),
2286 'description' => $property[
'settings'][
'WITH_DESCRIPTION'] ??
'Y',
2287 'allowUpload' => $fileType ?
'F' :
'I',
2288 'allowUploadExt' => $fileType,
2289 'maxCount' => ($property[
'settings'][
'MULTIPLE'] ??
'N') !==
'Y' ? 1 : null,
2292 'medialib' => false,
2293 'fileDialog' => true,
2297 return $this->getImageComponent([
2298 'FILE_SETTINGS' => $fileParams,
2299 'FILE_VALUES' => $fileValues,
2304 protected function getFilePropertyInputName(array $property): string
2306 $inputName = $property[
'name'] ??
'';
2308 if (isset($property[
'settings'][
'MULTIPLE']) && $property[
'settings'][
'MULTIPLE'] ===
'Y')
2310 $inputName .=
'[n#IND#]';
2316 protected function getProductFieldValue(array $field)
2318 $value = $this->entity->getField($field[
'originalName']);
2320 if ($field[
'originalName'] ===
'PREVIEW_TEXT')
2322 $detailTextType = $this->entity->getField(
'PREVIEW_TEXT_TYPE');
2323 if ($detailTextType !==
'html')
2329 if ($field[
'originalName'] ===
'DETAIL_TEXT')
2331 $detailTextType = $this->entity->getField(
'DETAIL_TEXT_TYPE');
2332 if ($detailTextType !==
'html')
2338 if ($field[
'originalName'] ===
'VAT_ID' && $value ===
null && !$this->entity->isNew())
2345 $field[
'originalName'] ===
'ACTIVE_FROM'
2346 || $field[
'originalName'] ===
'ACTIVE_TO'
2348 && !($this instanceof GridVariationForm)
2357 $field[
'originalName'] ===
'TIMESTAMP_X'
2358 || $field[
'originalName'] ===
'DATE_CREATE'
2366 if ($field[
'originalName'] ===
'NAME-CODE')
2369 'NAME' => $this->entity->getField(
'NAME'),
2370 'CODE' => $this->entity->getField(
'CODE'),
2377 protected function getPropertyFieldValue(array $field)
2380 $property = $this->entity->getPropertyCollection()->findById($field[
'propertyId']);
2381 $value = $property ? $property->getPropertyValueCollection()->getValues() :
null;
2383 if (!isset($field[
'type']))
2388 if ($field[
'type'] ===
'html')
2390 if ($field[
'multiple'])
2392 foreach ($value as &$item)
2394 $item = $item[
'TEXT'] ??
null;
2399 $value = $value[
'TEXT'] ??
null;
2402 elseif ($property && $property->getUserType() === PropertyTable::USER_TYPE_SEQUENCE)
2404 if ($field[
'multiple'])
2406 foreach ($value as $valueItemKey => $valueItem)
2410 $value[$valueItemKey] = (int)$value;
2414 $value[$valueItemKey] = $this->getSequence(
2416 $property->getSetting(
'IBLOCK_ID')
2425 $value = (int)$value;
2429 $value = $this->getSequence(
2431 $property->getSetting(
'IBLOCK_ID')
2440 protected function getSequence(
int $propertyId,
int $propertyIblockId): int
2442 static $sequenceList = [];
2444 if (empty($sequenceList[$propertyId]))
2446 $sequence = new \CIBlockSequence($propertyIblockId, $propertyId);
2447 $isAjaxRequest = \Bitrix\Main\Context::getCurrent()->getRequest()->isAjaxRequest();
2448 $sequenceList[$propertyId] = $isAjaxRequest ? $sequence->getCurrent() : $sequence->getNext();
2451 return $sequenceList[$propertyId];
2454 protected function getMeasures(): array
2456 static $measures =
null;
2458 if ($measures ===
null)
2469 $measures = \Bitrix\Catalog\MeasureTable::getList(
$params)->fetchAll();
2475 protected function getVats(): array
2477 static $vats =
null;
2481 $vats = Catalog\VatTable::getList([
2482 'select' => [
'ID',
'NAME',
'RATE',
'EXCLUDE_VAT'],
2483 'filter' => [
'=ACTIVE' =>
'Y'],
2490 protected function getDefaultVat(): array
2493 $iblockVatId = $this->entity->getIblockInfo()->getVatId();
2495 foreach ($this->getVats() as $vat)
2497 if ($vat[
'EXCLUDE_VAT'] ===
'Y')
2502 if ((
int)$vat[
'ID'] === $iblockVatId)
2505 "CATALOG_C_F_DEFAULT",
2506 [
'#VALUE#' => htmlspecialcharsbx($vat[
'NAME'])]
2515 'EXCLUDE_VAT' =>
null,
2517 "CATALOG_C_F_DEFAULT",
2518 [
'#VALUE#' =>
Loc::getMessage(
"CATALOG_PRODUCT_CARD_VARIATION_GRID_NOT_SELECTED")]
2523 protected function getCustomControlParameters(
string $fieldName): array
2526 'view' => $fieldName .
'[VIEW_HTML]',
2527 'edit' => $fieldName .
'[EDIT_HTML]',
2528 'editList' => $fieldName .
'[EDIT_HTML_LIST]',
2529 'viewList' => $fieldName .
'[VIEW_HTML_LIST]',
2533 protected function getUserFieldType(array $userField): string
2535 $isMultiple = $userField[
'MULTIPLE'] ===
'Y';
2536 switch ($userField[
'USER_TYPE_ID'])
2538 case UserField\Types\BooleanType::USER_TYPE_ID:
2539 $result = Control\Type::BOOLEAN;
2541 case UserField\Types\DateTimeType::USER_TYPE_ID:
2542 case UserField\Types\DateType::USER_TYPE_ID:
2543 $result = $isMultiple ? Control\Type::MULTI_DATETIME : Control\Type::DATETIME;
2545 case UserField\Types\DoubleType::USER_TYPE_ID:
2546 case UserField\Types\IntegerType::USER_TYPE_ID:
2547 $result = $isMultiple ? Control\Type::MULTI_NUMBER : Control\Type::NUMBER;
2549 case UserField\Types\EnumType::USER_TYPE_ID:
2550 $result = $isMultiple ? Control\Type::MULTI_LIST : Control\Type::LIST;
2552 case UserField\Types\FileType::USER_TYPE_ID:
2553 $result = Control\Type::CUSTOM;
2555 case UserField\Types\StringFormattedType::USER_TYPE_ID:
2556 $result = Control\Type::TEXTAREA;
2558 case UserField\Types\StringType::USER_TYPE_ID:
2559 $result = $isMultiple ? Control\Type::MULTI_TEXT : Control\Type::TEXT;
2561 case UserField\Types\UrlType::USER_TYPE_ID:
2562 $result = Control\Type::LINK;
2566 Loader::includeModule(
'highloadblock')
2567 && $userField[
'USER_TYPE_ID'] === \CUserTypeHlblock::USER_TYPE_ID
2570 $result = $isMultiple ? Control\Type::MULTI_LIST : Control\Type::LIST;
2574 $result = Control\Type::TEXT;