2021-09-08 10:05:09 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Intaro\RetailCrm\Icml;
|
|
|
|
|
|
|
|
use Bitrix\Highloadblock\HighloadBlockTable;
|
|
|
|
use CCatalog;
|
|
|
|
use CCatalogGroup;
|
|
|
|
use CCatalogSku;
|
2022-08-22 10:26:21 +03:00
|
|
|
use CCatalogVat;
|
2021-09-08 10:05:09 +03:00
|
|
|
use CIBlock;
|
2024-12-10 14:33:00 +03:00
|
|
|
use COption;
|
|
|
|
use Bitrix\Main\Config\Option;
|
2021-09-08 10:05:09 +03:00
|
|
|
use Intaro\RetailCrm\Service\Hl;
|
|
|
|
use RetailcrmConfigProvider;
|
2024-12-10 14:33:00 +03:00
|
|
|
use Bitrix\Main\Application;
|
|
|
|
use Bitrix\Main\Entity\Query;
|
2021-09-08 10:05:09 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Отвечает за управление настройками выгрузки icml каталога
|
2024-12-10 14:33:00 +03:00
|
|
|
* @var $PROFILE_ID - зачем если получаем в в конструкторе инстансе
|
2021-09-08 10:05:09 +03:00
|
|
|
* Class SettingsService
|
|
|
|
*
|
2024-12-10 14:33:00 +03:00
|
|
|
*
|
2021-09-08 10:05:09 +03:00
|
|
|
* @package Intaro\RetailCrm\Icml
|
|
|
|
*/
|
|
|
|
class SettingsService
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* инфоблок товаров, имеющих торговые предложения,
|
|
|
|
* при это сам инфоблок тоже является торговым каталогом
|
|
|
|
*/
|
|
|
|
public const CATALOG_WITH_SKU = 'X';
|
|
|
|
|
|
|
|
/*
|
|
|
|
* инфоблок товаров, имеющих торговые предложения,
|
|
|
|
* но сам торговым каталогом не является
|
|
|
|
*/
|
|
|
|
public const INFOBLOCK_WITH_SKU = 'P';
|
|
|
|
|
2024-12-10 14:33:00 +03:00
|
|
|
private const MODULE_ID = 'intaro.retailcrm';
|
|
|
|
|
|
|
|
private string $catalogCustomPropsOptionName;
|
|
|
|
|
|
|
|
private string $profileCatalogsOptionName;
|
|
|
|
|
|
|
|
private string $exportProfileId;
|
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
private $arOldSetupVars;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string|null
|
|
|
|
*/
|
|
|
|
private $action;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var mixed|string|null
|
|
|
|
*/
|
|
|
|
public $iblockExport;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var mixed|string|null
|
|
|
|
*/
|
|
|
|
public $loadPurchasePrice;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
public $iblockPropertySku = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
public $iblockPropertyUnitSku = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
public $iblockPropertyProduct = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
public $iblockPropertyUnitProduct = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
public $setupFileName = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
2022-08-22 10:26:21 +03:00
|
|
|
public $setupProfileName = '';
|
2021-09-08 10:05:09 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
2022-08-22 10:26:21 +03:00
|
|
|
public $priceTypes = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
public $vatRates = [];
|
2021-09-08 10:05:09 +03:00
|
|
|
|
2023-04-13 13:50:18 +03:00
|
|
|
/**
|
|
|
|
* @var mixed|string|null
|
|
|
|
*/
|
|
|
|
public $loadNonActivity;
|
|
|
|
|
2024-01-18 11:48:35 +03:00
|
|
|
/** @var array */
|
2024-12-10 14:33:00 +03:00
|
|
|
public $actualPropList = [];
|
|
|
|
|
|
|
|
/** @var array */
|
|
|
|
public $customPropList = [];
|
|
|
|
|
|
|
|
/** @var array */
|
|
|
|
public $defaultPropList = [];
|
2024-01-18 11:48:35 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
/**
|
|
|
|
* @var \Intaro\RetailCrm\Icml\SettingsService|null
|
|
|
|
*/
|
|
|
|
private static $instance = null;
|
|
|
|
|
2024-01-18 11:48:35 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
/**
|
|
|
|
* SettingsService constructor.
|
|
|
|
*
|
|
|
|
* @param array $arOldSetupVars
|
|
|
|
* @param string|null $action
|
|
|
|
*/
|
2024-12-10 14:33:00 +03:00
|
|
|
private function __construct(array $arOldSetupVars, ?string $action, ?string $profileId)
|
2021-09-08 10:05:09 +03:00
|
|
|
{
|
|
|
|
$this->arOldSetupVars = $arOldSetupVars;
|
|
|
|
$this->action = $action;
|
|
|
|
$this->iblockExport = $this->getSingleSetting('iblockExport');
|
|
|
|
$this->loadPurchasePrice = $this->getSingleSetting('loadPurchasePrice');
|
2023-04-13 13:50:18 +03:00
|
|
|
$this->loadNonActivity = $this->getSingleSetting('loadNonActivity');
|
2021-09-08 10:05:09 +03:00
|
|
|
$oldSetup = $this->getSingleSetting('SETUP_FILE_NAME');
|
|
|
|
$defaultFilePath = RetailcrmConfigProvider::getDefaultIcmlPath();
|
|
|
|
$this->setupFileName = htmlspecialcharsbx($oldSetup ?? $defaultFilePath);
|
|
|
|
$this->setupProfileName
|
|
|
|
= $this->getSingleSetting('SETUP_PROFILE_NAME') ?? GetMessage('PROFILE_NAME_EXAMPLE');
|
|
|
|
|
|
|
|
$this->getPriceTypes();
|
2022-08-22 10:26:21 +03:00
|
|
|
$this->getVatRates();
|
2024-01-18 11:48:35 +03:00
|
|
|
|
2024-12-10 14:33:00 +03:00
|
|
|
$this->exportProfileId = $profileId ?? '0';
|
|
|
|
$this->profileCatalogsOptionName = sprintf('exportProfileId_%s_catalogs', $this->exportProfileId);
|
|
|
|
|
|
|
|
$this->linkNewProfile();
|
|
|
|
$this->deleteEmptyProfileCatalogs();
|
|
|
|
|
|
|
|
$this->customPropList = $this->getNewProps();
|
|
|
|
$this->defaultPropList = $this->getIblockPropsPreset();
|
|
|
|
$this->actualPropList = $this->getActualPropList();
|
2021-09-08 10:05:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $arOldSetupVars
|
|
|
|
* @param string|null $action
|
|
|
|
*
|
|
|
|
* @return \Intaro\RetailCrm\Icml\SettingsService|null
|
|
|
|
*/
|
2024-12-10 14:33:00 +03:00
|
|
|
public static function getInstance(array $arOldSetupVars, ?string $action, ?string $profileId): ?SettingsService
|
2021-09-08 10:05:09 +03:00
|
|
|
{
|
2024-01-18 11:48:35 +03:00
|
|
|
if (is_null(self::$instance)) {
|
2024-12-10 14:33:00 +03:00
|
|
|
self::$instance = new self($arOldSetupVars, $action, $profileId);
|
2021-09-08 10:05:09 +03:00
|
|
|
}
|
2024-01-18 11:48:35 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
return self::$instance;
|
|
|
|
}
|
|
|
|
|
2024-12-10 14:33:00 +03:00
|
|
|
private function getActualPropList(): array
|
|
|
|
{
|
|
|
|
$customProps = [];
|
|
|
|
|
|
|
|
foreach ($this->customPropList as $propsByCatalog) {
|
|
|
|
$customProps = array_merge($customProps, $propsByCatalog);
|
|
|
|
}
|
|
|
|
|
|
|
|
return [
|
|
|
|
...$this->defaultPropList,
|
|
|
|
...$customProps
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getPriceTypes()
|
2021-09-08 10:05:09 +03:00
|
|
|
{
|
|
|
|
$dbPriceType = CCatalogGroup::GetList(['SORT' => 'ASC'], [], [], [], ['ID', 'NAME', 'BASE']);
|
|
|
|
|
|
|
|
while ($arPriceType = $dbPriceType->Fetch()) {
|
|
|
|
$this->priceTypes[$arPriceType['ID']] = $arPriceType;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-10 14:33:00 +03:00
|
|
|
private function getVatRates()
|
2022-08-22 10:26:21 +03:00
|
|
|
{
|
|
|
|
$dbVatRate = CCatalogVat::GetListEx(['SORT' => 'ASC'], ['ACTIVE' => 'Y'], false, false, ['ID', 'NAME', 'RATE']);
|
|
|
|
|
|
|
|
while ($arVatRate = $dbVatRate->Fetch()) {
|
|
|
|
$this->vatRates[$arVatRate['ID']] = $arVatRate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
/**
|
|
|
|
* @param string $selected
|
|
|
|
* @param string $key
|
|
|
|
* @param int $iblockId
|
|
|
|
* @param string $field
|
|
|
|
* @param string $fieldGroup
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getHlOptionStatus(string $selected, string $key, int $iblockId, string $field, string $fieldGroup): string
|
|
|
|
{
|
|
|
|
if ($this->arOldSetupVars[$fieldGroup . $selected . '_' . $key][$iblockId] === $field) {
|
|
|
|
return ' selected';
|
|
|
|
}
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $key
|
|
|
|
* @param int $iblockId
|
|
|
|
* @param string $tableName
|
|
|
|
* @param string $catalogType
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isHlSelected(
|
|
|
|
string $key,
|
|
|
|
int $iblockId,
|
|
|
|
string $tableName = '',
|
|
|
|
string $catalogType = ''
|
|
|
|
): bool {
|
|
|
|
return isset(
|
|
|
|
$tableName,
|
|
|
|
$this->arOldSetupVars['highloadblock' . $catalogType . $tableName . '_' .$key][$iblockId]
|
|
|
|
);
|
|
|
|
}
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
/**
|
|
|
|
* @param string $key
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isOptionHasPreset(string $key): bool
|
|
|
|
{
|
|
|
|
return version_compare(SM_VERSION, '14.0.0', '>=')
|
|
|
|
&& array_key_exists($key, $this->getIblockFieldsNames());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isSetupModulePage(): bool
|
|
|
|
{
|
|
|
|
global $APPLICATION;
|
|
|
|
|
|
|
|
return $APPLICATION->GetCurPage() === '/bitrix/admin/partner_modules.php';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $properties
|
|
|
|
* @param string $propName
|
|
|
|
*/
|
|
|
|
private function setProperties(array &$properties, string $propName): void
|
|
|
|
{
|
|
|
|
foreach ($this->arOldSetupVars[$propName] as $iblock => $val) {
|
2024-12-10 14:33:00 +03:00
|
|
|
if (!empty($val)) {
|
|
|
|
$properties[$iblock][$propName] = $val;
|
|
|
|
}
|
2021-09-08 10:05:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return mixed|string
|
|
|
|
*/
|
|
|
|
public function getSingleSetting(string $settingName)
|
|
|
|
{
|
|
|
|
return $this->arOldSetupVars[$settingName] ?? null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
2024-01-18 11:48:35 +03:00
|
|
|
private function getIblockPropsPreset(): array
|
2021-09-08 10:05:09 +03:00
|
|
|
{
|
|
|
|
return [
|
2024-01-18 11:48:35 +03:00
|
|
|
'article' => GetMessage('PROPERTY_ARTICLE_HEADER_NAME'),
|
|
|
|
'manufacturer' => GetMessage('PROPERTY_MANUFACTURER_HEADER_NAME'),
|
|
|
|
'color' => GetMessage('PROPERTY_COLOR_HEADER_NAME'),
|
|
|
|
'size' => GetMessage('PROPERTY_SIZE_HEADER_NAME'),
|
|
|
|
'weight' => GetMessage('PROPERTY_WEIGHT_HEADER_NAME'),
|
|
|
|
'length' => GetMessage('PROPERTY_LENGTH_HEADER_NAME'),
|
|
|
|
'width' => GetMessage('PROPERTY_WIDTH_HEADER_NAME'),
|
|
|
|
'height' => GetMessage('PROPERTY_HEIGHT_HEADER_NAME'),
|
|
|
|
'picture' => GetMessage('PROPERTY_PICTURE_HEADER_NAME'),
|
2021-09-08 10:05:09 +03:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2024-12-10 14:33:00 +03:00
|
|
|
private function getNewProps(): array
|
2024-01-18 11:48:35 +03:00
|
|
|
{
|
|
|
|
$result = [];
|
2024-12-10 14:33:00 +03:00
|
|
|
$currentProfileCatalogIds = $this->getProfileCatalogs();
|
2024-01-18 11:48:35 +03:00
|
|
|
|
2024-12-10 14:33:00 +03:00
|
|
|
if (!is_null($currentProfileCatalogIds)) {
|
|
|
|
foreach ($currentProfileCatalogIds as $catalogId) {
|
|
|
|
$catalogCustomProps = $this
|
|
|
|
->setCatalogCustomPropsOptionName($catalogId)
|
|
|
|
->getCustomProps()
|
|
|
|
;
|
2024-01-18 11:48:35 +03:00
|
|
|
|
2024-12-10 14:33:00 +03:00
|
|
|
foreach ($catalogCustomProps as $prop) {
|
|
|
|
$result[$catalogId][$prop['code']] = $prop['title'];
|
|
|
|
}
|
2024-01-18 11:48:35 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
2024-12-10 14:33:00 +03:00
|
|
|
private function getHintProps(): array
|
2021-09-08 10:05:09 +03:00
|
|
|
{
|
|
|
|
return [
|
|
|
|
'article' => ['ARTICLE', 'ART', 'ARTNUMBER', 'ARTICUL', 'ARTIKUL'],
|
|
|
|
'manufacturer' => ['MANUFACTURER', 'PROISVODITEL', 'PROISVOD', 'PROISV'],
|
|
|
|
'color' => ['COLOR', 'CVET'],
|
|
|
|
'size' => ['SIZE', 'RAZMER'],
|
|
|
|
'weight' => ['WEIGHT', 'VES', 'VEC'],
|
|
|
|
'length' => ['LENGTH', 'DLINA'],
|
|
|
|
'width' => ['WIDTH', 'SHIRINA'],
|
|
|
|
'height' => ['HEIGHT', 'VISOTA'],
|
|
|
|
'picture' => ['PICTURE', 'PICTURE'],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array[]
|
|
|
|
*/
|
|
|
|
public function getIblockFieldsNames(): array
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'weight' => [
|
|
|
|
'CODE' => 'catalog_weight',
|
|
|
|
'name' => GetMessage('SELECT_WEIGHT_PROPERTY_NAME'),
|
|
|
|
'unit' => 'mass',
|
|
|
|
],
|
|
|
|
'length' => [
|
|
|
|
'CODE' => 'catalog_length',
|
|
|
|
'name' => GetMessage('SELECT_LENGTH_PROPERTY_NAME'),
|
|
|
|
'unit' => 'length',
|
|
|
|
],
|
|
|
|
'width' => [
|
|
|
|
'CODE' => 'catalog_width',
|
|
|
|
'name' => GetMessage('SELECT_WIDTH_PROPERTY_NAME'),
|
|
|
|
'unit' => 'length',
|
|
|
|
],
|
|
|
|
'height' => [
|
|
|
|
'CODE' => 'catalog_height',
|
|
|
|
'name' => GetMessage('SELECT_HEIGHT_PROPERTY_NAME'),
|
|
|
|
'unit' => 'length',
|
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array[]
|
|
|
|
*/
|
|
|
|
public function getUnitsNames(): array
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'length' => [
|
|
|
|
'mm' => GetMessage('UNIT_MEASUREMENT_MM'),
|
|
|
|
'cm' => GetMessage('UNIT_MEASUREMENT_CM'),
|
|
|
|
'm' => GetMessage('UNIT_MEASUREMENT_M'),
|
|
|
|
],
|
|
|
|
'mass' => [
|
|
|
|
'mg' => GetMessage('UNIT_MEASUREMENT_MG'),
|
|
|
|
'g' => GetMessage('UNIT_MEASUREMENT_G'),
|
|
|
|
'kg' => GetMessage('UNIT_MEASUREMENT_KG'),
|
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
|
|
|
public function getHintUnit(): array
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'length' => 'mm',
|
|
|
|
'mass' => 'g',
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setProps(): void
|
|
|
|
{
|
2024-12-10 14:33:00 +03:00
|
|
|
foreach (array_keys($this->actualPropList) as $prop) {
|
2021-09-08 10:05:09 +03:00
|
|
|
$this->setProperties($this->iblockPropertySku, 'iblockPropertySku_' . $prop);
|
|
|
|
$this->setProperties($this->iblockPropertyUnitSku, 'iblockPropertyUnitSku_' . $prop);
|
|
|
|
$this->setProperties($this->iblockPropertyProduct, 'iblockPropertyProduct_' . $prop);
|
|
|
|
$this->setProperties($this->iblockPropertyUnitProduct, 'iblockPropertyUnitProduct_' . $prop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string|null $setupFileName
|
|
|
|
* @param string $setupProfileName
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
private function checkFileAndProfile(?string $setupFileName, string $setupProfileName): array
|
|
|
|
{
|
|
|
|
global $APPLICATION;
|
|
|
|
|
|
|
|
$arSetupErrors = [];
|
|
|
|
|
|
|
|
if (strlen($setupFileName) <= 0) {
|
|
|
|
$arSetupErrors[] = GetMessage('ERROR_NO_FILENAME');
|
|
|
|
} elseif ($APPLICATION->GetFileAccessPermission($setupFileName) < 'W') {
|
|
|
|
$arSetupErrors[] = str_replace('#FILE#', $setupFileName,
|
|
|
|
GetMessage('FILE_ACCESS_DENIED'));
|
|
|
|
}
|
|
|
|
|
|
|
|
$isValidAction = (
|
|
|
|
$this->action === 'EXPORT_SETUP'
|
|
|
|
|| $this->action === 'EXPORT_EDIT'
|
|
|
|
|| $this->action === 'EXPORT_COPY'
|
|
|
|
);
|
|
|
|
|
|
|
|
if ($isValidAction && strlen($setupProfileName) <= 0) {
|
|
|
|
$arSetupErrors[] = GetMessage('ERROR_NO_PROFILE_NAME');
|
|
|
|
}
|
|
|
|
|
|
|
|
return $arSetupErrors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
* @throws \Bitrix\Main\ArgumentException
|
|
|
|
* @throws \Bitrix\Main\LoaderException
|
|
|
|
* @throws \Bitrix\Main\ObjectPropertyException
|
|
|
|
* @throws \Bitrix\Main\SystemException
|
|
|
|
*/
|
|
|
|
public function getHlBlockList(): array
|
|
|
|
{
|
|
|
|
$hlBlockList = [];
|
|
|
|
$hlblockListDb = HighloadBlockTable::getList();
|
|
|
|
|
|
|
|
while ($hlblockArr = $hlblockListDb->Fetch()) {
|
|
|
|
$entity = Hl::getBaseEntityByHlId($hlblockArr['ID']);
|
|
|
|
$hbFields = $entity->getFields();
|
|
|
|
$hlBlockList[$hlblockArr['TABLE_NAME']]['LABEL'] = $hlblockArr['NAME'];
|
|
|
|
|
|
|
|
foreach ($hbFields as $hbFieldCode => $hbField) {
|
|
|
|
$hlBlockList[$hlblockArr['TABLE_NAME']]['FIELDS'][] = $hbFieldCode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $hlBlockList;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $iblockProperties
|
|
|
|
* @param bool $hlblockModule
|
|
|
|
* @param array $hlBlockList
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getSetupFieldsString(array $iblockProperties, bool $hlblockModule, array $hlBlockList): string
|
|
|
|
{
|
2023-04-13 13:50:18 +03:00
|
|
|
$values = 'loadPurchasePrice,SETUP_FILE_NAME,iblockExport,maxOffersValue,loadNonActivity';
|
2021-09-08 10:05:09 +03:00
|
|
|
|
|
|
|
foreach ($iblockProperties as $val) {
|
|
|
|
$values .= ',iblockPropertySku_' . $val
|
|
|
|
. ',iblockPropertyUnitSku_' . $val
|
|
|
|
. ',iblockPropertyProduct_' . $val
|
|
|
|
. ',iblockPropertyUnitProduct_' . $val;
|
|
|
|
|
|
|
|
if ($hlblockModule === true && $val !== 'picture') {
|
|
|
|
foreach ($hlBlockList as $hlblockTable => $hlblock) {
|
|
|
|
$values .= ',highloadblock' . $hlblockTable . '_' . $val;
|
|
|
|
$values .= ',highloadblock_product' . $hlblockTable . '_' . $val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $values;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $prop
|
|
|
|
*
|
|
|
|
* @return string|null
|
|
|
|
*/
|
|
|
|
public function getHlTableName(array $prop): ?string
|
|
|
|
{
|
|
|
|
if ($prop['USER_TYPE'] === 'directory') {
|
|
|
|
return $prop['USER_TYPE_SETTINGS']['TABLE_NAME'];
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $prop
|
|
|
|
* @param array|null $oldSelect
|
|
|
|
* @param string $key
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isOptionSelected(array $prop, array $oldSelect, string $key): bool
|
|
|
|
{
|
|
|
|
if (count($oldSelect) > 0) {
|
|
|
|
if ($prop['CODE'] === $oldSelect[$key]) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$iblockPropertiesHint = $this->getHintProps();
|
|
|
|
|
|
|
|
foreach ($iblockPropertiesHint[$key] as $hint) {
|
|
|
|
if ($prop['CODE'] === $hint) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $prop
|
|
|
|
* @param bool $isProduct
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getOptionClass(array $prop, bool $isProduct): string
|
|
|
|
{
|
|
|
|
$productMarker = $isProduct ? '-product' : '';
|
|
|
|
|
|
|
|
if ($prop['USER_TYPE'] === 'directory') {
|
|
|
|
return 'class="highloadblock' . $productMarker .'" id="'
|
|
|
|
. $prop['USER_TYPE_SETTINGS']['TABLE_NAME']
|
|
|
|
. '"';
|
|
|
|
}
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
return 'class="not-highloadblock"';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $unitSelect
|
|
|
|
* @param string|null $keyUnit
|
|
|
|
* @param string|null $key
|
|
|
|
* @param string|null $unitTypeName
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getUnitOptionStatus(array $unitSelect, ?string $keyUnit, ?string $key, ?string $unitTypeName): string
|
|
|
|
{
|
|
|
|
if (count($unitSelect) > 0) {
|
|
|
|
if ($keyUnit === $unitSelect[$key]) {
|
|
|
|
return ' selected';
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$hintUnit = $this->getHintUnit();
|
|
|
|
|
|
|
|
if ($keyUnit === $hintUnit[$unitTypeName]) {
|
|
|
|
return ' selected';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param int $iblockId
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2024-12-10 14:33:00 +03:00
|
|
|
private function getSiteList(int $iblockId): array
|
2021-09-08 10:05:09 +03:00
|
|
|
{
|
|
|
|
$siteList = [];
|
|
|
|
|
|
|
|
$rsSites = CIBlock::GetSite($iblockId);
|
|
|
|
|
|
|
|
while ($arSite = $rsSites->Fetch()) {
|
|
|
|
$siteList[] = $arSite['SITE_ID'];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $siteList;
|
|
|
|
}
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
/**
|
|
|
|
* @param int $iblockId
|
|
|
|
*
|
|
|
|
* @return array|null
|
|
|
|
*/
|
|
|
|
private function getSkuProps(int $iblockId): ?array
|
|
|
|
{
|
|
|
|
$propertiesSKU = null;
|
|
|
|
|
|
|
|
$iblockOffer = CCatalogSKU::GetInfoByProductIBlock($iblockId);
|
|
|
|
|
|
|
|
if ($iblockOffer !== false) {
|
2024-02-05 10:53:22 +03:00
|
|
|
$dbSkuProperties = CIBlock::GetProperties($iblockOffer['IBLOCK_ID'], [], ['MULTIPLE' => 'N']);
|
2021-09-08 10:05:09 +03:00
|
|
|
|
|
|
|
while ($prop = $dbSkuProperties->Fetch()) {
|
2024-12-10 14:33:00 +03:00
|
|
|
if ($prop['CODE'] !== '') {
|
|
|
|
$propertiesSKU[] = $prop;
|
|
|
|
}
|
2021-09-08 10:05:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $propertiesSKU;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает уже выбранные свойства
|
|
|
|
*
|
|
|
|
* @param array|null $oldValues
|
|
|
|
* @param int $iblockId
|
|
|
|
* @param string $keyGroup
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
private function getOldProps(?array $oldValues, int $iblockId, string $keyGroup = ''): array
|
|
|
|
{
|
|
|
|
$props = [];
|
|
|
|
|
|
|
|
if (isset($oldValues[$iblockId])) {
|
2024-12-10 14:33:00 +03:00
|
|
|
foreach (array_keys($this->actualPropList) as $prop) {
|
2024-01-18 11:48:35 +03:00
|
|
|
$fullKey = $keyGroup . '_' . $prop;
|
|
|
|
$props[$prop] = $oldValues[$iblockId][$fullKey];
|
2021-09-08 10:05:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $props;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $arCatalog
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
private function isCorrectCatalogType(array $arCatalog): bool
|
|
|
|
{
|
|
|
|
return $arCatalog['CATALOG_TYPE'] === 'D'
|
|
|
|
|| $arCatalog['CATALOG_TYPE'] === 'X'
|
|
|
|
|| $arCatalog['CATALOG_TYPE'] === 'P';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param int $iblockId
|
|
|
|
*
|
2022-05-05 10:20:15 +03:00
|
|
|
* @return array|null
|
2021-09-08 10:05:09 +03:00
|
|
|
*/
|
2024-12-10 14:33:00 +03:00
|
|
|
private function getProductProps(int $iblockId): ?array
|
2021-09-08 10:05:09 +03:00
|
|
|
{
|
|
|
|
$propertiesProduct = null;
|
|
|
|
|
2024-02-05 10:53:22 +03:00
|
|
|
$iblockResult = CIBlock::GetProperties($iblockId, [], ['MULTIPLE' => 'N']);
|
2021-09-08 10:05:09 +03:00
|
|
|
|
|
|
|
while ($prop = $iblockResult->Fetch()) {
|
2024-12-10 14:33:00 +03:00
|
|
|
if ($prop['CODE'] !== '') {
|
|
|
|
$propertiesProduct[] = $prop;
|
|
|
|
}
|
2021-09-08 10:05:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return $propertiesProduct;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $iblockId
|
|
|
|
* @param $iblockExport
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
2024-12-10 14:33:00 +03:00
|
|
|
private function isExport($iblockId, $iblockExport): bool
|
2021-09-08 10:05:09 +03:00
|
|
|
{
|
2023-03-15 11:55:04 +03:00
|
|
|
if (is_array($iblockExport) && count($iblockExport) !== 0) {
|
2021-09-08 10:05:09 +03:00
|
|
|
return (in_array($iblockId, $iblockExport));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param int $step
|
|
|
|
* @param string|null $fileName
|
|
|
|
* @param string|null $profileName
|
|
|
|
*
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
public function returnIfErrors(int $step, ?string $fileName, ?string $profileName): int
|
|
|
|
{
|
|
|
|
if ($step === 2) {
|
|
|
|
$arSetupErrors = $this->checkFileAndProfile(
|
|
|
|
$fileName ?? null,
|
|
|
|
$profileName ?? null
|
|
|
|
);
|
|
|
|
|
|
|
|
if (count($arSetupErrors) > 0) {
|
|
|
|
ShowError(implode('<br />', $arSetupErrors));
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $step;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getSettingsForIblocks(): array
|
|
|
|
{
|
|
|
|
$arIBlockList = [];
|
|
|
|
$intCountChecked = 0;
|
|
|
|
$intCountAvailIBlock = 0;
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
$dbRes = CIBlock::GetList(
|
|
|
|
['IBLOCK_TYPE' => 'ASC', 'NAME' => 'ASC'],
|
|
|
|
['CHECK_PERMISSIONS' => 'Y', 'MIN_PERMISSION' => 'W']
|
|
|
|
);
|
|
|
|
|
|
|
|
while ($iblock = $dbRes->Fetch()) {
|
|
|
|
$arCatalog = CCatalog::GetByIDExt($iblock['ID']);
|
|
|
|
|
|
|
|
if (!$arCatalog || !$this->isCorrectCatalogType($arCatalog)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
$arCatalog['CATALOG_TYPE'] === self::CATALOG_WITH_SKU
|
|
|
|
|| $arCatalog['CATALOG_TYPE'] === self::INFOBLOCK_WITH_SKU
|
|
|
|
) {
|
|
|
|
$propertiesSKU = $this->getSkuProps($iblock['ID']);
|
|
|
|
$oldPropertySKU = $this->getOldProps(
|
|
|
|
$this->iblockPropertySku,
|
|
|
|
$iblock['ID'],
|
|
|
|
'iblockPropertySku'
|
|
|
|
);
|
|
|
|
$oldPropertyUnitSKU = $this->getOldProps(
|
|
|
|
$this->iblockPropertyUnitSku,
|
|
|
|
$iblock['ID'],
|
|
|
|
'iblockPropertyUnitSku'
|
|
|
|
);
|
|
|
|
}
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
$arIBlockList[] = [
|
|
|
|
'ID' => $iblock['ID'],
|
|
|
|
'NAME' => $iblock['NAME'],
|
|
|
|
'IBLOCK_TYPE_ID' => $iblock['IBLOCK_TYPE_ID'],
|
|
|
|
'iblockExport' => $this->isExport($iblock['ID'], $this->iblockExport),
|
|
|
|
'PROPERTIES_SKU' => $propertiesSKU ?? null,
|
|
|
|
'OLD_PROPERTY_SKU_SELECT' => $oldPropertySKU ?? [],
|
|
|
|
'OLD_PROPERTY_UNIT_SKU_SELECT' => $oldPropertyUnitSKU ?? [],
|
|
|
|
'PROPERTIES_PRODUCT' => $this->getProductProps($iblock['ID']),
|
|
|
|
'OLD_PROPERTY_PRODUCT_SELECT' => $this->getOldProps(
|
|
|
|
$this->iblockPropertyProduct,
|
|
|
|
$iblock['ID'],
|
|
|
|
'iblockPropertyProduct'
|
|
|
|
),
|
|
|
|
'OLD_PROPERTY_UNIT_PRODUCT_SELECT' => $this->getOldProps(
|
|
|
|
$this->iblockPropertyUnitProduct,
|
|
|
|
$iblock['ID'],
|
|
|
|
'iblockPropertyUnitProduct'
|
|
|
|
),
|
|
|
|
'SITE_LIST' => '(' . implode(' ', $this->getSiteList($iblock['ID'])) . ')',
|
|
|
|
];
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
if ($arIBlockList['iblockExport']) {
|
|
|
|
$intCountChecked++;
|
|
|
|
}
|
|
|
|
|
|
|
|
$intCountAvailIBlock++;
|
|
|
|
|
|
|
|
unset($propertiesSKU, $oldPropertySKU, $oldPropertyUnitSKU);
|
|
|
|
}
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2021-09-08 10:05:09 +03:00
|
|
|
return [$arIBlockList, $intCountChecked, $intCountAvailIBlock, $arIBlockList['iblockExport'] ?? false];
|
|
|
|
}
|
2024-12-10 14:33:00 +03:00
|
|
|
|
|
|
|
public function setCatalogCustomPropsOptionName(string $catalogId): self
|
|
|
|
{
|
|
|
|
$this->catalogCustomPropsOptionName = sprintf(
|
|
|
|
'exportCustomProps_ProfileId_%s_catalogId_%s',
|
|
|
|
$this->exportProfileId,
|
|
|
|
$catalogId
|
|
|
|
);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getCustomProps(): ?array
|
|
|
|
{
|
|
|
|
$props = unserialize(COption::GetOptionString(self::MODULE_ID, $this->catalogCustomPropsOptionName));
|
|
|
|
|
|
|
|
if (!$props) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $props;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function removeCustomProps(array $propsToDelete, string $catalogId): void
|
|
|
|
{
|
|
|
|
$currentCatalogProps = $this->getCustomProps();
|
|
|
|
$updatedCatalogProps = array_values(
|
|
|
|
array_filter(
|
|
|
|
$currentCatalogProps,
|
|
|
|
fn ($currentProp) => !in_array($currentProp, $propsToDelete)
|
|
|
|
));
|
|
|
|
|
|
|
|
if (empty($updatedCatalogProps)) {
|
|
|
|
$this->deleteOptionEntry($this->catalogCustomPropsOptionName);
|
|
|
|
$this->deleteProfileCatalog($catalogId);
|
|
|
|
} else {
|
|
|
|
$this->updateCustomProps($updatedCatalogProps);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function updateCustomProps(array $updatedProps)
|
|
|
|
{
|
|
|
|
$serializedProps = serialize($updatedProps);
|
|
|
|
$this->updateOptionEntry($this->catalogCustomPropsOptionName, $serializedProps);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function setCustomProps(array $props)
|
|
|
|
{
|
|
|
|
$propsString = serialize($props);
|
|
|
|
$this->setOptionEntry($this->catalogCustomPropsOptionName, $propsString);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function saveCustomProps(array $newProps): void
|
|
|
|
{
|
|
|
|
$currentProps = $this->getCustomProps();
|
|
|
|
|
|
|
|
if (is_null($currentProps)) {
|
|
|
|
$this->setCustomProps($newProps);
|
|
|
|
} else {
|
|
|
|
$updatedProps = array_merge($currentProps, $newProps);
|
|
|
|
$this->updateCustomProps($updatedProps);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getProfileCatalogs(): ?array
|
|
|
|
{
|
|
|
|
$catalogs = unserialize(COption::GetOptionString(self::MODULE_ID, $this->profileCatalogsOptionName));
|
|
|
|
|
|
|
|
if (!$catalogs) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $catalogs;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setProfileCatalogs(array $catalogsId): void
|
|
|
|
{
|
|
|
|
$catalogs = serialize($catalogsId);
|
|
|
|
$this->setOptionEntry($this->profileCatalogsOptionName, $catalogs);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function deleteProfileCatalog(string $catalogId): void
|
|
|
|
{
|
|
|
|
$currentCatalogs = $this->getProfileCatalogs();
|
|
|
|
$catalogIdIndex = array_search($catalogId, $currentCatalogs);
|
|
|
|
|
|
|
|
if ($catalogIdIndex !== false) {
|
|
|
|
unset($currentCatalogs[$catalogIdIndex]);
|
|
|
|
}
|
|
|
|
|
|
|
|
$updatedCatalogs = serialize($currentCatalogs);
|
|
|
|
$this->updateOptionEntry($this->profileCatalogsOptionName, $updatedCatalogs);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function deleteEmptyProfileCatalogs(): void
|
|
|
|
{
|
|
|
|
$currentCatalogs = $this->getProfileCatalogs();
|
|
|
|
|
|
|
|
if (is_null($currentCatalogs)) {
|
|
|
|
$this->deleteOptionEntry($this->profileCatalogsOptionName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function setOptionEntry(string $name, string $value)
|
|
|
|
{
|
|
|
|
COption::SetOptionString(self::MODULE_ID, $name, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function updateOptionEntry(string $name, string $value)
|
|
|
|
{
|
|
|
|
COption::SetOptionString(self::MODULE_ID, $name, '');
|
|
|
|
COption::SetOptionString(self::MODULE_ID, $name, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function deleteOptionEntry(string $name)
|
|
|
|
{
|
|
|
|
COption::RemoveOption(self::MODULE_ID, $name);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function linkNewProfile(): void
|
|
|
|
{
|
|
|
|
$currentProfileCatalogs = unserialize(COption::GetOptionString(self::MODULE_ID, $this->profileCatalogsOptionName));
|
|
|
|
|
|
|
|
if (!$currentProfileCatalogs) {
|
|
|
|
$tmpProfileName = 'exportProfileId_0_catalogs';
|
|
|
|
$currentProfileCatalogs = unserialize(COption::GetOptionString(self::MODULE_ID, $tmpProfileName));
|
|
|
|
|
|
|
|
if ($currentProfileCatalogs) {
|
|
|
|
$this->setOptionEntry($this->profileCatalogsOptionName, serialize($currentProfileCatalogs));
|
|
|
|
$this->deleteOptionEntry($tmpProfileName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($currentProfileCatalogs as $catalogId) {
|
|
|
|
$optionName = sprintf('exportCustomProps_ProfileId_%s_catalogId_%s', $this->exportProfileId, $catalogId);
|
|
|
|
$propsCatalog = unserialize(COption::GetOptionString(self::MODULE_ID, $optionName));
|
|
|
|
|
|
|
|
if (!$propsCatalog) {
|
|
|
|
$tmpOptionName = sprintf('exportCustomProps_ProfileId_%s_catalogId_%s', '0', $catalogId);
|
|
|
|
$propsCatalog = unserialize(COption::GetOptionString(self::MODULE_ID, $tmpOptionName));
|
|
|
|
|
|
|
|
if ($propsCatalog) {
|
|
|
|
$this->setOptionEntry($optionName, serialize($propsCatalog));
|
|
|
|
$this->deleteOptionEntry($tmpOptionName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-09-08 10:05:09 +03:00
|
|
|
}
|