Розробка системи відгуків про товари у 1С-Бітрикс
У 1С-Бітрикс є вбудований механізм форумів (forum) та компонент bitrix:forum.reviews, який технічно може служити системою відгуків. Але більшість проектів від нього відмовляються: надлишкова структура форуму для простих відгуків, складність налаштування модерації, погана інтеграція з карточкою товара. На практиці відгуки будуються або на інфоблоках, або на ORM-моделі з нуля.
Два підходи до зберігання відгуків
Підхід 1: Інфоблок відгуків. Швидко, без розробки, але обмежено. Створюється інфоблок «Відгуки» зі властивостями: PRODUCT_ID (прив'язка до товара), RATING (число), ADVANTAGES, DISADVANTAGES, COMMENT. Елемент інфоблока = один відгук. Для прив'язки до товара використовується властивість типу «Елемент інфоблока» або просто числове поле з ID товара.
Вивід — компонент bitrix:catalog.reviews (якщо він є в шаблоні) або користувацький компонент на базі CIBlockElement::GetList() з фільтром PROPERTY_PRODUCT_ID = $productId.
Підхід 2: Власна ORM-модель. Більш гнучко: транзакції, складні запити, розширюваність. Таблиця b_product_review:
| Поле | Тип | Призначення |
|---|---|---|
| ID | int auto_increment | Первинний ключ |
| PRODUCT_ID | int | ID товара в інфоблоці |
| USER_ID | int | ID користувача (NULL для гостей) |
| AUTHOR_NAME | varchar(255) | Ім'я автора |
| AUTHOR_EMAIL | varchar(255) | Email для сповіщень |
| RATING | tinyint | Оцінка 1–5 |
| ADVANTAGES | text | Переваги |
| DISADVANTAGES | text | Недоліки |
| COMMENT | text | Основний текст |
| STATUS | enum | PENDING, APPROVED, REJECTED |
| CREATED_AT | datetime | Дата створення |
| IS_VERIFIED_PURCHASE | tinyint(1) | Купив ли користувач цей товар |
ORM-клас наслідується від \Bitrix\Main\ORM\Data\DataManager — отримуємо стандартний API D7 для виборок, додавання, оновлення.
Верифікація покупки
Один з ключових ознак довіри до відгуку — «Підтверджена покупка». Для визначення прапора IS_VERIFIED_PURCHASE при відправці відгуку перевіряємо історію замовлень:
function isVerifiedPurchase(int $userId, int $productId): bool
{
$orders = \Bitrix\Sale\OrderTable::getList([
'filter' => ['=USER_ID' => $userId, '=STATUS_ID' => 'F'],
'select' => ['ID'],
]);
$orderIds = array_column(iterator_to_array($orders), 'ID');
if (empty($orderIds)) {
return false;
}
$basket = \Bitrix\Sale\BasketTable::getList([
'filter' => [
'=ORDER_ID' => $orderIds,
'=PRODUCT_ID' => $productId,
],
'select' => ['ID'],
'limit' => 1,
])->fetch();
return (bool)$basket;
}
Статус 'F' — виконане замовлення. Перевіряємо саме виконані, щоб відсікти скасовані та неоплачені.
Модерація відгуків
Нові відгуки потрапляють в статус PENDING. В адміністративній частині створюється користувацька сторінка (або розділ в local/admin/) з таблицею відгуків та кнопками «Одобрити» / «Відхилити». При зміні статусу:
-
APPROVED→ відгук стає видимим на сайті, перераховується середній рейтинг товара. -
REJECTED→ відгук прихований, опціонально відправляється лист автору.
Сповіщення про новий відгук для модератора — поштова подія REVIEW_NEW_PENDING, шаблон в Параметри → Поштові подій.
Перерахунок рейтингу товара
Після одобрення або видалення відгуку потрібно перерахувати середній рейтинг та зберегти його у властивість товара (наприклад, AVERAGE_RATING числового типу). Це прискорює вивід рейтингу на сторінки каталога — не потрібен JOIN з таблицею відгуків при кожному запиті.
function recalculateProductRating(int $productId): void
{
$result = \Bitrix\Main\Application::getConnection()->query(
"SELECT AVG(RATING) as AVG_RATING, COUNT(*) as CNT
FROM b_product_review
WHERE PRODUCT_ID = {$productId} AND STATUS = 'APPROVED'"
)->fetch();
\CIBlockElement::SetPropertyValuesEx($productId, false, [
'AVERAGE_RATING' => round((float)$result['AVG_RATING'], 1),
'REVIEW_COUNT' => (int)$result['CNT'],
]);
}
Викликається з обробника подій при зміні статусу відгуку.
Антиспам та обмеження
- Перевірка на дублюючий відгук: один користувач — один відгук на товар (перевірка по
USER_ID + PRODUCT_IDабо поAUTHOR_EMAIL + PRODUCT_IDдля гостей). - Captcha для гостей (компонент
bitrix:main.captcha). - Обмеження частоти: один IP не може відправити більше 3 відгуків за годину (через
\Bitrix\Main\Data\Cacheабо таблицю з таймстампами).
Терміни розробки
| Масштаб | Склад | Термін |
|---|---|---|
| Базовий | ORM-модель, форма, вивід, модерація в ЛК | 4–6 днів |
| Повний | Верифікація покупки, перерахунок рейтингу, сповіщення, антиспам, адміністративний розділ | 8–12 днів |







