›
byrcsc/laravel-comments · 1.x
Pin comments and order pinned items first without changing moderation state.
Pinning holds a comment at the top of its thread, a pinned answer, an announcement, a correction from the author. It is a timestamp on the comment and an ordering scope, and nothing else.
$comment->pin(by: $moderator);
$comment->unpin(by: $moderator);The actor is optional and recorded on the event, not on the comment. Both methods return whether anything moved:
$comment->pin(); // true
$comment->pin(); // false, already pinned, nothing writtenPinning a pinned comment leaves the original pinned_at alone, so its position
in the thread does not shuffle under a second click.
$post->comments()
->approved()
->topLevel()
->pinnedFirst()
->with('replies')
->get();pinnedFirst() orders pinned comments first, most recently pinned among them,
then everything else oldest first, which is the order a thread reads in.
The null handling is spelled out rather than left to the driver: MySQL and SQLite sort nulls first, PostgreSQL sorts them last, and a listing whose order depends on the engine is a bug waiting for a migration.
To read only the pinned ones, a "pinned answers" strip above the thread:
$post->comments()->approved()->pinned()->get();The engine enforces no ceiling. A product that pins three announcements is not doing anything wrong, so the limit belongs in your controller:
$post->comments()->pinned()->each->unpin();
$comment->pin(by: $request->user());A pinned comment keeps whatever status it had, and moderating one leaves its
pin alone. The two never move each other, and pinning records no revision and
does not stamp edited_at, it changes what the package knows about the
comment, not what its author wrote.
Nothing stops you pinning a pending comment. Whether a pinned comment is
visible is still decided by your query.
| Method | Event |
|---|---|
pin() | CommentPinned |
unpin() | CommentUnpinned |
Both extend CommentPinChanged and carry the comment and the actor. Neither
fires when nothing moved, so one event means one real change, which is what an
activity feed downstream is built on.
use ByRcsc\LaravelComments\Events\CommentPinned;
use ByRcsc\LaravelComments\Events\CommentUnpinned;
use ByRcsc\LaravelComments\Events\CommentPinChanged;
use Illuminate\Support\Facades\Event;
Event::listen(
[CommentPinned::class, CommentUnpinned::class],
fn (CommentPinChanged $event) => $this->logPinChange($event->comment, $event->actor),
);pin and unpin are abilities on the shipped CommentPolicy, and both deny by
default. See authorization.