Событие обновление свойств элемента инфоблока

Ниже рассматривается процесс обновления пользовательского свойства у пользователя через событие OnAfterIBlockElementUpdate при обновлении элемента инфоблока в init.php

Событие обновления инфоблока в битрикс

Порой, использование функционала событий Битрикса может казаться достаточно путанной темой, особенно, если не работаешь с API Битрикса на постоянной основе. Настоящая статья ставит своей целью пролить немного света на данный вопрос, рассматривая практический пример обновления пользовательского свойства у пользователя через обработчик события обновления элемента инфоблока.

Обновление свойства через OnAfterIBlockElementUpdate

В файле /bitrix/php_interface/init.php регистрируем обработчик:

AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "UpdateChangeStatus");

Где OnAfterIBlockElementUpdate — название события битрикса (после обновления элемента инфоблока), UpdateChangeStatus — название нашей функции (может быть любой).

Может возникнуть вопрос, нужно ли в файле init.php дополнительно подключать модуль iblock через CModule::IncludeModule(‘iblock’)?

Ответ: Нет, это лишнее.

Далее, ниже, в этом же файле добавляем саму функцию (код функции приводится целиком, необходимые пояснения будут ниже):

function UpdateChangeStatus(&$arFields){
//Проверяем ИД инфоблока
if($arFields["IBLOCK_ID"] == 9){
// Проверяем имя элемента
if($arFields["NAME"] == 'Ручное пополнение системы') {

$db_props = CIBlockElement::GetProperty(9, $arFields["ID"], "sort", "asc", array());
$PROPS = array();
while($ar_props = $db_props->GetNext()){
$PROPS[$ar_props['CODE']] = $ar_props['VALUE'];
}

$filename = __DIR__ . '/log.txt';
//Проверяем статус. Если 8 (Выполнена), то обновляем внутренний счет юзера на сумму свойства
if($PROPS['UTR_TR_STATUS'] == 8) {
//Получаем данные по юзеру
$status = 'выполнена';
$arFilter = array("ID" => $PROPS['UTR_USER']);
$arParams["SELECT"] = array("UF_BALANCE_DOLL");
$arRes = CUser::GetList($by,$desc,$arFilter,$arParams);
if ($res = $arRes->Fetch()) {
$balanceUSD = $res["UF_BALANCE_DOLL"];
}
$newBalance = $balanceUSD + $PROPS['UTR_SUMM'];
$user = new CUser;
$fields = Array(
'UF_BALANCE_DOLL' => $newBalance,
);
$user->Update($PROPS['UTR_USER'], $fields);
$new_str .= 'При обновлении статуса транзакции '.$arFields["ID"].' с суммой '.$PROPS['UTR_SUMM'].' на '.$status.' обновился внутренний счет пользователя ';
$new_str .= $PROPS['UTR_USER'].' старая сумма: '.$balanceUSD.' новая сумма: '.$newBalance.'. Дата изменения статуса:'.date('m/d/Y h:i:s a', time());
file_put_contents($filename, PHP_EOL . $new_str, FILE_APPEND);
}


//Обработка ошибочного начисления (возвращаем в процессинг)

else if($PROPS['UTR_TR_STATUS'] == 7) {//Получаем данные по юзеру
$status = 'в процессе';
$arFilter = array("ID" => $PROPS['UTR_USER']);
$arParams["SELECT"] = array("UF_BALANCE_DOLL");
$arRes = CUser::GetList($by,$desc,$arFilter,$arParams);
if ($res = $arRes->Fetch()) {
$balanceUSD = $res["UF_BALANCE_DOLL"];
}

$newBalance = $balanceUSD - $PROPS['UTR_SUMM'];


$user = new CUser;
$fields = Array(
'UF_BALANCE_DOLL' => $newBalance,
);
$user->Update($PROPS['UTR_USER'], $fields);
$new_str .= 'При обновлении статуса транзакции '.$arFields["ID"].' с суммой '.$PROPS['UTR_SUMM'].' на '.$status.' обновился внутренний счет пользователя ';
$new_str .= $PROPS['UTR_USER'].' старая сумма: '.$balanceUSD.' новая сумма: '.$newBalance.'.   Дата изменения статуса: '.date('m/d/Y h:i:s a', time());
file_put_contents($filename, PHP_EOL . $new_str, FILE_APPEND);
}}
}

}

