NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Reviews for Laravel

Moderation lifecycle

Every review has a ReviewStatus of Pending, Approved or Rejected. New reviews are pending unless auto_approve is enabled, the builder called approved(), or the moderator approved them.

use RoundlyConsulting\Reviews\Facades\Reviews;

Reviews::approve($review);            // marks approved, stamps approved_at
Reviews::reject($review, 'Spam');     // marks rejected, stores the reason in meta

$review->isPending();
$review->isApproved();
$review->isRejected();

$review->meta?->get('rejection_reason'); // 'Spam'
  • approve() sets the status to approved, stamps approved_at and fires ReviewApproved.
  • reject() sets the status to rejected, clears approved_at, stores an optional reason under meta.rejection_reason and fires ReviewRejected with that reason.
  • Both are idempotent — approving an approved review (or rejecting a rejected one) changes nothing and fires no event.
  • Approving a rejected review drops its stale rejection_reason.
  • A review that lands approved or rejected on create or after an edit fires the same events.

A moderation queue

Reviews::query() covers every subject and respects a swapped reviews.model:

use RoundlyConsulting\Reviews\Facades\Reviews;

// The moderation queue — every subject, oldest first, owner responses excluded:
$queue = Reviews::query()->pending()->topLevel()->oldest()->paginate(20);

// Or newest first, as the README does:
Reviews::query()->pending()->latestFirst()->paginate();

Auto-approve

For trusted setups, REVIEWS_AUTO_APPROVE=true approves every new — and re-moderated, edited — review immediately and skips the moderator. To trust only some reviews, approve them per call with ->approved() on the builder.

The status enum

ReviewStatus and ModerationDecision use the Enums for Laravel helpers, so you get values(), labels(), options(), toOptions(), validationRule(), readable() and case lookups for free:

use RoundlyConsulting\Reviews\Enums\ReviewStatus;

$review->status;                       // ReviewStatus::Pending
$review->status->isApproved();         // bool

ReviewStatus::values();                // collect(['pending', 'approved', 'rejected'])
ReviewStatus::validationRule();        // 'in:pending,approved,rejected'
ReviewStatus::toOptions();             // value => label map for select inputs
ReviewStatus::Approved->readable();    // 'Approved'

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.