PHP code example of kirschbaum-development / commentions

1. Go to this page and download the library: Download kirschbaum-development/commentions library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

kirschbaum-development / commentions example snippets


use Kirschbaum\Commentions\Contracts\Commenter;

class User extends Model implements Commenter
{
    // ...
}

use Kirschbaum\Commentions\HasComments;
use Kirschbaum\Commentions\Contracts\Commentable;

class Project extends Model implements Commentable
{
    use HasComments;
}

    CommentsEntry::make('comments')
        ->mentionables(fn (Model $record) => User::all()),

\Filament\Infolists\Components\Section::make('Comments')
    ->schema([
        CommentsEntry::make('comments')
            ->mentionables(fn (Model $record) => User::all()),
    ]),

\Filament\Schemas\Components\Section::make('Comments')
    ->components([
        CommentsEntry::make('comments')
            ->mentionables(fn (Model $record) => User::all()),
    ]),

CommentsEntry::make('comments')
    ->record(fn () => $pivot)
    ->mentionables(User::all());

use Kirschbaum\Commentions\Filament\Actions\CommentsTableAction;

->actions([
    CommentsTableAction::make()
        ->mentionables(User::all())
])

use Kirschbaum\Commentions\Filament\Actions\CommentsAction;

->recordActions([
    CommentsAction::make()
        ->mentionables(User::all())
])

use Kirschbaum\Commentions\Filament\Actions\CommentsAction;

protected function getHeaderActions(): array
{
    return [
        CommentsAction::make()
            ->mentionables(User::all()),
    ];
}

use Filament\Forms\Components\ViewField;

public static function configure(Schema $schema): Schema
{
    return $schema
        ->components([
            // Your other form fields...

            ViewField::make('comments_section')
                ->view('...') // View file
                ->viewData(fn ($livewire) => [
                    'record' => $livewire->record ?? null
                ])
                ->columnSpanFull()
                ->hiddenLabel(),
        ]);
}

@livewire('commentions::comments', [
    'record' => $record,
    'mentionables' => \App\Models\User::all(),
    'readonly' => $readonly ?? false
])

@livewire('commentions.comments', [
    'record' => $record,
    'mentionables' => \App\Models\User::all(),
    'readonly' => $readonly ?? false
])

ViewField::make('comments_section')
    ->view('...') // View file
    ->viewData(fn ($livewire) => [
        'record' => $livewire->record ?? null,
        'readonly' => true, // Enable readonly mode
    ])
    ->columnSpanFull()
    ->hiddenLabel(),

// Make comments readonly
CommentsEntry::make()
    ->readonly()
    ->mentionables(User::all())

CommentsAction::make()
    ->readonly()
    ->mentionables(User::all())

CommentsTableAction::make()
    ->readonly()
    ->mentionables(User::all())

// You can also conditionally enable readonly mode
CommentsAction::make()
    ->readonly(auth()->user()->cannot('create', Comment::class))
    ->mentionables(User::all())

use Kirschbaum\Commentions\Filament\Actions\SubscriptionAction;

// In header actions
protected function getHeaderActions(): array
{
    return [
        SubscriptionAction::make(),
    ];
}

// In table actions (Filament 3)
->actions([
    SubscriptionTableAction::make(),
])

// In record actions (Filament 4)
->recordActions([
    SubscriptionAction::make(),
])

// Hide the sidebar entirely
<livewire:commentions::comments :mentionables="App\Models\User::all()" :record="$record" :sidebar-enabled="false" />

// Keep the sidebar, but hide the subscribers list (uses config default if omitted)
<livewire:commentions::comments :mentionables="App\Models\User::all()" :record="$record" :show-subscribers="false" />

// Hide the sidebar entirely
<livewire:commentions.comments :mentionables="App\Models\User::all()" :record="$record" :sidebar-enabled="false" />

// Keep the sidebar, but hide the subscribers list (uses config default if omitted)
<livewire:commentions.comments :mentionables="App\Models\User::all()" :record="$record" :show-subscribers="false" />

