Розробка модуля порівняння товарів для 1С-Бітрікс
У стандартній поставці Бітрікс є компонент bitrix:catalog.compare і вбудована сесійна корзина порівняння. На несклідних проектах цього досить. Але щойно з'являються вимоги — зберігати список між сесіями, порівнювати товари з різних категорій, виділяти відмінні характеристики, експортувати таблицю — стандартний компонент упирається в потолок. Власний модуль вирішує ці завдання без костилів.
Як працює вбудоване порівняння і де воно ламається
Вбудований механізм зберігає список у $_SESSION['CATALOG_COMPARE'] і в куці catalog_compare_items. При додаванні товара AJAX-метод компонента пише в сесію. Проблеми:
- Сесія живе до закриття браузера або таймауту — користувач повернувся на другий день і список порожній.
- Немає розділення за категоріями — можна додати в порівняння телевізор і сапоги, і компонент намагатиметься їх порівнювати.
- Характеристики виводяться все підряд без виділення відмінностей.
- Немає підтримки авторизованих користувачів: одна людина на двох пристроях — два різні списки.
Архітектура модуля
Модуль реєструється в системі через local/modules/vendor.compare/ зі стандартним include.php і install/index.php. Зберігання списків:
Таблиця b_compare_list:
| Поле | Тип | Назначення |
|---|---|---|
| ID | int auto_increment | Первинний ключ |
| USER_ID | int | ID авторизованого користувача, NULL для гостей |
| SESSION_ID | varchar(64) | Хеш сесії для гостей |
| CREATED_AT | datetime | Дата створення |
| UPDATED_AT | datetime | Дата останньої зміни |
Таблиця b_compare_item:
| Поле | Тип | Назначення |
|---|---|---|
| ID | int auto_increment | — |
| LIST_ID | int | FK на b_compare_list |
| PRODUCT_ID | int | ID товарного пропозиції |
| SECTION_ID | int | ID розділу каталогу |
| ADDED_AT | datetime | Коли додано |
ORM-класи наслідуються від \Bitrix\Main\ORM\Data\DataManager. Обмеження на кількість товарів в одному списку встановлюється через параметри модуля (таблиця b_option, простір імен модуля).
Логіка слияння при авторизації
Коли гість авторизується, його анонімний список потрібно сліяти з постійним:
public static function mergeOnLogin(int $userId, string $sessionId): void
{
$guestList = CompareListTable::getRow([
'filter' => ['=SESSION_ID' => $sessionId, '=USER_ID' => false],
]);
if (!$guestList) {
return;
}
$userList = CompareListTable::getOrCreate($userId);
$guestItems = CompareItemTable::getList([
'filter' => ['=LIST_ID' => $guestList['ID']],
]);
foreach ($guestItems as $item) {
CompareItemTable::addIfNotExists($userList['ID'], $item['PRODUCT_ID']);
}
CompareListTable::delete($guestList['ID']);
}
Подія OnAfterUserLogin з модуля main — місце для виклику цього методу.
Виділення відмінних характеристик
Це те, що покупець чекає від порівняння: рядки, в яких товари відрізняються, повинні бути візуально виділені. Алгоритм:
- Отримуємо властивості всіх товарів у порівнянні через
CIBlockElement::GetList()зSELECT = ['PROPERTY_*']. - Будуємо матрицю: ключ — символьний код властивості, значення — масив значень для кожного товара.
- Для кожного рядка матриці перевіряємо
count(array_unique($values)) > 1— якщо більше одного унікального значення, позначаємо як «відмінний». - На фронті до рядків з відмінностями додаємо CSS-клас
compare-row--diff.
Додатково фільтруємо рядки, де всі значення порожні — їх незачем показувати.
Фронтенд: AJAX і стан
Кнопка «Додати до порівняння» на карточці товара відправляє POST на компонент через bitrix:main.ajax. Стан іконки (додано / не додано) синхронізується через localStorage при завантаженні сторінки і оновлюється після кожного AJAX-відповіді.
Лічильник кількості товарів у порівнянні виводиться в шапці через окремий компонент, який читає кількість з сесії або API модуля без повного завантаження даних.
Експорт таблиці порівняння
На великих проектах просять експорт у PDF або Excel. Для PDF використовуємо mPDF або TCPDF (підключається як залежність через composer у local/). Для Excel — PhpSpreadsheet. Таблиця порівняння формується з тієї ж матриці властивостей і відображається у файл за запитом користувача.
Терміни розробки
| Масштаб | Склад | Тривалість |
|---|---|---|
| Базовий | Зберігання в БД, AJAX-додавання/видалення, таблиця порівняння | 4–6 днів |
| Стандартний | + Слияння при авторизації, виділення відмінностей, лічильник в шапці | 8–10 днів |
| Розширений | + Експорт PDF/Excel, порівняння між категоріями, параметри модуля в админці | 12–16 днів |







