76 if (!is_array($params))
80 $params = parent::onPrepareComponentParams($params);
81 $this->makeMagicWithPageNavigation();
84 if (isset($params[
'ELEMENT_COUNT']))
86 $params[
'PAGE_ELEMENT_COUNT'] = $params[
'ELEMENT_COUNT'];
90 if (isset($params[
'PREDICT_ELEMENT_COUNT']) && $params[
'PREDICT_ELEMENT_COUNT'] ===
'Y' && !empty($params[
'PRODUCT_ROW_VARIANTS']))
92 $isBigData = $this->request->get(
'bigData') ===
'Y';
93 $params[
'PRODUCT_ROW_VARIANTS'] = static::parseJsonParameter($params[
'PRODUCT_ROW_VARIANTS']);
94 $params[
'PAGE_ELEMENT_COUNT'] = static::predictElementCountByVariants($params[
'PRODUCT_ROW_VARIANTS'], $isBigData);
97 $params[
'PAGE_ELEMENT_COUNT'] = (int)($params[
'PAGE_ELEMENT_COUNT'] ?? 0);
98 $params[
'ELEMENT_COUNT'] = (int)($params[
'ELEMENT_COUNT'] ?? 0);
99 $params[
'LINE_ELEMENT_COUNT'] = (int)($params[
'LINE_ELEMENT_COUNT'] ?? 3);
101 $params[
'INCLUDE_SUBSECTIONS'] ??=
'';
103 $params[
'INCLUDE_SUBSECTIONS'],
111 $params[
'INCLUDE_SUBSECTIONS'] =
'Y';
114 $params[
'HIDE_NOT_AVAILABLE'] ??=
'';
115 if ($params[
'HIDE_NOT_AVAILABLE'] !==
'Y' && $params[
'HIDE_NOT_AVAILABLE'] !==
'L')
117 $params[
'HIDE_NOT_AVAILABLE'] =
'N';
120 $params[
'HIDE_NOT_AVAILABLE_OFFERS'] ??=
'';
121 if ($params[
'HIDE_NOT_AVAILABLE_OFFERS'] !==
'Y' && $params[
'HIDE_NOT_AVAILABLE_OFFERS'] !==
'L')
123 $params[
'HIDE_NOT_AVAILABLE_OFFERS'] =
'N';
126 $params[
'FILTER_NAME'] = trim((
string)($params[
'FILTER_NAME'] ??
''));
128 if (isset($params[
'GLOBAL_FILTER']))
130 $this->globalFilter = $params[
'GLOBAL_FILTER'];
135 $params[
'FILTER_NAME'] !==
''
136 && preg_match(self::PARAM_TITLE_MASK, $params[
'FILTER_NAME'])
137 && isset(
$GLOBALS[$params[
'FILTER_NAME']])
138 && is_array(
$GLOBALS[$params[
'FILTER_NAME']])
141 $this->globalFilter =
$GLOBALS[$params[
'FILTER_NAME']];
144 if (isset($this->globalFilter[
'FACET_OPTIONS']) && count($this->globalFilter) == 1)
146 unset($this->globalFilter[
'FACET_OPTIONS']);
150 $this->arResult[
'ORIGINAL_PARAMETERS'][
'GLOBAL_FILTER'] = $this->globalFilter;
153 $productMappingFilter = [];
155 Loader::includeModule(
'catalog')
159 $productMappingFilter = Catalog\Product\SystemField\ProductMapping::getExtendedFilterByArea(
164 $params[
'CACHE_FILTER'] = isset($params[
'CACHE_FILTER']) && $params[
'CACHE_FILTER'] ===
'Y';
166 !$params[
'CACHE_FILTER']
167 && !empty($this->globalFilter)
168 && array_diff_assoc($this->globalFilter, $productMappingFilter)
171 $params[
'CACHE_TIME'] = 0;
176 [
'ORDER' =>
'ELEMENT_SORT_FIELD',
'DIRECTION' =>
'ELEMENT_SORT_ORDER'],
177 [
'ORDER' =>
'SORT',
'DIRECTION' =>
'asc']
182 [
'ORDER' =>
'ELEMENT_SORT_FIELD2',
'DIRECTION' =>
'ELEMENT_SORT_ORDER2'],
183 [
'ORDER' =>
'ID',
'DIRECTION' =>
'desc']
186 $params[
'PAGER_BASE_LINK_ENABLE'] = (string)($params[
'PAGER_BASE_LINK_ENABLE'] ??
'');
187 $params[
'PAGER_TITLE'] = (string)($params[
'PAGER_TITLE'] ??
'');
188 $params[
'PAGER_TEMPLATE'] = (string)($params[
'PAGER_TEMPLATE'] ??
'');
189 $params[
'PAGER_PARAMS_NAME'] = trim((
string)($params[
'PAGER_PARAMS_NAME'] ??
''));
191 $params[
'PAGER_PARAMS_NAME'] !==
''
192 && preg_match(self::PARAM_TITLE_MASK, $params[
'PAGER_PARAMS_NAME'])
195 $this->pagerParameters =
$GLOBALS[$params[
'PAGER_PARAMS_NAME']] ?? [];
197 if (!is_array($this->pagerParameters))
199 $this->pagerParameters = [];
203 if (Loader::includeModule(
'catalog') && isset($params[
'CUSTOM_FILTER']) && is_string($params[
'CUSTOM_FILTER']))
207 $params[
'CUSTOM_FILTER'] = $this->parseCondition(Json::decode($params[
'CUSTOM_FILTER']), $params);
211 $params[
'CUSTOM_FILTER'] = array();
216 $params[
'CUSTOM_FILTER'] = array();
226 $params[
'CALCULATE_SKU_MIN_PRICE'] = (isset($params[
'CALCULATE_SKU_MIN_PRICE']) && $params[
'CALCULATE_SKU_MIN_PRICE'] ===
'Y');
239 $order = (isset($orderRow[
'ORDER']) ? trim($orderRow[
'ORDER']) :
'');
240 $direction = (isset($orderRow[
'DIRECTION']) ? trim($orderRow[
'DIRECTION']) :
'');
241 if (empty($params) || $order ===
'' || $direction ===
'')
245 if (empty($params[$order]))
247 $params[$order] = $default[
'ORDER'] ??
'SORT';
249 $params[$order] = strtoupper($params[$order]);
251 if ($params[$order] ===
'ID' && !empty($params[$direction]) && is_array($params[$direction]))
253 Collection::normalizeArrayValuesByInt($params[$direction],
false);
254 if (empty($params[$direction]))
256 $params[$direction] = $default[
'DIRECTION'] ??
'desc';
261 if (empty($params[$direction]) || !preg_match(self::SORT_ORDER_MASK, $params[$direction]))
263 $params[$direction] = $default[
'DIRECTION'] ??
'desc';
383 $usePropertyFeatures = Iblock\Model\PropertyFeature::isEnabledFeatures();
385 $params[
'PROPERTY_CODE'] = array();
386 $params[
'CART_PROPERTIES'] = array();
387 $params[
'SHOW_PRODUCTS'] = $params[
'SHOW_PRODUCTS'] ?? array();
389 foreach ($params as $name => $prop)
392 if (preg_match(
'/^PROPERTY_CODE_(\d+)$/', $name, $match))
394 $iblockId = (int)$match[1];
398 if (!empty($params[$name]) && is_array($params[$name]))
400 foreach ($params[$name] as $k => $v)
404 unset($params[$name][$k]);
408 $params[
'PROPERTY_CODE'][$iblockId] = $params[$name];
410 unset($params[$match[0]]);
412 elseif (preg_match(
'/^CART_PROPERTIES_(\d+)$/', $name, $match))
414 $iblockId = (int)$match[1];
418 if (!empty($params[$name]) && is_array($params[$name]))
420 foreach ($params[$name] as $k => $v)
422 if ($v ==
'' || $v ===
'-')
424 unset($params[$name][$k]);
427 $params[
'CART_PROPERTIES'][$iblockId] = $params[$name];
429 unset($params[$match[0]]);
431 elseif (preg_match(
'/^OFFER_TREE_PROPS_(\d+)$/', $name, $match))
433 $iblockId = (int)$match[1];
437 if (!empty($params[$name]) && is_array($params[$name]))
439 foreach ($params[$name] as $k => $v)
441 if ($v ==
'' || $v ===
'-')
443 unset($params[$name][$k]);
447 $params[
'OFFER_TREE_PROPS'][$iblockId] = $params[$name];
449 unset($params[$match[0]]);
451 elseif (preg_match(
'/^SHOW_PRODUCTS_(\d+)$/', $name, $match))
453 $iblockId = (int)$match[1];
457 if ($params[$name] ===
'Y')
459 $params[
'SHOW_PRODUCTS'][$iblockId] =
true;
462 unset($params[$match[0]]);
467 $parameters = array();
469 if (!empty($params[
'SHOW_PRODUCTS']))
471 foreach (array_keys($params[
'SHOW_PRODUCTS']) as $iblockId)
473 $catalog = \CCatalogSku::GetInfoByProductIBlock($iblockId);
476 $parameters[$iblockId] = array(
477 'PROPERTY_CODE' => $params[
'PROPERTY_CODE'][$iblockId] ?? array(),
478 'CART_PROPERTIES' => (!$usePropertyFeatures && isset($params[
'CART_PROPERTIES'][$iblockId])
479 ? $params[
'CART_PROPERTIES'][$iblockId]
485 if (!empty($catalog))
487 $parameters[$iblockId][
'OFFERS_FIELD_CODE'] = array(
'ID',
'CODE',
'NAME',
'SORT',
'PREVIEW_PICTURE',
'DETAIL_PICTURE');
488 $parameters[$iblockId][
'OFFERS_PROPERTY_CODE'] = $params[
'PROPERTY_CODE'][$catalog[
'IBLOCK_ID']] ?? array();
489 $parameters[$iblockId][
'OFFERS_CART_PROPERTIES'] = (!$usePropertyFeatures && isset($params[
'CART_PROPERTIES'][$catalog[
'IBLOCK_ID']])
490 ? $params[
'CART_PROPERTIES'][$catalog[
'IBLOCK_ID']]
493 $parameters[$iblockId][
'OFFERS_TREE_PROPS'] = (!$usePropertyFeatures && isset($params[
'OFFER_TREE_PROPS'][$catalog[
'IBLOCK_ID']])
494 ? $params[
'OFFER_TREE_PROPS'][$catalog[
'IBLOCK_ID']]
512 $usePropertyFeatures = Iblock\Model\PropertyFeature::isEnabledFeatures();
514 if (!isset($params[
'PROPERTY_CODE']) || !is_array($params[
'PROPERTY_CODE']))
516 $params[
'PROPERTY_CODE'] = array();
519 foreach ($params[
'PROPERTY_CODE'] as $k => $v)
523 unset($params[
'PROPERTY_CODE'][$k]);
527 if (!isset($params[
'OFFERS_FIELD_CODE']))
529 $params[
'OFFERS_FIELD_CODE'] = array();
531 elseif (!is_array($params[
'OFFERS_FIELD_CODE']))
533 $params[
'OFFERS_FIELD_CODE'] = array($params[
'OFFERS_FIELD_CODE']);
536 foreach ($params[
'OFFERS_FIELD_CODE'] as $key => $value)
540 unset($params[
'OFFERS_FIELD_CODE'][$key]);
544 if (!isset($params[
'OFFERS_PROPERTY_CODE']))
546 $params[
'OFFERS_PROPERTY_CODE'] = array();
548 elseif (!is_array($params[
'OFFERS_PROPERTY_CODE']))
550 $params[
'OFFERS_PROPERTY_CODE'] = array($params[
'OFFERS_PROPERTY_CODE']);
553 foreach ($params[
'OFFERS_PROPERTY_CODE'] as $key => $value)
557 unset($params[
'OFFERS_PROPERTY_CODE'][$key]);
561 $cartProperties = [];
562 $offersCartProperties = [];
563 $offersTreeProperties = [];
564 if (!$usePropertyFeatures)
566 if (!isset($params[
'PRODUCT_PROPERTIES']) || !is_array($params[
'PRODUCT_PROPERTIES']))
568 $params[
'PRODUCT_PROPERTIES'] = array();
571 foreach ($params[
'PRODUCT_PROPERTIES'] as $k => $v)
575 unset($params[
'PRODUCT_PROPERTIES'][$k]);
578 $cartProperties = $params[
'PRODUCT_PROPERTIES'];
580 if (!isset($params[
'OFFERS_CART_PROPERTIES']) || !is_array($params[
'OFFERS_CART_PROPERTIES']))
582 $params[
'OFFERS_CART_PROPERTIES'] = array();
585 foreach ($params[
'OFFERS_CART_PROPERTIES'] as $i => $pid)
589 unset($params[
'OFFERS_CART_PROPERTIES'][$i]);
592 $offersCartProperties = $params[
'OFFERS_CART_PROPERTIES'];
594 if (!isset($params[
'OFFER_TREE_PROPS']))
596 $params[
'OFFER_TREE_PROPS'] = array();
598 elseif (!is_array($params[
'OFFER_TREE_PROPS']))
600 $params[
'OFFER_TREE_PROPS'] = array($params[
'OFFER_TREE_PROPS']);
603 foreach ($params[
'OFFER_TREE_PROPS'] as $key => $value)
605 $value = (string)$value;
606 if ($value ==
'' || $value ===
'-')
608 unset($params[
'OFFER_TREE_PROPS'][$key]);
612 if (empty($params[
'OFFER_TREE_PROPS']) && !empty($params[
'OFFERS_CART_PROPERTIES']))
614 $params[
'OFFER_TREE_PROPS'] = $params[
'OFFERS_CART_PROPERTIES'];
615 foreach ($params[
'OFFER_TREE_PROPS'] as $key => $value)
619 unset($params[
'OFFER_TREE_PROPS'][$key]);
623 $offersTreeProperties = $params[
'OFFER_TREE_PROPS'];
627 $params[
'IBLOCK_ID'] => array(
628 'PROPERTY_CODE' => $params[
'PROPERTY_CODE'],
629 'CART_PROPERTIES' => $cartProperties,
630 'OFFERS_FIELD_CODE' => $params[
'OFFERS_FIELD_CODE'],
631 'OFFERS_PROPERTY_CODE' => $params[
'OFFERS_PROPERTY_CODE'],
632 'OFFERS_CART_PROPERTIES' => $offersCartProperties,
633 'OFFERS_TREE_PROPS' => $offersTreeProperties
669 $addParam = \CAjax::GetSessionParam($this->arParams[
'AJAX_ID']);
671 $regexpLinks =
'/(<a\s[^>]*?>.*?<\/a>)/is'.BX_UTF_PCRE_MODIFIER;
672 $regexpParams =
'/([\w\-]+)\s*=\s*([\"\'])(.*?)\2/is'.BX_UTF_PCRE_MODIFIER;
674 $this->checkPcreLimit($data);
675 $arData = preg_split($regexpLinks, $data, -1, PREG_SPLIT_DELIM_CAPTURE);
677 $dataCount = count($arData);
681 $ignoreAttributes = array(
691 $dataChanged =
false;
693 for ($i = 1; $i < $dataCount; $i += 2)
695 if (!preg_match(
'/^<a\s([^>]*?)>(.*?)<\/a>$/is'.BX_UTF_PCRE_MODIFIER, $arData[$i], $match))
700 if (!preg_match_all($regexpParams, $params, $linkParams))
703 $strAdditional =
' ';
707 foreach ($linkParams[0] as $key => $value)
712 $paramName = mb_strtolower($linkParams[1][$key]);
714 if ($paramName ===
'href')
718 elseif (isset($ignoreAttributes[$paramName]))
725 $strAdditional .= $value.
' ';
729 if ($urlKey >= 0 && !$ignoreLink)
731 $url = Text\Converter::getHtmlConverter()->decode($linkParams[3][$urlKey]);
732 $url = str_replace($search,
'', $url);
734 if ($this->isAjaxURL($url))
738 $pos = mb_strpos($url,
'#');
741 $realUrl = mb_substr($realUrl, 0, $pos);
744 $realUrl .= mb_strpos($url,
'?') ===
false ?
'?' :
'&';
745 $realUrl .= $addParam;
747 $arData[$i] = \CAjax::GetLinkEx($realUrl, $url, $match[2],
'comp_'.$this->arParams[
'AJAX_ID'], $strAdditional);
756 $data = implode(
'', $arData);
787 $url = mb_substr($url, 0, mb_strpos($url,
'?'));
804 $currentUrl = mb_substr($currentUrl, 0, mb_strpos($currentUrl,
'?'));
840 $this->storage[
'SUB_FILTER'] = array();
845 && $this->offerIblockExist($this->arParams[
'IBLOCK_ID'])
848 $catalogFilter = array();
849 foreach ($this->globalFilter as $key => $value)
851 if (\CProductQueryBuilder::isCatalogFilterField($key))
854 if ($key ===
'=PRODUCT_UF_PRODUCT_MAPPING')
858 $catalogFilter[$key] = $value;
859 unset($this->globalFilter[$key]);
863 $iblock = $this->storage[
'CATALOGS'][$this->arParams[
'IBLOCK_ID']];
864 $offersFilterExists = !empty($this->globalFilter[
'OFFERS']) && is_array($this->globalFilter[
'OFFERS']);
866 if ($offersFilterExists)
868 $this->storage[
'SUB_FILTER'] = array_merge($this->globalFilter[
'OFFERS'], $catalogFilter);
869 $this->storage[
'SUB_FILTER'][
'IBLOCK_ID'] = $iblock[
'IBLOCK_ID'];
870 $this->storage[
'SUB_FILTER'][
'ACTIVE_DATE'] =
'Y';
871 $this->storage[
'SUB_FILTER'][
'ACTIVE'] =
'Y';
873 if ($this->arParams[
'HIDE_NOT_AVAILABLE'] ===
'Y')
875 $this->storage[
'SUB_FILTER'][
'AVAILABLE'] =
'Y';
878 $this->filterFields[
'=ID'] = \CIBlockElement::SubQuery(
879 'PROPERTY_'.$iblock[
'SKU_PROPERTY_ID'],
880 $this->storage[
'SUB_FILTER']
883 elseif (!empty($catalogFilter))
885 $this->storage[
'SUB_FILTER'] = $catalogFilter;
886 $this->storage[
'SUB_FILTER'][
'IBLOCK_ID'] = $iblock[
'IBLOCK_ID'];
887 $this->storage[
'SUB_FILTER'][
'ACTIVE_DATE'] =
'Y';
888 $this->storage[
'SUB_FILTER'][
'ACTIVE'] =
'Y';
890 $this->filterFields[] = array(
892 array($catalogFilter),
893 '=ID' => \CIBlockElement::SubQuery(
894 'PROPERTY_'.$iblock[
'SKU_PROPERTY_ID'],
895 $this->storage[
'SUB_FILTER']
904 $iblockElements = array();
906 if (!empty($elementIterator))
908 while ($element = $elementIterator->GetNext())
910 $this->processElement($element);
911 $iblockElements[$element[
'ID']] = $element;
915 return $iblockElements;
920 if (!empty($iblockElements))
922 $iblockParams = $this->storage[
'IBLOCK_PARAMS'][$iblock];
923 $propertyCodes = $iblockParams[
'PROPERTY_CODE'];
924 $productProperties = $iblockParams[
'CART_PROPERTIES'];
925 $getPropertyCodes = !empty($propertyCodes);
926 $getProductProperties = $this->arParams[
'ADD_PROPERTIES_TO_BASKET'] ===
'Y' && !empty($productProperties);
927 $getIblockProperties = $getPropertyCodes || $getProductProperties;
929 if ($getIblockProperties || ($this->useCatalog && $this->useDiscountCache))
932 'ID' => array_keys($iblockElements),
933 'IBLOCK_ID' => $iblock
935 \CIBlockElement::GetPropertyValuesArray($iblockElements, $iblock, $propFilter);
937 if ($getPropertyCodes)
939 $propertyList = $this->getPropertyList($iblock, $propertyCodes);
942 foreach ($iblockElements as &$element)
944 if ($this->useCatalog && $this->useDiscountCache)
946 if ($this->storage[
'USE_SALE_DISCOUNTS'])
947 Catalog\Discount\DiscountManager::setProductPropertiesCache($element[
'ID'], $element[
"PROPERTIES"]);
949 \CCatalogDiscount::SetProductPropertiesCache($element[
'ID'], $element[
'PROPERTIES']);
952 if ($getIblockProperties)
954 if (!empty($propertyList))
956 foreach ($propertyList as $pid)
958 if (!isset($element[
'PROPERTIES'][$pid]))
961 $prop =& $element[
'PROPERTIES'][$pid];
962 $isArr = is_array($prop[
'VALUE']);
964 ($isArr && !empty($prop[
'VALUE']))
965 || (!$isArr && (
string)$prop[
'VALUE'] !==
'')
969 $element[
'DISPLAY_PROPERTIES'][$pid] = \CIBlockFormatProperties::GetDisplayValue($element, $prop);
976 if ($getProductProperties)
978 $element[
'PRODUCT_PROPERTIES'] = \CIBlockPriceTools::GetProductProperties(
982 $element[
'PROPERTIES']
985 if (!empty($element[
'PRODUCT_PROPERTIES']))
987 $element[
'PRODUCT_PROPERTIES_FILL'] = \CIBlockPriceTools::getFillProductProperties($element[
'PRODUCT_PROPERTIES']);
994 \CIBlockFormatProperties::clearCache();
1026 if (empty($sortFields))
1030 $this->isIblockCatalog
1033 || (!$this->
isMultiIblockMode() && $this->offerIblockExist($this->arParams[
'IBLOCK_ID']))
1036 && $this->arParams[
'HIDE_NOT_AVAILABLE'] ===
'L'
1039 $sortFields[
'AVAILABLE'] =
'desc,nulls';
1042 $field = strtoupper($this->arParams[
'ELEMENT_SORT_FIELD']);
1043 if (!isset($sortFields[$field]))
1045 $sortFields[$field] = $this->arParams[
'ELEMENT_SORT_ORDER'];
1048 $field = strtoupper($this->arParams[
'ELEMENT_SORT_FIELD2']);
1049 if (!isset($sortFields[$field]))
1051 $sortFields[$field] = $this->arParams[
'ELEMENT_SORT_ORDER2'];
1054 if (!isset($sortFields[
'ID']))
1056 $sortFields[
'ID'] =
'DESC';
1067 if (!empty($this->arParams[
'CUSTOM_ELEMENT_SORT']) && is_array($this->arParams[
'CUSTOM_ELEMENT_SORT']))
1069 foreach ($this->arParams[
'CUSTOM_ELEMENT_SORT'] as $field => $value)
1071 $field = strtoupper($field);
1072 if (isset($result[$field]))
1076 if ($field ===
'ID' && !empty($value) && is_array($value))
1078 Collection::normalizeArrayValuesByInt($value,
false);
1086 if (!is_string($value))
1090 if (!preg_match(self::SORT_ORDER_MASK, $value))
1096 $result[$field] = $value;
1098 unset($field, $value);
1124 $navComponentParameters = array();
1126 if ($this->arParams[
'PAGER_BASE_LINK_ENABLE'] ===
'Y')
1128 $pagerBaseLink = trim($this->arParams[
'PAGER_BASE_LINK']) ?: $this->arResult[
'SECTION_PAGE_URL'];
1130 if ($this->pagerParameters && isset($this->pagerParameters[
'BASE_LINK']))
1132 $pagerBaseLink = $this->pagerParameters[
'BASE_LINK'];
1133 unset($this->pagerParameters[
'BASE_LINK']);
1136 $navComponentParameters[
'BASE_LINK'] = \CHTTP::urlAddParams($pagerBaseLink, $this->pagerParameters, array(
'encode' =>
true));
1140 $uri =
new Main\Web\Uri($this->arParams[
'CURRENT_BASE_PAGE']);
1141 $uri->deleteParams(array(
1142 'PAGEN_'.$elementIterator->NavNum,
1143 'SIZEN_'.$elementIterator->NavNum,
1144 'SHOWALL_'.$elementIterator->NavNum,
1147 'bitrix_include_areas'
1149 $navComponentParameters[
'BASE_LINK'] = $uri->getUri();
1152 $this->arResult[
'NAV_STRING'] = $elementIterator->GetPageNavStringEx(
1153 $navComponentObject,
1154 $this->arParams[
'PAGER_TITLE'],
1155 $this->arParams[
'PAGER_TEMPLATE'],
1156 $this->arParams[
'PAGER_SHOW_ALWAYS'],
1158 $navComponentParameters
1160 $this->arResult[
'NAV_CACHED_DATA'] =
null;
1161 $this->arResult[
'NAV_RESULT'] = $elementIterator;
1162 $this->arResult[
'NAV_PARAM'] = $navComponentParameters;
1167 if (empty($offers) || empty($this->storage[
'CATALOGS'][$iblockId]))
1169 $uniqueSortHash = array();
1170 $filteredOffers = array();
1171 $filteredElements = array();
1176 $catalog = $this->storage[
'CATALOGS'][$iblockId];
1177 $this->storage[
'SUB_FILTER'][
'=PROPERTY_'.$catalog[
'SKU_PROPERTY_ID']] = array_keys($this->elementLinks);
1178 $filteredOffers = Iblock\Component\Filters::getFilteredOffersByProduct(
1179 $catalog[
'IBLOCK_ID'],
1180 $catalog[
'SKU_PROPERTY_ID'],
1181 $this->storage[
'SUB_FILTER']
1186 foreach ($offers as &$offer)
1188 $elementId = $offer[
'LINK_ELEMENT_ID'];
1190 if (!isset($this->elementLinks[$elementId]))
1193 if (!isset($uniqueSortHash[$elementId]))
1195 $uniqueSortHash[$elementId] = array();
1198 $uniqueSortHash[$elementId][$offer[
'SORT_HASH']] =
true;
1200 if ($this->elementLinks[$elementId][
'OFFER_ID_SELECTED'] == 0 && $offer[
'CAN_BUY'])
1202 if (isset($filteredOffers[$elementId]))
1204 if (isset($filteredOffers[$elementId][$offer[
'ID']]))
1206 $this->elementLinks[$elementId][
'OFFER_ID_SELECTED'] = $offer[
'ID'];
1207 $filteredElements[$elementId] =
true;
1210 elseif (isset($filteredByProperty[$elementId]))
1212 if (isset($filteredByProperty[$elementId][$offer[
'ID']]))
1214 $this->elementLinks[$elementId][
'OFFER_ID_SELECTED'] = $offer[
'ID'];
1215 $filteredElements[$elementId] =
true;
1220 $this->elementLinks[$elementId][
'OFFER_ID_SELECTED'] = $offer[
'ID'];
1226 if (!empty($filteredOffers))
1228 $this->arResult[
'FILTERED_OFFERS_ID'] = array();
1231 foreach ($this->elementLinks as &$element)
1233 if (isset($filteredOffers[$element[
'ID']]))
1235 $this->arResult[
'FILTERED_OFFERS_ID'][$element[
'ID']] = $filteredOffers[$element[
'ID']];
1238 if ($element[
'OFFER_ID_SELECTED'] == 0 || isset($filteredElements[$element[
'ID']]))
1241 if (count($uniqueSortHash[$element[
'ID']]) < 2)
1243 $element[
'OFFER_ID_SELECTED'] = 0;
1364 $this->arParams[
'PAGE_ELEMENT_COUNT'] > 0
1366 $this->arParams[
'DISPLAY_TOP_PAGER']
1367 || $this->arParams[
'DISPLAY_BOTTOM_PAGER']
1368 || $this->arParams[
'LAZY_LOAD'] ===
'Y'
1372 $this->navParams = array(
1373 'nPageSize' => $this->arParams[
'PAGE_ELEMENT_COUNT'],
1374 'bDescPageNumbering' => $this->arParams[
'PAGER_DESC_NUMBERING'],
1375 'bShowAll' => $this->arParams[
'PAGER_SHOW_ALL']
1377 $this->navigation = \CDBResult::GetNavParams($this->navParams);
1379 if ($this->navigation[
'PAGEN'] == 0 && $this->arParams[
'PAGER_DESC_NUMBERING_CACHE_TIME'] > 0)
1381 $this->arParams[
'CACHE_TIME'] = $this->arParams[
'PAGER_DESC_NUMBERING_CACHE_TIME'];
1386 $this->navParams = array(
1387 'nTopCount' => $this->arParams[
'PAGE_ELEMENT_COUNT'],
1388 'bDescPageNumbering' => $this->arParams[
'PAGER_DESC_NUMBERING'],
1390 $this->navigation =
false;
1395 $this->navParams = array(
'nTopCount' => $this->arParams[
'PAGE_ELEMENT_COUNT']);
1396 $this->navigation =
false;
1478 $params[
'ADDITIONAL_PICT_PROP'] = array();
1479 $params[
'LABEL_PROP'] = array();
1480 $params[
'LABEL_PROP_MOBILE'] = array();
1481 $params[
'PROPERTY_CODE_MOBILE'] = array();
1482 $params[
'ENLARGE_PROP'] = array();
1483 $params[
'OFFER_TREE_PROPS'] = array();
1485 foreach ($params as $name => $prop)
1487 if (preg_match(
'/^ADDITIONAL_PICT_PROP_(\d+)$/', $name, $match))
1489 $iblockId = (int)$match[1];
1493 if ($params[$name] !=
'' && $params[$name] !=
'-')
1495 $params[
'ADDITIONAL_PICT_PROP'][$iblockId] = $params[$name];
1497 unset($params[$match[0]]);
1499 elseif (preg_match(
'/^LABEL_PROP_(\d+)$/', $name, $match))
1501 $iblockId = (int)$match[1];
1505 if (!empty($params[$name]))
1507 if (!is_array($params[$name]))
1509 $params[$name] = array($params[$name]);
1512 foreach ($params[$name] as $k => $v)
1516 unset($params[$name][$k]);
1520 $params[
'LABEL_PROP'][$iblockId] = $params[$name];
1523 elseif (preg_match(
'/^LABEL_PROP_MOBILE_(\d+)$/', $name, $match))
1525 $iblockId = (int)$match[1];
1529 if (!empty($params[$name]) && is_array($params[$name]))
1531 foreach ($params[$name] as $k => $v)
1535 unset($params[$name][$k]);
1539 if (!empty($params[$name]))
1541 $params[$name] = array_flip($params[$name]);
1544 $params[
'LABEL_PROP_MOBILE'][$iblockId] = $params[$name];
1546 unset($params[$match[0]]);
1548 elseif (preg_match(
'/^PROPERTY_CODE_MOBILE_(\d+)$/', $name, $match))
1550 $iblockId = (int)$match[1];
1554 if (!empty($params[$name]) && is_array($params[$name]))
1556 foreach ($params[$name] as $k => $v)
1560 unset($params[$name][$k]);
1564 if (!empty($params[$name]))
1566 $params[$name] = array_flip($params[$name]);
1569 $params[
'PROPERTY_CODE_MOBILE'][$iblockId] = $params[$name];
1571 unset($params[$match[0]]);
1573 elseif (preg_match(
'/^ENLARGE_PROP_(\d+)$/', $name, $match))
1575 $iblockId = (int)$match[1];
1579 if ($params[$name] !=
'' && $params[$name] !=
'-')
1581 $params[
'ENLARGE_PROP'][$iblockId] = $params[$name];
1583 unset($params[$match[0]]);
1587 if (!empty($params[
'SHOW_PRODUCTS']))
1589 $usePropertyFeatures = Iblock\Model\PropertyFeature::isEnabledFeatures();
1591 foreach (array_keys($params[
'SHOW_PRODUCTS']) as $iblockId)
1593 if (!isset($this->storage[
'IBLOCK_PARAMS'][$iblockId]) || !is_array($this->storage[
'IBLOCK_PARAMS'][$iblockId]))
1595 $this->storage[
'IBLOCK_PARAMS'][$iblockId] = array();
1599 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'ADD_PICT_PROP'] = $params[
'ADDITIONAL_PICT_PROP'][$iblockId] ??
'';
1600 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'LABEL_PROP'] = $params[
'LABEL_PROP'][$iblockId] ?? array();
1601 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'LABEL_PROP_MOBILE'] = $params[
'LABEL_PROP_MOBILE'][$iblockId] ?? array();
1602 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'PROPERTY_CODE_MOBILE'] = $params[
'PROPERTY_CODE_MOBILE'][$iblockId] ?? array();
1603 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'ENLARGE_PROP'] = $params[
'ENLARGE_PROP'][$iblockId] ??
'';
1606 $catalog = \CCatalogSku::GetInfoByProductIBlock($iblockId);
1607 if (!empty($catalog))
1609 $this->storage[
'IBLOCK_PARAMS'][$iblockId][
'OFFERS_ADD_PICT_PROP'] = $params[
'ADDITIONAL_PICT_PROP'][$catalog[
'IBLOCK_ID']] ??
'';
1613 unset($usePropertyFeatures);
1703 if ($pageElementCount <= 0)
1708 $templateVariantsMap = static::getTemplateVariantsMap();
1710 if (empty($templateVariantsMap))
1717 foreach ($templateVariantsMap as $key => $variant)
1719 if ($variant[
'COUNT'] == $lineElementCount && $variant[
'ENLARGED_POS'] ===
false)
1728 ceil($pageElementCount / $templateVariantsMap[$variantId][
'COUNT']),
1729 array(
'VARIANT' => $variantId,
'BIG_DATA' =>
false)
1800 $variantsMap = static::getTemplateVariantsMap();
1801 $isBigData = $this->getAction() ===
'bigDataLoad';
1803 if ($this->arParams[
'ENLARGE_PRODUCT'] ===
'PROP')
1808 if (!empty($this->arParams[
'PRODUCT_ROW_VARIANTS']))
1812 foreach ($this->arParams[
'PRODUCT_ROW_VARIANTS'] as $variant)
1815 (!$isBigData && !$variant[
'BIG_DATA'])
1816 || ($isBigData && $variant[
'BIG_DATA'])
1831 $variantParam =
false;
1833 $itemsLength = count($this->arResult[
'ITEMS']);
1835 while (($itemsRemaining = $itemsLength - $itemsCounter) > 0)
1837 if ($variantParam ===
false)
1839 $variantParam = reset($this->arParams[
'PRODUCT_ROW_VARIANTS']);
1843 if (!empty($variantParam))
1846 $isBigData && !$variantParam[
'BIG_DATA']
1847 || !$isBigData && $variantParam[
'BIG_DATA']
1850 $variantParam = next($this->arParams[
'PRODUCT_ROW_VARIANTS']);
1852 if ($variantParam ===
false)
1854 $variantParam = reset($this->arParams[
'PRODUCT_ROW_VARIANTS']);
1857 if ($variantParam ===
false)
1865 $variantParam ===
false
1866 || !isset($variantsMap[$variantParam[
'VARIANT']])
1867 || ($variantsMap[$variantParam[
'VARIANT']][
'SHOW_ONLY_FULL'] && $variantsMap[$variantParam[
'VARIANT']][
'COUNT'] > $itemsRemaining)
1875 $variant = $variantsMap[$variantParam[
'VARIANT']];
1879 if ($this->arParams[
'ENLARGE_PRODUCT'] ===
'PROP' && $variant[
'ENLARGED_POS'] !==
false)
1881 if (!empty($enlargedIndexMap))
1883 $overallPos = $itemsCounter + $variant[
'ENLARGED_POS'];
1884 $overallPosKey = array_search($overallPos, $enlargedIndexMap);
1885 if ($overallPosKey ===
false)
1887 $closestPos =
false;
1888 $closestPosKey =
false;
1889 $enlargedPosInRange = array_intersect($enlargedIndexMap , range($itemsCounter, $itemsCounter + $variant[
'COUNT']));
1891 if (!empty($enlargedPosInRange))
1893 foreach ($enlargedPosInRange as $key => $posInRange)
1895 if ($closestPos ===
false || abs($overallPos - $closestPos) > abs($posInRange - $overallPos))
1897 $closestPos = $posInRange;
1898 $closestPosKey = $key;
1902 $temporary = array($this->arResult[
'ITEMS'][$closestPos]);
1903 unset($this->arResult[
'ITEMS'][$closestPos], $enlargedIndexMap[$closestPosKey]);
1904 array_splice($this->arResult[
'ITEMS'], $overallPos, 0, $temporary);
1909 unset($enlargedIndexMap[$overallPosKey]);
1915 $itemsCounter += $variant[
'COUNT'];
1916 $variantParam = next($this->arParams[
'PRODUCT_ROW_VARIANTS']);
1920 $this->arResult[
'ITEM_ROWS'] = $rows;
1932 $rowsRange = array();
1933 $variantsMap = static::getTemplateVariantsMap();
1935 if (!empty($this->arParams[
'PRODUCT_ROW_VARIANTS']))
1937 foreach ($this->arParams[
'PRODUCT_ROW_VARIANTS'] as $key => $row)
1939 if ($row[
'BIG_DATA'])
1943 if (isset($variantsMap[$row[
'VARIANT']]))
1945 $count += (int)$variantsMap[$row[
'VARIANT']][
'COUNT'];
1948 $rowsRange[] = $count;
1953 $shownIds = array();
1954 if (!empty($this->elements))
1956 foreach ($this->elements as $element)
1958 $shownIds[] = $element[
'ID'];
1963 'enabled' => $count > 0,
1966 'rowsRange' => $rowsRange,
1967 'shownIds' => $shownIds,
1969 'cookiePrefix' => \COption::GetOptionString(
'main',
'cookie_name',
'BITRIX_SM'),
1971 'serverTime' => $count > 0 ? time() : 0,
1973 'params' => $this->getBigDataServiceRequestParams(($this->arParams[
'RCM_TYPE'] ??
''))
2111 $skuPropList = array();
2113 if ($this->arResult[
'MODULES'][
'catalog'] && !empty($this->storage[
'IBLOCK_PARAMS']))
2115 $elementIndex = array_keys($this->elements);
2117 foreach ($this->storage[
'IBLOCK_PARAMS'] as $iblockId => $iblockParams)
2119 $skuPropList[$iblockId] = array();
2120 $sku = \CCatalogSku::GetInfoByProductIBlock($iblockId);
2121 $boolSku = !empty($sku) && is_array($sku);
2123 if ($boolSku && !empty($iblockParams[
'OFFERS_TREE_PROPS']) && $this->arParams[
'PRODUCT_DISPLAY_MODE'] ===
'Y')
2125 $skuPropList[$iblockId] = \CIBlockPriceTools::getTreeProperties(
2127 $iblockParams[
'OFFERS_TREE_PROPS'],
2129 'PICT' => $this->arResult[
'DEFAULT_PICTURE'],
2134 if (!empty($skuPropList[$iblockId]))
2136 if (!empty($this->productWithOffers[$iblockId]))
2138 $skuPropIds = array();
2139 foreach ($skuPropList[$iblockId] as $property)
2141 $skuPropIds[$property[
'CODE']] = array(
2142 'ID' => $property[
'ID'],
2143 'CODE' => $property[
'CODE'],
2144 'PROPERTY_TYPE' => $property[
'PROPERTY_TYPE'],
2145 'USER_TYPE' => $property[
'USER_TYPE']
2150 $needValues = array();
2151 foreach ($elementIndex as $index)
2153 if ($this->elements[$index][
'IBLOCK_ID'] != $iblockId)
2155 if ($this->elements[$index][
'PRODUCT'][
'TYPE'] != Catalog\ProductTable::TYPE_SKU)
2157 if (empty($this->elements[$index][
'OFFERS']))
2159 foreach ($this->elements[$index][
'OFFERS'] as $offer)
2161 foreach ($skuPropIds as $property)
2163 if (isset($offer[
'DISPLAY_PROPERTIES'][$property[
'CODE']]))
2165 if (!isset($needValues[$property[
'ID']]))
2166 $needValues[$property[
'ID']] = array();
2167 $valueId = ($property[
'PROPERTY_TYPE'] == Iblock\PropertyTable::TYPE_LIST
2168 ? $offer[
'DISPLAY_PROPERTIES'][$property[
'CODE']][
'VALUE_ENUM_ID']
2169 : $offer[
'DISPLAY_PROPERTIES'][$property[
'CODE']][
'VALUE']
2171 $needValues[$property[
'ID']][$valueId] = $valueId;
2181 if (!empty($needValues))
2182 \CIBlockPriceTools::getTreePropertyValues($skuPropList[$iblockId], $needValues);
2190 $this->arParams[
'PRODUCT_DISPLAY_MODE'] =
'N';
2196 return $skuPropList;
2201 $enableCompatible = $this->isEnableCompatible();
2202 foreach ($items as $key => &$item)
2204 $iblockParams = $this->storage[
'IBLOCK_PARAMS'][$item[
'IBLOCK_ID']];
2206 if (!isset($item[
'CATALOG_QUANTITY']))
2208 $item[
'CATALOG_QUANTITY'] = 0;
2211 $item[
'CATALOG_QUANTITY'] = $item[
'CATALOG_QUANTITY'] > 0 && is_float($item[
'ITEM_MEASURE_RATIOS'][$item[
'ITEM_MEASURE_RATIO_SELECTED']][
'RATIO'])
2212 ? (float)$item[
'CATALOG_QUANTITY']
2213 : (int)$item[
'CATALOG_QUANTITY'];
2215 $item[
'CATALOG'] =
false;
2216 $item[
'CATALOG_SUBSCRIPTION'] = ($item[
'CATALOG_SUBSCRIPTION'] ??
'') ===
'Y' ?
'Y' :
'N';
2218 $item[
'BIG_DATA'] = $this->getAction() ===
'bigDataLoad';
2220 \CIBlockPriceTools::getLabel($item, $iblockParams[
'LABEL_PROP']);
2221 $item[
'LABEL_PROP_MOBILE'] = $iblockParams[
'LABEL_PROP_MOBILE'];
2222 $item[
'PROPERTY_CODE_MOBILE'] = $iblockParams[
'PROPERTY_CODE_MOBILE'];
2223 static::checkEnlargedData($item, $iblockParams[
'ENLARGE_PROP']);
2225 if ($this->arParams[
'SHOW_SLIDER'] ===
'Y')
2227 $this->editTemplateProductSlider($item, $item[
'IBLOCK_ID'], 5,
true, array($this->arResult[
'DEFAULT_PICTURE']));
2231 $this->editTemplateCatalogInfo($item);
2233 if ($item[
'CATALOG'] && !empty($item[
'OFFERS']))
2235 if ($this->arParams[
'PRODUCT_DISPLAY_MODE'] ===
'Y')
2241 if ($this->arParams[
'CALCULATE_SKU_MIN_PRICE'] || $this->arParams[
'PRODUCT_DISPLAY_MODE'] !==
'Y')
2244 if ($this->arResult[
'MODULES'][
'catalog'] && !isset($this->arResult[
'CONVERT_CURRENCY'][
'CURRENCY_ID']))
2246 $baseCurrency = Currency\CurrencyManager::getBaseCurrency();
2249 $currency = $this->arResult[
'CONVERT_CURRENCY'][
'CURRENCY_ID'] ?? $baseCurrency;
2251 $item[
'ITEM_START_PRICE'] =
null;
2252 $item[
'ITEM_START_PRICE_SELECTED'] =
null;
2253 if ($enableCompatible)
2254 $item[
'MIN_PRICE'] =
false;
2257 $minPriceIndex =
null;
2258 foreach (array_keys($item[
'OFFERS']) as $index)
2260 if (!$item[
'OFFERS'][$index][
'CAN_BUY'] || $item[
'OFFERS'][$index][
'ITEM_PRICE_SELECTED'] ===
null)
2263 $currentPrice = $item[
'OFFERS'][$index][
'ITEM_PRICES'][$item[
'OFFERS'][$index][
'ITEM_PRICE_SELECTED']];
2264 if ($currentPrice[
'CURRENCY'] != $currency)
2266 $priceScale = \CCurrencyRates::ConvertCurrency(
2267 $currentPrice[
'RATIO_PRICE'],
2268 $currentPrice[
'CURRENCY'],
2274 $priceScale = $currentPrice[
'RATIO_PRICE'];
2276 if ($minPrice ===
null || $minPrice > $priceScale)
2278 $minPrice = $priceScale;
2279 $minPriceIndex = $index;
2281 unset($priceScale, $currentPrice);
2285 if ($minPriceIndex !==
null)
2287 $minOffer = $item[
'OFFERS'][$minPriceIndex];
2288 $item[
'ITEM_START_PRICE_SELECTED'] = $minPriceIndex;
2289 $item[
'ITEM_START_PRICE'] = $minOffer[
'ITEM_PRICES'][$minOffer[
'ITEM_PRICE_SELECTED']];
2290 if ($enableCompatible)
2292 $item[
'MIN_PRICE'] = array(
2293 'CATALOG_MEASURE_RATIO' => $minOffer[
'ITEM_MEASURE_RATIOS'][$minOffer[
'ITEM_MEASURE_RATIO_SELECTED']][
'RATIO'],
2294 'CATALOG_MEASURE' => $minOffer[
'ITEM_MEASURE'][
'ID'],
2295 'CATALOG_MEASURE_NAME' => $minOffer[
'ITEM_MEASURE'][
'TITLE'],
2296 '~CATALOG_MEASURE_NAME' => $minOffer[
'ITEM_MEASURE'][
'~TITLE'],
2297 'VALUE' => $item[
'ITEM_START_PRICE'][
'RATIO_BASE_PRICE'],
2298 'DISCOUNT_VALUE' => $item[
'ITEM_START_PRICE'][
'RATIO_PRICE'],
2299 'PRINT_VALUE' => $item[
'ITEM_START_PRICE'][
'PRINT_RATIO_BASE_PRICE'],
2300 'PRINT_DISCOUNT_VALUE' => $item[
'ITEM_START_PRICE'][
'PRINT_RATIO_PRICE'],
2301 'DISCOUNT_DIFF' => $item[
'ITEM_START_PRICE'][
'RATIO_DISCOUNT'],
2302 'PRINT_DISCOUNT_DIFF' => $item[
'ITEM_START_PRICE'][
'PRINT_RATIO_DISCOUNT'],
2303 'DISCOUNT_DIFF_PERCENT' => $item[
'ITEM_START_PRICE'][
'PERCENT'],
2304 'CURRENCY' => $item[
'ITEM_START_PRICE'][
'CURRENCY']
2309 unset($minPriceIndex, $minPrice);
2311 unset($baseCurrency, $currency);
2316 $this->arResult[
'MODULES'][
'catalog']
2319 $item[
'CATALOG_TYPE'] == Catalog\ProductTable::TYPE_PRODUCT
2320 || $item[
'CATALOG_TYPE'] == Catalog\ProductTable::TYPE_SET
2324 if ($enableCompatible)
2326 if ($item[
'ITEM_PRICE_SELECTED'] ===
null)
2328 $item[
'RATIO_PRICE'] =
null;
2329 $item[
'MIN_BASIS_PRICE'] =
null;
2333 $itemPrice = $item[
'ITEM_PRICES'][$item[
'ITEM_PRICE_SELECTED']];
2334 $item[
'RATIO_PRICE'] = array(
2335 'VALUE' => $itemPrice[
'RATIO_BASE_PRICE'],
2336 'DISCOUNT_VALUE' => $itemPrice[
'RATIO_PRICE'],
2337 'PRINT_VALUE' => $itemPrice[
'PRINT_RATIO_BASE_PRICE'],
2338 'PRINT_DISCOUNT_VALUE' => $itemPrice[
'PRINT_RATIO_PRICE'],
2339 'DISCOUNT_DIFF' => $itemPrice[
'RATIO_DISCOUNT'],
2340 'PRINT_DISCOUNT_DIFF' => $itemPrice[
'PRINT_RATIO_DISCOUNT'],
2341 'DISCOUNT_DIFF_PERCENT' => $itemPrice[
'PERCENT'],
2342 'CURRENCY' => $itemPrice[
'CURRENCY']
2344 $item[
'MIN_BASIS_PRICE'] = array(
2345 'VALUE' => $itemPrice[
'BASE_PRICE'],
2346 'DISCOUNT_VALUE' => $itemPrice[
'PRICE'],
2347 'PRINT_VALUE' => $itemPrice[
'PRINT_BASE_PRICE'],
2348 'PRINT_DISCOUNT_VALUE' => $itemPrice[
'PRINT_PRICE'],
2349 'DISCOUNT_DIFF' => $itemPrice[
'DISCOUNT'],
2350 'PRINT_DISCOUNT_DIFF' => $itemPrice[
'PRINT_DISCOUNT'],
2351 'DISCOUNT_DIFF_PERCENT' => $itemPrice[
'PERCENT'],
2352 'CURRENCY' => $itemPrice[
'CURRENCY']
2359 if (!empty($item[
'DISPLAY_PROPERTIES']))
2361 foreach ($item[
'DISPLAY_PROPERTIES'] as $propKey => $displayProp)
2364 if ($displayProp[
'PROPERTY_TYPE'] ===
'F')
2366 unset($item[
'DISPLAY_PROPERTIES'][$propKey]);
2372 $item[
'LAST_ELEMENT'] =
'N';
2376 $items[key($items)][
'LAST_ELEMENT'] =
'Y';
2404 $boolSkuDisplayProperties =
false;
2407 foreach ($item[
'OFFERS'] as $offerKey => $offer)
2409 if ($item[
'OFFER_ID_SELECTED'] > 0)
2411 $foundOffer = ($item[
'OFFER_ID_SELECTED'] == $offer[
'ID']);
2415 $foundOffer = $offer[
'CAN_BUY'];
2418 if ($foundOffer && $intSelected == -1)
2420 $intSelected = $offerKey;
2426 if (!empty($offer[
'DISPLAY_PROPERTIES']))
2428 $boolSkuDisplayProperties =
true;
2429 $skuProps = array();
2430 foreach ($offer[
'DISPLAY_PROPERTIES'] as $oneProp)
2432 if ($oneProp[
'PROPERTY_TYPE'] ===
'F')
2435 $skuProps[] = array(
2436 'CODE' => $oneProp[
'CODE'],
2437 'NAME' => $oneProp[
'NAME'],
2438 'VALUE' => $oneProp[
'DISPLAY_VALUE']
2444 $ratioSelectedIndex = $offer[
'ITEM_MEASURE_RATIO_SELECTED'];
2446 'ID' => $offer[
'ID'],
2447 'NAME' => ($offer[
'~NAME'] ??
''),
2448 'TREE' => $offer[
'TREE'],
2449 'DISPLAY_PROPERTIES' => $skuProps,
2452 'PRICE' => ($offer[
'RATIO_PRICE'] ?? $offer[
'MIN_PRICE'] ?? 0),
2453 'BASIS_PRICE' => ($offer[
'MIN_PRICE'] ?? 0),
2456 'ITEM_PRICE_MODE' => $offer[
'ITEM_PRICE_MODE'],
2457 'ITEM_PRICES' => $offer[
'ITEM_PRICES'],
2458 'ITEM_PRICE_SELECTED' => $offer[
'ITEM_PRICE_SELECTED'],
2459 'ITEM_QUANTITY_RANGES' => $offer[
'ITEM_QUANTITY_RANGES'],
2460 'ITEM_QUANTITY_RANGE_SELECTED' => $offer[
'ITEM_QUANTITY_RANGE_SELECTED'],
2461 'ITEM_MEASURE_RATIOS' => $offer[
'ITEM_MEASURE_RATIOS'],
2462 'ITEM_MEASURE_RATIO_SELECTED' => $ratioSelectedIndex,
2463 'SECOND_PICT' => $offer[
'SECOND_PICT'],
2464 'OWNER_PICT' => $offer[
'OWNER_PICT'],
2465 'PREVIEW_PICTURE' => $offer[
'PREVIEW_PICTURE'],
2466 'PREVIEW_PICTURE_SECOND' => $offer[
'PREVIEW_PICTURE_SECOND'],
2467 'CHECK_QUANTITY' => $offer[
'CHECK_QUANTITY'],
2468 'MAX_QUANTITY' => $offer[
'PRODUCT'][
'QUANTITY'],
2469 'STEP_QUANTITY' => $offer[
'ITEM_MEASURE_RATIOS'][$ratioSelectedIndex][
'RATIO'],
2470 'QUANTITY_FLOAT' => is_float($offer[
'ITEM_MEASURE_RATIOS'][$ratioSelectedIndex][
'RATIO']),
2471 'MEASURE' => $offer[
'ITEM_MEASURE'][
'TITLE'],
2472 'CAN_BUY' => $offer[
'CAN_BUY'],
2473 'CATALOG_SUBSCRIBE' => $offer[
'PRODUCT'][
'SUBSCRIBE']
2475 unset($ratioSelectedIndex);
2477 if (isset($offer[
'MORE_PHOTO_COUNT']) && $offer[
'MORE_PHOTO_COUNT'] > 0)
2479 $oneRow[
'MORE_PHOTO'] = $offer[
'MORE_PHOTO'];
2480 $oneRow[
'MORE_PHOTO_COUNT'] = $offer[
'MORE_PHOTO_COUNT'];
2483 $matrix[$offerKey] = $oneRow;
2486 if ($intSelected == -1)
2491 if (!$matrix[$intSelected][
'OWNER_PICT'])
2493 $item[
'PREVIEW_PICTURE'] = $matrix[$intSelected][
'PREVIEW_PICTURE'];
2494 $item[
'PREVIEW_PICTURE_SECOND'] = $matrix[$intSelected][
'PREVIEW_PICTURE_SECOND'];
2497 $item[
'JS_OFFERS'] = $matrix;
2498 $item[
'OFFERS_SELECTED'] = $intSelected;
2499 $item[
'OFFERS_PROPS_DISPLAY'] = $boolSkuDisplayProperties;
2505 $newOffers = array();
2507 $item[
'OFFERS_PROP'] =
false;
2508 $item[
'SKU_TREE_VALUES'] = array();
2510 $iblockParams = $this->storage[
'IBLOCK_PARAMS'][$item[
'IBLOCK_ID']];
2512 if (isset($this->arResult[
'SKU_PROPS'][$item[
'IBLOCK_ID']]))
2514 $skuPropList = $this->arResult[
'SKU_PROPS'][$item[
'IBLOCK_ID']];
2516 $skuPropIds = array_keys($skuPropList);
2517 $matrixFields = array_fill_keys($skuPropIds,
false);
2519 foreach ($item[
'OFFERS'] as $offerKey => $offer)
2521 $offer[
'ID'] = (int)$offer[
'ID'];
2523 if (isset($double[$offer[
'ID']]))
2527 foreach ($skuPropIds as $code)
2529 $row[$code] = $this->getTemplatePropCell($code, $offer, $matrixFields, $skuPropList);
2532 $matrix[$offerKey] = $row;
2534 \CIBlockPriceTools::clearProperties($offer[
'DISPLAY_PROPERTIES'], $iblockParams[
'OFFERS_TREE_PROPS']);
2535 \CIBlockPriceTools::setRatioMinPrice($offer,
false);
2537 if ($this->arParams[
'SHOW_SLIDER'] ===
'Y')
2539 $this->editTemplateOfferSlider($offer, $item[
'IBLOCK_ID'], 5,
true, $item[
'MORE_PHOTO']);
2542 $offerPictures = \CIBlockPriceTools::getDoublePicturesForItem($offer, $iblockParams[
'OFFERS_ADD_PICT_PROP']);
2543 $offer[
'OWNER_PICT'] = empty($offerPictures[
'PICT']);
2544 $offer[
'PREVIEW_PICTURE'] =
false;
2545 $offer[
'PREVIEW_PICTURE_SECOND'] =
false;
2546 $offer[
'SECOND_PICT'] =
true;
2548 if (!$offer[
'OWNER_PICT'])
2550 if (empty($offerPictures[
'SECOND_PICT']))
2552 $offerPictures[
'SECOND_PICT'] = $offerPictures[
'PICT'];
2555 $offer[
'PREVIEW_PICTURE'] = $offerPictures[
'PICT'];
2556 $offer[
'PREVIEW_PICTURE_SECOND'] = $offerPictures[
'SECOND_PICT'];
2559 if ($iblockParams[
'OFFERS_ADD_PICT_PROP'] !=
'' && isset($offer[
'DISPLAY_PROPERTIES'][$iblockParams[
'OFFERS_ADD_PICT_PROP']]))
2561 unset($offer[
'DISPLAY_PROPERTIES'][$iblockParams[
'OFFERS_ADD_PICT_PROP']]);
2563 $offer[
'TREE'] = [];
2565 $double[$offer[
'ID']] =
true;
2566 $newOffers[$offerKey] = $offer;
2569 $item[
'OFFERS'] = $newOffers;
2571 $usedFields = array();
2572 $sortFields = array();
2574 $matrixKeys = array_keys($matrix);
2575 foreach ($skuPropIds as $propCode)
2577 $boolExist = $matrixFields[$propCode];
2578 foreach ($matrixKeys as $offerKey)
2582 $propId = $this->arResult[
'SKU_PROPS'][$item[
'IBLOCK_ID']][$propCode][
'ID'];
2583 $value = $matrix[$offerKey][$propCode][
'VALUE'];
2585 if (!isset($item[
'SKU_TREE_VALUES'][$propId]))
2587 $item[
'SKU_TREE_VALUES'][$propId] = array();
2590 $item[
'SKU_TREE_VALUES'][$propId][$value] =
true;
2591 $item[
'OFFERS'][$offerKey][
'TREE'][
'PROP_'.$propId] = $value;
2592 $item[
'OFFERS'][$offerKey][
'SKU_SORT_'.$propCode] = $matrix[$offerKey][$propCode][
'SORT'];
2593 $usedFields[$propCode] =
true;
2594 $sortFields[
'SKU_SORT_'.$propCode] = SORT_NUMERIC;
2595 unset($value, $propId);
2599 unset($matrix[$offerKey][$propCode]);
2604 unset($propCode, $matrixKeys);
2606 $item[
'OFFERS_PROP'] = $usedFields;
2607 $item[
'OFFERS_PROP_CODES'] = !empty($usedFields) ? base64_encode(serialize(array_keys($usedFields))) :
'';
2609 Collection::sortByColumn($item[
'OFFERS'], $sortFields);