security · Проактивная защита 26.200.0 Безопасность

Security 26.200.0 не ставится на маке и Windows: фатал «Cannot redeclare class» прямо в апдейтере

4 мин чтения

Обновление безопасности

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

Обновление security 26.200.0 у нас не установилось вообще: апдейтер умирает с фаталом посреди своего скрипта. Если ваш прод на Linux — выдыхайте, вас это не касается. А вот если вы ставите обновления в локальной разработке на macOS или Windows (Docker с bind-mount проектной папки — это ровно тот случай) — есть неплохой шанс поймать то же самое. Разбираем, почему падает и что с этим делать.

Что происходит

Картина при установке через update:modules:

        Installing security (26.200.0)... PHP Fatal error:
Cannot redeclare class Bitrix\Main\Mail\Internal\EventMessageTable
(previously declared in .../main/lib/Mail/Internal/EventMessageTable.php:33)
in .../main/lib/Mail/Internal/EventMessage.php on line 33

    

Апдейтер security добавляет новый почтовый шаблон USER_OTP_AUTH_CODE (письмо с одноразовым паролем) через старый добрый CEventMessage->Add(). Дальше цепочка такая:

  1. CEventMessage->CheckFields() зовёт CEventType::GetListEx(), а тот регистрирует в ORM runtime-поле со ссылкой на data_type = 'Bitrix\Main\Mail\Internal\EventMessage' — имя сущности без суффикса Table.
  2. ORM делает class_exists('...\EventMessage'), автозагрузчик по PSR-4 идёт за файлом lib/Mail/Internal/EventMessage.php.
  3. На Linux такого файла нет: class_exists вернёт false, ORM спокойно допишет Table и продолжит. Никто ничего не замечает годами.
  4. На регистронезависимой файловой системе (macOS APFS по умолчанию, Windows NTFS) путь EventMessage.php схлопывается в легаси-файл eventmessage.php — старое lowercase-имя из тех времён, когда весь D7 лежал в нижнем регистре. Внутри него — тот же класс EventMessageTable, который уже загружен из соседнего EventMessageTable.php. PHP: «Cannot redeclare class», E_COMPILE_ERROR, занавес.

Соль в том, что в lib/Mail/Internal/ ядра сейчас живут обе версии файлов — старые lowercase (eventmessage.php, eventtype.php, …) и новые PascalCase (EventMessageTable.php, EventTypeTable.php, …). На Linux это два разных набора путей и всё легально. На маке и Windows это мина: любой class_exists по имени, которое случайно совпадёт со старым файлом, взводит её. Апдейтер security 26.200.0 — первый, кто на неё наступил.

Чем это грозит

  • Обновление не устанавливается. Версия security остаётся старой, тег/файлы не обновляются. Повторный запуск падает точно так же — ошибка детерминированная.
  • БД остаётся в полусостоянии. Фатал прилетает посреди апдейтер-скрипта: на нашей установке в b_event_type уже созданы типы USER_OTP_AUTH_CODE и USER_OTP_EMAIL_CONFIRM (у английских записей даже NAME не успел заполниться), а в b_event_message — ноль шаблонов: скрипт упал ровно на первом CEventMessage->Add(). После починки ФС обновление поставится поверх, но осиротевшие типы стоит проверить.

Что делать

  • Прод на Linux — ничего, ставьте как обычно.
  • Локальная разработка на маке/Windows — переносите код сайта на регистрозависимый том и обновляйтесь там. На маке это case-sensitive APFS-образ (Disk Utility → APFS (Case-sensitive)) или, для Docker, named volume вместо bind-mount проектной папки. Проверить свою ФС можно за секунду: touch a A && ls — если файл один, вы в зоне риска.
  • Руками удалять «лишние» lowercase-файлы ядра не советуем: это правка ядра со всеми вытекающими при следующем обновлении.

Мелочи и находки

Легаси-файл и его PascalCase-близнец — не совсем копии: в новом EventMessageTable.php код тот же, но венгерские префиксы вычищены ($arReplaceTagsOne$replaceTagsOne, $bOpenPhpTag$openPhpTag). То есть ядро мигрирует файлы на PascalCase с косметикой, а старые файлы оставляет лежать рядом — совместимость для тех, кто require'ит их напрямую. На регистрозависимой ФС это честная стратегия; на регистронезависимой — как видим, не очень.

Разбор основан на воспроизведённом фатале при установке через update:modules на эталонной установке (main 26.700.0, macOS + Docker bind-mount) — у security-обновления, которое не установилось, диффа по понятным причинам нет.

Читайте дальше

mail 26.900.0 Заметное Свежее

Mail 26.900.0: общие подписи ломают старый API, а тяжёлые вложения переезжают на Диск

Модуль mail получил один из самых жирных релизов за последнее время: 523 файла, +39 182/−3 131 строк. Внутри — три большие фичи (общие подписи, автоперенос тяжёлых вложений на Диск, избранное с AI-классификацией писем), переработанный IMAP-синк истории и три новые таблицы в БД. Если вы кастомизирова...

4 мин
main 26.700.0 Заметное Свежее

Main 26.700.0: в ядре появились фича-флаги

Битрикс выкатил main 26.700.0 — и это тот редкий случай, когда в ядре появляется целая новая подсистема: фича-флаги `Bitrix\Main\Config\Feature` с двумя таблицами в БД. Плюс несколько тихих поведенческих изменений, которые стоит проверить, если у вас не-UTF-8 сайт, кастомные фильтры пользователей ил...

4 мин
location 26.300.0 Заметное Свежее

Location 26.300.0: батчевый обратный геокодинг — до 20 координат за один вызов

Релиз от 17 июня 2026 с одной, но цельной темой: в модуль `location` завезли батчевый обратный геокодинг — метод `findByCoordsList`, который превращает список координат в список локаций за один вызов сервиса. Если вы строите интеграции с картами или доставкой и до сих пор дёргали `findByCoords` в ци...

2 мин
landing 26.1000.0 Заметное Свежее

Landing 26.1000.0: удалён Block::isContains, ссылки теперь режутся по белому списку схем

Обновление `landing` 26.1000.0 (сборка от 24.08.2026) — это на 90% security-хардening плюс новая песочница для превью страниц «на устройствах». Дифф огромный — 1300 файлов, +73 тысячи строк — но почти всё это пересобранные JS-бандлы, контентные блоки и webp вместо png. Содержательного PHP — примерно...

4 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…
Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти