Событие OnAfterUserRegister срабатывает после регистрации пользователя через штатный механизм и позволяет выполнить пост-обработку: добавить в группы, создать профиль во внешней системе или отправить приветствие. Главное — правильно отличать успешную регистрацию от ошибочной.
Когда вызывается событие
OnAfterUserRegister принадлежит модулю main и вызывается методом CUser::Register() — это тот путь, которым идёт компонент system.auth.registration и форма регистрации. В обработчик приходит массив-результат регистрации по ссылке.
Не путайте близкие события пользователя:
| Событие | Когда |
|---|---|
OnBeforeUserRegister | До регистрации, можно отменить и проверить поля |
OnAfterUserRegister | После регистрации через Register(), с результатом |
OnAfterUserAdd | После любого добавления пользователя, включая админку и API |
Register(), а через CUser::Add() (импорт, админка, свой код), OnAfterUserRegister не сработает. Для универсальной логики «на любое создание» используйте OnAfterUserAdd.Регистрация обработчика
Подключаем обработчик в /local/php_interface/init.php:
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler(
'main',
'OnAfterUserRegister',
['\Vendor\Account\RegisterHandler', 'onAfterRegister']
);
Это событие «старого» стиля с передачей массива по ссылке, но и здесь предпочтителен EventManager вместо устаревшего AddEventHandler(). Класс-обработчик держите в автозагружаемой директории, чтобы код подключался лениво.
Структура массива и проверка успеха
В обработчик приходит массив, который одновременно содержит поля формы и результат регистрации. Первое, что нужно сделать, — убедиться, что регистрация действительно прошла, а не завершилась ошибкой валидации:
public static function onAfterRegister(&$arFields)
{
// Ошибка регистрации — выходим
if (!empty($arFields['RESULT_MESSAGE']) && $arFields['RESULT_MESSAGE'] !== true) {
// в RESULT_MESSAGE лежит текст ошибки
return;
}
$userId = (int)($arFields['USER_ID'] ?? 0);
if ($userId <= 0) { return; }
// ... пост-обработка ...
}
USER_ID— ID созданного пользователя (появляется только при успехе);RESULT_MESSAGE—trueпри успехе или текст ошибки при неудаче;- остальные ключи — переданные из формы поля (
EMAIL,NAME,LOGINи другие).
RESULT_MESSAGE и наличие USER_ID, вы отправите приветствие или создадите профиль для несуществующего пользователя.Добавление в группы и создание профиля
Частый сценарий — назначить новому пользователю группы или служебные свойства. Добавление в группу делают через CUser::Update(), сохраняя уже имеющиеся группы:
$user = new \CUser();
$groups = \CUser::GetUserGroup($userId);
$groups[] = 5; // ID группы «Покупатели»
$user->Update($userId, [
'GROUP_ID' => array_unique($groups),
]);
Так же в обработчике удобно создать запись в собственной HL-таблице профиля, привязать пользователя к контрагенту B2B-портала или отправить его данные во внешнюю систему. Для внешнего вызова передавайте только подтверждённые поля из $arFields.
Активация по почте и приветственные письма
Если в настройках модуля main включена регистрация с подтверждением по email, пользователь создаётся неактивным и получает письмо с кодом активации. Учитывайте это в логике пост-регистрации:
- не выдавайте доступ к закрытым разделам до подтверждения — проверяйте флаг
ACTIVE; - приветственное письмо с полезным контентом лучше отправлять после активации, ловя её отдельно;
- штатные письма регистрации настраиваются как почтовые события типа
NEW_USERиUSER_INFO— их шаблоны редактируются в админке, а не в коде.
CEvent::Send() с отдельным типом почтового события — так письмо попадёт в очередь рассылки и будет управляться из админки, а не захардкожено в обработчике.Типичные ошибки и производительность
Несколько практических правил, которые экономят часы отладки:
- не полагайтесь на глобальный
$USER— на момент события пользователь ещё может быть не авторизован, берите ID из$arFields['USER_ID']; - не выполняйте тяжёлые синхронные запросы к внешним API прямо в обработчике — регистрация будет «висеть»; выносите их в очередь или агент;
- оборачивайте внешние вызовы в try/catch — падение интеграции не должно ломать регистрацию;
- помните про капчу и антибот: обработчик увидит и отклонённые попытки, если проверка RESULT_MESSAGE пропущена.
Для операций «на любое создание пользователя» (импорт, синхронизация, админка) дублируйте нужную логику в OnAfterUserAdd, вынеся её в общий метод. При этом учитывайте, что OnAfterUserAdd тоже приходит с массивом полей, но без ключа RESULT_MESSAGE — там наличие пользователя определяется по ID. Ещё одна частая ошибка — писать интеграционные данные в поле пользователя тем же вызовом Update(), который снова инициирует OnAfterUserUpdate; чтобы избежать лишних срабатываний, группируйте все правки в один вызов и ставьте предохранитель по ID, если логика может вызвать сама себя.
Итог
OnAfterUserRegister — правильное место для пост-регистрационных действий: добавления в группы, создания профиля и запуска интеграций. Ключевые правила — проверять RESULT_MESSAGE и наличие USER_ID, не блокировать регистрацию тяжёлыми внешними вызовами и помнить, что событие не срабатывает при создании пользователя через Add().
Когда регистрация становится частью B2B-сценария — с привязкой к контрагентам, ролями, синхронизацией с 1С и CRM, — мы в B2Bsite проектируем её как продуманный слой авторизации и обмена данными, устойчивый к сбоям внешних систем.
Частые вопросы
Чем OnAfterUserRegister отличается от OnAfterUserAdd?
OnAfterUserRegister срабатывает только при регистрации через CUser::Register (форма регистрации). OnAfterUserAdd вызывается при любом добавлении пользователя, включая админку, импорт и прямой вызов Add.
Как понять, что регистрация прошла успешно?
Проверьте RESULT_MESSAGE: при успехе он равен true, при ошибке содержит текст. Дополнительно убедитесь, что в массиве есть корректный USER_ID.
Почему обработчик срабатывает даже при ошибке регистрации?
Событие вызывается в конце процесса независимо от результата. Именно поэтому нужно проверять RESULT_MESSAGE и наличие USER_ID перед любыми действиями.
Как добавить нового пользователя в группу?
Получите текущие группы через CUser::GetUserGroup, добавьте нужный ID и сохраните через CUser::Update с ключом GROUP_ID, чтобы не потерять уже назначенные группы.
Можно ли отправить приветственное письмо из обработчика?
Да, но лучше через CEvent::Send с отдельным типом почтового события — так письмо управляется из админки. При регистрации с подтверждением отправляйте приветствие после активации.
Стоит ли обращаться к внешнему API прямо в обработчике?
Синхронный тяжёлый вызов замедлит регистрацию и может её оборвать при таймауте. Выносите интеграцию в очередь или агент, а внешние вызовы оборачивайте в try/catch.
Как получить ID пользователя в обработчике?
Берите его из $arFields['USER_ID']. Полагаться на глобальный объект $USER не стоит — на момент события авторизация может быть ещё не завершена.
Событие сработает при регистрации через соцсети?
Зависит от реализации: модуль socialservices может создавать пользователя другим путём. Для гарантированного охвата всех сценариев дублируйте логику в OnAfterUserAdd.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.