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)
132 $code = $error->getCode();
134 if ($code == self::ERROR_404)
137 trim($this->arParams[
'MESSAGE_404']) ?: $error->getMessage(),
139 $this->arParams[
'SET_STATUS_404'] ===
'Y',
140 $this->arParams[
'SHOW_404'] ===
'Y',
141 $this->arParams[
'FILE_404']
144 elseif ($code == self::ERROR_TEXT)
146 ShowError($error->getMessage());
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')
251 if (Loader::includeModule(
'catalog'))
253 \CJSCore::Init([
'core_condtree']);
256 $path = $componentPath.
'/settings/'.$settingsName.
'/script.js';
259 return $path.
'?'.$file->getModificationTime();
270 if (!is_array($params))
275 if (!isset($params[
'CURRENT_BASE_PAGE']))
277 $uri =
new Main\Web\Uri($this->request->getRequestUri());
279 $params[
'CURRENT_BASE_PAGE'] = $uri->getUri();
283 if (!isset($params[
'PARENT_NAME']) && $parent = $this->getParent())
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']))
295 $this->setSiteId($params[
'CUSTOM_SITE_ID']);
299 if (isset($params[
'AJAX_MODE']) && $params[
'AJAX_MODE'] ===
'Y')
301 $ajaxId = $this->request->get(
'AJAX_ID');
304 $params[
'AJAX_ID'] = $ajaxId;
308 $params[
'AJAX_ID'] = trim((
string)($params[
'AJAX_ID'] ??
''));
310 $params[
'CACHE_TIME'] = (int)($params[
'CACHE_TIME'] ?? 36000000);
312 $params[
'IBLOCK_ID'] = (int)($params[
'IBLOCK_ID'] ?? 0);
313 $params[
'SECTION_ID'] = (int)($params[
'SECTION_ID'] ?? 0);
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'])
356 $params[
'ACTION_COMPARE_VARIABLE'] = $params[
'ACTION_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')
383 $params[
'SET_TITLE'] = $params[
'ALLOW_SEO_DATA'] ===
'Y';
384 $params[
'SET_BROWSER_TITLE'] = $params[
'ALLOW_SEO_DATA'];
385 $params[
'SET_META_KEYWORDS'] = $params[
'ALLOW_SEO_DATA'];
386 $params[
'SET_META_DESCRIPTION'] = $params[
'ALLOW_SEO_DATA'];
390 $params[
'SET_TITLE'] = ($params[
'SET_TITLE'] ??
'') !==
'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')
422 $params[
'PRODUCT_PROPERTIES'] = array();
423 $params[
'OFFERS_CART_PROPERTIES'] = array();
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';
461 $params[
'CURRENCY_ID'] ??=
'';
462 if (!is_scalar($params[
'CURRENCY_ID']))
464 $params[
'CURRENCY_ID'] =
'';
466 $params[
'CURRENCY_ID'] = trim((
string)$params[
'CURRENCY_ID']);
467 if ($params[
'CURRENCY_ID'] ===
'' || $params[
'CONVERT_CURRENCY'] ===
'N')
469 $params[
'CONVERT_CURRENCY'] =
'N';
470 $params[
'CURRENCY_ID'] =
'';
473 $params[
'OFFERS_LIMIT'] = (int)($params[
'OFFERS_LIMIT'] ?? 0);
474 if ($params[
'OFFERS_LIMIT'] < 0)
476 $params[
'OFFERS_LIMIT'] = 0;
479 $params[
'CACHE_GROUPS'] = trim((
string)($params[
'CACHE_GROUPS'] ??
''));
480 if ($params[
'CACHE_GROUPS'] !==
'N')
482 $params[
'CACHE_GROUPS'] =
'Y';
485 if (isset($params[
'~PRICE_CODE']))
487 $params[
'PRICE_CODE'] = $params[
'~PRICE_CODE'];
489 $params[
'PRICE_CODE'] ??= [];
490 if (!is_array($params[
'PRICE_CODE']))
492 $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'] ??
''));
500 $params[
'DEPTH'] = (int)($params[
'DEPTH'] ?? 0);
502 if (empty($params[
'SECTION_ID']))
504 if ($params[
'SECTION_CODE'] !==
'')
506 $sectionId = $this->
getSectionIdByCode($params[
'SECTION_CODE'], $params[
'IBLOCK_ID']);
511 $params[
'SECTION_ELEMENT_ID'],
512 $params[
'SECTION_ELEMENT_CODE'],
517 $params[
'SECTION_ID'] = $sectionId;
521 $params[
'FILTER_IDS'] ??= [];
522 if (!is_array($params[
'FILTER_IDS']))
524 $params[
'FILTER_IDS'] = [$params[
'FILTER_IDS']];
537 $this->useCatalog = Loader::includeModule(
'catalog');
538 $this->storage[
'MODULES'] = array(
540 'catalog' => $this->useCatalog,
541 'currency' => $this->useCatalog
554 if ($this->useCatalog && $this->useDiscountCache && !empty($this->elementLinks))
556 foreach ($this->iblockProducts as $iblock => $products)
558 if ($this->storage[
'USE_SALE_DISCOUNTS'])
560 Catalog\Discount\DiscountManager::preloadPriceData($products, $this->storage[
'PRICES_ALLOW']);
561 Catalog\Discount\DiscountManager::preloadProductDataToExtendOrder($products, $this->
getUserGroups());
565 \CCatalogDiscount::SetProductSectionsCache($products);
566 \CCatalogDiscount::SetDiscountProductCache($products, array(
'IBLOCK_ID' => $iblock,
'GET_BY_ID' =>
'Y'));
579 if ($this->useCatalog && $this->useDiscountCache)
581 \CCatalogDiscount::ClearDiscountCache(array(
596 $this->storage[
'CONVERT_CURRENCY'] = array();
598 if ($this->arParams[
'CONVERT_CURRENCY'] ===
'Y')
601 if (Loader::includeModule(
'currency'))
603 $this->storage[
'MODULES'][
'currency'] =
true;
604 $correct = Currency\CurrencyManager::isCurrencyExist($this->arParams[
'CURRENCY_ID']);
608 $this->storage[
'CONVERT_CURRENCY'] = array(
609 'CURRENCY_ID' => $this->arParams[
'CURRENCY_ID']
614 $this->arParams[
'CONVERT_CURRENCY'] =
'N';
615 $this->arParams[
'CURRENCY_ID'] =
'';
629 if (empty($this->storage[
'CATALOGS'][$iblockId]))
632 $catalog = $this->storage[
'CATALOGS'][$iblockId];
634 if (empty($catalog[
'CATALOG_TYPE']))
637 return $catalog[
'CATALOG_TYPE'] == \CCatalogSku::TYPE_FULL || $catalog[
'CATALOG_TYPE'] == \CCatalogSku::TYPE_PRODUCT;
649 if ($this->useCatalog)
651 $this->storage[
'SHOW_CATALOG_WITH_OFFERS'] = Main\Config\Option::get(
'catalog',
'show_catalog_tab_with_offers') ===
'Y';
652 $this->storage[
'USE_SALE_DISCOUNTS'] = Main\Config\Option::get(
'sale',
'use_sale_discount_only') ===
'Y';
653 foreach (array_keys($this->iblockProducts) as $iblockId)
655 $catalog = \CCatalogSku::GetInfoByIBlock($iblockId);
656 if (!empty($catalog) && is_array($catalog))
658 $this->isIblockCatalog = $this->isIblockCatalog || $catalog[
'CATALOG_TYPE'] != \CCatalogSku::TYPE_PRODUCT;
659 $catalogs[$iblockId] = $catalog;
664 $this->storage[
'CATALOGS'] = $catalogs;
669 if (!$this->useCatalog)
672 $productId = (int)$productId;
676 $iblockId = (int)\CIBlockElement::GetIBlockByID($productId);
680 $iterator = Catalog\ProductTable::getList([
681 'select' => [
'ID',
'TYPE'],
682 'filter' => [
'=ID' => $productId]
684 $row = $iterator->fetch();
689 $row[
'ID'] = (int)$row[
'ID'];
690 $row[
'TYPE'] = (int)$row[
'TYPE'];
697 $row[
'ELEMENT_IBLOCK_ID'] = $iblockId;
698 $row[
'PRODUCT_IBLOCK_ID'] = 0;
700 if (isset($this->storage[
'CATALOGS'][$iblockId]))
702 if ($this->storage[
'CATALOGS'][$iblockId][
'CATALOG_TYPE'] == \CCatalogSku::TYPE_CATALOG)
703 $row[
'PRODUCT_IBLOCK_ID'] = $this->storage[
'CATALOGS'][$iblockId][
'IBLOCK_ID'];
705 $row[
'PRODUCT_IBLOCK_ID'] = $this->storage[
'CATALOGS'][$iblockId][
'PRODUCT_IBLOCK_ID'];
709 $catalog = \CCatalogSku::GetInfoByIBlock($iblockId);
710 if (empty($catalog) || !is_array($catalog))
713 if ($catalog[
'CATALOG_TYPE'] == \CCatalogSku::TYPE_PRODUCT)
716 if ($catalog[
'CATALOG_TYPE'] == \CCatalogSku::TYPE_OFFERS)
718 $iblockId = $catalog[
'PRODUCT_IBLOCK_ID'];
719 $catalog = \CCatalogSku::GetInfoByIBlock($iblockId);
721 if (!isset($this->storage[
'CATALOGS']))
722 $this->storage[
'CATALOGS'] = [];
723 $this->storage[
'CATALOGS'][$iblockId] = $catalog;
726 if ($this->storage[
'CATALOGS'][$iblockId][
'CATALOG_TYPE'] == \CCatalogSku::TYPE_CATALOG)
727 $row[
'PRODUCT_IBLOCK_ID'] = $this->storage[
'CATALOGS'][$iblockId][
'IBLOCK_ID'];
729 $row[
'PRODUCT_IBLOCK_ID'] = $this->storage[
'CATALOGS'][$iblockId][
'PRODUCT_IBLOCK_ID'];
742 $this->storage[
'PRICES'] = \CIBlockPriceTools::GetCatalogPrices(
743 isset($this->arParams[
'IBLOCK_ID']) && $this->arParams[
'IBLOCK_ID'] > 0 ? $this->arParams[
'IBLOCK_ID'] :
false,
744 $this->arParams[
'PRICE_CODE']
746 $this->storage[
'PRICES_ALLOW'] = \CIBlockPriceTools::GetAllowCatalogPrices($this->storage[
'PRICES']);
747 $this->storage[
'PRICES_CAN_BUY'] = array();
748 $this->storage[
'PRICES_MAP'] = array();
749 foreach ($this->storage[
'PRICES'] as $priceType)
751 $this->storage[
'PRICES_MAP'][$priceType[
'ID']] = $priceType[
'CODE'];
752 if ($priceType[
'CAN_BUY'])
753 $this->storage[
'PRICES_CAN_BUY'][$priceType[
'ID']] = $priceType[
'ID'];
756 $this->storage[
'PRICE_TYPES'] = array();
757 if ($this->useCatalog)
758 $this->storage[
'PRICE_TYPES'] = \CCatalogGroup::GetListArray();
760 $this->useDiscountCache =
false;
761 if ($this->useCatalog)
763 if (!empty($this->storage[
'CATALOGS']) && !empty($this->storage[
'PRICES_ALLOW']))
764 $this->useDiscountCache =
true;
767 if ($this->useCatalog && $this->useDiscountCache)
769 $this->useDiscountCache = \CIBlockPriceTools::SetCatalogDiscountCache(
770 $this->storage[
'PRICES_ALLOW'],
775 if ($this->useCatalog)
776 Catalog\Product\Price::loadRoundRules($this->storage[
'PRICES_ALLOW']);
786 $this->storage[
'VATS'] = [];
787 $this->storage[
'IBLOCKS_VAT'] = [];
788 if ($this->useCatalog)
790 $iterator = Catalog\VatTable::getList([
791 'select' => [
'ID',
'RATE'],
792 'order' => [
'ID' =>
'ASC']
794 while ($row = $iterator->fetch())
795 $this->storage[
'VATS'][(int)$row[
'ID']] = (
float)$row[
'RATE'];
796 unset($row, $iterator);
798 if (!empty($this->storage[
'CATALOGS']))
800 foreach ($this->storage[
'CATALOGS'] as $catalog)
802 $this->storage[
'IBLOCKS_VAT'][$catalog[
'IBLOCK_ID']] = 0;
803 if ($catalog[
'PRODUCT_IBLOCK_ID'] > 0)
804 $this->storage[
'IBLOCKS_VAT'][$catalog[
'PRODUCT_IBLOCK_ID']] = 0;
808 $iterator = Catalog\CatalogIblockTable::getList([
809 'select' => [
'IBLOCK_ID',
'VAT_ID'],
810 'filter' => [
'@IBLOCK_ID' => array_keys($this->storage[
'IBLOCKS_VAT'])]
812 while ($row = $iterator->fetch())
813 $this->storage[
'IBLOCKS_VAT'][(int)$row[
'IBLOCK_ID']] = (
int)$row[
'VAT_ID'];
814 unset($row, $iterator);
834 $this->storage[
'CURRENCY_LIST'] = array();
839 foreach ($this->iblockProducts as $iblock => $products)
844 if (!empty($iblockElements) && !$this->
hasErrors())
847 $this->elements = array_merge($this->elements, array_values($iblockElements));
848 $this->iblockProducts[$iblock] = array_keys($iblockElements);
851 unset($elementIterator, $iblockElements, $element);
870 if (!empty($this->productIdMap) && is_array($this->productIdMap))
872 $sortedElements = array();
874 foreach (array_keys($this->productIdMap) as $productId)
876 $parentId = $this->productIdMap[$productId];
878 foreach ($this->elements as $element)
880 if ($element[
'ID'] == $parentId)
882 $sortedElements[$productId] = $element;
888 $this->elements = array_values($sortedElements);
899 if (!empty($this->elements))
901 foreach ($this->elements as $index => $element)
903 $this->elementLinks[$element[
'ID']] =& $this->elements[$index];
925 $shownIds = $this->request->get(
'shownIds');
926 if (!empty($shownIds) && is_array($shownIds))
928 $this->arParams[
'FILTER_IDS'] += $shownIds;
931 $this->arParams[
'PAGE_ELEMENT_COUNT'] = $this->request->get(
'count') ?: 20;
932 $this->arParams[
'FILTER'] ??= [];
933 $this->arParams[
'FILTER'] = $this->arParams[
'FILTER'] ?: [
'PAYED'];
934 $this->arParams[
'BY'] ??=
'';
935 $this->arParams[
'BY'] = $this->arParams[
'BY'] ?:
'AMOUNT';
936 $this->arParams[
'PERIOD'] ??= 0;
937 $this->arParams[
'PERIOD'] = (int)$this->arParams[
'PERIOD'] ?: 30;
938 $this->arParams[
'DEPTH'] ??= 0;
939 $this->arParams[
'DEPTH'] = (int)$this->arParams[
'DEPTH'] ?: 2;
942 $this->filterFields = $this->
getFilter();
943 $this->filterFields[
'IBLOCK_ID'] = $this->arParams[
'IBLOCK_ID'];
947 $ids = $this->request->get(
'items') ?: array();
950 $recommendationId = $this->request->get(
'rid');
951 $ids = $this->
filterByParams($ids, $this->arParams[
'FILTER_IDS']);
953 foreach ($ids as $id)
955 $this->recommendationIdToProduct[$id] = $recommendationId;
960 if (Main\Loader::includeModule(
'sale') && count($ids) < $this->arParams[
'PAGE_ELEMENT_COUNT'])
966 if ($this->useCatalog && count($ids) < $this->arParams[
'PAGE_ELEMENT_COUNT'])
972 if (count($ids) < $this->arParams[
'PAGE_ELEMENT_COUNT'])
978 return array_slice($ids, 0, $this->arParams[
'PAGE_ELEMENT_COUNT']);
990 $this->arParams[
'PAGE_ELEMENT_COUNT'] = $this->arParams[
'PAGE_ELEMENT_COUNT'] * 10;
992 $this->arParams[
'PAGE_ELEMENT_COUNT'] = $this->arParams[
'PAGE_ELEMENT_COUNT'] / 10;
994 if (!empty($bestsellers))
996 $recommendationId =
'bestsellers';
997 $bestsellers = Main\Analytics\Catalog::getProductIdsByOfferIds($bestsellers);
998 $bestsellers = $this->
filterByParams($bestsellers, $this->arParams[
'FILTER_IDS']);
1000 foreach ($bestsellers as $id)
1002 if (!isset($this->recommendationIdToProduct[$id]))
1004 $this->recommendationIdToProduct[$id] = $recommendationId;
1008 $ids = array_unique(array_merge($ids, $bestsellers));
1022 $mostViewed = array();
1023 $recommendationId =
'mostviewed';
1025 $result = Catalog\CatalogViewedProductTable::getList(array(
1031 '=SITE_ID' => $this->getSiteId(),
1033 '>DATE_VISIT' =>
new Main\
Type\
DateTime(date(
'Y-m-d H:i:s', strtotime(
'-30 days')),
'Y-m-d H:i:s')
1035 'order' => array(
'SUM_HITS' =>
'DESC'),
1036 'limit' => $this->arParams[
'PAGE_ELEMENT_COUNT'] * 10
1038 while ($row = $result->fetch())
1040 $mostViewed[] = $row[
'ELEMENT_ID'];
1042 unset($row, $result);
1044 $mostViewed = $this->
filterByParams($mostViewed, $this->arParams[
'FILTER_IDS']);
1046 foreach ($mostViewed as $id)
1048 if (!isset($this->recommendationIdToProduct[$id]))
1050 $this->recommendationIdToProduct[$id] = $recommendationId;
1054 return array_unique(array_merge($ids, $mostViewed));
1072 $randomIds = array();
1073 $recommendationId =
'random';
1074 $filter = $this->filterFields;
1076 $filterIds = array_merge($ids, $this->arParams[
'FILTER_IDS']);
1077 if (!empty($filterIds))
1079 $filter[
'!ID'] = $filterIds;
1082 if ($this->arParams[
'SHOW_FROM_SECTION'] ===
'Y' && !empty($this->arParams[
'SECTION_ID']))
1084 $filter[
'SECTION_ID'] = $this->arParams[
'SECTION_ID'];
1087 $elementIterator = \CIBlockElement::GetList(array(
'RAND' =>
'ASC'), $filter,
false, array(
'nTopCount' => $limit), array(
'ID'));
1088 while ($element = $elementIterator->Fetch())
1090 $randomIds[] = $element[
'ID'];
1093 if (!empty($randomIds))
1098 foreach ($randomIds as $id)
1100 if (!isset($this->recommendationIdToProduct[$id]))
1102 $this->recommendationIdToProduct[$id] = $recommendationId;
1106 return array_merge($ids, $randomIds);
1117 protected function filterByParams($ids, $filterIds = array(), $useSectionFilter =
true)
1124 $ids = array_values(array_unique($ids));
1126 if (!empty($filterIds))
1128 $ids = array_diff($ids, $filterIds);
1133 $filter = $this->filterFields;
1134 $filter[
'ID'] = $ids;
1136 $correctIds = array();
1137 $elementIterator = \CIBlockElement::GetList(array(), $filter,
false,
false, array(
'ID'));
1138 while ($element = $elementIterator->Fetch())
1140 $correctIds[] = $element[
'ID'];
1143 if ($useSectionFilter && !empty($correctIds) && $this->arParams[
'SHOW_FROM_SECTION'] ===
'Y')
1147 $this->arParams[
'IBLOCK_ID'],
1148 $this->arParams[
'SECTION_ID'],
1149 $this->arParams[
'PAGE_ELEMENT_COUNT'],
1150 $this->arParams[
'DEPTH']
1154 $correctIds = array_flip($correctIds);
1156 foreach ($ids as $key => $id)
1158 if (!isset($correctIds[$id]))
1164 return array_values($ids);
1181 $sectionCode = (string)$sectionCode;
1183 if ($sectionCode ===
'')
1188 $sectionFilter = [];
1191 $sectionFilter[
'=IBLOCK_ID'] = $iblockId;
1193 elseif (!empty($this->arParams[
'IBLOCK_ID']))
1195 $sectionFilter[
'@IBLOCK_ID'] = $this->arParams[
'IBLOCK_ID'];
1197 if (empty($sectionFilter))
1202 $sectionFilter[
'=IBLOCK.ACTIVE'] =
'Y';
1203 $sectionFilter[
'=CODE'] = $sectionCode;
1205 $section = Iblock\SectionTable::getList(array(
1206 'select' => array(
'ID'),
1207 'filter' => $sectionFilter
1209 if (!empty($section))
1211 $sectionId = (int)$section[
'ID'];
1227 $elementId = (int)$elementId;
1228 $elementCode = (string)$elementCode;
1233 $filter[
'=IBLOCK_ID'] = $iblockId;
1235 elseif (!empty($this->arParams[
'IBLOCK_ID']))
1237 $filter[
'=IBLOCK_ID'] = $this->arParams[
'IBLOCK_ID'];
1246 $filter[
'=ID'] = $elementId;
1248 elseif ($elementCode !==
'')
1250 $filter[
'=CODE'] = $elementCode;
1257 $itemIterator = Iblock\ElementTable::getList(array(
1258 'select' => array(
'ID',
'IBLOCK_SECTION_ID'),
1261 if ($item = $itemIterator->fetch())
1263 $sectionId = (int)$item[
'IBLOCK_SECTION_ID'];
1273 Main\Type\Collection::normalizeArrayValuesByInt($elementIds);
1275 if (empty($elementIds))
1278 $iblockId = (int)$iblockId;
1279 $sectionId = (int)$sectionId;
1280 $limit = (int)$limit;
1281 $depth = (int)$depth;
1283 if ($iblockId <= 0 ||$depth < 0)
1286 $subSections = array();
1289 $parentSectionId = Catalog\Product\Viewed::getParentSection($sectionId, $depth);
1290 if ($parentSectionId !==
null)
1292 $subSections[$parentSectionId] = $parentSectionId;
1294 unset($parentSectionId);
1297 if (empty($subSections) && $sectionId <= 0)
1299 $getListParams = array(
1300 'select' => array(
'ID'),
1302 '@ID' => $elementIds,
1303 '=IBLOCK_ID' => $iblockId,
1304 '=WF_STATUS_ID' => 1,
1305 '=WF_PARENT_ELEMENT_ID' =>
null
1310 $getListParams[
'limit'] = $limit;
1313 $iterator = Iblock\ElementTable::getList($getListParams);
1317 if (empty($subSections))
1319 $subSections[$sectionId] = $sectionId;
1322 $sectionQuery =
new Main\Entity\Query(
Iblock\SectionTable::getEntity());
1323 $sectionQuery->setTableAliasPostfix(
'_parent');
1324 $sectionQuery->setSelect(array(
'ID',
'LEFT_MARGIN',
'RIGHT_MARGIN'));
1325 $sectionQuery->setFilter(array(
'@ID' => $subSections));
1327 $subSectionQuery =
new Main\Entity\Query(
Iblock\SectionTable::getEntity());
1328 $subSectionQuery->setTableAliasPostfix(
'_sub');
1329 $subSectionQuery->setSelect(array(
'ID'));
1330 $subSectionQuery->setFilter(array(
'=IBLOCK_ID' => $iblockId));
1331 $subSectionQuery->registerRuntimeField(
1333 new Main\
Entity\ReferenceField(
1335 Main\
Entity\Base::getInstanceByQuery($sectionQuery),
1336 array(
'>=this.LEFT_MARGIN' =>
'ref.LEFT_MARGIN',
'<=this.RIGHT_MARGIN' =>
'ref.RIGHT_MARGIN'),
1337 array(
'join_type' =>
'INNER')
1341 $sectionElementQuery =
new Main\Entity\Query(
Iblock\SectionElementTable::getEntity());
1342 $sectionElementQuery->setSelect(array(
'IBLOCK_ELEMENT_ID'));
1343 $sectionElementQuery->setGroup(array(
'IBLOCK_ELEMENT_ID'));
1344 $sectionElementQuery->setFilter(array(
'=ADDITIONAL_PROPERTY_ID' =>
null));
1345 $sectionElementQuery->registerRuntimeField(
1347 new Main\
Entity\ReferenceField(
1349 Main\
Entity\Base::getInstanceByQuery($subSectionQuery),
1350 array(
'=this.IBLOCK_SECTION_ID' =>
'ref.ID'),
1351 array(
'join_type' =>
'INNER')
1355 $elementQuery =
new Main\Entity\Query(
Iblock\ElementTable::getEntity());
1356 $elementQuery->setSelect(array(
'ID'));
1357 $elementQuery->setFilter(array(
'=IBLOCK_ID' => $iblockId,
'=WF_STATUS_ID' => 1,
'=WF_PARENT_ELEMENT_ID' =>
null));
1358 $elementQuery->registerRuntimeField(
1360 new Main\
Entity\ReferenceField(
1362 Main\
Entity\Base::getInstanceByQuery($sectionElementQuery),
1363 array(
'=this.ID' =>
'ref.IBLOCK_ELEMENT_ID'),
1364 array(
'join_type' =>
'INNER')
1369 $elementQuery->setLimit($limit);
1372 $iterator = $elementQuery->exec();
1374 unset($elementQuery, $sectionElementQuery, $subSectionQuery, $sectionQuery);
1377 while ($row = $iterator->fetch())
1379 $map[] = $row[
'ID'];
1381 unset($row, $iterator);
1396 $idsCount = count($ids);
1397 $rowsRange = $this->request->get(
'rowsRange');
1399 if (!empty($rowsRange))
1401 foreach ($rowsRange as $range)
1403 $range = (int)$range;
1405 if ($range > $idsCount)
1407 $limit = $range - $idsCount;
1414 $limit = $this->arParams[
'PAGE_ELEMENT_COUNT'] - $idsCount;
1423 'uid' => ($_COOKIE[
'BX_USER_ID'] ??
''),
1424 'aid' => Main\Analytics\Counter::getAccountId(),
1425 'count' => max($this->arParams[
'PAGE_ELEMENT_COUNT'] * 2, 30)
1429 if ($type ===
'any_similar')
1431 $possible = array(
'similar_sell',
'similar_view',
'similar');
1432 $type = $possible[array_rand($possible)];
1434 elseif ($type ===
'any_personal')
1436 $possible = array(
'bestsell',
'personal');
1437 $type = $possible[array_rand($possible)];
1439 elseif ($type ===
'any')
1441 $possible = array(
'similar_sell',
'similar_view',
'similar',
'bestsell',
'personal');
1442 $type = $possible[array_rand($possible)];
1449 $params[
'op'] =
'sim_domain_items';
1450 $params[
'type'] =
'order';
1451 $params[
'domain'] = Main\Context::getCurrent()->getServer()->getHttpHost();
1454 $params[
'op'] =
'recommend';
1456 case 'similar_sell':
1457 $params[
'op'] =
'simitems';
1458 $params[
'eid'] = $this->arParams[
'RCM_PROD_ID'];
1459 $params[
'type'] =
'order';
1461 case 'similar_view':
1462 $params[
'op'] =
'simitems';
1463 $params[
'eid'] = $this->arParams[
'RCM_PROD_ID'];
1464 $params[
'type'] =
'view';
1467 $params[
'op'] =
'simitems';
1468 $params[
'eid'] = $this->arParams[
'RCM_PROD_ID'];
1471 $params[
'op'] =
'recommend';
1476 if (!empty($this->storage[
'IBLOCK_PARAMS']))
1478 $iblocks = array_keys($this->storage[
'IBLOCK_PARAMS']);
1482 $iblockList = array();
1484 $iblockIterator = Catalog\CatalogIblockTable::getList(array(
1485 'select' => array(
'IBLOCK_ID',
'PRODUCT_IBLOCK_ID')
1487 while ($iblock = $iblockIterator->fetch())
1489 $iblock[
'IBLOCK_ID'] = (int)$iblock[
'IBLOCK_ID'];
1490 $iblock[
'PRODUCT_IBLOCK_ID'] = (int)$iblock[
'PRODUCT_IBLOCK_ID'];
1491 $iblockList[$iblock[
'IBLOCK_ID']] = $iblock[
'IBLOCK_ID'];
1493 if ($iblock[
'PRODUCT_IBLOCK_ID'] > 0)
1495 $iblockList[$iblock[
'PRODUCT_IBLOCK_ID']] = $iblock[
'PRODUCT_IBLOCK_ID'];
1500 $iblockIterator = Iblock\IblockSiteTable::getList(array(
1501 'select' => array(
'IBLOCK_ID'),
1502 'filter' => array(
'@IBLOCK_ID' => $iblockList,
'=SITE_ID' => $this->getSiteId())
1504 while ($iblock = $iblockIterator->fetch())
1506 $iblocks[] = $iblock[
'IBLOCK_ID'];
1510 $params[
'ib'] = join(
'.', $iblocks);
1525 if (!empty($filter))
1527 $productIterator = \CSaleProduct::GetBestSellerList(
1528 $this->arParams[
'BY'],
1531 $this->arParams[
'PAGE_ELEMENT_COUNT']
1533 while($product = $productIterator->fetch())
1546 if (!empty($this->arParams[
'FILTER']))
1548 $filter = array(
'=LID' => $this->getSiteId());
1549 $subFilter = array(
'LOGIC' =>
'OR');
1553 'ALLOW_DELIVERY' =>
true,
1558 if ($this->arParams[
'PERIOD'] > 0)
1560 $date = ConvertTimeStamp(AddToTimeStamp(array(
'DD' =>
'-'.$this->arParams[
'PERIOD'])));
1563 foreach ($this->arParams[
'FILTER'] as $field)
1565 if (isset($statuses[$field]))
1567 $subFilter[] = array(
1568 '>=DATE_'.$field => $date,
1574 if (empty($this->storage[
'ORDER_STATUS']) || in_array($field, $this->storage[
'ORDER_STATUS']))
1576 $subFilter[] = array(
1577 '=STATUS_ID' => $field,
1578 '>=DATE_UPDATE' => $date,
1588 foreach ($this->arParams[
'FILTER'] as $field)
1590 if (isset($statuses[$field]))
1592 $subFilter[] = array(
1598 if (empty($this->storage[
'ORDER_STATUS']) || in_array($field, $this->storage[
'ORDER_STATUS']))
1600 $subFilter[] = array(
1601 '=STATUS_ID' => $field,
1609 $filter[] = $subFilter;
1643 if (empty($originalIds))
1649 $productList = \CCatalogSku::getProductList($originalIds);
1650 if ($productList ===
false)
1652 $productList = array();
1655 foreach ($originalIds as $id)
1657 $result[$id] = isset($productList[$id]) ? $productList[$id][
'ID'] : (int)$id;
1675 $iblockItems = array();
1677 if (!empty($this->productIdMap) && is_array($this->productIdMap))
1679 $itemsIterator = Iblock\ElementTable::getList(array(
1680 'select' => array(
'ID',
'IBLOCK_ID'),
1681 'filter' => array(
'@ID' => $this->productIdMap)
1683 while ($item = $itemsIterator->fetch())
1685 $item[
'ID'] = (int)$item[
'ID'];
1686 $item[
'IBLOCK_ID'] = (int)$item[
'IBLOCK_ID'];
1688 if (!isset($iblockItems[$item[
'IBLOCK_ID']]))
1690 $iblockItems[$item[
'IBLOCK_ID']] = array();
1693 $iblockItems[$item[
'IBLOCK_ID']][] = $item[
'ID'];
1695 unset($item, $itemsIterator);
1697 elseif ($this->productIdMap ===
false)
1699 $iblockItems[$this->arParams[
'IBLOCK_ID']] = $this->arParams[
'ELEMENT_ID'] ?? 0;
1702 return $iblockItems;
1712 $defaultMeasure = array();
1714 if ($this->useCatalog)
1716 $defaultMeasure = \CCatalogMeasure::getDefaultMeasure(
true,
true);
1719 return $defaultMeasure;
1738 if (!empty($products))
1744 if (!empty($this->globalFilter))
1750 'order' => $this->sortFields,
1751 'navigation' => $this->navParams
1761 unset($iteratorParams);
1763 $elementIterator->SetUrlTemplates($this->arParams[
'DETAIL_URL']);
1765 return $elementIterator;
1777 if (!empty($params[
'order']))
1781 array_keys($params[
'order'])
1785 $iterator = \CIBlockElement::GetList(
1789 $params[
'navigation'],
1792 while ($row = $iterator->Fetch())
1794 $id = (int)$row[
'ID'];
1797 'IBLOCK_ID' => $row[
'IBLOCK_ID'],
1804 $fullIterator = \CIBlockElement::GetList(
1806 [
'IBLOCK_ID' => $params[
'filter'][
'IBLOCK_ID'],
'ID' => array_keys($list),
'SITE_ID' => $this->getSiteId()],
1811 while ($row = $fullIterator->Fetch())
1813 $id = (int)$row[
'ID'];
1814 $list[$id] = $list[$id] + $row;
1816 unset($row, $fullIterator);
1818 $iterator->InitFromArray(array_values($list));
1830 return \CIBlockElement::GetList(
1834 $params[
'navigation'],
1846 $this->selectFields = $this->
getSelect();
1847 $this->filterFields = $this->
getFilter();
1848 $this->sortFields = $this->
getSort();
1860 'ID',
'IBLOCK_ID',
'CODE',
'XML_ID',
'NAME',
'ACTIVE',
'DATE_ACTIVE_FROM',
'DATE_ACTIVE_TO',
'SORT',
1861 'PREVIEW_TEXT',
'PREVIEW_TEXT_TYPE',
'DETAIL_TEXT',
'DETAIL_TEXT_TYPE',
'DATE_CREATE',
'CREATED_BY',
'TAGS',
1862 'TIMESTAMP_X',
'MODIFIED_BY',
'IBLOCK_SECTION_ID',
'DETAIL_PAGE_URL',
'DETAIL_PICTURE',
'PREVIEW_PICTURE'
1865 $checkPriceProperties = (
1868 isset($this->arParams[
'IBLOCK_ID'])
1869 && $this->arParams[
'IBLOCK_ID'] > 0
1870 && !isset($this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']])
1874 if ($checkPriceProperties && !empty($this->storage[
'PRICES']))
1876 foreach ($this->storage[
'PRICES'] as $row)
1878 if (!empty($row[
'SELECT']))
1879 $result[] = $row[
'SELECT'];
1894 'IBLOCK_LID' => $this->getSiteId(),
1895 'ACTIVE_DATE' =>
'Y',
1896 'CHECK_PERMISSIONS' =>
'Y',
1897 'MIN_PERMISSION' =>
'R'
1918 $result = $this->
prepareQueryFields($this->selectFields, $this->filterFields, $this->sortFields);
1919 $this->selectFields = $result[
'SELECT'];
1920 $this->filterFields = $result[
'FILTER'];
1921 $this->sortFields = $result[
'ORDER'];
1922 if (!empty($this->globalFilter))
1925 $this->globalFilter = $result[
'FILTER'];
1940 if ($this->useCatalog)
1945 $filter = \CProductQueryBuilder::modifyFilterFromOrder(
1948 [
'QUANTITY' => $this->arParams[
'SHOW_PRICE_COUNT']]
1952 if (!empty($select))
1954 $select = array_unique($select);
1958 'SELECT' => $select,
1959 'FILTER' => $filter,
1982 if (!$this->useCatalog)
1983 return $selectFields;
1986 $result = $selectFields;
1988 if (!empty($additionalFields))
1990 $result = array_merge($result, $additionalFields);
1991 $result = array_unique($result);
1993 unset($additionalFields);
2010 'TYPE',
'AVAILABLE',
'BUNDLE',
2011 'QUANTITY',
'QUANTITY_TRACE',
'CAN_BUY_ZERO',
'MEASURE',
2013 'VAT_ID',
'VAT_INCLUDED',
2014 'WEIGHT',
'WIDTH',
'LENGTH',
'HEIGHT',
2015 'PAYMENT_TYPE',
'RECUR_SCHEME_LENGTH',
'RECUR_SCHEME_TYPE',
2021 $result = array_merge(
2024 'QUANTITY_TRACE_RAW',
'CAN_BUY_ZERO_RAW',
'SUBSCRIBE_RAW',
2025 'PURCHASING_PRICE',
'PURCHASING_CURRENCY',
2043 if (!$this->useCatalog)
2045 return \CProductQueryBuilder::convertOldSelect($select);
2056 if (!$this->useCatalog)
2058 return \CProductQueryBuilder::convertOldFilter($filter);
2069 if (!$this->useCatalog)
2071 return \CProductQueryBuilder::convertOldOrder($order);
2076 if (!$this->useCatalog)
2077 return $this->selectFields;
2092 if (!empty($condition) && is_array($condition))
2094 if ($condition[
'CLASS_ID'] ===
'CondGroup')
2096 if (!empty($condition[
'CHILDREN']))
2098 foreach ($condition[
'CHILDREN'] as $child)
2103 if ($child[
'CLASS_ID'] ===
'CondGroup')
2105 $result[] = $childResult;
2108 elseif (isset($result[key($childResult)]))
2110 $fieldName = key($childResult);
2112 if (!isset($result[
'LOGIC']))
2115 'LOGIC' => $condition[
'DATA'][
'All'],
2116 array($fieldName => $result[$fieldName])
2120 $result[][$fieldName] = $childResult[$fieldName];
2124 $result += $childResult;
2128 if (!empty($result))
2132 if (count($result) > 1)
2134 $result[
'LOGIC'] = $condition[
'DATA'][
'All'];
2152 if (!empty($condition) && is_array($condition))
2159 $result[$operator.$name] = $value;
2161 if ($name ===
'SECTION_ID')
2163 $result[
'INCLUDE_SUBSECTIONS'] = isset($params[
'INCLUDE_SUBSECTIONS']) && $params[
'INCLUDE_SUBSECTIONS'] ===
'N' ?
'N' :
'Y';
2165 if (isset($params[
'INCLUDE_SUBSECTIONS']) && $params[
'INCLUDE_SUBSECTIONS'] ===
'A')
2167 $result[
'SECTION_GLOBAL_ACTIVE'] =
'Y';
2170 $result = array($result);
2181 $conditionNameMap = array(
2182 'CondIBXmlID' =>
'XML_ID',
2183 'CondIBSection' =>
'SECTION_ID',
2184 'CondIBDateActiveFrom' =>
'DATE_ACTIVE_FROM',
2185 'CondIBDateActiveTo' =>
'DATE_ACTIVE_TO',
2186 'CondIBSort' =>
'SORT',
2187 'CondIBDateCreate' =>
'DATE_CREATE',
2188 'CondIBCreatedBy' =>
'CREATED_BY',
2189 'CondIBTimestampX' =>
'TIMESTAMP_X',
2190 'CondIBModifiedBy' =>
'MODIFIED_BY',
2191 'CondIBTags' =>
'TAGS',
2192 'CondCatQuantity' =>
'QUANTITY',
2193 'CondCatWeight' =>
'WEIGHT'
2196 if (isset($conditionNameMap[$condition[
'CLASS_ID']]))
2198 $name = $conditionNameMap[$condition[
'CLASS_ID']];
2200 elseif (mb_strpos($condition[
'CLASS_ID'],
'CondIBProp') !==
false)
2202 $name = $condition[
'CLASS_ID'];
2212 switch ($condition[
'DATA'][
'logic'])
2245 $value = $condition[
'DATA'][
'value'];
2249 case 'DATE_ACTIVE_FROM':
2250 case 'DATE_ACTIVE_TO':
2253 $value = ConvertTimeStamp($value,
'FULL');
2262 if (!empty($result))
2264 $subFilter = array();
2266 foreach ($result as $name => $value)
2268 if (!empty($result[$name]) && is_array($result[$name]))
2274 if (($ind = mb_strpos($name,
'CondIBProp')) !==
false)
2276 [$prefix, $iblock, $propertyId] = explode(
':', $name);
2277 $operator = $ind > 0? mb_substr($prefix, 0, $ind) :
'';
2279 $catalogInfo = \CCatalogSku::GetInfoByIBlock($iblock);
2280 if (!empty($catalogInfo))
2283 $catalogInfo[
'CATALOG_TYPE'] != \CCatalogSku::TYPE_CATALOG
2284 && $catalogInfo[
'IBLOCK_ID'] == $iblock
2287 $subFilter[$operator.
'PROPERTY_'.$propertyId] = $value;
2291 $result[$operator.
'PROPERTY_'.$propertyId] = $value;
2295 unset($result[$name]);
2300 if (!empty($subFilter) && !empty($catalogInfo))
2302 $offerPropFilter = array(
2303 'IBLOCK_ID' => $catalogInfo[
'IBLOCK_ID'],
2304 'ACTIVE_DATE' =>
'Y',
2308 if ($params[
'HIDE_NOT_AVAILABLE_OFFERS'] ===
'Y')
2310 $offerPropFilter[
'HIDE_NOT_AVAILABLE'] =
'Y';
2312 elseif ($params[
'HIDE_NOT_AVAILABLE_OFFERS'] ===
'L')
2314 $offerPropFilter[] = array(
2321 if (count($subFilter) > 1)
2323 $subFilter[
'LOGIC'] = $condition[
'DATA'][
'All'];
2324 $subFilter = array($subFilter);
2327 $result[
'=ID'] = \CIBlockElement::SubQuery(
2328 'PROPERTY_'.$catalogInfo[
'SKU_PROPERTY_ID'],
2329 $offerPropFilter + $subFilter
2356 $element[
'ID'] = (int)$element[
'ID'];
2357 $element[
'IBLOCK_ID'] = (int)$element[
'IBLOCK_ID'];
2359 if ($this->arParams[
'HIDE_DETAIL_URL'])
2361 $element[
'DETAIL_PAGE_URL'] = $element[
'~DETAIL_PAGE_URL'] =
'';
2366 $element[
'ACTIVE_FROM'] = ($element[
'DATE_ACTIVE_FROM'] ??
null);
2367 $element[
'ACTIVE_TO'] = ($element[
'DATE_ACTIVE_TO'] ??
null);
2371 $element[
'IPROPERTY_VALUES'] = $ipropValues->getValues();
2373 Iblock\Component\Tools::getFieldImageData(
2375 array(
'PREVIEW_PICTURE',
'DETAIL_PICTURE'),
2376 Iblock\Component\Tools::IPROPERTY_ENTITY_ELEMENT,
2380 if (isset($element[
'~TYPE']))
2385 $element[
'PRODUCT'] = array(
2386 'TYPE' => (
int)$element[
'~TYPE'],
2387 'AVAILABLE' => $element[
'~AVAILABLE'],
2388 'BUNDLE' => $element[
'~BUNDLE'],
2389 'QUANTITY' => $element[
'~QUANTITY'],
2390 'QUANTITY_TRACE' => $element[
'~QUANTITY_TRACE'],
2391 'CAN_BUY_ZERO' => $element[
'~CAN_BUY_ZERO'],
2392 'MEASURE' => (
int)$element[
'~MEASURE'],
2393 'SUBSCRIBE' => $element[
'~SUBSCRIBE'],
2394 'VAT_ID' => (
int)$element[
'~VAT_ID'],
2396 'VAT_INCLUDED' => $element[
'~VAT_INCLUDED'],
2397 'WEIGHT' => (
float)$element[
'~WEIGHT'],
2398 'WIDTH' => (
float)$element[
'~WIDTH'],
2399 'LENGTH' => (
float)$element[
'~LENGTH'],
2400 'HEIGHT' => (
float)$element[
'~HEIGHT'],
2401 'PAYMENT_TYPE' => $element[
'~PAYMENT_TYPE'],
2402 'RECUR_SCHEME_TYPE' => $element[
'~RECUR_SCHEME_TYPE'],
2403 'RECUR_SCHEME_LENGTH' => (
int)$element[
'~RECUR_SCHEME_LENGTH'],
2404 'TRIAL_PRICE_ID' => (
int)$element[
'~TRIAL_PRICE_ID']
2409 if ($element[
'PRODUCT'][
'VAT_ID'] > 0)
2410 $vatId = $element[
'PRODUCT'][
'VAT_ID'];
2411 elseif ($this->storage[
'IBLOCKS_VAT'][$element[
'IBLOCK_ID']] > 0)
2412 $vatId = $this->storage[
'IBLOCKS_VAT'][$element[
'IBLOCK_ID']];
2413 if ($vatId > 0 && isset($this->storage[
'VATS'][$vatId]))
2414 $vatRate = $this->storage[
'VATS'][$vatId];
2415 $element[
'PRODUCT'][
'VAT_RATE'] = $vatRate;
2416 unset($vatRate, $vatId);
2417 $element[
'PRODUCT'][
'USE_OFFERS'] = $element[
'PRODUCT'][
'TYPE'] == Catalog\ProductTable::TYPE_SKU;
2421 foreach ($translateFields as $currentKey => $oldKey)
2422 $element[$oldKey] = $element[$currentKey];
2423 unset($currentKey, $oldKey);
2424 $element[
'~CATALOG_VAT'] = $element[
'PRODUCT'][
'VAT_RATE'];
2425 $element[
'CATALOG_VAT'] = $element[
'PRODUCT'][
'VAT_RATE'];
2430 $element[
'~CATALOG_TYPE'] = $element[
'PRODUCT'][
'TYPE'];
2431 $element[
'CATALOG_TYPE'] = $element[
'PRODUCT'][
'TYPE'];
2432 $element[
'~CATALOG_QUANTITY'] = $element[
'PRODUCT'][
'QUANTITY'];
2433 $element[
'CATALOG_QUANTITY'] = $element[
'PRODUCT'][
'QUANTITY'];
2434 $element[
'~CATALOG_QUANTITY_TRACE'] = $element[
'PRODUCT'][
'QUANTITY_TRACE'];
2435 $element[
'CATALOG_QUANTITY_TRACE'] = $element[
'PRODUCT'][
'QUANTITY_TRACE'];
2436 $element[
'~CATALOG_CAN_BUY_ZERO'] = $element[
'PRODUCT'][
'CAN_BUY_ZERO'];
2437 $element[
'CATALOG_CAN_BUY_ZERO'] = $element[
'PRODUCT'][
'CAN_BUY_ZERO'];
2438 $element[
'~CATALOG_SUBSCRIBE'] = $element[
'PRODUCT'][
'SUBSCRIBE'];
2439 $element[
'CATALOG_SUBSCRIBE'] = $element[
'PRODUCT'][
'SUBSCRIBE'];
2442 foreach ($productFields as $field)
2443 unset($element[$field], $element[
'~'.$field]);
2448 $element[
'PRODUCT'] = array(
2450 'AVAILABLE' =>
null,
2451 'USE_OFFERS' =>
false
2455 $element[
'PROPERTIES'] = array();
2456 $element[
'DISPLAY_PROPERTIES'] = array();
2457 $element[
'PRODUCT_PROPERTIES'] = array();
2458 $element[
'PRODUCT_PROPERTIES_FILL'] = array();
2459 $element[
'OFFERS'] = array();
2460 $element[
'OFFER_ID_SELECTED'] = 0;
2462 if (!empty($this->storage[
'CATALOGS'][$element[
'IBLOCK_ID']]))
2465 if ($this->
getAction() ===
'bigDataLoad')
2467 $element[
'RCM_ID'] = $this->recommendationIdToProduct[$element[
'ID']];
2479 $buttons = \CIBlock::GetPanelButtons(
2480 $element[
'IBLOCK_ID'],
2482 $element[
'IBLOCK_SECTION_ID'],
2483 array(
'SECTION_BUTTONS' =>
false,
'SESSID' =>
false,
'CATALOG' =>
true)
2485 $element[
'EDIT_LINK'] = ($buttons[
'edit'][
'edit_element'][
'ACTION_URL'] ??
null);
2486 $element[
'DELETE_LINK'] = ($buttons[
'edit'][
'delete_element'][
'ACTION_URL'] ??
null);
2502 $propertyList = array();
2503 if (empty($propertyCodes))
2504 return $propertyList;
2506 $propertyCodes = array_fill_keys($propertyCodes,
true);
2508 $propertyIterator = Iblock\PropertyTable::getList(array(
2509 'select' => array(
'ID',
'CODE',
'SORT'),
2510 'filter' => array(
'=IBLOCK_ID' => $iblock,
'=ACTIVE' =>
'Y'),
2511 'order' => array(
'SORT' =>
'ASC',
'ID' =>
'ASC')
2513 while ($property = $propertyIterator->fetch())
2515 $code = (string)$property[
'CODE'];
2519 $code = $property[
'ID'];
2522 if (!isset($propertyCodes[$code]))
2525 $propertyList[] = $code;
2528 return $propertyList;
2538 $this->prices = array();
2539 $this->measures = array();
2540 $this->ratios = array();
2541 $this->quantityRanges = array();
2542 $this->oldData = array();
2554 if (empty($itemIds))
2556 Main\Type\Collection::normalizeArrayValuesByInt($itemIds,
true);
2557 if (empty($itemIds))
2559 $emptyRatioIds = array_fill_keys($itemIds,
true);
2561 $iterator = Catalog\MeasureRatioTable::getList(array(
2562 'select' => array(
'ID',
'RATIO',
'IS_DEFAULT',
'PRODUCT_ID'),
2563 'filter' => array(
'@PRODUCT_ID' => $itemIds),
2564 'order' => array(
'PRODUCT_ID' =>
'ASC')
2566 while ($row = $iterator->fetch())
2568 $ratio = max((
float)$row[
'RATIO'], (
int)$row[
'RATIO']);
2569 if ($ratio > CATALOG_VALUE_EPSILON)
2571 $row[
'RATIO'] = $ratio;
2572 $row[
'ID'] = (int)$row[
'ID'];
2573 $id = (int)$row[
'PRODUCT_ID'];
2574 if (!isset($this->ratios[$id]))
2575 $this->ratios[$id] = array();
2576 $this->ratios[$id][$row[
'ID']] = $row;
2577 unset($emptyRatioIds[$id]);
2582 unset($row, $iterator);
2583 if (!empty($emptyRatioIds))
2586 foreach (array_keys($emptyRatioIds) as $id)
2588 $this->ratios[$id] = array(
2589 $emptyRatio[
'ID'] => $emptyRatio
2592 unset($id, $emptyRatio);
2594 unset($emptyRatioIds);
2622 foreach (array_keys($items) as $index)
2624 if (!isset($items[$index][
'PRODUCT'][
'MEASURE']))
2626 if ($items[$index][
'PRODUCT'][
'MEASURE'] > 0)
2628 $items[$index][
'ITEM_MEASURE'] = array(
2629 'ID' => $items[$index][
'PRODUCT'][
'MEASURE'],
2636 $items[$index][
'ITEM_MEASURE'] = array(
2638 'TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'SYMBOL_RUS'],
2639 '~TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'~SYMBOL_RUS']
2658 foreach (array_keys($items) as $itemId)
2660 if (!isset($items[$itemId][
'ITEM_MEASURE']))
2662 $measureId = (int)$items[$itemId][
'ITEM_MEASURE'][
'ID'];
2664 $result[$measureId] = $measureId;
2681 if (empty($measureIds))
2683 Main\Type\Collection::normalizeArrayValuesByInt($measureIds,
true);
2684 if (empty($measureIds))
2687 $measureIterator = \CCatalogMeasure::getList(
2689 array(
'@ID' => $measureIds),
2692 array(
'ID',
'SYMBOL_RUS')
2694 while ($measure = $measureIterator->GetNext())
2696 $measure[
'ID'] = (int)$measure[
'ID'];
2697 $measure[
'TITLE'] = $measure[
'SYMBOL_RUS'];
2698 $measure[
'~TITLE'] = $measure[
'~SYMBOL_RUS'];
2699 unset($measure[
'SYMBOL_RUS'], $measure[
'~SYMBOL_RUS']);
2700 $this->measures[$measure[
'ID']] = $measure;
2702 unset($measure, $measureIterator);
2713 if (empty($itemIds))
2715 Main\Type\Collection::normalizeArrayValuesByInt($itemIds,
true);
2716 if (empty($itemIds))
2721 if (empty($this->storage[
'PRICES_ALLOW']))
2726 $quantityList = array_fill_keys($itemIds, array());
2729 'ID',
'PRODUCT_ID',
'CATALOG_GROUP_ID',
'PRICE',
'CURRENCY',
2730 'QUANTITY_FROM',
'QUANTITY_TO',
'PRICE_SCALE'
2732 if ($enableCompatible)
2733 $select[] =
'EXTRA_ID';
2735 $pagedItemIds = array_chunk($itemIds, 500);
2736 foreach ($pagedItemIds as $pageIds)
2738 if (empty($pageIds))
2741 $iterator = Catalog\PriceTable::getList(array(
2742 'select' => $select,
2743 'filter' => array(
'@PRODUCT_ID' => $pageIds,
'@CATALOG_GROUP_ID' => $this->storage[
'PRICES_ALLOW']),
2744 'order' => array(
'PRODUCT_ID' =>
'ASC',
'CATALOG_GROUP_ID' =>
'ASC')
2746 while ($row = $iterator->fetch())
2748 $id = (int)$row[
'PRODUCT_ID'];
2749 unset($row[
'PRODUCT_ID']);
2750 if (!isset($this->prices[$id]))
2752 $this->prices[$id] = array(
2754 'QUANTITY' => array(),
2759 if ($row[
'QUANTITY_FROM'] !==
null || $row[
'QUANTITY_TO'] !==
null)
2762 if (!isset($quantityList[$id][$hash]))
2764 $quantityList[$id][$hash] = array(
2766 'QUANTITY_FROM' => $row[
'QUANTITY_FROM'],
2767 'QUANTITY_TO' => $row[
'QUANTITY_TO'],
2768 'SORT_FROM' => (
int)$row[
'QUANTITY_FROM'],
2769 'SORT_TO' => ($row[
'QUANTITY_TO'] ===
null ? INF : (int)$row[
'QUANTITY_TO'])
2772 if (!isset($this->prices[$id][
'QUANTITY'][$hash]))
2774 $this->prices[$id][
'QUANTITY'][$hash] = array();
2776 $this->prices[$id][
'QUANTITY'][$hash][$row[
'CATALOG_GROUP_ID']] = $row;
2779 elseif (!isset($row[
'MEASURE_RATIO_ID']))
2781 $this->prices[$id][
'SIMPLE'][$row[
'CATALOG_GROUP_ID']] = $row;
2783 $this->storage[
'CURRENCY_LIST'][$row[
'CURRENCY']] = $row[
'CURRENCY'];
2787 unset($row, $iterator);
2789 unset($pageIds, $pagedItemIds);
2791 foreach ($itemIds as $id)
2793 if (isset($this->prices[$id]))
2795 foreach ($this->prices[$id] as $key => $data)
2798 unset($this->prices[$id][$key]);
2802 if (count($this->prices[$id]) !== 1)
2804 unset($this->prices[$id]);
2808 if (!empty($this->prices[$id][
'QUANTITY']))
2810 $productQuantity = $quantityList[$id];
2811 Main\Type\Collection::sortByColumn(
2813 array(
'SORT_FROM' => SORT_ASC,
'SORT_TO' => SORT_ASC),
2816 $this->quantityRanges[$id] = $productQuantity;
2817 unset($productQuantity);
2819 if (count($this->ratios[$id]) > 1)
2822 if (!empty($this->prices[$id][
'SIMPLE']))
2825 $this->quantityRanges[$id] = array(
2826 $range[
'HASH'] => $range
2829 if (count($this->ratios[$id]) > 1)
2837 unset($quantityList);
2839 unset($enableCompatible);
2849 if ($enableCompatible)
2852 foreach (array_keys($items) as $index)
2854 $id = $items[$index][
'ID'];
2855 if (!isset($this->calculatePrices[$id]))
2857 if (empty($this->prices[$id]))
2859 $productPrices = $this->prices[$id];
2861 'ITEM_PRICE_MODE' =>
null,
2862 'ITEM_PRICES' => array(),
2863 'ITEM_PRICES_CAN_BUY' =>
false
2865 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
2866 $result[
'ITEM_ALL_PRICES'] = array();
2867 $priceBlockIndex = 0;
2868 if (!empty($productPrices[
'QUANTITY']))
2870 $result[
'ITEM_PRICE_MODE'] = Catalog\ProductTable::PRICE_MODE_QUANTITY;
2871 $ratio = current($this->ratios[$id]);
2872 foreach ($this->quantityRanges[$id] as $range)
2874 $priceBlock = $this->calculatePriceBlock(
2876 $productPrices[
'QUANTITY'][$range[
'HASH']],
2880 if (!empty($priceBlock))
2882 $minimalPrice = ($this->arParams[
'FILL_ITEM_ALL_PRICES']
2883 ? $priceBlock[
'MINIMAL_PRICE']
2886 if ($minimalPrice[
'QUANTITY_FROM'] ===
null)
2888 $minimalPrice[
'MIN_QUANTITY'] = $ratio[
'RATIO'];
2892 $minimalPrice[
'MIN_QUANTITY'] = $ratio[
'RATIO'] * ((int)($minimalPrice[
'QUANTITY_FROM']/$ratio[
'RATIO']));
2893 if ($minimalPrice[
'MIN_QUANTITY'] < $minimalPrice[
'QUANTITY_FROM'])
2894 $minimalPrice[
'MIN_QUANTITY'] += $ratio[
'RATIO'];
2896 $result[
'ITEM_PRICES'][$priceBlockIndex] = $minimalPrice;
2897 if (isset($this->storage[
'PRICES_CAN_BUY'][$minimalPrice[
'PRICE_TYPE_ID']]))
2898 $result[
'ITEM_PRICES_CAN_BUY'] =
true;
2899 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
2901 $priceBlock[
'ALL_PRICES'][
'MIN_QUANTITY'] = $minimalPrice[
'MIN_QUANTITY'];
2902 $result[
'ITEM_ALL_PRICES'][$priceBlockIndex] = $priceBlock[
'ALL_PRICES'];
2904 unset($minimalPrice);
2912 if (!empty($productPrices[
'SIMPLE']))
2914 $result[
'ITEM_PRICE_MODE'] = Catalog\ProductTable::PRICE_MODE_SIMPLE;
2915 $ratio = current($this->ratios[$id]);
2916 $priceBlock = $this->calculatePriceBlock(
2918 $productPrices[
'SIMPLE'],
2922 if (!empty($priceBlock))
2924 $minimalPrice = ($this->arParams[
'FILL_ITEM_ALL_PRICES']
2925 ? $priceBlock[
'MINIMAL_PRICE']
2928 $minimalPrice[
'MIN_QUANTITY'] = $ratio[
'RATIO'];
2929 $result[
'ITEM_PRICES'][$priceBlockIndex] = $minimalPrice;
2930 if (isset($this->storage[
'PRICES_CAN_BUY'][$minimalPrice[
'PRICE_TYPE_ID']]))
2931 $result[
'ITEM_PRICES_CAN_BUY'] =
true;
2932 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
2934 $priceBlock[
'ALL_PRICES'][
'MIN_QUANTITY'] = $minimalPrice[
'MIN_QUANTITY'];
2935 $result[
'ITEM_ALL_PRICES'][$priceBlockIndex] = $priceBlock[
'ALL_PRICES'];
2937 unset($minimalPrice);
2943 $this->prices[$id] = $result;
2945 if (isset($items[$index][
'ACTIVE']) && $items[$index][
'ACTIVE'] ===
'N')
2947 $items[$index][
'CAN_BUY'] =
false;
2951 $items[$index][
'CAN_BUY'] = $result[
'ITEM_PRICES_CAN_BUY'] && $items[$index][
'PRODUCT'][
'AVAILABLE'] ===
'Y';
2954 unset($priceBlockIndex, $result);
2955 unset($productPrices);
2957 if ($enableCompatible)
2958 $this->resortOldPrices($id);
2969 $urls = $this->storage[
'URLS'];
2971 foreach (array_keys($items) as $index)
2973 $itemId = $items[$index][
'ID'];
2975 if (!empty($items[$index][
'ITEM_MEASURE']))
2977 $id = (int)$items[$index][
'ITEM_MEASURE'][
'ID'];
2978 if (isset($this->measures[$id]))
2980 $items[$index][
'ITEM_MEASURE'][
'TITLE'] = $this->measures[$id][
'TITLE'];
2981 $items[$index][
'ITEM_MEASURE'][
'~TITLE'] = $this->measures[$id][
'~TITLE'];
2986 $items[$index][
'ITEM_MEASURE_RATIOS'] = $this->ratios[$itemId] ?? [];
2988 $items[$index][
'ITEM_QUANTITY_RANGES'] = $this->quantityRanges[$itemId] ?? [];
2990 if (!empty($this->prices[$itemId]))
2992 $items[$index] = array_merge($items[$index], $this->prices[$itemId]);
2993 if (!empty($items[$index][
'ITEM_PRICES']))
2995 switch ($items[$index][
'ITEM_PRICE_MODE'])
2997 case Catalog\ProductTable::PRICE_MODE_SIMPLE:
2998 $items[$index][
'ITEM_PRICE_SELECTED'] = 0;
3000 case Catalog\ProductTable::PRICE_MODE_QUANTITY:
3001 foreach (array_keys($items[$index][
'ITEM_PRICES']) as $priceIndex)
3003 if ($items[$index][
'ITEM_PRICES'][$priceIndex][
'QUANTITY_HASH'] == $items[$index][
'ITEM_QUANTITY_RANGE_SELECTED'])
3005 $items[$index][
'ITEM_PRICE_SELECTED'] = $priceIndex;
3010 case Catalog\ProductTable::PRICE_MODE_RATIO:
3011 foreach (array_keys($items[$index][
'ITEM_PRICES']) as $priceIndex)
3013 if ($items[$index][
'ITEM_PRICES'][$priceIndex][
'MEASURE_RATIO_ID'] == $items[$index][
'ITEM_MEASURE_RATIO_SELECTED'])
3015 $items[$index][
'ITEM_PRICE_SELECTED'] = $priceIndex;
3025 if ($enableCompatible)
3028 $id = $items[$index][
'ID'];
3029 $items[$index][
'~BUY_URL'] = str_replace(
'#ID#', $id, $urls[
'~BUY_URL_TEMPLATE']);
3030 $items[$index][
'BUY_URL'] = str_replace(
'#ID#', $id, $urls[
'BUY_URL_TEMPLATE']);
3031 $items[$index][
'~ADD_URL'] = str_replace(
'#ID#', $id, $urls[
'~ADD_URL_TEMPLATE']);
3032 $items[$index][
'ADD_URL'] = str_replace(
'#ID#', $id, $urls[
'ADD_URL_TEMPLATE']);
3033 $items[$index][
'~SUBSCRIBE_URL'] = str_replace(
'#ID#', $id, $urls[
'~SUBSCRIBE_URL_TEMPLATE']);
3034 $items[$index][
'SUBSCRIBE_URL'] = str_replace(
'#ID#', $id, $urls[
'SUBSCRIBE_URL_TEMPLATE']);
3035 if ($this->arParams[
'DISPLAY_COMPARE'])
3037 $items[$index][
'~COMPARE_URL'] = str_replace(
'#ID#', $id, $urls[
'~COMPARE_URL_TEMPLATE']);
3038 $items[$index][
'COMPARE_URL'] = str_replace(
'#ID#', $id, $urls[
'COMPARE_URL_TEMPLATE']);
3039 $items[$index][
'~COMPARE_DELETE_URL'] = str_replace(
'#ID#', $id, $urls[
'~COMPARE_DELETE_URL_TEMPLATE']);
3040 $items[$index][
'COMPARE_DELETE_URL'] = str_replace(
'#ID#', $id, $urls[
'COMPARE_DELETE_URL_TEMPLATE']);
3045 $items[$index][
'CATALOG_MEASURE_NAME'] = $items[$index][
'ITEM_MEASURE'][
'TITLE'];
3046 $items[$index][
'~CATALOG_MEASURE_NAME'] = $items[$index][
'ITEM_MEASURE'][
'~TITLE'];
3049 $items[$index][
'CATALOG_MEASURE_RATIO'] = $items[$index][
'ITEM_MEASURE_RATIOS'][$items[$index][
'ITEM_MEASURE_RATIO_SELECTED']][
'RATIO'] ?? 1;
3052 if (!empty($this->oldData[$itemId]))
3053 $items[$index] = array_merge($this->oldData[$itemId], $items[$index]);
3058 unset($urls, $enableCompatible);
3070 protected function calculatePriceBlock(array $product, array $priceBlock, $ratio, $defaultBlock =
false)
3072 if (empty($product) || empty($priceBlock))
3075 $enableCompatible = $defaultBlock && $this->isEnableCompatible();
3077 if ($enableCompatible && !$this->arParams[
'USE_PRICE_COUNT'])
3078 $this->fillCompatibleRawPriceFields($product[
'ID'], $priceBlock);
3080 $userGroups = $this->getUserGroups();
3082 $baseCurrency = Currency\CurrencyManager::getBaseCurrency();
3084 $minimalPrice =
null;
3086 $minimalBuyerPrice =
null;
3087 $fullPrices = array();
3089 $currencyConvert = $this->arParams[
'CONVERT_CURRENCY'] ===
'Y';
3090 $resultCurrency = ($currencyConvert ? $this->storage[
'CONVERT_CURRENCY'][
'CURRENCY_ID'] :
null);
3092 $vatRate = (float)$product[
'PRODUCT'][
'VAT_RATE'];
3093 $percentVat = $vatRate * 0.01;
3094 $percentPriceWithVat = 1 + $percentVat;
3095 $vatInclude = $product[
'PRODUCT'][
'VAT_INCLUDED'] ===
'Y';
3097 $oldPrices = array();
3098 $oldMinPrice =
false;
3100 if ($enableCompatible && $this->arParams[
'USE_PRICE_COUNT'])
3102 $oldMatrix = $this->getCompatibleFieldValue($product[
'ID'],
'PRICE_MATRIX');
3103 if (empty($oldMatrix))
3105 $oldMatrix = $this->getEmptyPriceMatrix();
3106 $oldMatrix[
'AVAILABLE'] = $product[
'PRODUCT'][
'AVAILABLE'];
3110 foreach ($priceBlock as $rawPrice)
3112 $priceType = (int)$rawPrice[
'CATALOG_GROUP_ID'];
3113 $price = (float)$rawPrice[
'PRICE'];
3115 $price *= $percentPriceWithVat;
3116 $currency = $rawPrice[
'CURRENCY'];
3118 $changeCurrency = $currencyConvert && $currency !== $resultCurrency;
3119 if ($changeCurrency)
3121 $price = \CCurrencyRates::ConvertCurrency($price, $currency, $resultCurrency);
3122 $currency = $resultCurrency;
3125 $discounts = array();
3126 if (\CIBlockPriceTools::isEnabledCalculationDiscounts())
3128 \CCatalogDiscountSave::Disable();
3129 $discounts = \CCatalogDiscount::GetDiscount(
3131 $product[
'IBLOCK_ID'],
3138 \CCatalogDiscountSave::Enable();
3140 $discountPrice = \CCatalogProduct::CountPriceWithDiscount(
3145 if ($discountPrice !==
false)
3147 $priceWithVat = array(
3148 'UNROUND_BASE_PRICE' => $price,
3149 'UNROUND_PRICE' => $discountPrice,
3150 'BASE_PRICE' => Catalog\Product\Price::roundPrice(
3155 'PRICE' => Catalog\Product\Price::roundPrice(
3162 $price /= $percentPriceWithVat;
3163 $discountPrice /= $percentPriceWithVat;
3165 $priceWithoutVat = array(
3166 'UNROUND_BASE_PRICE' => $price,
3167 'UNROUND_PRICE' => $discountPrice,
3168 'BASE_PRICE' => Catalog\Product\Price::roundPrice(
3173 'PRICE' => Catalog\Product\Price::roundPrice(
3180 if ($this->arParams[
'PRICE_VAT_INCLUDE'])
3181 $priceRow = $priceWithVat;
3183 $priceRow = $priceWithoutVat;
3184 $priceRow[
'ID'] = $rawPrice[
'ID'];
3185 $priceRow[
'PRICE_TYPE_ID'] = $rawPrice[
'CATALOG_GROUP_ID'];
3186 $priceRow[
'CURRENCY'] = $currency;
3190 || ($priceRow[
'BASE_PRICE'] <= $priceRow[
'PRICE'])
3193 $priceRow[
'BASE_PRICE'] = $priceRow[
'PRICE'];
3194 $priceRow[
'DISCOUNT'] = 0;
3195 $priceRow[
'PERCENT'] = 0;
3199 $priceRow[
'DISCOUNT'] = $priceRow[
'BASE_PRICE'] - $priceRow[
'PRICE'];
3200 $priceRow[
'PERCENT'] = roundEx(100*$priceRow[
'DISCOUNT']/$priceRow[
'BASE_PRICE'], 0);
3202 if (isset($this->arParams[
'PRICE_VAT_SHOW_VALUE']) && $this->arParams[
'PRICE_VAT_SHOW_VALUE'])
3203 $priceRow[
'VAT'] = ($vatRate > 0 ? $priceWithVat[
'PRICE'] - $priceWithoutVat[
'PRICE'] : 0);
3205 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
3206 $fullPrices[$priceType] = $priceRow;
3208 $priceRow[
'QUANTITY_FROM'] = $rawPrice[
'QUANTITY_FROM'];
3209 $priceRow[
'QUANTITY_TO'] = $rawPrice[
'QUANTITY_TO'];
3211 $priceRow[
'MEASURE_RATIO_ID'] = $rawPrice[
'MEASURE_RATIO_ID'] ??
null;
3212 $priceRow[
'PRICE_SCALE'] = \CCurrencyRates::ConvertCurrency(
3214 $priceRow[
'CURRENCY'],
3217 $priceRow[
'BASE_PRICE_SCALE'] = $rawPrice[
'PRICE_SCALE'];
3220 $minimalPrice ===
null
3221 || $minimalPrice[
'PRICE_SCALE'] > $priceRow[
'PRICE_SCALE']
3224 $minimalPrice = $priceRow;
3227 $minimalPrice[
'PRICE_SCALE'] == $priceRow[
'PRICE_SCALE']
3228 && $minimalPrice[
'BASE_PRICE_SCALE'] > $priceRow[
'BASE_PRICE_SCALE']
3231 $minimalPrice = $priceRow;
3233 if (isset($this->storage[
'PRICES_CAN_BUY'][$priceRow[
'PRICE_TYPE_ID']]))
3236 $minimalBuyerPrice ===
null
3237 || $minimalBuyerPrice[
'PRICE_SCALE'] > $priceRow[
'PRICE_SCALE']
3240 $minimalBuyerPrice = $priceRow;
3243 $minimalBuyerPrice[
'PRICE_SCALE'] == $priceRow[
'PRICE_SCALE']
3244 && $minimalBuyerPrice[
'BASE_PRICE_SCALE'] > $priceRow[
'BASE_PRICE_SCALE']
3247 $minimalBuyerPrice = $priceRow;
3251 if ($enableCompatible)
3253 if ($this->arParams[
'USE_PRICE_COUNT'])
3256 $oldMatrix[
'ROWS'][$rowIndex] = array(
3257 'QUANTITY_FROM' => (
float)$rawPrice[
'QUANTITY_FROM'],
3258 'QUANTITY_TO' => (
float)$rawPrice[
'QUANTITY_TO']
3260 if (!isset($oldMatrix[
'MATRIX'][$priceType]))
3262 $oldMatrix[
'MATRIX'][$priceType] = array();
3263 $oldMatrix[
'COLS'][$priceType] = $this->storage[
'PRICE_TYPES'][$priceType];
3265 $oldMatrix[
'MATRIX'][$priceType][$rowIndex] = array(
3266 'ID' => $priceRow[
'ID'],
3267 'PRICE' => $priceRow[
'BASE_PRICE'],
3268 'DISCOUNT_PRICE' => $priceRow[
'PRICE'],
3269 'UNROUND_DISCOUNT_PRICE' => $priceRow[
'UNROUND_PRICE'],
3270 'CURRENCY' => $priceRow[
'CURRENCY'],
3271 'VAT_RATE' => $percentVat
3273 if ($changeCurrency)
3275 $oldMatrix[
'MATRIX'][$priceType][$rowIndex][
'ORIG_CURRENCY'] = $rawPrice[
'CURRENCY'];
3276 $oldMatrix[
'MATRIX'][$priceType][$rowIndex][
'ORIG_PRICE'] = \CCurrencyRates::ConvertCurrency(
3277 $priceRow[
'BASE_PRICE'],
3278 $priceRow[
'CURRENCY'],
3279 $rawPrice[
'CURRENCY']
3281 $oldMatrix[
'MATRIX'][$priceType][$rowIndex][
'ORIG_DISCOUNT_PRICE'] = \CCurrencyRates::ConvertCurrency(
3283 $priceRow[
'CURRENCY'],
3284 $rawPrice[
'CURRENCY']
3286 $oldMatrix[
'MATRIX'][$priceType][$rowIndex][
'ORIG_VAT_RATE'] = $percentVat;
3291 $priceCode = $this->storage[
'PRICES_MAP'][$priceType];
3292 $oldPriceRow = array(
3293 'PRICE_ID' => $priceRow[
'PRICE_TYPE_ID'],
3294 'ID' => $priceRow[
'ID'],
3295 'CAN_ACCESS' => ($this->storage[
'PRICES'][$priceCode][
'CAN_VIEW'] ?
'Y' :
'N'),
3296 'CAN_BUY' => ($this->storage[
'PRICES'][$priceCode][
'CAN_BUY'] ?
'Y' :
'N'),
3298 'CURRENCY' => $priceRow[
'CURRENCY'],
3299 'VALUE_VAT' => $priceWithVat[
'UNROUND_BASE_PRICE'],
3300 'VALUE_NOVAT' => $priceWithoutVat[
'UNROUND_BASE_PRICE'],
3301 'DISCOUNT_VALUE_VAT' => $priceWithVat[
'UNROUND_PRICE'],
3302 'DISCOUNT_VALUE_NOVAT' => $priceWithoutVat[
'UNROUND_PRICE'],
3303 'ROUND_VALUE_VAT' => $priceWithVat[
'PRICE'],
3304 'ROUND_VALUE_NOVAT' => $priceWithoutVat[
'PRICE'],
3305 'VALUE' => $priceRow[
'BASE_PRICE'],
3306 'UNROUND_DISCOUNT_VALUE' => $priceRow[
'UNROUND_PRICE'],
3307 'DISCOUNT_VALUE' => $priceRow[
'PRICE'],
3308 'DISCOUNT_DIFF' => $priceRow[
'DISCOUNT'],
3309 'DISCOUNT_DIFF_PERCENT' => $priceRow[
'PERCENT']
3311 $oldPriceRow[
'VATRATE_VALUE'] = $oldPriceRow[
'VALUE_VAT'] - $oldPriceRow[
'VALUE_NOVAT'];
3312 $oldPriceRow[
'DISCOUNT_VATRATE_VALUE'] = $oldPriceRow[
'DISCOUNT_VALUE_VAT'] - $oldPriceRow[
'DISCOUNT_VALUE_NOVAT'];
3313 $oldPriceRow[
'ROUND_VATRATE_VALUE'] = $oldPriceRow[
'ROUND_VALUE_VAT'] - $oldPriceRow[
'ROUND_VALUE_NOVAT'];
3314 if ($changeCurrency)
3315 $oldPriceRow[
'ORIG_CURRENCY'] = $rawPrice[
'CURRENCY'];
3316 $oldPrices[$priceCode] = $oldPriceRow;
3317 unset($oldPriceRow);
3326 $minimalPriceId =
null;
3327 if (is_array($minimalBuyerPrice))
3328 $minimalPrice = $minimalBuyerPrice;
3329 if (is_array($minimalPrice))
3331 unset($minimalPrice[
'PRICE_SCALE']);
3332 unset($minimalPrice[
'BASE_PRICE_SCALE']);
3333 $minimalPriceId = $minimalPrice[
'PRICE_TYPE_ID'];
3334 $prepareFields = array(
3335 'BASE_PRICE',
'PRICE',
'DISCOUNT'
3337 if (isset($this->arParams[
'PRICE_VAT_SHOW_VALUE']) && $this->arParams[
'PRICE_VAT_SHOW_VALUE'])
3338 $prepareFields[] =
'VAT';
3340 foreach ($prepareFields as $fieldName)
3342 $minimalPrice[
'PRINT_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3343 $minimalPrice[$fieldName],
3344 $minimalPrice[
'CURRENCY'],
3347 $minimalPrice[
'RATIO_'.$fieldName] = $minimalPrice[$fieldName]*$ratio;
3348 $minimalPrice[
'PRINT_RATIO_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3349 $minimalPrice[
'RATIO_'.$fieldName],
3350 $minimalPrice[
'CURRENCY'],
3356 if ($this->arParams[
'FILL_ITEM_ALL_PRICES'])
3358 foreach (array_keys($fullPrices) as $priceType)
3360 foreach ($prepareFields as $fieldName)
3362 $fullPrices[$priceType][
'PRINT_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3363 $fullPrices[$priceType][$fieldName],
3364 $fullPrices[$priceType][
'CURRENCY'],
3367 $fullPrices[$priceType][
'RATIO_'.$fieldName] = $fullPrices[$priceType][$fieldName]*$ratio;
3368 $fullPrices[$priceType][
'PRINT_RATIO_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3369 $minimalPrice[
'RATIO_'.$fieldName],
3370 $minimalPrice[
'CURRENCY'],
3379 unset($prepareFields);
3382 if ($enableCompatible)
3384 if ($this->arParams[
'USE_PRICE_COUNT'])
3386 $oldMatrix[
'CAN_BUY'] = array_values($this->storage[
'PRICES_CAN_BUY']);
3387 $this->oldData[$product[
'ID']][
'PRICE_MATRIX'] = $oldMatrix;
3391 $convertFields = array(
3392 'VALUE_NOVAT',
'VALUE_VAT',
'VATRATE_VALUE',
3393 'DISCOUNT_VALUE_NOVAT',
'DISCOUNT_VALUE_VAT',
'DISCOUNT_VATRATE_VALUE'
3396 $prepareFields = array(
3397 'VALUE_NOVAT',
'VALUE_VAT',
'VATRATE_VALUE',
3398 'DISCOUNT_VALUE_NOVAT',
'DISCOUNT_VALUE_VAT',
'DISCOUNT_VATRATE_VALUE',
3399 'VALUE',
'DISCOUNT_VALUE',
'DISCOUNT_DIFF'
3402 if (!empty($oldPrices))
3404 foreach (array_keys($oldPrices) as $index)
3406 foreach ($prepareFields as $fieldName)
3407 $oldPrices[$index][
'PRINT_'.$fieldName] = \CCurrencyLang::CurrencyFormat(
3408 $oldPrices[$index][$fieldName],
3409 $oldPrices[$index][
'CURRENCY'],
3413 if (isset($oldPrices[$index][
'ORIG_CURRENCY']))
3415 foreach ($convertFields as $fieldName)
3416 $oldPrices[$index][
'ORIG_' . $fieldName] = \CCurrencyRates::ConvertCurrency(
3417 $oldPrices[$index][$fieldName],
3418 $oldPrices[$index][
'CURRENCY'],
3419 $oldPrices[$index][
'ORIG_CURRENCY']
3423 if ($oldPrices[$index][
'PRICE_ID'] === $minimalPriceId)
3425 $oldPrices[$index][
'MIN_PRICE'] =
'Y';
3426 $oldMinPrice = $oldPrices[$index];
3431 unset($prepareFields);
3433 $this->oldData[$product[
'ID']][
'PRICES'] = $oldPrices;
3434 $this->oldData[$product[
'ID']][
'MIN_PRICE'] = $oldMinPrice;
3437 unset($oldMatrix, $oldMinPrice, $oldPrices);
3439 if (!$this->arParams[
'FILL_ITEM_ALL_PRICES'])
3440 return $minimalPrice;
3443 'MINIMAL_PRICE' => $minimalPrice,
3444 'ALL_PRICES' => array(
3445 'QUANTITY_FROM' => $minimalPrice[
'QUANTITY_FROM'],
3446 'QUANTITY_TO' => $minimalPrice[
'QUANTITY_TO'],
3447 'QUANTITY_HASH' => $minimalPrice[
'QUANTITY_HASH'],
3448 'MEASURE_RATIO_ID' => $minimalPrice[
'MEASURE_RATIO_ID'],
3449 'PRICES' => $fullPrices
3456 if (!isset($this->ratios[$id]))
3460 $minimalRatio =
null;
3462 foreach ($this->ratios[$id] as $ratio)
3464 if ($minimalRatio ===
null || $minimalRatio > $ratio[
'RATIO'])
3466 $minimalRatio = $ratio[
'RATIO'];
3467 $minimal = $ratio[
'ID'];
3469 if ($ratio[
'IS_DEFAULT'] ===
'Y')
3471 $result = $ratio[
'ID'];
3476 return ($result ===
null ? $minimal : $result);
3482 if ($ratioId ===
null)
3484 $this->ratios[$id] = array(
3485 $ratioId => $this->ratios[$id][$ratioId]
3491 return ($range[
'QUANTITY_FROM'] ===
null ?
'ZERO' : $range[
'QUANTITY_FROM']).
3492 '-'.($range[
'QUANTITY_TO'] ===
null ?
'INF' : $range[
'QUANTITY_TO']);
3499 'QUANTITY_FROM' =>
null,
3500 'QUANTITY_TO' =>
null,
3508 if (empty($this->quantityRanges[$id]))
3510 foreach ($this->quantityRanges[$id] as $range)
3513 return $range[
'HASH'];
3515 reset($this->quantityRanges[$id]);
3516 $firsrRange = current($this->quantityRanges[$id]);
3517 return $firsrRange[
'HASH'];
3527 $actionVar = $this->arParams[
'ACTION_VARIABLE'];
3528 $productIdVar = $this->arParams[
'PRODUCT_ID_VARIABLE'];
3529 $compareActionVar = $this->arParams[
'ACTION_COMPARE_VARIABLE'];
3531 $clearParams = Main\HttpRequest::getSystemParameters();
3532 $clearParams[] = $actionVar;
3533 $clearParams[] = $productIdVar;
3534 $clearParams[] = $compareActionVar;
3535 $clearParams[] =
'';
3537 if (!empty($this->arParams[
'CUSTOM_CURRENT_PAGE']))
3539 $pageUrl = $this->arParams[
'CUSTOM_CURRENT_PAGE'];
3543 if ($this->request->isAjaxRequest())
3545 $pageUrl = $this->arParams[
'CURRENT_BASE_PAGE'];
3549 $pageUrl = Main\Application::getInstance()->getContext()->getRequest()->getDecodedUri();
3555 if ($this->arParams[
'USE_COMPARE_LIST'] ==
'N' && $this->arParams[
'COMPARE_PATH'] !=
'')
3557 $compareUri =
new Main\Web\Uri($this->arParams[
'COMPARE_PATH']);
3561 $compareUri = $currentUri;
3564 $currentUri->deleteParams($clearParams);
3565 $compareUri->deleteParams($clearParams);
3568 $urls[
'BUY_URL_TEMPLATE'] = $currentUri->addParams([$actionVar => self::ACTION_BUY, $productIdVar =>
'#ID#'])->getUri();
3569 $urls[
'ADD_URL_TEMPLATE'] = $currentUri->addParams([$actionVar => self::ACTION_ADD_TO_BASKET, $productIdVar =>
'#ID#'])->getUri();
3570 $urls[
'SUBSCRIBE_URL_TEMPLATE'] = $currentUri->addParams([$actionVar => self::ACTION_SUBSCRIBE, $productIdVar =>
'#ID#'])->getUri();
3572 $urls[
'COMPARE_URL_TEMPLATE'] = $compareUri->addParams([$compareActionVar => self::ACTION_ADD_TO_COMPARE, $productIdVar =>
'#ID#'])->getUri();
3573 $urls[
'COMPARE_DELETE_URL_TEMPLATE'] = $compareUri->addParams([$compareActionVar => self::ACTION_DELETE_FROM_COMPARE, $productIdVar =>
'#ID#'])->getUri();
3575 unset($compareUri, $currentUri, $clearParams);
3577 foreach (array_keys($urls) as $index)
3579 $value = str_replace(
'%23ID%23',
'#ID#', $urls[$index]);
3580 $urls[
'~'.$index] = $value;
3581 $urls[$index] = Main\Text\HtmlFilter::encode($value, ENT_QUOTES);
3585 $this->storage[
'URLS'] = $urls;
3597 $id = $element[
'ID'];
3598 $iblockId = $element[
'IBLOCK_ID'];
3599 $catalog = !empty($this->storage[
'CATALOGS'][$element[
'IBLOCK_ID']])
3600 ? $this->storage[
'CATALOGS'][$element[
'IBLOCK_ID']]
3603 $element[
'ITEM_PRICE_MODE'] =
null;
3604 $element[
'ITEM_PRICES'] = array();
3605 $element[
'ITEM_QUANTITY_RANGES'] = array();
3606 $element[
'ITEM_MEASURE_RATIOS'] = array();
3607 $element[
'ITEM_MEASURE'] = array();
3608 $element[
'ITEM_MEASURE_RATIO_SELECTED'] =
null;
3609 $element[
'ITEM_QUANTITY_RANGE_SELECTED'] =
null;
3610 $element[
'ITEM_PRICE_SELECTED'] =
null;
3612 if (!empty($catalog))
3614 if (!isset($this->productWithOffers[$iblockId]))
3615 $this->productWithOffers[$iblockId] = array();
3618 $this->productWithOffers[$iblockId][$id] = $id;
3619 if ($this->storage[
'SHOW_CATALOG_WITH_OFFERS'] && $enableCompatible)
3621 $this->productWithPrices[$id] = $id;
3622 $this->calculatePrices[$id] = $id;
3627 $element[
'PRODUCT'][
'TYPE'],
3636 $this->productWithPrices[$id] = $id;
3637 $this->calculatePrices[$id] = $id;
3640 if (isset($this->productWithPrices[$id]))
3642 if ($element[
'PRODUCT'][
'MEASURE'] > 0)
3644 $element[
'ITEM_MEASURE'] = array(
3645 'ID' => $element[
'PRODUCT'][
'MEASURE'],
3652 $element[
'ITEM_MEASURE'] = array(
3654 'TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'SYMBOL_RUS'],
3655 '~TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'~SYMBOL_RUS']
3658 if ($enableCompatible)
3660 $element[
'CATALOG_MEASURE'] = $element[
'ITEM_MEASURE'][
'ID'];
3661 $element[
'CATALOG_MEASURE_NAME'] = $element[
'ITEM_MEASURE'][
'TITLE'];
3662 $element[
'~CATALOG_MEASURE_NAME'] = $element[
'ITEM_MEASURE'][
'~TITLE'];
3668 $element[
'PRICES'] = \CIBlockPriceTools::GetItemPrices(
3669 $element[
'IBLOCK_ID'],
3670 $this->storage[
'PRICES'],
3672 $this->arParams[
'PRICE_VAT_INCLUDE'],
3673 $this->storage[
'CONVERT_CURRENCY']
3675 if (!empty($element[
'PRICES']))
3677 $element[
'MIN_PRICE'] = \CIBlockPriceTools::getMinPriceFromList($element[
'PRICES']);
3680 $element[
'CAN_BUY'] = !empty($element[
'PRICES']);
3708 if ($this->useCatalog && !empty($this->iblockProducts))
3712 $paramStack = array();
3714 if ($enableCompatible)
3716 $paramStack[
'USE_PRICE_COUNT'] = $this->arParams[
'USE_PRICE_COUNT'];
3717 $paramStack[
'SHOW_PRICE_COUNT'] = $this->arParams[
'SHOW_PRICE_COUNT'];
3718 $this->arParams[
'USE_PRICE_COUNT'] =
false;
3719 $this->arParams[
'SHOW_PRICE_COUNT'] = 1;
3722 foreach (array_keys($this->iblockProducts) as $iblock)
3724 if (!empty($this->productWithOffers[$iblock]))
3727 if (!empty($iblockOffers))
3729 $offersId = array_keys($iblockOffers);
3741 $offers = array_merge($offers, $iblockOffers);
3743 unset($iblockOffers);
3746 if ($enableCompatible)
3748 $this->arParams[
'USE_PRICE_COUNT'] = $paramStack[
'USE_PRICE_COUNT'];
3749 $this->arParams[
'SHOW_PRICE_COUNT'] = $paramStack[
'SHOW_PRICE_COUNT'];
3751 unset($enableCompatible, $paramStack);
3764 $iblockParams = $this->storage[
'IBLOCK_PARAMS'][$iblockId];
3771 && !empty($this->productWithOffers[$iblockId])
3774 $catalog = $this->storage[
'CATALOGS'][$iblockId];
3776 $productProperty =
'PROPERTY_'.$catalog[
'SKU_PROPERTY_ID'];
3777 $productPropertyValue = $productProperty.
'_VALUE';
3780 $offersFilter[$productProperty] = $this->productWithOffers[$iblockId];
3782 $offersSelect = array(
3786 $productProperty => 1,
3787 'PREVIEW_PICTURE' => 1,
3788 'DETAIL_PICTURE' => 1,
3791 if ($this->arParams[
'SHOW_SKU_DESCRIPTION'] ===
'Y')
3793 $offersSelect[
'PREVIEW_TEXT'] = 1;
3794 $offersSelect[
'DETAIL_TEXT'] = 1;
3795 $offersSelect[
'PREVIEW_TEXT_TYPE'] = 1;
3796 $offersSelect[
'DETAIL_TEXT_TYPE'] = 1;
3799 if (!empty($iblockParams[
'OFFERS_FIELD_CODE']))
3801 foreach ($iblockParams[
'OFFERS_FIELD_CODE'] as $code)
3802 $offersSelect[$code] = 1;
3806 $offersSelect = $this->
getProductSelect($iblockId, array_keys($offersSelect));
3809 $offersSelect = $getListParams[
'SELECT'];
3810 $offersFilter = $getListParams[
'FILTER'];
3811 $offersOrder = $getListParams[
'ORDER'];
3812 unset($getListParams);
3814 $checkFields = array();
3815 foreach (array_keys($offersOrder) as $code)
3817 $code = mb_strtoupper($code);
3818 if ($code ==
'ID' || $code ==
'AVAILABLE')
3820 $checkFields[] = $code;
3827 $offersId = array();
3828 $offersCount = array();
3829 $iterator = \CIBlockElement::GetList(
3836 while($row = $iterator->GetNext())
3838 $row[
'ID'] = (int)$row[
'ID'];
3839 $row[
'IBLOCK_ID'] = (int)$row[
'IBLOCK_ID'];
3840 $productId = (int)$row[$productPropertyValue];
3842 if ($productId <= 0)
3845 if ($enableCompatible && $this->arParams[
'OFFERS_LIMIT'] > 0)
3847 $offersCount[$productId]++;
3848 if($offersCount[$productId] > $this->arParams[
'OFFERS_LIMIT'])
3852 $row[
'SORT_HASH'] =
'ID';
3853 if (!empty($checkFields))
3856 foreach ($checkFields as $code)
3857 $checkValues .= ($row[$code] ??
'').
'|';
3859 if ($checkValues !=
'')
3860 $row[
'SORT_HASH'] = md5($checkValues);
3861 unset($checkValues);
3863 $row[
'LINK_ELEMENT_ID'] = $productId;
3864 $row[
'PROPERTIES'] = array();
3865 $row[
'DISPLAY_PROPERTIES'] = array();
3867 $row[
'PRODUCT'] = array(
3868 'TYPE' => (
int)$row[
'~TYPE'],
3869 'AVAILABLE' => $row[
'~AVAILABLE'],
3870 'BUNDLE' => $row[
'~BUNDLE'],
3871 'QUANTITY' => $row[
'~QUANTITY'],
3872 'QUANTITY_TRACE' => $row[
'~QUANTITY_TRACE'],
3873 'CAN_BUY_ZERO' => $row[
'~CAN_BUY_ZERO'],
3874 'MEASURE' => (
int)$row[
'~MEASURE'],
3875 'SUBSCRIBE' => $row[
'~SUBSCRIBE'],
3876 'VAT_ID' => (
int)$row[
'~VAT_ID'],
3878 'VAT_INCLUDED' => $row[
'~VAT_INCLUDED'],
3879 'WEIGHT' => (
float)$row[
'~WEIGHT'],
3880 'WIDTH' => (
float)$row[
'~WIDTH'],
3881 'LENGTH' => (
float)$row[
'~LENGTH'],
3882 'HEIGHT' => (
float)$row[
'~HEIGHT'],
3883 'PAYMENT_TYPE' => $row[
'~PAYMENT_TYPE'],
3884 'RECUR_SCHEME_TYPE' => $row[
'~RECUR_SCHEME_TYPE'],
3885 'RECUR_SCHEME_LENGTH' => (
int)$row[
'~RECUR_SCHEME_LENGTH'],
3886 'TRIAL_PRICE_ID' => (
int)$row[
'~TRIAL_PRICE_ID']
3891 if ($row[
'PRODUCT'][
'VAT_ID'] > 0)
3892 $vatId = $row[
'PRODUCT'][
'VAT_ID'];
3893 elseif ($this->storage[
'IBLOCKS_VAT'][$catalog[
'IBLOCK_ID']] > 0)
3894 $vatId = $this->storage[
'IBLOCKS_VAT'][$catalog[
'IBLOCK_ID']];
3895 if ($vatId > 0 && isset($this->storage[
'VATS'][$vatId]))
3896 $vatRate = $this->storage[
'VATS'][$vatId];
3897 $row[
'PRODUCT'][
'VAT_RATE'] = $vatRate;
3898 unset($vatRate, $vatId);
3900 if ($enableCompatible)
3902 foreach ($translateFields as $currentKey => $oldKey)
3903 $row[$oldKey] = $row[$currentKey];
3904 unset($currentKey, $oldKey);
3905 $row[
'~CATALOG_VAT'] = $row[
'PRODUCT'][
'VAT_RATE'];
3906 $row[
'CATALOG_VAT'] = $row[
'PRODUCT'][
'VAT_RATE'];
3911 $row[
'~CATALOG_TYPE'] = $row[
'PRODUCT'][
'TYPE'];
3912 $row[
'CATALOG_TYPE'] = $row[
'PRODUCT'][
'TYPE'];
3913 $row[
'~CATALOG_QUANTITY'] = $row[
'PRODUCT'][
'QUANTITY'];
3914 $row[
'CATALOG_QUANTITY'] = $row[
'PRODUCT'][
'QUANTITY'];
3915 $row[
'~CATALOG_QUANTITY_TRACE'] = $row[
'PRODUCT'][
'QUANTITY_TRACE'];
3916 $row[
'CATALOG_QUANTITY_TRACE'] = $row[
'PRODUCT'][
'QUANTITY_TRACE'];
3917 $row[
'~CATALOG_CAN_BUY_ZERO'] = $row[
'PRODUCT'][
'CAN_BUY_ZERO'];
3918 $row[
'CATALOG_CAN_BUY_ZERO'] = $row[
'PRODUCT'][
'CAN_BUY_ZERO'];
3919 $row[
'~CATALOG_SUBSCRIBE'] = $row[
'PRODUCT'][
'SUBSCRIBE'];
3920 $row[
'CATALOG_SUBSCRIBE'] = $row[
'PRODUCT'][
'SUBSCRIBE'];
3923 foreach ($productFields as $field)
3924 unset($row[$field], $row[
'~'.$field]);
3928 $this->calculatePrices[$row[
'ID']] = $row[
'ID'];
3930 $row[
'ITEM_PRICE_MODE'] =
null;
3931 $row[
'ITEM_PRICES'] = array();
3932 $row[
'ITEM_QUANTITY_RANGES'] = array();
3933 $row[
'ITEM_MEASURE_RATIOS'] = array();
3934 $row[
'ITEM_MEASURE'] = array();
3935 $row[
'ITEM_MEASURE_RATIO_SELECTED'] =
null;
3936 $row[
'ITEM_QUANTITY_RANGE_SELECTED'] =
null;
3937 $row[
'ITEM_PRICE_SELECTED'] =
null;
3940 if ($row[
'PRODUCT'][
'MEASURE'] > 0)
3942 $row[
'ITEM_MEASURE'] = array(
3943 'ID' => $row[
'PRODUCT'][
'MEASURE'],
3950 $row[
'ITEM_MEASURE'] = array(
3952 'TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'SYMBOL_RUS'],
3953 '~TITLE' => $this->storage[
'DEFAULT_MEASURE'][
'~SYMBOL_RUS']
3956 if ($enableCompatible)
3958 $row[
'CATALOG_MEASURE'] = $row[
'ITEM_MEASURE'][
'ID'];
3959 $row[
'CATALOG_MEASURE_NAME'] = $row[
'ITEM_MEASURE'][
'TITLE'];
3960 $row[
'~CATALOG_MEASURE_NAME'] = $row[
'ITEM_MEASURE'][
'~TITLE'];
3963 $row[
'PROPERTIES'] = array();
3964 $row[
'DISPLAY_PROPERTIES'] = array();
3966 Iblock\Component\Tools::getFieldImageData(
3968 array(
'PREVIEW_PICTURE',
'DETAIL_PICTURE'),
3969 Iblock\Component\Tools::IPROPERTY_ENTITY_ELEMENT,
3973 $offersId[$row[
'ID']] = $row[
'ID'];
3974 $offers[$row[
'ID']] = $row;
3976 unset($row, $iterator);
3978 if (!empty($offersId))
3980 $loadPropertyCodes = ($iblockParams[
'OFFERS_PROPERTY_CODE'] ?? []);
3981 if (
Iblock\Model\PropertyFeature::isEnabledFeatures())
3983 $loadPropertyCodes = array_merge($loadPropertyCodes, $iblockParams[
'OFFERS_TREE_PROPS'] ?? []);
3986 $propertyList = $this->
getPropertyList($catalog[
'IBLOCK_ID'], $loadPropertyCodes);
3987 unset($loadPropertyCodes);
3989 if (!empty($propertyList) || $this->useDiscountCache)
3991 \CIBlockElement::GetPropertyValuesArray($offers, $catalog[
'IBLOCK_ID'], $offersFilter);
3992 foreach ($offers as &$row)
3994 if ($this->useDiscountCache)
3996 if ($this->storage[
'USE_SALE_DISCOUNTS'])
3997 Catalog\Discount\DiscountManager::setProductPropertiesCache($row[
'ID'], $row[
"PROPERTIES"]);
3999 \CCatalogDiscount::SetProductPropertiesCache($row[
'ID'], $row[
"PROPERTIES"]);
4002 if (!empty($propertyList))
4004 foreach ($propertyList as $pid)
4006 if (!isset($row[
"PROPERTIES"][$pid]))
4008 $prop = &$row[
"PROPERTIES"][$pid];
4009 $boolArr = is_array($prop[
"VALUE"]);
4011 ($boolArr && !empty($prop[
"VALUE"])) ||
4012 (!$boolArr && (
string)$prop[
"VALUE"] !==
'')
4015 $row[
"DISPLAY_PROPERTIES"][$pid] = \CIBlockFormatProperties::GetDisplayValue($row, $prop);
4017 unset($boolArr, $prop);
4024 if (!empty($propertyList))
4026 \CIBlockFormatProperties::clearCache();
4029 if ($this->useDiscountCache)
4031 if ($this->storage[
'USE_SALE_DISCOUNTS'])
4033 Catalog\Discount\DiscountManager::preloadPriceData($offersId, $this->storage[
'PRICES_ALLOW']);
4034 Catalog\Discount\DiscountManager::preloadProductDataToExtendOrder($offersId, $this->
getUserGroups());
4038 \CCatalogDiscount::SetProductSectionsCache($offersId);
4039 \CCatalogDiscount::SetDiscountProductCache($offersId, array(
'IBLOCK_ID' => $catalog[
'IBLOCK_ID'],
'GET_BY_ID' =>
'Y'));
4051 $offersFilter = array(
4052 'IBLOCK_ID' => $iblockId,
4054 'ACTIVE_DATE' =>
'Y',
4055 'CHECK_PERMISSIONS' =>
'N'
4058 if ($this->arParams[
'HIDE_NOT_AVAILABLE_OFFERS'] ===
'Y')
4060 $offersFilter[
'AVAILABLE'] =
'Y';
4062 elseif ($this->arParams[
'HIDE_NOT_AVAILABLE_OFFERS'] ===
'L')
4064 $offersFilter[
'CUSTOM_FILTER'] = array(
4071 if (!$this->arParams[
'USE_PRICE_COUNT'])
4073 $offersFilter[
'SHOW_PRICE_COUNT'] = $this->arParams[
'SHOW_PRICE_COUNT'];
4076 return $offersFilter;
4086 $offersOrder = array(
4087 mb_strtoupper($this->arParams[
'OFFERS_SORT_FIELD']) => $this->arParams[
'OFFERS_SORT_ORDER'],
4088 mb_strtoupper($this->arParams[
'OFFERS_SORT_FIELD2']) => $this->arParams[
'OFFERS_SORT_ORDER2']
4090 if (!isset($offersOrder[
'ID']))
4091 $offersOrder[
'ID'] =
'DESC';
4093 return $offersOrder;
4100 foreach ($offers as &$offer)
4102 $elementId = $offer[
'LINK_ELEMENT_ID'];
4104 if (!isset($this->elementLinks[$elementId]))
4107 $offer[
'CAN_BUY'] = $this->elementLinks[$elementId][
'ACTIVE'] ===
'Y' && $offer[
'CAN_BUY'];
4109 $this->elementLinks[$elementId][
'OFFERS'][] = $offer;
4111 unset($elementId, $offer);
4120 $this->arParams[
'CONVERT_CURRENCY'] ===
'Y'
4121 && !empty($this->storage[
'CURRENCY_LIST'])
4122 && defined(
'BX_COMP_MANAGED_CACHE')
4125 $this->storage[
'CURRENCY_LIST'][$this->storage[
'CONVERT_CURRENCY'][
'CURRENCY_ID']] = $this->storage[
'CONVERT_CURRENCY'][
'CURRENCY_ID'];
4126 $taggedCache = Main\Application::getInstance()->getTaggedCache();
4127 foreach ($this->storage[
'CURRENCY_LIST'] as $oneCurrency)
4129 $taggedCache->registerTag(
'currency_id_'.$oneCurrency);
4132 unset($oneCurrency);
4133 unset($taggedCache);
4136 unset($this->storage[
'CURRENCY_LIST']);
4181 if (!empty($this->iblockProducts))
4184 $iblockIterator = Iblock\IblockSiteTable::getList(array(
4185 'select' => array(
'IBLOCK_ID'),
4187 '=IBLOCK_ID' => array_keys($this->iblockProducts),
4188 '=SITE_ID' => $this->getSiteId(),
4189 '=IBLOCK.ACTIVE' =>
'Y'
4192 while ($iblock = $iblockIterator->fetch())
4194 $iblocks[$iblock[
'IBLOCK_ID']] =
true;
4197 foreach ($this->iblockProducts as $iblock => $products)
4199 if (!isset($iblocks[$iblock]))
4201 unset($this->iblockProducts[$iblock]);
4205 if (empty($this->iblockProducts))
4207 $this->abortResultCache();
4208 $this->errorCollection->setError(
new Error(
Loc::getMessage(
'INVALID_IBLOCK'), self::ERROR_TEXT));
4225 if (!empty($this->productIds) && is_array($this->productIds))
4227 foreach ($this->productIds as $productId)
4230 if ($this->productIdMap[$productId] == $productId)
4235 if (isset($this->elementLinks[$this->productIdMap[$productId]]) && !empty($this->elementLinks[$this->productIdMap[$productId]][
'OFFERS']))
4238 foreach ($this->elementLinks[$this->productIdMap[$productId]][
'OFFERS'] as $key => $offer)
4240 if ($offer[
'ID'] != $productId)
4242 unset($this->elementLinks[$this->productIdMap[$productId]][
'OFFERS'][$key]);
4255 $this->arResult = array_merge($this->arResult, $this->storage[
'URLS']);
4256 $this->arResult[
'CONVERT_CURRENCY'] = $this->storage[
'CONVERT_CURRENCY'];
4257 $this->arResult[
'CATALOGS'] = $this->storage[
'CATALOGS'];
4258 $this->arResult[
'MODULES'] = $this->storage[
'MODULES'];
4259 $this->arResult[
'PRICES_ALLOW'] = $this->storage[
'PRICES_ALLOW'];
4263 if ($this->arParams[
'IBLOCK_ID'] > 0)
4265 $this->arResult[
'CATALOG'] =
false;
4268 !empty($this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']])
4269 && is_array($this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']])
4272 $this->arResult[
'CATALOG'] = $this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']];
4283 global $APPLICATION;
4285 if ($this->request->get($this->arParams[
'ACTION_VARIABLE'].self::ACTION_BUY) !==
null)
4287 $action = self::ACTION_BUY;
4289 elseif ($this->request->get($this->arParams[
'ACTION_VARIABLE'].self::ACTION_ADD_TO_BASKET))
4291 $action = self::ACTION_ADD_TO_BASKET;
4295 $action = mb_strtoupper($this->request->get($this->arParams[
'ACTION_VARIABLE']));
4298 $productId = (int)$this->request->get($this->arParams[
'PRODUCT_ID_VARIABLE']);
4301 ($action == self::ACTION_ADD_TO_BASKET || $action == self::ACTION_BUY || $action == self::ACTION_SUBSCRIBE)
4302 && Loader::includeModule(
'sale')
4303 && Loader::includeModule(
'catalog')
4306 $addByAjax = $this->request->get(
'ajax_basket') ===
'Y';
4309 $this->request->set(Main\Text\Encoding::convertEncoding($this->request->toArray(),
'UTF-8', SITE_CHARSET));
4326 'STATUS' =>
'ERROR',
4327 'MESSAGE' => $errorMsg
4331 $APPLICATION->RestartBuffer();
4332 header(
'Content-Type: application/json');
4333 \CMain::FinalActions(Main\Web\Json::encode($addResult));
4339 $pathRedirect = $action == self::ACTION_BUY
4340 ? $this->arParams[
'BASKET_URL']
4341 : $APPLICATION->GetCurPageParam(
'', array(
4342 $this->arParams[
'PRODUCT_ID_VARIABLE'],
4343 $this->arParams[
'ACTION_VARIABLE'],
4344 $this->arParams[
'PRODUCT_QUANTITY_VARIABLE'],
4345 $this->arParams[
'PRODUCT_PROPS_VARIABLE']
4348 LocalRedirect($pathRedirect);
4352 $this->errorCollection->setError(
new Error($errorMsg, self::ERROR_TEXT));
4360 $successfulAdd =
true;
4363 if (!empty($productId) && ($sectionId > 0 || !empty($sectionCode)))
4367 if (!empty($productsMap[$productId]))
4369 $sectionId = (int)$sectionId;
4370 $sectionCode = (string)$sectionCode;
4372 $filter = [
'ID' => $productsMap[$productId]];
4377 $filter[
'SECTION_ID'] = $sectionId;
4378 $filter[
'INCLUDE_SUBSECTIONS'] =
'Y';
4379 $elementIterator = \CIBlockElement::GetList(array(), $filter,
false,
false, array(
'ID'));
4380 $element = $elementIterator->Fetch();
4381 unset($elementIterator);
4383 elseif ($sectionCode !=
'')
4385 $iblockId = (int)\CIBlockElement::GetIBlockByID($productsMap[$productId]);
4388 $sectionIterator = \CIBlockSection::GetList(
4390 [
'IBLOCK_ID' => $iblockId,
'=CODE' => $sectionCode],
4394 $section = $sectionIterator->Fetch();
4395 unset($sectionIterator);
4396 if (!empty($section))
4398 $filter[
'SECTION_ID'] = (int)$section[
'ID'];
4399 $filter[
'INCLUDE_SUBSECTIONS'] =
'Y';
4400 $elementIterator = \CIBlockElement::GetList(array(), $filter,
false,
false, array(
'ID'));
4401 $element = $elementIterator->Fetch();
4402 unset($elementIterator);
4409 if (empty($element))
4411 $successfulAdd =
false;
4417 return [$successfulAdd, $errorMsg];
4428 global $APPLICATION;
4430 $successfulAdd =
true;
4434 $productProperties = array();
4436 $productId = (int)$productId;
4437 if ($productId <= 0)
4440 $successfulAdd =
false;
4446 if (empty($product))
4449 $successfulAdd =
false;
4454 if ($this->arParams[
'CHECK_LANDING_PRODUCT_SECTION'])
4457 $productId, $this->arParams[
'SECTION_ID'], $this->arParams[
'SECTION_CODE']
4466 $successfulAdd =
false;
4471 if ($this->arParams[
'ADD_PROPERTIES_TO_BASKET'] ===
'Y')
4474 $iblockParams = $this->storage[
'IBLOCK_PARAMS'][$product[
'PRODUCT_IBLOCK_ID']];
4477 $skuAddProps = $this->request->get(
'basket_props') ?:
'';
4478 if (!empty($iblockParams[
'OFFERS_CART_PROPERTIES']) || !empty($skuAddProps))
4480 $productProperties = \CIBlockPriceTools::GetOfferProperties(
4482 $product[
'PRODUCT_IBLOCK_ID'],
4483 $iblockParams[
'OFFERS_CART_PROPERTIES'],
4487 unset($skuAddProps);
4491 if (!empty($iblockParams[
'CART_PROPERTIES']))
4493 $productPropsVar = $this->request->get($this->arParams[
'PRODUCT_PROPS_VARIABLE']);
4494 if (is_array($productPropsVar))
4496 $productProperties = \CIBlockPriceTools::CheckProductProperties(
4497 $product[
'PRODUCT_IBLOCK_ID'],
4499 $iblockParams[
'CART_PROPERTIES'],
4501 $this->arParams[
'PARTIAL_PRODUCT_PROPERTIES'] ===
'Y'
4503 if (!is_array($productProperties))
4505 $errorMsg =
Loc::getMessage(
'CATALOG_PARTIAL_BASKET_PROPERTIES_ERROR');
4506 $successfulAdd =
false;
4511 if ($this->arParams[
'PARTIAL_PRODUCT_PROPERTIES'] !==
'Y')
4514 $successfulAdd =
false;
4517 unset($productPropsVar);
4520 unset($iblockParams);
4526 if ($this->arParams[
'USE_PRODUCT_QUANTITY'])
4528 $quantity = (float)$this->request->get($this->arParams[
'PRODUCT_QUANTITY_VARIABLE']);
4533 $ratioIterator = \CCatalogMeasureRatio::getList(
4535 array(
'PRODUCT_ID' => $productId),
4538 array(
'PRODUCT_ID',
'RATIO')
4540 if ($ratio = $ratioIterator->Fetch())
4542 $intRatio = (int)$ratio[
'RATIO'];
4543 $floatRatio = (float)$ratio[
'RATIO'];
4544 $quantity = $floatRatio > $intRatio ? $floatRatio : $intRatio;
4557 if (isset($rewriteFields[
'SUBSCRIBE']) && $rewriteFields[
'SUBSCRIBE'] ==
'Y')
4559 if (!SubscribeProduct($productId, $rewriteFields, $productProperties))
4561 if ($ex = $APPLICATION->GetException())
4563 $errorMsg = $ex->GetString();
4570 $successfulAdd =
false;
4576 'PRODUCT_ID' => $productId,
4577 'QUANTITY' => $quantity
4579 if (!empty($productProperties))
4581 $product[
'PROPS'] = $productProperties;
4584 $basketResult = Catalog\Product\Basket::addProduct($product, $rewriteFields, [
4587 if (!$basketResult->isSuccess())
4589 $errorMsg = implode(
'; ', $basketResult->getErrorMessages());
4590 $successfulAdd =
false;
4592 unset($basketResult);
4596 return array($successfulAdd, $errorMsg);
4608 return ($this->arParams[
'USE_MERGE_WHEN_ADD_PRODUCT_TO_BASKET'] ??
'Y') !==
'N';
4613 $rewriteFields = [];
4615 if ($action === self::ACTION_ADD_TO_BASKET || $action === self::ACTION_BUY)
4617 $rewriteFields[
'DELAY'] =
'N';
4620 if ($action == self::ACTION_SUBSCRIBE)
4622 $notify = unserialize(Main\
Config\Option::get(
'sale',
'subscribe_prod',
''), [
'allowed_classes' =>
false]);
4623 if (!empty($notify[$this->getSiteId()]) && $notify[$this->getSiteId()][
'use'] ===
'Y')
4625 $rewriteFields[
'SUBSCRIBE'] =
'Y';
4626 $rewriteFields[
'CAN_BUY'] =
'N';
4630 return $rewriteFields;
4642 if (empty($this->productIds))
4644 static::sendJsonAnswer();
4660 if (empty($this->productIds))
4662 static::sendJsonAnswer();
4674 $lastUsage = Main\Config\Option::get(
'main',
'rcm_component_usage', 0);
4676 if ($lastUsage == 0 || (time() - $lastUsage) > 3600)
4678 Main\Config\Option::set(
'main',
'rcm_component_usage', time());
4705 $this->initComponentTemplate();
4710 $this->includeComponentTemplate();
4732 $emptyPreview =
false;
4733 $documentRoot = Main\Application::getDocumentRoot();
4734 $emptyPreviewPath = $this->getTemplate()->GetFolder().
'/images/no_photo.png';
4736 $file =
new Main\IO\File($documentRoot.$emptyPreviewPath);
4737 if ($file->isExists())
4739 $size = getimagesize($documentRoot.$emptyPreviewPath);
4742 $emptyPreview = array(
4744 'SRC' => $emptyPreviewPath,
4745 'FILE_NAME' =>
'no_photo.png',
4746 'WIDTH' => (
int)$size[0],
4747 'HEIGHT' => (
int)$size[1]
4752 return $emptyPreview;
4759 while (!empty($items))
4761 $rows[] = array_splice($items, 0, $this->arParams[
'LINE_ELEMENT_COUNT']);
4769 $currencies = array();
4771 if ($this->arResult[
'MODULES'][
'currency'])
4773 if (isset($this->arResult[
'CONVERT_CURRENCY'][
'CURRENCY_ID']))
4775 $currencyFormat = \CCurrencyLang::GetFormatDescription($this->arResult[
'CONVERT_CURRENCY'][
'CURRENCY_ID']);
4776 $currencies = array(
4778 'CURRENCY' => $this->arResult[
'CONVERT_CURRENCY'][
'CURRENCY_ID'],
4780 'FORMAT_STRING' => $currencyFormat[
'FORMAT_STRING'],
4781 'DEC_POINT' => $currencyFormat[
'DEC_POINT'],
4782 'THOUSANDS_SEP' => $currencyFormat[
'THOUSANDS_SEP'],
4783 'DECIMALS' => $currencyFormat[
'DECIMALS'],
4784 'THOUSANDS_VARIANT' => $currencyFormat[
'THOUSANDS_VARIANT'],
4785 'HIDE_ZERO' => $currencyFormat[
'HIDE_ZERO']
4789 unset($currencyFormat);
4793 $currencyIterator = Currency\CurrencyTable::getList(array(
4794 'select' => array(
'CURRENCY')
4796 while ($currency = $currencyIterator->fetch())
4798 $currencyFormat = \CCurrencyLang::GetFormatDescription($currency[
'CURRENCY']);
4799 $currencies[] = array(
4800 'CURRENCY' => $currency[
'CURRENCY'],
4802 'FORMAT_STRING' => $currencyFormat[
'FORMAT_STRING'],
4803 'DEC_POINT' => $currencyFormat[
'DEC_POINT'],
4804 'THOUSANDS_SEP' => $currencyFormat[
'THOUSANDS_SEP'],
4805 'DECIMALS' => $currencyFormat[
'DECIMALS'],
4806 'THOUSANDS_VARIANT' => $currencyFormat[
'THOUSANDS_VARIANT'],
4807 'HIDE_ZERO' => $currencyFormat[
'HIDE_ZERO']
4811 unset($currencyFormat, $currency, $currencyIterator);
4825 global $APPLICATION;
4827 if (!empty($result))
4829 $result[
'JS'] = Main\Page\Asset::getInstance()->getJs();
4832 $APPLICATION->RestartBuffer();
4835 echo Main\Web\Json::encode($result);
4836 \CMain::FinalActions();
4849 $this->request->get($this->arParams[
'ACTION_VARIABLE']) !==
null
4850 && $this->request->get($this->arParams[
'PRODUCT_ID_VARIABLE']) !==
null
4853 $action =
'processLink';
4855 elseif ($this->request->isAjaxRequest() && $this->request->get(
'action') ===
'deferredLoad')
4857 $action = $this->request->get(
'bigData') ===
'Y' ?
'bigDataLoad' :
'deferredLoad';
4861 $action =
'initialLoad';
4874 if (is_callable(array($this, $action.
'Action')))
4876 call_user_func(array($this, $action.
'Action'));
4889 return $this->processErrors();
4898 return $this->processErrors();
4901 return $this->arResult[
'ID'] ??
false;
4910 return $this->arParams;
4915 $params =& $this->arParams;
4917 $params = array_merge($defaultParams, $params);
4919 $params[
'SHOW_OLD_PRICE'] = $params[
'SHOW_OLD_PRICE'] ===
'Y' ?
'Y' :
'N';
4920 $params[
'SHOW_CLOSE_POPUP'] = $params[
'SHOW_CLOSE_POPUP'] ===
'Y' ?
'Y' :
'N';
4921 $params[
'SHOW_DISCOUNT_PERCENT'] = $params[
'SHOW_DISCOUNT_PERCENT'] ===
'Y' ?
'Y' :
'N';
4922 $params[
'DISCOUNT_PERCENT_POSITION'] = trim($params[
'DISCOUNT_PERCENT_POSITION']) ?:
'bottom-right';
4923 $params[
'LABEL_PROP_POSITION'] = trim($params[
'LABEL_PROP_POSITION']) ?:
'top-left';
4924 $params[
'PRODUCT_SUBSCRIPTION'] = $params[
'PRODUCT_SUBSCRIPTION'] ===
'N' ?
'N' :
'Y';
4925 $params[
'MESS_BTN_BUY'] = trim($params[
'MESS_BTN_BUY']);
4926 $params[
'MESS_BTN_ADD_TO_BASKET'] = trim($params[
'MESS_BTN_ADD_TO_BASKET']);
4927 $params[
'MESS_BTN_SUBSCRIBE'] = trim($params[
'MESS_BTN_SUBSCRIBE']);
4928 $params[
'MESS_BTN_DETAIL'] = trim($params[
'MESS_BTN_DETAIL']);
4929 $params[
'MESS_NOT_AVAILABLE'] = trim($params[
'MESS_NOT_AVAILABLE']);
4930 $params[
'MESS_BTN_COMPARE'] = trim($params[
'MESS_BTN_COMPARE']);
4931 $params[
'SHOW_SLIDER'] = $params[
'SHOW_SLIDER'] ===
'N' ?
'N' :
'Y';
4932 $params[
'SLIDER_INTERVAL'] = (int)$params[
'SLIDER_INTERVAL'] ?: 5000;
4933 $params[
'SLIDER_PROGRESS'] = $params[
'SLIDER_PROGRESS'] ===
'Y' ?
'Y' :
'N';
4934 $params[
'USE_ENHANCED_ECOMMERCE'] = $params[
'USE_ENHANCED_ECOMMERCE'] ===
'Y' ?
'Y' :
'N';
4935 $params[
'DATA_LAYER_NAME'] = trim($params[
'DATA_LAYER_NAME']);
4936 $params[
'BRAND_PROPERTY'] = $params[
'BRAND_PROPERTY'] !==
'-' ? trim($params[
'BRAND_PROPERTY']) :
'';
4938 if (!isset($params[
'SHOW_MAX_QUANTITY']) || !in_array($params[
'SHOW_MAX_QUANTITY'], array(
'Y',
'M',
'N')))
4940 $params[
'SHOW_MAX_QUANTITY'] =
'N';
4943 $params[
'RELATIVE_QUANTITY_FACTOR'] = (int)($params[
'RELATIVE_QUANTITY_FACTOR'] ?? 0) > 0 ? (int)$params[
'RELATIVE_QUANTITY_FACTOR'] : 5;
4949 'TEMPLATE_THEME' =>
'blue',
4950 'SHOW_MAX_QUANTITY' =>
'N',
4951 'SHOW_OLD_PRICE' =>
'N',
4952 'SHOW_CLOSE_POPUP' =>
'N',
4953 'SHOW_DISCOUNT_PERCENT' =>
'N',
4954 'DISCOUNT_PERCENT_POSITION' =>
'bottom-right',
4955 'LABEL_PROP' => array(),
4956 'LABEL_PROP_MOBILE' => array(),
4957 'LABEL_PROP_POSITION' =>
'top-left',
4958 'PRODUCT_SUBSCRIPTION' =>
'Y',
4959 'MESS_BTN_BUY' =>
'',
4960 'MESS_BTN_ADD_TO_BASKET' =>
'',
4961 'MESS_BTN_SUBSCRIBE' =>
'',
4962 'MESS_BTN_DETAIL' =>
'',
4963 'MESS_NOT_AVAILABLE' =>
'',
4964 'MESS_BTN_COMPARE' =>
'',
4965 'SHOW_SLIDER' =>
'N',
4966 'SLIDER_INTERVAL' => 5000,
4967 'SLIDER_PROGRESS' =>
'N',
4968 'USE_ENHANCED_ECOMMERCE' =>
'N',
4969 'DATA_LAYER_NAME' =>
'dataLayer',
4970 'BRAND_PROPERTY' =>
''
4976 $theme =& $this->arParams[
'TEMPLATE_THEME'];
4977 $theme = (string)$theme;
4981 $theme = preg_replace(
'/[^a-zA-Z0-9_\-\(\)\!]/',
'', $theme);
4982 if ($theme ===
'site')
4984 $siteId = $this->getSiteId();
4985 $templateId = Main\Config\Option::get(
'main',
'wizard_template_id',
'eshop_bootstrap', $siteId);
4986 $templateId = preg_match(
'/^eshop_adapt/', $templateId) ?
'eshop_adapt' : $templateId;
4987 $theme = Main\Config\Option::get(
'main',
'wizard_'.$templateId.
'_theme_id',
'blue', $siteId);
4992 $documentRoot = Main\Application::getDocumentRoot();
4993 $templateFolder = $this->getTemplate()->GetFolder();
4995 $themesFolder =
new Main\IO\Directory($documentRoot.$templateFolder.
'/themes/');
4997 if ($themesFolder->isExists())
4999 $file =
new Main\IO\File($documentRoot.$templateFolder.
'/themes/'.$theme.
'/style.css');
5001 if (!$file->isExists())
5022 if (!empty($item) && is_array($item))
5024 $item[
'ENLARGED'] =
'N';
5025 $propertyCode = (string)$propertyCode;
5027 if ($propertyCode !==
'' && isset($item[
'PROPERTIES'][$propertyCode]))
5029 $prop = $item[
'PROPERTIES'][$propertyCode];
5030 if (!empty($prop[
'VALUE']))
5032 $item[
'ENLARGED'] =
'Y';
5040 $propCode = $this->storage[
'IBLOCK_PARAMS'][$iblock][
'ADD_PICT_PROP'];
5042 $slider = \CIBlockPriceTools::getSliderForItem($item, $propCode, $addDetailToSlider);
5050 $slider = array_slice($slider, 0, $limit);
5053 $item[
'SHOW_SLIDER'] =
true;
5054 $item[
'MORE_PHOTO'] = $slider;
5055 $item[
'MORE_PHOTO_COUNT'] = count($slider);
5060 $propCode = $this->storage[
'IBLOCK_PARAMS'][$iblock][
'OFFERS_ADD_PICT_PROP'];
5062 $slider = \CIBlockPriceTools::getSliderForItem($item, $propCode, $addDetailToSlider);
5070 $slider = array_slice($slider, 0, $limit);
5073 $item[
'MORE_PHOTO'] = $slider;
5074 $item[
'MORE_PHOTO_COUNT'] = count($slider);
5079 if ($this->arResult[
'MODULES'][
'catalog'])
5081 $item[
'CATALOG'] =
true;
5083 $item[
'CATALOG_TYPE'] = $item[
'PRODUCT'][
'TYPE'];
5088 $item[
'CATALOG_TYPE'] = 0;
5089 $item[
'OFFERS'] = array();
5097 'SORT' => PHP_INT_MAX,
5101 if (isset($offer[
'DISPLAY_PROPERTIES'][$code]))
5103 $matrixFields[$code] =
true;
5104 $cell[
'NA'] =
false;
5106 if ($skuPropList[$code][
'USER_TYPE'] ===
'directory')
5108 $intValue = $skuPropList[$code][
'XML_MAP'][$offer[
'DISPLAY_PROPERTIES'][$code][
'VALUE']];
5109 $cell[
'VALUE'] = $intValue;
5111 elseif ($skuPropList[$code][
'PROPERTY_TYPE'] ===
'L')
5113 $cell[
'VALUE'] = (int)$offer[
'DISPLAY_PROPERTIES'][$code][
'VALUE_ENUM_ID'];
5115 elseif ($skuPropList[$code][
'PROPERTY_TYPE'] ===
'E')
5117 $cell[
'VALUE'] = (int)$offer[
'DISPLAY_PROPERTIES'][$code][
'VALUE'];
5120 $cell[
'SORT'] = $skuPropList[$code][
'VALUES'][$cell[
'VALUE']][
'SORT'];
5128 if (!$this->useCatalog)
5130 if (!isset($this->storage[
'CATALOGS'][$iblockId]))
5133 $this->storage[
'CATALOGS'][$iblockId][
'CATALOG_TYPE'] != \CCatalogSku::TYPE_PRODUCT
5134 && $this->storage[
'CATALOGS'][$iblockId][
'CATALOG_TYPE'] != \CCatalogSku::TYPE_FULL
5137 return $this->storage[
'CATALOGS'][$iblockId][
'IBLOCK_ID'];
5151 if (!$this->useCatalog)
5153 if (!isset($this->storage[
'CATALOGS'][$iblockId]))
5156 switch ($this->storage[
'CATALOGS'][$iblockId][
'CATALOG_TYPE'])
5158 case \CCatalogSku::TYPE_CATALOG:
5159 $list = Catalog\Product\PropertyCatalogFeature::getBasketPropertyCodes(
5165 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'CART_PROPERTIES'] = $list;
5167 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'OFFERS_CART_PROPERTIES'] = [];
5169 case \CCatalogSku::TYPE_PRODUCT:
5170 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'CART_PROPERTIES'] = [];
5171 $list = Catalog\Product\PropertyCatalogFeature::getBasketPropertyCodes(
5177 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'OFFERS_CART_PROPERTIES'] = $list;
5180 case \CCatalogSku::TYPE_FULL:
5181 $list = Catalog\Product\PropertyCatalogFeature::getBasketPropertyCodes(
5187 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'CART_PROPERTIES'] = $list;
5188 $list = Catalog\Product\PropertyCatalogFeature::getBasketPropertyCodes(
5194 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'OFFERS_CART_PROPERTIES'] = $list;
5197 case \CCatalogSku::TYPE_OFFERS:
5198 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'CART_PROPERTIES'] = [];
5199 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'OFFERS_CART_PROPERTIES'] = [];
5208 if (!$this->useCatalog)
5210 if (!isset($this->storage[
'CATALOGS'][$iblockId]))
5213 switch ($this->storage[
'CATALOGS'][$iblockId][
'CATALOG_TYPE'])
5215 case \CCatalogSku::TYPE_CATALOG:
5216 case \CCatalogSku::TYPE_OFFERS:
5217 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'OFFERS_TREE_PROPS'] = [];
5219 case \CCatalogSku::TYPE_PRODUCT:
5220 case \CCatalogSku::TYPE_FULL:
5221 $list = Catalog\Product\PropertyCatalogFeature::getOfferTreePropertyCodes(
5222 $this->storage[
'CATALOGS'][$iblockId][
'IBLOCK_ID'],
5227 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'OFFERS_TREE_PROPS'] = $list;
5265 if (isset($USER) && $USER instanceof \CUser)
5267 $result = $USER->GetUserGroupArray();
5268 Main\Type\Collection::normalizeArrayValuesByInt($result,
true);
5299 $initFields = array(
5300 'PRICES' => array(),
5301 'PRICE_MATRIX' =>
false,
5302 'MIN_PRICE' =>
false
5304 if (!$this->arParams[
'USE_PRICE_COUNT'] && !empty($this->storage[
'PRICES']))
5306 foreach ($this->storage[
'PRICES'] as $value)
5308 if (!$value[
'CAN_VIEW'] && !$value[
'CAN_BUY'])
5311 $priceType = $value[
'ID'];
5312 $initFields[
'CATALOG_GROUP_ID_'.$priceType] = $priceType;
5313 $initFields[
'~CATALOG_GROUP_ID_'.$priceType] = $priceType;
5314 $initFields[
'CATALOG_GROUP_NAME_'.$priceType] = $value[
'TITLE'];
5315 $initFields[
'~CATALOG_GROUP_NAME_'.$priceType] = $value[
'~TITLE'];
5316 $initFields[
'CATALOG_CAN_ACCESS_'.$priceType] = ($value[
'CAN_VIEW'] ?
'Y' :
'N');
5317 $initFields[
'~CATALOG_CAN_ACCESS_'.$priceType] = ($value[
'CAN_VIEW'] ?
'Y' :
'N');
5318 $initFields[
'CATALOG_CAN_BUY_'.$priceType] = ($value[
'CAN_BUY'] ?
'Y' :
'N');
5319 $initFields[
'~CATALOG_CAN_BUY_'.$priceType] = ($value[
'CAN_BUY'] ?
'Y' :
'N');
5320 $initFields[
'CATALOG_PRICE_ID_'.$priceType] =
null;
5321 $initFields[
'~CATALOG_PRICE_ID_'.$priceType] =
null;
5322 $initFields[
'CATALOG_PRICE_'.$priceType] =
null;
5323 $initFields[
'~CATALOG_PRICE_'.$priceType] =
null;
5324 $initFields[
'CATALOG_CURRENCY_'.$priceType] =
null;
5325 $initFields[
'~CATALOG_CURRENCY_'.$priceType] =
null;
5326 $initFields[
'CATALOG_QUANTITY_FROM_'.$priceType] =
null;
5327 $initFields[
'~CATALOG_QUANTITY_FROM_'.$priceType] =
null;
5328 $initFields[
'CATALOG_QUANTITY_TO_'.$priceType] =
null;
5329 $initFields[
'~CATALOG_QUANTITY_TO_'.$priceType] =
null;
5330 $initFields[
'CATALOG_EXTRA_ID_'.$priceType] =
null;
5331 $initFields[
'~CATALOG_EXTRA_ID_'.$priceType] =
null;
5337 foreach (array_keys($items) as $index)
5338 $this->oldData[$items[$index][
'ID']] = $initFields;
5339 unset($index, $initFields);
5352 if (!isset($this->oldData[$id]) || empty($prices) || $this->arParams[
'USE_PRICE_COUNT'])
5354 foreach ($prices as $rawPrice)
5356 $priceType = $rawPrice[
'CATALOG_GROUP_ID'];
5357 $this->oldData[$id][
'CATALOG_PRICE_ID_'.$priceType] = $rawPrice[
'ID'];
5358 $this->oldData[$id][
'~CATALOG_PRICE_ID_'.$priceType] = $rawPrice[
'ID'];
5359 $this->oldData[$id][
'CATALOG_PRICE_'.$priceType] = $rawPrice[
'PRICE'];
5360 $this->oldData[$id][
'~CATALOG_PRICE_'.$priceType] = $rawPrice[
'PRICE'];
5361 $this->oldData[$id][
'CATALOG_CURRENCY_'.$priceType] = $rawPrice[
'CURRENCY'];
5362 $this->oldData[$id][
'~CATALOG_CURRENCY_'.$priceType] = $rawPrice[
'CURRENCY'];
5363 $this->oldData[$id][
'CATALOG_QUANTITY_FROM_'.$priceType] = $rawPrice[
'QUANTITY_FROM'];
5364 $this->oldData[$id][
'~CATALOG_QUANTITY_FROM_'.$priceType] = $rawPrice[
'QUANTITY_FROM'];
5365 $this->oldData[$id][
'CATALOG_QUANTITY_TO_'.$priceType] = $rawPrice[
'QUANTITY_TO'];
5366 $this->oldData[$id][
'~CATALOG_QUANTITY_TO_'.$priceType] = $rawPrice[
'QUANTITY_TO'];
5367 $this->oldData[$id][
'CATALOG_EXTRA_ID_'.$priceType] = $rawPrice[
'EXTRA_ID'];
5368 $this->oldData[$id][
'~CATALOG_EXTRA_ID_'.$priceType] = $rawPrice[
'EXTRA_ID'];
5384 if (!isset($this->oldData[$id]))
5386 return ($this->oldData[$id][$field] ??
null);
5399 ($row[
'QUANTITY_FROM'] ===
null || $row[
'QUANTITY_FROM'] <= $this->arParams[
'SHOW_PRICE_COUNT'])
5400 && ($row[
'QUANTITY_TO'] ===
null || $row[
'QUANTITY_TO'] >= $this->arParams[
'SHOW_PRICE_COUNT'])
5414 'MATRIX' => array(),
5415 'CAN_BUY' => array(),
5417 'CURRENCY_LIST' => array()
5428 private function resortOldPrices($id)
5430 if (empty($this->oldData[$id][
'PRICES']) || count($this->oldData[$id][
'PRICES']) < 2)
5432 foreach (array_keys($this->oldData[$id][
'PRICES']) as $priceCode)
5433 $this->oldData[$id][
'PRICES'][$priceCode][
'_SORT'] = $this->storage[
'PRICES'][$priceCode][
'SORT'];
5435 Main\Type\Collection::sortByColumn(
5436 $this->oldData[$id][
'PRICES'],
5437 array(
'_SORT' => SORT_ASC,
'PRICE_ID' => SORT_ASC),
5440 foreach (array_keys($this->oldData[$id][
'PRICES']) as $priceCode)
5441 unset($this->oldData[$id][
'PRICES'][$priceCode][
'_SORT']);
5453 'TYPE' =>
'CATALOG_TYPE',
5454 'AVAILABLE' =>
'CATALOG_AVAILABLE',
5455 'BUNDLE' =>
'CATALOG_BUNDLE',
5456 'QUANTITY' =>
'CATALOG_QUANTITY',
5457 'QUANTITY_TRACE' =>
'CATALOG_QUANTITY_TRACE',
5458 'CAN_BUY_ZERO' =>
'CATALOG_CAN_BUY_ZERO',
5459 'MEASURE' =>
'CATALOG_MEASURE',
5460 'SUBSCRIBE' =>
'CATALOG_SUBSCRIBE',
5461 'VAT_ID' =>
'CATALOG_VAT_ID',
5462 'VAT_INCLUDED' =>
'CATALOG_VAT_INCLUDED',
5463 'WEIGHT' =>
'CATALOG_WEIGHT',
5464 'WIDTH' =>
'CATALOG_WIDTH',
5465 'LENGTH' =>
'CATALOG_LENGTH',
5466 'HEIGHT' =>
'CATALOG_HEIGHT',
5467 'PAYMENT_TYPE' =>
'CATALOG_PRICE_TYPE',
5468 'RECUR_SCHEME_LENGTH' =>
'CATALOG_RECUR_SCHEME_LENGTH',
5469 'RECUR_SCHEME_TYPE' =>
'CATALOG_RECUR_SCHEME_TYPE',
5470 'QUANTITY_TRACE_RAW' =>
'CATALOG_QUANTITY_TRACE_ORIG',
5471 'CAN_BUY_ZERO_RAW' =>
'CATALOG_CAN_BUY_ZERO_ORIG',
5472 'SUBSCRIBE_RAW' =>
'CATALOG_SUBSCRIBE_ORIG',
5473 'PURCHASING_PRICE' =>
'CATALOG_PURCHASING_PRICE',
5474 'PURCHASING_CURRENCY' =>
'CATALOG_PURCHASING_CURRENCY',
5475 'BARCODE_MULTI' =>
'CATALOG_BARCODE_MULTI',
5476 'TRIAL_PRICE_ID' =>
'CATALOG_TRIAL_PRICE_ID',
5477 'WITHOUT_ORDER' =>
'CATALOG_WITHOUT_ORDER',
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'
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)
static sendJsonAnswer(array $result=array())
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 getSystemParameters()
static loadMessages($file)
static getMessage($code, $replace=null, $language=null)