feat: Add complete reviews system with star ratings
✨ New Features: - Reviews system with 1-5 star ratings - User can add, edit, and delete their own reviews - One review per product per user (DB constraint) - Automatic average rating calculation - Review count tracking - Interactive star selection UI - AJAX-powered review submission - Responsive design for all devices 🗄️ Database: - New 'reviews' table with full structure - Added 'rating' and 'review_count' fields to products - PostgreSQL triggers for automatic rating updates - Database functions for rating calculations - Indexes for performance optimization 📦 Backend (PHP): - Review model with 15+ methods - ReviewController with 5 actions - Updated Product model to include ratings - Updated ProductController to load reviews - 5 new API endpoints 🎨 Frontend: - Reviews list component (_reviews_list.php) - Review form component (_review_form.php) - Reviews sechow page - Star ratings in catalog view - Interactive JavaScript (200+ lines) - Adaptive styles (400+ lines) 🔒 Security: - Server-side authorization checks - XSS protection (htmlspecialchars) - SQL injection protection (PDO prepared) - Input validation (client + server) - Access control for review editing 📝 Modified Files: - app/Models/Product.php - added rating fields to queries - app/Controllers/ProductController.php - loads reviews - app/Views/products/show.php - reviews section - app/Views/products/catalog.php - star ratings - config/routes.php - review endpoints - public/style_for_cite.less - rating styles 🆕 New Files: - app/Models/Review.php - app/Controllers/ReviewController.php - app/Views/products/_reviews_list.php - app/Views/products/_review_form.php
This commit is contained in:
@@ -11,7 +11,9 @@ class Product extends Model
|
||||
|
||||
public function findWithCategory(int $id): ?array
|
||||
{
|
||||
$sql = "SELECT p.*, c.name as category_name, c.slug as category_slug
|
||||
$sql = "SELECT p.*, c.name as category_name, c.slug as category_slug,
|
||||
COALESCE(p.rating, 0) as rating,
|
||||
COALESCE(p.review_count, 0) as review_count
|
||||
FROM {$this->table} p
|
||||
LEFT JOIN categories c ON p.category_id = c.category_id
|
||||
WHERE p.product_id = ?";
|
||||
@@ -20,7 +22,9 @@ class Product extends Model
|
||||
|
||||
public function getAvailable(array $filters = [], int $limit = 50): array
|
||||
{
|
||||
$sql = "SELECT p.*, c.name as category_name
|
||||
$sql = "SELECT p.*, c.name as category_name,
|
||||
COALESCE(p.rating, 0) as rating,
|
||||
COALESCE(p.review_count, 0) as review_count
|
||||
FROM {$this->table} p
|
||||
LEFT JOIN categories c ON p.category_id = c.category_id
|
||||
WHERE p.is_available = TRUE";
|
||||
@@ -67,7 +71,9 @@ class Product extends Model
|
||||
|
||||
public function getAllForAdmin(bool $showAll = true): array
|
||||
{
|
||||
$sql = "SELECT p.*, c.name as category_name
|
||||
$sql = "SELECT p.*, c.name as category_name,
|
||||
COALESCE(p.rating, 0) as rating,
|
||||
COALESCE(p.review_count, 0) as review_count
|
||||
FROM {$this->table} p
|
||||
LEFT JOIN categories c ON p.category_id = c.category_id";
|
||||
|
||||
@@ -82,7 +88,10 @@ class Product extends Model
|
||||
|
||||
public function getSimilar(int $productId, int $categoryId, int $limit = 3): array
|
||||
{
|
||||
$sql = "SELECT * FROM {$this->table}
|
||||
$sql = "SELECT *,
|
||||
COALESCE(rating, 0) as rating,
|
||||
COALESCE(review_count, 0) as review_count
|
||||
FROM {$this->table}
|
||||
WHERE category_id = ?
|
||||
AND product_id != ?
|
||||
AND is_available = TRUE
|
||||
|
||||
Reference in New Issue
Block a user