403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/catalog/lib/v2/Sku/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/catalog/lib/v2/Sku/SkuRepository.php
<?php

namespace Bitrix\Catalog\v2\Sku;

use Bitrix\Catalog\ProductTable;
use Bitrix\Catalog\v2\BaseIblockElementEntity;
use Bitrix\Catalog\v2\BaseIblockElementRepository;
use Bitrix\Catalog\v2\Iblock\IblockInfo;
use Bitrix\Catalog\v2\Product\BaseProduct;
use Bitrix\Catalog\v2\Product\ProductRepositoryContract;
use Bitrix\Catalog\v2\Property\Property;
use Bitrix\Catalog\v2\Property\PropertyCollection;
use Bitrix\Catalog\v2\Property\PropertyRepositoryContract;

/**
 * Class SkuRepository
 *
 * @package Bitrix\Catalog\v2\Sku
 *
 * !!! This API is in alpha stage and is not stable. This is subject to change at any time without notice.
 * @internal
 */
class SkuRepository extends BaseIblockElementRepository implements SkuRepositoryContract
{
	/** @var \Bitrix\Catalog\v2\Sku\SkuFactory */
	protected $factory;
	/** @var \Bitrix\Catalog\v2\Product\ProductRepositoryContract */
	protected $productRepository;
	/** @var \Bitrix\Catalog\v2\Property\PropertyRepositoryContract */
	protected $propertyRepository;

	/**
	 * SkuRepository constructor.
	 *
	 * @param \Bitrix\Catalog\v2\Sku\SkuFactory $factory
	 * @param \Bitrix\Catalog\v2\Iblock\IblockInfo $iblockInfo
	 * @param \Bitrix\Catalog\v2\Product\ProductRepositoryContract $productRepository
	 * @param \Bitrix\Catalog\v2\Property\PropertyRepositoryContract $propertyRepository
	 */
	public function __construct(
		SkuFactory $factory,
		IblockInfo $iblockInfo,
		ProductRepositoryContract $productRepository,
		PropertyRepositoryContract $propertyRepository
	)
	{
		parent::__construct($factory, $iblockInfo);
		$this->productRepository = $productRepository;
		$this->propertyRepository = $propertyRepository;
	}

	/**
	 * @param \Bitrix\Catalog\v2\Product\BaseProduct $product
	 * @return \Bitrix\Catalog\v2\Sku\SkuCollection|\Bitrix\Catalog\v2\Sku\BaseSku[]
	 */
	public function getCollectionByProduct(BaseProduct $product): SkuCollection
	{
		$callback = function (array $params) use ($product) {
			yield from $this->getSkuIteratorForProduct($product, $params);
		};

		return $this->factory
			->createCollection()
			->setIteratorCallback($callback)
		;
	}

	/**
	 * Sku entities for product.
	 *
	 * @param BaseProduct $product
	 * @param array $params parameters for `getList` method
	 *
	 * @return \Bitrix\Catalog\v2\Sku\Sku[]
	 */
	public function getEntitiesByProduct(BaseProduct $product, array $params): \Generator
	{
		return $this->getSkuIteratorForProduct($product, $params);
	}

	/**
	 * @param \Bitrix\Catalog\v2\Product\BaseProduct $product
	 * @return \Bitrix\Catalog\v2\Sku\SkuCollection|\Bitrix\Catalog\v2\Sku\BaseSku[]
	 */
	public function loadEagerCollectionByProduct(BaseProduct $product): SkuCollection
	{
		$callback = function (array $params) use ($product) {
			yield from $this->getSkuIteratorEagerLoading($product, $params);
		};

		return $this->factory
			->createCollection()
			->setIteratorCallback($callback)
		;
	}

	public function getEntitiesBy($params): array
	{
		$sku = parent::getEntitiesBy($params);

		if (!empty($sku))
		{
			$this->loadParentProducts(...$sku);
		}

		return $sku;
	}

	protected function getAdditionalFilter(): array
	{
		$filter = parent::getAdditionalFilter();
		$filter['IBLOCK_ID'] = $this->iblockInfo->getSkuIblockId();

		return $filter;
	}

	protected function getAdditionalProductFilter(): array
	{
		$filter = parent::getAdditionalProductFilter();

		$filter['=TYPE'] = [
			ProductTable::TYPE_PRODUCT,
			ProductTable::TYPE_OFFER,
			ProductTable::TYPE_FREE_OFFER,
		];

		return $filter;
	}

	protected function makeEntity(array $fields = []): BaseIblockElementEntity
	{
		$type = (int)($fields['TYPE'] ?? 0);

		if ($type === ProductTable::TYPE_OFFER || $type === ProductTable::TYPE_FREE_OFFER)
		{
			$entityClass = $this->factory::SKU;
		}
		else
		{
			$entityClass = $this->factory::SIMPLE_SKU;
		}

		return $this->factory->createEntity($entityClass);
	}

	private function loadParentProducts(BaseSku ...$skuItems): void
	{
		$skuByProductMap = $this->getSkuByProductMap($skuItems);

		if (!empty($skuByProductMap))
		{
			$products = $this->productRepository->getEntitiesBy([
				'filter' => [
					'=ID' => array_keys($skuByProductMap),
				],
			]);

			/** @var BaseProduct $product */
			foreach ($products as $product)
			{
				$productSkuItems = $skuByProductMap[$product->getId()] ?? [];
				$skuCollection = $this->getCollectionByProduct($product)
					->setParent($product)
					->add(...$productSkuItems)
				;
				$product->setSkuCollection($skuCollection);
			}
		}
	}

