main · Главный модуль 26.750.0 Заметное

Main 26.750.0: точка в имени плейсхолдера больше не ломает почтовые шаблоны

5 мин чтения

Main 26.750.0 меняет три файла ядра, +16/−5 строк, и заметная правка среди них одна (вторая, в лицензионном ActivationSystem, служебная). Но сидит она в месте, где из почтового шаблона генерируется PHP-код, так что посмотреть на неё стоит всем, у кого в шаблонах есть плейсхолдеры с точкой в имени, вроде #ORDER.ID#.

Проверьте шаблоны с точкой в именах

Исправлена ветка Bitrix\Main\Mail\Internal\EventMessageTable::replaceTemplateToPhp(), которая превращает текст шаблона в PHP. Метод находит плейсхолдеры по маске /#([0-9a-zA-Z_.]+?)#/ (точка в имени разрешена), а потом подставляет найденные имена в две регулярки: в общую альтернативу, по которой ищет теги, и в паттерн для замены повторов. Имена попадали туда как есть, без экранирования. А точка в регулярке совпадает с одним любым однобайтовым символом, кроме перевода строки (модификаторов s и u у этих паттернов нет).

Тег, который встречается в шаблоне больше одного раза, метод заменяет по одному вхождению через preg_replace(…, 1). Неэкранированный паттерн /#ORDER.ID#/ цеплял и #ORDER_ID#, так что если тот стоял в тексте раньше, первая замена доставалась ему:

        <?php declare(strict_types=1);

use Bitrix\Main\Mail\Internal\EventMessageTable;

echo EventMessageTable::replaceTemplateToPhp(
    'Заказ #ORDER_ID#, код #ORDER.ID#, ещё раз код #ORDER.ID#'
);

    
        до 26.750.0: Заказ <?=$arParams["ORDER.ID"];?>, код <?=$arParams["ORDER.ID"];?>, ещё раз код #ORDER.ID#
с 26.750.0:  Заказ <?=$arParams["ORDER_ID"];?>, код <?=$arParams["ORDER.ID"];?>, ещё раз код <?=$arParams["ORDER.ID"];?>

    

До обновления на место #ORDER_ID# в письмо шло значение ORDER.ID, а последний #ORDER.ID# доходил до получателя сырым.

В общей альтернативе неэкранированная точка мешала, только если на её месте в тексте стоял символ вне маски. Рядом с #ORDER.ID# фрагмент #ORDER"ID# превращался в $arParams["ORDER"ID"], и eval сгенерированного кода падал с ParseError. Теги, которые сами проходят маску, вроде #ORDERXID#, здесь и раньше разбирались верно, потому что имя метод берёт из найденного текста.

Что поменяли в методе:

  • имена плейсхолдеров при сборке альтернативы проходят через preg_quote($k, '/');
  • список имён чистится array_unique(), и повторяющийся плейсхолдер больше не добавляет одинаковые ветки (в комментарии к коду это объяснено экономией лимита компиляции PCRE);
  • появилась страховка: найденный тег, который не проходит проверку /^[0-9a-zA-Z_.]+\z/, пропускается и в PHP-литерал не попадает. В коде это названо «defence in depth», и пока работает экранирование, до этой ветки дело не дойдёт;
  • во второй части метода, где заменяются повторяющиеся теги, паттерн для preg_replace теперь тоже строится через preg_quote.

Для шаблонов без точек в именах результат конвертации прежний, кроме шаблонов, где один плейсхолдер повторяется тысячи раз: там старая регулярка не компилировалась («regular expression is too large») и не срабатывала ни одна подстановка, а благодаря array_unique() теперь срабатывают. В шаблонах с именами вида #A.B# повторяющийся тег, перед которым стоит похожий тег, теперь заменяется во всех местах, #A_B# перед ним больше не получает чужое значение, а фрагмент вроде #A"B# остаётся текстом. Но всё это касается только заново собранного MESSAGE_PHP, а старый лежит в БД, пока шаблон не пересохранят.

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

  • Правка чинит регулярки, собранные из неэкранированных имён плейсхолдеров. Имена берутся из текста самого шаблона, а в шаблоне и так можно писать <? ?> (метод отдельно отслеживает эти теги), и MESSAGE_PHP исполняется через eval (EventMessageThemeCompiler.php:383, по коду в эталоне). Объяснения есть только в комментариях к коду. Новой возможности выполнить код правка не закрывает: автор шаблона и раньше мог вставить <? ?>.
  • Комментарии к правкам подробные и на английском, при том что остальной EventMessageTable.php почти не комментирован.
  • Четыре «изменённые сигнатуры» в Bitrix\Main\UpdateSystem\ActivationSystem (activateByHash, applyLicenseInfo, reincarnate, sendInfoToPartner) оказались ложной тревогой. Файл обфусцирован, его пересобрали, и у параметров новые случайные имена; типы и число аргументов те же. Логика при этом всё же поменялась: если раскодировать строки обфускатора на обоих снапшотах, в applyLicenseInfo() видна новая ветка. Когда в ответе сервера лицензий есть BI_CONSTRUCTOR_DATE, значение пишется в опцию main / ~bi_constructor_expired_at, рядом с давней парой R7_SERVER_DATE → ~UT_custom_servers_expired_at.
  • В version.php заодно расставили пробелы после запятых в define. Версия собрана 27 августа (SM_VERSION_DATE).
  • Deprecated, новых API и изменений в БД нет.

Что делать

Публичный API не тронут. Если в почтовых шаблонах есть плейсхолдеры с точкой в имени, пересохраните эти шаблоны в админке или через EventMessageTable::update($id, ['MESSAGE' => $message]). По коду в эталоне MESSAGE_PHP хранится в БД и пересобирается только при сохранении MESSAGE (onBeforeUpdate/onBeforeAdd, EventMessageTable.php:252,270) или когда поле пустое (EventMessageCompiler.php:131–139). Без пересохранения письма так и собираются из старого MESSAGE_PHP, поэтому тестовое письмо отправляйте уже после него и сравнивайте с тем, что уходило раньше.

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

main 26.700.0 Заметное

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

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

4 мин
main 26.650.0 Заметное

main 26.650.0: сброс счётчиков ленты пачкой и превью своих ссылок без похода наружу

Два изменения в ядре, оба — про лишнюю работу, которую система делала на ровном месте. Счётчики живой ленты научились сбрасываться одним вызовом вместо цикла, а превью ссылок перестало ходить HTTP-запросом на собственный портал. Ломающих удалений нет: все правки сигнатур — добавление аргументов с де...

3 мин
voximplant 26.700.0 Ломающее Свежее

Voximplant 26.700.0: оценку качества связи убрали, у notifyAdmins() появился тип

Модуль телефонии voximplant 26.700.0 вышел в коробочный Битрикс24 11 сентября 2026 года, по данным официального канала «Битрикс24 changelog». Из карточки звонка убрали оценку качества связи вместе с её JS-событиями, у `Im::notifyAdmins()` появился тип параметра, а публичные константы `SipStatusInfor...

3 мин
ui 26.687.0 Рутинное Свежее

UI 26.687.0: триал VibePlus в облаке и дизайн чипа TintedBitrixGpt

`Bitrix\UI\Controller\InfoHelper` при активации демо сначала спрашивает у модуля bitrix24, включён ли старт VibePlus, и если да, запускает триал VibePlus вместо обычного демо тарифа. Ветка срабатывает только при подключённом модуле bitrix24 и определённой константе `BX24_HOST_NAME`. В `ui.system.chi...

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

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

на связи

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

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

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

Войти