Files
web_work/app/Controllers/OrderController.php
kirill.khorkov a4092adf2e 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
2026-01-06 17:04:09 +03:00

127 lines
3.7 KiB
PHP

<?php
namespace App\Controllers;
use App\Core\Controller;
use App\Models\Order;
use App\Models\Cart;
class OrderController extends Controller
{
private Order $orderModel;
private Cart $cartModel;
public function __construct()
{
$this->orderModel = new Order();
$this->cartModel = new Cart();
}
public function checkout(): void
{
$this->requireAuth();
if ($this->isAdmin()) {
$this->redirect('/catalog');
return;
}
$user = $this->getCurrentUser();
$cartItems = $this->cartModel->getUserCart($user['id']);
$totals = $this->cartModel->getCartTotal($user['id']);
$this->view('cart/checkout', [
'user' => $user,
'cartItems' => $cartItems,
'totalQuantity' => $totals['quantity'],
'totalAmount' => $totals['amount']
]);
}
public function create(): void
{
if (!$this->isAuthenticated()) {
$this->json([
'success' => false,
'message' => 'Требуется авторизация'
]);
return;
}
if ($this->isAdmin()) {
$this->json([
'success' => false,
'message' => 'Доступ запрещен'
]);
return;
}
$user = $this->getCurrentUser();
$cartItems = $this->cartModel->getUserCart($user['id']);
if (empty($cartItems)) {
$this->json([
'success' => false,
'message' => 'Корзина пуста'
]);
return;
}
$orderData = [
'customer_name' => $this->getPost('full_name', $user['full_name']),
'customer_email' => $this->getPost('email', $user['email']),
'customer_phone' => $this->getPost('phone', $user['phone']),
'delivery_address' => $this->getPost('address', ''),
'delivery_region' => $this->getPost('region', ''),
'postal_code' => $this->getPost('postal_code', ''),
'delivery_method' => $this->getPost('delivery', 'courier'),
'payment_method' => $this->getPost('payment', 'card'),
'promo_code' => $this->getPost('promo_code', ''),
'discount' => (float) $this->getPost('discount', 0),
'delivery_price' => (float) $this->getPost('delivery_price', 2000),
'notes' => $this->getPost('notes', '')
];
if (empty($orderData['customer_name'])) {
$this->json([
'success' => false,
'message' => 'Укажите ФИО'
]);
return;
}
if (empty($orderData['customer_phone'])) {
$this->json([
'success' => false,
'message' => 'Укажите телефон'
]);
return;
}
if (empty($orderData['delivery_address'])) {
$this->json([
'success' => false,
'message' => 'Укажите адрес доставки'
]);
return;
}
try {
$result = $this->orderModel->createFromCart($user['id'], $cartItems, $orderData);
$this->json([
'success' => true,
'order_id' => $result['order_id'],
'order_number' => $result['order_number'],
'message' => 'Заказ успешно оформлен'
]);
} catch (\Exception $e) {
$this->json([
'success' => false,
'message' => $e->getMessage()
]);
}
}
}