События пронизывают каждый модуль и позволяют разработчику внести изменение в поведение продукта не затрагивая ядро. Таких событий на самом деле очень много (хотя порой действительно нужных нет).
Но часто описание в документации крайне скудное, или его вовсе нет. В этом сообщении я научу вас как узнавать, есть ли событие, и как правильно им пользоваться. Нам потребуются базовые знания английского + начальные навыки программирования (не учитывая алгоритмы написания самих обработчиков) + немножко логики. Ну а в качестве инструмента обязательно обзаводимся Живым API.
Давайте поставим перед собой задачу, абстрактно-навскидочную. Допустим, хотим для каждой создаваемой группы в соцсети (или в корпортале) в описание добавлять информацию о том, что ругаться нельзя и некоторому пользователю вообще нельзя создавать группы.
После установки модуля идем на его страницу в админке и выбираем в списке модулей socialnetwork (ведь работаем с соцсетью).
В самом начале, до API, перед нами вываливается список событий. Тут включаем наши знания английского языка и находим что-то подходящее:
Переходим по ссылке к просмотру кода, и учимся анализировать вызов обработчиков (они всегда одинаковые, меняются только переменные и логика обработки ответа).
На что смотрим?
1. Количество переменных. Тут их всего одна ($arFields). Именно столько же переменных нам надо будет вызвать в нашем обработчике (об этом ниже). Переменных также может быть две или больше. К примеру, посмотрим там же код чуть ниже и увидим другой вызов обработчиков, которому передается уже две переменные:
Но возвращаемся к первому событию, к OnBeforeSocNetGroupAdd.
2. Далее смотрим на возможность переопределить переменную. Если перед одной из переменных стоит &, значит ее можно переопределить (это называется передача по ссылке). Иногда, логически возможность переопределения должна быть, а ее нет, тогда об этом стоит сообщить разработчикам Битрикса, они это поправят. Кстати, вообще, события они довольно охотно включают в продукт, если без предлагаемого вами события действительно не обойтись и оно не дает нагрузки.
3. Далее смотрим на возможность отмены действия. В нашем случае (OnBeforeSocNetGroupAdd) как раз есть такая возможность - судя по коду, если мы в нашем обработчике сделаем return false, группа создана не будет.
А вот, к примеру, если глянем OnSocNetGroupAdd, то там возможности отмены действия нет. Ибо действие уже произведено.
Пишем обработчик для нашего события
Тут вам рекомендую к прочтению хелп. Важный момент подчеркну - для обработки событий в ваших модулях вам надо использовать RegisterModuleDependences (регистрируется при установке модуля, и удаляется посредством UnRegisterModuleDependences при удалении модуля). А для обработки в иных случаях вам надо использовать AddEventHandler.
Ну и все. Имя модуля нам известно, имя события известно, пишем функцию/метод по правилам из хелпа и руководствуясь пунктами выше:
1. Не забываем про количество переменных. 2. Если есть (и нужна) возможность переопределения, то перед аргументами нашей функции тоже ставим знак & (func tion Test($a, &$b) {}). 3. Отмену действия рассмотрим ниже.
Как узнать что содержится в переменных, какие ключи массива и так далее?
Очень просто. Делаем вывод на экран переменных с завершением работы в теле функции:
Ну и давайте рассмотрим отмену действия с передачей ошибки в систему
if ($GLOBALS['USER']->GetID() == 2) {
$GLOBALS['APPLICATION']->throwException('Вы не можете создавать группы.');
return false;
}
Подытожим
Итак, вот получился наш абстрактный обработчик, который добавляет к описанию группы правило, и запрещает пользователю с ID=2 создавать группы в принципе.
AddEventHandler('socialnetwork', 'OnBeforeSocNetGroupAdd', 'TestHandler');
func tion TestHandler(&$arFields) {
$arFields['DESCRIPTION'] .= ' Ругаться матом запрещено!';
if ($GLOBALS['USER']->GetID() == 2) {
$GLOBALS['APPLICATION']->throwException('Вы не можете создавать группы.');
return false;
}
}
Рекомендации и правила
1. Подключение модуля, чье событие мы обрабатываем, делать не надо. Ведь модуль уже подключен, раз вызвал обработчик.
2. Лучше не плодить функции, а создать класс ваших обработчиков (в идеале по одному классу на каждый модуль), и писать обработчики внутри классов. Например, CForumHandlers::onBeforeTopicAdd();
Ребята, я может чего не понял но причем тут AddEventHandler разве нужно использовать не RegisterModuleDependences??? и еще может кто нибудь в двухсловах обьяснит для чего нам переопределения переменных и почему в последнем примере мы не использовали & ???
Александр, я же написал - для модулей Register*, иначе AddEvent*. Разница в том, что первый регистрирует в БД. Просто примите за правило первое время. А в последнем примере я просто забыл амперсанд, да. Там он нужен.
Ну и еще добавлю небольшие пять копеек Александр, суть в том - что ваши действия, которые вы будете осуществлять должны: 1. физически где то быть прописаны 2. зафиксированы, что они должны срабатывать на нужное событие Поэтому Если вы используете init.php, то и первое и второе (именно это важное условие) вы можете сделать там и никаких потерь не получите в случае использования Register... там же вы попадаете на следующее +3 - насилуете базу на каждой странице Register... нужен в случае, если вам надо как то зафиксировать 2 раз и навсегда именно на уровне БД
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».