dgvai/laravel-user-review
Laravel package that adds user reviews and star/point ratings to any Eloquent model via a Reviewable trait. Users can create or update a single review per model, and admins can post one reply (Google Play–style). Includes migrations, config, rating averages & percent.
Installation
composer require dgvai/laravel-user-review
Publish the migration and config:
php artisan vendor:publish --provider="Dgvai\UserReview\UserReviewServiceProvider"
Run migrations:
php artisan migrate
Apply the Trait
Use the Reviewable trait on any model (e.g., Product, Service):
use Dgvai\UserReview\Traits\Reviewable;
class Product extends Model
{
use Reviewable;
}
First Use Case: Enable Reviews
Configure the model in config/user-review.php:
'models' => [
'Product' => \App\Models\Product::class,
],
Now users can submit reviews via a form (e.g., Blade template) targeting the model’s reviews() relationship.
Submitting a Review
Use the createReview() method on the reviewable model:
$product->createReview([
'user_id' => auth()->id(),
'rating' => 5,
'comment' => 'Great product!',
]);
Validate with the package’s built-in rules (extend via ReviewRequest in app/Http/Requests).
Admin Replies
Admins reply via createAdminReply():
$review->createAdminReply([
'admin_id' => auth()->id(),
'response' => 'Thank you for your feedback!',
]);
Displaying Reviews Fetch reviews with eager loading:
$product->load('reviews.user', 'reviews.adminReply');
Loop in Blade:
@foreach($product->reviews as $review)
<div class="review">
<p>Rating: {{ $review->rating }}/5</p>
<p>{{ $review->comment }}</p>
@if($review->adminReply)
<p class="admin-reply">{{ $review->adminReply->response }}</p>
@endif
</div>
@endforeach
Aggregating Ratings
Use the averageRating accessor:
$avgRating = $product->averageRating; // Returns float (e.g., 4.2)
ReviewRequest to add custom rules (e.g., min/max ratings).ReviewCreated or AdminReplyAdded to notify users/admins via Observers or Listeners.public function toArray($request)
{
return [
'rating' => $this->rating,
'comment' => $this->comment,
'user' => $this->user->name,
'admin_reply' => $this->adminReply?->response,
];
}
Migration Conflicts
reviews table already exists, drop it or manually adjust the migration. The package assumes a fresh setup.Model Binding Issues
id (default). Custom keys may require trait overrides.Admin Reply Uniqueness
Rating Scale Assumptions
getRatingScale() method in your model if using a different scale (e.g., 1–10).reviewable_id and reviewable_type columns are populated in the reviews table. Use:
$product->reviews()->withTrashed()->get(); // Include soft-deleted reviews
admin_id is set (not null) and the review_id matches. Use:
$review->fresh()->load('adminReply');
Custom Review Models
Override the default Review model by binding it in the service provider:
$this->app->bind(
Dgvai\UserReview\Contracts\Review::class,
App\Models\CustomReview::class
);
Additional Review Fields
Add columns to the reviews table (e.g., ip_address, device_info) and update the migration. Extend the Review model’s $fillable.
Multi-Language Support
Use Laravel’s localization for review fields (e.g., comment column). Store translations in a pivot table or JSON column.
Soft Deletes
Enable soft deletes for reviews by adding SoftDeletes to the Review model and configuring the deleted_at column in the migration.
config/user-review.php must list all models using the trait. Add dynamically if needed:
'models' => collect(config('user-review.models'))
->merge([App\Models\NewModel::class])
->toArray(),
admin_id field. Use a middleware to set this for admin routes:
public function handle($request, Closure $next)
{
if (auth()->user()->isAdmin()) {
request()->merge(['admin_id' => auth()->id()]);
}
return $next($request);
}
How can I help you explore Laravel packages today?