Архитектура модулей

Bitrix Framework состоит из модулей. Модуль — это автономный компонент системы, который реализует определенную функциональность.

Модуль включает в себя:

  • бизнес-логику,

  • административный интерфейс,

  • компоненты для публичной части,

  • обработчики событий

  • другие элементы, необходимые для работы отдельной части сайта.

Некоторые модули расширяют функционал уже установленных модулей. Например, модуль Торговый каталог добавляет функции работы с товарами к модулю Информационные блоки.

Управление модулями в системе

Все модули отображаются в административной части на странице Настройки > Настройки продукта > Модули.

Неиспользуемый модуль можно удалить. Для некоторых модулей перед удалением система может предложить сохранить таблицы базы данных и другие данные модуля.

Настройки модуля

У модуля может быть собственная страница настроек в административном разделе Настройки > Настройки продукта > Настройки модулей > [Название конкретного модуля]. Наличие страницы настроек зависит от файла options.php в структуре модуля.

Подключить модуль

Чтобы использовать функции модуля, подключите его методом Loader::includeModule(). Метод возвращает true, если модуль подключен, и false, если модуль не установлен или его не удалось подключить.

<?php
use Bitrix\Main\Loader;

if (Loader::includeModule('module_name'))
{
    // В этой области доступны классы и функции модуля
}

Если без модуля нельзя продолжать выполнение сценария, используйте Loader::requireModule(). Метод выбрасывает исключение Bitrix\Main\LoaderException, если модуль не подключен. Если исключение не обработано, выполнение сценария прерывается.

<?php
use Bitrix\Main\Loader;

Loader::requireModule('module_name');

// После успешного подключения доступны классы и функции модуля

Структура файлов модуля

Стандартные модули располагаются в /bitrix/modules/ID_модуля/. Пользовательские модули обязательно размещать в /local/modules/.

Подробнее о папке Local в статье Структура директорий

  • /admin/ — файлы для административного раздела.

    • menu.php — пункты меню для административного раздела.
  • /install/ — файлы для установки и удаления.

    • /admin/ — вспомогательные скрипты для установки.

    • /js/ — JavaScript файлы модуля.

    • /db/ — SQL-скрипты для создания таблиц для разных баз данных, например, /mysql/ или /pgsql/.

    • /images/ — изображения модуля.

    • /components/ — компоненты.

    • /panel/ — стили для административной панели.

    • index.php — главный файл с описанием модуля.

    • version.php — файл с версией модуля.

  • /lang/код_языка/ — языковые файлы.

  • /lib/ — классы ядра D7 ORM.

  • .settings.php — настройки модуля.

  • include.php — подключение основных классов и функций модуля.

  • default_option.php — настройки модуля по умолчанию.

  • options.php — страница настроек модуля.

  • prolog.php — подключается в начале всех админских скриптов модуля.

В Bitrix Framework существуют две архитектуры ядра: классическое ядро и ядро D7. В старых модулях, которые используют классы API классического ядра может быть папка /classes/.

  • /general/ — классы для любой базы данных.

  • /mysql/, /mssql/, /oracle/, /pgsql/ — классы для конкретных СУБД.

Модуль может содержать классы классического ядра и D7 одновременно, но в новом коде рекомендуется использовать только D7.

Классы модуля

Система подключает классы ядра автоматически при соблюдении правил.

  1. Имена файлов и классов. Путь внутри /lib/ повторяет пространство имен после базового пространства модуля и имя класса. Автозагрузчик сначала ищет путь в регистре пространства имен и класса, затем — полностью строчными буквами. Например, класс Company\Module\MyService можно разместить в /lib/MyService.php или /lib/myservice.php, а Company\Module\Search\IndexManager — в /lib/Search/IndexManager.php или /lib/search/indexmanager.php.

  2. Пространства имен. Класс должен находиться в пространстве имен, которое соответствует идентификатору модуля. Для модуля company.module пространство имен будет Company\Module.

    <?php
    // Файл: /local/modules/company.module/lib/myservice.php
    namespace Company\Module;
    
    class MyService
    {
        // Логика класса
    }
    
  3. Подключение модуля. Перед использованием классов модуль нужно подключить.

    <?php
    use Bitrix\Main\Loader;
    use Company\Module\MyService;
    
    if (Loader::includeModule('company.module'))
    {
        // Теперь можно использовать классы модуля
        $service = new MyService();
    }
    

    Если код не должен работать без модуля, подключите модуль методом Loader::requireModule().

    <?php
    use Bitrix\Main\Loader;
    use Company\Module\MyService;
    
    Loader::requireModule('company.module');
    
    $service = new MyService();
    

Описание модуля

Чтобы зарегистрировать модуль в системе, создайте файл описания index.php в папке /local/modules/ID_модуля/install/. Файл должен содержать класс — наследник базового класса CModule из Главного модуля. Имя класса должно совпадать с ID модуля с заменой точки на нижнее подчеркивание.

Пример. Для модуля company.module имя класса будет company_module.

В классе нужно задать обязательные свойства.

  • MODULE_ID — идентификатор модуля.

  • MODULE_VERSION — версия модуля из трех чисел, разделенных точками, например 1.0.0.

  • MODULE_VERSION_DATE — дата выпуска версии в формате ГГГГ-ММ-ДД ЧЧ:МИ:СС.

  • MODULE_NAME — название модуля.

  • MODULE_DESCRIPTION — описание модуля.

  • MODULE_GROUP_RIGHTS — значение Y указывает, что модуль использует собственные права доступа.

Значения MODULE_NAME и MODULE_DESCRIPTION рекомендуется хранить в языковом файле. Для класса из /install/index.php языковой файл должен находиться по пути /lang/<код_языка>/install/index.php. При построении списка модулей система создает объект класса модуля и выводит значения этих свойств.

А также описать логику для двух обязательных методов.

  • DoInstall() — устанавливает модуль.

  • DoUninstall() — удаляет модуль.

Пример файла /install/index.php.

<?php

use Bitrix\Main\Application;
use Bitrix\Main\IO\File;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\ModuleManager;

Loc::loadMessages(__FILE__);

/**
 * Класс для модуля `vendor.modulename`, вместо точки `.` используется прочерк `_`
 */
class vendor_modulename extends CModule
{
    public $MODULE_ID = 'vendor.modulename';

    public function __construct()
    {
        $this->MODULE_NAME = Loc::getMessage('VENDOR_MODULENAME_MODULE_NAME');
        $this->MODULE_DESCRIPTION = Loc::getMessage('VENDOR_MODULENAME_MODULE_DESC');

        include(__DIR__ . '/version.php');

        if (isset($arModuleVersion['VERSION']))
        {
            $this->MODULE_VERSION = $arModuleVersion['VERSION'];
            $this->MODULE_VERSION_DATE = $arModuleVersion['VERSION_DATE'] ?? null;
        }
    }

    public function DoInstall()
    {
        $this->InstallDB();
        $this->InstallFiles();

        ModuleManager::registerModule($this->MODULE_ID);
    }

    public function DoUninstall()
    {
        $this->UnInstallDB();
        $this->UnInstallFiles();

        ModuleManager::unRegisterModule($this->MODULE_ID);
    }

    /**
     * Выполнение SQL-скрипта для создания таблиц модуля
     *
     * @return void
     */
    public function InstallDB()
    {
        global $APPLICATION;

        $db = Application::getConnection();
        $errors = $db->executeSqlBatch(
            File::getFileContents(__DIR__ . '/db/' . $db->getType() . '/install.sql')
        );
        if (!empty($errors))
        {
            $APPLICATION->ThrowException(
                join(',', $errors)
            );
        }
    }

    /**
     * Выполнение SQL-скрипта для удаления таблицы модуля
     *
     * @return void
     */
    public function UnInstallDB()
    {
        global $APPLICATION;

        $db = Application::getConnection();
        $errors = $db->executeSqlBatch(
            File::getFileContents(__DIR__ . '/db/' . $db->getType() . '/uninstall.sql')
        );
        if (!empty($errors))
        {
            $APPLICATION->ThrowException(
                join(',', $errors)
            );
        }
    }

