reviewModel = new Review(); $this->productModel = new Product(); } /** * Create a new review (POST /reviews) */ public function create(): void { // Require authentication if (!$this->isAuthenticated()) { $this->json([ 'success' => false, 'message' => 'Требуется авторизация' ], 401); return; } // Admins cannot leave reviews if ($this->isAdmin()) { $this->json([ 'success' => false, 'message' => 'Администраторы не могут оставлять отзывы' ], 403); return; } $productId = (int) $this->getPost('product_id', 0); $rating = (int) $this->getPost('rating', 0); $comment = trim($this->getPost('comment', '')); $user = $this->getCurrentUser(); // Validate product ID if ($productId <= 0) { $this->json([ 'success' => false, 'message' => 'Неверный ID товара' ], 400); return; } // Check if product exists $product = $this->productModel->find($productId); if (!$product) { $this->json([ 'success' => false, 'message' => 'Товар не найден' ], 404); return; } // Validate rating if ($rating < 1 || $rating > 5) { $this->json([ 'success' => false, 'message' => 'Рейтинг должен быть от 1 до 5' ], 400); return; } // Check if user can review if (!$this->reviewModel->userCanReview($user['id'], $productId)) { $this->json([ 'success' => false, 'message' => 'Вы уже оставили отзыв на этот товар' ], 400); return; } // Create review $reviewId = $this->reviewModel->createReview([ 'product_id' => $productId, 'user_id' => $user['id'], 'rating' => $rating, 'comment' => $comment, 'is_approved' => true ]); if ($reviewId) { // Get updated product info $updatedProduct = $this->productModel->find($productId); $this->json([ 'success' => true, 'message' => 'Спасибо за ваш отзыв!', 'review_id' => $reviewId, 'product_rating' => $updatedProduct['rating'] ?? 0, 'product_review_count' => $updatedProduct['review_count'] ?? 0 ]); } else { $this->json([ 'success' => false, 'message' => 'Ошибка при создании отзыва' ], 500); } } /** * Update a review (POST /reviews/{id}) */ public function update(int $id): void { // Require authentication if (!$this->isAuthenticated()) { $this->json([ 'success' => false, 'message' => 'Требуется авторизация' ], 401); return; } $user = $this->getCurrentUser(); $review = $this->reviewModel->find($id); if (!$review) { $this->json([ 'success' => false, 'message' => 'Отзыв не найден' ], 404); return; } // Check ownership (only owner or admin can update) if ($review['user_id'] !== $user['id'] && !$this->isAdmin()) { $this->json([ 'success' => false, 'message' => 'У вас нет прав для редактирования этого отзыва' ], 403); return; } $rating = (int) $this->getPost('rating', 0); $comment = trim($this->getPost('comment', '')); // Validate rating if ($rating < 1 || $rating > 5) { $this->json([ 'success' => false, 'message' => 'Рейтинг должен быть от 1 до 5' ], 400); return; } // Update review $success = $this->reviewModel->updateReview($id, [ 'rating' => $rating, 'comment' => $comment ]); if ($success) { // Get updated product info $updatedProduct = $this->productModel->find($review['product_id']); $this->json([ 'success' => true, 'message' => 'Отзыв обновлен', 'product_rating' => $updatedProduct['rating'] ?? 0, 'product_review_count' => $updatedProduct['review_count'] ?? 0 ]); } else { $this->json([ 'success' => false, 'message' => 'Ошибка при обновлении отзыва' ], 500); } } /** * Delete a review (POST /reviews/{id}/delete) */ public function delete(int $id): void { // Require authentication if (!$this->isAuthenticated()) { $this->json([ 'success' => false, 'message' => 'Требуется авторизация' ], 401); return; } $user = $this->getCurrentUser(); $review = $this->reviewModel->find($id); if (!$review) { $this->json([ 'success' => false, 'message' => 'Отзыв не найден' ], 404); return; } // Check ownership (only owner or admin can delete) if ($review['user_id'] !== $user['id'] && !$this->isAdmin()) { $this->json([ 'success' => false, 'message' => 'У вас нет прав для удаления этого отзыва' ], 403); return; } $productId = $review['product_id']; $success = $this->reviewModel->deleteReview($id); if ($success) { // Get updated product info $updatedProduct = $this->productModel->find($productId); $this->json([ 'success' => true, 'message' => 'Отзыв удален', 'product_rating' => $updatedProduct['rating'] ?? 0, 'product_review_count' => $updatedProduct['review_count'] ?? 0 ]); } else { $this->json([ 'success' => false, 'message' => 'Ошибка при удалении отзыва' ], 500); } } /** * Get reviews for a product (GET /reviews/product/{id}) */ public function getByProduct(int $productId): void { $product = $this->productModel->find($productId); if (!$product) { $this->json([ 'success' => false, 'message' => 'Товар не найден' ], 404); return; } $reviews = $this->reviewModel->getByProduct($productId, true); $distribution = $this->reviewModel->getRatingDistribution($productId); $this->json([ 'success' => true, 'reviews' => $reviews, 'rating_distribution' => $distribution, 'average_rating' => $product['rating'] ?? 0, 'total_reviews' => $product['review_count'] ?? 0 ]); } /** * Toggle review approval (admin only) (POST /reviews/{id}/toggle-approval) */ public function toggleApproval(int $id): void { $this->requireAdmin(); $review = $this->reviewModel->find($id); if (!$review) { $this->json([ 'success' => false, 'message' => 'Отзыв не найден' ], 404); return; } $success = $this->reviewModel->toggleApproval($id); if ($success) { $updatedReview = $this->reviewModel->find($id); $this->json([ 'success' => true, 'message' => 'Статус отзыва изменен', 'is_approved' => $updatedReview['is_approved'] ]); } else { $this->json([ 'success' => false, 'message' => 'Ошибка при изменении статуса' ], 500); } } }