Розробка модуля обраного для 1С-Бітрікс
Стандартний Бітрікс не має готового модуля обраного для каталогу. Є модуль sale з «відкладеними товарами» — вони потрапляють у корзину зі статусом Y у полі DELAY. Це не обране: товари змішуються з корзиною логічно і технічно, немає можливості створювати кілька списків, немає підтримки гостей з синхронізацією при вході. Повноцінне обране реалізується окремим модулем.
Зберігання даних
Модуль розташовується в local/modules/vendor.wishlist/. Дві основні таблиці:
Таблиця b_wishlist — списки обраного (користувач може мати кілька: «Хочу купити», «Подарунки», «Відложено»):
| Поле | Тип | Назначення |
|---|---|---|
| ID | int auto_increment | Первинний ключ |
| USER_ID | int | ID користувача (NULL для гостей) |
| SESSION_ID | varchar(64) | Хеш сесії гостя |
| TITLE | varchar(255) | Назва списку |
| IS_PUBLIC | tinyint(1) | Можна ли робити поділ за посиланням |
| PUBLIC_HASH | varchar(32) | Унікальний хеш для публічного URL |
| CREATED_AT | datetime | — |
Таблиця b_wishlist_item:
| Поле | Тип | Назначення |
|---|---|---|
| ID | int auto_increment | — |
| LIST_ID | int | FK на b_wishlist |
| PRODUCT_ID | int | ID товарного пропозиції |
| ELEMENT_ID | int | ID елемента інфоблоку (батьківський товар) |
| ADDED_AT | datetime | — |
| NOTE | text | Особиста заметка користувача про товар |
Синхронізація гість → авторизований користувач
При вході користувача в систему запускається обробник подій OnAfterUserLogin:
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'main',
'OnAfterUserLogin',
[WishlistMerger::class, 'merge']
);
Метод merge знаходить анонімний список за SESSION_ID, переносить з нього товари в основний список користувача (з перевіркою дублів через SELECT перед INSERT), після чого видаляє анонімний список. Якщо користувач ще не має жодного списку, анонімний список просто переназначається через UPDATE b_wishlist SET USER_ID = ?, SESSION_ID = NULL WHERE SESSION_ID = ?.
Кнопка «В обране» на карточці товара
Кнопка відправляє AJAX-запит на компонент vendor:wishlist.button. Компонент приймає PRODUCT_ID і ACTION (add/remove/toggle), виконує операцію і повертає JSON з новим станом.
На сторінці каталогу стани кнопок ініціалізуються один раз: при завантаженні сторінки робиться єдиний запит, що повертає масив PRODUCT_ID поточного користувача, які вже в обраному. JavaScript позначає відповідні кнопки без повторних запитів до сервера.
// Отримання всіх ID товарів в обраному для поточного користувача
$items = WishlistItemTable::getList([
'filter' => ['=LIST_ID' => $listId],
'select' => ['PRODUCT_ID'],
])->fetchAll();
$productIds = array_column($items, 'PRODUCT_ID');
Публічні списки та шеринг
Кожен список може бути зроблений публічним. У цьому випадку генерується PUBLIC_HASH через \Bitrix\Main\Security\Random::getString(32). URL вида /wishlist/share/abc123/ відкриває список для будь-якого відвідувача в режимі перегляду. Той, що переглядає, може додати окремі товари в свою корзину, але не може редагувати чужий список.
Функція корисна для подарункових списків: користувач складає список бажаних подарунків і відправляє посилання рідним.
Сповіщення про зниження ціни
Опціональна, але популярна функція: якщо товар з обраного подешевів, користувач отримує email-сповіщення. Реалізується агентом (\Bitrix\Main\Agent) або cron-завданням:
- Агент раз на добу перебирає унікальні
PRODUCT_IDзb_wishlist_item. - Для кожного отримує поточну ціну через
\CCatalogProduct::GetByID()абоPrice::getList(). - Порівнює з ціною, збереженою у полі
LAST_PRICE(додається в таблицюb_wishlist_item). - При зниженні відправляє поштову подію
WISHLIST_PRICE_DROP.
Лічильник в шапці
Кількість товарів в обраному виводиться в шапці. Щоб не робити важкий запит при кожній завантаженні сторінки, лічильник кешується в $_SESSION['WISHLIST_COUNT'] і інвалідується при кожній зміні списку. Компонент шапки читає значення з сесії — один PHP-виклик без звернення до БД.
Терміни розробки
| Масштаб | Склад | Тривалість |
|---|---|---|
| Базовий | Один список, зберігання в БД, AJAX-кнопка, лічильник в шапці | 4–5 днів |
| Стандартний | + Слияння гість/користувач, сторінка обраного в ЛК, кілька списків | 7–10 днів |
| Розширений | + Публічні списки, сповіщення про зниження ціни, експорт списку | 12–15 днів |