    /**
     * Копирование ресурсов, компонентов и оберток административных скриптов
     *
     * @return void
     */
    public function InstallFiles()
    {
        CopyDirFiles(__DIR__ . '/js', $_SERVER['DOCUMENT_ROOT'] . '/local/js', true);
        CopyDirFiles(__DIR__ . '/admin', $_SERVER['DOCUMENT_ROOT'] . '/bitrix/admin', true);
        CopyDirFiles(__DIR__ . '/themes', $_SERVER['DOCUMENT_ROOT'] . '/local/themes', true, true);
        CopyDirFiles(__DIR__ . '/components', $_SERVER['DOCUMENT_ROOT'] . '/local/components', true, true);
    }

    /**
     * Удаление установленных файлов модуля
     *
     * @return void
     */
    public function UnInstallFiles()
    {
        DeleteDirFiles(__DIR__ . '/js', $_SERVER['DOCUMENT_ROOT'] . '/local/js');
        DeleteDirFiles(__DIR__ . '/admin', $_SERVER['DOCUMENT_ROOT'] . '/bitrix/admin');
        DeleteDirFiles(__DIR__ . '/themes', $_SERVER['DOCUMENT_ROOT'] . '/local/themes');
        DeleteDirFiles(__DIR__ . '/components', $_SERVER['DOCUMENT_ROOT'] . '/local/components');
    }
}

Методы InstallDB() и UnInstallDB() читают SQL из файлов /install/db/<тип_БД>/install.sql и uninstall.sql. Метод executeSqlBatch() принимает текст запросов, поэтому содержимое файла нужно получить через File::getFileContents().

Информация о версии

Файл install/version.php содержит информацию о версии модуля. Он подключается в конструкторе класса модуля.

<?php
$arModuleVersion = [
    'VERSION' => '1.0.0',
    'VERSION_DATE' => '2023-12-01 12:00:00',
];

Установить модуль

Перед установкой разместите файлы модуля в папке /local/modules/ваш.модуль/. Затем перейдите в раздел Marketplace > Установленные решения и нажмите Установить для нужного модуля.

Во время установки система запускает метод DoInstall() из класса модуля. Метод выполняет действия, описанные в классе модуля. Например в классе модуля можно описать:

  • регистрацию модуля в системе с помощью ModuleManager::registerModule(),

  • создание необходимых таблиц в базе данных,

  • регистрацию обработчиков событий.

Пошаговая установка

Если перед установкой нужно получить параметры от администратора, разбейте установку на шаги. На первом шаге DoInstall() показывает административную форму через $APPLICATION->IncludeAdminFile(). Форма передает скрытые поля install=Y, step=2 и параметры установки. На втором шаге DoInstall() читает значения из запроса и выполняет установку: создает таблицы, регистрирует модуль, копирует файлы, добавляет обработчики событий.

Для пошаговой установки создайте два файла:

  • /install/install_step1.php — форма первого шага,

  • /install/index.php — файл описания модуля с классом, который показывает форму и обрабатывает второй шаг.

В форме служебные поля управляют сценарием установки:

  • id — указывает модуль,
  • install=Y — сохраняет действие установки,
  • step=2 — переводит установщик ко второму шагу,
  • lang — сохраняет язык административного интерфейса.

Пример файла /install/install_step1.php для первого шага установки.

<?php
// Файл: /local/modules/company.module/install/install_step1.php
?>
<form action="<?= $APPLICATION->GetCurPage() ?>">
    <?= bitrix_sessid_post() ?>
    <input type="hidden" name="lang" value="<?= LANG ?>">
    <input type="hidden" name="id" value="company.module">
    <input type="hidden" name="install" value="Y">
    <input type="hidden" name="step" value="2">

    <p>
        <input type="checkbox" name="create_demo_data" id="create_demo_data" value="Y">
        <label for="create_demo_data">Создать демонстрационные данные</label>
    </p>

    <input type="submit" name="inst" value="Установить модуль">
</form>

Пример обработки шагов в файле /install/index.php.

<?php
use Bitrix\Main\ModuleManager;

class company_module extends CModule
{
    public $MODULE_ID = 'company.module';

    public function InstallDB(array $params = [])
    {
        if (($params['createDemoData'] ?? 'N') === 'Y')
        {
            // Создание демонстрационных данных модуля
        }

        return true;
    }

