melsaka / commentable
实现Laravel Eloquent模型的评论系统。
Requires
- php: ^8.1
- laravel/framework: ^10.10
README
Laravel的Commentable包提供了一个方便的方式来管理应用中的评论和相关的功能。本文档将指导您如何使用此包。
目录
安装
通过Composer将包添加到您的Laravel应用中
composer require melsaka/commentable
在config/app.php中注册包的服务提供者。
'providers' => [ ... Melsaka\Commentable\CommentableServiceProvider::class, ... ];
运行迁移以将所需的表添加到数据库中
php artisan migrate
将CanComment
特质添加到评论所有者模型中,例如User
模型
use Melsaka\Commentable\CanComment; class User extends Model { use CanComment; // ... }
将HasComments
特质添加到您的可评论模型中,例如Post
模型
use Melsaka\Commentable\HasComments; class Post extends Model { use HasComments; // ... }
如果您想启用任何commentable
模型(例如Post
模型)中的rating
功能,请添加commentsAreRated()
方法。
默认情况下,评论没有评分false
。您可以通过添加此方法并使其返回true
来更改此设置。
class Post extends Model { use HasComments; public function commentsAreRated(): bool { return true; // return false by default } // .. }
默认情况下,新评论被接受,但有时您不想批准所有用户的评论;
在这种情况下,添加commentsAreAccepted()
方法并使其返回false
(默认值为true
)。
class Post extends Model { use HasComments; public function commentsAreAccepted(): bool { return false; // return true by default } // .. }
使用CanComment
特质的所有者模型还有一个commentsAreAccepted()
方法,默认返回false
。
例如,您可以仅为此方法返回true
以供管理员用户,因此所有管理员用户的评论将自动被接受。
class User extends Model { use CanComment; protected $fillable = [ 'isAdmin', // .. ]; public function commentsAreAccepted(): bool { return $this->isAdmin; // default false } // .. }
配置
要配置包,发布其配置文件
php artisan vendor:publish --tag=commentable
然后您可以修改配置文件以更改评论表名(如果需要),默认为comments
。
使用
添加评论
要添加新评论,您可以在for
和via
方法之后使用add
方法,如下所示
use App\Models\User; use App\Models\Post; use Melsaka\Commentable\Models\Comment; $post = Post::first(); $owner = User::first(); $parent = $post->comments()->first(); $data = [ 'body' => 'this ia a new reply', 'accepted' => true, 'rate' => 4.5, 'parent_id' => $parent->id, ]; Comment::for($post)->via($owner)->add($data, $parent);
-
$post
是可评论模型。 -
$owner
是评论的所有者。 -
$data
可以是一个string
或一个包含评论数据的array
。 -
$parent
是一个可选参数,可以将评论添加为父评论的回复,默认值为null
。
注意:在接下来的示例中,我们可能会使用到$post
、$owner
和$parent
变量。
您也可以以多种不同的方式添加评论
$data = 'this is a new parent comment'; (new Comment)->for($post)->via($owner)->add($data); $post->addComment($data, $owner); $owner->addComment($data, $post);
注意:所有这些方法都接受$parent
参数,但默认值为null
。因此,您也可以这样做
$post->addComment($data, $post, $parent);
编辑评论
要编辑评论,使用edit
方法并传入您想要编辑的$comment
作为第一个参数
Comment::for($post)->edit($comment, $data, $parent);
-
$comment
可以是评论的ID,或评论本身。 -
$data
可以是一个string
或一个包含更新评论数据的array
。 -
$parent
是可选的,默认值为null
。
您也可以使用不同的方法来编辑评论
$comment->for($post)->editTo($data); $post->editComment($comment, $data); $owner->editComment($comment, $data);
在这个例子中:$comment->for($post)->editTo($data);
,for方法减少了执行的查询数。
但即使没有它,您也可以编辑评论,因为我们无论如何都会获取可评论的模型,如果您在方法中不提供它。
如果评论的 commentable_id
或 owner_id
与 $post->id
或 $owner->id
不相同,则 editComment
方法不会更新。
注意:所有这些方法都接受$parent
参数,但默认值为null
。因此,您也可以这样做
$post->editComment($data, $post, $parent);
您还可以使用 addParent()
方法给评论添加一个父级。
$comment->addParent($parent);
删除评论
要删除一个或多个评论,请使用 remove
方法。
Comment::remove($comment);
$comment
可以是一个 Comment 实例,评论的 集合,评论 ID 的 数组,或单个评论 ID。
要删除单个评论实例,您还可以使用
$comment->remove();
您可以用不同的方式删除评论
$post->removeComment($comment); $post->deleteComment($comment); $owner->removeComment($comment); $owner->deleteComment($comment);
如果评论的 commentable_id
或 owner_id
与 $post->id
或 $owner->id
不相同,则 deleteComment
和 removeComment
方法不会删除 $comment
。
更改评论状态
您可以使用 accept
方法将评论状态更改为已接受。
$comment->accept();
要拒绝评论,请使用 reject
方法。
$comment->reject();
您还可以对帖子上的评论进行接受或拒绝。
$post->acceptComment($comment); $post->rejectComment($comment);
如果评论的 commentable_id
或 owner_id
与 $post->id
或 $owner->id
不相同,则 acceptComment
和 rejectComment
方法不会更新 $comment
的状态。
评分评论
要更改评论的评分,请使用 rateIt
方法。
$comment->rateIt($rate);
您还可以使用这些方法对评论进行评分
Comment::rateIt($rate, $comment); $post->rateComment($comment, $rate);
如果 $post
的 commentsAreRated
为 false 或 commentable_id
与 $post->id
不相同,则 rateComment
返回 false。
您还可以使用 averageRate()
方法获取帖子的平均评分。
$post->averageRate();
获取方法
要按 ID 获取评论,您可以使用 Comment::getCommentOfId($id)
,如果 ID 不存在则返回 404。
Comment::getCommentOfId($id);
注意:如果您提供了一个有效的 $comment
实例,它将返回给您。
您还可以使用各种获取方法来检索评论。
获取帖子评论
Comment::of($post)->get();
获取用户评论
Comment::by($owner)->get();
按用户获取帖子评论
Comment::of($post)->by($owner)->get();
预加载评论回复和回复计数
Comment::of($post)->by($owner)->withReplies()->withRepliesCount()->get();
仅获取已接受回复
Comment::of($post)->withAcceptedReplies()->get(); Comment::of($post)->withAcceptedRepliesCount()->get();
仅获取被拒绝回复
Comment::of($post)->withRejectedReplies()->get(); Comment::of($post)->withRejectedRepliesCount()->get();
这些方法也可以接受回调函数进行进一步自定义。
您可以在 with
、withCount
、load
和 loadCount
方法中使用回调函数。
Comment::of($post)->withReplies(function ($query) { $query->where('accepted', true); })->get(); // Or Comment::of($post)->withAcceptedReplies(function ($query) { $query->whereNotNull('rate'); })->get();
您还可以像这样从可评论模型和所有者模型中使用 with
和 load
方法
Post::withComments()->get(); Post::withAcceptedComments()->get(); User::withComments()->get(); User::withAcceptedComments()->get(); $post->loadAcceptedComments(); $owner->loadAcceptedComments();
这些方法也接受 callback
函数。
您还可以加载 replies
/repliesCount
。
$comment->loadReplies(); $comment->loadRepliesCount(); $comment->loadAcceptedReplies(); $comment->loadAcceptedRepliesCount(); $comment->loadRejectedReplies(); $comment->loadRejectedRepliesCount();
它们都接受回调函数。
$comment->loadReplies(function ($query) { $query->where('accepted', true); });
关系方法
Comment
模型已设置此关系,您可能需要在您的应用程序中使用它。
// To get the commentable model of a comment $comment->commentable; // To get the owner model of a comment $comment->owner; // To get the comment parent if it's a reply $comment->parent; // To get the comment replies if it's a parent comment $comment->replies; // Or maybe add some conditions $comment->replies()->onlyAccepted()->get();
您可以通过这种方式从 related
模型获取 comments
。
$post->comments(); $post->replies(); $owner->comments(); $owner->replies();
每个相关的 CanComment
或 HasComments
模型都有这些内置方法。
$post->morphsArray(); $owner->morphsArray(); $post->primaryId(); $owner->primaryId();
您可以使用 morphsArray()
方法按 commentable
或 owner
过滤,如下所示
Comment::where($post->morphsArray())->get(); // which is similr to this Comment::of($post); // or Comment::where($owner->morphsArray())->get(); // which is similr to this Comment::by($owner); // or $post->commentsBy($owner); $owner->commentsOn($owner);
但是,(of, by)
方法返回只有 onlyParent
的评论和 withRepliesCount
。
而此代码
Comment::where($owner->morphsArray())->get();
返回 comments
和 replies
一起,但没有回复计数,您将不得不检查 parent_id
以确定哪个是 parent
评论,哪个是 reply
。
过滤器
如果您想过滤评论,可以使用这些方法
// Available filters: Comment::of($post)->onlyParent()->get(); Comment::of($post)->onlyAccepted()->get(); Comment::of($post)->onlyRejected()->get(); Comment::of($post)->onlyRated()->get(); Comment::of($post)->onlyNotRated()->get();
您还可以这样链式调用过滤器
Comment::of($post) ->by($owner) ->onlyParents() ->onlyAccepted() ->onlyRated() ->get();
检查器
您也可以检查 $comment
是否有 replies
或 parent
。
$comment->hasReplies(); $comment->hasParent();
您还可以检查一个 commentable
模型是否 hasCommentsBy
一个所有者或相反。
$post->hasCommentsBy($owner); $owner->hasCommentsOn($post);
检查 $comment
是否属于一个相关 Model
。
$post->hasComment($comment); $owner->commented($comment);
Commentable表
评论表的结构如下
Schema::create('comments', function (Blueprint $table) { $table->id(); $table->morphs('commentable'); $table->morphs('owner'); $table->text('body'); $table->boolean('accepted')->default(true); $table->double('rate', 15, 8)->nullable(); $table->bigInteger('parent_id'); $table->timestamps(); });
许可证
本软件包采用MIT许可协议(MIT)发布。