documentgenerator 26.200.0 Ломающее

Documentgenerator 26.200.0: плейсхолдеры в атрибутах DOCX больше не вычищаются, у DocxXml новые сигнатуры

3 мин чтения Устаревших API: 2

Ломающее обновление

Удалены или изменены публичные API — прикладной код может перестать работать.

Генератор документов 26.200.0 заполняет DOCX обходом DOM вместо регулярки по всему XML, и плейсхолдеры в атрибутах разметки, кроме descr и name у картинок, теперь доходят до готового документа как текст. У Bitrix\DocumentGenerator\Body\DocxXml удалён protected-метод и сменились сигнатуры ещё двух, а установщик модуля переехал с install.sql на миграции main. В коробочный Битрикс24 версия вышла 2 сентября 2026 года, так указано в официальном канале «Битрикс24 changelog».

Проверьте готовые документы по своим DOCX-шаблонам

До 26.200.0 DocxXml::replacePlaceholders() прогонял preg_replace_callback по всему XML документа, а новая версия ищет плейсхолдеры только в текстовых узлах //w:t и в атрибутах descr и name у //w:drawing//wp:docPr. Плейсхолдер в descr или name заменяется пустой строкой.

Раньше clearPlaceholdersInAttributes() вырезал из XML плейсхолдеры, которых нет ни в w:t, ни среди картинок. В 26.200.0 тело метода сведено к return;, а сам он помечен @deprecated Attribute cleanup is not part of the supported DOCX placeholder surface. Вызов из normalizeContent() остался, замены у метода нет. Такие плейсхолдеры остаются в готовом документе как текст и уезжают пользователю вместе с файлом.

DocxXml::getPlaceholders() отдаёт только плейсхолдеры картинок и текстовых узлов, без остальных совпадений регулярки по XML.

Сгенерируйте по документу из каждого своего DOCX-шаблона и посмотрите, что осталось в фигурных скобках, например так: unzip -p contract.docx 'word/*.xml' | grep -o '{[^{}]*}'. Первыми проверяйте шаблоны, где плейсхолдеры стоят вне обычного текста.

Обновите наследников DocxXml

Если в /local/ есть класс, унаследованный от Bitrix\DocumentGenerator\Body\DocxXml, проверьте в нём три метода.

replaceRealByTemporaryPlaceholers(array $placeholdersMatches, DocxXml $document) удалён, опечатку в имени учитывайте при поиске. Вызов через parent:: упадёт с fatal error, а ваше переопределение станет мёртвым кодом, потому что модуль этот метод больше не вызывает. Вместо него есть replaceWhitelistedPlaceholdersByTemporaryPlaceholders(DocxXml $document, bool $includeImageAttributes = true). Готовые совпадения регулярки он не принимает и ищет плейсхолдеры в DOM сам.

processContentWithTemporaryPlaceholders() потерял четвёртый параметр bool $isPurgeEmptyValue = true. Лишний позиционный аргумент PHP отбросит без ошибки, так что сломается это тихо. Режим остался один. Фигурные скобки, которые не являются временными плейсхолдерами, остаются как есть, а временный плейсхолдер без ключа в $values заменяется пустой строкой.

getPlaceholders(): array теперь объявлен в самом DocxXml. У родителя Xml::getPlaceholders() типа возврата нет, поэтому переопределение без : array в наследнике DocxXml до 26.200.0 работало, а на новой версии даёт fatal error о несовместимой сигнатуре. Хватит дописать тип:

        <?php declare(strict_types=1);

namespace Vendor\Docs\Body;

use Bitrix\DocumentGenerator\Body\DocxXml;

final class ContractDocxXml extends DocxXml
{
    public function getPlaceholders(): array
    {
        $placeholders = parent::getPlaceholders();
        // ваша доработка списка

        return $placeholders;
    }
}

    

Для наследников в DocxXml появились protected-методы новой схемы: getTextPlaceholderNames(), getPlaceholderNamesFromXml(string $content), replaceNodeValuePlaceholdersByTemporaryPlaceholders() и getTemporaryPlaceholder(). К ним добавились константы TEMPORARY_PLACEHOLDER_CONTEXT_TEXT и TEMPORARY_PLACEHOLDER_CONTEXT_DOCPR_ATTRIBUTE.

Проверьте поля, исправленные вручную

В Bitrix\DocumentGenerator\Document сравнение ручного значения с вычисленным вынесли в private isOverrideKept(), его используют getValue() и getExternalValues(true). Скаляры и Value-объекты сравниваются как строки с normalizeValue($computedRaw, true). В docblock объяснено, что так Money, Date и похожие значения перестанут всегда считаться изменёнными.

Ручную правку поля, у которого вычисленное значение является массивом, getValue() раньше не применял никогда, потому что условие требовало !is_array($this->values[$name]). Теперь применяет, если она отличается от вычисленного значения (сравнение через !=). Поле-массив с ручной правкой после обновления начнёт отдавать эту правку. Ещё setFields() стал пропускать элементы, которые не являются массивами.

Уберите из своих скриптов install.sql модуля

