diff --git a/composer.json b/composer.json index 24bb795..5888f7c 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ } }, "scripts": { - "test": "vendor/bin/phpunit", + "test": "XDEBUG_MODE=coverage vendor/bin/phpunit", "test-coverage": "vendor/bin/phpunit --coverage-html coverage" }, "config": { diff --git a/config/config.php b/config/config.php index 9c3c85b..1bfbdde 100644 --- a/config/config.php +++ b/config/config.php @@ -15,4 +15,8 @@ return [ */ 'user_model' => null, + /** + * Determines if replies will be deleted when comments are deleted + */ + 'delete_replies_along_comments' => false, ]; \ No newline at end of file diff --git a/src/Comment.php b/src/Comment.php index ebacf3b..48b4fba 100644 --- a/src/Comment.php +++ b/src/Comment.php @@ -2,6 +2,8 @@ namespace BeyondCode\Comments; +use BeyondCode\Comments\Events\CommentAdded; +use BeyondCode\Comments\Events\CommentDeleted; use Exception; use Illuminate\Database\Eloquent\Model; use BeyondCode\Comments\Traits\HasComments; @@ -20,6 +22,25 @@ class Comment extends Model 'is_approved' => 'boolean' ]; + public static function boot(): void + { + parent::boot(); + + static::deleting(function (self $model) { + if (config('comments.delete_replies_along_comments')) { + $model->comments()->delete(); + } + }); + + static::deleted(function (self $model) { + CommentDeleted::dispatch($model); + }); + + static::created(function (self $model) { + CommentAdded::dispatch($model); + }); + } + public function scopeApproved($query) { return $query->where('is_approved', true); @@ -43,7 +64,7 @@ class Comment extends Model return $this; } - + public function disapprove() { $this->update([ @@ -65,5 +86,4 @@ class Comment extends Model throw new Exception('Could not determine the commentator model name.'); } - -} +} \ No newline at end of file diff --git a/src/Events/CommentAdded.php b/src/Events/CommentAdded.php new file mode 100644 index 0000000..fbfd42b --- /dev/null +++ b/src/Events/CommentAdded.php @@ -0,0 +1,22 @@ + $comment, - 'is_approved' => ($user instanceof Commentator) ? ! $user->needsCommentApproval($this) : false, + 'is_approved' => ($user instanceof Commentator) ? !$user->needsCommentApproval($this) : false, 'user_id' => is_null($user) ? null : $user->getKey(), 'commentable_id' => $this->getKey(), 'commentable_type' => get_class(), @@ -51,5 +51,4 @@ trait HasComments return $this->comments()->save($comment); } - } \ No newline at end of file diff --git a/tests/CommentsTest.php b/tests/CommentsTest.php index e20a05c..2df950e 100644 --- a/tests/CommentsTest.php +++ b/tests/CommentsTest.php @@ -2,9 +2,13 @@ namespace BeyondCode\Comments\Tests; +use BeyondCode\Comments\Events\CommentAdded; +use BeyondCode\Comments\Events\CommentDeleted; use BeyondCode\Comments\Tests\Models\ApprovedUser; use BeyondCode\Comments\Tests\Models\Post; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Foundation\Auth\User; +use Illuminate\Support\Facades\Event; class CommentsTest extends TestCase { @@ -145,4 +149,69 @@ class CommentsTest extends TestCase $this->assertSame('this comment is approved', $post->comments()->approved()->first()->comment); } -} + + /** @test */ + public function comments_are_deleted_when_posts_are_deleted() + { + $post = Post::create([ + 'title' => 'Some post' + ]); + + $comment = $post->comment('this comment will be deleted'); + + $post->delete(); + + $this->assertFalse($comment->exists()); + } + + /** @test */ + public function replies_are_deleted_when_post_comments_are_deleted() + { + config(['comments.delete_replies_along_comments' => true]); + + $post = Post::create([ + 'title' => 'Some post' + ]); + + $comment = $post->comment('this comment will be deleted'); + $reply = $comment->comment('this comment will be deleted too'); + + $comment->delete(); + + $this->assertFalse($reply->exists()); + } + + /** @test */ + public function comment_added_event_is_dispatched_when_comment_is_created() + { + Event::fake([CommentAdded::class]); + + $post = Post::create([ + 'title' => 'Some post' + ]); + + $comment = $post->comment('this comment is added'); + + Event::assertDispatched(CommentAdded::class, function ($event) use ($comment) { + return $event->comment->is($comment); + }); + } + + /** @test */ + public function comment_deleted_event_is_dispatched_when_comment_is_deleted() + { + Event::fake([CommentDeleted::class]); + + $post = Post::create([ + 'title' => 'Some post' + ]); + + $comment = $post->comment('this comment is added'); + + $comment->delete(); + + Event::assertDispatched(CommentDeleted::class, function ($event) use ($comment) { + return $event->comment->is($comment); + }); + } +} \ No newline at end of file diff --git a/tests/Models/Post.php b/tests/Models/Post.php index 8260dc6..c8997a3 100644 --- a/tests/Models/Post.php +++ b/tests/Models/Post.php @@ -3,6 +3,7 @@ namespace BeyondCode\Comments\Tests\Models; use BeyondCode\Comments\Traits\HasComments; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Post extends Model @@ -10,4 +11,13 @@ class Post extends Model use HasComments; protected $guarded = []; -} \ No newline at end of file + + public static function boot(): void + { + parent::boot(); + + static::deleting(function (self $model) { + $model->comments()->delete(); + }); + } +}