Перейти к содержимому

Модуль установился, но не работает - разбор причин

Модуль числится в списке установленных, но признаков жизни не подаёт: пункта в меню админки нет, страница модуля отдаёт 404, классы не находятся, обработчики молчат. Разбираем причины по убыванию частоты, начиная с подключения модуля.

С чего начать

Проверяем, подключается ли модуль вообще:

$id = 'vendor.module';
var_dump(\Bitrix\Main\Loader::includeModule($id)); // false - модуль не зарегистрирован
var_dump(class_exists('\\Vendor\\Module\\Sync')); // классы видит автозагрузка include.php
// имя модуля пишется с точкой: код партнёра и код решения

Этот вызов делит причины пополам. Ложь означает, что установщик не зарегистрировал модуль в системе, а истина при ненайденном классе переводит разбор на автозагрузку.

Смотрим, что установка скопировала наружу:

Окно терминала
ls -la /home/bitrix/www/bitrix/admin/ | grep vendor_module
ls -la /home/bitrix/www/local/modules/vendor.module/admin/menu.php
# каталог модуля веб-серверу недоступен, наружу файлы попадают только копированием

Тела административных страниц остаются в каталоге модуля, а в общий каталог админки установка копирует короткие вызывающие скрипты. Пропущенное копирование оставляет решение без единой открываемой страницы.

Сверяем регистрацию автозагрузки в точке входа:

// /local/modules/vendor.module/include.php - подключается при includeModule()
\Bitrix\Main\Loader::registerNamespace('Vendor\Module', __DIR__ . '/lib');
// имя файла в нижнем регистре повторяет имя класса, namespace собран из кода модуля
\Bitrix\Main\Loader::registerAutoLoadClasses('vendor.module', ['Vendor\Module\Log' => 'lib/log.php']);
// вторая форма - явная карта классов для путей мимо правила автозагрузки

Смотрим описание пункта меню:

/local/modules/vendor.module/admin/menu.php
$aMenu[] = array(
'parent_menu' => 'global_menu_settings', // раздел админки для пункта
'sort' => 1800,
'text' => GetMessage('VENDOR_MODULE_MENU'),
'url' => 'vendor_module_index.php?lang=' . LANGUAGE_ID,
);

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

Читаем список обработчиков события из базы:

$rs = GetModuleEvents('iblock', 'OnAfterIBlockElementAdd');
while ($h = $rs->Fetch()) { print_r($h); } // пусто - регистрации в установщике не было
// метод обработчика объявляют статическим, иначе вызов падает на стороне PHP

Причины

  1. Установщик не зарегистрировал модуль в системе примерно 30% случаев

    ПризнакПодключение модуля возвращает ложь, хотя решение видно в списке установленных.

    ПроверкаИщем вызов регистрации модуля в методе установки: без него модуль не считается установленным.

    Что делатьДобавляем регистрацию модуля в метод установки и проходим установку заново на чистой копии.

  2. Автозагрузка классов не описана в точке входа примерно 25% случаев

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

    ПроверкаСмотрим файл подключения модуля: регистрацию пространства имён или явную карту классов.

    Что делатьРегистрируем пространство имён по стандарту и приводим имя файла к нижнему регистру.

  3. Файлы модуля не скопированы наружу при установке примерно 20% случаев

    ПризнакПункт меню ведёт на страницу, которой нет, а иконки решения не отображаются.

    ПроверкаИщем вызывающий скрипт модуля в каталоге админки по префиксу с кодом модуля.

    Что делатьКопируем каталоги установки в доступные веб-серверу папки и снимаем копии при удалении.

  4. Пункт меню не описан или ушёл в чужой раздел примерно 15% случаев

    ПризнакСтраница модуля открывается по прямой ссылке, но в меню админки её пункта нет.

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

    Что делатьЗаполняем массив пунктов с родительским разделом либо добавляем пункт на событии сборки меню.

  5. Обработчики зарегистрированы, но не вызываются примерно 10% случаев

    ПризнакУстановка прошла, а код обработчика при сохранении заказа не отрабатывает.

    ПроверкаЧитаем список обработчиков события из базы и сверяем имя класса и метода.

    Что делатьОбъявляем метод обработчика статическим и приводим пространство имён к правилу автозагрузки.

Частые вопросы

Почему Битрикс не находит класс из моего модуля?

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

Почему при установке модуля меню в админке не отображается?

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

Почему обработчик события не вызывается?

Запись в базе есть, но класс не находится автозагрузкой либо метод объявлен нестатическим. Смотрят список обработчиков события и сигнатуру метода в классе модуля.

Можно ли вызывать классы своего модуля прямо в установщике?

Да, но только после регистрации модуля и его подключения внутри метода установки. До регистрации подключение возвращает ложь, и класс не находится.

Почему у пункта модуля нет иконки?

Файлы фона лежат в каталоге тем модуля, куда ссылается стиль пункта меню. Без копирования этого каталога при установке иконка не появляется.

Смежное

Первоисточник