1С Битрикс · 6 мин чтения

Разработка компонентов Битрикс: свои решения под задачу проекта

Разработка компонентов Битрикс нужна там, где заканчиваются возможности готового каталога, инфоблоков и типовых форм заказа. На практике из десяти проектов на 1С-Битрикс: Управление сайтом восемь требуют минимум пару своих компонентов: нестандартный вывод карточек товара, форму с валидацией под конкретный CRM-процесс, интеграцию с эквайрингом Т‑Банка или расчёт доставки через СДЭК. Правки через хуки в init.php или чужой шаблон работают недолго: через полгода такой проект превращается в код, который боится любого обновления модуля. Свой компонент решает это иначе - логика живёт в отдельной папке, не трогает ядро и переживает обновления системы.

Когда типовых компонентов Битрикса не хватает

Стандартные bitrix:catalog.section, bitrix:catalog.element и bitrix:sale.order.ajax закрывают витрину и оформление заказа в базовом виде. Свой компонент нужен, когда:

  • вывод карточек товара завязан на нестандартные свойства сразу из нескольких инфоблоков;
  • форма заказа должна дёргать внешний API - расчёт доставки СДЭК, проверку промокода, статус оплаты через Т‑Банк - до сабмита, а не после;
  • в личном кабинете нужен виджет, которого нет ни в одном модуле: график начислений бонусов, история заявок, дашборд для менеджера;
  • событие Битрикса (OnSaleOrderSaved, OnAfterIBlockElementAdd) должно уходить наружу - в Telegram-бота для уведомления менеджера или в n8n для дальнейшей автоматизации.

Каждый из этих сценариев встречался мне минимум раз в проекте, и в каждом случае доработка типового компонента через override шаблона работает первые пару месяцев, а потом ломается на очередном обновлении модуля.

Из чего состоит компонент: структура файлов

Компонент в Битриксе - это папка внутри /local/components/vendor/component_name/ (не /bitrix/components/, потому что local не затирается при обновлении маркетплейса). Минимальный набор файлов выглядит так:

/local/components/kalinkindev/order.custom/
├── component.php
├── class.php
├── .parameters.php
├── templates/
│   └── .default/
│       ├── template.php
│       ├── style.css
│       └── script.js
└── lang/
    └── ru/
        └── component.php

component.php - точка входа, здесь подключается класс и вызывается executeComponent(). class.php содержит всю бизнес-логику: выборку данных, обращение к внешним сервисам, подготовку arResult. .parameters.php описывает параметры, которые администратор увидит в визуальном редакторе - от него зависит, сможет ли контент-менеджер сам поменять число элементов на странице без звонка разработчику. Шаблон в templates/.default/ отвечает только за вёрстку и получает уже готовые данные, без прямых запросов к базе.

D7 и CBitrixComponent: на чём строить логику

Компоненты старого типа с процедурным кодом в component.php до сих пор работают, но для чего-то сложнее вывода списка перехожу на D7: класс наследуется от CBitrixComponent, данные достаю через ORM-сущности (BitrixIblockElementTable, кастомные Entity для highload-блоков), ошибки собираю в ErrorCollection вместо разбросанных по коду ShowError().

<?php
namespace Kalinkindev\Order;

use Bitrix\Main\ErrorCollection;

class CustomOrderComponent extends \CBitrixComponent
{
    private ErrorCollection $errors;

    public function onPrepareComponentParams($arParams)
    {
        $arParams['CACHE_TIME'] = $arParams['CACHE_TIME'] ?? 3600;
        return $arParams;
    }

    public function executeComponent()
    {
        $this->errors = new ErrorCollection();

        if ($this->startResultCache()) {
            $this->arResult['ITEMS'] = $this->getDeliveryOptions();
            if (!$this->errors->isEmpty()) {
                $this->abortResultCache();
            }
            $this->includeComponentTemplate();
        }
    }
}

Такой подход даёт нормальную обработку ошибок на шаблоне (arResult[‘ERRORS’] вместо ShowError() посреди вёрстки) и класс, который тестируется отдельно: логику выборки можно вызвать напрямую в phpunit-тесте, без поднятия всего движка.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Интеграция с инфоблоками, highload-блоками и внешними сервисами

