shubraVeil/includes/Review.php
2024-12-25 14:31:31 +02:00

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
]
);
}
}
}