Commentions is a drop-in package for Filament that allows you to add comments to your resources. You can configure it so your users are mentionable in the comments, and it dispatches events so you can handle mentions in your own application however you like.
composer require kirschbaum-development/commentions
- Publish the migrations
php artisan vendor:publish --tag="commentions-migrations"
- In your
User
model implement theCommenter
interface.
use Kirschbaum\Commentions\Contracts\Commenter;
class User extends Model implements Commenter
{
// ...
}
- In the model you want to add comments, implement the
Commentable
interface and theHasComments
trait.
use Kirschbaum\Commentions\HasComments;
use Kirschbaum\Commentions\Contracts\Commentable;
class Project extends Model implements Commentable
{
use HasComments;
}
You can register the plugin in your Panel(s) like so:
use Kirschbaum\Commentions\CommentionsPlugin;
return $panel
->plugins([
CommentionsPlugin::make(),
])
There are a couple of ways to use Commentions with Filament.
- Register the component in your Filament Infolists:
Infolists\Components\Section::make('Comments')
->schema([
CommentsEntry::make('comments')
->mentionables(fn (Model $record) => User::all()),
]),
- Or in your table actions:
use Kirschbaum\Commentions\Filament\Actions\CommentsTableAction;
->actions([
CommentsTableAction::make()
->mentionables(User::all())
])
- Or as a header action:
use Kirschbaum\Commentions\Filament\Actions\CommentsAction;
protected function getHeaderActions(): array
{
return [
CommentsAction::make(),
];
}
If your User
model lives in a different namespace than App\Models\User
, you can configure it in config/commentions.php
:
'commenter' => [
'model' => \App\Domains\Users\User::class,
],
If you need to customize the Comment model, you can extend the \Kirschbaum\Commentions\Comment
class and then update the comment.model
option in your config/commentions.php
file:
'comment' => [
'model' => \App\Models\Comment::class,
// ...
],
By default, users can create comments, as well as edit and delete their own comments. You can adjust these permissions by implementing your own policy:
namespace App\Policies;
use Kirschbaum\Commentions\Comment;
use Kirschbaum\Commentions\Contracts\Commenter;
use Kirschbaum\Commentions\Policies\CommentPolicy;
class CommentPolicy extends CommentPolicy
{
public function create(Commenter $user): bool
{
// TODO: Implement custom permission logic.
}
public function update($user, Comment $comment): bool
{
// TODO: Implement custom permission logic.
}
public function delete($user, Comment $comment): bool
{
// TODO: Implement custom permission logic.
}
}
Update the comment.policy
option in your config/commentions.php
file:
'comment' => [
// ...
'policy' => \App\Policies\CommentPolicy::class,
],
By default, the name
property will be used to render the mention names. You can customize it either by implementing the Filament HasName
interface OR by implementing the optional getCommenterName
method.
use Filament\Models\Contracts\HasName;
use Kirschbaum\Commentions\Contracts\Commenter;
class User extends Model implements Commenter, HasName
{
public function getFilamentName(): string
{
return (string) '#' . $this->id . ' - ' . $this->name;
}
}
use Kirschbaum\Commentions\Contracts\Commenter;
class User extends Model implements Commenter
{
public function getCommenterName(): string
{
return (string) '#' . $this->id . ' - ' . $this->name;
}
}
To configure the avatar, make sure your User model implements Filament's HasAvatar
interface.
use Filament\Models\Contracts\HasAvatar;
class User extends Authenticatable implements Commenter, HasName, HasAvatar
{
public function getFilamentAvatarUrl(): ?string
{
return $this->avatar_url;
}
}
Two events are dispatched when a comment is created or reacted to:
Kirschbaum\Commentions\Events\UserWasMentionedEvent
Kirschbaum\Commentions\Events\CommentWasReactedEvent
Every time a user is mentioned, the Kirschbaum\Commentions\Events\UserWasMentionedEvent
is dispatched. You can listen to this event and send notifications to the mentioned user.
Example usage:
namespace App\Listeners;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\UserMentionedInCommentNotification;
use Kirschbaum\Commentions\Events\UserWasMentionedEvent;
class SendUserMentionedNotification implements ShouldQueue
{
use InteractsWithQueue;
public function handle(UserWasMentionedEvent $event): void
{
$event->user->notify(
new UserMentionedInCommentNotification($event->comment)
);
}
}
If you have event auto-discovery, this should be enough. Otherwise, make sure to register your listener on the EventServiceProvider
.
By default, when a new comment is made, the Commenter
is automatically set to the current user logged in user (auth()->user()
). If you want to change this behavior, you can implement your own resolver:
use Kirschbaum\Commentions\Config;
Config::resolveAuthenticatedUserUsing(
fn () => auth()->guard('my-guard')->user()
)
$comment->getMentioned()->each(function (Commenter $commenter) {
// do something with $commenter...
});
Commentions supports polling for new comments. You can enable it on any component by calling the pollingInterval
method and passing the number of seconds.
Infolists\Components\Section::make('Comments')
->schema([
CommentsEntry::make('comments')
->pollingInterval(10)
]),
Sometimes you might want to render non-Comments in the list of comments. For example, you might want to render when the status of a project is changed. For this, you can override the getComments
method in your model, and return instances of the Kirschbaum\Commentions\RenderableComment
data object.
use Kirschbaum\Commentions\RenderableComment;
public function getComments(): Collection
{
$statusHistory = $this->statusHistory()->get()->map(fn (StatusHistory $statusHistory) => new RenderableComment(
id: $statusHistory->id,
authorName: $statusHistory->user->name,
body: sprintf('Status changed from %s to %s', $statusHistory->old_status, $statusHistory->new_status),
createdAt: $statusHistory->created_at,
));
$comments = $this->comments()->latest()->with('author')->get();
return $statusHistory->merge($comments);
}
If you discover any security related issues, please email [email protected] instead of using the issue tracker.
Development of this package is sponsored by Kirschbaum Development Group, a developer driven company focused on problem solving, team building, and community. Learn more about us or join us!
The MIT License (MIT). Please see License File for more information.