›
›
›
  1. docs
  2. ›
  3. byrcsc/laravel-comments
1.x
Browse documentationOpenClose

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Commentable models
  • Threads and replies
  • Moderation
  • Initial status
  • Pinning
  • Reactions
  • Edits and revisions
  • Attachments
  • Deleting comments

Operations

  • Comment counts
  • Events and listeners
  • Reply notifications
  • Authorization
  • Rendering and safety

Reference

  • Configuration
  • Console commands
  • Testing
  • Troubleshooting

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Commentable models
  • Threads and replies
  • Moderation
  • Initial status
  • Pinning
  • Reactions
  • Edits and revisions
  • Attachments
  • Deleting comments

Operations

  • Comment counts
  • Events and listeners
  • Reply notifications
  • Authorization
  • Rendering and safety

Reference

  • Configuration
  • Console commands
  • Testing
  • Troubleshooting

byrcsc/laravel-comments · 1.x

Commentable models.

Add comments to an Eloquent model and use the relationships provided by HasComments.

Any Eloquent model becomes commentable by adding one trait. This page covers what that trait gives you and what a comment row holds.

use ByRcsc\LaravelComments\Concerns\HasComments;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasComments;
}

There is no registration step and no interface to implement. The trait adds a polymorphic relation and two write methods.

Write a comment

comment() takes a body and the model writing it:

$comment = $post->comment('Great write-up!', by: $user);

$by is any Eloquent model. The package stores commentator_type and commentator_id as a morph and never assumes a user class.

commentAsGuest() takes a name and an email instead:

$comment = $post->commentAsGuest(
    'Where can I download the slides?',
    name: 'Jane',
    email: 'jane@example.com',
);

A comment carries exactly one of the two identities. A guest comment has a null commentator_type, which is how the package tells them apart, and why guest comments have their own default status, cannot react, and are never notified.

Both methods throw a CommentableNotPersistedException when the commentable has not been saved yet. There is nothing for the comment to point at.

Read comments

$post->comments;              // every comment, any status, any depth
$post->comments()->count();

The relation is a plain MorphMany, so everything you know about Eloquent applies. Narrow it with the scopes:

$post->comments()->approved()->topLevel()->with('replies')->get();
ScopeReturns
topLevel()Thread starters, comments with no parent
pending()Comments waiting on a moderator
approved()Comments in the approved set
rejected()Comments a moderator turned down
spam()Comments marked as spam, kept apart from rejected
pinned()Comments held at the top of their thread
pinnedFirst()Ordering: pinned first, most recently pinned among them

Soft-deleted comments are excluded by Eloquent's own global scope; reach them with withTrashed(). See deleting comments.

What a comment holds

ColumnMeaning
commentable_type, commentable_idThe record being commented on
commentator_type, commentator_idWho wrote it, or null for a guest
guest_name, guest_emailThe guest identity, or null for a model-authored comment
parent_idThe comment being replied to, or null at the top
bodyStored verbatim, untrusted input
statuspending, approved, rejected, or spam
edited_atWhen the body last changed, or null
pinned_atWhen it was pinned, or null
reply_notified_atWhen its author was told about it, or null
deleted_atSoft-delete tombstone marker

status casts to a CommentStatus enum; the four timestamps cast to Carbon.

Relations on a comment

$comment->commentable;      // the record it is on
$comment->commentator;      // the model that wrote it, or null for a guest
$comment->parent;           // the comment it replies to, or null
$comment->replies;          // direct replies only
$comment->reactions;        // every reaction row
$comment->reactionCounts;   // grouped counts, for rendering
$comment->revisions;        // prior bodies, oldest first
$comment->attachments;      // attachment metadata, oldest first

Ask who wrote it

$comment->isBy($user);  // bool

Both halves of the morph have to match: a User and an Admin that happen to share a primary key are not the same author. A guest-authored comment matches nobody, which is what makes ownership checks deny for one.

Optional: keep a count

A commentable can keep a denormalized count of its approved, non-deleted comments on its own table. It is off until you override one method and add the column yourself:

public function commentsCountColumn(): ?string
{
    return 'comments_count';
}

See comment counts for the migration, the maintenance guarantees, and the repair command.

Optional: decide the initial status

A commentable can implement DecidesCommentStatus to say what status its new comments start in, overriding both configured defaults. See initial status.

What to read next

  • Threads and replies to read nested discussions.
  • Initial status to choose how new comments enter moderation.
  • Comment counts to store an approved count on the model.
PreviousQuick startNextThreads and replies
View source

On this page

  1. Write a comment
  2. Read comments
  3. What a comment holds
  4. Relations on a comment
  5. Ask who wrote it
  6. Optional: keep a count
  7. Optional: decide the initial status
  8. What to read next