	private function getSkuByProductMap(array $skuItems): array
	{
		$skuByProductMap = [];

		$skuMap = [];
		/** @var \Bitrix\Catalog\v2\Sku\BaseSku $sku */
		foreach ($skuItems as $sku)
		{
			if ($sku->getParent() === null)
			{
				$skuMap[$sku->getId()] = $sku;
			}
		}

		if (!empty($skuMap))
		{
			$skuPropertyId = $this->iblockInfo->getSkuPropertyId();
			$propertyValuesIterator = \CIBlockElement::GetPropertyValues(
				$this->iblockInfo->getSkuIblockId(),
				['ID' => array_keys($skuMap)],
				false,
				['ID' => $skuPropertyId]
			);

			while ($propertyValues = $propertyValuesIterator->fetch())
			{
				$productId = $propertyValues[$skuPropertyId];
				$sku = $skuMap[$propertyValues['IBLOCK_ELEMENT_ID']];

				$skuByProductMap[$productId][] = $sku;
			}
		}

		return $skuByProductMap;
	}

	private function getSkuIteratorForProduct(BaseProduct $product, array $params = []): \Generator
	{
		if ($product->isSimple())
		{
			if ($product->getSkuCollection()->isEmpty())
			{
				yield $this->createEntity();
			}
		}
		elseif (!$product->isNew())
		{
			$params['filter']['PROPERTY_' . $this->iblockInfo->getSkuPropertyId()] = $product->getId();
			$params['order']['ID'] ??= 'DESC';

			foreach ($this->getList($params) as $item)
			{
				yield $this->createEntity($item);
			}
		}
	}

	private function getSkuIteratorEagerLoading(BaseProduct $product, array $params = []): \Generator
	{
		if ($product->isSimple())
		{
			if ($product->getSkuCollection()->isEmpty())
			{
				yield $this->createEntity();
			}
		}
		elseif (!$product->isNew())
		{
			$params['filter']['PROPERTY_' . $this->iblockInfo->getSkuPropertyId()] = $product->getId();
			$params['order']['ID'] = 'DESC';

			$items = [];
			foreach ($this->getList($params) as $item)
			{
				$items[$item['ID']] = $item;
			}

			$skuIds = array_keys($items);

			$propertySettings = $this->propertyRepository->getPropertiesSettingsByFilter([
				'=IBLOCK_ID' => $this->iblockInfo->getSkuIblockId(),
			]);

			$propertyElementMap = $this->getPropertyMapBySkuIds($skuIds, $propertySettings);

			foreach ($items as $skuId => $item)
			{
				$propertyCollection = $this->propertyRepository->createCollection();

				foreach ($propertySettings as $setting)
				{
					$propertyItem =
						$propertyElementMap[$skuId][$setting['ID']]
						?? $this->propertyRepository->createEntity([], $setting)
					;

					if ($propertyItem)
					{
						$propertyCollection->add($propertyItem);
					}
				}

				yield $this->createEntity($item, $propertyCollection);
			}
		}
	}

	/**
	 * @param array $skuIds
	 * @param array $propertySettings
	 * @return array
	 */
	private function getPropertyMapBySkuIds(array $skuIds, array $propertySettings): array
	{
		$skuPropertyFilter = [
			'filter' => [
				'IBLOCK_ID' => $this->iblockInfo->getSkuIblockId(),
				'ID' => $skuIds,
			],
		];

		$properties = $this->propertyRepository->getEntitiesBy($skuPropertyFilter, $propertySettings);
		$propertyElementMap = [];

		/** @var Property $property */
		foreach ($properties as $property)
		{
			$elementId = $property->getSetting('IBLOCK_ELEMENT_ID');

			if ($elementId > 0)
			{
				$propertyElementMap[$elementId] = $propertyElementMap[$elementId] ?? [];
				$propertyElementMap[$elementId][$property->getSetting('ID')] = $property;
			}
		}

		return $propertyElementMap;
	}

	protected function createEntity(array $fields = [], PropertyCollection $propertyCollection = null): BaseIblockElementEntity
	{
		$entity = parent::createEntity($fields);

		if ($propertyCollection)
		{
			$entity->setPropertyCollection($propertyCollection);
		}

		return $entity;
	}

	public function setDetailUrlTemplate(?string $template): BaseIblockElementRepository
	{
		if (isset($this->productRepository))
		{
			if ($this->productRepository->getDetailUrlTemplate() === null)
			{
				$this->productRepository->setDetailUrlTemplate($template);
				$this->productRepository->setAutoloadDetailUrl($template !== null);
			}
		}

		return parent::setDetailUrlTemplate($template);
	}

	public function setAutoloadDetailUrl(bool $state): BaseIblockElementRepository
	{
		if (isset($this->productRepository))
		{
			$this->productRepository->setAutoloadDetailUrl($state);
		}

		return parent::setAutoloadDetailUrl($state);
	}

	public function getCountByProductId(int $productId): int
	{
		$filter = [
			'PROPERTY_' . $this->iblockInfo->getSkuPropertyId() => $productId,
		];

		return \CIBlockElement::GetList(
			[],
			array_merge(
				[
					// 'ACTIVE' => 'Y',
					// 'ACTIVE_DATE' => 'Y',
				],
				$filter,
				$this->getAdditionalFilter()
			),
			[]
		);
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit