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

Each comment carries a status — pending, approved or hidden — backed by the CommentStatus enum. By default new comments are approved immediately; set require_approval (COMMENTS_REQUIRE_APPROVAL=true) to hold them for review:

use RoundlyConsulting\Comments\Facades\Comments;

Comments::approve($comment); // status → approved, dispatches CommentApproved
Comments::hide($comment);    // status → hidden,   dispatches CommentHidden

A held comment notifies nobody it mentions: approving it fires CommentMentioned for each resolved mention, once per person — see @mentions.

Moderation queues

A site-wide moderation queue — every subject at once — starts from Comments::query():

use RoundlyConsulting\Comments\Facades\Comments;

Comments::query()->pending()->mostReported()->paginate();   // every subject at once
Comments::query()->pending()->approveAll();

Plain query scopes on the Comment model work too:

use RoundlyConsulting\Comments\Models\Comment;

Comment::pending()->get();  // awaiting review
Comment::approved()->get(); // approved
Comment::hidden()->get();   // hidden
Comment::visible()->get();  // visible === true AND status === approved
Comment::roots()->get();    // top-level comments only

The visible flag and the status are independent: a comment is publicly shown only when visible is true and the status is approved — exactly what the visible() scope and approvedComments check.

Bulk moderation

The fluent query moderates everything it matches. Each terminal walks the matches by primary key and runs every row through the manager — so the policy, the lifecycle event and Comments::fake() see each comment — and returns how many were affected:

// Bulk moderation — each row runs through the manager, so the policy, the lifecycle
// event and Comments::fake() all see every comment:
Comments::for($post)->pending()->approveAll(); // int: comments approved
Comments::byAuthor($user)->hideAll();          // int: comments hidden
Comments::for($post)->deleteAll();             // int: comments soft-deleted

The status enum

use RoundlyConsulting\Comments\Enums\CommentStatus;

$comment->status === CommentStatus::Pending;

CommentStatus::values()->all();    // ['pending', 'approved', 'hidden']
CommentStatus::labels()->all();    // ['Pending', 'Approved', 'Hidden']
CommentStatus::options();          // Collection of options (value, label, name)
CommentStatus::validationRule();   // 'in:pending,approved,hidden'
CommentStatus::Hidden->readable(); // 'Hidden'

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.