Способы кастомизации: обзор и алгоритм выбора

Урок 1 из 8

25 мин

Нормально

Порядок исполнения страницы

Чтобы эффективно вести разработку на базе «1С-Битрикс: Управление Сайтом», нужно хорошо понимать логику работы фреймворка. Система предоставляет множество инструментов и выбор правильного из всего предоставленного арсенала — уже половина решения любой задачи.

За каждый URL, который открывает в браузере пользователь, в системе отвечает PHP-скрипт. Для статических страниц адрес равен пути к файлу. Например, открывая адрес /company/about.php пользователь запускает скрипт about.php из директории company. Для ЧПУ схема чуть сложнее. Подробно мы рассматривали ее в одном из предыдущих уроков про комплексные компоненты, но HTTP-запрос в конечном итоге также запускает PHP-скрипт публичной страницы.

Что же происходит при запуске скрипта публичной страницы?

Подробное описание этого процесса с указанием доступных констант и вызовом событий вы найдете в документации, здесь мы рассмотрим процесс в общем.

Каждая публичная страница начинается с подключения /bitrix/header.php. Последующий процесс выглядит так:

  1. Подключается файл старого ядра dbconn.php, в котором задаются важнейшие константы
  2. Подключается конфигурационный файл .settings.php
  3. Подключение к базе данных
  4. Подключается init.php из php_interface
  5. Определяется по правилам нужный шаблон сайта
  6. Проверка прав текущего пользователя на текущий запрошенный ресурс
  7. Начинается буферизация вывода (см. семейство функций ob_* в PHP)
  8. Подключается header.php шаблона сайта
  9. Исполняется тело страницы
  10. Подключается footer.php шаблона сайта
  11. Заканчивается буферизация вывода, срабатывают все отложенные функции
  12. Выполняются созревшие агенты (если не включены агенты на cron)
  13. Происходит отправка E-mail из очереди
  14. Отключение от БД

Алгоритм выбора инструмента

Большинство задач при работе с фреймворком можно решить несколькими способами. Приведем условный универсальный алгоритм выбора подходящего инструмента.

  • Требуется изменение внешнего вида?
    • Изменение должно быть на всех страницах сайта?
      • Изменение общих файлов для всех шаблонов сайта
    • Изменение должно быть на части страниц сайта?
      • Изменение шаблона сайта
      • Изменение комплексного компонента
    • Изменение должно быть на конкретной странице?
      • Изменение страницы/раздела
      • Изменение компонентов
      • Изменение языковых фраз
  • Требуется изменение логики?
    • Требуется изменить отправку E-mail?
      • Изменение почтовых шаблонов и почтовых событий
    • Требуется изменить реакцию на действия пользователя?
      • Изменение обработчиков событий
      • Изменение компонентов
  • Требуется изменять данные в БД?
    • Разовое изменение?
      • Изменение дополнительных свойств (UF и ИБ)
    • Повторяющиеся изменения?
      • Изменение агентов или cron-скриптов
      • Изменение обработчиков событий
  • Требуется настроить обмен данными с другой системой?
    • Изменение стандартного обмена с 1С
    • Настройка сервера веб-сервисов (SOAP, REST)
    • Настройка клиента веб-сервисов

Также бывает полезно перед началом разработки поискать уже существующие решения в Маркетплейсе. Большинство распространенных задач уже кем-то решены и часто вы можете получить решение своей задачи даже не открывая IDE.

Рассмотрим каждое решение по отдельности.

Инструменты разработчика

Компоненты

Философия фреймворка — в разделении логики всего проекта на компоненты, небольшие функциональные блоки, которые можно повторно использовать. Если перед вами стоит задача изменения какого-либо из компонентов, решать ее нужно в следующем порядке.

  1. Найти вызов компонента. В большинстве случаев они вызываются в шаблоне сайта или на странице. Реже — внутри других компонентов или в служебных файлах (например, файлы ext-меню или точка входа для обмена с 1С)
  2. Попробовать решить задачу через параметры компонента. Правило хорошего тона — создавать настройки, влияющие на логику работы компонента, даже очень узкоспециализированного. Прежде чем браться за IDE нужно изучить стандартные возможности, которые предоставляет фреймворк, и для этого воспользуйтесь документацией. Через настройки решаются такие задачи как вывод или скрытие полей, сортировка записей, управление количеством выводимых записей
  3. Если изменением настроек задача не может быть решена, посмотрите на другие шаблоны этого компонента, доступные в системе.
  4. Если ни настройками, ни другими существующими шаблонами задача не решается, тогда уже нужна кастомизация. Различают кастомизацию шаблона компонента и кастомизацию самого компонента. Кастомизация шаблона предполагает использование файла result_modifier.php и component_epilog.php и изменение вывода в template.php. Корректным решением будет “добирание” данных из БД через API фреймворка в result_modifier (например, на сайте компании для каждой новости выбрать из БД связанных с этой новостью сотрудников)
  5. И только в крайнем случае, когда логика, требующая изменения, заложена в самом компоненте, прибегают к кастомизации компонента. Это предполагает копирование компонента “как есть” в свое пространство имен и внесение доработок в его файлы (главным образом в class.php)

Примеры result_modifier.php

// Пометить все внешние ссылки параметром _blank, чтобы вывести его в template.php
foreach ($arResult as $i => $item) {
    if (substr_count($arItem["LINK"], 'https://')) {
        $arResult[$i]["PARAMS"]["TARGET"] = "_blank";
    }
}
// Подготовить данные для инициализации JS-карты
$arResult['JS_DATA'] = array();

foreach ($arResult["ITEMS"] as $arItem) {
    if (!empty($arItem['DISPLAY_PROPERTIES']['LOCATION'])) {
        $yandex = explode(',', $arItem['DISPLAY_PROPERTIES']['LOCATION']['VALUE']);
        $yandex_X = floatval($yandex[0]);
        $yandex_Y = floatval($yandex[1]);

        $arResult['JS_DATA'][] = array(
            'ID' => $arItem['ID'],
            'NAME' => $arItem['NAME'],
            'COORDINATES' => array($yandex_X, $yandex_Y),
            'ADDRESS' => $arItem['DISPLAY_PROPERTIES']['ADDRESS']['DISPLAY_VALUE'],
            'ICON' => '/images/ico_yan.png',
            'ICON_HOV' => '/images/ico_yan_h.png',
        );
    }
}

Обработчики событий

Фреймворк сразу после установки предоставляет пользователям обширный набор возможностей: управление инфоблоками, создание страниц и разделов, управление пользователями, создание веб-форм, создание рассылок, управление правами и т.д.

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

Разработчик может добавлять свой PHP-код, который будет исполняться в момент добавления пользователя, перед редиректом, после удаления элемента инфоблока или при деактивации веб-формы.

Рассмотрим пример, который поможет понять разницу в подходах с кастомизацией компонентов и использованием обработчиков событий.

Допустим, требуется ограничить самостоятельную регистрацию пользователей, разрешить ее только с E-mail’ами в доменной зоне .ru.

Если задачу решить через доработку компонента регистрации, то пользователь не сможет самостоятельно пройти регистрацию в публичной части сайта с почтой за пределами зоны .ru

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

Ведь самостоятельная регистрация через компонент в публичной части — только один из вариантов создания пользователей. Их может добавить администратор в панели управления, может импортировать в виде CSV файла. А еще пользователи могут создаваться системой при оформлении заказа в интернет-магазине.

Примеры

// Отправить уведомления при регистрации пользователя
public static function onAfterUserRegister($arFields)
{
	if($arFields["USER_ID"]) {
		Utm::getInstance()->saveEntityWhenRegisterUser($arFields["USER_ID"]);
        Lidb24::addLidUserRegister($arFields);
        EventLog::addEvent(EventLog::USER_REGISTER, $arFields);
    }
}

// Сохранить цену товара до обновления
public static function onBeforePriceUpdate($id, $fields)
{
	$oldPrice = PriceTable::getList([
		"select" => [
			"PRICE",
		],
		"filter" => ["=ID" => $id],
	])->fetch()['PRICE'];
	static::$oldPrices[$id] = $oldPrice;

	return true;
}

// Оповестить об изменении цены товара
public static function onPriceUpdate($id, $fields)
{
	$notifications = new PriceNotification($id);
	if ($notifications->getReguestInfo() && static::$oldPrices[$id] != $fields['PRICE']) {
		$notifications->sendEmails();
	}

	return true;
}

Почтовая система и отправка СМС

Фреймворк умеет отправлять сообщения на E-mail и для этого в административном разделе и документации есть отдельный раздел Почтовой системы.

Если задача требует изменения внешнего вида и содержимого письма или создания нового уведомления, решение состоит из 3-х шагов:

  1. Найти или написать код, инициирующий отправку E-mail. Расположен он может быть где угодно: в компонентах, в обработчиках событий, в агентах и т.д.
  2. Найти или создать Почтовое событие. Это группирующая сущность, объединяющая конкретные Почтовые шаблоны. Так например при заполнении заявки на регистрацию может быть одно Почтовое событие NEW_USER_REQUEST, в рамках которого отправляются два разных письма — одно сотруднику компании, другое самому потенциальному пользователю сайта.
  3. Найти или создать Почтовый шаблон. Именно из шаблона берутся заголовки, отправитель, получатели, тело и вложения писем.

Аналогично почтовым событиям в платформе существуют и СМС-события

Агенты

Некоторые процессы сайта должны работать независимо от поведения пользователей. Например, обновление валют и цен на сайте должно происходить не по нажатию на кнопку админом, а автоматически каждую полночь. По расписанию должны работать рассылки и напоминания, разного рода обновления и синхронизации данных.

Плохим решением будет встраивание этих действий в обработчики событий или шапку сайта. Таким процессам место в планировщике задач, в механизме под названием Агенты.

Агенты позволяют запланировать вызов PHP-методов и функций и повторять его по требуемым правилам. Если на сервере с «1С-Битрикс: Управление Сайтом» поддерживается технология cron, то агенты могут быть перенесены на этот механизм, окончательно отвязавшись от публичной части сайта и наличия посетителей в ней. Перенос агентов на cron — рекомендуемый шаг для всех проектов.

