• Модуль: iblock
  • Путь к файлу: ~/bitrix/modules/iblock/lib/component/base.php
  • Класс: BitrixIblockComponentBase
  • Вызов: Base::getIblockOffers
protected function getIblockOffers($iblockId)
{
	$offers = array();
	$iblockParams = $this->storage['IBLOCK_PARAMS'][$iblockId];

	$enableCompatible = $this->isEnableCompatible();

	if (
		$this->useCatalog
		&& $this->offerIblockExist($iblockId)
		&& !empty($this->productWithOffers[$iblockId])
	)
	{
		$catalog = $this->storage['CATALOGS'][$iblockId];

		$productProperty = 'PROPERTY_'.$catalog['SKU_PROPERTY_ID'];
		$productPropertyValue = $productProperty.'_VALUE';

		$offersFilter = $this->getOffersFilter($catalog['IBLOCK_ID']);
		$offersFilter[$productProperty] = $this->productWithOffers[$iblockId];

		$offersSelect = array(
			'ID' => 1,
			'IBLOCK_ID' => 1,
			'CODE' => 1,
			$productProperty => 1,
			'PREVIEW_PICTURE' => 1,
			'DETAIL_PICTURE' => 1,
		);

		if ($this->arParams['SHOW_SKU_DESCRIPTION'] === 'Y')
		{
			$offersSelect['PREVIEW_TEXT'] = 1;
			$offersSelect['DETAIL_TEXT'] = 1;
			$offersSelect['PREVIEW_TEXT_TYPE'] = 1;
			$offersSelect['DETAIL_TEXT_TYPE'] = 1;
		}

		if (!empty($iblockParams['OFFERS_FIELD_CODE']))
		{
			foreach ($iblockParams['OFFERS_FIELD_CODE'] as $code)
				$offersSelect[$code] = 1;
			unset($code);
		}

		$offersSelect = $this->getProductSelect($iblockId, array_keys($offersSelect));

		$getListParams = $this->prepareQueryFields($offersSelect, $offersFilter, $this->getOffersSort());
		$offersSelect = $getListParams['SELECT'];
		$offersFilter = $getListParams['FILTER'];
		$offersOrder = $getListParams['ORDER'];
		unset($getListParams);

		$checkFields = array();
		foreach (array_keys($offersOrder) as $code)
		{
			$code = mb_strtoupper($code);
			if ($code == 'ID' || $code == 'AVAILABLE')
				continue;
			$checkFields[] = $code;
		}
		unset($code);

		$productFields = $this->getProductFields($iblockId);
		$translateFields = $this->getCompatibleProductFields();

		$offersId = array();
		$offersCount = array();
		$iterator = CIBlockElement::GetList(
			$offersOrder,
			$offersFilter,
			false,
			false,
			$offersSelect
		);
		while($row = $iterator->GetNext())
		{
			$row['ID'] = (int)$row['ID'];
			$row['IBLOCK_ID'] = (int)$row['IBLOCK_ID'];
			$productId = (int)$row[$productPropertyValue];

			if ($productId <= 0)
				continue;

			if ($enableCompatible && $this->arParams['OFFERS_LIMIT'] > 0)
			{
				$offersCount[$productId]++;
				if($offersCount[$productId] > $this->arParams['OFFERS_LIMIT'])
					continue;
			}

			$row['SORT_HASH'] = 'ID';
			if (!empty($checkFields))
			{
				$checkValues = '';
				foreach ($checkFields as $code)
					$checkValues .= ($row[$code] ?? '').'|';
				unset($code);
				if ($checkValues != '')
					$row['SORT_HASH'] = md5($checkValues);
				unset($checkValues);
			}
			$row['LINK_ELEMENT_ID'] = $productId;
			$row['PROPERTIES'] = array();
			$row['DISPLAY_PROPERTIES'] = array();

			$row['PRODUCT'] = array(
				'TYPE' => (int)$row['~TYPE'],
				'AVAILABLE' => $row['~AVAILABLE'],
				'BUNDLE' => $row['~BUNDLE'],
				'QUANTITY' => $row['~QUANTITY'],
				'QUANTITY_TRACE' => $row['~QUANTITY_TRACE'],
				'CAN_BUY_ZERO' => $row['~CAN_BUY_ZERO'],
				'MEASURE' => (int)$row['~MEASURE'],
				'SUBSCRIBE' => $row['~SUBSCRIBE'],
				'VAT_ID' => (int)$row['~VAT_ID'],
				'VAT_RATE' => 0,
				'VAT_INCLUDED' => $row['~VAT_INCLUDED'],
				'WEIGHT' => (float)$row['~WEIGHT'],
				'WIDTH' => (float)$row['~WIDTH'],
				'LENGTH' => (float)$row['~LENGTH'],
				'HEIGHT' => (float)$row['~HEIGHT'],
				'PAYMENT_TYPE' => $row['~PAYMENT_TYPE'],
				'RECUR_SCHEME_TYPE' => $row['~RECUR_SCHEME_TYPE'],
				'RECUR_SCHEME_LENGTH' => (int)$row['~RECUR_SCHEME_LENGTH'],
				'TRIAL_PRICE_ID' => (int)$row['~TRIAL_PRICE_ID']
			);

			$vatId = 0;
			$vatRate = 0;
			if ($row['PRODUCT']['VAT_ID'] > 0)
				$vatId = $row['PRODUCT']['VAT_ID'];
			elseif ($this->storage['IBLOCKS_VAT'][$catalog['IBLOCK_ID']] > 0)
				$vatId = $this->storage['IBLOCKS_VAT'][$catalog['IBLOCK_ID']];
			if ($vatId > 0 && isset($this->storage['VATS'][$vatId]))
				$vatRate = $this->storage['VATS'][$vatId];
			$row['PRODUCT']['VAT_RATE'] = $vatRate;
			unset($vatRate, $vatId);

			if ($enableCompatible)
			{
				foreach ($translateFields as $currentKey => $oldKey)
					$row[$oldKey] = $row[$currentKey];
				unset($currentKey, $oldKey);
				$row['~CATALOG_VAT'] = $row['PRODUCT']['VAT_RATE'];
				$row['CATALOG_VAT'] = $row['PRODUCT']['VAT_RATE'];
			}
			else
			{
				// temporary (compatibility custom templates)
				$row['~CATALOG_TYPE'] = $row['PRODUCT']['TYPE'];
				$row['CATALOG_TYPE'] = $row['PRODUCT']['TYPE'];
				$row['~CATALOG_QUANTITY'] = $row['PRODUCT']['QUANTITY'];
				$row['CATALOG_QUANTITY'] = $row['PRODUCT']['QUANTITY'];
				$row['~CATALOG_QUANTITY_TRACE'] = $row['PRODUCT']['QUANTITY_TRACE'];
				$row['CATALOG_QUANTITY_TRACE'] = $row['PRODUCT']['QUANTITY_TRACE'];
				$row['~CATALOG_CAN_BUY_ZERO'] = $row['PRODUCT']['CAN_BUY_ZERO'];
				$row['CATALOG_CAN_BUY_ZERO'] = $row['PRODUCT']['CAN_BUY_ZERO'];
				$row['~CATALOG_SUBSCRIBE'] = $row['PRODUCT']['SUBSCRIBE'];
				$row['CATALOG_SUBSCRIBE'] = $row['PRODUCT']['SUBSCRIBE'];
			}

			foreach ($productFields as $field)
				unset($row[$field], $row['~'.$field]);
			unset($field);

			if ($row['PRODUCT']['TYPE'] == CatalogProductTable::TYPE_OFFER)
				$this->calculatePrices[$row['ID']] = $row['ID'];

			$row['ITEM_PRICE_MODE'] = null;
			$row['ITEM_PRICES'] = array();
			$row['ITEM_QUANTITY_RANGES'] = array();
			$row['ITEM_MEASURE_RATIOS'] = array();
			$row['ITEM_MEASURE'] = array();
			$row['ITEM_MEASURE_RATIO_SELECTED'] = null;
			$row['ITEM_QUANTITY_RANGE_SELECTED'] = null;
			$row['ITEM_PRICE_SELECTED'] = null;
			$row['CHECK_QUANTITY'] = $this->isNeedCheckQuantity($row['PRODUCT']);

			if ($row['PRODUCT']['MEASURE'] > 0)
			{
				$row['ITEM_MEASURE'] = array(
					'ID' => $row['PRODUCT']['MEASURE'],
					'TITLE' => '',
					'~TITLE' => ''
				);
			}
			else
			{
				$row['ITEM_MEASURE'] = array(
					'ID' => null,
					'TITLE' => $this->storage['DEFAULT_MEASURE']['SYMBOL_RUS'],
					'~TITLE' => $this->storage['DEFAULT_MEASURE']['~SYMBOL_RUS']
				);
			}
			if ($enableCompatible)
			{
				$row['CATALOG_MEASURE'] = $row['ITEM_MEASURE']['ID'];
				$row['CATALOG_MEASURE_NAME'] = $row['ITEM_MEASURE']['TITLE'];
				$row['~CATALOG_MEASURE_NAME'] = $row['ITEM_MEASURE']['~TITLE'];
			}

			$row['PROPERTIES'] = array();
			$row['DISPLAY_PROPERTIES'] = array();

			IblockComponentTools::getFieldImageData(
				$row,
				array('PREVIEW_PICTURE', 'DETAIL_PICTURE'),
				IblockComponentTools::IPROPERTY_ENTITY_ELEMENT,
				''
			);

			$offersId[$row['ID']] = $row['ID'];
			$offers[$row['ID']] = $row;
		}
		unset($row, $iterator);

		if (!empty($offersId))
		{
			$loadPropertyCodes = ($iblockParams['OFFERS_PROPERTY_CODE'] ?? []);
			if (IblockModelPropertyFeature::isEnabledFeatures())
			{
				$loadPropertyCodes = array_merge($loadPropertyCodes, $iblockParams['OFFERS_TREE_PROPS'] ?? []);
			}

			$propertyList = $this->getPropertyList($catalog['IBLOCK_ID'], $loadPropertyCodes);
			unset($loadPropertyCodes);

			if (!empty($propertyList) || $this->useDiscountCache)
			{
				CIBlockElement::GetPropertyValuesArray($offers, $catalog['IBLOCK_ID'], $offersFilter);
				foreach ($offers as &$row)
				{
					if ($this->useDiscountCache)
					{
						if ($this->storage['USE_SALE_DISCOUNTS'])
							CatalogDiscountDiscountManager::setProductPropertiesCache($row['ID'], $row["PROPERTIES"]);
						else
							CCatalogDiscount::SetProductPropertiesCache($row['ID'], $row["PROPERTIES"]);
					}

					if (!empty($propertyList))
					{
						foreach ($propertyList as $pid)
						{
							if (!isset($row["PROPERTIES"][$pid]))
								continue;
							$prop = &$row["PROPERTIES"][$pid];
							$boolArr = is_array($prop["VALUE"]);
							if (
								($boolArr && !empty($prop["VALUE"])) ||
								(!$boolArr && (string)$prop["VALUE"] !== '')
							)
							{
								$row["DISPLAY_PROPERTIES"][$pid] = CIBlockFormatProperties::GetDisplayValue($row, $prop);
							}
							unset($boolArr, $prop);
						}
						unset($pid);
					}
				}
				unset($row);
			}
			if (!empty($propertyList))
			{
				CIBlockFormatProperties::clearCache();
			}

			if ($this->useDiscountCache)
			{
				if ($this->storage['USE_SALE_DISCOUNTS'])
				{
					CatalogDiscountDiscountManager::preloadPriceData($offersId, $this->storage['PRICES_ALLOW']);
					CatalogDiscountDiscountManager::preloadProductDataToExtendOrder($offersId, $this->getUserGroups());
				}
				else
				{
					CCatalogDiscount::SetProductSectionsCache($offersId);
					CCatalogDiscount::SetDiscountProductCache($offersId, array('IBLOCK_ID' => $catalog['IBLOCK_ID'], 'GET_BY_ID' => 'Y'));
				}
			}
		}
		unset($offersId);
	}

	return $offers;
}