Свои компоненты чаще всего пишу не ради вывода контента, а для стыковки Битрикса с внешним миром:

  • расчёт доставки СДЭК прямо в форме заказа: компонент дёргает API СДЭК по индексу или адресу, показывает пункты выдачи на карте и передаёт стоимость в заказ до оплаты, а не после подтверждения;
  • приём оплаты через Т‑Банк с созданием платежа на этапе оформления, а не редиректом на отдельную страницу эквайринга модуля sale;
  • характеристики товара из highload-блока, которые не влезают в стандартные свойства инфоблока - типичный случай для магазинов с сотнями фильтруемых параметров;
  • уведомление менеджера в Telegram при смене статуса заказа через обработчик события OnSaleStatusOrderChange, который отправляет вебхук в n8n, а тот уже маршрутизирует сообщение в нужный чат.

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

Кеширование компонентов без просадки производительности

Кастомный компонент, который на каждый хит страницы обращается к API СДЭК или Т‑Банка, за неделю кладёт прод при десятке одновременных пользователей. Кеширую то, что можно кешировать: результат запроса тарифов по индексу - на час через управляемый кеш с тегами по инфоблоку, а не через жёсткий CACHE_TIME, чтобы сброс происходил по событию OnAfterIBlockElementUpdate, а не по таймеру. Данные, которые обязаны быть актуальными в моменте - статус оплаты, остаток на складе - кешу не подлежат, но здесь нельзя гонять в цикле по одному запросу на элемент: highload-блоки и D7 ORM дают getList() с фильтром по массиву ID, и один запрос на пятьдесят элементов в разы дешевле пятидесяти запросов по одному.

Композитный кеш Битрикса (модуль composite) с кастомными компонентами дружит не всегда: если в шаблоне есть логика, завязанная на текущего пользователя - персональные бонусы, история заявок - такой блок оборачиваю в подгрузку через AJAX, иначе вся страница попадает в статический кеш с чужими данными на экране у следующего посетителя.

Тестирование и деплой своих компонентов

Обновление модулей 1С-Битрикс само по себе не трогает /local/components/, и это ровно то преимущество, ради которого свои компоненты пишут вместо правок в /bitrix/. Перед выкладкой на прод гоняю изменения на копии сайта с той же версией модулей и PHP, а не на локальном стенде с другой версией: разница между PHP 8.1 и 8.2 в деталях типизации ловит баги, которых на локали не видно.

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

Частые вопросы

Сколько стоит разработка кастомного компонента для Битрикс?

Зависит от объёма: доработка вывода карточек товара под нестандартные свойства инфоблока - одна оценка, интеграция с эквайрингом или СДЭК с обработкой событий и вебхуками - совсем другая, там счёт идёт на недели, а не на часы. Точка отсчёта для оценки конкретной задачи - консультация от 3 000 ₽, дальше называю сумму по ТЗ.

Можно ли дорабатывать типовой компонент вместо создания своего?

Через override шаблона - копию в /local/templates/ с изменённым template.php - да, для косметических правок вёрстки. Но если меняется логика выборки данных или добавляется обращение к внешнему API, override быстро превращается в дублирование половины component.php с патчами поверх, и на следующем обновлении модуля этот патч перестаёт совпадать со структурой оригинала. В таких случаях свой компонент с нуля выходит дешевле в поддержке, даже если разработка занимает на пару дней больше.

Переживут ли кастомные компоненты обновление 1С-Битрикс?

Если компонент лежит в /local/components/ и не переопределяет файлы ядра напрямую, обновление модулей через маркетплейс его не тронет. Ломается такое обычно не от апдейта самого Битрикса, а от смены версии PHP на хостинге или от изменений в API модуля, к которому компонент обращается, например sale - это стоит проверять на копии сайта перед переносом изменений на прод, а не после.

Нужен ли доступ к маркетплейсу 1С-Битрикс для установки своих компонентов?

Нет, свои компоненты в /local/components/ устанавливаются копированием файлов через FTP, git-деплой или систему обновлений хостинга, лицензия модуля Marketplace для этого не нужна. Доступ к маркетплейсу нужен, только если планируете публиковать компонент как отдельное решение для чужих проектов - для внутренней разработки под конкретный сайт это не требуется.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно