landing · Сайты 24 26.1000.0 Заметное

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

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

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

Проверьте вызовы Block::isContains — метода больше нет

Самое жёсткое: публичный Bitrix\Landing\Block::isContains(int $entityId, string $needed, bool $isLanding = false): bool удалён. Не помечен deprecated — именно удалён. Если ваш код его вызывает, после обновления получите фатальную ошибку.

Взамен появились два узкоспециализированных метода:

  • Block::findVisibleLandingIdByFileInBlock(int $blockId, int $fileId): ?int
  • Block::findVisibleLandingIdByFileInLanding(int $landingId, int $fileId): ?int

Причина замены — Mantis #252316: старый метод искал подстроку, и числовой префикс id файла ложно совпадал (искали файл 25 — находили 250). Новая реализация ищет ссылку на файл Диска по точному паттерну через Connector\Disk::getExactFileHrefPattern. Важно: прямой замены для произвольного строкового $needed нет — если вы искали в блоке не файл, а что-то своё, придётся писать поиск самостоятельно.

Ссылки со странными схемами молча превратятся в пустую строку

Второе, что может «выстрелить» тихо и не сразу. При сохранении контента:

  • Node\Link теперь прогоняет href через новый Sanitizer::sanitizeHref() — allow-list схем, default-deny;
  • Node\Text, Node\Img, Node\Icon пропускают data-pseudo-url через sanitizePseudoUrl() вместо сырого json_encode;
  • Block::setAttributes санирует все атрибуты с манифест-типом url (через новый сборщик Block::collectUrlAttrs).

Белый список: http, https, mailto, tel, sms, skype плюс псевдосхемы ландингов page:, block:, form:, product:, file:, user:, help:. Всё остальное — включая намеренно заблокированные javascript:, data:, vbscript: — при сохранении молча становится пустой строкой. Никаких ошибок, никаких предупреждений.

Если ваши кастомные блоки писали в url-атрибуты нестандартные значения (свои схемы, диплинки приложений) — после обновления при первом же пересохранении блока они обнулятся. Проверяйте.

Остальные ломающие изменения — по мелочи, но проверьте наследников

  • Hook\Page\Fonts::resolveFontName() — сигнатура изменилась: resolveFontName(string $fontCode, ?string $claimedName = null). Метод protected, параметр опционален — заденет только тех, кто переопределял его в наследниках. По сути защита от подмены имени Google-шрифта: заявленное имя из сниппета принимается только как регистровый вариант доверенного slug (isCasingVariantOfSlug), потому что имена Google Fonts регистрозависимы.
  • Vibe\TemplateRegions — из enum выпилены 17 региональных кейсов (AutomationDe, AutomationFr, AutomationJa и т.д.), вместо них один AutomationCn = 'alaio.vibe_automation_cn'. Сигнатура resolve() расширена: resolve(Templates $code, ?string $portalZone = null, ?string $language = null) — региональность теперь параметр, а не отдельный кейс. Ссылки на удалённые кейсы enum сломаются на этапе компиляции.
  • Subtype\Form::getFormsViaConnector() — возвращаемый тип сменился с array на ?array (null = коннектор не дал валидного ответа). Ломает наследников этого protected-метода.
  • Connector\Crm — маркер #requisiteCompanyTitle теперь экранируется через htmlspecialcharsbx. Контекст жёсткий: контент блока исполняется через eval() в Block::view() (Mantis #253063). Если кто-то клал HTML в название компании и ждал, что он отрендерится — больше не отрендерится.
  • Manager::availableOnlyForZone() — починили мемоизацию: раньше первый вердикт замораживался для всех последующих зон, теперь кэш пер-зона. Поведение изменится, но в корректную сторону.

Deprecated

Новых @deprecated в PHP API нет. Единственное вхождение — шум пересобранного JS-бандла с давно существовавшей пометкой.

Новое: Sanitizer и sandboxed device preview

Sanitizer — три метода для санации ссылок

Класс Bitrix\Landing\Sanitizer получил публичный API, который можно использовать и в своём коде:

        <?php declare(strict_types=1);

use Bitrix\Landing\Sanitizer;

$sanitizer = new Sanitizer();

// Обычный href: allow-list схем + текстовый аудитор
$href = $sanitizer->sanitizeHref($request->get('link') ?? '');
// 'javascript:alert(1)' -> ''
// 'page:#landing123'    -> останется, псевдосхемы ландингов в белом списке

// data-pseudo-url: json с ключами text/href/query/target/enabled
$pseudoUrl = $sanitizer->sanitizePseudoUrl($rawPseudoUrl);
// декодирует \uXXXX-экранирование — спрятать схему юникодом не выйдет

// Жёсткий вариант (единственный static): только http/https и относительные ссылки
$strict = Sanitizer::sanitizeHrefScheme($userInput);
// режет protocol-relative (//evil.host) и управляющие символы:
// "java\tscript:" тоже не пройдёт

    

Обратите внимание на sanitizePseudoUrl: она специально декодирует \uXXXX-экранирование перед проверкой, чтобы скрытые схемы стали видны. И на sanitizeHrefScheme — это static-метод для случаев, когда псевдосхемы ландингов не нужны вовсе.

Device preview в песочнице

