✨ 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
127 lines
3.7 KiB
PHP
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()
|
|
]);
|
|
}
|
|
}
|
|
}
|