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

Reviewmaster Laravel Package

beksos/reviewmaster

Laravel package to add user reviews and star/point ratings to any Eloquent model via a Reviewable trait. Supports configurable user model and a single admin reply per review (Google Play-style). Includes migrations, config publishing, and helper methods like makeReview().

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require beksos/reviewmaster
    

    Publish the migration and config:

    php artisan vendor:publish --provider="BechirAhmed\Reviewmaster\ReviewmasterServiceProvider" --tag="migrations"
    php artisan vendor:publish --provider="BechirAhmed\Reviewmaster\ReviewmasterServiceProvider" --tag="config"
    

    Run the migration:

    php artisan migrate
    
  2. Configure Models Add HasReviews trait to your model (e.g., Product):

    use BechirAhmed\Reviewmaster\Traits\HasReviews;
    
    class Product extends Model
    {
        use HasReviews;
    }
    
  3. First Review Create a review for a product:

    $product = Product::find(1);
    $review = $product->reviews()->create([
        'user_id' => auth()->id(),
        'rating' => 5,
        'comment' => 'Great product!',
    ]);
    
  4. Display Reviews Fetch and display reviews for a product:

    $reviews = Product::find(1)->reviews()->with('user')->get();
    

Implementation Patterns

Core Workflows

  1. Review Creation

    • Use createReview() helper method on models:
      $product->createReview($request->all());
      
    • Validate input via ReviewRequest (if provided in the package).
  2. Aggregating Ratings

    • Get average rating for a model:
      $avgRating = $product->averageRating;
      
    • Get total reviews count:
      $reviewCount = $product->reviewCount;
      
  3. Filtering & Sorting

    • Filter reviews by rating:
      $highRated = $product->reviews()->where('rating', '>=', 4)->get();
      
    • Sort by newest first:
      $recentReviews = $product->reviews()->latest()->get();
      
  4. User-Specific Logic

    • Check if a user has reviewed a model:
      $product->hasReviewFrom(auth()->id());
      
    • Prevent duplicate reviews (e.g., in a form request):
      $this->validate($request, [
          'rating' => 'required|integer|min:1|max:5',
          // ...
      ]);
      
  5. API Responses

    • Serialize reviews with relationships:
      return Product::with(['reviews.user'])->find($id);
      
    • Use resource classes (e.g., ReviewResource) if provided.

Integration Tips

  1. Blade Views Loop through reviews in a template:

    @foreach($product->reviews as $review)
        <div class="review">
            <p>Rating: {{ $review->rating }}/5</p>
            <p>{{ $review->comment }}</p>
            <small>By {{ $review->user->name }}</small>
        </div>
    @endforeach
    
  2. Admin Panels

    • Filter reviews in admin interfaces (e.g., Nova, Filament):
      $reviews = Review::query()
          ->whereHas('reviewable', function ($q) {
              $q->where('type', Product::class);
          })->get();
      
  3. Notifications

    • Trigger notifications when a review is added:
      event(new ReviewCreated($review));
      
  4. Caching

    • Cache aggregated ratings (e.g., averageRating) to reduce DB load:
      Cache::remember("product_{$product->id}_rating", now()->addHours(1), function () use ($product) {
          return $product->averageRating;
      });
      
  5. Testing

    • Test review creation and aggregation:
      $product = Product::factory()->create();
      $product->createReview(['rating' => 5, 'comment' => 'Test']);
      $this->assertEquals(5, $product->fresh()->averageRating);
      

Gotchas and Tips

Pitfalls

  1. Missing Foreign Key

    • Ensure the reviewable_id and reviewable_type columns exist in the reviews table. If not, re-run migrations or manually add them:
      Schema::table('reviews', function (Blueprint $table) {
          $table->unsignedBigInteger('reviewable_id');
          $table->string('reviewable_type');
      });
      
  2. Polymorphic Relationships

    • The package uses Laravel’s polymorphic relationships. If your model doesn’t support it, add:
      public function reviews()
      {
          return $this->morphMany(Review::class, 'reviewable');
      }
      
  3. User Association

    • The user_id field is assumed to exist in the reviews table. If not, add it to the migration or config.
  4. Rating Validation

    • Default validation may not cover all cases (e.g., non-integer ratings). Extend the ReviewRequest or add custom validation:
      $this->validate($request, ['rating' => 'required|integer|between:1,5']);
      
  5. Soft Deletes

    • If your models use soft deletes, ensure the reviews table also has a deleted_at column and the relationship accounts for it:
      return $this->morphMany(Review::class, 'reviewable')->withTrashed();
      

Debugging

  1. Query Logs

    • Enable query logging to debug relationship issues:
      DB::enableQueryLog();
      $product->reviews; // Trigger the relationship
      dd(DB::getQueryLog());
      
  2. Common Errors

    • "Reviewable model not found": Verify the reviewable_type matches your model’s class name (e.g., App\Models\Product).
    • "Column not found": Check if the reviews table columns match the migration (e.g., rating, comment, user_id).
  3. Seeding

    • Seed reviews for testing:
      $product = Product::factory()->create();
      Review::factory()->count(5)->create(['reviewable_id' => $product->id, 'reviewable_type' => Product::class]);
      

Extension Points

  1. Custom Review Models

    • Extend the Review model to add fields (e.g., helpful_votes):
      class Review extends \BechirAhmed\Reviewmaster\Models\Review
      {
          protected $fillable = ['helpful_votes', ...];
      }
      
  2. Custom Validation

    • Override the validation logic in a form request:
      public function rules()
      {
          return [
              'rating' => 'required|integer|min:1|max:5|not_in:0',
              'comment' => 'required|string|max:1000',
          ];
      }
      
  3. Custom Aggregations

    • Add custom accessors to models:
      public function getPositiveRatingPercentageAttribute()
      {
          return $this->reviews()->where('rating', '>=', 4)->count() / $this->reviewCount * 100;
      }
      
  4. Events

    • Listen for review events to trigger actions:
      ReviewCreated::subscribe(function ($review) {
          // Send email, update analytics, etc.
      });
      
  5. API Resources

    • Customize the ReviewResource to hide sensitive data:
      public function toArray($request)
      {
          return [
              'id' => $this->id,
              'rating' => $this->rating,
              'comment' => Str::limit($this->comment, 100),
              'user' => UserResource::make($this->whenLoaded('user')),
          ];
      }
      

Config Quirks

  1. Reviewable Models

    • The config/reviewmaster.php may define allowed reviewable models. Ensure your model is listed:
      'models' => [
          'product' => \App\Models\Product::class,
      ],
      
  2. Default Values

    • Override default review settings (e.g., max rating) in the config:
      'max_rating' => 5,
      'min_rating' => 1,
      
  3. Guard Clauses

    • The package may assume certain guard clauses (e.g., preventing non-authenticated users from reviewing). Adjust in middleware or policies if needed.
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui