Installation:
composer require lakm/laravel-comments
php artisan vendor:publish --provider="Lakm\Comments\CommentsServiceProvider" --tag="migrations"
php artisan migrate
comments, comment_replies, and comment_votes tables.Configuration:
php artisan vendor:publish --provider="Lakm\Comments\CommentsServiceProvider" --tag="config"
config/comments.php with your preferred settings (e.g., model, table_names, moderation).First Use Case:
use Lakm\Comments\Facades\Comments;
// In your controller:
$comments = Comments::getComments($postId);
// In your Blade view:
@comments(['model' => $post, 'comments' => $comments])
Post in this case) uses the Lakm\Comments\Contracts\Commentable trait.Commenting on Models:
Commentable trait on any model to enable comments:
use Lakm\Comments\Contracts\Commentable;
class Post extends Model
{
use Commentable;
}
Comments::create($postId, $userId, 'This is a comment!');
Nested Replies:
Comments::reply($commentId, $userId, 'Reply text', $parentReplyId = null);
@comments(['model' => $post, 'comments' => $comments, 'withReplies' => true])
Moderation & Approval:
config/comments.php:
'moderation' => [
'enabled' => true,
'default_status' => 'pending',
],
Comments::approve($commentId);
Comments::reject($commentId, 'Reason');
Voting System:
'voting' => [
'enabled' => true,
'types' => ['up', 'down'],
],
Comments::vote($commentId, 'up', $userId);
Theming:
php artisan vendor:publish --provider="Lakm\Comments\CommentsServiceProvider" --tag="public"
resources/views/vendor/comments/.API Support:
Use the CommentsController provided by the package or extend it:
use Lakm\Comments\Http\Controllers\CommentsController;
Route::post('/comments', [CommentsController::class, 'store']);
Real-Time Updates: Pair with Laravel Echo/Pusher for live comment/reply notifications:
Echo.channel('comments')
.listen('CommentCreated', (e) => {
// Update UI
});
Soft Deletes: Enable soft deletes in config:
'soft_deletes' => true,
Then use:
Comments::restore($commentId);
Comments::forceDelete($commentId);
Caching: Cache comment queries for performance:
$comments = Cache::remember("comments_{$postId}", now()->addHours(1), function () use ($postId) {
return Comments::getComments($postId);
});
Model Trait Conflicts:
Commentable trait is added after other traits (e.g., HasFactory, Notifiable) to avoid method conflicts.commentable_type and commentable_id in the comments table.Migration Issues:
comments table schema to match the package’s expectations (e.g., user_id, commentable_id, status columns).php artisan comments:install if migrations fail silently.Permission Denied:
Route::middleware(['auth'])->group(function () {
// Comment routes
});
Comments::setAuthResolver(function () {
return Auth::user();
});
Nested Reply Depth:
'reply_depth' => 5,
Vote Abuse:
Route::middleware(['throttle:10,1'])->group(function () {
// Vote routes
});
Query Logging: Enable Laravel’s query logging to debug comment retrieval:
DB::enableQueryLog();
$comments = Comments::getComments($postId);
dd(DB::getQueryLog());
Event Debugging: Listen for comment events to trace workflows:
Comments::on('comment.created', function ($comment) {
Log::info('New comment:', ['comment' => $comment]);
});
Validation Errors:
Customize validation rules in config/comments.php:
'validation' => [
'comment' => 'required|string|max:5000',
'reply' => 'required|string|max:3000',
],
Custom Fields:
Extend the Comment model to add fields:
class Comment extends \Lakm\Comments\Models\Comment
{
protected $casts = [
'custom_field' => 'boolean',
];
}
Update migrations and config accordingly.
Event Hooks:
Subscribe to package events in EventServiceProvider:
protected $listen = [
'Lakm\Comments\Events\CommentCreated' => [
'App\Listeners\LogComment',
],
];
API Resources:
Override the default CommentResource:
class CustomCommentResource extends \Lakm\Comments\Http\Resources\CommentResource
{
public function toArray($request)
{
$array = parent::toArray($request);
$array['custom_field'] = $this->custom_field;
return $array;
}
}
Update routes to use your resource.
Testing: Use the package’s test helpers:
use Lakm\Comments\Testing\CreatesComments;
class CommentTest extends TestCase
{
use CreatesComments;
public function testCommentCreation()
{
$comment = $this->createComment($postId, $userId, 'Test comment');
$this->assertDatabaseHas('comments', ['id' => $comment->id]);
}
}
Table Names: Customize table names in config:
'table_names' => [
'comments' => 'custom_comments',
'replies' => 'custom_replies',
],
User Model: Specify a custom user model:
'user_model' => \App\Models\CustomUser::class,
Illuminate\Contracts\Auth\Authenticatable.Default Status:
Set default comment status (pending, approved, rejected):
'moderation' => [
'default_status' => 'pending',
],
Avatar Handling: Customize avatar logic in config:
'avatar' => [
'gravatar' => false,
'default' => 'https://via.placeholder.com/50',
],
Or override the getAvatarUrl() method in the Comment model.
Eager Loading: Eager-load relationships to avoid N+1 queries:
$comments = Comments::with(['user', 'replies.user'])->getComments($postId);
Pagination: Paginate comments/replies:
$comments = Comments::getComments($postId)->paginate(10);
Caching Strategies: Cache comment counts for models:
How can I help you explore Laravel packages today?