Привет, Хабр. Недавно я написал целый цикл статей по работе со смарт‑процессами, помогающий погрузить «непосвященного» человека в азы API коробочной версии, реализующего возможности управления смарт‑процессами и связанными с ними элементами. В рамках последней статьи, разъясняющей применение обработчиков события, от слушателей и интересующихся получил в личку много вопросов, связанных в целом с применением обработчиков событий в Битрикс24. В сегодняшней статье рассмотрим один из популярных практических кейсов — реализовать возможность управлять какими‑либо настройками обработчиков события из стандартной панели администратора Битрикс24.
Я понимаю, что руководств по сборке модулей Битрикс и на Хабре и в официальной документации достаточно много. Но на мой взгляд основная проблема таких руководств — это их объем (автор руководства пытается расписать все возможные файлы в составе модуля), что для начинающего неподготовленного пользователя (вспоминаю тут себя в начале карьеры Битрикс разработчика) может быть трудным к пониманию. Я ни в коем случае не утверждаю, что авторы данных материалов написали их плохо, на определенном этапе развития специалистам нужны и полные материалы целиком, поэтому своих читателей такие материалы конечно же найдут. Мои же статьи в данном цикле рассчитаны на аудиторию, только начинающую делать первые шаги в Битрикс разработке, потому упрощение пойдет им определенно на пользу.
Если что, основная статья начинается отсюда 🙂
В сегодняшней статье‑туториале мы соберем модуль для Битрикс24, реализующий добавление и удаление обработчиков события, а также страницу настроек, позволяющую включать и отключать эти обработчики для определенных воронок сделки. Многоязычность пока для простоты понимания реализовывать не будем. Может, разберем данный вопрос в следующих статьях. Пишите в комментариях, если хотите что‑то разобрать в следующих статьях цикла.
Если обратиться к принятым стандартам разработки BitrixFramework, системные модули и модули, загружаемые из 1С‑Битрикс: Маркетплейс, располагаются в папке /bitrix/modules/. У нас же модуль полностью кастомный, его структуру мы будем создавать в папке /local/modules/.
Начинаем создание модуля
Как корабль назовешь — так он и поплывет пойдет, говорят моряки. Перед тем как собирать вместе файлы модуля, нам нужно определиться с его техническим названием, которое будет его однозначно идентифицировать в системе. Раз основная задача — научиться оперировать обработчиками события через модуль — назовем его learnevents.
Соответственно создаем папку для нашего модуля по пути /local/modules/learnevents.
Разбирать полный состав файлов модуля мы не будем, писал выше почему. Далее будем создавать минимальный набор файлов, который нам понадобится для решения нашей задачи.
Папка install
Первой создаем папку /local/modules/learnevents/install. В ней будут находиться файлы, отвечающие за установку и удаление нашего модуля.
Первым в папке создаем файл /local/modules/learnevents/install/version.php следующего содержания:
<?php $arModuleVersion = [ 'VERSION' => '1.0.0', 'VERSION_DATE' => '2025-05-13', ];
Нетрудно догадаться, что в данном файле мы указываем текущую версию модуля и дату его выпуска. Можно указать в принципе любые подходящие по формату данные.
Далее создаем основной файл установщика модуля /local/modules/learnevents/install/index.php. В коде будут поясняющие комментарии:
<?php use Bitrix\Main\ModuleManager; //Основной класс установщика модуля, должен наследоваться от системного класса CModule class learnevents extends CModule { //Системный идентификатор модуля, должен совпадать с названием класса public $MODULE_ID = 'learnevents'; //Версия модуля и дата. Оставляем пустыми так как подгрузим нужные в конструкторе public $MODULE_VERSION; public $MODULE_VERSION_DATE; //Название модуля, выводимое в админ панели public $MODULE_NAME = 'Управляемые обработчики'; //Описание модуля, выводимое в админ панели public $MODULE_DESCRIPTION = 'Тестовый модуль, показывающий возможности управления обработчиками события'; //Адрес сайта разработчика модуля public $PARTNER_URI = 'https://site.ru'; //Не использовать права доступа к модулю на основе групп пользователей public $MODULE_GROUP_RIGHTS = 'N'; //Основной конструктор класса, в котором мы читаем файл version.php и берем оттуда версию модуля и дату релиза public function __construct() { $arModuleVersion = []; include __DIR__ . '/version.php'; if (is_array($arModuleVersion) && array_key_exists('VERSION', $arModuleVersion)) { $this->MODULE_VERSION = $arModuleVersion['VERSION']; $this->MODULE_VERSION_DATE = $arModuleVersion['VERSION_DATE']; } } //Метод, устанавливающий обработчики события при установке модуля public function InstallEvents() { $eventManager = \Bitrix\Main\EventManager::getInstance(); $eventManager->registerEventHandler("crm", "OnBeforeCrmDealAdd",//Событие, на которое вешаем обработчик $this->MODULE_ID,//Идентификатор модуля, берем текущий "Learn\\Event\\Main",//PHP Класс с неймспейсом, в котором реализован метод обработчика "RunEvent"//Название метода-обработчика ); //Далее код других обработчиков return true; } //Метод, удаляющий обработчики события при удалении модуля public function UnInstallEvents() { $eventManager = \Bitrix\Main\EventManager::getInstance(); $eventManager->unRegisterEventHandler("crm", "OnBeforeCrmDealAdd",//Событие, на которое вешаем обработчик $this->MODULE_ID,//Идентификатор модуля, берем текущий "Learn\\Event\\Main",//PHP Класс с неймспейсом, в котором реализован метод обработчика "RunEvent"//Название метода-обработчика ); //Далее код других обработчиков return true; } //Метод, запускающийся при установке модуля public function DoInstall() { $this->InstallEvents();//Запускаем установку обработчиков ModuleManager::registerModule($this->MODULE_ID);//Регистрируем модуль в системе как установленный } //Метод, запускающийся при удалении модуля public function DoUninstall() { $this->UnInstallEvents();//Запускаем удаление обработчиков ModuleManager::unRegisterModule($this->MODULE_ID);//Снимаем регистрацию модуля в системе } }
Далее добавляем файл /local/modules/learnevent/install/unstep1.php. Он будет отвечать за страничку, которая появляется перед удалением модуля в панели администратора:
<? //Если пользователь не авторизован, прерываем метод if(!check_bitrix_sessid()) return; echo CAdminMessage::ShowNote('Управляемые обработчики'); ?> <form action="<?=$APPLICATION->GetCurPage(); ?>"> <?=bitrix_sessid_post(); ?> <input type="hidden" name="step" value="2"> <input type="hidden" name="id" value="learnevent"> <input type="hidden" name="uninstall" value="Y"> <input type="submit" name="nextstep" value="Далее"> <input type="submit" name="cancel" value="Отменить"> </form>
Часто на данную страничку добавляют сообщения для тех, кто собирается удалить модуль, например «Пожалуйста, не удаляйте! Мы еще можем быть полезны».:-)
Папка lib
В данной папке традиционно размещаются классы модуля, которые будут автоматически подключены при его установке. В нашем случае создаем файл /local/modules/learnevent/lib/main.php:
namespace Learn\Event; use Bitrix\Main\Config\Option; class Main { /** * @return array|false Массив направлений сделки * @description Возвращает массим текущих направлений сделок, поднадобится в админке */ public static function getDealFunnels() { //Проверяем активен ли модуль CRM. Без него никакие Сделки доступны не будут if (\Bitrix\Main\Loader::includeModule('crm')) { //Получаем ООП Фабрику работы со сделками $factory = \Bitrix\Crm\Service\Container::getInstance()->getFactory( \CCrmOwnerType ::Deal ); //Получаем массив всех объектов направлений и делаем перебор $categories = $factory->getCategories(); $arCategories = []; foreach ($categories as $category) { //Получаем данные каждого направления и записываем в массив $arCategories[] = $category->getData(); } return $arCategories; } else { return false; } } /** * @return array|false Результат обработчика * @description Обработчик, который мы подключаем через модуля */ public static function RunEvent(&$arFields) { //Проверяем, установлен ли флажок "Активно" в админке if (Option::get("learnevent", "ACTIVE") == "Y") { global $USER; //Получаем список пользователей $userExeptions = unserialize(Option::get("learnevent", "USER_EXEPTIONS")); $pipeline = Option::get("learnevent", "PIPELINE"); if ((is_array($userExeptions) && in_array($USER->GetID(), $userExeptions)) || $userExeptions == $USER->GetID()) { if (isset($arFields['CATEGORY_ID']) && !empty($arFields['CATEGORY_ID']) && ($arFields['CATEGORY_ID'] == $pipeline)) { //Какие-то действия, если наше условие сработало. Например прерываем создание Сделки $arFields['RESULT_MESSAGE'] = "Извините, данному пользователю запрещено создавать Сделку в данной воронке!"; return false; } } } } }
В данном файле можно разместить методы для других обработчиков. Также никто не запрещает повесить несколько разных методов на одно событие.
Корневая папка модуля
Теперь перейдем к одному из важнейших файлов, который реализует окно настроек модуля в панели администрирования Битрикс24. Этот файл по стандарту лежит в папке модуля и носит название options.php. В нашем случае создаем его по пути /local/modules/learnevent/options.php и добавляем туда код:
<?php //Подключаем нужные нам неймспейсы и скрипты use \Bitrix\Main\Loader, \Bitrix\Main\Config\Option; require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_before.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_after.php'; global $APPLICATION; $moduleName = 'learnevent'; if (!Loader::IncludeModule($moduleName)) { return; } //Проверяем права доступа, если их нет - перекидываем на форму авторизации $POST_RIGHT = $APPLICATION->GetGroupRight($moduleName); if ($POST_RIGHT == "D") $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED")); //Получаем данные POST Запроса если настройки изменены, проводим фильтрацию данных для безопасности $request = Bitrix\Main\Application::getInstance()->getContext()->getRequest(); $request->addFilter(new \Bitrix\Main\Web\PostDecodeFilter); //Сохраняем настройки модуля в системные опции (таблица b_option в БД) if ($POST_RIGHT == "W" && check_bitrix_sessid() && $request->isPost()) { COption::SetOptionString($moduleName, 'ACTIVE', $request->get('ACTIVE')); COption::SetOptionString($moduleName, 'PIPELINE', $request->get('PIPELINE')); //Так как у нас может быть множественное значение а база можно хранить только единицное - делаем сериализацию массива в строку COption::SetOptionString($moduleName, 'USER_EXEPTIONS', serialize($request->get('USER_EXEPTIONS'))); } //Инициализируем табы админки, у нас таб будет один $tabs = [ [ 'DIV' => 'main', 'TAB' => 'Настройки', 'ICON' => '', ] ]; $tabControl = new \CAdminTabControl('tabControl', $tabs); //Далее добавляем форму с полями настроек, которые будут выводиться в админке ?> <form method="POST" action="<? echo $APPLICATION->GetCurPage() ?>?mid=<?= urlencode($mid) ?>&lang=<? echo LANGUAGE_ID ?>" ENCTYPE="multipart/form-data" name="post_form"> <?= bitrix_sessid_post() ?> <?php $tabControl->Begin(); $tabControl->BeginNextTab(); ?> <?//Поле "Обработчик активен"?> <tr> <td>Обработчик активен</td> <td><input type="checkbox" name="ACTIVE" value="Y" <?php if (Option::get($moduleName, 'ACTIVE') == "Y") echo 'checked'; ?>/></td> </tr> <?//Поле "Воронка Сделки". Далее получаем массив воронок и текущую настройку?> <tr> <?php $allCategories = \Learn\Event\Main::getDealFunnels(); ?> <?php $currentCategory = Option::get($moduleName, 'PIPELINE'); ?> <td>Воронка Сделки</td> <td> <select name="PIPELINE"> <?php foreach ($allCategories as $allCategory) { ?> <option value="<?= $allCategory['ID'] ?>"<?php if ($allCategory['ID'] == $currentCategory) echo ' selected'; ?>><?= $allCategory['NAME'] ?></option> <?php } ?> </select> </td> </tr> <?//Поле "Для пользователей". Множественный выбор пользователей для которых будет срабатывать обработчик.?> <tr> <?php $userCurId = unserialize(Option::get($moduleName, 'USER_EXEPTIONS')); ?> <?php $order = array('sort' => 'asc'); $tmp = 'sort'; // параметр проигнорируется методом, но обязан быть $rsUsers = \CUser::GetList($order, $tmp); $allUsers = []; while ($arUser = $rsUsers->Fetch()) { $allUsers[$arUser["ID"]] = "[" . $arUser["ID"] . "] " . $arUser["NAME"] . " " . $arUser["LAST_NAME"]; } ?> <td>Для пользователей</td> <td> <select name="USER_EXEPTIONS[]" multiple> <?php foreach ($allUsers as $userID => $userName) { ?> <option value="<?= $userID ?>"<?php if ((is_array($userCurId) && in_array($userID, $userCurId)) || $userCurId == $userID) echo ' selected'; ?>><?= $userName ?></option> <?php } ?> </select> </td> </tr> <? $tabControl->End(); ?> <input type="submit" value="Сохранить"> </form> <?php require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_admin.php'; ?>
Данный файл реализует стандартную страницу настроек нашего модуля в разделе панели администратора Битрикс (Настройки — Настройки продукта — Настройки модулей — Управляемые обработчики).
Вместо заключения
Выше мы разобрали минимально необходимый набор файлов, реализующих модуль для Битрикс24, устанавливающий обработчики события, и хранящий настройки для них. Модуль содержит минимальный набор системных методов для того, чтобы Битрикс воспринимал его именно как модуль, а не как набор скриптов непонятного назначения. Всем спасибо за внимание и жду нашей встречи в следующих статьях!
Если вы работаете с коробочной версией Битрикс24 и хотите глубже разобраться в механике событий — их типах, регистрации и возможностях для управления сущностями, обратите внимание на предстоящий открытый урок «События в Битрикс24: Путеводитель по изменениям».
Разберёмся в архитектуре событийной модели и обсудим, как эффективно внедрять собственные сценарии обработки изменений. Старт 21 мая в 20:00 — участие бесплатное, нужно только зарегистрироваться.
А в календаре мероприятий можно записаться на открытые уроки по другим ИТ-направлениям.
ссылка на оригинал статьи https://habr.com/ru/articles/909170/
Добавить комментарий