    public function DoInstall()
    {
        global $APPLICATION;

        if (!check_bitrix_sessid())
        {
            return false;
        }

        $step = (int)($_REQUEST['step'] ?? 1);

        if ($step < 2)
        {
            $APPLICATION->IncludeAdminFile(
                'Установка модуля',
                __DIR__ . '/install_step1.php'
            );

            return true;
        }

        $this->InstallDB([
            'createDemoData' => $_REQUEST['create_demo_data'] ?? 'N',
        ]);
        $this->InstallFiles();

        ModuleManager::registerModule($this->MODULE_ID);

        return true;
    }
}

Удалить модуль

Чтобы удалить модуль, нажмите Стереть на странице Установленные решения и подтвердите действие.

При удалении система запускает метод DoUninstall(). Метод выполняет действия, описанные в классе модуля. Например в классе модуля можно описать:

  • снятие регистрации модуля через ModuleManager::unRegisterModule(),

  • удаление таблиц модуля из базы данных, если нет подтверждения о сохранении данных.

Из системы нельзя удалить:

  • главный модуль main,

  • управление структурой fileman,

  • UI-библиотеку ui,

  • проактивную защиту security.

Пошаговое удаление с сохранением данных

Если перед удалением модуля нужно спросить администратора, сохранять ли таблицы базы данных или другие данные модуля, разбейте удаление на шаги.

Для пошагового удаления создайте три файла:

  • /install/uninstall_step1.php — форма с вопросом о сохранении данных,

  • /install/index.php — файл описания модуля с классом, который показывает форму, читает savedata и выполняет удаление,

  • /install/uninstall_step2.php — экран результата удаления.

На первом шаге метод DoUninstall() показывает административную форму. В форме передайте скрытые поля uninstall=Y, step=2 и поле с флагом сохранения данных, например savedata=Y.

В форме удаления поле:

  • id — указывает модуль,
  • uninstall=Y — сохраняет действие удаления,
  • step=2 — переводит удаление ко второму шагу,
  • savedata=Y — передает решение администратора сохранить данные.
<?php
// Файл: /local/modules/company.module/install/uninstall_step1.php
?>
<form action="<?= $APPLICATION->GetCurPage() ?>">
    <?= bitrix_sessid_post() ?>
    <input type="hidden" name="lang" value="<?= LANG ?>">
    <input type="hidden" name="id" value="company.module">
    <input type="hidden" name="uninstall" value="Y">
    <input type="hidden" name="step" value="2">

    <p>Вы можете сохранить данные в таблицах базы данных:</p>
    <p>
        <input type="checkbox" name="savedata" id="savedata" value="Y" checked>
        <label for="savedata">Сохранить таблицы</label>
    </p>

    <input type="submit" name="inst" value="Удалить модуль">
</form>

На втором шаге DoUninstall() получает значение savedata из запроса и передает его в метод удаления базы данных. Если администратор оставил флаг savedata=Y, метод UnInstallDB() не удаляет таблицы. Если флага нет или он отличается от Y, метод удаляет данные модуля.

<?php
use Bitrix\Main\Application;
use Bitrix\Main\ModuleManager;

class company_module extends CModule
{
    public $MODULE_ID = 'company.module';

    public function DoUninstall()
    {
        if (!check_bitrix_sessid())
        {
            return false;
        }

        global $APPLICATION;

        $step = (int)($_REQUEST['step'] ?? 1);

        if ($step < 2)
        {
            $APPLICATION->IncludeAdminFile(
                'Удаление модуля',
                __DIR__ . '/uninstall_step1.php'
            );

            return true;
        }

        $this->UnInstallDB([
            'savedata' => $_REQUEST['savedata'] ?? 'N',
        ]);
        $this->UnInstallFiles();

        ModuleManager::unRegisterModule($this->MODULE_ID);

        $APPLICATION->IncludeAdminFile(
            'Удаление модуля',
            __DIR__ . '/uninstall_step2.php'
        );

        return true;
    }

    public function UnInstallDB(array $params = [])
    {
        if (($params['savedata'] ?? 'N') === 'Y')
        {
            return true;
        }

        $connection = Application::getConnection();
        $connection->dropTable('company_module_item');

        return true;
    }
}

