melsaka/commentable

实现Laravel Eloquent模型的评论系统。

v0.1.1 2023-11-13 02:36 UTC

This package is auto-updated.

Last update: 2024-09-13 04:20:10 UTC


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

使用

添加评论

要添加新评论,您可以在forvia方法之后使用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_idowner_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_idowner_id$post->id$owner->id 不相同,则 deleteCommentremoveComment 方法不会删除 $comment

更改评论状态

您可以使用 accept 方法将评论状态更改为已接受。

$comment->accept();

要拒绝评论,请使用 reject 方法。

$comment->reject();

您还可以对帖子上的评论进行接受或拒绝。

$post->acceptComment($comment);

$post->rejectComment($comment);

如果评论的 commentable_idowner_id$post->id$owner->id 不相同,则 acceptCommentrejectComment 方法不会更新 $comment 的状态。

评分评论

要更改评论的评分,请使用 rateIt 方法。

$comment->rateIt($rate);

您还可以使用这些方法对评论进行评分

Comment::rateIt($rate, $comment);

$post->rateComment($comment, $rate);

如果 $postcommentsAreRatedfalsecommentable_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();

这些方法也可以接受回调函数进行进一步自定义。

您可以在 withwithCountloadloadCount 方法中使用回调函数。

Comment::of($post)->withReplies(function ($query) {

    $query->where('accepted', true);

})->get();

// Or

Comment::of($post)->withAcceptedReplies(function ($query) {

    $query->whereNotNull('rate');

})->get();

您还可以像这样从可评论模型和所有者模型中使用 withload 方法

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

每个相关的 CanCommentHasComments 模型都有这些内置方法。

$post->morphsArray();

$owner->morphsArray();

$post->primaryId();

$owner->primaryId();

您可以使用 morphsArray() 方法按 commentableowner 过滤,如下所示

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

返回 commentsreplies 一起,但没有回复计数,您将不得不检查 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 是否有 repliesparent

$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)发布。