18Loc::loadMessages(__FILE__);
20abstract class Base extends \CBitrixComponent
35 private $cacheUsage =
true;
36 private $extendedMode =
true;
85 parent::__construct($component);
107 $this->action = $action;
117 return (
bool)
count($this->errorCollection);
125 protected function processErrors()
127 if (!empty($this->errorCollection))
130 foreach ($this->errorCollection as
$error)
134 if (
$code == self::ERROR_404)
137 $this->arParams[
'MESSAGE_404'] ?:
$error->getMessage(),
139 $this->arParams[
'SET_STATUS_404'] ===
'Y',
140 $this->arParams[
'SHOW_404'] ===
'Y',
141 $this->arParams[
'FILE_404']
162 $this->cacheUsage = (bool)$state;
174 return !$this->cacheUsage;
187 $this->extendedMode = (bool)$state;
199 return $this->extendedMode;
210 $this->compatibleMode = (bool)$state;
220 return $this->compatibleMode;
229 $this->separateLoading = (bool)$state;
237 return $this->separateLoading;
249 if ($settingsName ===
'filter_conditions')
259 return $path.
'?'.$file->getModificationTime();
275 if (!isset(
$params[
'CURRENT_BASE_PAGE']))
285 $params[
'PARENT_NAME'] = $parent->getName();
286 $params[
'PARENT_TEMPLATE_NAME'] = $parent->getTemplateName();
287 $params[
'PARENT_TEMPLATE_PAGE'] = $parent->getTemplatePage();
291 $this->arResult[
'ORIGINAL_PARAMETERS'] =
$params;
293 if (isset(
$params[
'CUSTOM_SITE_ID']) && is_string(
$params[
'CUSTOM_SITE_ID']))
301 $ajaxId = $this->request->get(
'AJAX_ID');
315 $params[
'SECTION_CODE'] = trim((
string)(
$params[
'SECTION_CODE'] ??
''));
316 $params[
'SECTION_URL'] = trim((
string)(
$params[
'SECTION_URL'] ??
''));
317 $params[
'STRICT_SECTION_CHECK'] = isset(
$params[
'STRICT_SECTION_CHECK']) &&
$params[
'STRICT_SECTION_CHECK'] ===
'Y';
319 $params[
'CHECK_LANDING_PRODUCT_SECTION'] = (
320 isset(
$params[
'CHECK_LANDING_PRODUCT_SECTION'])
321 &&
$params[
'CHECK_LANDING_PRODUCT_SECTION'] ===
'Y'
324 $params[
'DETAIL_URL'] = trim((
string)(
$params[
'DETAIL_URL'] ??
''));
325 $params[
'BASKET_URL'] = trim((
string)(
$params[
'BASKET_URL'] ??
''));
326 if (
$params[
'BASKET_URL'] ===
'')
328 $params[
'BASKET_URL'] =
'/personal/basket.php';
331 $params[
'SHOW_SKU_DESCRIPTION'] =
$params[
'SHOW_SKU_DESCRIPTION'] ??
'N';
333 $params[
'HIDE_DETAIL_URL'] = isset(
$params[
'HIDE_DETAIL_URL']) &&
$params[
'HIDE_DETAIL_URL'] ===
'Y';
335 $params[
'ACTION_VARIABLE'] = trim((
string)(
$params[
'ACTION_VARIABLE'] ??
''));
336 if (
$params[
'ACTION_VARIABLE'] ===
'' || !preg_match(self::PARAM_TITLE_MASK,
$params[
'ACTION_VARIABLE']))
338 $params[
'ACTION_VARIABLE'] =
'action';
341 $params[
'PRODUCT_ID_VARIABLE'] = trim((
string)(
$params[
'PRODUCT_ID_VARIABLE'] ??
''));
343 $params[
'PRODUCT_ID_VARIABLE'] ===
''
344 || !preg_match(self::PARAM_TITLE_MASK,
$params[
'PRODUCT_ID_VARIABLE'])
347 $params[
'PRODUCT_ID_VARIABLE'] =
'id';
350 $params[
'ACTION_COMPARE_VARIABLE'] = trim((
string)(
$params[
'ACTION_COMPARE_VARIABLE'] ??
''));
352 $params[
'ACTION_COMPARE_VARIABLE'] ===
''
353 || !preg_match(self::PARAM_TITLE_MASK,
$params[
'ACTION_COMPARE_VARIABLE'])
359 $params[
'PRODUCT_QUANTITY_VARIABLE'] = trim((
string)(
$params[
'PRODUCT_QUANTITY_VARIABLE'] ??
''));
361 $params[
'PRODUCT_QUANTITY_VARIABLE'] ===
''
362 || !preg_match(self::PARAM_TITLE_MASK,
$params[
'PRODUCT_QUANTITY_VARIABLE'])
365 $params[
'PRODUCT_QUANTITY_VARIABLE'] =
'quantity';
368 $params[
'PRODUCT_PROPS_VARIABLE'] = trim((
string)(
$params[
'PRODUCT_PROPS_VARIABLE'] ??
''));
370 $params[
'PRODUCT_PROPS_VARIABLE'] ===
''
371 || !preg_match(self::PARAM_TITLE_MASK,
$params[
'PRODUCT_PROPS_VARIABLE'])
374 $params[
'PRODUCT_PROPS_VARIABLE'] =
'prop';
379 isset(
$params[
'ALLOW_SEO_DATA'])
380 && (
$params[
'ALLOW_SEO_DATA'] ===
'Y' ||
$params[
'ALLOW_SEO_DATA'] ===
'N')
391 $params[
'SET_BROWSER_TITLE'] = isset(
$params[
'SET_BROWSER_TITLE']) &&
$params[
'SET_BROWSER_TITLE'] ===
'N' ?
'N' :
'Y';
392 $params[
'SET_META_KEYWORDS'] = isset(
$params[
'SET_META_KEYWORDS']) &&
$params[
'SET_META_KEYWORDS'] ===
'N' ?
'N' :
'Y';
393 $params[
'SET_META_DESCRIPTION'] = isset(
$params[
'SET_META_DESCRIPTION']) &&
$params[
'SET_META_DESCRIPTION'] ===
'N' ?
'N' :
'Y';
395 $params[
'SET_LAST_MODIFIED'] = isset(
$params[
'SET_LAST_MODIFIED']) &&
$params[
'SET_LAST_MODIFIED'] ===
'Y';
396 $params[
'ADD_SECTIONS_CHAIN'] = isset(
$params[
'ADD_SECTIONS_CHAIN']) &&
$params[
'ADD_SECTIONS_CHAIN'] ===
'Y';
398 $params[
'DISPLAY_COMPARE'] = isset(
$params[
'DISPLAY_COMPARE']) &&
$params[
'DISPLAY_COMPARE'] ===
'Y';
399 $params[
'COMPARE_PATH'] = trim((
string)(
$params[
'COMPARE_PATH'] ??
''));
400 $params[
'COMPARE_NAME'] = trim((
string)(
$params[
'COMPARE_NAME'] ??
''));
401 if (
$params[
'COMPARE_NAME'] ===
'')
403 $params[
'COMPARE_NAME'] =
'CATALOG_COMPARE_LIST';
405 $params[
'USE_COMPARE_LIST'] = (isset(
$params[
'USE_COMPARE_LIST']) &&
$params[
'USE_COMPARE_LIST'] ===
'Y' ?
'Y' :
'N');
407 $params[
'USE_PRICE_COUNT'] = isset(
$params[
'USE_PRICE_COUNT']) &&
$params[
'USE_PRICE_COUNT'] ===
'Y';
408 $params[
'SHOW_PRICE_COUNT'] = (int)(
$params[
'SHOW_PRICE_COUNT'] ?? 1);
409 if (
$params[
'SHOW_PRICE_COUNT'] <= 0)
411 $params[
'SHOW_PRICE_COUNT'] = 1;
413 $params[
'FILL_ITEM_ALL_PRICES'] = isset(
$params[
'FILL_ITEM_ALL_PRICES']) &&
$params[
'FILL_ITEM_ALL_PRICES'] ===
'Y';
415 $params[
'USE_PRODUCT_QUANTITY'] = isset(
$params[
'USE_PRODUCT_QUANTITY']) &&
$params[
'USE_PRODUCT_QUANTITY'] ===
'Y';
417 $params[
'ADD_PROPERTIES_TO_BASKET'] = isset(
$params[
'ADD_PROPERTIES_TO_BASKET']) &&
$params[
'ADD_PROPERTIES_TO_BASKET'] ===
'N' ?
'N' :
'Y';
418 if (
Iblock\
Model\PropertyFeature::isEnabledFeatures())
419 $params[
'ADD_PROPERTIES_TO_BASKET'] =
'Y';
420 if (
$params[
'ADD_PROPERTIES_TO_BASKET'] ===
'N')
426 $params[
'PARTIAL_PRODUCT_PROPERTIES'] = isset(
$params[
'PARTIAL_PRODUCT_PROPERTIES']) &&
$params[
'PARTIAL_PRODUCT_PROPERTIES'] ===
'Y' ?
'Y' :
'N';
428 $params[
'OFFERS_SORT_FIELD'] = trim((
string)(
$params[
'OFFERS_SORT_FIELD'] ??
''));
429 if (
$params[
'OFFERS_SORT_FIELD'] ===
'')
431 $params[
'OFFERS_SORT_FIELD'] =
'sort';
434 $params[
'OFFERS_SORT_ORDER'] = trim((
string)(
$params[
'OFFERS_SORT_ORDER'] ??
''));
436 $params[
'OFFERS_SORT_ORDER'] ===
''
437 || !preg_match(self::SORT_ORDER_MASK,
$params[
'OFFERS_SORT_ORDER'])
440 $params[
'OFFERS_SORT_ORDER'] =
'asc';
443 $params[
'OFFERS_SORT_FIELD2'] = trim((
string)(
$params[
'OFFERS_SORT_FIELD2'] ??
''));
444 if (
$params[
'OFFERS_SORT_FIELD2'] ===
'')
446 $params[
'OFFERS_SORT_FIELD2'] =
'id';
449 $params[
'OFFERS_SORT_ORDER2'] = trim((
string)(
$params[
'OFFERS_SORT_ORDER2'] ??
''));
451 $params[
'OFFERS_SORT_ORDER2'] ===
''
452 || !preg_match(self::SORT_ORDER_MASK,
$params[
'OFFERS_SORT_ORDER2'])
455 $params[
'OFFERS_SORT_ORDER2'] =
'desc';
458 $params[
'PRICE_VAT_INCLUDE'] = !(isset(
$params[
'PRICE_VAT_INCLUDE']) &&
$params[
'PRICE_VAT_INCLUDE'] ===
'N');
460 $params[
'CONVERT_CURRENCY'] = isset(
$params[
'CONVERT_CURRENCY']) &&
$params[
'CONVERT_CURRENCY'] ===
'Y' ?
'Y' :
'N';
462 if (!is_scalar(
$params[
'CURRENCY_ID']))
467 if (
$params[
'CURRENCY_ID'] ===
'' ||
$params[
'CONVERT_CURRENCY'] ===
'N')
469 $params[
'CONVERT_CURRENCY'] =
'N';
474 if (
$params[
'OFFERS_LIMIT'] < 0)
479 $params[
'CACHE_GROUPS'] = trim((
string)(
$params[
'CACHE_GROUPS'] ??
''));
480 if (
$params[
'CACHE_GROUPS'] !==
'N')
485 if (isset(
$params[
'~PRICE_CODE']))
490 if (!is_array(
$params[
'PRICE_CODE']))
495 $params[
'SHOW_FROM_SECTION'] = isset(
$params[
'SHOW_FROM_SECTION']) &&
$params[
'SHOW_FROM_SECTION'] ===
'Y' ?
'Y' :
'N';
496 if (
$params[
'SHOW_FROM_SECTION'] ===
'Y')
498 $params[
'SECTION_ELEMENT_ID'] = (int)(
$params[
'SECTION_ELEMENT_ID'] ?? 0);
499 $params[
'SECTION_ELEMENT_CODE'] = trim((
string)(
$params[
'SECTION_ELEMENT_CODE'] ??
''));
502 if (empty(
$params[
'SECTION_ID']))
504 if (
$params[
'SECTION_CODE'] !==
'')
512 $params[
'SECTION_ELEMENT_CODE'],
517 $params[
'SECTION_ID'] = $sectionId;
522 if (!is_array(
$params[
'FILTER_IDS']))
527 $params[
'MESSAGE_404'] = trim((
string)(
$params[
'MESSAGE_404'] ??
''));
528 $params[
'SET_STATUS_404'] = (
$params[
'SET_STATUS_404'] ??
'N') ===
'Y' ?
'Y' :
'N';
529 $params[
'SHOW_404'] = (
$params[
'SHOW_404'] ??
'N') ===
'Y' ?
'Y' :
'N';
543 $this->storage[
'MODULES'] =
array(
545 'catalog' => $this->useCatalog,
546 'currency' => $this->useCatalog
559 if ($this->useCatalog && $this->useDiscountCache && !empty($this->elementLinks))
561 foreach ($this->iblockProducts as
$iblock => $products)
563 if ($this->storage[
'USE_SALE_DISCOUNTS'])
584 if ($this->useCatalog && $this->useDiscountCache)
601 $this->storage[
'CONVERT_CURRENCY'] =
array();
603 if ($this->arParams[
'CONVERT_CURRENCY'] ===
'Y')
608 $this->storage[
'MODULES'][
'currency'] =
true;
613 $this->storage[
'CONVERT_CURRENCY'] =
array(
614 'CURRENCY_ID' => $this->arParams[
'CURRENCY_ID']
619 $this->arParams[
'CONVERT_CURRENCY'] =
'N';
620 $this->arParams[
'CURRENCY_ID'] =
'';
634 if (empty($this->storage[
'CATALOGS'][
$iblockId]))
639 if (empty(
$catalog[
'CATALOG_TYPE']))
642 return $catalog[
'CATALOG_TYPE'] == \CCatalogSku::TYPE_FULL ||
$catalog[
'CATALOG_TYPE'] == \CCatalogSku::TYPE_PRODUCT;
654 if ($this->useCatalog)
656 $this->storage[
'SHOW_CATALOG_WITH_OFFERS'] =
Main\Config\Option::get(
'catalog',
'show_catalog_tab_with_offers') ===
'Y';
658 foreach (array_keys($this->iblockProducts) as
$iblockId)
663 $this->isIblockCatalog = $this->isIblockCatalog ||
$catalog[
'CATALOG_TYPE'] != \CCatalogSku::TYPE_PRODUCT;
669 $this->storage[
'CATALOGS'] = $catalogs;
674 if (!$this->useCatalog)
677 $productId = (int)$productId;
681 $iblockId = (int)\CIBlockElement::GetIBlockByID($productId);
686 'select' => [
'ID',
'TYPE'],
687 'filter' => [
'=ID' => $productId]
694 $row[
'ID'] = (int)$row[
'ID'];
695 $row[
'TYPE'] = (int)$row[
'TYPE'];
697 $row[
'TYPE'] ==
Catalog\ProductTable::TYPE_EMPTY_SKU
698 || $row[
'TYPE'] ==
Catalog\ProductTable::TYPE_FREE_OFFER
703 $row[
'PRODUCT_IBLOCK_ID'] = 0;
705 if (isset($this->storage[
'CATALOGS'][
$iblockId]))
707 if ($this->storage[
'CATALOGS'][
$iblockId][
'CATALOG_TYPE'] == \CCatalogSku::TYPE_CATALOG)
708 $row[
'PRODUCT_IBLOCK_ID'] = $this->storage[
'CATALOGS'][
$iblockId][
'IBLOCK_ID'];
710 $row[
'PRODUCT_IBLOCK_ID'] = $this->storage[
'CATALOGS'][
$iblockId][
'PRODUCT_IBLOCK_ID'];
718 if (
$catalog[
'CATALOG_TYPE'] == \CCatalogSku::TYPE_PRODUCT)
721 if (
$catalog[
'CATALOG_TYPE'] == \CCatalogSku::TYPE_OFFERS)
726 if (!isset($this->storage[
'CATALOGS']))
727 $this->storage[
'CATALOGS'] = [];
731 if ($this->storage[
'CATALOGS'][
$iblockId][
'CATALOG_TYPE'] == \CCatalogSku::TYPE_CATALOG)
732 $row[
'PRODUCT_IBLOCK_ID'] = $this->storage[
'CATALOGS'][
$iblockId][
'IBLOCK_ID'];
734 $row[
'PRODUCT_IBLOCK_ID'] = $this->storage[
'CATALOGS'][
$iblockId][
'PRODUCT_IBLOCK_ID'];
748 isset($this->arParams[
'IBLOCK_ID']) && $this->arParams[
'IBLOCK_ID'] > 0 ? $this->arParams[
'IBLOCK_ID'] :
false,
749 $this->arParams[
'PRICE_CODE']
752 $this->storage[
'PRICES_CAN_BUY'] =
array();
753 $this->storage[
'PRICES_MAP'] =
array();
754 foreach ($this->storage[
'PRICES'] as $priceType)
756 $this->storage[
'PRICES_MAP'][$priceType[
'ID']] = $priceType[
'CODE'];
757 if ($priceType[
'CAN_BUY'])
758 $this->storage[
'PRICES_CAN_BUY'][$priceType[
'ID']] = $priceType[
'ID'];
761 $this->storage[
'PRICE_TYPES'] =
array();
762 if ($this->useCatalog)
765 $this->useDiscountCache =
false;
766 if ($this->useCatalog)
768 if (!empty($this->storage[
'CATALOGS']) && !empty($this->storage[
'PRICES_ALLOW']))
769 $this->useDiscountCache =
true;
772 if ($this->useCatalog && $this->useDiscountCache)
775 $this->storage[
'PRICES_ALLOW'],
780 if ($this->useCatalog)
781 Catalog\Product\Price::loadRoundRules($this->storage[
'PRICES_ALLOW']);
791 $this->storage[
'VATS'] = [];
792 $this->storage[
'IBLOCKS_VAT'] = [];
793 if ($this->useCatalog)
796 'select' => [
'ID',
'RATE'],
797 'order' => [
'ID' =>
'ASC']
800 $this->storage[
'VATS'][(int)$row[
'ID']] = (
float)$row[
'RATE'];
803 if (!empty($this->storage[
'CATALOGS']))
805 foreach ($this->storage[
'CATALOGS'] as
$catalog)
807 $this->storage[
'IBLOCKS_VAT'][
$catalog[
'IBLOCK_ID']] = 0;
808 if (
$catalog[
'PRODUCT_IBLOCK_ID'] > 0)
809 $this->storage[
'IBLOCKS_VAT'][
$catalog[
'PRODUCT_IBLOCK_ID']] = 0;
814 'select' => [
'IBLOCK_ID',
'VAT_ID'],
815 'filter' => [
'@IBLOCK_ID' => array_keys($this->storage[
'IBLOCKS_VAT'])]
818 $this->storage[
'IBLOCKS_VAT'][(int)$row[
'IBLOCK_ID']] = (
int)$row[
'VAT_ID'];
839 $this->storage[
'CURRENCY_LIST'] =
array();
844 foreach ($this->iblockProducts as
$iblock => $products)
849 if (!empty($iblockElements) && !$this->
hasErrors())
852 $this->elements = array_merge($this->elements, array_values($iblockElements));
853 $this->iblockProducts[
$iblock] = array_keys($iblockElements);
856 unset($elementIterator, $iblockElements, $element);
875 if (!empty($this->productIdMap) && is_array($this->productIdMap))
877 $sortedElements =
array();
879 foreach (array_keys($this->productIdMap) as $productId)
881 $parentId = $this->productIdMap[$productId];
883 foreach ($this->elements as $element)
885 if ($element[
'ID'] == $parentId)
887 $sortedElements[$productId] = $element;
893 $this->elements = array_values($sortedElements);
904 if (!empty($this->elements))
906 foreach ($this->elements as $index => $element)
908 $this->elementLinks[$element[
'ID']] =& $this->elements[$index];
930 $shownIds = $this->request->get(
'shownIds');
931 if (!empty($shownIds) && is_array($shownIds))
933 $this->arParams[
'FILTER_IDS'] += $shownIds;
936 $this->arParams[
'PAGE_ELEMENT_COUNT'] = $this->request->get(
'count') ?: 20;
937 $this->arParams[
'FILTER'] ??= [];
938 $this->arParams[
'FILTER'] = $this->arParams[
'FILTER'] ?: [
'PAYED'];
939 $this->arParams[
'BY'] ??=
'';
940 $this->arParams[
'BY'] = $this->arParams[
'BY'] ?:
'AMOUNT';
941 $this->arParams[
'PERIOD'] ??= 0;
942 $this->arParams[
'PERIOD'] = (int)$this->arParams[
'PERIOD'] ?: 30;
943 $this->arParams[
'DEPTH'] ??= 0;
944 $this->arParams[
'DEPTH'] = (int)$this->arParams[
'DEPTH'] ?: 2;
947 $this->filterFields = $this->
getFilter();
948 $this->filterFields[
'IBLOCK_ID'] = $this->arParams[
'IBLOCK_ID'];
952 $ids = $this->request->get(
'items') ?:
array();
955 $recommendationId = $this->request->get(
'rid');
956 $ids = $this->
filterByParams($ids, $this->arParams[
'FILTER_IDS']);
958 foreach ($ids as $id)
960 $this->recommendationIdToProduct[$id] = $recommendationId;
971 if ($this->useCatalog &&
count($ids) < $this->arParams[
'PAGE_ELEMENT_COUNT'])
977 if (
count($ids) < $this->arParams[
'PAGE_ELEMENT_COUNT'])
983 return array_slice($ids, 0, $this->arParams[
'PAGE_ELEMENT_COUNT']);
995 $this->arParams[
'PAGE_ELEMENT_COUNT'] = $this->arParams[
'PAGE_ELEMENT_COUNT'] * 10;
997 $this->arParams[
'PAGE_ELEMENT_COUNT'] = $this->arParams[
'PAGE_ELEMENT_COUNT'] / 10;
999 if (!empty($bestsellers))
1001 $recommendationId =
'bestsellers';
1003 $bestsellers = $this->
filterByParams($bestsellers, $this->arParams[
'FILTER_IDS']);
1005 foreach ($bestsellers as $id)
1007 if (!isset($this->recommendationIdToProduct[$id]))
1009 $this->recommendationIdToProduct[$id] = $recommendationId;
1013 $ids = array_unique(array_merge($ids, $bestsellers));
1027 $mostViewed =
array();
1028 $recommendationId =
'mostviewed';
1030 $result = Catalog\CatalogViewedProductTable::getList(
array(
1038 '>DATE_VISIT' =>
new Main\
Type\
DateTime(date(
'Y-m-d H:i:s', strtotime(
'-30 days')),
'Y-m-d H:i:s')
1040 'order' =>
array(
'SUM_HITS' =>
'DESC'),
1041 'limit' => $this->arParams[
'PAGE_ELEMENT_COUNT'] * 10
1043 while ($row =
$result->fetch())
1045 $mostViewed[] = $row[
'ELEMENT_ID'];
1049 $mostViewed = $this->
filterByParams($mostViewed, $this->arParams[
'FILTER_IDS']);
1051 foreach ($mostViewed as $id)
1053 if (!isset($this->recommendationIdToProduct[$id]))
1055 $this->recommendationIdToProduct[$id] = $recommendationId;
1059 return array_unique(array_merge($ids, $mostViewed));
1077 $randomIds =
array();
1078 $recommendationId =
'random';
1081 $filterIds = array_merge($ids, $this->arParams[
'FILTER_IDS']);
1082 if (!empty($filterIds))
1087 if ($this->arParams[
'SHOW_FROM_SECTION'] ===
'Y' && !empty($this->arParams[
'SECTION_ID']))
1089 $filter[
'SECTION_ID'] = $this->arParams[
'SECTION_ID'];
1092 $elementIterator = \CIBlockElement::GetList(
array(
'RAND' =>
'ASC'),
$filter,
false,
array(
'nTopCount' => $limit),
array(
'ID'));
1093 while ($element = $elementIterator->Fetch())
1095 $randomIds[] = $element[
'ID'];
1098 if (!empty($randomIds))
1103 foreach ($randomIds as $id)
1105 if (!isset($this->recommendationIdToProduct[$id]))
1107 $this->recommendationIdToProduct[$id] = $recommendationId;
1111 return array_merge($ids, $randomIds);
1129 $ids = array_values(array_unique($ids));
1131 if (!empty($filterIds))
1133 $ids = array_diff($ids, $filterIds);
1141 $correctIds =
array();
1142 $elementIterator = \CIBlockElement::GetList(
array(),
$filter,
false,
false,
array(
'ID'));
1143 while ($element = $elementIterator->Fetch())
1145 $correctIds[] = $element[
'ID'];
1148 if ($useSectionFilter && !empty($correctIds) && $this->arParams[
'SHOW_FROM_SECTION'] ===
'Y')
1152 $this->arParams[
'IBLOCK_ID'],
1153 $this->arParams[
'SECTION_ID'],
1154 $this->arParams[
'PAGE_ELEMENT_COUNT'],
1155 $this->arParams[
'DEPTH']
1159 $correctIds = array_flip($correctIds);
1161 foreach ($ids as
$key => $id)
1163 if (!isset($correctIds[$id]))
1169 return array_values($ids);
1186 $sectionCode = (string)$sectionCode;
1188 if ($sectionCode ===
'')
1193 $sectionFilter = [];
1196 $sectionFilter[
'=IBLOCK_ID'] =
$iblockId;
1198 elseif (!empty($this->arParams[
'IBLOCK_ID']))
1200 $sectionFilter[
'@IBLOCK_ID'] = $this->arParams[
'IBLOCK_ID'];
1202 if (empty($sectionFilter))
1207 $sectionFilter[
'=IBLOCK.ACTIVE'] =
'Y';
1208 $sectionFilter[
'=CODE'] = $sectionCode;
1211 'select' =>
array(
'ID'),
1212 'filter' => $sectionFilter
1214 if (!empty($section))
1216 $sectionId = (int)$section[
'ID'];
1232 $elementId = (int)$elementId;
1233 $elementCode = (string)$elementCode;
1240 elseif (!empty($this->arParams[
'IBLOCK_ID']))
1242 $filter[
'=IBLOCK_ID'] = $this->arParams[
'IBLOCK_ID'];
1253 elseif ($elementCode !==
'')
1255 $filter[
'=CODE'] = $elementCode;
1263 'select' =>
array(
'ID',
'IBLOCK_SECTION_ID'),
1266 if ($item = $itemIterator->fetch())
1268 $sectionId = (int)$item[
'IBLOCK_SECTION_ID'];
1280 if (empty($elementIds))
1284 $sectionId = (int)$sectionId;
1285 $limit = (int)$limit;
1286 $depth = (int)$depth;
1291 $subSections =
array();
1295 if ($parentSectionId !==
null)
1297 $subSections[$parentSectionId] = $parentSectionId;
1299 unset($parentSectionId);
1302 if (empty($subSections) && $sectionId <= 0)
1305 'select' =>
array(
'ID'),
1307 '@ID' => $elementIds,
1309 '=WF_STATUS_ID' => 1,
1310 '=WF_PARENT_ELEMENT_ID' =>
null
1322 if (empty($subSections))
1324 $subSections[$sectionId] = $sectionId;
1328 $sectionQuery->setTableAliasPostfix(
'_parent');
1329 $sectionQuery->setSelect(
array(
'ID',
'LEFT_MARGIN',
'RIGHT_MARGIN'));
1330 $sectionQuery->setFilter(
array(
'@ID' => $subSections));
1333 $subSectionQuery->setTableAliasPostfix(
'_sub');
1334 $subSectionQuery->setSelect(
array(
'ID'));
1336 $subSectionQuery->registerRuntimeField(
1340 Main\
Entity\Base::getInstanceByQuery($sectionQuery),
1341 array(
'>=this.LEFT_MARGIN' =>
'ref.LEFT_MARGIN',
'<=this.RIGHT_MARGIN' =>
'ref.RIGHT_MARGIN'),
1342 array(
'join_type' =>
'INNER')
1346 $sectionElementQuery =
new Main\Entity\Query(
Iblock\SectionElementTable::getEntity());
1347 $sectionElementQuery->setSelect(
array(
'IBLOCK_ELEMENT_ID'));
1348 $sectionElementQuery->setGroup(
array(
'IBLOCK_ELEMENT_ID'));
1349 $sectionElementQuery->setFilter(
array(
'=ADDITIONAL_PROPERTY_ID' =>
null));
1350 $sectionElementQuery->registerRuntimeField(
1354 Main\
Entity\Base::getInstanceByQuery($subSectionQuery),
1355 array(
'=this.IBLOCK_SECTION_ID' =>
'ref.ID'),
1356 array(
'join_type' =>
'INNER')
1361 $elementQuery->setSelect(
array(
'ID'));
1362 $elementQuery->setFilter(
array(
'=IBLOCK_ID' =>
$iblockId,
'=WF_STATUS_ID' => 1,
'=WF_PARENT_ELEMENT_ID' =>
null));
1363 $elementQuery->registerRuntimeField(
1367 Main\
Entity\Base::getInstanceByQuery($sectionElementQuery),
1368 array(
'=this.ID' =>
'ref.IBLOCK_ELEMENT_ID'),
1369 array(
'join_type' =>
'INNER')
1374 $elementQuery->setLimit($limit);
1379 unset($elementQuery, $sectionElementQuery, $subSectionQuery, $sectionQuery);
1384 $map[] = $row[
'ID'];
1401 $idsCount =
count($ids);
1402 $rowsRange = $this->request->get(
'rowsRange');
1404 if (!empty($rowsRange))
1406 foreach ($rowsRange as $range)
1408 $range = (int)$range;
1410 if ($range > $idsCount)
1412 $limit = $range - $idsCount;
1419 $limit = $this->arParams[
'PAGE_ELEMENT_COUNT'] - $idsCount;
1428 'uid' => ($_COOKIE[
'BX_USER_ID'] ??
''),
1430 'count' => max($this->arParams[
'PAGE_ELEMENT_COUNT'] * 2, 30)
1434 if (
$type ===
'any_similar')
1436 $possible =
array(
'similar_sell',
'similar_view',
'similar');
1437 $type = $possible[array_rand($possible)];
1441 $possible =
array(
'bestsell',
'personal');
1442 $type = $possible[array_rand($possible)];
1446 $possible =
array(
'similar_sell',
'similar_view',
'similar',
'bestsell',
'personal');
1447 $type = $possible[array_rand($possible)];
1454 $params[
'op'] =
'sim_domain_items';
1456 $params[
'domain'] = Main\Context::getCurrent()->getServer()->getHttpHost();
1461 case 'similar_sell':
1463 $params[
'eid'] = $this->arParams[
'RCM_PROD_ID'];
1466 case 'similar_view':
1468 $params[
'eid'] = $this->arParams[
'RCM_PROD_ID'];
1473 $params[
'eid'] = $this->arParams[
'RCM_PROD_ID'];
1481 if (!empty($this->storage[
'IBLOCK_PARAMS']))
1483 $iblocks = array_keys($this->storage[
'IBLOCK_PARAMS']);
1490 'select' =>
array(
'IBLOCK_ID',
'PRODUCT_IBLOCK_ID')
1492 while (
$iblock = $iblockIterator->fetch())
1495 $iblock[
'PRODUCT_IBLOCK_ID'] = (int)
$iblock[
'PRODUCT_IBLOCK_ID'];
1498 if (
$iblock[
'PRODUCT_IBLOCK_ID'] > 0)
1505 $iblockIterator = Iblock\IblockSiteTable::getList(
array(
1506 'select' =>
array(
'IBLOCK_ID'),
1509 while (
$iblock = $iblockIterator->fetch())
1511 $iblocks[] =
$iblock[
'IBLOCK_ID'];
1515 $params[
'ib'] = join(
'.', $iblocks);
1533 $this->arParams[
'BY'],
1536 $this->arParams[
'PAGE_ELEMENT_COUNT']
1538 while($product = $productIterator->fetch())
1551 if (!empty($this->arParams[
'FILTER']))
1554 $subFilter =
array(
'LOGIC' =>
'OR');
1558 'ALLOW_DELIVERY' =>
true,
1563 if ($this->arParams[
'PERIOD'] > 0)
1568 foreach ($this->arParams[
'FILTER'] as $field)
1570 if (isset($statuses[$field]))
1572 $subFilter[] =
array(
1573 '>=DATE_'.$field => $date,
1579 if (empty($this->storage[
'ORDER_STATUS']) || in_array($field, $this->storage[
'ORDER_STATUS']))
1581 $subFilter[] =
array(
1582 '=STATUS_ID' => $field,
1583 '>=DATE_UPDATE' => $date,
1593 foreach ($this->arParams[
'FILTER'] as $field)
1595 if (isset($statuses[$field]))
1597 $subFilter[] =
array(
1603 if (empty($this->storage[
'ORDER_STATUS']) || in_array($field, $this->storage[
'ORDER_STATUS']))
1605 $subFilter[] =
array(
1606 '=STATUS_ID' => $field,
1648 if (empty($originalIds))
1654 $productList = \CCatalogSku::getProductList($originalIds);
1655 if ($productList ===
false)
1657 $productList =
array();
1660 foreach ($originalIds as $id)
1662 $result[$id] = isset($productList[$id]) ? $productList[$id][
'ID'] : (int)$id;
1680 $iblockItems =
array();
1682 if (!empty($this->productIdMap) && is_array($this->productIdMap))
1685 'select' =>
array(
'ID',
'IBLOCK_ID'),
1686 'filter' =>
array(
'@ID' => $this->productIdMap)
1688 while ($item = $itemsIterator->fetch())
1690 $item[
'ID'] = (int)$item[
'ID'];
1691 $item[
'IBLOCK_ID'] = (int)$item[
'IBLOCK_ID'];
1693 if (!isset($iblockItems[$item[
'IBLOCK_ID']]))
1695 $iblockItems[$item[
'IBLOCK_ID']] =
array();
1698 $iblockItems[$item[
'IBLOCK_ID']][] = $item[
'ID'];
1700 unset($item, $itemsIterator);
1702 elseif ($this->productIdMap ===
false)
1704 $iblockItems[$this->arParams[
'IBLOCK_ID']] = $this->arParams[
'ELEMENT_ID'] ?? 0;
1707 return $iblockItems;
1717 $defaultMeasure =
array();
1719 if ($this->useCatalog)
1721 $defaultMeasure = \CCatalogMeasure::getDefaultMeasure(
true,
true);
1724 return $defaultMeasure;
1743 if (!empty($products))
1749 if (!empty($this->globalFilter))
1755 'order' => $this->sortFields,
1766 unset($iteratorParams);
1768 $elementIterator->SetUrlTemplates($this->arParams[
'DETAIL_URL']);
1770 return $elementIterator;
1799 $id = (int)$row[
'ID'];
1802 'IBLOCK_ID' => $row[
'IBLOCK_ID'],
1809 $fullIterator = \CIBlockElement::GetList(
1811 [
'IBLOCK_ID' =>
$params[
'filter'][
'IBLOCK_ID'],
'ID' => array_keys($list),
'SITE_ID' => $this->
getSiteId()],
1816 while ($row = $fullIterator->Fetch())
1818 $id = (int)$row[
'ID'];
1819 $list[$id] = $list[$id] + $row;
1821 unset($row, $fullIterator);
1823 $iterator->InitFromArray(array_values($list));
1835 return \CIBlockElement::GetList(
1851 $this->selectFields = $this->
getSelect();
1852 $this->filterFields = $this->
getFilter();
1853 $this->sortFields = $this->
getSort();
1865 'ID',
'IBLOCK_ID',
'CODE',
'XML_ID',
'NAME',
'ACTIVE',
'DATE_ACTIVE_FROM',
'DATE_ACTIVE_TO',
'SORT',
1866 'PREVIEW_TEXT',
'PREVIEW_TEXT_TYPE',
'DETAIL_TEXT',
'DETAIL_TEXT_TYPE',
'DATE_CREATE',
'CREATED_BY',
'TAGS',
1867 'TIMESTAMP_X',
'MODIFIED_BY',
'IBLOCK_SECTION_ID',
'DETAIL_PAGE_URL',
'DETAIL_PICTURE',
'PREVIEW_PICTURE'
1870 $checkPriceProperties = (
1873 isset($this->arParams[
'IBLOCK_ID'])
1874 && $this->arParams[
'IBLOCK_ID'] > 0
1875 && !isset($this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']])
1879 if ($checkPriceProperties && !empty($this->storage[
'PRICES']))
1881 foreach ($this->storage[
'PRICES'] as $row)
1883 if (!empty($row[
'SELECT']))
1900 'ACTIVE_DATE' =>
'Y',
1901 'CHECK_PERMISSIONS' =>
'Y',
1902 'MIN_PERMISSION' =>
'R'
1924 $this->selectFields =
$result[
'SELECT'];
1925 $this->filterFields =
$result[
'FILTER'];
1926 $this->sortFields =
$result[
'ORDER'];
1927 if (!empty($this->globalFilter))
1930 $this->globalFilter =
$result[
'FILTER'];
1945 if ($this->useCatalog)
1953 [
'QUANTITY' => $this->arParams[
'SHOW_PRICE_COUNT']]
1987 if (!$this->useCatalog)
1993 if (!empty($additionalFields))
1998 unset($additionalFields);
2015 'TYPE',
'AVAILABLE',
'BUNDLE',
2016 'QUANTITY',
'QUANTITY_TRACE',
'CAN_BUY_ZERO',
'MEASURE',
2018 'VAT_ID',
'VAT_INCLUDED',
2019 'WEIGHT',
'WIDTH',
'LENGTH',
'HEIGHT',
2020 'PAYMENT_TYPE',
'RECUR_SCHEME_LENGTH',
'RECUR_SCHEME_TYPE',
2029 'QUANTITY_TRACE_RAW',
'CAN_BUY_ZERO_RAW',
'SUBSCRIBE_RAW',
2030 'PURCHASING_PRICE',
'PURCHASING_CURRENCY',
2048 if (!$this->useCatalog)
2050 return \CProductQueryBuilder::convertOldSelect(
$select);
2061 if (!$this->useCatalog)
2063 return \CProductQueryBuilder::convertOldFilter(
$filter);
2074 if (!$this->useCatalog)
2076 return \CProductQueryBuilder::convertOldOrder(
$order);
2081 if (!$this->useCatalog)
2097 if (!empty($condition) && is_array($condition))
2099 if ($condition[
'CLASS_ID'] ===
'CondGroup')
2101 if (!empty($condition[
'CHILDREN']))
2103 foreach ($condition[
'CHILDREN'] as $child)
2108 if ($child[
'CLASS_ID'] ===
'CondGroup')
2115 $fieldName = key($childResult);
2120 'LOGIC' => $condition[
'DATA'][
'All'],
2125 $result[][$fieldName] = $childResult[$fieldName];
2139 $result[
'LOGIC'] = $condition[
'DATA'][
'All'];
2157 if (!empty($condition) && is_array($condition))
2164 $result[$operator.$name] = $value;
2166 if (
$name ===
'SECTION_ID')
2168 $result[
'INCLUDE_SUBSECTIONS'] = isset(
$params[
'INCLUDE_SUBSECTIONS']) &&
$params[
'INCLUDE_SUBSECTIONS'] ===
'N' ?
'N' :
'Y';
2170 if (isset(
$params[
'INCLUDE_SUBSECTIONS']) &&
$params[
'INCLUDE_SUBSECTIONS'] ===
'A')
2172 $result[
'SECTION_GLOBAL_ACTIVE'] =
'Y';
2186 $conditionNameMap =
array(
2187 'CondIBXmlID' =>
'XML_ID',
2188 'CondIBSection' =>
'SECTION_ID',
2189 'CondIBDateActiveFrom' =>
'DATE_ACTIVE_FROM',
2190 'CondIBDateActiveTo' =>
'DATE_ACTIVE_TO',
2191 'CondIBSort' =>
'SORT',
2192 'CondIBDateCreate' =>
'DATE_CREATE',
2193 'CondIBCreatedBy' =>
'CREATED_BY',
2194 'CondIBTimestampX' =>
'TIMESTAMP_X',
2195 'CondIBModifiedBy' =>
'MODIFIED_BY',
2196 'CondIBTags' =>
'TAGS',
2197 'CondCatQuantity' =>
'QUANTITY',
2198 'CondCatWeight' =>
'WEIGHT'
2201 if (isset($conditionNameMap[$condition[
'CLASS_ID']]))
2203 $name = $conditionNameMap[$condition[
'CLASS_ID']];
2205 elseif (mb_strpos($condition[
'CLASS_ID'],
'CondIBProp') !==
false)
2207 $name = $condition[
'CLASS_ID'];
2217 switch ($condition[
'DATA'][
'logic'])
2250 $value = $condition[
'DATA'][
'value'];
2254 case 'DATE_ACTIVE_FROM':
2255 case 'DATE_ACTIVE_TO':
2258 $value = ConvertTimeStamp($value,
'FULL');
2269 $subFilter =
array();
2279 if (($ind = mb_strpos(
$name,
'CondIBProp')) !==
false)
2282 $operator = $ind > 0? mb_substr($prefix, 0, $ind) :
'';
2284 $catalogInfo = \CCatalogSku::GetInfoByIBlock(
$iblock);
2285 if (!empty($catalogInfo))
2288 $catalogInfo[
'CATALOG_TYPE'] != \CCatalogSku::TYPE_CATALOG
2289 && $catalogInfo[
'IBLOCK_ID'] ==
$iblock
2292 $subFilter[$operator.
'PROPERTY_'.$propertyId] = $value;
2296 $result[$operator.
'PROPERTY_'.$propertyId] = $value;
2305 if (!empty($subFilter) && !empty($catalogInfo))
2307 $offerPropFilter =
array(
2308 'IBLOCK_ID' => $catalogInfo[
'IBLOCK_ID'],
2309 'ACTIVE_DATE' =>
'Y',
2313 if (
$params[
'HIDE_NOT_AVAILABLE_OFFERS'] ===
'Y')
2315 $offerPropFilter[
'HIDE_NOT_AVAILABLE'] =
'Y';
2319 $offerPropFilter[] =
array(
2326 if (
count($subFilter) > 1)
2328 $subFilter[
'LOGIC'] = $condition[
'DATA'][
'All'];
2329 $subFilter =
array($subFilter);
2332 $result[
'=ID'] = \CIBlockElement::SubQuery(
2333 'PROPERTY_'.$catalogInfo[
'SKU_PROPERTY_ID'],
2334 $offerPropFilter + $subFilter
2361 $element[
'ID'] = (int)$element[
'ID'];
2362 $element[
'IBLOCK_ID'] = (int)$element[
'IBLOCK_ID'];
2364 if ($this->arParams[
'HIDE_DETAIL_URL'])
2366 $element[
'DETAIL_PAGE_URL'] = $element[
'~DETAIL_PAGE_URL'] =
'';
2371 $element[
'ACTIVE_FROM'] = ($element[
'DATE_ACTIVE_FROM'] ??
null);
2372 $element[
'ACTIVE_TO'] = ($element[
'DATE_ACTIVE_TO'] ??
null);
2376 $element[
'IPROPERTY_VALUES'] = $ipropValues->getValues();
2380 array(
'PREVIEW_PICTURE',
'DETAIL_PICTURE'),
2385 if (isset($element[
'~TYPE']))
2390 $element[
'PRODUCT'] =
array(
2391 'TYPE' => (
int)$element[
'~TYPE'],
2392 'AVAILABLE' => $element[
'~AVAILABLE'],
2393 'BUNDLE' => $element[
'~BUNDLE'],
2394 'QUANTITY' => $element[
'~QUANTITY'],
2395 'QUANTITY_TRACE' => $element[
'~QUANTITY_TRACE'],
2396 'CAN_BUY_ZERO' => $element[
'~CAN_BUY_ZERO'],
2397 'MEASURE' => (
int)$element[
'~MEASURE'],
2398 'SUBSCRIBE' => $element[
'~SUBSCRIBE'],
2399 'VAT_ID' => (
int)$element[
'~VAT_ID'],
2401 'VAT_INCLUDED' => $element[
'~VAT_INCLUDED'],
2402 'WEIGHT' => (
float)$element[
'~WEIGHT'],
2403 'WIDTH' => (
float)$element[
'~WIDTH'],
2404 'LENGTH' => (
float)$element[
'~LENGTH'],
2405 'HEIGHT' => (
float)$element[
'~HEIGHT'],
2406 'PAYMENT_TYPE' => $element[
'~PAYMENT_TYPE'],
2407 'RECUR_SCHEME_TYPE' => $element[
'~RECUR_SCHEME_TYPE'],
2408 'RECUR_SCHEME_LENGTH' => (
int)$element[
'~RECUR_SCHEME_LENGTH'],
2409 'TRIAL_PRICE_ID' => (
int)$element[
'~TRIAL_PRICE_ID']
2414 if ($element[
'PRODUCT'][
'VAT_ID'] > 0)
2415 $vatId = $element[
'PRODUCT'][
'VAT_ID'];
2416 elseif ($this->storage[
'IBLOCKS_VAT'][$element[
'IBLOCK_ID']] > 0)
2417 $vatId = $this->storage[
'IBLOCKS_VAT'][$element[
'IBLOCK_ID']];
2418 if ($vatId > 0 && isset($this->storage[
'VATS'][$vatId]))
2419 $vatRate = $this->storage[
'VATS'][$vatId];
2420 $element[
'PRODUCT'][
'VAT_RATE'] = $vatRate;
2421 unset($vatRate, $vatId);
2426 foreach ($translateFields as $currentKey => $oldKey)
2427 $element[$oldKey] = $element[$currentKey];
2428 unset($currentKey, $oldKey);
2429 $element[
'~CATALOG_VAT'] = $element[
'PRODUCT'][
'VAT_RATE'];
2430 $element[
'CATALOG_VAT'] = $element[
'PRODUCT'][
'VAT_RATE'];
2435 $element[
'~CATALOG_TYPE'] = $element[
'PRODUCT'][
'TYPE'];
2436 $element[
'CATALOG_TYPE'] = $element[
'PRODUCT'][
'TYPE'];
2437 $element[
'~CATALOG_QUANTITY'] = $element[
'PRODUCT'][
'QUANTITY'];
2438 $element[
'CATALOG_QUANTITY'] = $element[
'PRODUCT'][
'QUANTITY'];
2439 $element[
'~CATALOG_QUANTITY_TRACE'] = $element[
'PRODUCT'][
'QUANTITY_TRACE'];
2440 $element[
'CATALOG_QUANTITY_TRACE'] = $element[
'PRODUCT'][
'QUANTITY_TRACE'];
2441 $element[
'~CATALOG_CAN_BUY_ZERO'] = $element[
'PRODUCT'][
'CAN_BUY_ZERO'];
2442 $element[
'CATALOG_CAN_BUY_ZERO'] = $element[
'PRODUCT'][
'CAN_BUY_ZERO'];
2443 $element[
'~CATALOG_SUBSCRIBE'] = $element[
'PRODUCT'][
'SUBSCRIBE'];
2444 $element[
'CATALOG_SUBSCRIBE'] = $element[
'PRODUCT'][
'SUBSCRIBE'];
2448 unset($element[$field], $element[
'~'.$field]);
2453 $element[
'PRODUCT'] =
array(
2455 'AVAILABLE' =>
null,
2456 'USE_OFFERS' =>
false
2460 $element[
'PROPERTIES'] =
array();
2461 $element[
'DISPLAY_PROPERTIES'] =
array();
2462 $element[
'PRODUCT_PROPERTIES'] =
array();
2463 $element[
'PRODUCT_PROPERTIES_FILL'] =
array();
2464 $element[
'OFFERS'] =
array();
2465 $element[
'OFFER_ID_SELECTED'] = 0;
2467 if (!empty($this->storage[
'CATALOGS'][$element[
'IBLOCK_ID']]))
2470 if ($this->
getAction() ===
'bigDataLoad')
2472 $element[
'RCM_ID'] = $this->recommendationIdToProduct[$element[
'ID']];
2484 $buttons = \CIBlock::GetPanelButtons(
2485 $element[
'IBLOCK_ID'],
2487 $element[
'IBLOCK_SECTION_ID'],
2488 array(
'SECTION_BUTTONS' =>
false,
'SESSID' =>
false,
'CATALOG' =>
true)
2490 $element[
'EDIT_LINK'] = ($buttons[
'edit'][
'edit_element'][
'ACTION_URL'] ??
null);
2491 $element[
'DELETE_LINK'] = ($buttons[
'edit'][
'delete_element'][
'ACTION_URL'] ??
null);
2507 $propertyList =
array();
2508 if (empty($propertyCodes))
2509 return $propertyList;
2511 $propertyCodes = array_fill_keys($propertyCodes,
true);
2514 'select' =>
array(
'ID',
'CODE',
'SORT'),
2515 'filter' =>
array(
'=IBLOCK_ID' =>
$iblock,
'=ACTIVE' =>
'Y'),
2516 'order' =>
array(
'SORT' =>
'ASC',
'ID' =>
'ASC')
2518 while ($property = $propertyIterator->fetch())
2520 $code = (string)$property[
'CODE'];
2524 $code = $property[
'ID'];
2527 if (!isset($propertyCodes[
$code]))
2530 $propertyList[] =
$code;
2533 return $propertyList;
2543 $this->prices =
array();
2544 $this->measures =
array();
2545 $this->ratios =
array();
2546 $this->quantityRanges =
array();
2547 $this->oldData =
array();
2559 if (empty($itemIds))
2562 if (empty($itemIds))
2564 $emptyRatioIds = array_fill_keys($itemIds,
true);
2567 'select' =>
array(
'ID',
'RATIO',
'IS_DEFAULT',
'PRODUCT_ID'),
2568 'filter' =>
array(
'@PRODUCT_ID' => $itemIds),
2569 'order' =>
array(
'PRODUCT_ID' =>
'ASC')
2573 $ratio = max((
float)$row[
'RATIO'], (
int)$row[
'RATIO']);
2576 $row[
'RATIO'] = $ratio;
2577 $row[
'ID'] = (int)$row[
'ID'];
2578 $id = (int)$row[
'PRODUCT_ID'];
2579 if (!isset($this->ratios[$id]))
2580 $this->ratios[$id] =
array();
2581 $this->ratios[$id][$row[
'ID']] = $row;
2582 unset($emptyRatioIds[$id]);
2588 if (!empty($emptyRatioIds))
2591 foreach (array_keys($emptyRatioIds) as $id)
2593 $this->ratios[$id] =
array(
2594 $emptyRatio[
'ID'] => $emptyRatio
2597 unset($id, $emptyRatio);
2599 unset($emptyRatioIds);
2627 foreach (array_keys(
$items) as $index)
2629 if (!isset(
$items[$index][
'PRODUCT'][
'MEASURE']))
2631 if (
$items[$index][
'PRODUCT'][
'MEASURE'] > 0)
2634 'ID' =>
$items[$index][
'PRODUCT'][
'MEASURE'],
2643 'TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'SYMBOL_RUS'],
2644 '~TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'~SYMBOL_RUS'],
2663 foreach (array_keys(
$items) as $itemId)
2665 if (!isset(
$items[$itemId][
'ITEM_MEASURE']))
2667 $measureId = (int)
$items[$itemId][
'ITEM_MEASURE'][
'ID'];
2669 $result[$measureId] = $measureId;
2686 if (empty($measureIds))
2689 if (empty($measureIds))
2694 array(
'@ID' => $measureIds),
2697 array(
'ID',
'SYMBOL_RUS')
2701 $measure[
'ID'] = (int)$measure[
'ID'];
2702 $measure[
'TITLE'] = $measure[
'SYMBOL_RUS'];
2703 $measure[
'~TITLE'] = $measure[
'~SYMBOL_RUS'];
2704 unset($measure[
'SYMBOL_RUS'], $measure[
'~SYMBOL_RUS']);
2705 $this->measures[$measure[
'ID']] = $measure;
2718 if (empty($itemIds))
2721 if (empty($itemIds))
2726 if (empty($this->storage[
'PRICES_ALLOW']))
2731 $quantityList = array_fill_keys($itemIds,
array());
2734 'ID',
'PRODUCT_ID',
'CATALOG_GROUP_ID',
'PRICE',
'CURRENCY',
2735 'QUANTITY_FROM',
'QUANTITY_TO',
'PRICE_SCALE'
2737 if ($enableCompatible)
2740 $pagedItemIds = array_chunk($itemIds, 500);
2741 foreach ($pagedItemIds as $pageIds)
2743 if (empty($pageIds))
2748 'filter' =>
array(
'@PRODUCT_ID' => $pageIds,
'@CATALOG_GROUP_ID' => $this->storage[
'PRICES_ALLOW']),
2749 'order' =>
array(
'PRODUCT_ID' =>
'ASC',
'CATALOG_GROUP_ID' =>
'ASC')
2753 $id = (int)$row[
'PRODUCT_ID'];
2754 unset($row[
'PRODUCT_ID']);
2755 if (!isset($this->prices[$id]))
2757 $this->prices[$id] =
array(
2759 'QUANTITY' =>
array(),
2764 if ($row[
'QUANTITY_FROM'] !==
null || $row[
'QUANTITY_TO'] !==
null)
2767 if (!isset($quantityList[$id][
$hash]))
2771 'QUANTITY_FROM' => $row[
'QUANTITY_FROM'],
2772 'QUANTITY_TO' => $row[
'QUANTITY_TO'],
2773 'SORT_FROM' => (
int)$row[
'QUANTITY_FROM'],
2774 'SORT_TO' => ($row[
'QUANTITY_TO'] ===
null ? INF : (
int)$row[
'QUANTITY_TO'])
2777 if (!isset($this->prices[$id][
'QUANTITY'][
$hash]))
2779 $this->prices[$id][
'QUANTITY'][
$hash] =
array();
2781 $this->prices[$id][
'QUANTITY'][
$hash][$row[
'CATALOG_GROUP_ID']] = $row;
2784 elseif (!isset($row[
'MEASURE_RATIO_ID']))
2786 $this->prices[$id][
'SIMPLE'][$row[
'CATALOG_GROUP_ID']] = $row;
2788 $this->storage[
'CURRENCY_LIST'][$row[
'CURRENCY']] = $row[
'CURRENCY'];
2794 unset($pageIds, $pagedItemIds);
2796 foreach ($itemIds as $id)
2798 if (isset($this->prices[$id]))
2800 foreach ($this->prices[$id] as
$key =>
$data)
2803 unset($this->prices[$id][
$key]);
2807 if (
count($this->prices[$id]) !== 1)
2809 unset($this->prices[$id]);
2813 if (!empty($this->prices[$id][
'QUANTITY']))
2815 $productQuantity = $quantityList[$id];
2818 array(
'SORT_FROM' => SORT_ASC,
'SORT_TO' => SORT_ASC),
2821 $this->quantityRanges[$id] = $productQuantity;
2822 unset($productQuantity);
2824 if (
count($this->ratios[$id]) > 1)
2827 if (!empty($this->prices[$id][
'SIMPLE']))
2830 $this->quantityRanges[$id] =
array(
2831 $range[
'HASH'] => $range
2834 if (
count($this->ratios[$id]) > 1)
2842 unset($quantityList);
2844 unset($enableCompatible);
2854 if ($enableCompatible)
2857 foreach (array_keys(
$items) as $index)
2859 $id =
$items[$index][
'ID'];
2860 $items[$index][
'CAN_BUY'] =
false;
2861 if (!isset($this->calculatePrices[$id]))
2863 if (empty($this->prices[$id]))
2865 $productPrices = $this->prices[$id];
2867 'ITEM_PRICE_MODE' =>
null,
2868 'ITEM_PRICES' =>
array(),
2869 'ITEM_PRICES_CAN_BUY' =>
false
2871 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
2873 $priceBlockIndex = 0;
2874 if (!empty($productPrices[
'QUANTITY']))
2877 $ratio = current($this->ratios[$id]);
2878 foreach ($this->quantityRanges[$id] as $range)
2880 $priceBlock = $this->calculatePriceBlock(
2882 $productPrices[
'QUANTITY'][$range[
'HASH']],
2886 if (!empty($priceBlock))
2888 $minimalPrice = ($this->arParams[
'FILL_ITEM_ALL_PRICES']
2889 ? $priceBlock[
'MINIMAL_PRICE']
2892 if ($minimalPrice[
'QUANTITY_FROM'] ===
null)
2894 $minimalPrice[
'MIN_QUANTITY'] = $ratio[
'RATIO'];
2898 $minimalPrice[
'MIN_QUANTITY'] = $ratio[
'RATIO'] * ((int)($minimalPrice[
'QUANTITY_FROM']/$ratio[
'RATIO']));
2899 if ($minimalPrice[
'MIN_QUANTITY'] < $minimalPrice[
'QUANTITY_FROM'])
2900 $minimalPrice[
'MIN_QUANTITY'] += $ratio[
'RATIO'];
2902 $result[
'ITEM_PRICES'][$priceBlockIndex] = $minimalPrice;
2903 if (isset($this->storage[
'PRICES_CAN_BUY'][$minimalPrice[
'PRICE_TYPE_ID']]))
2904 $result[
'ITEM_PRICES_CAN_BUY'] =
true;
2905 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
2907 $priceBlock[
'ALL_PRICES'][
'MIN_QUANTITY'] = $minimalPrice[
'MIN_QUANTITY'];
2908 $result[
'ITEM_ALL_PRICES'][$priceBlockIndex] = $priceBlock[
'ALL_PRICES'];
2910 unset($minimalPrice);
2918 if (!empty($productPrices[
'SIMPLE']))
2921 $ratio = current($this->ratios[$id]);
2922 $priceBlock = $this->calculatePriceBlock(
2924 $productPrices[
'SIMPLE'],
2928 if (!empty($priceBlock))
2930 $minimalPrice = ($this->arParams[
'FILL_ITEM_ALL_PRICES']
2931 ? $priceBlock[
'MINIMAL_PRICE']
2934 $minimalPrice[
'MIN_QUANTITY'] = $ratio[
'RATIO'];
2935 $result[
'ITEM_PRICES'][$priceBlockIndex] = $minimalPrice;
2936 if (isset($this->storage[
'PRICES_CAN_BUY'][$minimalPrice[
'PRICE_TYPE_ID']]))
2937 $result[
'ITEM_PRICES_CAN_BUY'] =
true;
2938 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
2940 $priceBlock[
'ALL_PRICES'][
'MIN_QUANTITY'] = $minimalPrice[
'MIN_QUANTITY'];
2941 $result[
'ITEM_ALL_PRICES'][$priceBlockIndex] = $priceBlock[
'ALL_PRICES'];
2943 unset($minimalPrice);
2951 if (isset(
$items[$index][
'ACTIVE']) &&
$items[$index][
'ACTIVE'] ===
'N')
2953 $items[$index][
'CAN_BUY'] =
false;
2957 $items[$index][
'CAN_BUY'] =
$result[
'ITEM_PRICES_CAN_BUY'] &&
$items[$index][
'PRODUCT'][
'AVAILABLE'] ===
'Y';
2960 unset($priceBlockIndex,
$result);
2961 unset($productPrices);
2963 if ($enableCompatible)
2964 $this->resortOldPrices($id);
2975 $urls = $this->storage[
'URLS'];
2977 foreach (array_keys(
$items) as $index)
2979 $itemId =
$items[$index][
'ID'];
2981 if (!empty(
$items[$index][
'ITEM_MEASURE']))
2983 $id = (int)
$items[$index][
'ITEM_MEASURE'][
'ID'];
2984 if (isset($this->measures[$id]))
2986 $items[$index][
'ITEM_MEASURE'][
'TITLE'] = $this->measures[$id][
'TITLE'];
2987 $items[$index][
'ITEM_MEASURE'][
'~TITLE'] = $this->measures[$id][
'~TITLE'];
2992 $items[$index][
'ITEM_MEASURE_RATIOS'] = $this->ratios[$itemId] ?? [];
2994 $items[$index][
'ITEM_QUANTITY_RANGES'] = $this->quantityRanges[$itemId] ?? [];
2996 if (!empty($this->prices[$itemId]))
2998 $items[$index] = array_merge(
$items[$index], $this->prices[$itemId]);
2999 if (!empty(
$items[$index][
'ITEM_PRICES']))
3001 switch (
$items[$index][
'ITEM_PRICE_MODE'])
3004 $items[$index][
'ITEM_PRICE_SELECTED'] = 0;
3007 foreach (array_keys(
$items[$index][
'ITEM_PRICES']) as $priceIndex)
3009 if (
$items[$index][
'ITEM_PRICES'][$priceIndex][
'QUANTITY_HASH'] ==
$items[$index][
'ITEM_QUANTITY_RANGE_SELECTED'])
3011 $items[$index][
'ITEM_PRICE_SELECTED'] = $priceIndex;
3017 foreach (array_keys(
$items[$index][
'ITEM_PRICES']) as $priceIndex)
3019 if (
$items[$index][
'ITEM_PRICES'][$priceIndex][
'MEASURE_RATIO_ID'] ==
$items[$index][
'ITEM_MEASURE_RATIO_SELECTED'])
3021 $items[$index][
'ITEM_PRICE_SELECTED'] = $priceIndex;
3031 if ($enableCompatible)
3034 $id =
$items[$index][
'ID'];
3035 $items[$index][
'~BUY_URL'] = str_replace(
'#ID#', $id, $urls[
'~BUY_URL_TEMPLATE']);
3036 $items[$index][
'BUY_URL'] = str_replace(
'#ID#', $id, $urls[
'BUY_URL_TEMPLATE']);
3037 $items[$index][
'~ADD_URL'] = str_replace(
'#ID#', $id, $urls[
'~ADD_URL_TEMPLATE']);
3038 $items[$index][
'ADD_URL'] = str_replace(
'#ID#', $id, $urls[
'ADD_URL_TEMPLATE']);
3039 $items[$index][
'~SUBSCRIBE_URL'] = str_replace(
'#ID#', $id, $urls[
'~SUBSCRIBE_URL_TEMPLATE']);
3040 $items[$index][
'SUBSCRIBE_URL'] = str_replace(
'#ID#', $id, $urls[
'SUBSCRIBE_URL_TEMPLATE']);
3041 if ($this->arParams[
'DISPLAY_COMPARE'])
3043 $items[$index][
'~COMPARE_URL'] = str_replace(
'#ID#', $id, $urls[
'~COMPARE_URL_TEMPLATE']);
3044 $items[$index][
'COMPARE_URL'] = str_replace(
'#ID#', $id, $urls[
'COMPARE_URL_TEMPLATE']);
3045 $items[$index][
'~COMPARE_DELETE_URL'] = str_replace(
'#ID#', $id, $urls[
'~COMPARE_DELETE_URL_TEMPLATE']);
3046 $items[$index][
'COMPARE_DELETE_URL'] = str_replace(
'#ID#', $id, $urls[
'COMPARE_DELETE_URL_TEMPLATE']);
3051 $items[$index][
'CATALOG_MEASURE_NAME'] =
$items[$index][
'ITEM_MEASURE'][
'TITLE'];
3052 $items[$index][
'~CATALOG_MEASURE_NAME'] =
$items[$index][
'ITEM_MEASURE'][
'~TITLE'];
3055 $items[$index][
'CATALOG_MEASURE_RATIO'] =
$items[$index][
'ITEM_MEASURE_RATIOS'][
$items[$index][
'ITEM_MEASURE_RATIO_SELECTED']][
'RATIO'] ?? 1;
3058 if (!empty($this->oldData[$itemId]))
3059 $items[$index] = array_merge($this->oldData[$itemId],
$items[$index]);
3064 unset($urls, $enableCompatible);
3076 protected function calculatePriceBlock(
array $product,
array $priceBlock, $ratio, $defaultBlock =
false)
3078 if (empty($product) || empty($priceBlock))
3081 $enableCompatible = $defaultBlock && $this->isEnableCompatible();
3083 if ($enableCompatible && !$this->arParams[
'USE_PRICE_COUNT'])
3084 $this->fillCompatibleRawPriceFields($product[
'ID'], $priceBlock);
3086 $userGroups = $this->getUserGroups();
3088 $baseCurrency = Currency\CurrencyManager::getBaseCurrency();
3090 $minimalPrice =
null;
3092 $minimalBuyerPrice =
null;
3093 $fullPrices =
array();
3095 $currencyConvert = $this->arParams[
'CONVERT_CURRENCY'] ===
'Y';
3096 $resultCurrency = ($currencyConvert ? $this->storage[
'CONVERT_CURRENCY'][
'CURRENCY_ID'] :
null);
3098 $vatRate = (float)$product[
'PRODUCT'][
'VAT_RATE'];
3099 $percentVat = $vatRate * 0.01;
3100 $percentPriceWithVat = 1 + $percentVat;
3101 $vatInclude = $product[
'PRODUCT'][
'VAT_INCLUDED'] ===
'Y';
3103 $oldPrices =
array();
3104 $oldMinPrice =
false;
3106 if ($enableCompatible && $this->arParams[
'USE_PRICE_COUNT'])
3108 $oldMatrix = $this->getCompatibleFieldValue($product[
'ID'],
'PRICE_MATRIX');
3109 if (empty($oldMatrix))
3111 $oldMatrix = $this->getEmptyPriceMatrix();
3112 $oldMatrix[
'AVAILABLE'] = $product[
'PRODUCT'][
'AVAILABLE'];
3116 foreach ($priceBlock as $rawPrice)
3118 $priceType = (int)$rawPrice[
'CATALOG_GROUP_ID'];
3119 $price = (float)$rawPrice[
'PRICE'];
3121 $price *= $percentPriceWithVat;
3124 $changeCurrency = $currencyConvert &&
$currency !== $resultCurrency;
3125 if ($changeCurrency)
3131 $discounts =
array();
3135 $discounts = \CCatalogDiscount::GetDiscount(
3137 $product[
'IBLOCK_ID'],
3146 $discountPrice = \CCatalogProduct::CountPriceWithDiscount(
3151 if ($discountPrice !==
false)
3153 $priceWithVat =
array(
3154 'UNROUND_BASE_PRICE' => $price,
3155 'UNROUND_PRICE' => $discountPrice,
3156 'BASE_PRICE' => Catalog\Product\Price::roundPrice(
3161 'PRICE' => Catalog\Product\Price::roundPrice(
3168 $price /= $percentPriceWithVat;
3169 $discountPrice /= $percentPriceWithVat;
3171 $priceWithoutVat =
array(
3172 'UNROUND_BASE_PRICE' => $price,
3173 'UNROUND_PRICE' => $discountPrice,
3174 'BASE_PRICE' => Catalog\Product\Price::roundPrice(
3179 'PRICE' => Catalog\Product\Price::roundPrice(
3186 if ($this->arParams[
'PRICE_VAT_INCLUDE'])
3187 $priceRow = $priceWithVat;
3189 $priceRow = $priceWithoutVat;
3190 $priceRow[
'ID'] = $rawPrice[
'ID'];
3191 $priceRow[
'PRICE_TYPE_ID'] = $rawPrice[
'CATALOG_GROUP_ID'];
3196 || ($priceRow[
'BASE_PRICE'] <= $priceRow[
'PRICE'])
3199 $priceRow[
'BASE_PRICE'] = $priceRow[
'PRICE'];
3200 $priceRow[
'DISCOUNT'] = 0;
3201 $priceRow[
'PERCENT'] = 0;
3205 $priceRow[
'DISCOUNT'] = $priceRow[
'BASE_PRICE'] - $priceRow[
'PRICE'];
3206 $priceRow[
'PERCENT'] =
roundEx(100*$priceRow[
'DISCOUNT']/$priceRow[
'BASE_PRICE'], 0);
3208 if (isset($this->arParams[
'PRICE_VAT_SHOW_VALUE']) && $this->arParams[
'PRICE_VAT_SHOW_VALUE'])
3209 $priceRow[
'VAT'] = ($vatRate > 0 ? $priceWithVat[
'PRICE'] - $priceWithoutVat[
'PRICE'] : 0);
3211 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
3212 $fullPrices[$priceType] = $priceRow;
3214 $priceRow[
'QUANTITY_FROM'] = $rawPrice[
'QUANTITY_FROM'];
3215 $priceRow[
'QUANTITY_TO'] = $rawPrice[
'QUANTITY_TO'];
3217 $priceRow[
'MEASURE_RATIO_ID'] = $rawPrice[
'MEASURE_RATIO_ID'] ??
null;
3218 $priceRow[
'PRICE_SCALE'] = \CCurrencyRates::ConvertCurrency(
3220 $priceRow[
'CURRENCY'],
3223 $priceRow[
'BASE_PRICE_SCALE'] = $rawPrice[
'PRICE_SCALE'];
3226 $minimalPrice ===
null
3227 || $minimalPrice[
'PRICE_SCALE'] > $priceRow[
'PRICE_SCALE']
3230 $minimalPrice = $priceRow;
3233 $minimalPrice[
'PRICE_SCALE'] == $priceRow[
'PRICE_SCALE']
3234 && $minimalPrice[
'BASE_PRICE_SCALE'] > $priceRow[
'BASE_PRICE_SCALE']
3237 $minimalPrice = $priceRow;
3239 if (isset($this->storage[
'PRICES_CAN_BUY'][$priceRow[
'PRICE_TYPE_ID']]))
3242 $minimalBuyerPrice ===
null
3243 || $minimalBuyerPrice[
'PRICE_SCALE'] > $priceRow[
'PRICE_SCALE']
3246 $minimalBuyerPrice = $priceRow;
3249 $minimalBuyerPrice[
'PRICE_SCALE'] == $priceRow[
'PRICE_SCALE']
3250 && $minimalBuyerPrice[
'BASE_PRICE_SCALE'] > $priceRow[
'BASE_PRICE_SCALE']
3253 $minimalBuyerPrice = $priceRow;
3257 if ($enableCompatible)
3259 if ($this->arParams[
'USE_PRICE_COUNT'])
3262 $oldMatrix[
'ROWS'][$rowIndex] =
array(
3263 'QUANTITY_FROM' => (
float)$rawPrice[
'QUANTITY_FROM'],
3264 'QUANTITY_TO' => (
float)$rawPrice[
'QUANTITY_TO']
3266 if (!isset($oldMatrix[
'MATRIX'][$priceType]))
3268 $oldMatrix[
'MATRIX'][$priceType] =
array();
3269 $oldMatrix[
'COLS'][$priceType] = $this->storage[
'PRICE_TYPES'][$priceType];
3271 $oldMatrix[
'MATRIX'][$priceType][$rowIndex] =
array(
3272 'ID' => $priceRow[
'ID'],
3273 'PRICE' => $priceRow[
'BASE_PRICE'],
3274 'DISCOUNT_PRICE' => $priceRow[
'PRICE'],
3275 'UNROUND_DISCOUNT_PRICE' => $priceRow[
'UNROUND_PRICE'],
3276 'CURRENCY' => $priceRow[
'CURRENCY'],
3277 'VAT_RATE' => $percentVat
3279 if ($changeCurrency)
3281 $oldMatrix[
'MATRIX'][$priceType][$rowIndex][
'ORIG_CURRENCY'] = $rawPrice[
'CURRENCY'];
3282 $oldMatrix[
'MATRIX'][$priceType][$rowIndex][
'ORIG_PRICE'] = \CCurrencyRates::ConvertCurrency(
3283 $priceRow[
'BASE_PRICE'],
3284 $priceRow[
'CURRENCY'],
3285 $rawPrice[
'CURRENCY']
3287 $oldMatrix[
'MATRIX'][$priceType][$rowIndex][
'ORIG_DISCOUNT_PRICE'] = \CCurrencyRates::ConvertCurrency(
3289 $priceRow[
'CURRENCY'],
3290 $rawPrice[
'CURRENCY']
3292 $oldMatrix[
'MATRIX'][$priceType][$rowIndex][
'ORIG_VAT_RATE'] = $percentVat;
3297 $priceCode = $this->storage[
'PRICES_MAP'][$priceType];
3298 $oldPriceRow =
array(
3299 'PRICE_ID' => $priceRow[
'PRICE_TYPE_ID'],
3300 'ID' => $priceRow[
'ID'],
3301 'CAN_ACCESS' => ($this->storage[
'PRICES'][$priceCode][
'CAN_VIEW'] ?
'Y' :
'N'),
3302 'CAN_BUY' => ($this->storage[
'PRICES'][$priceCode][
'CAN_BUY'] ?
'Y' :
'N'),
3304 'CURRENCY' => $priceRow[
'CURRENCY'],
3305 'VALUE_VAT' => $priceWithVat[
'UNROUND_BASE_PRICE'],
3306 'VALUE_NOVAT' => $priceWithoutVat[
'UNROUND_BASE_PRICE'],
3307 'DISCOUNT_VALUE_VAT' => $priceWithVat[
'UNROUND_PRICE'],
3308 'DISCOUNT_VALUE_NOVAT' => $priceWithoutVat[
'UNROUND_PRICE'],
3309 'ROUND_VALUE_VAT' => $priceWithVat[
'PRICE'],
3310 'ROUND_VALUE_NOVAT' => $priceWithoutVat[
'PRICE'],
3311 'VALUE' => $priceRow[
'BASE_PRICE'],
3312 'UNROUND_DISCOUNT_VALUE' => $priceRow[
'UNROUND_PRICE'],
3313 'DISCOUNT_VALUE' => $priceRow[
'PRICE'],
3314 'DISCOUNT_DIFF' => $priceRow[
'DISCOUNT'],
3315 'DISCOUNT_DIFF_PERCENT' => $priceRow[
'PERCENT']
3317 $oldPriceRow[
'VATRATE_VALUE'] = $oldPriceRow[
'VALUE_VAT'] - $oldPriceRow[
'VALUE_NOVAT'];
3318 $oldPriceRow[
'DISCOUNT_VATRATE_VALUE'] = $oldPriceRow[
'DISCOUNT_VALUE_VAT'] - $oldPriceRow[
'DISCOUNT_VALUE_NOVAT'];
3319 $oldPriceRow[
'ROUND_VATRATE_VALUE'] = $oldPriceRow[
'ROUND_VALUE_VAT'] - $oldPriceRow[
'ROUND_VALUE_NOVAT'];
3320 if ($changeCurrency)
3321 $oldPriceRow[
'ORIG_CURRENCY'] = $rawPrice[
'CURRENCY'];
3322 $oldPrices[$priceCode] = $oldPriceRow;
3323 unset($oldPriceRow);
3332 $minimalPriceId =
null;
3333 if (is_array($minimalBuyerPrice))
3334 $minimalPrice = $minimalBuyerPrice;
3335 if (is_array($minimalPrice))
3337 unset($minimalPrice[
'PRICE_SCALE']);
3338 unset($minimalPrice[
'BASE_PRICE_SCALE']);
3339 $minimalPriceId = $minimalPrice[
'PRICE_TYPE_ID'];
3340 $prepareFields =
array(
3341 'BASE_PRICE',
'PRICE',
'DISCOUNT'
3343 if (isset($this->arParams[
'PRICE_VAT_SHOW_VALUE']) && $this->arParams[
'PRICE_VAT_SHOW_VALUE'])
3344 $prepareFields[] =
'VAT';
3346 foreach ($prepareFields as $fieldName)
3348 $minimalPrice[
'PRINT_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3349 $minimalPrice[$fieldName],
3350 $minimalPrice[
'CURRENCY'],
3353 $minimalPrice[
'RATIO_'.$fieldName] = $minimalPrice[$fieldName]*$ratio;
3354 $minimalPrice[
'PRINT_RATIO_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3355 $minimalPrice[
'RATIO_'.$fieldName],
3356 $minimalPrice[
'CURRENCY'],
3362 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
3364 foreach (array_keys($fullPrices) as $priceType)
3366 foreach ($prepareFields as $fieldName)
3368 $fullPrices[$priceType][
'PRINT_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3369 $fullPrices[$priceType][$fieldName],
3370 $fullPrices[$priceType][
'CURRENCY'],
3373 $fullPrices[$priceType][
'RATIO_'.$fieldName] = $fullPrices[$priceType][$fieldName]*$ratio;
3374 $fullPrices[$priceType][
'PRINT_RATIO_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3375 $fullPrices[
'RATIO_'.$fieldName],
3376 $fullPrices[
'CURRENCY'],
3385 unset($prepareFields);
3388 if ($enableCompatible)
3390 if ($this->arParams[
'USE_PRICE_COUNT'])
3392 $oldMatrix[
'CAN_BUY'] = array_values($this->storage[
'PRICES_CAN_BUY']);
3393 $this->oldData[$product[
'ID']][
'PRICE_MATRIX'] = $oldMatrix;
3397 $convertFields =
array(
3398 'VALUE_NOVAT',
'VALUE_VAT',
'VATRATE_VALUE',
3399 'DISCOUNT_VALUE_NOVAT',
'DISCOUNT_VALUE_VAT',
'DISCOUNT_VATRATE_VALUE'
3402 $prepareFields =
array(
3403 'VALUE_NOVAT',
'VALUE_VAT',
'VATRATE_VALUE',
3404 'DISCOUNT_VALUE_NOVAT',
'DISCOUNT_VALUE_VAT',
'DISCOUNT_VATRATE_VALUE',
3405 'VALUE',
'DISCOUNT_VALUE',
'DISCOUNT_DIFF'
3408 if (!empty($oldPrices))
3410 foreach (array_keys($oldPrices) as $index)
3412 foreach ($prepareFields as $fieldName)
3413 $oldPrices[$index][
'PRINT_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3414 $oldPrices[$index][$fieldName],
3415 $oldPrices[$index][
'CURRENCY'],
3419 if (isset($oldPrices[$index][
'ORIG_CURRENCY']))
3421 foreach ($convertFields as $fieldName)
3422 $oldPrices[$index][
'ORIG_' . $fieldName] = \CCurrencyRates::ConvertCurrency(
3423 $oldPrices[$index][$fieldName],
3424 $oldPrices[$index][
'CURRENCY'],
3425 $oldPrices[$index][
'ORIG_CURRENCY']
3429 if ($oldPrices[$index][
'PRICE_ID'] === $minimalPriceId)
3431 $oldPrices[$index][
'MIN_PRICE'] =
'Y';
3432 $oldMinPrice = $oldPrices[$index];
3437 unset($prepareFields);
3439 $this->oldData[$product[
'ID']][
'PRICES'] = $oldPrices;
3440 $this->oldData[$product[
'ID']][
'MIN_PRICE'] = $oldMinPrice;
3443 unset($oldMatrix, $oldMinPrice, $oldPrices);
3445 if (!$this->arParams[
'FILL_ITEM_ALL_PRICES'])
3446 return $minimalPrice;
3449 'MINIMAL_PRICE' => $minimalPrice,
3450 'ALL_PRICES' =>
array(
3451 'QUANTITY_FROM' => $minimalPrice[
'QUANTITY_FROM'],
3452 'QUANTITY_TO' => $minimalPrice[
'QUANTITY_TO'],
3453 'QUANTITY_HASH' => $minimalPrice[
'QUANTITY_HASH'],
3454 'MEASURE_RATIO_ID' => $minimalPrice[
'MEASURE_RATIO_ID'],
3455 'PRICES' => $fullPrices
3462 if (!isset($this->ratios[$id]))
3466 $minimalRatio =
null;
3468 foreach ($this->ratios[$id] as $ratio)
3470 if ($minimalRatio ===
null || $minimalRatio > $ratio[
'RATIO'])
3472 $minimalRatio = $ratio[
'RATIO'];
3473 $minimal = $ratio[
'ID'];
3475 if ($ratio[
'IS_DEFAULT'] ===
'Y')
3488 if ($ratioId ===
null)
3490 $this->ratios[$id] =
array(
3491 $ratioId => $this->ratios[$id][$ratioId]
3497 return ($range[
'QUANTITY_FROM'] ===
null ?
'ZERO' : $range[
'QUANTITY_FROM']).
3498 '-'.($range[
'QUANTITY_TO'] ===
null ?
'INF' : $range[
'QUANTITY_TO']);
3505 'QUANTITY_FROM' =>
null,
3506 'QUANTITY_TO' =>
null,
3514 if (empty($this->quantityRanges[$id]))
3516 foreach ($this->quantityRanges[$id] as $range)
3519 return $range[
'HASH'];
3521 reset($this->quantityRanges[$id]);
3522 $firsrRange = current($this->quantityRanges[$id]);
3523 return $firsrRange[
'HASH'];
3533 $actionVar = $this->arParams[
'ACTION_VARIABLE'];
3534 $productIdVar = $this->arParams[
'PRODUCT_ID_VARIABLE'];
3535 $compareActionVar = $this->arParams[
'ACTION_COMPARE_VARIABLE'];
3538 $clearParams[] = $actionVar;
3539 $clearParams[] = $productIdVar;
3540 $clearParams[] = $compareActionVar;
3541 $clearParams[] =
'';
3543 if (!empty($this->arParams[
'CUSTOM_CURRENT_PAGE']))
3545 $pageUrl = $this->arParams[
'CUSTOM_CURRENT_PAGE'];
3549 if ($this->request->isAjaxRequest())
3551 $pageUrl = $this->arParams[
'CURRENT_BASE_PAGE'];
3561 if ($this->arParams[
'USE_COMPARE_LIST'] ==
'N' && $this->arParams[
'COMPARE_PATH'] !=
'')
3563 $compareUri =
new Main\Web\Uri($this->arParams[
'COMPARE_PATH']);
3567 $compareUri = $currentUri;
3570 $currentUri->deleteParams($clearParams);
3571 $compareUri->deleteParams($clearParams);
3574 $urls[
'BUY_URL_TEMPLATE'] = $currentUri->addParams([$actionVar => self::ACTION_BUY, $productIdVar =>
'#ID#'])->getUri();
3575 $urls[
'ADD_URL_TEMPLATE'] = $currentUri->addParams([$actionVar => self::ACTION_ADD_TO_BASKET, $productIdVar =>
'#ID#'])->getUri();
3576 $urls[
'SUBSCRIBE_URL_TEMPLATE'] = $currentUri->addParams([$actionVar => self::ACTION_SUBSCRIBE, $productIdVar =>
'#ID#'])->getUri();
3578 $urls[
'COMPARE_URL_TEMPLATE'] = $compareUri->addParams([$compareActionVar => self::ACTION_ADD_TO_COMPARE, $productIdVar =>
'#ID#'])->getUri();
3579 $urls[
'COMPARE_DELETE_URL_TEMPLATE'] = $compareUri->addParams([$compareActionVar => self::ACTION_DELETE_FROM_COMPARE, $productIdVar =>
'#ID#'])->getUri();
3581 unset($compareUri, $currentUri, $clearParams);
3583 foreach (array_keys($urls) as $index)
3585 $value = str_replace(
'%23ID%23',
'#ID#', $urls[$index]);
3586 $urls[
'~'.$index] = $value;
3591 $this->storage[
'URLS'] = $urls;
3603 $id = $element[
'ID'];
3605 $catalog = !empty($this->storage[
'CATALOGS'][$element[
'IBLOCK_ID']])
3606 ? $this->storage[
'CATALOGS'][$element[
'IBLOCK_ID']]
3609 $element[
'ITEM_PRICE_MODE'] =
null;
3610 $element[
'ITEM_PRICES'] =
array();
3611 $element[
'ITEM_QUANTITY_RANGES'] =
array();
3612 $element[
'ITEM_MEASURE_RATIOS'] =
array();
3613 $element[
'ITEM_MEASURE'] =
array();
3614 $element[
'ITEM_MEASURE_RATIO_SELECTED'] =
null;
3615 $element[
'ITEM_QUANTITY_RANGE_SELECTED'] =
null;
3616 $element[
'ITEM_PRICE_SELECTED'] =
null;
3620 if (!isset($this->productWithOffers[
$iblockId]))
3622 if ($element[
'PRODUCT'][
'TYPE'] ==
Catalog\ProductTable::TYPE_SKU)
3624 $this->productWithOffers[
$iblockId][$id] = $id;
3625 if ($this->storage[
'SHOW_CATALOG_WITH_OFFERS'] && $enableCompatible)
3627 $this->productWithPrices[$id] = $id;
3628 $this->calculatePrices[$id] = $id;
3633 $element[
'PRODUCT'][
'TYPE'],
3635 Catalog\ProductTable::TYPE_PRODUCT,
3636 Catalog\ProductTable::TYPE_SET,
3637 Catalog\ProductTable::TYPE_OFFER,
3638 Catalog\ProductTable::TYPE_SERVICE,
3642 $this->productWithPrices[$id] = $id;
3643 $this->calculatePrices[$id] = $id;
3646 if (isset($this->productWithPrices[$id]))
3648 if ($element[
'PRODUCT'][
'MEASURE'] > 0)
3650 $element[
'ITEM_MEASURE'] =
array(
3651 'ID' => $element[
'PRODUCT'][
'MEASURE'],
3658 $element[
'ITEM_MEASURE'] =
array(
3660 'TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'SYMBOL_RUS'],
3661 '~TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'~SYMBOL_RUS']
3664 if ($enableCompatible)
3666 $element[
'CATALOG_MEASURE'] = $element[
'ITEM_MEASURE'][
'ID'];
3667 $element[
'CATALOG_MEASURE_NAME'] = $element[
'ITEM_MEASURE'][
'TITLE'];
3668 $element[
'~CATALOG_MEASURE_NAME'] = $element[
'ITEM_MEASURE'][
'~TITLE'];
3675 $element[
'IBLOCK_ID'],
3676 $this->storage[
'PRICES'],
3678 $this->arParams[
'PRICE_VAT_INCLUDE'],
3679 $this->storage[
'CONVERT_CURRENCY']
3681 if (!empty($element[
'PRICES']))
3686 $element[
'CAN_BUY'] = !empty($element[
'PRICES']);
3714 if ($this->useCatalog && !empty($this->iblockProducts))
3718 $paramStack =
array();
3720 if ($enableCompatible)
3722 $paramStack[
'USE_PRICE_COUNT'] = $this->arParams[
'USE_PRICE_COUNT'];
3723 $paramStack[
'SHOW_PRICE_COUNT'] = $this->arParams[
'SHOW_PRICE_COUNT'];
3724 $this->arParams[
'USE_PRICE_COUNT'] =
false;
3725 $this->arParams[
'SHOW_PRICE_COUNT'] = 1;
3728 foreach (array_keys($this->iblockProducts) as
$iblock)
3730 if (!empty($this->productWithOffers[
$iblock]))
3733 if (!empty($iblockOffers))
3735 $offersId = array_keys($iblockOffers);
3747 $offers = array_merge($offers, $iblockOffers);
3749 unset($iblockOffers);
3752 if ($enableCompatible)
3754 $this->arParams[
'USE_PRICE_COUNT'] = $paramStack[
'USE_PRICE_COUNT'];
3755 $this->arParams[
'SHOW_PRICE_COUNT'] = $paramStack[
'SHOW_PRICE_COUNT'];
3757 unset($enableCompatible, $paramStack);
3770 $iblockParams = $this->storage[
'IBLOCK_PARAMS'][
$iblockId];
3777 && !empty($this->productWithOffers[
$iblockId])
3782 $productProperty =
'PROPERTY_'.$catalog[
'SKU_PROPERTY_ID'];
3783 $productPropertyValue = $productProperty.
'_VALUE';
3786 $offersFilter[$productProperty] = $this->productWithOffers[
$iblockId];
3788 $offersSelect =
array(
3792 $productProperty => 1,
3793 'PREVIEW_PICTURE' => 1,
3794 'DETAIL_PICTURE' => 1,
3797 if ($this->arParams[
'SHOW_SKU_DESCRIPTION'] ===
'Y')
3799 $offersSelect[
'PREVIEW_TEXT'] = 1;
3800 $offersSelect[
'DETAIL_TEXT'] = 1;
3801 $offersSelect[
'PREVIEW_TEXT_TYPE'] = 1;
3802 $offersSelect[
'DETAIL_TEXT_TYPE'] = 1;
3805 if (!empty($iblockParams[
'OFFERS_FIELD_CODE']))
3807 foreach ($iblockParams[
'OFFERS_FIELD_CODE'] as
$code)
3808 $offersSelect[
$code] = 1;
3820 $checkFields =
array();
3821 foreach (array_keys($offersOrder) as
$code)
3826 $checkFields[] =
$code;
3833 $offersId =
array();
3834 $offersCount =
array();
3844 $row[
'ID'] = (int)$row[
'ID'];
3845 $row[
'IBLOCK_ID'] = (int)$row[
'IBLOCK_ID'];
3846 $productId = (int)$row[$productPropertyValue];
3848 if ($productId <= 0)
3851 if ($enableCompatible && $this->arParams[
'OFFERS_LIMIT'] > 0)
3853 $offersCount[$productId]++;
3854 if($offersCount[$productId] > $this->arParams[
'OFFERS_LIMIT'])
3858 $row[
'SORT_HASH'] =
'ID';
3859 if (!empty($checkFields))
3862 foreach ($checkFields as
$code)
3863 $checkValues .= ($row[
$code] ??
'').
'|';
3865 if ($checkValues !=
'')
3866 $row[
'SORT_HASH'] = md5($checkValues);
3867 unset($checkValues);
3869 $row[
'LINK_ELEMENT_ID'] = $productId;
3870 $row[
'PROPERTIES'] =
array();
3871 $row[
'DISPLAY_PROPERTIES'] =
array();
3873 $row[
'PRODUCT'] =
array(
3874 'TYPE' => (
int)$row[
'~TYPE'],
3875 'AVAILABLE' => $row[
'~AVAILABLE'],
3876 'BUNDLE' => $row[
'~BUNDLE'],
3877 'QUANTITY' => $row[
'~QUANTITY'],
3878 'QUANTITY_TRACE' => $row[
'~QUANTITY_TRACE'],
3879 'CAN_BUY_ZERO' => $row[
'~CAN_BUY_ZERO'],
3880 'MEASURE' => (
int)$row[
'~MEASURE'],
3881 'SUBSCRIBE' => $row[
'~SUBSCRIBE'],
3882 'VAT_ID' => (
int)$row[
'~VAT_ID'],
3884 'VAT_INCLUDED' => $row[
'~VAT_INCLUDED'],
3885 'WEIGHT' => (
float)$row[
'~WEIGHT'],
3886 'WIDTH' => (
float)$row[
'~WIDTH'],
3887 'LENGTH' => (
float)$row[
'~LENGTH'],
3888 'HEIGHT' => (
float)$row[
'~HEIGHT'],
3889 'PAYMENT_TYPE' => $row[
'~PAYMENT_TYPE'],
3890 'RECUR_SCHEME_TYPE' => $row[
'~RECUR_SCHEME_TYPE'],
3891 'RECUR_SCHEME_LENGTH' => (
int)$row[
'~RECUR_SCHEME_LENGTH'],
3892 'TRIAL_PRICE_ID' => (
int)$row[
'~TRIAL_PRICE_ID']
3897 if ($row[
'PRODUCT'][
'VAT_ID'] > 0)
3898 $vatId = $row[
'PRODUCT'][
'VAT_ID'];
3899 elseif ($this->storage[
'IBLOCKS_VAT'][
$catalog[
'IBLOCK_ID']] > 0)
3900 $vatId = $this->storage[
'IBLOCKS_VAT'][
$catalog[
'IBLOCK_ID']];
3901 if ($vatId > 0 && isset($this->storage[
'VATS'][$vatId]))
3902 $vatRate = $this->storage[
'VATS'][$vatId];
3903 $row[
'PRODUCT'][
'VAT_RATE'] = $vatRate;
3904 unset($vatRate, $vatId);
3906 if ($enableCompatible)
3908 foreach ($translateFields as $currentKey => $oldKey)
3909 $row[$oldKey] = $row[$currentKey];
3910 unset($currentKey, $oldKey);
3911 $row[
'~CATALOG_VAT'] = $row[
'PRODUCT'][
'VAT_RATE'];
3912 $row[
'CATALOG_VAT'] = $row[
'PRODUCT'][
'VAT_RATE'];
3917 $row[
'~CATALOG_TYPE'] = $row[
'PRODUCT'][
'TYPE'];
3918 $row[
'CATALOG_TYPE'] = $row[
'PRODUCT'][
'TYPE'];
3919 $row[
'~CATALOG_QUANTITY'] = $row[
'PRODUCT'][
'QUANTITY'];
3920 $row[
'CATALOG_QUANTITY'] = $row[
'PRODUCT'][
'QUANTITY'];
3921 $row[
'~CATALOG_QUANTITY_TRACE'] = $row[
'PRODUCT'][
'QUANTITY_TRACE'];
3922 $row[
'CATALOG_QUANTITY_TRACE'] = $row[
'PRODUCT'][
'QUANTITY_TRACE'];
3923 $row[
'~CATALOG_CAN_BUY_ZERO'] = $row[
'PRODUCT'][
'CAN_BUY_ZERO'];
3924 $row[
'CATALOG_CAN_BUY_ZERO'] = $row[
'PRODUCT'][
'CAN_BUY_ZERO'];
3925 $row[
'~CATALOG_SUBSCRIBE'] = $row[
'PRODUCT'][
'SUBSCRIBE'];
3926 $row[
'CATALOG_SUBSCRIBE'] = $row[
'PRODUCT'][
'SUBSCRIBE'];
3930 unset($row[$field], $row[
'~'.$field]);
3933 if ($row[
'PRODUCT'][
'TYPE'] ==
Catalog\ProductTable::TYPE_OFFER)
3934 $this->calculatePrices[$row[
'ID']] = $row[
'ID'];
3936 $row[
'ITEM_PRICE_MODE'] =
null;
3937 $row[
'ITEM_PRICES'] =
array();
3938 $row[
'ITEM_QUANTITY_RANGES'] =
array();
3939 $row[
'ITEM_MEASURE_RATIOS'] =
array();
3940 $row[
'ITEM_MEASURE'] =
array();
3941 $row[
'ITEM_MEASURE_RATIO_SELECTED'] =
null;
3942 $row[
'ITEM_QUANTITY_RANGE_SELECTED'] =
null;
3943 $row[
'ITEM_PRICE_SELECTED'] =
null;
3946 if ($row[
'PRODUCT'][
'MEASURE'] > 0)
3948 $row[
'ITEM_MEASURE'] =
array(
3949 'ID' => $row[
'PRODUCT'][
'MEASURE'],
3956 $row[
'ITEM_MEASURE'] =
array(
3958 'TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'SYMBOL_RUS'],
3959 '~TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'~SYMBOL_RUS']
3962 if ($enableCompatible)
3964 $row[
'CATALOG_MEASURE'] = $row[
'ITEM_MEASURE'][
'ID'];
3965 $row[
'CATALOG_MEASURE_NAME'] = $row[
'ITEM_MEASURE'][
'TITLE'];
3966 $row[
'~CATALOG_MEASURE_NAME'] = $row[
'ITEM_MEASURE'][
'~TITLE'];
3969 $row[
'PROPERTIES'] =
array();
3970 $row[
'DISPLAY_PROPERTIES'] =
array();
3974 array(
'PREVIEW_PICTURE',
'DETAIL_PICTURE'),
3979 $offersId[$row[
'ID']] = $row[
'ID'];
3980 $offers[$row[
'ID']] = $row;
3984 if (!empty($offersId))
3986 $loadPropertyCodes = ($iblockParams[
'OFFERS_PROPERTY_CODE'] ?? []);
3987 if (
Iblock\
Model\PropertyFeature::isEnabledFeatures())
3989 $loadPropertyCodes = array_merge($loadPropertyCodes, $iblockParams[
'OFFERS_TREE_PROPS'] ?? []);
3993 unset($loadPropertyCodes);
3995 if (!empty($propertyList) || $this->useDiscountCache)
3997 \CIBlockElement::GetPropertyValuesArray($offers,
$catalog[
'IBLOCK_ID'], $offersFilter);
3998 foreach ($offers as &$row)
4000 if ($this->useDiscountCache)
4002 if ($this->storage[
'USE_SALE_DISCOUNTS'])
4005 \CCatalogDiscount::SetProductPropertiesCache($row[
'ID'], $row[
"PROPERTIES"]);
4008 if (!empty($propertyList))
4010 foreach ($propertyList as $pid)
4012 if (!isset($row[
"PROPERTIES"][$pid]))
4014 $prop = &$row[
"PROPERTIES"][$pid];
4015 $boolArr = is_array($prop[
"VALUE"]);
4017 ($boolArr && !empty($prop[
"VALUE"])) ||
4018 (!$boolArr && (
string)$prop[
"VALUE"] !==
'')
4021 $row[
"DISPLAY_PROPERTIES"][$pid] = \CIBlockFormatProperties::GetDisplayValue($row, $prop);
4023 unset($boolArr, $prop);
4030 if (!empty($propertyList))
4035 if ($this->useDiscountCache)
4037 if ($this->storage[
'USE_SALE_DISCOUNTS'])
4057 $offersFilter =
array(
4060 'ACTIVE_DATE' =>
'Y',
4061 'CHECK_PERMISSIONS' =>
'N'
4064 if ($this->arParams[
'HIDE_NOT_AVAILABLE_OFFERS'] ===
'Y')
4066 $offersFilter[
'AVAILABLE'] =
'Y';
4068 elseif ($this->arParams[
'HIDE_NOT_AVAILABLE_OFFERS'] ===
'L')
4070 $offersFilter[
'CUSTOM_FILTER'] =
array(
4077 if (!$this->arParams[
'USE_PRICE_COUNT'])
4079 $offersFilter[
'SHOW_PRICE_COUNT'] = $this->arParams[
'SHOW_PRICE_COUNT'];
4082 return $offersFilter;
4092 $offersOrder =
array(
4093 mb_strtoupper($this->arParams[
'OFFERS_SORT_FIELD']) => $this->arParams[
'OFFERS_SORT_ORDER'],
4094 mb_strtoupper($this->arParams[
'OFFERS_SORT_FIELD2']) => $this->arParams[
'OFFERS_SORT_ORDER2']
4096 if (!isset($offersOrder[
'ID']))
4097 $offersOrder[
'ID'] =
'DESC';
4099 return $offersOrder;
4106 foreach ($offers as &$offer)
4108 $elementId = $offer[
'LINK_ELEMENT_ID'];
4110 if (!isset($this->elementLinks[$elementId]))
4113 $offer[
'CAN_BUY'] = $this->elementLinks[$elementId][
'ACTIVE'] ===
'Y' && $offer[
'CAN_BUY'];
4115 $this->elementLinks[$elementId][
'OFFERS'][] = $offer;
4117 unset($elementId, $offer);
4126 $this->arParams[
'CONVERT_CURRENCY'] ===
'Y'
4127 && !empty($this->storage[
'CURRENCY_LIST'])
4128 && defined(
'BX_COMP_MANAGED_CACHE')
4131 $this->storage[
'CURRENCY_LIST'][$this->storage[
'CONVERT_CURRENCY'][
'CURRENCY_ID']] = $this->storage[
'CONVERT_CURRENCY'][
'CURRENCY_ID'];
4133 foreach ($this->storage[
'CURRENCY_LIST'] as $oneCurrency)
4135 $taggedCache->registerTag(
'currency_id_'.$oneCurrency);
4138 unset($oneCurrency);
4139 unset($taggedCache);
4142 unset($this->storage[
'CURRENCY_LIST']);
4187 if (!empty($this->iblockProducts))
4190 $iblockIterator = Iblock\IblockSiteTable::getList(
array(
4191 'select' =>
array(
'IBLOCK_ID'),
4193 '=IBLOCK_ID' => array_keys($this->iblockProducts),
4195 '=IBLOCK.ACTIVE' =>
'Y'
4198 while (
$iblock = $iblockIterator->fetch())
4200 $iblocks[
$iblock[
'IBLOCK_ID']] =
true;
4203 foreach ($this->iblockProducts as
$iblock => $products)
4205 if (!isset($iblocks[
$iblock]))
4207 unset($this->iblockProducts[
$iblock]);
4211 if (empty($this->iblockProducts))
4214 $this->errorCollection->setError(
new Error(Loc::getMessage(
'INVALID_IBLOCK'), self::ERROR_TEXT));
4231 if (!empty($this->productIds) && is_array($this->productIds))
4233 foreach ($this->productIds as $productId)
4236 if ($this->productIdMap[$productId] == $productId)
4241 if (isset($this->elementLinks[$this->productIdMap[$productId]]) && !empty($this->elementLinks[$this->productIdMap[$productId]][
'OFFERS']))
4244 foreach ($this->elementLinks[$this->productIdMap[$productId]][
'OFFERS'] as
$key => $offer)
4246 if ($offer[
'ID'] != $productId)
4248 unset($this->elementLinks[$this->productIdMap[$productId]][
'OFFERS'][
$key]);
4261 $this->arResult = array_merge($this->arResult, $this->storage[
'URLS']);
4262 $this->arResult[
'CONVERT_CURRENCY'] = $this->storage[
'CONVERT_CURRENCY'];
4263 $this->arResult[
'CATALOGS'] = $this->storage[
'CATALOGS'];
4264 $this->arResult[
'MODULES'] = $this->storage[
'MODULES'];
4265 $this->arResult[
'PRICES_ALLOW'] = $this->storage[
'PRICES_ALLOW'];
4269 if ($this->arParams[
'IBLOCK_ID'] > 0)
4271 $this->arResult[
'CATALOG'] =
false;
4274 !empty($this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']])
4275 && is_array($this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']])
4278 $this->arResult[
'CATALOG'] = $this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']];
4291 if ($this->request->get($this->arParams[
'ACTION_VARIABLE'].self::ACTION_BUY) !==
null)
4293 $action = self::ACTION_BUY;
4295 elseif ($this->request->get($this->arParams[
'ACTION_VARIABLE'].self::ACTION_ADD_TO_BASKET))
4297 $action = self::ACTION_ADD_TO_BASKET;
4301 $action = $this->request->get($this->arParams[
'ACTION_VARIABLE']);
4304 ? mb_strtoupper(trim($action))
4309 $productId = (int)$this->request->get($this->arParams[
'PRODUCT_ID_VARIABLE']);
4312 ($action == self::ACTION_ADD_TO_BASKET || $action == self::ACTION_BUY || $action == self::ACTION_SUBSCRIBE)
4317 $addByAjax = $this->request->get(
'ajax_basket') ===
'Y';
4320 $this->request->set($this->request->toArray());
4331 'MESSAGE' => Loc::getMessage(
'CATALOG_SUCCESSFUL_ADD_TO_BASKET')
4337 'STATUS' =>
'ERROR',
4343 header(
'Content-Type: application/json');
4344 \CMain::FinalActions(
Main\
Web\Json::encode($addResult));
4350 $pathRedirect = $action == self::ACTION_BUY
4351 ? $this->arParams[
'BASKET_URL']
4353 $this->arParams[
'PRODUCT_ID_VARIABLE'],
4354 $this->arParams[
'ACTION_VARIABLE'],
4355 $this->arParams[
'PRODUCT_QUANTITY_VARIABLE'],
4356 $this->arParams[
'PRODUCT_PROPS_VARIABLE']
4363 $this->errorCollection->setError(
new Error(
$errorMsg, self::ERROR_TEXT));
4371 $successfulAdd =
true;
4374 if (!empty($productId) && ($sectionId > 0 || !empty($sectionCode)))
4378 if (!empty($productsMap[$productId]))
4380 $sectionId = (int)$sectionId;
4381 $sectionCode = (string)$sectionCode;
4383 $filter = [
'ID' => $productsMap[$productId]];
4388 $filter[
'SECTION_ID'] = $sectionId;
4389 $filter[
'INCLUDE_SUBSECTIONS'] =
'Y';
4390 $elementIterator = \CIBlockElement::GetList(
array(),
$filter,
false,
false,
array(
'ID'));
4391 $element = $elementIterator->Fetch();
4392 unset($elementIterator);
4394 elseif ($sectionCode !=
'')
4396 $iblockId = (int)\CIBlockElement::GetIBlockByID($productsMap[$productId]);
4399 $sectionIterator = \CIBlockSection::GetList(
4401 [
'IBLOCK_ID' =>
$iblockId,
'=CODE' => $sectionCode],
4405 $section = $sectionIterator->Fetch();
4406 unset($sectionIterator);
4407 if (!empty($section))
4409 $filter[
'SECTION_ID'] = (int)$section[
'ID'];
4410 $filter[
'INCLUDE_SUBSECTIONS'] =
'Y';
4411 $elementIterator = \CIBlockElement::GetList(
array(),
$filter,
false,
false,
array(
'ID'));
4412 $element = $elementIterator->Fetch();
4413 unset($elementIterator);
4420 if (empty($element))
4422 $successfulAdd =
false;
4423 $errorMsg = Loc::getMessage(
'CATALOG_PRODUCT_NOT_FOUND');
4441 $successfulAdd =
true;
4445 $productProperties =
array();
4447 $productId = (int)$productId;
4448 if ($productId <= 0)
4450 $errorMsg = Loc::getMessage(
'CATALOG_PRODUCT_ID_IS_ABSENT');
4451 $successfulAdd =
false;
4457 if (empty($product))
4459 $errorMsg = Loc::getMessage(
'CATALOG_PRODUCT_NOT_FOUND');
4460 $successfulAdd =
false;
4465 if ($this->arParams[
'CHECK_LANDING_PRODUCT_SECTION'])
4468 $productId, $this->arParams[
'SECTION_ID'], $this->arParams[
'SECTION_CODE']
4476 $errorMsg = Loc::getMessage(
'CATALOG_PRODUCT_NOT_FOUND');
4477 $successfulAdd =
false;
4482 if ($this->arParams[
'ADD_PROPERTIES_TO_BASKET'] ===
'Y')
4485 $iblockParams = $this->storage[
'IBLOCK_PARAMS'][$product[
'PRODUCT_IBLOCK_ID']];
4486 if ($product[
'TYPE'] ==
Catalog\ProductTable::TYPE_OFFER)
4488 $skuAddProps = $this->request->get(
'basket_props') ?:
'';
4489 if (!empty($iblockParams[
'OFFERS_CART_PROPERTIES']) || !empty($skuAddProps))
4493 $product[
'PRODUCT_IBLOCK_ID'],
4494 $iblockParams[
'OFFERS_CART_PROPERTIES'],
4498 unset($skuAddProps);
4502 if (!empty($iblockParams[
'CART_PROPERTIES']))
4504 $productPropsVar = $this->request->get($this->arParams[
'PRODUCT_PROPS_VARIABLE']);
4505 if (is_array($productPropsVar))
4508 $product[
'PRODUCT_IBLOCK_ID'],
4510 $iblockParams[
'CART_PROPERTIES'],
4512 $this->arParams[
'PARTIAL_PRODUCT_PROPERTIES'] ===
'Y'
4514 if (!is_array($productProperties))
4516 $errorMsg = Loc::getMessage(
'CATALOG_PARTIAL_BASKET_PROPERTIES_ERROR');
4517 $successfulAdd =
false;
4522 if ($this->arParams[
'PARTIAL_PRODUCT_PROPERTIES'] !==
'Y')
4524 $errorMsg = Loc::getMessage(
'CATALOG_EMPTY_BASKET_PROPERTIES_ERROR');
4525 $successfulAdd =
false;
4528 unset($productPropsVar);
4531 unset($iblockParams);
4537 if ($this->arParams[
'USE_PRODUCT_QUANTITY'])
4539 $quantity = (float)$this->request->get($this->arParams[
'PRODUCT_QUANTITY_VARIABLE']);
4546 array(
'PRODUCT_ID' => $productId),
4549 array(
'PRODUCT_ID',
'RATIO')
4551 if ($ratio = $ratioIterator->Fetch())
4553 $intRatio = (int)$ratio[
'RATIO'];
4554 $floatRatio = (float)$ratio[
'RATIO'];
4555 $quantity = $floatRatio > $intRatio ? $floatRatio : $intRatio;
4568 if (isset($rewriteFields[
'SUBSCRIBE']) && $rewriteFields[
'SUBSCRIBE'] ==
'Y')
4579 $errorMsg = Loc::getMessage(
'CATALOG_ERROR2BASKET');
4582 $successfulAdd =
false;
4588 'PRODUCT_ID' => $productId,
4589 'QUANTITY' => $quantity
4591 if (!empty($productProperties))
4593 $product[
'PROPS'] = $productProperties;
4596 $basketResult = Catalog\Product\Basket::addProduct($product, $rewriteFields, [
4599 if (!$basketResult->isSuccess())
4601 $errorMsg = implode(
'; ', $basketResult->getErrorMessages());
4602 $successfulAdd =
false;
4604 unset($basketResult);
4620 return ($this->arParams[
'USE_MERGE_WHEN_ADD_PRODUCT_TO_BASKET'] ??
'Y') !==
'N';
4625 $rewriteFields = [];
4627 if ($action === self::ACTION_ADD_TO_BASKET || $action === self::ACTION_BUY)
4629 $rewriteFields[
'DELAY'] =
'N';
4632 if ($action == self::ACTION_SUBSCRIBE)
4634 $notify = unserialize(
Main\
Config\Option::get(
'sale',
'subscribe_prod',
''), [
'allowed_classes' =>
false]);
4635 if (!empty($notify[$this->
getSiteId()]) && $notify[$this->
getSiteId()][
'use'] ===
'Y')
4637 $rewriteFields[
'SUBSCRIBE'] =
'Y';
4638 $rewriteFields[
'CAN_BUY'] =
'N';
4642 return $rewriteFields;
4654 if (empty($this->productIds))
4656 static::sendJsonAnswer();
4672 if (empty($this->productIds))
4674 static::sendJsonAnswer();
4688 if ($lastUsage == 0 || (time() - $lastUsage) > 3600)
4744 $emptyPreview =
false;
4746 $emptyPreviewPath = $this->
getTemplate()->GetFolder().
'/images/no_photo.png';
4749 if ($file->isExists())
4754 $emptyPreview =
array(
4756 'SRC' => $emptyPreviewPath,
4757 'FILE_NAME' =>
'no_photo.png',
4758 'WIDTH' => (
int)$size[0],
4759 'HEIGHT' => (
int)$size[1]
4764 return $emptyPreview;
4773 $rows[] = array_splice(
$items, 0, $this->arParams[
'LINE_ELEMENT_COUNT']);
4781 $currencies =
array();
4783 if (!empty($this->arResult[
'MODULES'][
'currency']))
4785 if (isset($this->arResult[
'CONVERT_CURRENCY'][
'CURRENCY_ID']))
4787 $currencyFormat = \CCurrencyLang::GetFormatDescription($this->arResult[
'CONVERT_CURRENCY'][
'CURRENCY_ID']);
4788 $currencies =
array(
4790 'CURRENCY' => $this->arResult[
'CONVERT_CURRENCY'][
'CURRENCY_ID'],
4806 'select' =>
array(
'CURRENCY')
4808 while (
$currency = $currencyIterator->fetch())
4811 $currencies[] =
array(
4842 $result[
'JS'] = Main\Page\Asset::getInstance()->getJs();
4849 \CMain::FinalActions();
4862 $this->request->get($this->arParams[
'ACTION_VARIABLE']) !==
null
4863 && $this->request->get($this->arParams[
'PRODUCT_ID_VARIABLE']) !==
null
4866 $action =
'processLink';
4868 elseif ($this->request->isAjaxRequest() && $this->request->get(
'action') ===
'deferredLoad')
4870 $action = $this->request->get(
'bigData') ===
'Y' ?
'bigDataLoad' :
'deferredLoad';
4874 $action =
'initialLoad';
4887 if (is_callable(
array($this, $action.
'Action')))
4889 call_user_func(
array($this, $action.
'Action'));
4902 return $this->processErrors();
4911 return $this->processErrors();
4914 return $this->arResult[
'ID'] ??
false;
4937 $params[
'SHOW_OLD_PRICE'] =
$params[
'SHOW_OLD_PRICE'] ===
'Y' ?
'Y' :
'N';
4938 $params[
'SHOW_CLOSE_POPUP'] =
$params[
'SHOW_CLOSE_POPUP'] ===
'Y' ?
'Y' :
'N';
4939 $params[
'SHOW_DISCOUNT_PERCENT'] =
$params[
'SHOW_DISCOUNT_PERCENT'] ===
'Y' ?
'Y' :
'N';
4940 $params[
'DISCOUNT_PERCENT_POSITION'] = trim(
$params[
'DISCOUNT_PERCENT_POSITION']) ?:
'bottom-right';
4941 $params[
'LABEL_PROP_POSITION'] = trim(
$params[
'LABEL_PROP_POSITION']) ?:
'top-left';
4942 $params[
'PRODUCT_SUBSCRIPTION'] =
$params[
'PRODUCT_SUBSCRIPTION'] ===
'N' ?
'N' :
'Y';
4944 $params[
'MESS_BTN_ADD_TO_BASKET'] = trim(
$params[
'MESS_BTN_ADD_TO_BASKET']);
4945 $params[
'MESS_BTN_SUBSCRIBE'] = trim(
$params[
'MESS_BTN_SUBSCRIBE']);
4947 $params[
'MESS_NOT_AVAILABLE'] = trim(
$params[
'MESS_NOT_AVAILABLE']);
4949 $params[
'SHOW_SLIDER'] =
$params[
'SHOW_SLIDER'] ===
'N' ?
'N' :
'Y';
4950 $params[
'SLIDER_INTERVAL'] = (int)
$params[
'SLIDER_INTERVAL'] ?: 5000;
4951 $params[
'SLIDER_PROGRESS'] =
$params[
'SLIDER_PROGRESS'] ===
'Y' ?
'Y' :
'N';
4952 $params[
'USE_ENHANCED_ECOMMERCE'] =
$params[
'USE_ENHANCED_ECOMMERCE'] ===
'Y' ?
'Y' :
'N';
4954 $params[
'BRAND_PROPERTY'] =
$params[
'BRAND_PROPERTY'] !==
'-' ? trim(
$params[
'BRAND_PROPERTY']) :
'';
4956 if (!isset(
$params[
'SHOW_MAX_QUANTITY']) || !in_array(
$params[
'SHOW_MAX_QUANTITY'],
array(
'Y',
'M',
'N')))
4958 $params[
'SHOW_MAX_QUANTITY'] =
'N';
4961 $params[
'RELATIVE_QUANTITY_FACTOR'] = (int)(
$params[
'RELATIVE_QUANTITY_FACTOR'] ?? 0) > 0 ? (int)
$params[
'RELATIVE_QUANTITY_FACTOR'] : 5;
4967 'TEMPLATE_THEME' =>
'blue',
4968 'SHOW_MAX_QUANTITY' =>
'N',
4969 'SHOW_OLD_PRICE' =>
'N',
4970 'SHOW_CLOSE_POPUP' =>
'N',
4971 'SHOW_DISCOUNT_PERCENT' =>
'N',
4972 'DISCOUNT_PERCENT_POSITION' =>
'bottom-right',
4973 'LABEL_PROP' =>
array(),
4974 'LABEL_PROP_MOBILE' =>
array(),
4975 'LABEL_PROP_POSITION' =>
'top-left',
4976 'PRODUCT_SUBSCRIPTION' =>
'Y',
4977 'MESS_BTN_BUY' =>
'',
4978 'MESS_BTN_ADD_TO_BASKET' =>
'',
4979 'MESS_BTN_SUBSCRIBE' =>
'',
4980 'MESS_BTN_DETAIL' =>
'',
4981 'MESS_NOT_AVAILABLE' =>
'',
4982 'MESS_BTN_COMPARE' =>
'',
4983 'SHOW_SLIDER' =>
'N',
4984 'SLIDER_INTERVAL' => 5000,
4985 'SLIDER_PROGRESS' =>
'N',
4986 'USE_ENHANCED_ECOMMERCE' =>
'N',
4987 'DATA_LAYER_NAME' =>
'dataLayer',
4988 'BRAND_PROPERTY' =>
''
4994 $theme =& $this->arParams[
'TEMPLATE_THEME'];
4995 $theme = (string)$theme;
4999 $theme = preg_replace(
'/[^a-zA-Z0-9_\-\(\)\!]/',
'', $theme);
5000 if ($theme ===
'site')
5011 $templateFolder = $this->
getTemplate()->GetFolder();
5015 if ($themesFolder->isExists())
5019 if (!$file->isExists())
5047 if (!empty($item) && is_array($item))
5049 $item[
'ENLARGED'] =
'N';
5050 $propertyCode = (string)$propertyCode;
5052 if ($propertyCode !==
'' && isset($item[
'PROPERTIES'][$propertyCode]))
5054 $prop = $item[
'PROPERTIES'][$propertyCode];
5055 if (!empty($prop[
'VALUE']))
5057 $item[
'ENLARGED'] =
'Y';
5065 $propCode = $this->storage[
'IBLOCK_PARAMS'][
$iblock][
'ADD_PICT_PROP'];
5075 $slider = array_slice($slider, 0, $limit);
5078 $item[
'SHOW_SLIDER'] =
true;
5079 $item[
'MORE_PHOTO'] = $slider;
5080 $item[
'MORE_PHOTO_COUNT'] =
count($slider);
5085 $propCode = $this->storage[
'IBLOCK_PARAMS'][
$iblock][
'OFFERS_ADD_PICT_PROP'];
5095 $slider = array_slice($slider, 0, $limit);
5098 $item[
'MORE_PHOTO'] = $slider;
5099 $item[
'MORE_PHOTO_COUNT'] =
count($slider);
5104 if ($this->arResult[
'MODULES'][
'catalog'])
5106 $item[
'CATALOG'] =
true;
5108 $item[
'CATALOG_TYPE'] = $item[
'PRODUCT'][
'TYPE'];
5113 $item[
'CATALOG_TYPE'] = 0;
5114 $item[
'OFFERS'] =
array();
5122 'SORT' => PHP_INT_MAX,
5126 if (isset($offer[
'DISPLAY_PROPERTIES'][
$code]))
5128 $matrixFields[
$code] =
true;
5129 $cell[
'NA'] =
false;
5131 if ($skuPropList[
$code][
'USER_TYPE'] ===
'directory')
5133 $intValue = $skuPropList[
$code][
'XML_MAP'][$offer[
'DISPLAY_PROPERTIES'][
$code][
'VALUE']] ?? 0;
5134 $cell[
'VALUE'] = $intValue;
5136 elseif ($skuPropList[
$code][
'PROPERTY_TYPE'] ===
'L')
5138 $cell[
'VALUE'] = (int)$offer[
'DISPLAY_PROPERTIES'][
$code][
'VALUE_ENUM_ID'];
5140 elseif ($skuPropList[
$code][
'PROPERTY_TYPE'] ===
'E')
5142 $cell[
'VALUE'] = (int)$offer[
'DISPLAY_PROPERTIES'][
$code][
'VALUE'];
5145 $cell[
'SORT'] = $skuPropList[
$code][
'VALUES'][$cell[
'VALUE']][
'SORT'];
5153 if (!$this->useCatalog)
5155 if (!isset($this->storage[
'CATALOGS'][
$iblockId]))
5158 $this->storage[
'CATALOGS'][
$iblockId][
'CATALOG_TYPE'] != \CCatalogSku::TYPE_PRODUCT
5159 && $this->storage[
'CATALOGS'][
$iblockId][
'CATALOG_TYPE'] != \CCatalogSku::TYPE_FULL
5162 return $this->storage[
'CATALOGS'][
$iblockId][
'IBLOCK_ID'];
5176 if (!$this->useCatalog)
5178 if (!isset($this->storage[
'CATALOGS'][
$iblockId]))
5181 switch ($this->storage[
'CATALOGS'][
$iblockId][
'CATALOG_TYPE'])
5183 case \CCatalogSku::TYPE_CATALOG:
5184 $list = Catalog\Product\PropertyCatalogFeature::getBasketPropertyCodes(
5190 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'CART_PROPERTIES'] = $list;
5192 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'OFFERS_CART_PROPERTIES'] = [];
5194 case \CCatalogSku::TYPE_PRODUCT:
5195 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'CART_PROPERTIES'] = [];
5196 $list = Catalog\Product\PropertyCatalogFeature::getBasketPropertyCodes(
5202 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'OFFERS_CART_PROPERTIES'] = $list;
5205 case \CCatalogSku::TYPE_FULL:
5206 $list = Catalog\Product\PropertyCatalogFeature::getBasketPropertyCodes(
5212 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'CART_PROPERTIES'] = $list;
5213 $list = Catalog\Product\PropertyCatalogFeature::getBasketPropertyCodes(
5219 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'OFFERS_CART_PROPERTIES'] = $list;
5222 case \CCatalogSku::TYPE_OFFERS:
5223 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'CART_PROPERTIES'] = [];
5224 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'OFFERS_CART_PROPERTIES'] = [];
5233 if (!$this->useCatalog)
5235 if (!isset($this->storage[
'CATALOGS'][
$iblockId]))
5238 switch ($this->storage[
'CATALOGS'][
$iblockId][
'CATALOG_TYPE'])
5240 case \CCatalogSku::TYPE_CATALOG:
5241 case \CCatalogSku::TYPE_OFFERS:
5242 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'OFFERS_TREE_PROPS'] = [];
5244 case \CCatalogSku::TYPE_PRODUCT:
5245 case \CCatalogSku::TYPE_FULL:
5246 $list = Catalog\Product\PropertyCatalogFeature::getOfferTreePropertyCodes(
5247 $this->storage[
'CATALOGS'][
$iblockId][
'IBLOCK_ID'],
5252 $this->storage[
'IBLOCK_PARAMS'][
$iblockId][
'OFFERS_TREE_PROPS'] = $list;
5271 $product[
'QUANTITY_TRACE'] ===
Catalog\ProductTable::STATUS_YES
5272 && $product[
'CAN_BUY_ZERO'] ===
Catalog\ProductTable::STATUS_NO
5324 $initFields =
array(
5325 'PRICES' =>
array(),
5326 'PRICE_MATRIX' =>
false,
5327 'MIN_PRICE' =>
false
5329 if (!$this->arParams[
'USE_PRICE_COUNT'] && !empty($this->storage[
'PRICES']))
5331 foreach ($this->storage[
'PRICES'] as $value)
5333 if (!$value[
'CAN_VIEW'] && !$value[
'CAN_BUY'])
5336 $priceType = $value[
'ID'];
5337 $initFields[
'CATALOG_GROUP_ID_'.$priceType] = $priceType;
5338 $initFields[
'~CATALOG_GROUP_ID_'.$priceType] = $priceType;
5339 $initFields[
'CATALOG_GROUP_NAME_'.$priceType] = $value[
'TITLE'];
5340 $initFields[
'~CATALOG_GROUP_NAME_'.$priceType] = $value[
'~TITLE'];
5341 $initFields[
'CATALOG_CAN_ACCESS_'.$priceType] = ($value[
'CAN_VIEW'] ?
'Y' :
'N');
5342 $initFields[
'~CATALOG_CAN_ACCESS_'.$priceType] = ($value[
'CAN_VIEW'] ?
'Y' :
'N');
5343 $initFields[
'CATALOG_CAN_BUY_'.$priceType] = ($value[
'CAN_BUY'] ?
'Y' :
'N');
5344 $initFields[
'~CATALOG_CAN_BUY_'.$priceType] = ($value[
'CAN_BUY'] ?
'Y' :
'N');
5345 $initFields[
'CATALOG_PRICE_ID_'.$priceType] =
null;
5346 $initFields[
'~CATALOG_PRICE_ID_'.$priceType] =
null;
5347 $initFields[
'CATALOG_PRICE_'.$priceType] =
null;
5348 $initFields[
'~CATALOG_PRICE_'.$priceType] =
null;
5349 $initFields[
'CATALOG_CURRENCY_'.$priceType] =
null;
5350 $initFields[
'~CATALOG_CURRENCY_'.$priceType] =
null;
5351 $initFields[
'CATALOG_QUANTITY_FROM_'.$priceType] =
null;
5352 $initFields[
'~CATALOG_QUANTITY_FROM_'.$priceType] =
null;
5353 $initFields[
'CATALOG_QUANTITY_TO_'.$priceType] =
null;
5354 $initFields[
'~CATALOG_QUANTITY_TO_'.$priceType] =
null;
5355 $initFields[
'CATALOG_EXTRA_ID_'.$priceType] =
null;
5356 $initFields[
'~CATALOG_EXTRA_ID_'.$priceType] =
null;
5362 foreach (array_keys(
$items) as $index)
5363 $this->oldData[
$items[$index][
'ID']] = $initFields;
5364 unset($index, $initFields);
5377 if (!isset($this->oldData[$id]) || empty(
$prices) || $this->arParams[
'USE_PRICE_COUNT'])
5379 foreach (
$prices as $rawPrice)
5381 $priceType = $rawPrice[
'CATALOG_GROUP_ID'];
5382 $this->oldData[$id][
'CATALOG_PRICE_ID_'.$priceType] = $rawPrice[
'ID'];
5383 $this->oldData[$id][
'~CATALOG_PRICE_ID_'.$priceType] = $rawPrice[
'ID'];
5384 $this->oldData[$id][
'CATALOG_PRICE_'.$priceType] = $rawPrice[
'PRICE'];
5385 $this->oldData[$id][
'~CATALOG_PRICE_'.$priceType] = $rawPrice[
'PRICE'];
5386 $this->oldData[$id][
'CATALOG_CURRENCY_'.$priceType] = $rawPrice[
'CURRENCY'];
5387 $this->oldData[$id][
'~CATALOG_CURRENCY_'.$priceType] = $rawPrice[
'CURRENCY'];
5388 $this->oldData[$id][
'CATALOG_QUANTITY_FROM_'.$priceType] = $rawPrice[
'QUANTITY_FROM'];
5389 $this->oldData[$id][
'~CATALOG_QUANTITY_FROM_'.$priceType] = $rawPrice[
'QUANTITY_FROM'];
5390 $this->oldData[$id][
'CATALOG_QUANTITY_TO_'.$priceType] = $rawPrice[
'QUANTITY_TO'];
5391 $this->oldData[$id][
'~CATALOG_QUANTITY_TO_'.$priceType] = $rawPrice[
'QUANTITY_TO'];
5392 $this->oldData[$id][
'CATALOG_EXTRA_ID_'.$priceType] = $rawPrice[
'EXTRA_ID'];
5393 $this->oldData[$id][
'~CATALOG_EXTRA_ID_'.$priceType] = $rawPrice[
'EXTRA_ID'];
5409 if (!isset($this->oldData[$id]))
5411 return ($this->oldData[$id][$field] ??
null);
5424 ($row[
'QUANTITY_FROM'] ===
null || $row[
'QUANTITY_FROM'] <= $this->arParams[
'SHOW_PRICE_COUNT'])
5425 && ($row[
'QUANTITY_TO'] ===
null || $row[
'QUANTITY_TO'] >= $this->arParams[
'SHOW_PRICE_COUNT'])
5439 'MATRIX' =>
array(),
5440 'CAN_BUY' =>
array(),
5442 'CURRENCY_LIST' =>
array()
5453 private function resortOldPrices($id)
5455 if (empty($this->oldData[$id][
'PRICES']) ||
count($this->oldData[$id][
'PRICES']) < 2)
5457 foreach (array_keys($this->oldData[$id][
'PRICES']) as $priceCode)
5458 $this->oldData[$id][
'PRICES'][$priceCode][
'_SORT'] = $this->storage[
'PRICES'][$priceCode][
'SORT'];
5461 $this->oldData[$id][
'PRICES'],
5462 array(
'_SORT' => SORT_ASC,
'PRICE_ID' => SORT_ASC),
5465 foreach (array_keys($this->oldData[$id][
'PRICES']) as $priceCode)
5466 unset($this->oldData[$id][
'PRICES'][$priceCode][
'_SORT']);
5478 'TYPE' =>
'CATALOG_TYPE',
5479 'AVAILABLE' =>
'CATALOG_AVAILABLE',
5480 'BUNDLE' =>
'CATALOG_BUNDLE',
5481 'QUANTITY' =>
'CATALOG_QUANTITY',
5482 'QUANTITY_TRACE' =>
'CATALOG_QUANTITY_TRACE',
5483 'CAN_BUY_ZERO' =>
'CATALOG_CAN_BUY_ZERO',
5484 'MEASURE' =>
'CATALOG_MEASURE',
5485 'SUBSCRIBE' =>
'CATALOG_SUBSCRIBE',
5486 'VAT_ID' =>
'CATALOG_VAT_ID',
5487 'VAT_INCLUDED' =>
'CATALOG_VAT_INCLUDED',
5488 'WEIGHT' =>
'CATALOG_WEIGHT',
5489 'WIDTH' =>
'CATALOG_WIDTH',
5490 'LENGTH' =>
'CATALOG_LENGTH',
5491 'HEIGHT' =>
'CATALOG_HEIGHT',
5492 'PAYMENT_TYPE' =>
'CATALOG_PRICE_TYPE',
5493 'RECUR_SCHEME_LENGTH' =>
'CATALOG_RECUR_SCHEME_LENGTH',
5494 'RECUR_SCHEME_TYPE' =>
'CATALOG_RECUR_SCHEME_TYPE',
5495 'QUANTITY_TRACE_RAW' =>
'CATALOG_QUANTITY_TRACE_ORIG',
5496 'CAN_BUY_ZERO_RAW' =>
'CATALOG_CAN_BUY_ZERO_ORIG',
5497 'SUBSCRIBE_RAW' =>
'CATALOG_SUBSCRIBE_ORIG',
5498 'PURCHASING_PRICE' =>
'CATALOG_PURCHASING_PRICE',
5499 'PURCHASING_CURRENCY' =>
'CATALOG_PURCHASING_CURRENCY',
5500 'BARCODE_MULTI' =>
'CATALOG_BARCODE_MULTI',
5501 'TRIAL_PRICE_ID' =>
'CATALOG_TRIAL_PRICE_ID',
5502 'WITHOUT_ORDER' =>
'CATALOG_WITHOUT_ORDER',
5503 '~TYPE' =>
'~CATALOG_TYPE',
5504 '~AVAILABLE' =>
'~CATALOG_AVAILABLE',
5505 '~BUNDLE' =>
'~CATALOG_BUNDLE',
5506 '~QUANTITY' =>
'~CATALOG_QUANTITY',
5507 '~QUANTITY_TRACE' =>
'~CATALOG_QUANTITY_TRACE',
5508 '~CAN_BUY_ZERO' =>
'~CATALOG_CAN_BUY_ZERO',
5509 '~MEASURE' =>
'~CATALOG_MEASURE',
5510 '~SUBSCRIBE' =>
'~CATALOG_SUBSCRIBE',
5511 '~VAT_ID' =>
'~CATALOG_VAT_ID',
5512 '~VAT_INCLUDED' =>
'~CATALOG_VAT_INCLUDED',
5513 '~WEIGHT' =>
'~CATALOG_WEIGHT',
5514 '~WIDTH' =>
'~CATALOG_WIDTH',
5515 '~LENGTH' =>
'~CATALOG_LENGTH',
5516 '~HEIGHT' =>
'~CATALOG_HEIGHT',
5517 '~PAYMENT_TYPE' =>
'~CATALOG_PRICE_TYPE',
5518 '~RECUR_SCHEME_LENGTH' =>
'~CATALOG_RECUR_SCHEME_LENGTH',
5519 '~RECUR_SCHEME_TYPE' =>
'~CATALOG_RECUR_SCHEME_TYPE',
5520 '~QUANTITY_TRACE_RAW' =>
'~CATALOG_QUANTITY_TRACE_ORIG',
5521 '~CAN_BUY_ZERO_RAW' =>
'~CATALOG_CAN_BUY_ZERO_ORIG',
5522 '~SUBSCRIBE_RAW' =>
'~CATALOG_SUBSCRIBE_ORIG',
5523 '~PURCHASING_PRICE' =>
'~CATALOG_PURCHASING_PRICE',
5524 '~PURCHASING_CURRENCY' =>
'~CATALOG_PURCHASING_CURRENCY',
5525 '~BARCODE_MULTI' =>
'~CATALOG_BARCODE_MULTI',
5526 '~TRIAL_PRICE_ID' =>
'~CATALOG_TRIAL_PRICE_ID',
5527 '~WITHOUT_ORDER' =>
'~CATALOG_WITHOUT_ORDER'
const CATALOG_VALUE_EPSILON
SubscribeProduct($intProductID, $arRewriteFields=array(), $arProductParams=array())
if($strVal !='') $productFields
static preloadPriceData(array $productIds, array $catalogGroups)
static preloadProductDataToExtendOrder(array $productIds, array $userGroups)
static setProductPropertiesCache($productId, $props)
static getParentSection($sectionId, $depth)
const PRICE_MODE_QUANTITY
static isCurrencyExist($currency)
getRandomRecommendation($ids)
getProductInfo($productId)
parseConditionLevel($condition, $params)
searchItemSelectedQuantityRangeHash($id)
static checkEnlargedData(&$item, $propertyCode)
checkProductSection($productId, $sectionId=0, $sectionCode='')
getProductIdMap($productIds)
getMeasureIds(array $items)
getIblockElements($elementIterator)
applyTemplateModifications()
onPrepareComponentParams($params)
parsePropertyCondition(array &$result, array $condition, $params)
getProductFields($iblockId)
searchItemSelectedRatioId($id)
__construct($component=null)
getOffersIblockId($iblockId)
modifyElementPrices(&$element)
isNeedCheckQuantity(array $product)
sliceItemsForSlider(&$items)
getRewriteFields($action)
getIblockOffers($iblockId)
const ACTION_ADD_TO_COMPARE
editTemplateCatalogInfo(&$item)
const ACTION_DELETE_FROM_COMPARE
getIblockSelectFields($iblockId)
calculateItemPrices(array &$items)
getBestSellersProductIds()
getElementList($iblockId, $products)
getBestSellersRecommendation($ids)
filterByParams($ids, $filterIds=array(), $useSectionFilter=true)
initCatalogDiscountCache()
getProductSelect($iblockId, array $selectFields)
getSectionIdByCode($sectionCode='', int $iblockId=0)
convertOrder(array $order)
getTemplateEmptyPreview()
addProductToBasket($productId, $action)
getProductsSeparatedByIblock()
isMergeProductWhenAddedBasket()
setCompatibleMode($state)
parseConditionName(array $condition)
getSeparateList(array $params)
getBigDataServiceRequestParams($type='')
loadMeasureRatios(array $itemIds)
getCompatibleFieldValue($id, $field)
processElement(array &$element)
filterIdBySection($elementIds, $iblockId, $sectionId, $limit, $depth=0)
parseCondition($condition, $params)
checkProductIblock(array $product)
getTemplateDefaultParams()
parseConditionOperator($condition)
static getSettingsScript($componentPath, $settingsName)
parseConditionValue($condition, $name)
getRecommendationLimit($ids)
getTemplatePropCell($code, $offer, &$matrixFields, $skuPropList)
loadOfferTreePropertyCodes($iblockId)
getSectionIdByElement($elementId, $elementCode='', int $iblockId=0)
prepareQueryFields(array $select, array $filter, array $order)
chooseOffer($offers, $iblockId)
const ACTION_ADD_TO_BASKET
modifyElementCommonData(array &$element)
getQuantityRangeHash(array $range)
getOffersFilter($iblockId)
clearCatalogDiscountCache()
initIblockPropertyFeatures()
prepareElementQueryFields()
convertFilter(array $filter)
loadBasketPropertyCodes($iblockId)
setSeparateLoading($state)
setElementPanelButtons(&$element)
fillCompatibleRawPriceFields($id, array $prices)
static getProductsMap(array $originalIds=array())
convertSelect(array $select)
initItemsMeasure(array &$items)
getCompatibleProductFields()
$recommendationIdToProduct
checkQuantityRange(array $row)
getFullIterator(array $params)
getPropertyList($iblock, $propertyCodes)
initCompatibleFields(array $items)
loadMeasures(array $measureIds)
editTemplateProductSlider(&$item, $iblock, $limit=0, $addDetailToSlider=true, $default=array())
loadDisplayPropertyCodes($iblockId)
modifyDisplayProperties($iblock, &$iblockElements)
loadPrices(array $itemIds)
offerIblockExist($iblockId)
editTemplateOfferSlider(&$item, $iblock, $limit=0, $addDetailToSlider=true, $default=array())
getMostViewedRecommendation($ids)
transferItems(array &$items)
static sendJsonAnswer(array $result=[])
static getProductIdsByOfferIds($offerIds)
static get($moduleId, $name, $default="", $siteId=false)
static set($moduleId, $name, $value="", $siteId="")
static getSystemParameters()
static includeModule($moduleName)
static getList(array $parameters=array())
static encode($string, $flags=ENT_COMPAT, $doubleEncode=true)
static normalizeArrayValuesByInt(&$map, $sorted=true)
static sortByColumn(array &$array, $columns, $callbacks='', $defaultValueIfNotSetValue=null, $preserveKeys=false)
static encode($data, $options=null)
static SetDiscountProductCache($arItem, $arParams=array())
static SetProductSectionsCache($arItemIDs)
static ClearDiscountCache($arTypes)
static ConvertCurrency($valSum, $curFrom, $curTo, $valDate="")
initComponentTemplate($templatePage="", $siteTemplate=false, $customTemplatePath="")
startResultCache($cacheTime=false, $additionalCacheID=false, $cachePath=false)
includeComponentTemplate($templatePage="", $customTemplatePath="")
setResultCacheKeys($arResultCacheKeys)
static getList($arOrder=array(), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
static Init($arExt=array(), $bReturn=false)
static modifyFilterFromOrder(array $filter, array $order, array $options)
static GetBestSellerList($by="AMOUNT", $arFilter=Array(), $arOrderFilter=Array(), $limit=0)
if( $strWarning=="") if($strWarning=="") $componentPath
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(! $catalogEdit->isSuccess()) $iblock
if(! $useStoreControl) $measureIterator
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
foreach(['Bitrix\\Main'=> '/lib', 'Psr\\Container'=> '/vendor/psr/container/src', 'Psr\\Log'=> '/vendor/psr/log/src', 'Psr\\Http\\Message'=> '/vendor/psr/http-message/src', 'Psr\\Http\\Client'=> '/vendor/psr/http-client/src', 'Http\\Promise'=> '/vendor/php-http/promise/src', 'PHPMailer\\PHPMailer'=> '/vendor/phpmailer/phpmailer/src', 'GeoIp2'=> '/vendor/geoip2/geoip2/src', 'MaxMind\\Db'=> '/vendor/maxmind-db/reader/src/MaxMind/Db', 'PhpParser'=> '/vendor/nikic/php-parser/lib/PhpParser', 'Recurr'=> '/vendor/simshaun/recurr/src/Recurr',] as $namespace=> $namespacePath) $documentRoot
if(file_exists($_SERVER['DOCUMENT_ROOT'] . "/urlrewrite.php")) $uri
ShowError($strError, $cls="errortext")
AddToTimeStamp($arrAdd, $stmp=false)
LocalRedirect($url, $skip_security_check=false, $status="302 Found")
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</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."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
if($params["BILLBY_ORDER_SUBJECT"]) if( $params["PAYMENT_DATE_PAY_BEFORE"]) if($params['BILLBY_PAYER_SHOW']=='Y') $currencyFormat