use Kirschbaum\Commentions\Filament\Actions\CommentsAction;

->recordActions([
    CommentsAction::make()
        ->mentionables(User::all())
        ->disableSidebar()
])

// Subscribe a user
$commentable->subscribe($user);

// Unsubscribe a user
$commentable->unsubscribe($user);

// Check if a user is subscribed
$isSubscribed = $commentable->isSubscribed($user);

// Get all subscribers
$subscribers = $commentable->getSubscribers();

use Kirschbaum\Commentions\Filament\Actions\CommentsAction;

->recordActions([
    CommentsAction::make()
        ->mentionables(User::all())
        ->perPage(10)

])

use Kirschbaum\Commentions\Filament\Actions\CommentsAction;

->recordActions([
    CommentsAction::make()
        ->mentionables(User::all())
        ->disablePagination();

])

use Kirschbaum\Commentions\Filament\Infolists\Components\CommentsEntry;

Infolists\Components\Section::make('Comments')
    ->schema([
        CommentsEntry::make('comments')
            ->mentionables(fn (Model $record) => User::all())
            ->perPage(8)
            ->loadMoreIncrementsBy(8)
            ->loadMoreLabel('Show older'),
    ])

    'commenter' => [
        'model' => \App\Domains\Users\User::class,
    ],

    'comment' => [
        'model' => \App\Models\Comment::class,
        // ...
    ],

namespace App\Policies;

use Kirschbaum\Commentions\Comment;
use Kirschbaum\Commentions\Contracts\Commenter;
use Kirschbaum\Commentions\Policies\CommentPolicy as CommentionsPolicy;

class CommentPolicy extends CommentionsPolicy
{
    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.
    }
}

    'comment' => [
        // ...
        'policy' => \App\Policies\CommentPolicy::class,
    ],

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;
    }
}

    'reactions' => [
        'enabled' => env('COMMENTIONS_REACTIONS_ENABLED', true),

        'allowed' => ['👍', '❤️', '😂', '🎉', '👀'],
    ],

CommentsEntry::make('comments')
    ->mentionables(User::all())
    ->disableReactions();

CommentsAction::make()
    ->mentionables(User::all())
    ->disableReactions();

    'avatars' => [
        'enabled' => env('COMMENTIONS_AVATARS_ENABLED', true),
    ],

CommentsEntry::make('comments')
    ->mentionables(User::all())
    ->disableAvatars();

CommentsAction::make()
    ->mentionables(User::all())
    ->disableAvatars();

use Filament\Models\Contracts\HasAvatar;

class User extends Authenticatable implements Commenter, HasName, HasAvatar
{
    public function getFilamentAvatarUrl(): ?string
    {
        return $this->avatar_url;
    }
}

// config/commentions.php
use Filament\AvatarProviders\GravatarProvider;

return [
    // ...
    'avatar_provider' => GravatarProvider::class,
];

use Kirschbaum\Commentions\Config;
use Filament\Actions\Action;

Config::registerCommentActions(fn ($comment) => Action::make('activityLogs')
    ->icon('heroicon-s-clock')
    ->iconButton()
    ->modalContent(/* ... */)
);

    'ratings' => [
        'enabled' => env('COMMENTIONS_RATINGS_ENABLED', false),

        'max' => (int) env('COMMENTIONS_RATINGS_MAX', 5),
    ],

CommentsEntry::make('comments')
    ->mentionables(fn (Model $record) => User::all())
    ->enableRatings()
    ->maxRating(10)

    'attachments' => [
        'enabled' => env('COMMENTIONS_ATTACHMENTS_ENABLED', false),

        // Filesystem disk and directory used to store uploads.
        'disk' => env('COMMENTIONS_ATTACHMENTS_DISK', 'public'),
        'directory' => env('COMMENTIONS_ATTACHMENTS_DIRECTORY', 'commentions-attachments'),

        // Maximum size per file, in kilobytes.
        'max_size' => (int) env('COMMENTIONS_ATTACHMENTS_MAX_SIZE', 10240),

        // Maximum number of files per comment.
        'max_files' => (int) env('COMMENTIONS_ATTACHMENTS_MAX_FILES', 5),

        // Accepted MIME types, validated against the file's actual contents.
        'accepted_mime_types' => [
            'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'application/pdf',
            // ...
        ],
    ],

