melsaka/commentable 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

melsaka/commentable

Composer 安装命令:

composer require melsaka/commentable

包简介

Implementing a Comment system for Laravel's Eloquent models.

README 文档

README

The Commentable package for Laravel provides a convenient way to manage comments and comment-related functionality in your application. This documentation will guide you through the usage of this package.

Table of Contents

Installation

Add the package to your Laravel app via Composer:

composer require melsaka/commentable

Register the package's service provider in config/app.php.

'providers' => [
    ...
    Melsaka\Commentable\CommentableServiceProvider::class,
    ...
];

Run the migrations to add the required table to your database:

php artisan migrate

Add CanComment trait to the comment owner model, User model for example:

use Melsaka\Commentable\CanComment;

class User extends Model
{
    use CanComment;
    
    // ...   
}

Add HasComments trait to your commentable model, Post model for example:

use Melsaka\Commentable\HasComments;

class Post extends Model
{
    use HasComments;
    
    // ...   
}

If you want to enable rating feature in any commentable model (Post model in this case) add commentsAreRated() method.

By default, comments are not rated false. You can change this by adding this method and making it return true.

class Post extends Model
{
    use HasComments;

    public function commentsAreRated(): bool
    {
        return true; // return false by default
    }

    // ..
}

By default, new comments are accepted, but sometimes you don't want to approve comments for all users;

In this case add commentsAreAccepted() method and make it return false, it return true by default.

class Post extends Model
{
    use HasComments;

    public function commentsAreAccepted(): bool
    {
        return false; // return true by default
    }

    // ..
}

The owner model that uses the CanComment trait also has a commentsAreAccepted() method, which returns false by default.

You can make this method return true for admin users only for emaple, so all admin users comments be accepted automatically.

class User extends Model 
{
    use CanComment;
  
    protected $fillable = [
        'isAdmin',
        // ..
    ];

    public function commentsAreAccepted(): bool
    {
        return $this->isAdmin; // default false
    }

    // ..
}

Configuration

To configure the package, publish its configuration file:

php artisan vendor:publish --tag=commentable

You can then modify the configuration file to change the comments table name if you want, default: comments.

Usage

Adding Comments

To add a new comment, you can use the add method after for and via methods like this:

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 is the commentable model.

  • $owner is the owner of the comment.

  • $data can be a string or an array holding comment data.

  • $parent is an optional parameter to add the comment as a reply to a parent comment, default: null.

Note: We may use $post, $owner, $parent variables in the upcoming examples.

You can also add comments in a many different ways:

$data = 'this is a new parent comment';

(new Comment)->for($post)->via($owner)->add($data);

$post->addComment($data, $owner);

$owner->addComment($data, $post);

Note: all these methods accept $parent param but it's null by default. so you can do this as well:

$post->addComment($data, $post, $parent);

Editing Comments

To edit a comment, use the edit method and pass the $comment you want to edit as the first parameter:

Comment::for($post)->edit($comment, $data, $parent);
  • $comment can be the comment's ID, or the comment itself.

  • $data can be a string or an array containing the updated comment data.

  • $parent is optional and has a default value of null.

You can also edit comments using different methods:

$comment->for($post)->editTo($data);

$post->editComment($comment, $data);

$owner->editComment($comment, $data);

In this example: $comment->for($post)->editTo($data);, The for method reduces the queries executed.

But you can edit comments without it since we fetch the commentable model anyway, if you don't provide it in a for method.

Also the editComment method won't update, if comment commentable_id or owner_id is not the same as $post->id or $owner->id.

Note: all these methods accept $parent param but it's null by default. so you can do this as well:

$post->editComment($data, $post, $parent);

You can also add a parent to a comment using addParent() method

$comment->addParent($parent);

Removing Comments

To remove one or more comments, use the remove method:

Comment::remove($comment);
  • $comment can be a Comment instance, a collection of comments, an array of comment IDs, or a single comment ID.

To remove a single comment instance, you can also use:

$comment->remove();

You can remove comments in different ways:

$post->removeComment($comment);

$post->deleteComment($comment);

$owner->removeComment($comment);

$owner->deleteComment($comment);

The deleteComment and removeComment methods won't remove $comment, if comment commentable_id or owner_id is not the same as $post->id or $owner->id.

Changing Comment Status

You can change the comment status to accepted using the accept method:

$comment->accept();

To reject a comment, use the reject method:

$comment->reject();

You can also accept or reject comments on a post:

$post->acceptComment($comment);

$post->rejectComment($comment);

The acceptComment and rejectComment methods won't update $comment status, if comment commentable_id or owner_id is not the same as $post->id or $owner->id.

Rating Comments

To change the rating of a comment, use the rateIt method:

$comment->rateIt($rate);

You can also rate a comment using these methods:

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

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

rateComment returns false if $post commentsAreRated is false or commentable_id is not the same as $post->id.

You can also get the post average rate using averageRate() method.

$post->averageRate();

Getters Methods

To get comment by id, you can use Comment::getCommentOfId($id) it returns 404 if id not exist.

Comment::getCommentOfId($id); 

Note: if you give it a valid $comment instance it will return it back to you.

You can also use various getter methods to retrieve comments:

Get Post Comments

Comment::of($post)->get();

Get User Comments

Comment::by($owner)->get();

Get Post Comments by User

Comment::of($post)->by($owner)->get();

Eager Load Comment Replies and Replies Count

Comment::of($post)->by($owner)->withReplies()->withRepliesCount()->get();

Get Only Accepted Replies

Comment::of($post)->withAcceptedReplies()->get();

Comment::of($post)->withAcceptedRepliesCount()->get();

Get Only Rejected Replies

Comment::of($post)->withRejectedReplies()->get();

Comment::of($post)->withRejectedRepliesCount()->get();

These methods can also accept callback functions for further customization.

You can use callback function within the with, withCount, load and loadCount methods:

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

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

})->get();

// Or

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

    $query->whereNotNull('rate');

})->get();

You can also use with and load methods from commentable and owner models like this:

Post::withComments()->get();

Post::withAcceptedComments()->get();

User::withComments()->get();

User::withAcceptedComments()->get();

$post->loadAcceptedComments();

$owner->loadAcceptedComments();

These methods accept callback function as well.

You can also load replies/repliesCount.

$comment->loadReplies(); 

$comment->loadRepliesCount(); 

$comment->loadAcceptedReplies(); 

$comment->loadAcceptedRepliesCount(); 

$comment->loadRejectedReplies(); 

$comment->loadRejectedRepliesCount(); 

And all of them accept a callback function:

$comment->loadReplies(function ($query) {
    $query->where('accepted', true);
}); 

Relation Methods

Comment Model has this relation setup that you may need to use in your app:

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

You can get the comments from related model like this:

$post->comments();

$post->replies();

$owner->comments();

$owner->replies();

Every related model CanComment or HasComments have these built-in methods as well:

$post->morphsArray();

$owner->morphsArray();

$post->primaryId();

$owner->primaryId();

You can use the morphsArray() method to filter by commentable or owner like this:

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

But the difference is that (of, by) methods return onlyParent comments withRepliesCount.

While this code:

Comment::where($owner->morphsArray())->get();

Returns comments and replies toghter without reply count and you will have to check the parent_id to know which is the parent comment and which is the reply.

Filters

If you want to filter the comments you can use these methods:

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

You can also chain filters like this:

Comment::of($post)
    ->by($owner)
    ->onlyParents()
    ->onlyAccepted()
    ->onlyRated()
    ->get();

Checkers

You can Check if $comment has replies or parent

$comment->hasReplies();

$comment->hasParent();

You can also check if a commentable model hasCommentsBy an owner or the other way around:

$post->hasCommentsBy($owner);

$owner->hasCommentsOn($post);

Check if a $comment belongs to a related Model:

$post->hasComment($comment);

$owner->commented($comment);

Commentable Table

The structure of the coments table is as follows:

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

License

This package is released under the MIT license (MIT).

melsaka/commentable 适用场景与选型建议

melsaka/commentable 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 8 次下载、GitHub Stars 达 1, 最近一次更新时间为 2023 年 09 月 10 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 melsaka/commentable 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 melsaka/commentable 我们能提供哪些服务?
定制开发 / 二次开发

基于 melsaka/commentable 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 8
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 17
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-09-10