Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/fix-php-code-style-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,11 @@ jobs:
branch: php-style-fixes
title: Fix PHP Code Styling
labels: code-style
auto-merge: true
delete-branch: true

- name: Auto-merge Pull Request
uses: pascalgn/[email protected]
with:
merge-method: squash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"require": {
"php": "^8.2",
"filament/filament": "^3",
"kalnoy/nestedset": "^6.0",
"spatie/laravel-package-tools": "^1.15.0"
},
"require-dev": {
Expand Down Expand Up @@ -71,4 +72,4 @@
},
"minimum-stability": "dev",
"prefer-stable": true
}
}
31 changes: 30 additions & 1 deletion config/nested-comments.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
<?php

// config for Coolsam/NestedComments
return [
'tables' => [
'comments' => 'comments',
'reactions' => 'reactions',
'users' => 'users', // The table that will be used to get the authenticated user
],

'models' => [
'comment' => \Coolsam\NestedComments\Models\Comment::class,
'reaction' => \Coolsam\NestedComments\Models\Reaction::class,
'user' => env( 'AUTH_MODEL', 'App\Models\User'), // The model that will be used to get the authenticated user

Check failure on line 13 in config/nested-comments.php

View workflow job for this annotation

GitHub Actions / phpstan

Called 'env' outside of the config directory which returns null when the config is cached, use 'config'.
],

'policies' => [
'comment' => null,
'reaction' => null,
],
'allowed-reactions' => [
'👍', // thumbs up
'👎', // thumbs down
'❤️', // heart
'😂', // laughing
'😮', // surprised
'😢', // crying
'😡', // angry
'🔥', // fire
'🎉', // party popper
'🚀', // rocket
],
'allow-multiple-reactions' => env('ALLOW_MULTIPLE_REACTIONS', false), // Allow multiple reactions from the same user

Check failure on line 32 in config/nested-comments.php

View workflow job for this annotation

GitHub Actions / phpstan

Called 'env' outside of the config directory which returns null when the config is cached, use 'config'.
'allow-guest-reactions' => env('ALLOW_GUEST_REACTIONS', false), // Allow guest users to react

Check failure on line 33 in config/nested-comments.php

View workflow job for this annotation

GitHub Actions / phpstan

Called 'env' outside of the config directory which returns null when the config is cached, use 'config'.
'allow-guest-comments' => env('ALLOW_GUEST_COMMENTS', false), // Allow guest users to comment

Check failure on line 34 in config/nested-comments.php

View workflow job for this annotation

GitHub Actions / phpstan

Called 'env' outside of the config directory which returns null when the config is cached, use 'config'.
];
25 changes: 22 additions & 3 deletions database/migrations/create_nested_comments_table.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,37 @@

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up()
{
Schema::create('nested_comments_table', function (Blueprint $table) {
$users = Config::get('nested-comments.tables.users', 'users');
Schema::create(Config::get('nested-comments.tables.comments'), function (Blueprint $table) use ($users) {
$table->id();
$table->nestedSet();
$table->foreignId('user_id')->nullable()->constrained($users)->cascadeOnDelete();
$table->text('body');
$table->morphs('commentable');
$table->ipAddress()->nullable();
$table->timestamps();
});

// add fields

Schema::create(Config::get('nested-comments.tables.reactions'), function (Blueprint $table) use ($users) {
$table->id();
$table->foreignId('user_id')->nullable()->constrained($users)->cascadeOnDelete();
$table->morphs('reactable');
$table->string('emoji');
$table->ipAddress()->nullable();
$table->timestamps();
});
}

public function down()
{
Schema::dropIfExists(Config::get('nested-comments.tables.reactions'));
Schema::dropIfExists(Config::get('nested-comments.tables.comments'));
}
};
136 changes: 135 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@tailwindcss/typography": "^0.5.9",
"autoprefixer": "^10.4.14",
"esbuild": "^0.25.2",
"flowbite": "^3.1.2",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.26",
"postcss-import": "^15.1.0",
Expand Down
85 changes: 85 additions & 0 deletions src/Concerns/HasComments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace Coolsam\NestedComments\Concerns;

use Coolsam\NestedComments\Models\Comment;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;

/**
* @mixin Model
*/
trait HasComments

Check failure on line 12 in src/Concerns/HasComments.php

View workflow job for this annotation

GitHub Actions / phpstan

Trait Coolsam\NestedComments\Concerns\HasComments is used zero times and is not analysed.
{
public function comments(): MorphMany
{
return $this->morphMany(config('nested-comments.models.comment'), 'commentable');
}

public function getCommentsCountAttribute(): int
{
return $this->comments()->count();
}

public function getCommentsTree($offset = null, $limit = null, $columns = ['*'])
{
$query = $this->comments()
->getQuery()
->where('parent_id', '=', null);
if (filled($offset)) {
$query->offset($offset);
}
if (filled($limit)) {
$query->limit($limit);
}

$columns = ['id', 'parent_id', '_lft', '_rgt', ...$columns];

return collect($query->get($columns)->map(function (Comment $comment) use ($columns) {
$descendants = $comment->getDescendants($columns);
return collect($comment->toArray())->put('descendants', $descendants->toArray());
})->toArray());
}

/**
* @throws \Exception
*/
public function addComment(string $comment, mixed $parentId = null)
{
$allowGuest = config('nested-comments.allow-guest-comments', false);
if (! $allowGuest && ! auth()->check()) {
throw new \Exception('You must be logged in to comment.');
}

if ($allowGuest && ! auth()->check()) {
$userId = null;
} else {
$userId = auth()->id();
}

return $this->comments()->create([
'user_id' => $userId,
'body' => $comment,
'commentable_id' => $this->getKey(),
'commentable_type' => $this->getMorphClass(),
'parent_id' => $parentId,
'ip_address' => request()->ip(),
]);
}

/**
* @throws \Exception
*/
public function deleteComment(Comment $comment): ?bool
{
if (! auth()->check()) {
throw new \Exception('You must be logged in to delete your comment.');
}

if ($comment->getAttribute('user_id') !== auth()->id()) {
throw new \Exception('You are not authorized to delete this comment.');
}

return $comment->delete();
}
}
Loading
Loading