Примеры

// Удалить товары с остатком = 0
public static function deleteOffersWithZeroLeftOver(): string
{
$offerClass = Offer::getInstance()->getElementClass();
$offerRows = $offerClass::query()
->setSelect(['ID'])
->where('AMOUNT.VALUE', 0)
->setLimit(100)
->exec();

while ($offer = $offerRows->fetch()) {
$offerClass::delete($offer['ID']);
}

return __METHOD__ . '();';
}

// Удалить старые цены
public static function clean($days = 7) {
$date = ConvertTimeStamp(time()- $days * 24 * 60 * 60, "FULL");
$prices = PriceTable::getList([
'filter' => [' $date],
'select' => ['ID'],
]);
while ($price = $prices-> fetch()) {
PriceTable::update($price['ID'], ['PRICE' => 0]);
}
return __METHOD__ . "($days);";
}

Поисковая система

Поисковая система в «1С-Битрикс: Управление Сайтом» отвечает за нахождение записей компонентами поиска. По-умолчанию фреймворк предоставляет пользователям возможность отыскать страницы, элементы и разделы инфоблоков по отрывкам названия, описания и свойств, допуская незначительные опечатки и неточности.

Но если решаемая задача связана с изменением порядка вывода найденных записей или расширению критериев поиска, для разработчика это означает использование API поисковой системы и ее обработчиков событий.

Дополнительные свойства (UF и ИБ)

Нельзя вывести или использовать для расчетов данные, которых нет. Основные сущности, представленные в фреймворке допускают две возможности расширения:

  1. Добавление (даже без участия разработчика) новых полей в элементы инфоблока, разделы, для пользователей или страниц сайта. Это могут быть поля любых простых типов: Строки, Текст, Числа, Файлы, Списки и т.п. Например, администратор без разработчика может создать поля “Дата трудоустройства” и “Скан пропуска” для пользователя и настроить компонент регистрации, чтобы он запрашивал эти поля у новых пользователей.
  2. Создание нестандартных дополнительных полей. Например, привязка к группе пользователя или поля с непростой логикой валидации. Для этого уже потребуется разработчик.

Веб-сервисы (SOAP и REST)

Если планируется, что проект на базе «1С-Битрикс: Управление Сайтом» станет участником обмена данными с другими узлами сети, то один из вариантов действий — создание сервера веб-сервисов. Фреймворк предоставляет инструменты для создания серверов формата SOAP и REST. Также система может быть клиентом таких веб-сервисов.

Использование механизмов фреймворка вместо разработки с нуля позволяет решить вопрос с авторизацией (используется системная авторизация фреймворка) и сразу перейти к созданию API сайта в парадигме 1 метод API = 1 PHP-метод

Веб-формы (из модуля form)

Хороший разработчик должен быть знаком с каждым модулем фреймворка и уметь выбирать нужный компонент среди похожих. Например, для создания формы “Заказать звонок” можно использовать на выбор:

  1. Форма добавления / редактирования (bitrix:iblock.element.add.form)
  2. Форма обратной связи (bitrix:main.feedback)
  3. Заполнение веб-формы (bitrix:form.result.new)

На первый взгляд, компоненты работают одинаково — просят пользователя заполнить форму и благодарят, если все заполнено корректно. Но только первый из компонентов сохранит результат в Инфоблоке и не отправит никакого письма администратору, второй — отправит письмо, но ничего не сохранит и не даст ввести поле Телефон. И только третий компонент сочетает в себе гибкое управление полями, возможность оповещения по E-mail и сохранение результата формы в БД.

Модуль веб-форм (form) и его компоненты решают одну конкретную задачу, поэтому их возможности шире, чем компоненты для “типовых” случаев. Более того, в модуле веб-форм есть визуальный конструктор веб-форм и интеграция с CRM Битрикс24.

Отличия «Битрикс24» от «1С-Битрикс: Управление Сайтом»

Несмотря на связь продуктов «Битрикс24» и «1С-Битрикс: Управление Сайтом» и общие механизмы, лежащие в их основе, разработчик всегда должен помнить, какие способы доработки в каком продукте применимы.

«Битрикс24» — это «1С-Битрикс: Управление Сайтом» плюс набор публичных страниц с размещенными компонентами, свои сущности в БД и записи, а также несколько специализированных модулей.

Каждое обновление «Битрикс24» может затронуть эти части системы и стереть те изменения, которые по неосторожности внес туда разработчик.

Поэтому при работе с «Битрикс24» (коробочная редакция) действуют те же правила, которые нужно соблюдать при работе с готовыми решениями. Запрещено редактировать и удалять публичные страницы, менять настройки компонентов и шаблоны.

Запрещено кастомизировать компоненты, заменяя вызов стандартных на свои.

При этом вы можете создавать свои разделы и страницы, т.к. ни одно обновление на них не повлияет (вероятность, что в обновлении появится раздел с одноименным названием мала).