Ошибка активации (подтверждения) аккаунта в 1C-Bitrix
Не так давно при тестировании одного сайта на CMS 1C-Bitrix, который я дорабатывал, обнаружилась ошибка самостоятельной (через e-mail) активации своего аккаунта после регистрации.
Ошибка (трудности в завершении активации) сопровождались следующим сообщением:
Во время подтверждения регистрации произошла ошибка. Обратитесь к администрации сервера.
Поначалу мне показалось это немного странным, так как немного ранее я несколько раз протестировал функционал регистрации и всё, что в него входит (активация аккаунта, восстановление пароля и прочее). Первое, что мне пришло в голову, это то, что ошибка была связана с нестандартной страницей активации аккаунта (на сайте я сделал свою страницу подтверждения регистрации, используя стандартный компонент system.auth.confirmation), второе – что проблема в самих данных пользователя. Проверив эти вещи несколько раз, понял, что дело в чём-то другом.
Поискав информацию на этот счёт в Интернете, я наткнулся на рекомендацию о том, что дело может быть в использовании события OnBeforeUserUpdate, которое срабатывает до сохранения данных пользователя. Как это ни странно, но именно его я использовал и правил не так давно.
Что я сделал неправильно, используя это событие, сейчас поясню.
Событие OnBeforeUserUpdate было прописано в файле init.php, и если вы ранее не сталкивались с этим файлом, то этот пост может быть вам полезным.
Так как я люблю оптимизировать код, то я вместе с событием OnBeforeUserUpdate использовал событие OnBeforeUserRegister (вызывается до попытки регистрации нового пользователя) и составил для них обоих одну общую функцию:
function OnBeforeUserRegisterHandler(&$arFields) {
if(trim($arFields['NAME']) == '') {
$GLOBALS['APPLICATION']->ThrowException('Поле «Имя» обязательно для заполнения.');
return false;
}
return $arFields;
}
AddEventHandler('main', 'OnBeforeUserRegister', 'OnBeforeUserRegisterHandler');
AddEventHandler('main', 'OnBeforeUserUpdate', 'OnBeforeUserRegisterHandler');
Здесь, как вы могли догадаться, сделано обязательным к заполнению (в регистрации и редактировании профиля) стандартное поле «Имя». Думаю, вы понимаете, почему я указал одну и ту же функцию у двух обработчиков. Если нет – пишите в комментарии, дам пояснения на этот счёт.
Всё хорошо, один раз функция делает проверку в момент (до попытки) регистрации, один – в момент (до сохранения) редактирования данных пользователя, но только здесь есть одно «но»: функция при событии OnBeforeUserUpdate срабатывает ещё и в момент активации учётной записи. По факту в этот момент (момент активации аккаунта, точнее до него) происходит попытка изменения некоторых, пусть и условно технических, данных. Так как поле «Имя» у нас в активацию не передаётся, то происходит описанная ранее ошибка.
Как я вышел из этой ситуации? А довольно просто. В 1C-Bitrix существует функция is_set (некий аналог isset из PHP), которая проверяет существование элемента в массиве по ключу. Я просто добавил дополнительное условие, проверив, было ли поле передано для его дальнейшего использования в условии, и это решило мою проблему с активацией аккаунтов пользователей на сайте с 1C-Bitrix:
function OnBeforeUserRegisterHandler(&$arFields) {
if(is_set($arFields, 'NAME') && trim($arFields['NAME']) == '') {
$GLOBALS['APPLICATION']->ThrowException('Поле «Имя» обязательно для заполнения.');
return false;
}
return $arFields;
}
AddEventHandler('main', 'OnBeforeUserRegister', 'OnBeforeUserRegisterHandler');
AddEventHandler('main', 'OnBeforeUserUpdate', 'OnBeforeUserRegisterHandler');
Надеюсь, этот пост даст вам правильное направление в решении подобных задач.