Файлы install/db/mysql/install.sql, uninstall.sql и их pgsql-копии удалены. documentgenerator::InstallDB() и UnInstallDB() вызывают $this->installMigrations() и $this->uninstallMigrations($dropTables), это protected-методы CModule из main. В main 26.250.100 их ещё нет, в main 26.650.0 уже есть. Скрипты, которые читали install.sql модуля напрямую, перестанут работать.

Схема не менялась. Те же 15 таблиц, от b_documentgenerator_template до b_documentgenerator_actualize_queue, описаны в install/migrations/tables.php через CreateTableBuilder с прежними полями и индексами. В migration_config.json задан defaultTableName: b_documentgenerator_template и соответствие install/components → components, install/js → js.

Обработчики событий и агенты переехали из install/index.php в install/migrations/events.php и agents.php. Обработчиков три: main:onNumberGeneratorsClassesCollect через registerCompatible, rest:OnRestServiceBuildDescription и pull:OnGetDependentModule с sort 800. При удалении модуля в режиме ModuleUninstall вызов register превращается в unregister.

Агентов тоже три, все непериодические: Driver::installDefaultRoles() с интервалом 150, Service\ActualizeQueue::process(5) и Driver::installDefaultTemplatesForCurrentRegion() с интервалом 300. Первый запуск раньше задавался явно (+150 с, без задержки и +300 с). Теперь задержку выбирает Migration\Agent::doAdd() из main: 60 с при установке модуля, 15 минут при установке дистрибутива, 10 минут в облаке.

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

  • Временный плейсхолдер раньше выглядел как {SystemHtmlValues<N>}, где N бралось из random_int(200, 10000). Новый выглядит как {SystemDocxValue<hex>} с bin2hex(random_bytes(16)) и проверкой, что такого плейсхолдера ещё нет ни в карте, ни в тексте документа.
  • Старый код склеивал XPath-запрос с текстом плейсхолдера ($matches[0]). Новый делает один запрос //w:t[text()[contains(.,"{")]] и разбирает значения узлов регуляркой.
  • В размножаемых блоках после каждого processMultiplyingBlock() добавлен saveContent(), а имена полей внутри блока берутся из DOM через getPlaceholderNamesFromXml() с кешем по контенту. Для пустой картинки (empty или ' ') узлы w:drawing удаляются из блока, раньше на место плейсхолдера картинки подставлялся маркер {__SystemEmptyImage}.
  • Docx::setNodes() существовал и раньше, а сохранять изменения начал только сейчас. Он нормализует внутренний документ, кладёт его контент обратно в zip и обновляет $this->content. Его вызывает анонимайзер модуля disk. Метод save() в disk/lib/integration/anonymizer/docxprovider.php сначала зовёт setNodes(), а потом process(). Внутри цикла по внутренним документам после addContentToZip() добавлен ещё $this->zip->close(), хотя addContentToZip() сама делает close() и open(). Повторного open() до следующей итерации нет.
  • Имена агентов в install/migrations/agents.php начинаются с \. Migration\Agent::doAdd() в режиме isDevMode() отвергает такие имена исключением 201 «Agent name should not start with backslash», но CModule::installMigrations() dev-режим не включает. Если переводите свой модуль на миграции, пишите имена агентов без ведущего слеша.
  • Controller\Template::add() пропускает список доступа через private filterAccessCodes(), который отбрасывает нестроковые и пустые коды и убирает дубли. Если после фильтра ничего не осталось, старые права шаблона не удаляются. Раньше непустой массив мусора приводил к deleteByTemplateIds() и попыткам add().
  • Компонент documentgenerator.templates передаёт фильтр региона в URL слайдера как ['REGION' => [$region['CODE']]] вместо ключа 'REGION[]'.

Устаревшие и удалённые API в этой версии

Символ Статус Чем заменять
Bitrix\DocumentGenerator\Body\DocxXml::clearPlaceholdersInAttributes() Deprecated —
Bitrix\DocumentGenerator\Body\DocxXml::replaceRealByTemporaryPlaceholers() Удалено Bitrix\DocumentGenerator\Body\DocxXml::replaceWhitelistedPlaceholdersByTemporaryPlaceholders()

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

documentgenerator 26.200.100 Ломающее Свежее

Documentgenerator 26.200.100: рисунки без файла больше не остаются в размноженных строках DOCX

Documentgenerator 26.200.100 перестал оставлять в разметке DOCX рисунки из размноженных строк, у которых файл картинки не существует или не читается. Если вы наследуете `Docx` и переопределяете protected `replaceImages()`, смените `: void` на `: array` и возвращайте ID связей на удаление, иначе полу...

1 мин
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 мин
ui 26.675.0 Ломающее Свежее

UI 26.675.0: ui.actionpanel переехал в бандл, а rich_text по-новому обходится с квадратными скобками

Модуль ui 26.675.0 собран 26 августа 2026. Из PHP поменялись `Converter` и `Whitelist` в `Bitrix\UI\Format\BBCode`, и пользовательские поля типа `rich_text` теперь иначе сохраняют и индексируют текст с квадратными скобками. На фронтенде старую панель групповых действий `ui.actionpanel` перевели на б...

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

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

на связи

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

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

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

Войти