194 lines
6.8 KiB
PHP
194 lines
6.8 KiB
PHP
<?php
|
|
class Review {
|
|
private $db;
|
|
private $notification;
|
|
|
|
public function __construct($db, $notification) {
|
|
$this->db = $db;
|
|
$this->notification = $notification;
|
|
}
|
|
|
|
public function addReview($user_id, $product_id, $rating, $comment, $images = []) {
|
|
// Start transaction
|
|
$this->db->begin_transaction();
|
|
|
|
try {
|
|
// Add review
|
|
$stmt = $this->db->prepare("INSERT INTO reviews (user_id, product_id, rating, comment, created_at) VALUES (?, ?, ?, ?, NOW())");
|
|
$stmt->bind_param('iiis', $user_id, $product_id, $rating, $comment);
|
|
$stmt->execute();
|
|
$review_id = $stmt->insert_id;
|
|
|
|
// Add review images if any
|
|
if (!empty($images)) {
|
|
$stmt = $this->db->prepare("INSERT INTO review_images (review_id, image_path) VALUES (?, ?)");
|
|
foreach ($images as $image) {
|
|
$stmt->bind_param('is', $review_id, $image);
|
|
$stmt->execute();
|
|
}
|
|
}
|
|
|
|
// Update product rating
|
|
$this->updateProductRating($product_id);
|
|
|
|
// Notify product owner
|
|
$this->notifyProductOwner($product_id, $user_id, $rating);
|
|
|
|
$this->db->commit();
|
|
return $review_id;
|
|
|
|
} catch (\Exception $e) {
|
|
$this->db->rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function getProductReviews($product_id, $limit = 10, $offset = 0) {
|
|
$stmt = $this->db->prepare("
|
|
SELECT r.*, u.username, u.avatar,
|
|
GROUP_CONCAT(ri.image_path) as images
|
|
FROM reviews r
|
|
LEFT JOIN users u ON r.user_id = u.id
|
|
LEFT JOIN review_images ri ON r.id = ri.review_id
|
|
WHERE r.product_id = ?
|
|
GROUP BY r.id
|
|
ORDER BY r.created_at DESC
|
|
LIMIT ? OFFSET ?
|
|
");
|
|
$stmt->bind_param('iii', $product_id, $limit, $offset);
|
|
$stmt->execute();
|
|
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
|
|
}
|
|
|
|
public function getUserReviews($user_id, $limit = 10, $offset = 0) {
|
|
$stmt = $this->db->prepare("
|
|
SELECT r.*, p.name as product_name, p.image as product_image,
|
|
GROUP_CONCAT(ri.image_path) as images
|
|
FROM reviews r
|
|
LEFT JOIN products p ON r.product_id = p.id
|
|
LEFT JOIN review_images ri ON r.id = ri.review_id
|
|
WHERE r.user_id = ?
|
|
GROUP BY r.id
|
|
ORDER BY r.created_at DESC
|
|
LIMIT ? OFFSET ?
|
|
");
|
|
$stmt->bind_param('iii', $user_id, $limit, $offset);
|
|
$stmt->execute();
|
|
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
|
|
}
|
|
|
|
public function updateReview($review_id, $user_id, $rating, $comment, $images = []) {
|
|
$this->db->begin_transaction();
|
|
|
|
try {
|
|
// Update review
|
|
$stmt = $this->db->prepare("UPDATE reviews SET rating = ?, comment = ?, updated_at = NOW() WHERE id = ? AND user_id = ?");
|
|
$stmt->bind_param('isii', $rating, $comment, $review_id, $user_id);
|
|
$stmt->execute();
|
|
|
|
// Update images
|
|
if (!empty($images)) {
|
|
// Delete old images
|
|
$stmt = $this->db->prepare("DELETE FROM review_images WHERE review_id = ?");
|
|
$stmt->bind_param('i', $review_id);
|
|
$stmt->execute();
|
|
|
|
// Add new images
|
|
$stmt = $this->db->prepare("INSERT INTO review_images (review_id, image_path) VALUES (?, ?)");
|
|
foreach ($images as $image) {
|
|
$stmt->bind_param('is', $review_id, $image);
|
|
$stmt->execute();
|
|
}
|
|
}
|
|
|
|
// Update product rating
|
|
$stmt = $this->db->prepare("SELECT product_id FROM reviews WHERE id = ?");
|
|
$stmt->bind_param('i', $review_id);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result()->fetch_assoc();
|
|
$this->updateProductRating($result['product_id']);
|
|
|
|
$this->db->commit();
|
|
return true;
|
|
|
|
} catch (\Exception $e) {
|
|
$this->db->rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function deleteReview($review_id, $user_id) {
|
|
$this->db->begin_transaction();
|
|
|
|
try {
|
|
// Get product_id before deletion
|
|
$stmt = $this->db->prepare("SELECT product_id FROM reviews WHERE id = ? AND user_id = ?");
|
|
$stmt->bind_param('ii', $review_id, $user_id);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result()->fetch_assoc();
|
|
|
|
if (!$result) {
|
|
throw new \Exception('Review not found or unauthorized');
|
|
}
|
|
|
|
// Delete review images
|
|
$stmt = $this->db->prepare("DELETE FROM review_images WHERE review_id = ?");
|
|
$stmt->bind_param('i', $review_id);
|
|
$stmt->execute();
|
|
|
|
// Delete review
|
|
$stmt = $this->db->prepare("DELETE FROM reviews WHERE id = ? AND user_id = ?");
|
|
$stmt->bind_param('ii', $review_id, $user_id);
|
|
$stmt->execute();
|
|
|
|
// Update product rating
|
|
$this->updateProductRating($result['product_id']);
|
|
|
|
$this->db->commit();
|
|
return true;
|
|
|
|
} catch (\Exception $e) {
|
|
$this->db->rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
private function updateProductRating($product_id) {
|
|
$stmt = $this->db->prepare("
|
|
UPDATE products p
|
|
SET rating = (
|
|
SELECT AVG(rating)
|
|
FROM reviews
|
|
WHERE product_id = ?
|
|
)
|
|
WHERE id = ?
|
|
");
|
|
$stmt->bind_param('ii', $product_id, $product_id);
|
|
$stmt->execute();
|
|
}
|
|
|
|
private function notifyProductOwner($product_id, $reviewer_id, $rating) {
|
|
$stmt = $this->db->prepare("SELECT user_id FROM products WHERE id = ?");
|
|
$stmt->bind_param('i', $product_id);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result()->fetch_assoc();
|
|
|
|
if ($result) {
|
|
$message = $rating >= 4
|
|
? "Someone left a positive review on your product!"
|
|
: "You received a new review on your product.";
|
|
|
|
$this->notification->createNotification(
|
|
$result['user_id'],
|
|
'product_review',
|
|
$message,
|
|
[
|
|
'product_id' => $product_id,
|
|
'reviewer_id' => $reviewer_id,
|
|
'rating' => $rating
|
|
]
|
|
);
|
|
}
|
|
}
|
|
}
|