Обновление через сервис обновлений
Есть два способа обновить модуль, и ведут они себя по-разному.
Подменой файлов — вы заливаете новый код и нажимаете «Обновить» в Маркетплейсе. Битрикс зовёт у модуля метод обновления, тот раскладывает файлы и правит схему. Это обычный путь.
Через сервис обновлений — Битрикс скачивает пакет и применяет его сам. Метод обновления модуля при этом не вызывается вовсе. Вместо него ядро выполняет скрипт updater<версия>.php из корня скачанного архива.
Разница существенная: если бы модуль рассчитывал только на первый путь, при обновлении через сервис миграции не запустились бы ни разу, и клиент получил бы новый код на старой схеме.
Что делает скрипт обновления
Образец лежит в модуле — install/updater.php. Он повторяет то же, что делает обычное обновление:
| Шаг | Зачем |
|---|---|
| Раскладка файлов | скрипты, стили, эндпоинт и заглушки админки лежат вне каталога модуля, подмена каталога их не трогает |
| Правка схемы | таблица состояния, её колонки, поля словаря, индекс, агент — всё идемпотентно |
| Перерегистрация обработчиков | состав событий между версиями меняется |
| Досев прав | только тем группам, у которых доступа не было |
Одной правки схемы мало: без раскладки файлов на обновлённом сайте останется клиентская часть прежней версии.
Две ловушки, на которых ломались соседние модули
Скрипт исполняется из каталога распакованного архива, а не из каталога установленного модуля. Поэтому подключать соседний файл по __DIR__ нельзя — это ведёт в пустоту и даёт фатальную ошибку, которую не поймает catch. Установщик ищется по трём путям, и порядок важен: сначала /local/, затем /bitrix/, и только потом архив. Иначе на сайте с модулем в /local/ подключится установщик чужой версии.
Копию скрипта в архив кладёт сборка пакета. Сам по себе install/updater.php не запускается никогда: ядро ищет файл с именем вида updater8.0.0.php в корне архива. Упаковщик модуля это делает.
Что будет на неподходящем PHP
Скрипт обновления первым делом сравнивает версию PHP с требованием модуля и, если она ниже, отказывается: схему базы и служебные файлы не трогает, а причину кладёт в отчёт обновления — там же, где Битрикс показывает остальные сообщения о пакете.
Важно понимать, чего этот отказ не делает. Файлы каталога модуля механизм обновления подменяет раньше, чем доходит до скрипта, — отменить это скрипт уже не может. То есть отказ бережёт согласованность: схема и разложенные по сайту файлы остаются от прежней версии и продолжают работать вместе. А каталог модуля к тому моменту уже новый, и до подъёма PHP машинный перевод работать не будет.
Что делать: поднять версию PHP и нажать «Обновить» в списке модулей ещё раз. Откатываться для этого не нужно.
Как убедиться, что обновление прошло
Проверьте то же, что и после обычного обновления: файлы вне каталога модуля, колонки таблицы состояния, состав агентов. Список — Что проверить после выкладки.
Отдельный признак: агента Agents\LangIblockQueue::tick(); быть не должно. Он удалён из модуля, и обновление снимает его запись. Если он остался — значит обновление не выполнялось, и агент будет падать на каждом запуске: класса больше нет.