Обратите внимание, что ID инфоблока и имя элемента мы проверяем внутри функции, чтобы не зацепить ничего лишнего. Второй момент, на который стоит обратить внимание, что в файле также не подключается дополнительно модуль CUser ни внутри функции, ни вне её. Третий и самый важный комментарий: значение $PROPS[‘UTR_TR_STATUS’] — это значение свойства уже после сохранения элемента инфоблока. Это требуется учитывать при написании функционала скрипта.

Честно говоря, статья о событии OnAfterIBlockElementUpdate получилась уж очень емкой, поэтому ниже приводится небольшой бонус в виде обработчика события, который является не менее часто используемым, чем OnAfterIBlockElementUpdate:

Обработчик события добавления элемента инфоблока OnAfterIBlockElementAdd

AddEventHandler("iblock", "OnAfterIBlockElementAdd", "AdminUserPlus");
function AdminUserPlus(&$arFields){
//Проверяем ИД инфоблока
if($arFields["IBLOCK_ID"] == 9){



$db_props = CIBlockElement::GetProperty(9, $arFields["ID"], "sort", "asc", array());
$PROPS = array();
while($ar_props = $db_props->GetNext()){
$PROPS[$ar_props['CODE']] = $ar_props['VALUE'];

}

$filename = __DIR__ . '/log.txt';
//Проверяем тип операции. Если 14, то обновляем внутренний счет юзера (в USD) на указанную сумму
if($PROPS['UTR_OPERATION'] == 14) {
//Получаем данные по юзеру
$status = '(Пополнение средств администратором)';
$arFilter = array("ID" => $PROPS['UTR_USER']);
$arParams["SELECT"] = array("UF_BALANCE_DOLL");
$arRes = CUser::GetList($by,$desc,$arFilter,$arParams);
if ($res = $arRes->Fetch()) {
$balanceUSD = $res["UF_BALANCE_DOLL"];
}

$newBalance = $balanceUSD + $PROPS['UTR_SUMM'];


$user = new CUser;
$fields = Array(
'UF_BALANCE_DOLL' => $newBalance,
);
$user->Update($PROPS['UTR_USER'], $fields);
$new_str .= 'При ручном добавлении админом транзакции '.$arFields["ID"].' с суммой '.$PROPS['UTR_SUMM'].' и кодом операции '.$status.' обновился внутренний счет пользователя ';
$new_str .= $PROPS['UTR_USER'].' старая сумма: '.$balanceUSD.' новая сумма: '.$newBalance.'. Дата изменения статуса:'.date('m/d/Y h:i:s a', time());
file_put_contents($filename, PHP_EOL . $new_str, FILE_APPEND);
}
//Проверяем тип операции. Если 15, то обновляем внутренний счет юзера (в USD) на указанную сумму
else if($PROPS['UTR_OPERATION'] == 15) {
//Получаем данные по юзеру
$status = '(Списание средств администратором)';
$arFilter = array("ID" => $PROPS['UTR_USER']);
$arParams["SELECT"] = array("UF_BALANCE_DOLL");
$arRes = CUser::GetList($by,$desc,$arFilter,$arParams);
if ($res = $arRes->Fetch()) {
$balanceUSD = $res["UF_BALANCE_DOLL"];
}

$newBalance = $balanceUSD - $PROPS['UTR_SUMM'];


$user = new CUser;
$fields = Array(
'UF_BALANCE_DOLL' => $newBalance,
);
$user->Update($PROPS['UTR_USER'], $fields);
$new_str .= 'При ручном добавлении админом транзакции '.$arFields["ID"].' с суммой '.$PROPS['UTR_SUMM'].' и кодом операции '.$status.' обновился внутренний счет пользователя ';
$new_str .= $PROPS['UTR_USER'].' старая сумма: '.$balanceUSD.' новая сумма: '.$newBalance.'. Дата изменения статуса:'.date('m/d/Y h:i:s a', time());
file_put_contents($filename, PHP_EOL . $new_str, FILE_APPEND);
}

}

}

Наверное, тут можно обойтись без комментариев к коду, потому как он практически идентичен предыдущему. Разница в том, что он отрабатывает при добавлении, а не обновлении элемента инфоблока.

Хотелось бы думать, что данная статья хоть немного пролила свет на использование обработчиков событий в битриксе. Хотя, конечно, тема очень объемная.