Skip to content

Commit 9614ff2

Browse files
committed
Wip
1 parent 136b8f2 commit 9614ff2

File tree

5 files changed

+356
-16
lines changed

5 files changed

+356
-16
lines changed

README.md

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -133,46 +133,79 @@ $product->addReview([
133133

134134
### Update a rating
135135
```php
136-
// In Progress
136+
// Retrieve the product you want to update the review for.
137+
$product = Product::findOrFail(1);
138+
139+
// Prepare the updated data.
140+
$data = [
141+
'review' => 'Updated review text', // New review text.
142+
'department' => 'default', // Optionally, change the department.
143+
'recommend' => false, // Update recommendation flag.
144+
'approved' => true, // Update approval status if needed.
145+
'ratings' => [
146+
'overall' => 4,
147+
'communication' => 3,
148+
'follow_up' => 4,
149+
'price' => 2,
150+
],
151+
];
152+
153+
// Call the updateReview method on the product.
154+
$product->updateReview($reviewId, $data);
137155
```
138156
### Marking review as approved
139157
```php
140-
// Inm progress
158+
// Retrieve the product you want to mark as approved
159+
$product = Product::findOrFail(1);
160+
161+
// Approve th review
162+
$product->approveReview($reviewId);
141163
```
142-
### Delete a rating:
164+
### Delete a review/rating:
143165
```php
144-
// Inm progress
166+
// Retrieve the product with the review you want to delete
167+
$product = Product::findOrFail(1);
168+
169+
// Delete the review
170+
$product->deleteReview($reviewId);
145171
```
146172

147173
### Fetch approved or not approved reviews/ratings for a particular resource
148174
```php
149-
// Inm progress
175+
// Approved reviews with ratings
176+
$product = Product::findOrFail($postId);
177+
178+
// Get approved reviews (with related ratings)
179+
// Default: approved = true, withRatings = true
180+
$product->getReviews();
181+
182+
// Get not approved reviews (with related ratings)
183+
$product->getReviews(false);
184+
$product->getReviews(approved: false);
185+
186+
// Get approved reviews (without related ratings)
187+
$product->getReviews(true, false);
188+
$product->getReviews(withRatings: false);
150189
```
151190
### Fetch the average rating:
152191
````php
153-
// Inm progress
192+
// In progress
154193
````
155194

156195
or
157196

158197
````php
159-
// Inm progress
198+
// In progress
160199
````
161200

162201
### Get all ratings:
163202
```php
164-
// Inm progress
203+
// In progress
165204
```
166205

167206
### Count total rating:
168207
````php
169-
// Inm progress
170-
````
171-
172-
### Fetch the rating percentage.
173-
This is also how you enforce a maximum rating value.
174-
````php
175-
// Inm progress
208+
// In progress
176209
````
177210

178211
### Notes

src/Contracts/ReviewRateableContract.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,23 @@ public function setModel(mixed $model): self;
2323
*/
2424
public function addReview(array $data, ?int $userId = null): mixed;
2525

26+
/**
27+
* Update a review by its ID.
28+
*
29+
* @param int $reviewId
30+
* @param array $data
31+
* @return bool
32+
*/
33+
public function updateReview(int $reviewId, array $data): bool;
34+
35+
/**
36+
* Mark a review as approved by its ID.
37+
*
38+
* @param int $reviewId
39+
* @return bool
40+
*/
41+
public function approveReview(int $reviewId): bool;
42+
2643
/**
2744
* Get the average rating for a given key.
2845
*
@@ -83,4 +100,13 @@ public function totalReviews(bool $approved = true): int;
83100
* @return float|null
84101
*/
85102
public function overallAverageRating(bool $approved = true): ?float;
103+
104+
/**
105+
* Delete a review.
106+
*
107+
* @param int $reviewId
108+
* @return bool
109+
*/
110+
public function deleteReview(int $reviewId): bool;
111+
86112
}

src/Services/ReviewRateableService.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,34 @@ public function addReview(array $data, ?int $userId = null): ReviewRateableContr
5252
return $this->getModel()->addReview($data, $userId);
5353
}
5454

55+
/**
56+
* Update a review and its ratings by review ID.
57+
*
58+
* The $data array can include:
59+
* - 'review': New review text.
60+
* - 'department': New department key.
61+
* - 'recommend': New recommendation flag.
62+
* - 'approved': New approval status.
63+
* - 'ratings': An associative array of rating values (key => value).
64+
*
65+
* @param int $reviewId
66+
* @param array $data
67+
* @return bool True on success, false if the review was not found.
68+
* @throws Exception
69+
*/
70+
public function updateReview(int $reviewId, array $data): bool
71+
{
72+
return $this->getModel()->updateReview($reviewId, $data);
73+
}
74+
75+
/**
76+
* Delegate approving a review.
77+
*/
78+
public function approveReview(int $reviewId): bool
79+
{
80+
return $this->getModel()->approveReview($reviewId);
81+
}
82+
5583
/**
5684
* Delegate averageRating calculation to the model.
5785
*
@@ -140,4 +168,15 @@ public function overallAverageRating(bool $approved = true): ?float
140168
{
141169
return $this->getModel()->overallAverageRating($approved);
142170
}
171+
172+
/**
173+
* @param int $reviewId
174+
* @return bool
175+
* @throws Exception
176+
*/
177+
public function deleteReview(int $reviewId): bool
178+
{
179+
return $this->getModel()->deleteReview($reviewId);
180+
}
181+
143182
}

src/Traits/ReviewRateable.php

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,99 @@ public function addReview(array $data, ?int $userId = null): Review
7979
return $review;
8080
}
8181

82+
/**
83+
* Update a review and its ratings by review ID.
84+
*
85+
* The $data array can include:
86+
* - 'review': New review text.
87+
* - 'department': New department key.
88+
* - 'recommend': New recommendation flag.
89+
* - 'approved': New approval status.
90+
* - 'ratings': An associative array of rating values (key => value).
91+
*
92+
* @param int $reviewId
93+
* @param array $data
94+
* @return bool True on success, false if the review was not found.
95+
*/
96+
public function updateReview(int $reviewId, array $data): bool
97+
{
98+
$review = $this->reviews()->find($reviewId);
99+
100+
if (!$review) {
101+
return false;
102+
}
103+
104+
// Prepare attributes for the review update.
105+
$attributes = [];
106+
if (isset($data['review'])) {
107+
$attributes['review'] = $data['review'];
108+
}
109+
if (isset($data['department'])) {
110+
$attributes['department'] = $data['department'];
111+
}
112+
if (isset($data['recommend'])) {
113+
$attributes['recommend'] = $data['recommend'];
114+
}
115+
if (isset($data['approved'])) {
116+
$attributes['approved'] = $data['approved'];
117+
}
118+
if (!empty($attributes)) {
119+
$review->update($attributes);
120+
}
121+
122+
// Update ratings if provided.
123+
if (isset($data['ratings']) && is_array($data['ratings'])) {
124+
// Determine which department's rating keys to use.
125+
$department = $attributes['department'] ?? $review->department;
126+
$departments = config('review-rateable.departments', []);
127+
$configRatings = $departments[$department]['ratings'] ?? [];
128+
129+
// Get global min and max rating values.
130+
$min = config('review-rateable.min_rating_value', 1);
131+
$max = config('review-rateable.max_rating_value', 10);
132+
133+
foreach ($data['ratings'] as $key => $value) {
134+
if ($value < $min) {
135+
$value = $min;
136+
} elseif ($value > $max) {
137+
$value = $max;
138+
}
139+
140+
$rating = $review->ratings()->where('key', $key)->first();
141+
if ($rating) {
142+
$rating->update(['value' => $value]);
143+
} else {
144+
if (array_key_exists($key, $configRatings)) {
145+
$review->ratings()->create(['key' => $key, 'value' => $value]);
146+
}
147+
}
148+
}
149+
}
150+
151+
return true;
152+
}
153+
154+
/**
155+
* Mark a review as approved by its ID.
156+
*
157+
* @param int $reviewId
158+
* @return bool True if the update was successful, false if the review was not found.
159+
*/
160+
public function approveReview(int $reviewId): bool
161+
{
162+
$review = $this->reviews()->find($reviewId);
163+
if (!$review) {
164+
return false;
165+
}
166+
return $review->update(['approved' => true]);
167+
}
168+
82169
/**
83170
* Get all reviews (with attached ratings) for the model,
84171
* filtered by the approved status.
85172
*
86-
* @param bool $approved
173+
* @param bool $approved
174+
* @param bool $withRatings
87175
* @return Collection
88176
*/
89177
public function getReviews(bool $approved = true, bool $withRatings = true): Collection
@@ -238,4 +326,22 @@ public function overallAverageRating(bool $approved = true): ?float
238326

239327
return $ratings->avg('value');
240328
}
329+
330+
/**
331+
* Delete a review by its ID.
332+
*
333+
* @param int $reviewId
334+
* @return bool True if the review was deleted, false otherwise.
335+
*/
336+
public function deleteReview(int $reviewId): bool
337+
{
338+
$review = $this->reviews()->find($reviewId);
339+
340+
if ($review) {
341+
return $review->delete();
342+
}
343+
344+
return false;
345+
}
346+
241347
}

0 commit comments

Comments
 (0)