Файл uninstall_step2.php нужен, чтобы показать результат удаления. Если при удалении возникли ошибки, сохраните их в свойство класса или в глобальную переменную и выведите на этом экране вместо сообщения об успешном завершении.

<?php
// Файл: /local/modules/company.module/install/uninstall_step2.php

if (!check_bitrix_sessid())
{
    return;
}
?>
<p>Удаление модуля завершено.</p>

<form action="<?= $APPLICATION->GetCurPage() ?>">
    <input type="hidden" name="lang" value="<?= LANG ?>">
    <input type="submit" value="Вернуться к списку модулей">
</form>

Параметры модуля

Параметры модулей система хранит в базе данных. Параметры можно задавать через административный интерфейс или в коде.

Файлы параметров

Файл default_option.php содержит значения параметров по умолчанию. Имя массива состоит из идентификатора модуля с заменой точек на _ и суффикса _default_option. Для модуля company.module используйте $company_module_default_option.

<?php
// Файл: /local/modules/company.module/default_option.php
$company_module_default_option = [
    'API_KEY' => '',
    'CACHE_TIME' => 3600,
    'ENABLE_LOG' => 'Y'
];

Метод Option::get() сначала возвращает сохраненное значение. Если его нет, метод возвращает непустой аргумент $default. При $default, равном пустой строке, метод ищет значение в default_option.php. Если значения нет и в файле, метод возвращает $default.

Страница настроек

Файл options.php содержит форму и логику сохранения параметров. Система подключает его из /bitrix/admin/settings.php после административного пролога. В этот момент доступны $APPLICATION, $USER, идентификатор выбранного модуля $mid и константа языка интерфейса LANGUAGE_ID. Повторно подключать пролог и эпилог в options.php не нужно.

Создайте /local/modules/company.module/options.php. Для доступа к странице settings.php нужна операция view_other_settings или edit_other_settings. Пользователю также нужен доступ на чтение файла /bitrix/admin/settings.php, который определяют права на файлы и каталоги сайта.

В примере пользователь с правом R на модуль может просматривать параметры, а с правом W и операцией edit_other_settings — сохранять их.

Форма отправляет POST-запрос на страницу настроек. Поле mid выбирает модуль, а lang сохраняет язык интерфейса. Функция bitrix_sessid_post() добавляет CSRF-токен, который код проверяет через check_bitrix_sessid() перед сохранением.

<?php
use Bitrix\Main\Config\Option;
use Bitrix\Main\Context;

if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true)
{
    return;
}

$moduleId = 'company.module';
$moduleRight = $APPLICATION->GetGroupRight($moduleId);

if ($moduleRight < 'R')
{
    $APPLICATION->AuthForm('Доступ запрещен');
    return;
}

$canSave = $moduleRight >= 'W' && $USER->CanDoOperation('edit_other_settings');
$request = Context::getCurrent()->getRequest();

if ($request->isPost() && $canSave && check_bitrix_sessid())
{
    Option::set($moduleId, 'ENABLE_LOG', $request->getPost('ENABLE_LOG') === 'Y' ? 'Y' : 'N');
}

$enableLog = Option::get($moduleId, 'ENABLE_LOG');
?>
<form method="post" action="/bitrix/admin/settings.php">
    <?= bitrix_sessid_post() ?>
    <input type="hidden" name="mid" value="<?= htmlspecialcharsbx($moduleId) ?>">
    <input type="hidden" name="lang" value="<?= htmlspecialcharsbx(LANGUAGE_ID) ?>">

    <p>
        <label>
            <input type="checkbox" name="ENABLE_LOG" value="Y"<?= $enableLog === 'Y' ? ' checked' : '' ?><?= !$canSave ? ' disabled' : '' ?>>
            Включить журналирование
        </label>
    </p>
    <input type="submit" value="Сохранить"<?= !$canSave ? ' disabled' : '' ?>>
</form>

Вызов Option::get() без третьего аргумента использует значение ENABLE_LOG из default_option.php, пока администратор не сохранит параметр.

Работа с параметрами через код

Для работы с параметрами модуля используют класс \Bitrix\Main\Config\Option.

Получить параметр

Метод get($moduleId, $name, $default = "", $siteId = false) получает значение параметра.

$apiKey = \Bitrix\Main\Config\Option::get('my.module', 'api_key', 'default_value');
  • $moduleId — идентификатор модуля.

  • $name — имя параметра.

  • $default — значение для отсутствующего параметра. Непустое значение имеет приоритет перед default_option.php.

  • $siteId — идентификатор сайта. Если false, используется текущий сайт. Не обязательный параметр.

Установить значение параметра

Метод set($moduleId, $name, $value = "", $siteId = "") устанавливает значение параметра $value. Если параметр существует — обновляет его, иначе создает новый.

\Bitrix\Main\Config\Option::set('my.module', 'api_key', 'new_secret_key');
\Bitrix\Main\Config\Option::set('my.module', 'cache_time', 3600, 's1'); // Для конкретного сайта

После сохранения вызываются события OnAfterSetOption и OnAfterSetOption_[имя_параметра]. Если $siteId не указан, параметр считается общим для всех сайтов.

Удалить параметр

Метод delete($moduleId, array $filter = []) удаляет параметр по фильтру. Фильтр может содержать ключи:

  • name — имя параметра для удаления.

  • site_id — идентификатор сайта. Если не указан, удаляются параметры для всех сайтов.

// Удалить конкретный параметр для всех сайтов
\Bitrix\Main\Config\Option::delete('my.module', ['name' => 'api_key']);

// Удалить параметр только для конкретного сайта
\Bitrix\Main\Config\Option::delete('my.module', [
    'name' => 'api_key',
    'site_id' => 's1'
]);

// Удалить все параметры модуля
\Bitrix\Main\Config\Option::delete('my.module');

Административные скрипты

Административные скрипты — это PHP-файлы, которые создают интерфейс управления модулем в административной панели. Для пользовательского модуля разместите их в папке /local/modules/ID_модуля/admin/.

Файлы в папке /admin/ недоступны для прямого вызова через браузер, поэтому для каждого административного скрипта нужно сделать скрипт-обертку в папке /bitrix/admin/.

  • Основной скрипт — /local/modules/company.module/admin/my_page.php.

  • Обертка — /bitrix/admin/company_module_my_page.php.

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . '/local/modules/company.module/admin/my_page.php');

Разместите обертки в /local/modules/company.module/install/admin/. При установке метод InstallFiles() модуля должен скопировать их в /bitrix/admin/, как в примере установщика выше. Метод UnInstallFiles() удаляет установленные обертки из этой же папки.

Для корректной работы административных скриптов в каждом из них необходимо определить константу ADMIN_MODULE_NAME, которая служит идентификатором модуля в административном интерфейсе. Константа связывает административные скрипты модуля с системой.

  • Определяет, какому модулю принадлежит административная страница.

  • Участвует в формировании ссылки на страницу настроек модуля по кнопке Настройки на административной панели.

  • Помогает в проверках прав доступа к разделам модуля.

Константа задается в файле prolog.php модуля.

<?php
define('ADMIN_MODULE_NAME', 'company.module');

Подключите prolog.php в начале каждого административного скрипта.

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . '/local/modules/company.module/prolog.php');

Административные списки

Административный список — таблица с записями модуля на странице из папки /admin/. Пример такой страницы в ядре — список пользователей в разделе Настройки > Пользователи > Список пользователей. Страница настроек options.php к административным скриптам не относится. Это форма параметров модуля, она описана в разделе «Параметры модуля».

В модуле main доступны два класса для вывода списков:

  • CAdminList — базовый класс для вывода списков элементов в интерфейсе административного раздела. Класс выводит таблицу с сортировкой, фильтрацией и действиями с элементами.

  • CAdminUiList — наследник CAdminList, добавляет поддержку современного интерфейса в административном разделе: AJAX-загрузка, улучшенные фильтры, гибкая настройка колонок. Класс применяют в новых модулях и интерфейсах.

Режимы работы грида

Грид — это компонент для вывода данных в виде таблицы с поддержкой сортировки, фильтрации, редактирования и других действий без перезагрузки страницы. Поддерживает несколько режимов работы:

  • простой вывод списка элементов (открытие страницы),

  • обработка быстрого редактирования элементов,

  • обновление грида без перезагрузки страницы, например сортировка,

  • выгрузка в формат для Excel,

  • показ формы настроек грида.

Конструктор списка определяет режим по параметру mode запроса. Если параметр не передан или содержит неизвестное значение, список работает в режиме обычного вывода страницы. Чтобы узнать текущий режим, вызовите метод getCurrentMode():

$sTableID = 'tbl_user'; // Идентификатор таблицы для списка
$lAdmin = new CAdminUiList($sTableID); // Создаем экземпляр списка

$mode = $lAdmin->getCurrentMode(); // Получаем текущий режим работы
$excelMode = $mode === CAdminList::MODE_EXPORT; // Проверяем, включен ли режим экспорта в Excel

Метод вернет одну из констант класса CAdminList:

  • public const MODE_PAGE = 'normal'; — обычный вывод страницы,

  • public const MODE_LIST = 'list'; — обновление грида без полной перезагрузки,

  • public const MODE_ACTION = 'frame'; — обработка результатов быстрого редактирования,

  • public const MODE_EXPORT = 'excel'; — выгрузка в Excel,

  • public const MODE_CONFIG = 'settings'; — показ формы настроек.

Вспомогательные методы

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

  • public function isPageMode(): bool — возвращает true, если страница с гридом открывается в браузере,

  • public function isExportMode(): bool — возвращает true в режиме выгрузки в Excel,

  • public function isAjaxMode(): bool — возвращает true при обновлении грида и обработке быстрого редактирования, то есть в режимах MODE_LIST и MODE_ACTION,

  • public function isConfigMode(): bool — возвращает true при показе окна настроек,

  • public function isActionMode(): bool — возвращает true при обработке результатов inline-редактирования,

  • public function isListMode(): bool — возвращает true при обновлении блока грида без обновления страницы.

Пример. Проверка режима экспорта через вспомогательный метод.

$excelMode = $lAdmin->isExportMode(); // То же, что сравнение с CAdminList::MODE_EXPORT

Обработка inline-редактирования элементов

Пользователь меняет значения прямо в таблице, а страница получает измененные поля без перезагрузки.

Пример. Сохранение результатов inline-редактирования.

// Проверить, было ли отправлено inline-редактирование
if ($lAdmin->EditAction())
{
    // Добавить загруженные файлы в список изменяемых полей
    $lAdmin->ConvertFilesToEditFields();

    // Обработать каждую измененную запись
    foreach ($lAdmin->GetEditFields() as $id => $fields)
    {
        // Сохранить изменения для записи с ID $id
        // $fields содержит новые значения полей
    }
}

Методы:

  • public function GetEditFields(): array — возвращает массив измененных записей. Ключ массива — ID записи, значение — новые значения полей. Записи с пустым ID и записи без изменений метод пропускает.

  • public function ConvertFilesToEditFields(): void — добавляет загруженные файлы в общий массив полей.

Групповые операции

Групповая операция применяет одно действие сразу к нескольким выбранным элементам списка.

Метод GroupAction() возвращает массив идентификаторов выбранных элементов. Если действие не выбрано, элементы не отмечены или проверка сессии не прошла, метод вернет false.

Если пользователь отметил пункт Для всех, метод GroupAction() вернет массив с одной пустой строкой. В этом случае получите идентификаторы всех элементов списка самостоятельно, например выборкой с текущим фильтром.

Пример. Обработка группового действия.

// Получить идентификаторы выбранных элементов
$itemIds = $lAdmin->GroupAction();

if ($itemIds)
{
    // Получить выбранное действие
    $actionId = $lAdmin->GetAction();

    // Проверить действие Для всех
    if ($lAdmin->IsGroupActionToAll())
    {
        // Заполнить $itemIds идентификаторами всех элементов списка
        $itemIds = [];
    }

    // Обработать каждый элемент
    foreach ($itemIds as $itemId)
    {
        switch ($actionId)
        {
            case 'delete':
                // Удалить элемент
                break;
            case 'update':
                // Обновить элемент
                break;
            default:
                // Другое действие
        }
    }
}

