2021-05-31 16:33:02 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Intaro\RetailCrm\Icml;
|
|
|
|
|
|
|
|
use Intaro\RetailCrm\Model\Bitrix\Xml\OfferParam;
|
|
|
|
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlCategory;
|
|
|
|
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlData;
|
|
|
|
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer;
|
|
|
|
use XMLWriter;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Отвечает за запись данных каталога в файл
|
|
|
|
*
|
|
|
|
* Class IcmlWriter
|
|
|
|
* @package Intaro\RetailCrm\Icml
|
|
|
|
*/
|
|
|
|
class IcmlWriter
|
|
|
|
{
|
|
|
|
public const INFO = 'INFO';
|
|
|
|
public const CATEGORY_PART = 1000;
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @var \XMLWriter
|
|
|
|
*/
|
|
|
|
private $writer;
|
2021-11-02 11:25:26 +03:00
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
private $filePath;
|
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* IcmlWriter constructor.
|
2021-11-02 11:25:26 +03:00
|
|
|
*
|
|
|
|
* @param string $filePath
|
2021-05-31 16:33:02 +03:00
|
|
|
*/
|
2021-11-02 11:25:26 +03:00
|
|
|
public function __construct(string $filePath)
|
2021-05-31 16:33:02 +03:00
|
|
|
{
|
2021-11-02 11:25:26 +03:00
|
|
|
$this->filePath = $filePath;
|
2021-05-31 16:33:02 +03:00
|
|
|
$this->writer = new XMLWriter();
|
2021-11-02 11:25:26 +03:00
|
|
|
$this->writer->openMemory();
|
|
|
|
$this->writer->setIndent(false);
|
|
|
|
$this->writer->startDocument('1.0', LANG_CHARSET);
|
2021-05-31 16:33:02 +03:00
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlData $data
|
|
|
|
*/
|
|
|
|
public function writeToXmlTop(XmlData $data): void
|
|
|
|
{
|
|
|
|
$this->writer->startElement('yml_catalog');
|
|
|
|
$this->writeSimpleAttribute('date', Date('Y-m-d H:i:s'));
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
$this->writer->startElement('shop');
|
|
|
|
$this->writeSimpleElement('name', $data->shopName);
|
|
|
|
$this->writeSimpleElement('company', $data->company);
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
public function writeToXmlBottom(): void
|
|
|
|
{
|
|
|
|
$this->writer->endElement();
|
|
|
|
$this->writer->endElement();
|
2021-11-02 11:25:26 +03:00
|
|
|
file_put_contents($this->filePath, $this->writer->flush(true), FILE_APPEND);
|
|
|
|
$this->writer->endDocument();
|
2021-05-31 16:33:02 +03:00
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlData $data
|
|
|
|
*/
|
|
|
|
public function writeToXmlHeaderAndCategories(XmlData $data): void
|
|
|
|
{
|
|
|
|
$this->writer->startElement('categories');
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
foreach ($data->categories as $key => $category) {
|
|
|
|
$this->writeCategory($category);
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
if (
|
|
|
|
count($data->categories) === $key + 1
|
|
|
|
|| is_int(count($data->categories) / self::CATEGORY_PART)
|
|
|
|
) {
|
2021-11-02 11:25:26 +03:00
|
|
|
file_put_contents($this->filePath, $this->writer->flush(true), FILE_APPEND);
|
2021-05-31 16:33:02 +03:00
|
|
|
}
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
$this->writer->endElement();
|
2021-11-02 11:25:26 +03:00
|
|
|
file_put_contents($this->filePath, $this->writer->flush(true), FILE_APPEND);
|
2021-05-31 16:33:02 +03:00
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
public function startOffersBlock(): void
|
|
|
|
{
|
|
|
|
$this->writer->startElement('offers');
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
public function endBlock(): void
|
|
|
|
{
|
|
|
|
$this->writer->endElement();
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param XmlOffer[] $offers
|
2023-04-13 13:50:18 +03:00
|
|
|
* @param bool $isNotActiveProduct
|
2021-05-31 16:33:02 +03:00
|
|
|
*/
|
2023-04-13 13:50:18 +03:00
|
|
|
public function writeOffers(array $offers, $isNotActiveProduct = false): void
|
2021-05-31 16:33:02 +03:00
|
|
|
{
|
|
|
|
foreach ($offers as $offer) {
|
2023-04-13 13:50:18 +03:00
|
|
|
$this->writeOffer($offer, $isNotActiveProduct);
|
2021-05-31 16:33:02 +03:00
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
|
|
|
file_put_contents($this->filePath, $this->writer->flush(true), FILE_APPEND);
|
2021-05-31 16:33:02 +03:00
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer $offer
|
2023-04-13 13:50:18 +03:00
|
|
|
* @param bool $isNotActiveProduct
|
2021-05-31 16:33:02 +03:00
|
|
|
*/
|
2023-04-13 13:50:18 +03:00
|
|
|
private function writeOffer(XmlOffer $offer, $isNotActiveProduct): void
|
2021-05-31 16:33:02 +03:00
|
|
|
{
|
|
|
|
$this->writer->startElement('offer');
|
|
|
|
$this->writeSimpleAttribute('id', $offer->id);
|
|
|
|
$this->writeSimpleAttribute('productId', $offer->productId);
|
|
|
|
$this->writeSimpleAttribute('quantity', $offer->quantity);
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2023-04-13 13:50:18 +03:00
|
|
|
if ($isNotActiveProduct) {
|
|
|
|
$this->writeSimpleElement('productActivity', 'N');
|
|
|
|
} else {
|
|
|
|
$this->writeSimpleElement('activity', $offer->activity);
|
|
|
|
}
|
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
foreach ($offer->categoryIds as $categoryId) {
|
|
|
|
$this->writeSimpleElement('categoryId', $categoryId);
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
if (!empty($offer->picture)) {
|
|
|
|
$this->writeSimpleElement('picture', $offer->picture);
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
if (!empty($offer->unitCode->code)) {
|
|
|
|
$this->writer->startElement('unit');
|
|
|
|
$this->writeSimpleAttribute('code', $offer->unitCode->code);
|
|
|
|
$this->writeSimpleAttribute('name', $offer->unitCode->name);
|
|
|
|
$this->writeSimpleAttribute('sym', $offer->unitCode->sym);
|
|
|
|
$this->writer->endElement();
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
foreach ($offer->params as $param) {
|
|
|
|
$this->writeParam($param);
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
$this->writeSimpleElement('url', $offer->url);
|
|
|
|
$this->writeSimpleElement('price', $offer->price);
|
|
|
|
$this->writeSimpleElement('name', $offer->name);
|
|
|
|
$this->writeSimpleElement('productName', $offer->productName);
|
|
|
|
$this->writeSimpleElement('xmlId', $offer->xmlId);
|
|
|
|
$this->writeOptionalSimpleElement('vendor', $offer->vendor);
|
|
|
|
$this->writeOptionalSimpleElement('barcode', $offer->barcode);
|
|
|
|
$this->writeOptionalSimpleElement('vatRate', $offer->vatRate);
|
|
|
|
$this->writeOptionalSimpleElement('weight', $offer->weight);
|
|
|
|
$this->writeOptionalSimpleElement('dimensions', $offer->dimensions);
|
|
|
|
$this->writeOptionalSimpleElement('purchasePrice', $offer->purchasePrice);
|
|
|
|
$this->writer->endElement();
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* Создает ноду, если значение не пустое
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
* @param $value
|
|
|
|
*/
|
|
|
|
private function writeOptionalSimpleElement(string $name, $value): void
|
|
|
|
{
|
|
|
|
if (!empty($value)) {
|
|
|
|
$this->writeSimpleElement($name, $value);
|
|
|
|
}
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param string $name
|
|
|
|
* @param $value
|
|
|
|
*/
|
|
|
|
private function writeSimpleElement(string $name, $value): void
|
|
|
|
{
|
|
|
|
$this->writer->startElement($name);
|
|
|
|
$this->writer->text($this->prepareValue($value));
|
|
|
|
$this->writer->endElement();
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param string $name
|
|
|
|
* @param $value
|
|
|
|
*/
|
|
|
|
private function writeSimpleAttribute(string $name, $value): void
|
|
|
|
{
|
|
|
|
$this->writer->startAttribute($name);
|
|
|
|
$this->writer->text($this->prepareValue($value));
|
|
|
|
$this->writer->endAttribute();
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param $text
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function prepareValue($text): string
|
|
|
|
{
|
|
|
|
global $APPLICATION;
|
|
|
|
|
|
|
|
return strip_tags($APPLICATION->ConvertCharset($text, 'utf-8', 'utf-8'));
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlCategory $category
|
|
|
|
*/
|
|
|
|
private function writeCategory(XmlCategory $category): void
|
|
|
|
{
|
|
|
|
$this->writer->startElement('category');
|
|
|
|
$this->writeSimpleAttribute('id', $category->id);
|
|
|
|
$this->writeParentId($category->parentId);
|
|
|
|
$this->writeSimpleElement('name', $category->name);
|
|
|
|
$this->writeSimpleElement('picture', $category->picture);
|
|
|
|
$this->writer->endElement();
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\OfferParam $param
|
|
|
|
*/
|
|
|
|
private function writeParam(OfferParam $param): void
|
|
|
|
{
|
|
|
|
$this->writer->startElement('param');
|
|
|
|
$this->writeSimpleAttribute('name', $param->name);
|
|
|
|
$this->writeSimpleAttribute('code', $param->code);
|
|
|
|
$this->writer->text($this->prepareValue($param->value));
|
|
|
|
$this->writer->endElement();
|
|
|
|
}
|
2021-11-02 11:25:26 +03:00
|
|
|
|
2021-05-31 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @param string $parentId
|
|
|
|
*/
|
|
|
|
private function writeParentId(string $parentId)
|
|
|
|
{
|
|
|
|
if ($parentId > 0) {
|
|
|
|
$this->writeSimpleAttribute('parentId', $parentId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|