1
0
mirror of synced 2024-11-30 09:16:06 +03:00
bitrix-module/intaro.retailcrm/lib/icml/xmlofferdirector.php

330 lines
12 KiB
PHP
Raw Normal View History

2021-05-31 16:33:02 +03:00
<?php
namespace Intaro\RetailCrm\Icml;
2021-09-08 16:31:17 +03:00
use CIBlock;
use CIBlockSection;
2021-05-31 16:33:02 +03:00
use Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo;
use Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams;
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer;
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetup;
use Intaro\RetailCrm\Repository\CatalogRepository;
use Intaro\RetailCrm\Repository\FileRepository;
use Intaro\RetailCrm\Repository\HlRepository;
use Intaro\RetailCrm\Repository\MeasureRepository;
use Intaro\RetailCrm\Repository\SiteRepository;
/**
* Class XmlOfferDirector
* @package Intaro\RetailCrm\Icml
*/
class XmlOfferDirector
{
/**
* @var \Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetup
*/
private $setup;
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
/**
* @var \Intaro\RetailCrm\Repository\FileRepository
*/
private $fileRepository;
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
/**
* @var \Intaro\RetailCrm\Repository\CatalogRepository
*/
private $catalogRepository;
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
/**
* @var \Intaro\RetailCrm\Icml\XmlOfferBuilder
*/
2021-09-08 16:31:17 +03:00
private $xmlOfferBuilder;
/**
* @var array
*/
private $barcodes;
2021-05-31 16:33:02 +03:00
/**
* XmlOfferFactory constructor.
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetup $setup
*/
public function __construct(XmlSetup $setup)
{
$this->setup = $setup;
$this->fileRepository = new FileRepository(SiteRepository::getDefaultServerName());
$this->catalogRepository = new CatalogRepository();
$this->xmlOfferBuilder = new XmlOfferBuilder(
$setup,
MeasureRepository::getMeasures(),
SiteRepository::getDefaultServerName()
);
2021-09-08 16:31:17 +03:00
$this->barcodes = $this->catalogRepository->getBarcodes();
2021-05-31 16:33:02 +03:00
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
/**
* Возвращает страницу (массив) с товарами или торговыми предложениями (в зависимости от $param)
*
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams $param
* @param \Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo $catalogIblockInfo
* @return XmlOffer[]
*/
public function getXmlOffersPart(SelectParams $param, CatalogIblockInfo $catalogIblockInfo): array
{
$ciBlockResult = $this->catalogRepository->getProductPage($param, $catalogIblockInfo, $this->setup->loadNonActivity);
2021-05-31 16:33:02 +03:00
$offers = [];
2021-09-08 16:31:17 +03:00
while ($offer = $ciBlockResult->Fetch()) {
$categories = $this->catalogRepository->getProductCategories($offer['ID']);
$offer['DETAIL_PAGE_URL'] = $this->replaceUrlTemplate($offer, $categories);
$this->setXmlOfferParams($param, $offer, $catalogIblockInfo);
$this->xmlOfferBuilder
->setCategories(array_column($categories, 'IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID'));
2021-05-31 16:33:02 +03:00
$offers[] = $this->xmlOfferBuilder->build();
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
return $offers;
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
/**
* возвращает массив XmlOffers для конкретного продукта
*
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams $paramsForOffer
* @param \Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo $catalogIblockInfo
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer $product
* @return XmlOffer[]
*/
public function getXmlOffersBySingleProduct(
SelectParams $paramsForOffer,
CatalogIblockInfo $catalogIblockInfo,
XmlOffer $product
): array {
$xmlOffers = $this->getXmlOffersPart($paramsForOffer, $catalogIblockInfo);
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
return $this->addProductInfo($xmlOffers, $product);
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
/**
* Декорирует оферы информацией из товаров
*
* @param XmlOffer[] $xmlOffers
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer $product
* @return \Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer[]
*/
private function addProductInfo(array $xmlOffers, XmlOffer $product): array
{
foreach ($xmlOffers as $offer) {
$offer->productId = $product->id;
2021-09-08 10:05:09 +03:00
$offer->params = $this->mergeParams($offer->params, $product->params);
2021-05-31 16:33:02 +03:00
$offer->unitCode = $offer->unitCode === null ? null : $offer->unitCode->merge($product->unitCode);
$offer->vatRate = $offer->vatRate === 'none' ? $product->vatRate : $offer->vatRate;
$offer->vendor = $offer->mergeValues($product->vendor, $offer->vendor);
$offer->picture = $offer->mergeValues($product->picture, $offer->picture);
$offer->weight = $offer->mergeValues($product->weight, $offer->weight);
$offer->dimensions = $offer->mergeValues($product->dimensions, $offer->dimensions);
2021-09-08 16:31:17 +03:00
$offer->barcode = $offer->mergeValues($product->barcode, $offer->barcode);
2021-05-31 16:33:02 +03:00
$offer->categoryIds = $product->categoryIds;
$offer->productName = $product->productName;
2021-09-08 16:31:17 +03:00
$offer->url = $this->mergeUrls($product->url, $offer->url);
2021-05-31 16:33:02 +03:00
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
return $xmlOffers;
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
/**
* Получение настраиваемых параметров, если они лежат в HL-блоке
*
* @param int $iblockId //ID инфоблока товаров, даже если данные нужны по SKU
* @param array $productProps
* @param array $configurableParams
* @param array $hls
* @return array
*/
private function getHlParams(int $iblockId, array $productProps, array $configurableParams, array $hls): array
{
$params = [];
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
foreach ($hls as $hlName => $hlBlockProduct) {
if (isset($hlBlockProduct[$iblockId])) {
reset($hlBlockProduct[$iblockId]);
$firstKey = key($hlBlockProduct[$iblockId]);
$hlRepository = new HlRepository($hlName);
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
if ($hlRepository->getHl() === null) {
continue;
}
$result = $hlRepository->getDataByXmlId($productProps[$configurableParams[$firstKey] . '_VALUE']);
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
if ($result === null) {
continue;
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
foreach ($hlBlockProduct[$iblockId] as $hlPropCodeKey => $hlPropCode) {
if (isset($result[$hlPropCode])) {
$params[$hlPropCodeKey] = $result[$hlPropCode];
}
}
}
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
return $params;
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
/**
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams $param
* @param array $product
* @param \Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo $catalogIblockInfo
*/
private function setXmlOfferParams(
SelectParams $param,
array $product,
2021-09-08 16:31:17 +03:00
CatalogIblockInfo $catalogIblockInfo
2021-05-31 16:33:02 +03:00
): void {
if ($param->parentId === null) {
$pictureProperty = $this->setup->properties->products->pictures[$catalogIblockInfo->productIblockId];
} else {
$pictureProperty = $this->setup->properties->sku->pictures[$catalogIblockInfo->productIblockId];
}
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
//достаем значения из HL блоков товаров
$this->xmlOfferBuilder->setProductHlParams($this->getHlParams(
$catalogIblockInfo->productIblockId,
$product,
$param->configurable,
$this->setup->properties->highloadblockProduct
));
2021-09-08 16:31:17 +03:00
2021-05-31 16:33:02 +03:00
//достаем значения из HL блоков торговых предложений
$this->xmlOfferBuilder->setSkuHlParams($this->getHlParams(
$catalogIblockInfo->productIblockId,
$product,
$param->configurable,
$this->setup->properties->highloadblockSku
));
$this->xmlOfferBuilder->setSelectParams($param);
$this->xmlOfferBuilder->setOfferProps($product);
2021-09-08 16:31:17 +03:00
$this->xmlOfferBuilder->setBarcode($this->barcodes[$product['ID']] ?? '');
2021-05-31 16:33:02 +03:00
$this->xmlOfferBuilder->setCatalogIblockInfo($catalogIblockInfo);
$this->xmlOfferBuilder->setPicturesPath(
$this
->fileRepository
->getProductPicture($product, $pictureProperty ?? '')
);
}
2021-09-08 16:31:17 +03:00
/**
* @param array $offer
* @param array $categories
*
* @return string
*/
private function replaceUrlTemplate(array $offer, array $categories): string
{
if (strpos($offer['DETAIL_PAGE_URL'], '#PRODUCT_URL#')) {
return $offer['DETAIL_PAGE_URL'];
}
$replaceableUrlParts = [
'#SITE_DIR#'=> 'LANG_DIR',
'#ID#' => 'ID',
'#CODE#' => 'CODE',
'#EXTERNAL_ID#' => 'EXTERNAL_ID',
'#IBLOCK_TYPE_ID#' => 'IBLOCK_TYPE_ID',
'#IBLOCK_ID#' => 'IBLOCK_ID',
'#IBLOCK_CODE#' => 'IBLOCK_CODE',
'#IBLOCK_EXTERNAL_ID#' => 'IBLOCK_EXTERNAL_ID',
'#ELEMENT_ID#' => 'ID',
'#ELEMENT_CODE#' => 'CODE',
];
$resultUrl = $offer['DETAIL_PAGE_URL'];
foreach ($replaceableUrlParts as $key => $replaceableUrlPart) {
if (isset($offer[$replaceableUrlPart])) {
$resultUrl = str_replace($key, $offer[$replaceableUrlPart], $resultUrl);
}
}
if (
isset($categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID'])
&& strpos($offer['DETAIL_PAGE_URL'], '#SECTION_ID#') !== false
) {
$resultUrl = str_replace(
'#SECTION_ID#',
$categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID'],
$resultUrl
);
}
if (
isset($categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_CODE'])
&& strpos($offer['DETAIL_PAGE_URL'], '#SECTION_CODE#') !== false
) {
$resultUrl = str_replace(
'#SECTION_CODE#',
$categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_CODE'],
$resultUrl
);
}
if (
isset(
$categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_CODE'],
$categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID']
)
&& strpos($offer['DETAIL_PAGE_URL'], '#SECTION_CODE_PATH#') !== false
) {
$resultUrl = str_replace(
'#SECTION_CODE_PATH#',
CIBlockSection::getSectionCodePath($categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID']),
$resultUrl
);
}
return str_replace('//', '/', $resultUrl);
}
/**
* @param string $productUrl
* @param string $offerUrl
*
* @return string
*/
private function mergeUrls(string $productUrl, string $offerUrl): string
{
if (strpos($offerUrl, '#PRODUCT_URL#') !== false) {
return $productUrl;
}
return $offerUrl;
}
2021-09-08 10:05:09 +03:00
/**
* @param array $offerParams
* @param array $productParams
*/
private function mergeParams(array $offerParams, array $productParams): array
{
$offerCodes = [];
2021-09-08 16:31:17 +03:00
2021-09-08 10:05:09 +03:00
/** @var \Intaro\RetailCrm\Model\Bitrix\Xml\OfferParam $offerParam */
foreach ($offerParams as $offerParam) {
$offerCodes[] = $offerParam->code;
}
/** @var \Intaro\RetailCrm\Model\Bitrix\Xml\OfferParam $productParam */
foreach ($productParams as $productParam) {
if (in_array($productParam->code, $offerCodes, true)) {
continue;
}
2021-09-08 16:31:17 +03:00
2021-09-08 10:05:09 +03:00
$offerParams[] = $productParam;
}
2021-09-08 16:31:17 +03:00
2021-09-08 10:05:09 +03:00
return $offerParams;
}
2021-05-31 16:33:02 +03:00
}