Битрикс: таргетинг баннеров

В битриксе есть встроенная сущность баннеры. Но этой сущности почему-то не повезло и тут штатно не предусмотрено вариантов пользовательских полей или подобной возможности расширить функционал. Но даже из того, что есть не всегда удобно пользоваться имеющимся функционалом из кода. Для отбора баннеров есть метод CAdvBanner::GetList(). Но к сожалению, в нём нет доступа к таким полезным параметрам, как "Разделы и страницы, только на которых должны показываться баннеры" и "Разделы и страницы, на которых не могут показываться баннеры".
Более того, для этих полезных параметров даже нет толкового описания: в каком формате тут надо вписывать значения. Так вот, указывать тут нужно относительные ссылки. Они будут искаться по маске. Т.е. если указать "/info/contacts/", то в отбор попадёт и страница "/info/contacts/shop/".
Скорее всего, разработчики битрикса подразумевали, что баннерами будут пользоваться только через компонент "bitrix:advertising.banner". Внутри этого компонента производится проверка настроек таргетинга. Но там нет возможности получить расширенный функционал работы с баннерами, который можно реализовать самостоятельно. Например, если на сайте есть региональное деление; нельзя штатными средствами заставить показывать разные баннеры в разных регионах (в Москве показываем один баннер, в Санкт-Петербурге - другой). Если таких регионов сотни - это уже проблема.

Используем таргетинг в своём коде

Отладчик PHP творит чудеса. Когда надо на батискафе погрузиться в код битрикса и выяснить внутреннее устройство - xdebug - самое то. Таким методом был найден недокументированный метод CAdvBanner::GetPageWeights_RS(). Этот метод как раз и отбирает все баннеры, которые подпадают под правила таргетинга. Но этот метод не проверяет доступность баннера по времени или активности. Внутри вся работа делается чудовищным километровым запросом. Да, прямым запросом к базе. Я не стал изобретать свой велосипед (хотя наверняка можно сделать гораздо более оптимально по быстродействию - с заточкой под собственные нужды) и применил этот готовый метод. На выходе он выдаёт идентификаторы всех разрешённых баннеров. А дальше уже можно использовать GetList для более строго отбора и подмешивать в фильтр эти идентификаторы баннеров, попадающих под таргетинг.
Если на сайте десятки тысяч баннеров с таргетингов, то, думаю. производительность будет весьма печальная. SQL-запрос с кучей JOIN'ов и LIKE'ов будет очень неторопливым. Придётся-таки изобретать свой велосипед. Но если баннеров в битриксе не много, то метод рабочий и имеет право на жизнь.
Получается такая заготовка, чтобы получить все активные баннеры (в том числе и попадающие под таргетинг):

// Получим все активные баннеры магазинов
$isModuleAdvertising = true;
try {
    Bitrix\Main\Loader::includeModule('advertising');
} catch (\Exception $exception) {
    $isModuleAdvertising = false;
}
if ($isModuleAdvertising) {
    // Получим баннеры, подходящие под настроенные
    // ограничения по страницам (таргетинг)
    $rs = CAdvBanner::GetPageWeights_RS();
    $arBitrixAllowedBannerIds = [];
    while ($arBanner = $rs->Fetch()) {
        $arBitrixAllowedBannerIds[] = $arBanner['BANNER_ID'];
    }
    if ($arBitrixAllowedBannerIds) {
        $arBannersFilter = [
            'TYPE_SID'             => 'my-banner-type',
            'TYPE_SID_EXACT_MATCH' => 'Y',
            'STATUS_SID'           => 'PUBLISHED',
            'ACTIVE'               => 'Y',
            'SITE'                 => SITE_ID,
            'LAMP'                 => 'green',
            // Включим в запрос баннеры, подходящие для данной страницы
            'ID_EXACT_MATCH'       => 'Y',
            'ID'                   => implode('|', $arBitrixAllowedBannerIds)
        ];
        }

        $by = 's_weight';
        $order = 'asc';
        $bannerDbRes = CAdvBanner::GetList(
            $by,
            $order,
            $arBannersFilter,
            $is_filtered,
            'N'
        );

        while ($bannerData = $bannerDbRes->Fetch()) {
            // Что-то делаем с данными баннера
        }
    }
}

Комментарии

Популярные сообщения из этого блога

Пропорциональное распределение суммы

Битрикс: своя геолокация

Bitrix24 API - разбор демо приложения третьего типа