Центральная фича релиза. Превью страницы «на устройствах» в редакторе теперь живёт в изолированном iframe (sandboxed, opaque origin), и под это появился API:

        <?php declare(strict_types=1);

use Bitrix\Landing\Landing;

Landing::setDevicePreviewMode();

if (Landing::getDevicePreviewMode())
{
    // страница рендерится в песочнице редактора,
    // это НЕ то же самое, что preview непубликованной страницы
}

    

У sandboxed-iframe opaque origin, поэтому вокруг него доработали кучу мелочей:

  • install/components/bitrix/landing.pub/class.php получил ~160 строк: определение same-origin превью (isSandboxedDevicePreview) и инъекция storage-шима в самое начало <head> — в песочнице cookie/localStorage бросают DOMException и валят целые скрипт-блоки;
  • Assets\PreProcessing\Icon::buildInlineVendorStyles() и buildInlineFontFace() — иконочные шрифты инлайнятся, потому что сетевые шрифты в opaque origin блокируются;
  • Hook\Page\Cookies::enabled() возвращает false в device-preview-режиме — баннер согласия в такой песочнице работать не может.

Снапшот форм в Subtype\Form

Subtype\Form оброс пакетом методов вокруг «снапшота форм»: isConnector(), getConnectorFormsResponse(), isFormsSnapshotAvailable(), isActiveFormId(int), getFormActivityState(int): ?bool, resolveImportFormId(): ?int, resetFormsRuntimeState(). Кэш форм переехал со static $forms на поля класса с флагом доступности.

Смежно доработан перенос сайтов: Transfer\Script\Action\PrepareBlocksData получил resolveTargetFormId(), isTargetFormSnapshotAvailable(), getFormActivityState() и ~20 приватных методов нормализации маркеров CRM-форм — при импорте сайта форма перепривязывается на целевом портале. Enum Transfer\Requisite\Dictionary\RatioPart пополнился кейсами CrmFormTargetId и CrmFormActivity.

Шрифты

Hook\Page\Fonts::extractClaimedFontName(string $content): ?string — извлекает заявленный font-family из сниппета шрифта. Работает в паре с обновлённым resolveFontName (см. выше).

БД

Изменений схемы нет: db.diff пуст, ни новых таблиц, ни полей.

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

  • В комментариях кода упоминаются охранные тесты — например, CrmRequisiteCompanyTitleEscapeTest. Битрикс пишет тесты на свои security-фиксы, приятно видеть.
  • 242 новых файла — почти всё контент: 150 файлов в landing.blocks.mp_widget.* (west_auto_overview_block, vibe_auto, west_auto_header/footer_banner) и 48 в install/blocks/bitrix/mp_widget.west_auto_* — новые виджеты «west auto» и «vibe auto» для главной страницы и Vibe (overview- и link-блоки: CRM, задачи и проекты, воркфлоу, ИИ, смарт-процессы).
  • Доступность: новое JS-расширение install/js/landing/ui/a11y/ и модули decorate-tree.js / get-tree-focusable.js — клавиатурная навигация по дереву меню.
  • Массовая замена png на webp в landing.site_master, landing.demo, landing.mainpage.pub; 39 удалённых файлов — в основном старые png/svg.

Итого

severity: notable. Схему БД не тронули, но публичный API ломали без сантиментов: Block::isContains удалён без deprecated, у Fonts::resolveFontName и Vibe\TemplateRegions::resolve изменились сигнатуры, а санация URL-схем молча обнуляет нестандартные ссылки при сохранении. Перед обновлением сделайте grep по isContains, кейсам Automation* из Vibe\TemplateRegions и своим кастомным блокам с url-атрибутами.

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

Символ Статус Чем заменять
Bitrix\Landing\Block::isContains() Удалено Bitrix\Landing\Block::findVisibleLandingIdByFileInBlock() / Bitrix\Landing\Block::findVisibleLandingIdByFileInLanding()

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

landing 26.700.0 Заметное Свежее

landing 26.700.0: Copilot-чат для сайтов снят, генерация переехала на Tailwind

Модуль лендингов развернул подход к генерации сайтов: отдельный чат-бот Copilot удалён вместе с публичными экшенами, а вместо него — сборка страницы Tailwind-блоками и набор инструментов для AI-ассистента. Релиз ломающий: удалены и AJAX-экшены, и целые классы, и часть шагов генерации переехала в дру...

4 мин
landing 26.800.0 Заметное Свежее

landing 26.800.0: ассистент умеет публиковать сайт, установщик — на миграциях

Небольшой релиз с одним ломающим краем: у AI-ассистента появился инструмент публикации сайта, у инструментов — логирование вызовов, а установщик модуля переехал на `UpdateSystem\Migration`. Ломается ровно один метод — и ломается тихо.

3 мин
landing 26.900.0 Безопасность Свежее

landing 26.900.0: undo/redo закрыли от инъекции PHP, execute стал final

Главное в релизе — не новые фичи, а ужесточение истории правок. Действия undo/redo теперь проходят обязательную проверку на PHP-открывающий тег, а метод `execute()` сделан `final`, чтобы проверку нельзя было обойти переопределением. Плюс удалён контроллер `AiBlocks`, появившийся всего два релиза наз...

1 мин
security 26.200.0 Безопасность Свежее

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

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

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

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

на связи

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

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

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

Войти