- Модуль: iblock
- Путь к файлу: ~/bitrix/modules/iblock/lib/component/elementlist.php
- Класс: BitrixIblockComponentElementList
- Вызов: ElementList::sortItemsByTemplateVariants
protected function sortItemsByTemplateVariants()
{
$rows = array();
$variantsMap = static::getTemplateVariantsMap();
$isBigData = $this->getAction() === 'bigDataLoad';
if ($this->arParams['ENLARGE_PRODUCT'] === 'PROP')
{
$enlargedIndexMap = $this->getEnlargedIndexMap();
}
if (!empty($this->arParams['PRODUCT_ROW_VARIANTS']))
{
$showItems = false;
foreach ($this->arParams['PRODUCT_ROW_VARIANTS'] as $variant)
{
if (
(!$isBigData && !$variant['BIG_DATA'])
|| ($isBigData && $variant['BIG_DATA'])
)
{
$showItems = true;
break;
}
}
}
else
{
$showItems = true;
}
if ($showItems)
{
$variantParam = false;
$itemsCounter = 0;
$itemsLength = count($this->arResult['ITEMS']);
while (($itemsRemaining = $itemsLength - $itemsCounter) > 0)
{
if ($variantParam === false)
{
$variantParam = reset($this->arParams['PRODUCT_ROW_VARIANTS']);
}
// skip big_data rows on initial load and not_big_data rows on deferred load
if (!empty($variantParam))
{
if (
$isBigData && !$variantParam['BIG_DATA']
|| !$isBigData && $variantParam['BIG_DATA']
)
{
$variantParam = next($this->arParams['PRODUCT_ROW_VARIANTS']);
// if last variant is not suitable - should reset again
if ($variantParam === false)
{
$variantParam = reset($this->arParams['PRODUCT_ROW_VARIANTS']);
}
if ($variantParam === false)
break;
else
continue;
}
}
if (
$variantParam === false
|| !isset($variantsMap[$variantParam['VARIANT']])
|| ($variantsMap[$variantParam['VARIANT']]['SHOW_ONLY_FULL'] && $variantsMap[$variantParam['VARIANT']]['COUNT'] > $itemsRemaining)
)
{
// default variant
$variant = $variantsMap[self::getDefaultVariantId()];
}
else
{
$variant = $variantsMap[$variantParam['VARIANT']];
}
// sorting by property $arResult['ITEMS'] for proper elements enlarge
if ($this->arParams['ENLARGE_PRODUCT'] === 'PROP' && $variant['ENLARGED_POS'] !== false)
{
if (!empty($enlargedIndexMap))
{
$overallPos = $itemsCounter + $variant['ENLARGED_POS'];
$overallPosKey = array_search($overallPos, $enlargedIndexMap);
if ($overallPosKey === false)
{
$closestPos = false;
$closestPosKey = false;
$enlargedPosInRange = array_intersect($enlargedIndexMap , range($itemsCounter, $itemsCounter + $variant['COUNT']));
if (!empty($enlargedPosInRange))
{
foreach ($enlargedPosInRange as $key => $posInRange)
{
if ($closestPos === false || abs($overallPos - $closestPos) > abs($posInRange - $overallPos))
{
$closestPos = $posInRange;
$closestPosKey = $key;
}
}
$temporary = array($this->arResult['ITEMS'][$closestPos]);
unset($this->arResult['ITEMS'][$closestPos], $enlargedIndexMap[$closestPosKey]);
array_splice($this->arResult['ITEMS'], $overallPos, 0, $temporary);
}
}
else
{
unset($enlargedIndexMap[$overallPosKey]);
}
}
}
$rows[] = $variant;
$itemsCounter += $variant['COUNT'];
$variantParam = next($this->arParams['PRODUCT_ROW_VARIANTS']);
}
}
$this->arResult['ITEM_ROWS'] = $rows;
}