Надо еще допилить, так как проверка регионов в акции очень тупо сделана, но код уже работает.
Для опорной точники, беру ID региона из инфоблока. Он передается в сессию и из сессии получая ID можно применить акцию
<?
use Bitrix\Main\Loader;
Loader::includeModule('catalog');
//Если используем в настройках интернет-магазина только правила корзины, то оставляем правила для корзины.
Если не используем, то оставляем для скидок на товар и меняем класс от которого наследуем на CCatalogActionCtrlBasketProductFields
AddEventHandler("catalog", "OnCondCatControlBuildList", Array("CatalogCondCtrlCityName ", "GetControlDescr"));
AddEventHandler("sale", "OnCondSaleActionsControlBuildList", Array("CatalogCondCtrlCityName ", "GetControlDescr"));
class CatalogCondCtrlCityName extends \CCatalogCondCtrlComplex
{
public static function GetClassName(): string
{
return __CLASS__;
}
public static function GetControlID(): array|string
{
return array('CondCityName');
}
/**
* Функция добавляет категорию условий и добавляет в нее сами условия описнные в функции GetControls()
*/
public static function GetControlShow($arParams): array
{
$arControls = static::GetControls();
$arResult = array(
'controlgroup' => true,
'group' => false,
'label' => 'Город',
'showIn' => static::GetShowIn($arParams['SHOW_IN_GROUPS']),
'children' => array()
);
foreach ($arControls as &$arOneControl)
{
$arResult['children'][] = array(
'controlId' => $arOneControl['ID'],
'group' => false,
'label' => $arOneControl['LABEL'],
'showIn' => static::GetShowIn($arParams['SHOW_IN_GROUPS']),
'control' => array(
array(
'id' => 'prefix',
'type' => 'prefix',
'text' => $arOneControl['PREFIX']
),
static::GetLogicAtom($arOneControl['LOGIC']),
static::GetValueAtom($arOneControl['JS_VALUE'])
)
);
}
if (isset($arOneControl))
unset($arOneControl);
return $arResult;
}
/**
* Функция добавления условий
*/
public static function GetControls($strControlID = false): array|bool
{
if (CModule::IncludeModule("iblock")):
//получаем из инфоблока регионов, регионы сайта и их ID
$iblock_id = 9;
$element = CIBlockElement::GetList (
Array("ID" => "ASC"),
Array("IBLOCK_ID" => $iblock_id),
false,
false,
Array('ID', 'NAME')
);
while($ar_fields = $element->GetNext())
{
$CityList[$ar_fields['ID']] = $ar_fields['NAME'];
}
endif;
$arControlList = array(
'CondCityName' => array(
'ID' => 'CondCityName',
'FIELD' => 'CITY_NAME',
'FIELD_TYPE' => 'int',
'LABEL' => 'Название города',
'PREFIX' => 'Город скидки',
'LOGIC' => static::GetLogic(array(BT_COND_LOGIC_EQ, BT_COND_LOGIC_NOT_EQ)),
'JS_VALUE' => array(
'type' => 'select',
'values' => $CityList,
'multiple' => 'Y',
'show_value' => 'Y',
),
'PHP_VALUE' => array(
'VALIDATE' => 'list'
)
),
);
foreach ($arControlList as &$control)
{
if (!isset($control['PARENT']))
$control['PARENT'] = true;
$control['MULTIPLE'] = 'N';
}
unset($control);
if ($strControlID === false)
{
return $arControlList;
}
elseif (isset($arControlList[$strControlID]))
{
return $arControlList[$strControlID];
}
else
{
return false;
}
}
/**
* Функция подготавливает строчное представление метода проверки условий.
* Эта строка запускается языковой конструкцией eval() в модуле скидок.
*
* @param $arOneCondition array Массив состояний
* @param $arParams
* @param $arControl
* @param bool $arSubs
* @return string
*/
public static function Generate($arOneCondition, $arParams, $arControl, $arSubs = false): string
{
$logic = $arOneCondition['logic'] === 'Equal' ? 'true' : 'false';
$arOneConditionValue = json_encode($arOneCondition["value"]);
return 'CatalogCondCtrlCityName::CityCheck($GLOBALS["arRegion"]["ID"], \'' . $arOneConditionValue . '\') === ' . $logic;
}
public static function CityCheck($city, $targetCityAsString): bool
{
$targetCity = json_decode($targetCityAsString, true);
return in_array($city, $targetCity);
}
}
?>
Была проверка по сессии, но в шаблоне ASPRO используют глобальные переменные, перевел код на $GLOBALS['arRegion']['ID']
Другие варианты:
$GLOBALS["arRegionLink"]["PROPERTY_LINK_REGION"]
$_SESSION["ASPRO_FILTER"]["arRegionLink"]["PROPERTY_LINK_REGION"]
Добавить комментарий