Блог о программировании на PHP, Yii2, 1C-Bitrix

Bitrix: композит, интриги, расследования

Первый подход к использованию композита на сайте оказался достаточно интересным, и оказал двоякое впечатление о нем (версия главного модуля 14.5.1). Для начала немного общей теории.

Для того, чтобы включить режим композитного сайта необходимо активировать его в настройках продукта. Сразу же указываем все страницы в маске исключения, которые жестко привязаны к разным пользователям и будут полностью динамическими для них. Примером для интернет-магазина будут страницы: /personal/*, /order/*, /cart/*, /auth/* и т.д., маска * означает, что будут включены все нижележащие страницы тоже.

Далее, открываем вкладку группы, и указываем все группы пользователей на сайте в которые входят пользователи, для которых необходимо, чтобы включался композитный режим, и сразу же первая неудобная ситуация, необходимо указать именно все группы, для конкретного пользователя, т.е. если здесь будут указаны: Группа1, Группа2, а пользователь будет принадлежать Группе3, то композитный режим для него не будет работать. С одной стороны наверно хорошо, чтобы композитный режим не работал для администраторов, но зачем делать именно так? Для чего существует обратная логика включения, как на линуксе, если пользователь входит хоть в 1 указанную группу, то для него применяется все, что указано для нее, пока что не понятно.

В следствии из предыдущего абзаца композитный режим необходимо тестировать под анонимным пользователем, битрикс организовал привязку администратор к куки, поэтому для тестирования сбрасываем куки, ну или смело нажимаем ctrl+shift+N.

Поехали дальше, базовая настройка композита в коде. Для отладки в 14.5.1 существует только лог в файл (в 14.5.2 обещали добавить новую систему отладки, ждем…), иногда почему-то глючила, и не писала туда ничего. Для включения лога необходимо в файл /bitrix/php_interface/dbconn.php записать две строчки:

define( "BX_COMPOSITE_DEBUG", true );
define( "LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"]."/log.txt" );

Лог будет заполняться записями вида:

Host: ваш домен
Date: дата добавления
Module: composite
Путь до файла в котором произошла ошибка

Если компоненты на странице голосуют «против» композита ( демократия на сайте просто :) ).

Самое простое — это добавление статических компонентов, которые не должны учитывать изменения для разных пользователей, в их случае в начало компонента добавляется запись вида:

<?$this->setFrameMode( true );?>

И все, композит для данного компонента включен, поэтому для информационного сайта без пользователей перевод его на композитный режим займет около часа, зависит от количества пользователей, ну и от кода в компонентах ( некоторые люди пишут так, что этот код вообще сложно прочитать, а не то, чтобы перевести на композит ).

Существует ньюанс использования для комплексных компонентов, в их случае строку setFrameMode необходимо указывать только для их шаблонов ( section.php, news.php ), для внутренних компонентов не обязательно.

Сложности перевода начинаются с динамических областей. Самый просто пример добавления динамической зоны — это строка статуса авторизации пользователя, которая обычно объявляется в header.php в шаблоне сайта:

<?\Bitrix\Main\Page\Frame::getInstance()->startDynamicWithID("user-block");?>
<?if( !$GLOBALS["USER"]->IsAuthorized() ){?>
    <a href="/auth/">Авторизация</a>
<?}else{?>
    <a href="/personal/"><?=$GLOBALS["USER"]->GetFullName()?></a>
<?}?>
<?\Bitrix\Main\Page\Frame::getInstance()->finishDynamicWithID("user-block", "");?>

Для включения динамической зоны в шаблоне компонента нужно указать следующий код:

 <?$frame = $this->createFrame("dyn1", false)->begin("");?>

Динамическая область, например получение товаров в корзине для данного пользователя.

<?$frame->end();?>

Ну или можно не объявлять название динамической области и код будет иметь вид:

<?$frame = $this->createFrame()->begin("");?>

Так же, если необходимо включить весь компонент в динамическую область, то можно не указывать $frame->end();,

Ньюансы использования:

  1. Необходимо всегда указывать пустую строку в функции begin (ну или то, что должно стоять вместо динамической зоны, пока она грузится), если этого не будет сделано, то вся динамическая область будет заключена в html кеш страницы и при обновлении данных кеш будет сбрасываться, в саппорте сказали, что это не баг, да да да…
  2. Очень странное поведения при использование нескольких динамических зоны в 1 файле и объявлении их подряд, например:
    <?$frame = $this->createFrame()->begin("");?>
        Динамическая зона 1
    <?$frame->end();?>
    <?$frame = $this->createFrame()->begin("");?>
        Динамическая зона 2
    <?$frame->end();?>
    <?$frame = $this->createFrame()->begin("");?>
        Динамическая зона 3
    <?$frame->end();?>

    То в шаблоне html страницы будет код:

    Динамическая зона 1
    Динамическая зона 3

    Первая и вторая почему-то перекрываются, в саппорте опять же сказали, что скорее всего это вложенность динамических зон, и снова не баг, да да да…
    Временный фикс для этого случая — это объявление дополнительной пустой динамической зоны после первой.

В принципе все, если сайт простой, то композитный режим на нем настроить достаточно просто.

В 14.5.1 существует баг, который портит всю картину для композита в интернет магазине, это отсутствие привязки к ajax режиму, т.е. если зайти на страницу каталога, где обрезается header и footer в режиме аякс ( необходимо для работы динамического фильтра и обновления товаров ), то страница будет отдана полностью, поэтому тем, кто использует 14.5.1 и такие аякс обновления, добавляем /catalog/* в исключения, что приблизительно сводит весь смысл внедрения композита на 0.

В 14.5.2 ( выпуск в начале июля ) обещали пофиксить данный баг, ждем…

Так же замечен баг( техподдержкой отрицается это ), заключающийся в том, что если кастомизировать контентную область в событиях OnAfterEpilog или OnEndBufferContent, то заменяемая область не будет фигурировать в html кеше странице, а выскочит в json запросе динамических зон и весь композит зафейлится, придется пока отказаться от идеи автоматизированного добавления счетчиков на сайт, а какая была хорошая идея :)

Замечен также «баг» с обработкой url’ов без слеша в конце, например, если для каталога настройки разделов имеют вид: «/catalog/#SECTION_CODE_PATH#». Решается это путем установки «*» в маску исключения и убиранием галочки «Сохранять на диск только страницы без параметров», к сожалению, на данный, момент это единственное решение.