Розробка та налаштування модулів 1С-Бітрікс
Головна пастка Бітрікса — init.php. Кинув туди обробник OnBeforeIBlockElementUpdate, потім ще один, через рік файл на 2000 рядків, і при кожному хіті весь цей ком виконується. Ми переносимо бізнес-логіку у повноцінні модулі з D7 ORM, власними таблицями й адміністративним інтерфейсом. Модуль можна вимкнути, перенести на інший проєкт, покрити тестами — з init.php нічого з цього не вийде.
Стандартні модулі: де граблів найбільше
Інформаційні блоки. Архітектура ІБ — перше, що ми ревʼюїмо на будь-якому проєкті. Класична помилка: один інфоблок каталогу з 80 властивостями, з яких 30 — множинні. Таблиця b_iblock_element_property роздувається до мільйонів рядків, CIBlockElement::GetList при фільтрації за трьома властивостями іде у повне сканування. Переносимо довідники у Highload-блоки, прибираємо множинні властивості де можна, проєктуємо структуру з прицілом на те, що каталог виросте у 5 разів.
Інтернет-магазин (sale). Модуль потужний, але бізнес-правила кошика — окрема історія. Налаштовуємо пріоритети знижок, щоб дві акції не дали 60% замість 30%, підключаємо платіжні обробники, прописуємо обробники OnSaleOrderBeforeSaved для кастомної валідації.
Пошук. Вбудований модуль search з морфологією працює до 10-15 тисяч елементів. Далі — Elasticsearch. Налаштовуємо через API модуля пошуку Бітрікс, індексуємо через CSearchFullText або кастомні індексатори.
Highload-блоки. Для довідників, логів, користувацьких даних — замість роздутих ІБ. Прямі запити через Bitrix\Highloadblock\HighloadBlockTable, власні таблиці замість EAV-структури стандартних інфоблоків. Мільйон записів — без деградації.
Поштові події. Налаштування — не лише шаблони у b_event_message. Головне — SPF, DKIM, DMARC на DNS, інакше транзакційні листи летять у спам. Перевіряємо доставлюваність, налаштовуємо bounce-обробку.
Розробка кастомних модулів
Кожен модуль — за структурою /local/modules/vendor.modulename/:
-
install/index.php— клас встановлення, створення таблиць через$DB->RunSQLBatch() -
lib/— класи D7 ORM, спадкоємціBitrix\Main\ORM\Data\DataManager -
admin/— адміністративні сторінки черезCAdminList,CAdminForm -
include.php— автозавантаження, реєстрація обробників черезEventManager::getInstance()->registerEventHandler() - REST API endpoints через
\Bitrix\Rest\RestManager
Модуль реєструється в системі, з'являється у списку «Встановлені рішення», має власні налаштування у /bitrix/admin/settings.php?mid=vendor.modulename. Його можна вмикати, вимикати, оновлювати через UpdateSystem або власний механізм міграцій.
Що робили:
- Управління акціями — візуальний конструктор умов через
CAdminCalendar, таймери через агенти (CAgent::AddAgent), аналітика ефективності у зв'язці з модулем sale - Калькулятор вартості — React-віджет на фронті, REST API у модулі, формули зберігаються у Highload-блоці
- Система бронювання — real-time календар, блокування через
$DB->StartTransaction()/$DB->Commit()при одночасних запитах, синхронізація з channel manager через webhook
Компоненти та композитний кеш
Кастомізація компонентів — через result_modifier.php та component_epilog.php, а не через правку template.php стандартного шаблону. Так ядро оновлюється безболісно.
Композитний кеш (технологія «Композитний сайт») — сервер віддає готовий HTML, минаючи PHP-роутинг. Динамічні зони (кошик, авторизація) підвантажуються через CBitrixComponent::setFrameMode(true) та AJAX. TTFB падає до 30-50 мс. Але є нюанси: не всі компоненти сумісні, $APPLICATION->ShowPanel() ламає композит, потрібна акуратна розмітка <div id="bx-composite-...">.
Маркетплейс: аудит перед встановленням
Перед встановленням модуля з маркетплейсу — обов'язковий аудит. Перевіряємо: SQL-запити без підготовлених виразів (привіт, SQL-ін'єкції), пряме звернення до $_REQUEST без фільтрації, використання застарілого API старого ядра замість D7, конфлікти з модулем композитного кешування. Модуль без оновлень понад рік і з парою десятків встановлень — найімовірніше, головний біль на найближчому оновленні PHP.
Міграція на D7
При оновленні PHP до 8.x або переході на нову редакцію — рефакторинг застарілих викликів:
-
CIBlockElement::GetList()→Bitrix\Iblock\Elements\ElementTable::getList() -
CSaleOrder::GetList()→Bitrix\Sale\Order::getList() -
CModule::IncludeModule()→Bitrix\Main\Loader::includeModule() - Тестування на staging, відкат через git у разі проблем
Вартість розробки модулів
| Складність | Приклади | Терміни | Орієнтовна вартість |
|---|---|---|---|
| Простий | Віджет зворотного дзвінка, банерна система, простий калькулятор | 3-5 днів | від 30 000 руб. |
| Середній | Система бронювання, конфігуратор товарів, модуль відгуків з модерацією | 1-2 тижні | від 80 000 руб. |
| Складний | Мультирегіональність, кастомна програма лояльності, інтеграція з ERP | 2-4 тижні | від 150 000 руб. |
| Enterprise | Маркетплейс-платформа, складні бізнес-процеси з багатьма ролями | 1-3 місяці | від 350 000 руб. |
У вартість входить проєктування, розробка, тестування, документація та встановлення.
Тестування модулів
Unit-тести через PHPUnit. Покриваємо бізнес-логіку: розрахунок знижок, валідація, формування документів. Моки для Bitrix\Main\Application::getConnection() — щоб тести не залежали від БД.
Інтеграційні тести. Перевіряємо обробники подій на реальній базі — OnAfterIBlockElementAdd, OnSaleOrderSaved та інші. REST API endpoints тестуємо через curl або PHPUnit HTTP-клієнт. Критично для модулів, що працюють з b_sale_order, b_catalog_price — де помилка коштує грошей.
Сумісність. PHP 7.4, 8.0, 8.1, 8.2. Редакції: Стандарт, Малий бізнес, Бізнес. Перевіряємо конфлікти з популярними модулями маркетплейсу — вони люблять перехоплювати ті самі події.
Навантажувальне. Для модулів з великими обсягами: заміри на 10K, 100K, 1M записів. Профілювання через Xdebug на предмет витоків пам'яті та N+1 запитів.
Приклади з практики
Модуль акцій для мережі електроніки. Штатні знижки модуля sale не покривали сценарії «2+1», подарунок при купівлі від суми, комбіновані умови. Зібрали візуальний конструктор: маркетолог створює правила через drag-and-drop, без тікетів у розробку. Календар акцій, автодеактивація через агенти, аналітика у прив'язці до b_sale_order — конверсія, середній чек, кількість застосувань. Час запуску нової акції впав з двох днів до півгодини.
Калькулятор для будівельників. Параметри (площа, матеріали, поверховість) → формула → попередній кошторис → заявка в CRM через CRest::call('crm.lead.add'). Регіональні коефіцієнти та сезонні надбавки — з Highload-блоку, ціни матеріалів — з обміну з 1С. Кількість цільових заявок зросла на третину: клієнти бачать розбивку за статтями до дзвінка менеджеру.
Бронювання для мережі готелів. Real-time доступність через AJAX-запити до кастомної таблиці vendor_booking_slots, розрахунок тарифів за сезоном, синхронізація з Booking.com через channel manager API. Блокування номера при одночасному бронюванні — через SELECT ... FOR UPDATE у транзакції. Часові пояси обробляються через \DateTimeZone — гість з Владивостока й менеджер з Москви бачать одну картину.







