• Модуль: catalog
  • Путь к файлу: ~/bitrix/modules/catalog/lib/product/catalogprovider.php
  • Класс: BitrixCatalogProductCatalogProvider
  • Вызов: CatalogProvider::getData
private function getData(array $products, array $options = array()): SaleResult
	{
		$context = $this->getContext();

		$resultProductList = array_fill_keys(array_keys($products), false);

		$result = new SaleResult();

		$userId = (int)($context['USER_ID'] ?? 0);
		if ($userId < 0)
		{
			$userId = 0;
		}
		$siteId = $context['SITE_ID'] ?? false;
		$currency = $context['CURRENCY'] ?? false;
		$currency = (is_string($currency) ? CurrencyCurrencyManager::checkCurrencyID($context['CURRENCY']) : false);
		if ($currency === false)
		{
			$currency = SaleInternalsSiteCurrencyTable::getSiteCurrency($siteId ?: SITE_ID);
		}
		$adminSection = (defined('ADMIN_SECTION') && ADMIN_SECTION === true);

		if (in_array('DISABLE_CACHE', $options))
		{
			$this->enableCache = false;
		}

		$catalogDataEnabled = self::isCatalogDataEnabled($options);

		$outputVariable = static::getOutputVariable($options);

		$productGetIdList = array();
		$correctProductIds = [];

		$iblockElementSelect = array('ID', 'IBLOCK_ID', 'IBLOCK_SECTION_ID', 'ACTIVE', 'ACTIVE_DATE', 'XML_ID');
		if (!$catalogDataEnabled)
		{
			$iblockElementSelect = array_merge($iblockElementSelect, array('NAME', 'DETAIL_PAGE_URL'));
		}

		$resultList = array();
		foreach ($products as $productId => $itemData)
		{
			$resultList[$productId] = false;
			if (!isset($itemData['ITEM_CODE']))
			{
				$itemData['ITEM_CODE'] = $productId;
				$products[$productId]['ITEM_CODE'] = $productId;
			}

			if (!isset($itemData['BASKET_CODE']))
			{
				$itemData['BASKET_CODE'] = $productId;
				$products[$productId]['BASKET_CODE'] = $productId;
			}

			$hash = $productId."|".$userId;
			$productCachedData = static::getHitCache(self::CACHE_ITEM_RIGHTS, $hash, $iblockElementSelect);
			if ($this->enableCache && !empty($productCachedData))
			{
				$products[$productId]['PRODUCT_DATA'] = $productCachedData;
				$correctProductIds[$productId] = true;
			}
			else
			{
				$productGetIdList[] = $productId;
			}
		}

		if (!empty($productGetIdList))
		{
			$productDataList = $this->getElements(
				$productGetIdList,
				$iblockElementSelect,
				($adminSection ? $userId : null)
			);

			foreach ($productDataList as $productId => $productData)
			{
				$products[$productId]['PRODUCT_DATA'] = $productData;
				$hash = $productId."|".$userId;
				static::setHitCache(self::CACHE_ITEM_RIGHTS, $hash, $productData);
				$correctProductIds[$productId] = true;
			}

			$products = array_intersect_key(
				$products,
				$correctProductIds
			);
			if (empty($products))
			{
				return static::getResultProvider($result, $outputVariable, $resultList);
			}
		}
		unset($correctProductIds);

		$iblockList = array();
		$iblockDataList = array();
		$iblockGetIdList = array();
		foreach ($products as $productId => $productData)
		{
			$iblockId = $productData['PRODUCT_DATA']['IBLOCK_ID'];
			$iblockList[$iblockId][] = $productId;
		}

		foreach ($iblockList as $iblockId => $iblockProductIdList)
		{
			$iblockData = static::getHitCache(self::CACHE_CATALOG_IBLOCK_LIST, $iblockId);
			if ($this->enableCache && !empty($iblockData))
			{
				$iblockDataList[$iblockId] = $iblockData;
			}
			else
			{
				$iblockGetIdList[] = $iblockId;
			}
		}

		if (!empty($iblockGetIdList))
		{
			$iblockDataList = $this->getIblockData($iblockGetIdList) + $iblockDataList;
		}

		$iblockList = array_intersect_key(
			$iblockList,
			$iblockDataList
		);

		$iblockProductMap = static::createIblockProductMap($iblockList, $iblockDataList);

		$correctProductList = static::checkSkuPermission($iblockProductMap);

		$products = array_intersect_key(
			$products,
			array_fill_keys($correctProductList, true)
		);
		if (empty($products))
		{
			return static::getResultProvider($result, $outputVariable, $resultList);
		}

		$products = static::changeSubscribeProductQuantity($products, $iblockProductMap);

		// catalog product

		$catalogSelect = array(
			'ID',
			'CAN_BUY_ZERO',
			'QUANTITY_TRACE',
			'QUANTITY',
			'QUANTITY_RESERVED',
			'MEASURE',
			'TYPE',
			'AVAILABLE',
		);
		if (!$catalogDataEnabled)
		{
			$catalogSelect = array_merge($catalogSelect, array(
				'WEIGHT',
				'WIDTH',
				'HEIGHT',
				'LENGTH',
				'BARCODE_MULTI'
			));
		}
		$catalogSelect = array_merge($catalogSelect, CatalogProductSystemField::getProviderSelectFields());

		$catalogProductDataList = static::getCatalogProducts(array_keys($products), $catalogSelect);

		$products = array_intersect_key($products, $catalogProductDataList);
		if (empty($products))
		{
			return static::getResultProvider($result, $outputVariable, $resultList);
		}

		// fill catalog xml id
		$products = self::fillCatalogXmlId($products, $iblockProductMap);
		// prepare offers xml id
		$products = self::fillOfferXmlId($products, $catalogProductDataList);

		// get prices and discounts
		$priceDataList = self::getPriceDataList(
			$products,
			[
				'IS_ADMIN_SECTION' => $adminSection,
				'USER_ID' => $userId,
				'SITE_ID' => $siteId,
				'CURRENCY' => $currency,
			]
		);
		$discountList = self::getDiscountList($priceDataList);

		$productQuantityList = array();
		$productPriceList = array();

		$fullQuantityMode = in_array('FULL_QUANTITY', $options);

		foreach ($products as $productId => $productData)
		{
			$catalogProductData = $catalogProductDataList[$productId];

			$quantityList = array();

			if (array_key_exists('QUANTITY', $productData))
			{
				$quantityList = array($productData['BASKET_CODE'] => $productData['QUANTITY']);
			}

			if (!empty($productData[Base::FLAT_QUANTITY_LIST]))
			{
				$quantityList = $productData[Base::FLAT_QUANTITY_LIST];
			}

			$productQuantityList[$productData['BASKET_CODE']]['QUANTITY_RESERVED'] = $catalogProductData['QUANTITY_RESERVED'];

			$baseCatalogQuantity = (float)$catalogProductData['QUANTITY'];

			$allCount = count($quantityList);
			$sumQuantity = 0;
			foreach ($quantityList as $quantity)
			{
				$sumQuantity += (float)abs($quantity);
			}

			$catalogQuantityForAvaialable = $baseCatalogQuantity;
			$checkCatalogQuantity = $baseCatalogQuantity;

			$isEnough = !($catalogProductData['CHECK_QUANTITY'] && $catalogQuantityForAvaialable < $sumQuantity);
			$setQuantity = $baseCatalogQuantity;
			foreach ($quantityList as $basketCode => $quantity)
			{
				$quantity = (float)abs($quantity);

				if (!$isEnough)
				{
					if ($catalogQuantityForAvaialable - $quantity < 0)
					{
						$quantity = $catalogQuantityForAvaialable;
					}

					$catalogQuantityForAvaialable -= $quantity;
				}

				$productQuantityList[$basketCode]['AVAILABLE_QUANTITY'] = (
					$baseCatalogQuantity >= $quantity || !$catalogProductData['CHECK_QUANTITY']
						? $quantity
						: $baseCatalogQuantity
				);

				if ($fullQuantityMode)
				{
					$checkCatalogQuantity -= $quantity;
					$setQuantity = $quantity;
					$allCount--;

					if ($allCount == 0)
					{
						$setQuantity = $checkCatalogQuantity + $quantity;
					}
				}
				else
				{
					if ($baseCatalogQuantity - $quantity > 0 || !$catalogProductData['CHECK_QUANTITY'])
					{
						$setQuantity = $quantity;
					}
				}

				$productQuantityList[$basketCode]['QUANTITY'] = $setQuantity;
			}
			unset($basketCode, $quantity);

			foreach (array_keys($quantityList) as $basketCode)
			{
				if (isset($priceDataList[$productId][$basketCode]))
				{
					$productPriceList[$basketCode] = $priceDataList[$productId][$basketCode];
				}
			}
			unset($basketCode);

			$measure = isset($catalogProductData['MEASURE']) ? (int)$catalogProductData['MEASURE'] : null;
			$measureFields = static::getMeasure($measure);
			if (!empty($measureFields))
			{
				$catalogProductDataList[$productId] = $measureFields + $catalogProductDataList[$productId];
			}
		}

		unset($fullQuantityMode);

		$resultData = static::setCatalogDataToProducts($products, $catalogProductDataList, $options);

		$priceResultList = static::createProductPriceList($products, $productPriceList, $discountList);

		$resultList = static::createProductResult($products, $resultData, $priceResultList, $productQuantityList);

		$resultList = $resultList + $resultProductList;

		return static::getResultProvider($result, $outputVariable, $resultList);
	}