use Kirschbaum\Commentions\Filament\Infolists\Components\CommentsEntry;

CommentsEntry::make('comments')->mentionables(User::all())->enableAttachments();
CommentsEntry::make('comments')->mentionables(User::all())->enableAttachments(fn () => auth()->user()->isAdmin());
CommentsEntry::make('comments')->mentionables(User::all())->disableAttachments();

use Kirschbaum\Commentions\Config;

Config::resolveTipTapCssClassesUsing(function () {
    return 'prose max-w-none focus:outline-none p-4';
});

use Kirschbaum\Commentions\Filament\Infolists\Components\CommentsEntry;

CommentsEntry::make('comments')
    ->mentionables(fn (Model $record) => User::all())
    ->tipTapCssClasses('prose max-w-none focus:outline-none p-4')

use Kirschbaum\Commentions\Filament\Actions\CommentsAction;

CommentsAction::make()
    ->mentionables(User::all())
    ->tipTapCssClasses('prose max-w-none focus:outline-none p-4')

    'toolbar' => [
        'enabled' => env('COMMENTIONS_TOOLBAR_ENABLED', true),

        'buttons' => [
            ['bold', 'italic', 'underline'],
            ['bulletList', 'orderedList'],
            ['link'],
        ],
    ],

use Kirschbaum\Commentions\Filament\Infolists\Components\CommentsEntry;

CommentsEntry::make('comments')
    ->mentionables(fn (Model $record) => User::all())
    ->toolbarButtons([['bold', 'italic'], ['link']])

use Kirschbaum\Commentions\Filament\Actions\CommentsAction;

CommentsAction::make()
    ->mentionables(User::all())
    ->toolbarButtons(['bold', 'italic', 'link'])

// lang/vendor/commentions/en/comments.php
return [
    'label' => 'Notes',
    'no_comments_yet' => 'No notes yet.',
    'add_reaction' => 'Add a reaction',
    'cancel' => 'Close',
    'delete' => 'Remove',
    'save' => 'Update',
];

namespace App\Listeners;

use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\NewCommentNotification;
use Kirschbaum\Commentions\Events\UserIsSubscribedToCommentableEvent;

class SendSubscribedUserNotification implements ShouldQueue
{
    use InteractsWithQueue;

    public function handle(UserIsSubscribedToCommentableEvent $event): void
    {
        $event->user->notify(
            new NewCommentNotification($event->comment)
        );
    }
}

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)
        );
    }
}

    'notifications' => [
        'mentions' => [
            'enabled' => true,
            'channels' => ['mail', 'database'],
        ],
    ],

use Kirschbaum\Commentions\Config;

Config::resolveCommentUrlUsing(function (\Kirschbaum\Commentions\Comment $comment) {
    // Return a URL to view the record and scroll to the comment
    return route('projects.show', $comment->commentable) . '#comment-' . $comment->getId();
});

use Kirschbaum\Commentions\Config;

Config::resolveAuthenticatedUserUsing(
    fn () => auth()->guard('my-guard')->user()
)

$comment->getMentioned()->each(function (Commenter $commenter) {
    // do something with $commenter...
});

Infolists\Components\Section::make('Comments')
    ->schema([
        CommentsEntry::make('comments')
            ->mentionables(fn (Model $record) => User::all())
            ->poll('10s')
    ]),

protected function afterSave(): void
{
    $this->dispatch('commentions:refresh');
}

use Kirschbaum\Commentions\RenderableComment;

public function getComments(?int $limit = null): 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();

    $mergedCollection = $statusHistory->merge($comments);

    if ($limit) {
        return $mergedCollection->take($limit);
    }

    return $mergedCollection;
}
bash
php artisan commentions:install
bash
php artisan filament:assets
bash
php artisan vendor:publish --tag="commentions-config"