feat(data): add review repository
This commit is contained in:
1 parent
e2dbd78cc9
commit
0be2439890
1 file changed
+108
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Bazaar\Repositories;
|
||||
|
||||
use Bazaar\Core\Database;
|
||||
|
||||
final class ReviewRepository
|
||||
{
|
||||
public function __construct(private readonly Database $db)
|
||||
{
|
||||
}
|
||||
|
||||
public function create(int $productId, int $userId, int $rating, string $title, string $body): int
|
||||
{
|
||||
return $this->db->insert(
|
||||
'INSERT INTO reviews (productId, userId, rating, title, body, status, createdAt)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||
[$productId, $userId, $rating, $title, $body, 'pending', gmdate('c')]
|
||||
);
|
||||
}
|
||||
|
||||
public function find(int $id): ?array
|
||||
{
|
||||
return $this->db->selectOne('SELECT * FROM reviews WHERE id = ?', [$id]);
|
||||
}
|
||||
|
||||
public function existsForUser(int $productId, int $userId): bool
|
||||
{
|
||||
return (int) $this->db->scalar(
|
||||
'SELECT COUNT(*) FROM reviews WHERE productId = ? AND userId = ?',
|
||||
[$productId, $userId]
|
||||
) > 0;
|
||||
}
|
||||
|
||||
public function approvedForProduct(int $productId): array
|
||||
{
|
||||
return $this->db->select(
|
||||
'SELECT r.*, u.name AS authorName
|
||||
FROM reviews r
|
||||
JOIN users u ON u.id = r.userId
|
||||
WHERE r.productId = ? AND r.status = ?
|
||||
ORDER BY r.createdAt DESC, r.id DESC',
|
||||
[$productId, 'approved']
|
||||
);
|
||||
}
|
||||
|
||||
public function summary(int $productId): array
|
||||
{
|
||||
$row = $this->db->selectOne(
|
||||
'SELECT COUNT(*) AS reviewCount, COALESCE(AVG(rating), 0) AS average
|
||||
FROM reviews WHERE productId = ? AND status = ?',
|
||||
[$productId, 'approved']
|
||||
);
|
||||
return [
|
||||
'count' => (int) $row['reviewCount'],
|
||||
'average' => round((float) $row['average'], 2),
|
||||
];
|
||||
}
|
||||
|
||||
public function summaries(array $productIds): array
|
||||
{
|
||||
if ($productIds === []) {
|
||||
return [];
|
||||
}
|
||||
$placeholders = implode(', ', array_fill(0, count($productIds), '?'));
|
||||
$rows = $this->db->select(
|
||||
"SELECT productId, COUNT(*) AS reviewCount, COALESCE(AVG(rating), 0) AS average
|
||||
FROM reviews
|
||||
WHERE status = 'approved' AND productId IN ({$placeholders})
|
||||
GROUP BY productId",
|
||||
$productIds
|
||||
);
|
||||
$byProduct = [];
|
||||
foreach ($rows as $row) {
|
||||
$byProduct[(int) $row['productId']] = [
|
||||
'count' => (int) $row['reviewCount'],
|
||||
'average' => round((float) $row['average'], 2),
|
||||
];
|
||||
}
|
||||
return $byProduct;
|
||||
}
|
||||
|
||||
public function moderationQueue(string $status = 'pending'): array
|
||||
{
|
||||
return $this->db->select(
|
||||
'SELECT r.*, u.name AS authorName, u.email AS authorEmail, p.name AS productName, p.slug AS productSlug
|
||||
FROM reviews r
|
||||
JOIN users u ON u.id = r.userId
|
||||
JOIN products p ON p.id = r.productId
|
||||
WHERE r.status = ?
|
||||
ORDER BY r.createdAt ASC, r.id ASC',
|
||||
[$status]
|
||||
);
|
||||
}
|
||||
|
||||
public function setStatus(int $id, string $status): void
|
||||
{
|
||||
$this->db->statement(
|
||||
'UPDATE reviews SET status = ?, moderatedAt = ? WHERE id = ?',
|
||||
[$status, gmdate('c'), $id]
|
||||
);
|
||||
}
|
||||
|
||||
public function countByStatus(string $status): int
|
||||
{
|
||||
return (int) $this->db->scalar('SELECT COUNT(*) FROM reviews WHERE status = ?', [$status]);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user