Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel User Review Laravel Package

gpablore/laravel-user-review

Add Google Play–style user reviews and star/point ratings to any Eloquent model via a simple trait. Users can leave one review with optional text; admins can post a single support reply. Includes migrations, config, and helpers for averages and percentages.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require dgvai/laravel-user-review
    
  2. Publish Config & Migrations

    php artisan vendor:publish --provider="DGvai\Review\ReviewerServiceProvider"
    php artisan migrate
    php artisan config:cache
    
  3. Apply the Trait Add Reviewable to your model (e.g., Product, Service):

    use DGvai\Review\Traits\Reviewable;
    
    class Product extends Model
    {
        use Reviewable;
    }
    
  4. First Review Submission Use the submitReview() method in a controller:

    $review = $product->submitReview([
        'rating' => 5, // Required (1-5 stars)
        'comment' => 'Great product!',
        'user_id' => auth()->id(), // Auto-fetched if using middleware
    ]);
    

Implementation Patterns

Core Workflows

  1. Review Submission

    • User Flow: Authenticated users submit reviews via a form (e.g., Blade template with CSRF protection).
    • Validation: The trait handles basic validation (e.g., rating between 1–5, comment max length).
    • Example Controller:
      public function store(Request $request, $model, $id)
      {
          $modelInstance = $model::findOrFail($id);
          $review = $modelInstance->submitReview($request->all() + ['user_id' => auth()->id()]);
          return redirect()->back()->with('success', 'Review submitted!');
      }
      
  2. Admin Replies

    • Single Response: Admins reply once per review via replyToReview():
      $review->replyToReview(['response' => 'Thank you for your feedback!']);
      
    • UI Integration: Use hasAdminReply() to toggle reply visibility in Blade:
      @if($review->hasAdminReply())
          <div class="admin-reply">{{ $review->adminReply->response }}</div>
      @endif
      
  3. Displaying Reviews

    • Model Methods:
      • $product->reviews → Collection of all reviews.
      • $product->averageRating → Float (e.g., 4.2).
      • $product->starRating() → HTML string (e.g., <div class="stars">★★★★☆</div>).
    • Blade Example:
      <div class="reviews">
          @foreach($product->reviews as $review)
              <div class="review">
                  <div class="rating">{{ $review->starRating() }}</div>
                  <p>{{ $review->comment }}</p>
                  @include('partials.admin-reply', ['review' => $review])
              </div>
          @endforeach
      </div>
      
  4. API Integration

    • Resource Example:
      public function toArray($request)
      {
          return [
              'id' => $this->id,
              'rating' => $this->rating,
              'comment' => $this->comment,
              'admin_reply' => $this->adminReply?->response,
              'created_at' => $this->created_at->diffForHumans(),
          ];
      }
      

Gotchas and Tips

Pitfalls

  1. Missing Middleware

    • Issue: submitReview() expects auth()->id() to be set. Unauthenticated users will fail silently.
    • Fix: Add middleware to routes:
      Route::middleware(['auth'])->group(function () {
          Route::post('/products/{product}/reviews', [ReviewController::class, 'store']);
      });
      
  2. Duplicate Reviews

    • Issue: The trait lacks built-in deduplication (e.g., same user reviewing twice).
    • Workaround: Add a unique constraint in the migration or validate in the controller:
      $validated = $request->validate([
          'user_id' => 'required|exists:users,id',
      ], [
          'user_id.unique' => 'You have already reviewed this item.',
      ]);
      
  3. Admin Reply Overwrite

    • Issue: replyToReview() overwrites existing replies without warning.
    • Mitigation: Add a check in your controller:
      if ($review->adminReply) {
          return back()->with('error', 'Reply already exists.');
      }
      

Debugging

  1. Missing Database Tables

    • Symptom: submitReview() fails with SQLSTATE[42S02].
    • Solution: Run migrations again or check config/review.php for table names.
  2. Rating Calculation Errors

    • Symptom: averageRating returns null or incorrect values.
    • Debug: Verify the reviews relationship in your model:
      public function reviews()
      {
          return $this->hasMany(Review::class);
      }
      

Extension Points

  1. Custom Review Model

    • Use Case: Extend the default Review model (e.g., add ip_address for fraud detection).
    • Implementation: Override the trait’s getReviewModel() method:
      class Product extends Model
      {
          use Reviewable;
      
          protected function getReviewModel()
          {
              return \App\Models\CustomReview::class;
          }
      }
      
  2. Dynamic Rating Scales

    • Use Case: Allow 1–10 ratings instead of 1–5.
    • Solution: Override the trait’s validation logic:
      protected function getRatingRules()
      {
          return ['rating' => 'required|integer|min:1|max:10'];
      }
      
  3. Soft Deletes for Reviews

    • Use Case: Soft-delete reviews instead of hard deletes.
    • Implementation: Add SoftDeletes to the Review model and update the trait’s delete() method:
      use Illuminate\Database\Eloquent\SoftDeletes;
      
      class Review extends Model
      {
          use SoftDeletes;
      }
      
  4. Localization

    • Use Case: Support non-English comments or admin replies.
    • Tip: Use Laravel’s localization features and store comment/response as JSON:
      $review->comment = ['en' => 'Great!', 'es' => '¡Excelente!'];
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours