beeralex/beeralex.reviews
最新稳定版本:v1.1.01
Composer 安装命令:
composer require beeralex/beeralex.reviews
包简介
My reviews module
README 文档
README
Система управления отзывами для Bitrix с поддержкой модерации, загрузки файлов и REST API.
Основные возможности
- ✅ Создание отзывов с автоматической валидацией (PHP 8.1+ атрибуты)
- 📁 Загрузка файлов (фото к отзывам)
- 🔐 Модерация — новые отзывы требуют одобрения
- 👤 Авторизованные и гостевые пользователи
- ⭐ Рейтинг 1-5 звезд
- 📥 Импорт отзывов из 2GIS (deprecated)
- 🔄 Сортировка (новые/старые)
- 🌐 REST API интеграция
Требования
- PHP 8.1+
- Bitrix Framework 22.0+
- Модуль
beeralex.core(базовые абстракции) - Модуль
beeralex.api(для REST API) - Инфоблок с кодом
product_reviews
Установка
Через Composer
Добавьте в composer.json:
"extra": { "installer-paths": { "local/modules/{$name}/": ["type:bitrix-module"] } }
Установите пакет:
composer require beeralex/beeralex.reviews
Ручная установка
- Разместите модуль в
/local/modules/beeralex.reviews/ - Установите через административную панель Bitrix
- Модуль автоматически зарегистрирует сервисы
Настройка инфоблока
Создайте инфоблок с кодом product_reviews и свойствами:
USER_NAME (string) - Имя пользователя
EVAL (number) - Оценка (1-5)
REVIEW (text) - Текст отзыва
CONTACT_DETAILS (string) - Email/телефон
ELEMENT_ID (number) - ID товара
USER (number) - ID пользователя Bitrix
FILES (file) - Фотографии (множественное)
Быстрый старт
Создание отзыва
use Beeralex\Reviews\Services\ReviewsService; use Beeralex\Reviews\Dto\ReviewDTO; $service = service(ReviewsService::class); $dto = new ReviewDTO(); $dto->userName = 'Иван Петров'; $dto->eval = 5; $dto->review = 'Отличный товар, рекомендую!'; $dto->contactDetails = 'ivan@example.com'; $dto->elementId = 123; // ID товара $dto->userId = $USER->GetID() ?: null; $result = $service->add($dto, $_FILES); if ($result->isSuccess()) { $elementId = $result->getData()['elementId']; echo "Отзыв создан с ID: {$elementId}"; } else { foreach ($result->getErrorMessages() as $error) { echo "Ошибка: {$error}\n"; } }
Валидация данных
ReviewDTO использует атрибуты для автоматической валидации:
$dto = new ReviewDTO(); $dto->userName = 'А'; // Слишком короткое имя $dto->eval = 6; // Вне диапазона 1-5 $dto->review = 'OK'; // Слишком короткий отзыв if (!$dto->isValid()) { foreach ($dto->getErrors() as $error) { echo $error->getMessage() . "\n"; } } // Вывод: // Имя должно быть от 2 до 100 символов // Максимальная оценка - 5 // Отзыв должен быть от 10 до 5000 символов
Получение отзывов товара
use Beeralex\Reviews\Repository\ReviewsRepository; $repo = service(ReviewsRepository::class); $reviews = $repo->all( filter: [ 'IBLOCK_SECTION_ID' => 123, // ID товара 'ACTIVE' => 'Y' ], select: [ 'ID', 'DATE_CREATE', 'PROPERTY_USER_NAME', 'PROPERTY_EVAL', 'PROPERTY_REVIEW', ], order: ['ID' => 'DESC'] ); foreach ($reviews as $review) { echo "{$review['PROPERTY_USER_NAME_VALUE']}: "; echo str_repeat('⭐', $review['PROPERTY_EVAL_VALUE']); echo " - {$review['PROPERTY_REVIEW_VALUE']['TEXT']}\n"; }
REST API
Модуль интегрирован с beeralex.api через ReviewController.
Получить список отзывов
fetch('/api/v1/review/index/?product_id=123&count=10') .then(res => res.json()) .then(data => console.log('Отзывы:', data));
Создать отзыв
const formData = new FormData(); formData.append('userName', 'Иван Петров'); formData.append('eval', 5); formData.append('review', 'Отличный товар!'); formData.append('elementId', 123); formData.append('files[]', fileInput.files[0]); fetch('/api/v1/review/store/', { method: 'POST', body: formData }) .then(res => res.json()) .then(data => { if (data.status === 'success') { console.log('Отзыв создан:', data.data.elementId); } else { console.error('Ошибки:', data.errors); } });
Ответ (успех):
{
"status": "success",
"data": {
"elementId": 456
}
}
Ответ (ошибка):
{
"status": "error",
"errors": [
{
"message": "Имя должно быть от 2 до 100 символов",
"code": "review_create"
}
]
}
Архитектура
Основные компоненты
ReviewsService → Фасад для создания отзывов
├── ReviewCreatorService → Логика создания, валидация
│ ├── UploadService → Загрузка файлов
│ └── ReviewsRepository → Работа с инфоблоком
└── ReviewDTO → Валидация данных
Сервисы
ReviewsService — упрощенный интерфейс для добавления отзывов
ReviewCreatorService — реализация CreatorContract, содержит бизнес-логику
UploadService — реализация FileUploaderContract, загружает файлы через Bitrix CFile
ReviewsRepository — работа с инфоблоком отзывов (extends IblockRepository)
SortingRepository — статические варианты сортировки (новые/старые)
Расширение функционала
Добавление автоответа на отзыв
namespace App\Reviews\Services; use Beeralex\Reviews\Services\ReviewCreatorService as BaseCreator; use Beeralex\Reviews\Dto\ReviewDTO; use Bitrix\Main\Result; class ReviewCreatorService extends BaseCreator { public function create(ReviewDTO $dto, array $files): Result { $result = parent::create($dto, $files); if ($result->isSuccess()) { $this->sendThankYouEmail($dto); } return $result; } protected function sendThankYouEmail(ReviewDTO $dto): void { \CEvent::Send('REVIEW_THANK_YOU', 's1', [ 'USER_NAME' => $dto->userName, 'EMAIL' => $dto->contactDetails, ]); } }
Зарегистрируйте в /local/.settings_extra.php:
use Beeralex\Reviews\Contracts\CreatorContract; use App\Reviews\Services\ReviewCreatorService; return [ 'services' => [ 'value' => [ CreatorContract::class => [ 'constructor' => static function () { return new ReviewCreatorService( service(FileUploaderContract::class), service(ReviewsRepository::class) ); } ], ] ] ];
Добавление проверки на спам
namespace App\Reviews\Services; use Beeralex\Reviews\Services\ReviewCreatorService as BaseCreator; use Beeralex\Reviews\Dto\ReviewDTO; use Bitrix\Main\Result; use Bitrix\Main\Error; class ReviewCreatorService extends BaseCreator { public function create(ReviewDTO $dto, array $files): Result { $result = new Result(); if ($this->isSpam($dto)) { $result->addError(new Error('Отзыв отклонен как спам')); return $result; } return parent::create($dto, $files); } protected function isSpam(ReviewDTO $dto): bool { $spamWords = ['казино', 'кредит', 'займ']; $text = mb_strtolower($dto->review); foreach ($spamWords as $word) { if (str_contains($text, $word)) { return true; } } return false; } }
Уведомления через beeralex.notification
namespace App\Reviews\Services; use Beeralex\Reviews\Services\ReviewCreatorService as BaseCreator; use Beeralex\Notification\NotificationManager; use Beeralex\Notification\Dto\NotificationMessage; class ReviewCreatorService extends BaseCreator { public function create(ReviewDTO $dto, array $files): Result { $result = parent::create($dto, $files); if ($result->isSuccess()) { $this->notifyAdmin($dto, $result->getData()['elementId']); } return $result; } protected function notifyAdmin(ReviewDTO $dto, int $reviewId): void { $manager = new NotificationManager(); $message = new NotificationMessage( eventName: 'NEW_REVIEW_MODERATION', fields: [ 'REVIEW_ID' => $reviewId, 'USER_NAME' => $dto->userName, 'RATING' => $dto->eval, 'PRODUCT_ID' => $dto->elementId, ], userId: 1 // Администратор ); $manager->notify($message); } }
Импорт отзывов (deprecated)
⚠️ Устарело. Рекомендуется использовать API-интеграцию вместо импорта.
Импорт из 2GIS
use Beeralex\Reviews\Import\ImportFrom2Gis; $importer = new ImportFrom2Gis( service: service(ReviewsService::class), branches: ['70000001234567890'], // ID филиалов 2GIS apiKey: 'your_2gis_api_key' ); $importer->process();
Примеры компонентов
Форма добавления отзыва
class ReviewFormComponent extends CBitrixComponent { public function executeComponent() { if ($this->request->isPost() && check_bitrix_sessid()) { $this->handleSubmit(); } $this->includeComponentTemplate(); } protected function handleSubmit(): void { $dto = new ReviewDTO(); $dto->userName = $this->request->getPost('userName'); $dto->eval = (int)$this->request->getPost('eval'); $dto->review = $this->request->getPost('review'); $dto->elementId = (int)$this->arParams['PRODUCT_ID']; $dto->userId = $GLOBALS['USER']->GetID() ?: null; $result = service(ReviewsService::class)->add($dto, $_FILES); if ($result->isSuccess()) { $this->arResult['SUCCESS'] = true; } else { $this->arResult['ERRORS'] = $result->getErrorMessages(); } } }
Список отзывов товара
class ReviewListComponent extends CBitrixComponent { public function executeComponent() { $repo = service(ReviewsRepository::class); $this->arResult['REVIEWS'] = $repo->all( filter: [ 'IBLOCK_SECTION_ID' => $this->arParams['PRODUCT_ID'], 'ACTIVE' => 'Y' ], select: [ 'ID', 'DATE_CREATE', 'PROPERTY_USER_NAME', 'PROPERTY_EVAL', 'PROPERTY_REVIEW', 'PROPERTY_FILES', ], order: ['ID' => 'DESC'] ); // Статистика $evals = array_column($this->arResult['REVIEWS'], 'PROPERTY_EVAL_VALUE'); $this->arResult['AVERAGE_RATING'] = !empty($evals) ? round(array_sum($evals) / count($evals), 1) : 0; $this->arResult['TOTAL_COUNT'] = count($this->arResult['REVIEWS']); $this->includeComponentTemplate(); } }
Модерация
Все новые отзывы создаются с ACTIVE='N' и требуют одобрения.
Автоматическая модерация через агент
// В /local/php_interface/init.php CAgent::AddAgent( "\\App\\Agents\\ReviewModerationAgent::moderate();", "", "N", 3600 // Каждый час ); // Класс агента namespace App\Agents; class ReviewModerationAgent { public static function moderate(): string { $repo = service(ReviewsRepository::class); // Одобрить отзывы 4-5 звезд от авторизованных $reviews = $repo->all([ 'ACTIVE' => 'N', '>=PROPERTY_EVAL' => 4, '!PROPERTY_USER' => false, ]); foreach ($reviews as $review) { $repo->update($review['ID'], ['ACTIVE' => 'Y']); } return "\\App\\Agents\\ReviewModerationAgent::moderate();"; } }
Зависимости
beeralex.core— Repository, FileService, AbstractRequestDtobeeralex.api— ReviewController- Bitrix/Main — Result, Error, Validation
- Bitrix/Iblock — работа с инфоблоками
Документация
Полная документация доступна в docs/README.md
Лицензия
Проприетарный модуль. © beeralex
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-06