// Массив для замен категорий товаров в процессе переноса и обновления данных из 1С
$arReplace_RND_735jYx = array(// Под ID понимается категория с которой осуществляется работа, а не её родитель. Так же под EXTERNAL_ID и NAME подразумеваются значения текущей секции/категории, а не её родителя. В out под теми же именами массива понимаются значения категории/секции с которой идёт сопоставление.Если значение не известно его можно оставить пустым или присвоить ему false или можно его не описывать в массиве - ошибки так же не будет.
array("in"=>array("ID"=>false,"EXTERNAL_ID"=>"5926a1ef-afe3-11e7-9151-0025226dfab1","NAME"=>"ГОРЕЛКИ, ПЛИТКИ, ГАЗ"),"out"=>array("ID"=>4910,"EXTERNAL_ID"=>false,"NAME"=>false))
);
// Это вспомогательная функция - она определяет Id секции/категории, на которую нужно переопределить текущую категорию у товара в процессе синхронизации с 1С. Напрямую данная функция в обработчиках событий не используется.
function myGetSectionIdForReplace_RND_352kTn($checkid = false) {
$one = true;
$outsectionid = false;// В эту переменную подставится нужное значение секции/категории или так и будет возвращено значение false
$ar_res = array();// Эту переменную с точки зрения PHP объявлять не обязательно, но в C# - переменная объявляется не ниже уровня в котором используется. придерживаюсь этого правила, можно удалть эту строчку ничего не изменися - проверка на E_notice на всякйий случай реализована уровнем ниже.
if ($checkid) {
if(CModule::IncludeModule("iblock")) {
$res = CIBlockSection::GetByID($checkid);
if (isset($GLOBALS["arReplace_RND_735jYx"])) {
$arreplace = $GLOBALS["arReplace_RND_735jYx"];
}
while (// Что за условия ниже я прокоментирую
(($one === true) and ($res !== false) and (($ar_res = $res->GetNext()) !== false)) or//Если первый проход цикла $res уже получен, создаётся $ar_res как GetNext метод $res, $ar_res проверяется на возврат false
(($one === false) and isset($ar_res["IBLOCK_SECTION_ID"]) and (($res = CIBlockSection::GetByID($ar_res["IBLOCK_SECTION_ID"])) !== false) and (($ar_res = $res->GetNext()) !== false))// Последующие проходы цикла - проверяем существование $ar_res["IBLOCK_SECTION_ID"], если есть создаём от него $res, $res проверяем на возврат false, далее от $res создаётся $ar_res, $ar_res так же проверяется на возврат false
) {
// $ar_res был создан в условии цикла, поэтому далее в теле цикла его не создаём, а сразу используем
if ($one === true) {$one = false;}// Если первый проход меняем значение переменной для последующих циклов
if (isset($arreplace) and is_array($arreplace)) {
foreach ($arreplace as $v) {
if ((isset($v["in"]["ID"]) and isset($ar_res["ID"]) and ($v["in"]["ID"] == $ar_res["ID"])) or (isset($v["in"]["EXTERNAL_ID"]) and isset($ar_res["EXTERNAL_ID"]) and ($v["in"]["EXTERNAL_ID"] == $ar_res["EXTERNAL_ID"])) or (isset($v["in"]["NAME"]) and isset($ar_res["NAME"]) and ($v["in"]["NAME"] == $ar_res["NAME"]))) {
if ($v["out"]["ID"]) {
$outsectionid = $v["out"]["ID"];
} elseif ($v["out"]["EXTERNAL_ID"] or $v["out"]["NAME"]) {
$qkey = "";
$qvalue = "";
if ($v["out"]["EXTERNAL_ID"]) {
$qkey = "EXTERNAL_ID";
$qvalue = $v["out"]["EXTERNAL_ID"];
} elseif ($v["out"]["NAME"]) {
$qkey = "NAME";
$qvalue = $v["out"]["NAME"];
}
if (($res2 = CIBlockSection::GetList(array("SORT"=>"ASC"),array($qkey=>$qvalue))) !== false) {
if (($ar_res2 = $res2->GetNext()) !== false) {
if (isset($ar_res2["ID"]) and $ar_res2["ID"]) {
$outsectionid = $ar_res2["ID"];
}
}
}
}
if ($outsectionid) {
break(2);
}
}
}
}
}
}
}
return $outsectionid;
}
// Создаём сами обработчики событий на добавление и изменение инфоблока
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "myCheckProductSection");
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "myCheckProductSection");
// Обработчики ссылаются на функцию myCheckTovarSection создаём её
// Обратите внимание массив передаётся в функцию по ссылке(значёк &), это нужно для того, чтобы изменения внесённые в массив сохранились в базе данных(или как это называют в битрикс были присвоены соответствующему элементу инфоблока).
function myCheckProductSection(&$arFields) {
// внутри функции проверяем нужно ли переопределить ид секции(это то же самое что категория) для данного товара, и если требуется, то новое значение присваиваем массиву.
if ($newsection = myGetSectionIdForReplace_RND_352kTn($arFields["IBLOCK_SECTION"][0])) {
$ar["IBLOCK_SECTION"] = array($newsection);
}
}