Методы:

  • public function GetAction() — возвращает идентификатор группового действия или null, если действие не передано,

  • public function IsGroupActionToAll() — возвращает true, если пользователь отметил в гриде пункт Для всех.

Языковые файлы

Языковые файлы хранят текстовые сообщения модуля для разных языков. Для пользовательского модуля разместите их в папке /local/modules/ID_модуля/lang/ID_языка/, повторяя структуру основных файлов.

Пример. Структура языковых файлов для /local/modules/company.module/admin/my_page.php.

/local/modules/company.module/
├── admin/
│   └── my_page.php
└── lang/
    ├── en/
    │   └── admin/
    │       └── my_page.php
    └── ru/
        └── admin/
            └── my_page.php

Содержимое языкового файла — это массив $MESS. Система автоматически ищет и загружает фразы из него.

<?php
$MESS['COMPANY_MODULE_PAGE_TITLE'] = 'Управление модулем компании';
$MESS['COMPANY_MODULE_SAVE_BTN'] = 'Сохранить';

Подключить языковые файлы

Подключить языковой файл можно функцией Loc::loadMessages().

<?php
// В файле: /local/modules/company.module/admin/my_page.php
use Bitrix\Main\Localization\Loc;

Loc::loadMessages(__FILE__);

echo Loc::getMessage('COMPANY_MODULE_PAGE_TITLE');

Параметр __FILE__ передает путь к текущему файлу, что позволяет системе найти соответствующий языковой файл в папке lang.

Структура внутри папки языка должна повторять путь исходного PHP-файла относительно корня модуля.

/install/index.php
└── /lang/ru/install/index.php

/admin/my_page.php
└── /lang/ru/admin/my_page.php

Подробнее в статье Локализация.

Административное меню

Модуль может добавлять пункты в административное меню. Для этого создайте файл menu.php в папке модуля с массивом пунктов меню.

<?php
// Файл: /local/modules/company.module/admin/menu.php

use Bitrix\Main\Localization\Loc;

Loc::loadMessages(__FILE__);

return [
    [
        'parent_menu' => 'global_menu_services',
        'sort' => 100,
        'text' => Loc::getMessage('COMPANY_MODULE_MENU_TITLE'),
        'title' => Loc::getMessage('COMPANY_MODULE_MENU_TOOLTIP'),
        'url' => 'company_module_my_page.php?lang=' . LANGUAGE_ID,
        'icon' => 'company_menu_icon',
        'items_id' => 'menu_company_module',
    ]
];

Система автоматически собирает пункты меню из всех установленных модулей.

Взаимодействие модулей

Модули могут взаимодействовать между собой несколькими способами.

  1. Прямое взаимодействие. После подключения модуля функции и методы классов вызываются напрямую.

    <?php
    if (\Bitrix\Main\Loader::includeModule('iblock'))
    {
        $iblockId = CIBlock::GetList([], ['CODE' => 'news'])->Fetch()['ID'];
        // Дальнейшая работа с инфоблоком
    }
    

    Если модуль обязателен для дальнейшей работы, используйте Loader::requireModule().

    <?php
    \Bitrix\Main\Loader::requireModule('iblock');
    
    $iblockId = CIBlock::GetList([], ['CODE' => 'news'])->Fetch()['ID'];
    // Дальнейшая работа с инфоблоком
    
  2. Взаимодействие через события. Модуль генерирует событие в определенный момент. Другие модули могут подписаться на это событие и выполнить свой код.

    Подробнее в статье События.

  3. Взаимодействие через конфигурацию модулей. Один модуль может читать настройки другого модуля через \Bitrix\Main\Config\Option и менять свое поведение на основе этих значений. Такой способ подходит для интеграций, где модуль не вызывает чужие классы напрямую, а использует сохраненные параметры: включение функции, идентификатор инфоблока, код сайта или другие настройки.

    <?php
    $iblockId = \Bitrix\Main\Config\Option::get('company.module', 'news_iblock_id');
    
    if ($iblockId > 0 && \Bitrix\Main\Loader::includeModule('iblock'))
    {
        // Работа с инфоблоком, который выбран в настройках модуля
    }