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
|
|
|
|
|
{
|
2023-04-13 13:50:18 +03:00
|
|
|
|
$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
|
|
|
|
|
2024-04-01 09:34:11 +03:00
|
|
|
|
$this->xmlOfferBuilder->setServerName($this->fileRepository->getServerName($catalogIblockInfo->productIblockId));
|
|
|
|
|
|
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
|
2024-04-01 09:34:11 +03:00
|
|
|
|
->getProductPicture($product, $pictureProperty ?? '', $catalogIblockInfo->productIblockId)
|
2021-05-31 16:33:02 +03:00
|
|
|
|
);
|
|
|
|
|
}
|
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
|
|
|
|
}
|