This package can be used to comment on any model you have in your application.
- View comments
- Create comment
- Delete comment
- Edit comment
- Reply to comment
- Authorization rules | with customization
- View customization
- Dispatch events
- Likes | Dislikes | Comment rating
- API for basic function: get, update, delete, create
- HTML filter customization (using HTMLPurifier)
- php 7.1 +
- laravel 5.6 +
Your application should contain auth module.
- Laravel 6.x: https://laravel.com/docs/6.x/authentication
- Laravel 5.6: https://laravel.com/docs/5.6/authentication
composer require tizis/lara-comments
We need to create the table for comments.
php artisan migrate
Add the Commenter
trait to your User model so that you can retrieve the comments for a user:
use tizis\laraComments\Traits\Commenter;
class User extends Authenticatable {
use ..., Commenter;
use tizis\laraComments\Entity\Comment as laraComment;
class Comment extends laraComment
{
}
Add the Commentable
trait and the ICommentable
interface to the model for which you want to enable comments for:
use tizis\laraComments\Contracts\ICommentable;
use tizis\laraComments\Traits\Commentable;
class Post extends Model implements ICommentable {
use Commentable;
If you need, you can overwrite default comment policy class:
<?php
namespace App\Http\Policies;
use App\Entity\Comment;
use tizis\laraComments\Policies\CommentPolicy as CommentPolicyPackage;
class CommentPolicy extends CommentPolicyPackage
{
// overwrite delete rule
public function delete($user, $comment): bool
{
// ever true
return true;
}
}
Then register policy in AuthServiceProvider
:
use Illuminate\Support\Facades\Gate;
use App\Http\Policies\CommentPolicy;
...
public function boot()
{
Gate::resource('comments_custom', CommentPolicy::class, [
'delete' => 'delete',
'reply' => 'reply',
'edit' => 'edit',
'vote' => 'vote',
'store => 'store'
]);
}
And add policy prefix to comments.php config
'policy_prefix' => 'comments_custom',
In the config
file you can specify:
- where is your User model located; the default is
\App\User::class
- where is your Comment model located; the default is
\App\Comment::class
- policy prefix, you can create custom policy class and extends
tizis\laraComments\Policies\CommentPolicy;
- allow tags for html filter
- API prefix
Publish the config file (optional):
php artisan vendor:publish --provider="tizis\laraComments\Providers\ServiceProvider" --tag=config
The default UI is made for Bootstrap 4
, but you can change it
however you want.
⚠⚠⚠⚠WARNING⚠⚠⚠⚠
All view examples include js/css files for correct working. The possibility of conflict
with your scripts and styles.
php artisan vendor:publish --provider="tizis\laraComments\Providers\ServiceProvider" --tag=views
In the view where you want to display comments, place this code and modify it:
laravel 6
@comments(['model' => $post]) @endcomments
Laravel 7
<x-comments :model="$post"/>
In the example above we are setting argument the model
as class of the book model.
Behind the scenes, the package detects the currently logged in user if any.
If you open the page containing the view where you have placed the above code, you should see a working comments form.
Title | Method | Url | Params | Route name |
---|---|---|---|---|
Get comments | GET | /api/comments/ | commentable_encrypted_key, order_by (column name, default is id), order_direction (default is asc) | route('comments.get') |
Store comment | POST | /api/comments/ | commentable_encrypted_key, message | route('comments.store') |
Delete comment | DELETE | /api/comments/{comment_id} | -- | route('comments.delete', $comment_id) |
Edit comment | POST | /api/comments/{comment_id} | message | route('comments.update', $comment_id) |
Reply to comment | POST | /api/comments/{comment_id} | message | route('comments.reply', $comment_id) |
Vote to comment | POST | /api/comments/{comment_id}/vote | vote(bool) | route('comments.vote', $comment_id) |
If you don't want use out of the box features: API, or the CommentController, but want to access the built-in features - you can use tizis\laraComments\UseCases\CommentService
CommentService
class used inside default comment controller for request processing.
To disable API routes by default, set the route.root => null
config value.
Methods:
- Сreate comment:
CommentService::createComment
$user = Auth::user();
$modelId = decrypt($request->commentable_encrypted_key)['id']; // get model id from encrypted model key
$model = $model = Post::findOrFail($modelId);
$message = '123'
$parent = rand(1, 100); // optional
$createdComment = CommentService::createComment(new Comment(), $user, $model, $message, [optional $parent]);
- Delete comment:
CommentService::deleteComment
$comment = Comment::findOrFail(123);
CommentService::deleteComment($comment);
- Update comment:
CommentService::updateComment
$comment = Comment::findOrFail(123);
$message = 'new text';
$updatedComment = CommentService::updateComment($comment, $message);
This package fires events to let you know when things happen.
tizis\laraComments\Events\CommentCreated
tizis\laraComments\Events\CommentUpdated
tizis\laraComments\Events\CommentDeleted
⚠ WARNING! Only for API! ⚠
Supported preprocessors for attributes of get api:
- user [Object]
- comment [String]
Sometimes additional processing of content is necessary before transmission over API.
'api' => [
'get' => [
'preprocessor' => [
'comment' => App\Helpers\CommentPreprocessor\Comment::class,
'user' => App\Helpers\CommentPreprocessor\User::class
...
]
]
]
Create preprocessor class and implement ICommentPreprocessor
interface:
Examples:
Comment:
namespace App\Helpers\CommentPreprocessor;
use tizis\laraComments\Contracts\ICommentPreprocessor;
class Comment implements ICommentPreprocessor
{
public function process($comment): array
{
return 'Hi, ' . $comment . '!';
}
}
User:
namespace App\Helpers\CommentPreprocessor;
use tizis\laraComments\Contracts\ICommentPreprocessor;
class User implements ICommentPreprocessor
{
public function process($user): array
{
$user->name = $user->name . '[Moderator]'
return $user;
}
}
Without preprocessing:
$comment = 1;
echo $comment; // 1
$user = Auth::user();
echo $user->name; // user1
With preprocessing:
$comment = 1;
echo $comment; // Hi, 1 !
$user = Auth::user();
echo $user->name; // user1[Moderator]
- Scope withCommentsCount()
/**
* Add comments_count attribute to model
*/
Posts::withCommentsCount()->orderBy('id', 'desc')->get()
use tizis\laraComments\Http\CommentsHelper;
- getNewestComments(default $take = 10, default $commentable_type = null)
- getCommenterRating(int $userId, [optional Carbon $cacheTtl])
- moveCommentTo(CommentInterface $comment, ICommentable $newCommentableAssociate)
- moveCommentToAndRemoveParentAssociateOfRoot(CommentInterface $comment, ICommentable $newCommentableAssociate)
CommentsHelper::getNewestComments(20) // Return last 20 comments
CommentsHelper::getNewestComments(20, Book::class) // Return last 20 comments of Book model
This repository include only bootstrap4
template, but you can create you own UI. This is just a example of package features.
This is example of backend
rendering, this way have bad performance
when 100+ comments on post due to the need to check user permissions (reply, edit, delete etc) for each comment.
A good idea
is use API and build UI with Vue js (or any other library) with verification of user permissions (only for UI) on frontend.
commentable_type
and commentable_id
request attributes was merged into single commentable_encrypted_key
You need to replace these deprecated attributes.
Example:
Old /bootstrap4/form.blade.php
<input type="hidden" name="commentable_type" value="\{{ get_class($model) }}"/>
<input type="hidden" name="commentable_id" value="{{ $model->id }}"/>
New /bootstrap4/form.blade.php
<input type="hidden" name="commentable_encrypted_key" value="{{ $model->getEncryptedKey() }}"/>