refactor: rename for Laravel conventions and better DX
- Rename IsCommenter trait to CanComment, Commenter interface to Commentator - Move models to Models/ namespace (Comment, Reaction, Attachment, Subscription) - Rename user_type/user_id polymorphic columns to commenter_type/commenter_id - Rename Config class to CommentsConfig, update config key tables->table_names - Rename getCommentName() to getCommentDisplayName() on commentator models - Add column_names config section for commenter morph customization - Add table_names config with all 5 tables individually configurable - Expand translation file with structured i18n groups - Update all Blade views, Livewire components, events, listeners, and tests
This commit is contained in:
@@ -5,9 +5,10 @@ namespace Relaticle\Comments;
|
||||
use App\Models\User;
|
||||
use Closure;
|
||||
use Relaticle\Comments\Mentions\DefaultMentionResolver;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
use Relaticle\Comments\Policies\CommentPolicy;
|
||||
|
||||
class Config
|
||||
class CommentsConfig
|
||||
{
|
||||
protected static ?Closure $resolveAuthenticatedUser = null;
|
||||
|
||||
@@ -23,7 +24,25 @@ class Config
|
||||
|
||||
public static function getCommentTable(): string
|
||||
{
|
||||
return config('comments.tables.comments', 'comments');
|
||||
return static::getTableName('comments');
|
||||
}
|
||||
|
||||
public static function getTableName(string $table): string
|
||||
{
|
||||
$defaults = [
|
||||
'comments' => 'comments',
|
||||
'reactions' => 'comment_reactions',
|
||||
'mentions' => 'comment_mentions',
|
||||
'subscriptions' => 'comment_subscriptions',
|
||||
'attachments' => 'comment_attachments',
|
||||
];
|
||||
|
||||
return config("comments.table_names.{$table}", $defaults[$table] ?? $table);
|
||||
}
|
||||
|
||||
public static function getCommenterMorphName(): string
|
||||
{
|
||||
return config('comments.column_names.commenter_morph', 'commenter');
|
||||
}
|
||||
|
||||
public static function getMaxDepth(): int
|
||||
@@ -42,20 +42,20 @@ class CommentsServiceProvider extends PackageServiceProvider
|
||||
public function packageRegistered(): void
|
||||
{
|
||||
Relation::morphMap([
|
||||
'comment' => Config::getCommentModel(),
|
||||
'comment' => CommentsConfig::getCommentModel(),
|
||||
]);
|
||||
|
||||
$this->app->bind(
|
||||
MentionResolver::class,
|
||||
fn () => new (Config::getMentionResolver())
|
||||
fn () => new (CommentsConfig::getMentionResolver())
|
||||
);
|
||||
}
|
||||
|
||||
public function packageBooted(): void
|
||||
{
|
||||
Gate::policy(
|
||||
Config::getCommentModel(),
|
||||
Config::getPolicyClass(),
|
||||
CommentsConfig::getCommentModel(),
|
||||
CommentsConfig::getPolicyClass(),
|
||||
);
|
||||
|
||||
Event::listen(CommentCreated::class, SendCommentRepliedNotification::class);
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace Relaticle\Comments\Concerns;
|
||||
use Filament\Models\Contracts\HasAvatar;
|
||||
use Filament\Models\Contracts\HasName;
|
||||
|
||||
trait IsCommenter
|
||||
trait CanComment
|
||||
{
|
||||
public function getCommentName(): string
|
||||
public function getCommentDisplayName(): string
|
||||
{
|
||||
if ($this instanceof HasName) {
|
||||
return $this->getFilamentName();
|
||||
@@ -3,13 +3,13 @@
|
||||
namespace Relaticle\Comments\Concerns;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
|
||||
trait HasComments
|
||||
{
|
||||
public function comments(): MorphMany
|
||||
{
|
||||
return $this->morphMany(Config::getCommentModel(), 'commentable');
|
||||
return $this->morphMany(CommentsConfig::getCommentModel(), 'commentable');
|
||||
}
|
||||
|
||||
public function topLevelComments(): MorphMany
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace Relaticle\Comments\Contracts;
|
||||
|
||||
interface Commenter
|
||||
interface Commentator
|
||||
{
|
||||
public function getKey();
|
||||
|
||||
public function getMorphClass();
|
||||
|
||||
public function getCommentName(): string;
|
||||
public function getCommentDisplayName(): string;
|
||||
|
||||
public function getCommentAvatarUrl(): ?string;
|
||||
}
|
||||
@@ -8,8 +8,8 @@ use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class CommentCreated implements ShouldBroadcast
|
||||
{
|
||||
@@ -27,7 +27,7 @@ class CommentCreated implements ShouldBroadcast
|
||||
/** @return array<int, PrivateChannel> */
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$prefix = Config::getBroadcastChannelPrefix();
|
||||
$prefix = CommentsConfig::getBroadcastChannelPrefix();
|
||||
|
||||
return [
|
||||
new PrivateChannel("{$prefix}.{$this->comment->commentable_type}.{$this->comment->commentable_id}"),
|
||||
@@ -36,7 +36,7 @@ class CommentCreated implements ShouldBroadcast
|
||||
|
||||
public function broadcastWhen(): bool
|
||||
{
|
||||
return Config::isBroadcastingEnabled();
|
||||
return CommentsConfig::isBroadcastingEnabled();
|
||||
}
|
||||
|
||||
/** @return array{comment_id: int|string, commentable_type: string, commentable_id: int|string} */
|
||||
|
||||
@@ -8,8 +8,8 @@ use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class CommentDeleted implements ShouldBroadcast
|
||||
{
|
||||
@@ -27,7 +27,7 @@ class CommentDeleted implements ShouldBroadcast
|
||||
/** @return array<int, PrivateChannel> */
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$prefix = Config::getBroadcastChannelPrefix();
|
||||
$prefix = CommentsConfig::getBroadcastChannelPrefix();
|
||||
|
||||
return [
|
||||
new PrivateChannel("{$prefix}.{$this->comment->commentable_type}.{$this->comment->commentable_id}"),
|
||||
@@ -36,7 +36,7 @@ class CommentDeleted implements ShouldBroadcast
|
||||
|
||||
public function broadcastWhen(): bool
|
||||
{
|
||||
return Config::isBroadcastingEnabled();
|
||||
return CommentsConfig::isBroadcastingEnabled();
|
||||
}
|
||||
|
||||
/** @return array{comment_id: int|string, commentable_type: string, commentable_id: int|string} */
|
||||
|
||||
@@ -7,8 +7,8 @@ use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class CommentReacted implements ShouldBroadcast
|
||||
{
|
||||
@@ -26,7 +26,7 @@ class CommentReacted implements ShouldBroadcast
|
||||
/** @return array<int, PrivateChannel> */
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$prefix = Config::getBroadcastChannelPrefix();
|
||||
$prefix = CommentsConfig::getBroadcastChannelPrefix();
|
||||
|
||||
return [
|
||||
new PrivateChannel("{$prefix}.{$this->comment->commentable_type}.{$this->comment->commentable_id}"),
|
||||
@@ -35,7 +35,7 @@ class CommentReacted implements ShouldBroadcast
|
||||
|
||||
public function broadcastWhen(): bool
|
||||
{
|
||||
return Config::isBroadcastingEnabled();
|
||||
return CommentsConfig::isBroadcastingEnabled();
|
||||
}
|
||||
|
||||
/** @return array{comment_id: int|string, reaction: string, action: string} */
|
||||
|
||||
@@ -8,8 +8,8 @@ use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class CommentUpdated implements ShouldBroadcast
|
||||
{
|
||||
@@ -27,7 +27,7 @@ class CommentUpdated implements ShouldBroadcast
|
||||
/** @return array<int, PrivateChannel> */
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$prefix = Config::getBroadcastChannelPrefix();
|
||||
$prefix = CommentsConfig::getBroadcastChannelPrefix();
|
||||
|
||||
return [
|
||||
new PrivateChannel("{$prefix}.{$this->comment->commentable_type}.{$this->comment->commentable_id}"),
|
||||
@@ -36,7 +36,7 @@ class CommentUpdated implements ShouldBroadcast
|
||||
|
||||
public function broadcastWhen(): bool
|
||||
{
|
||||
return Config::isBroadcastingEnabled();
|
||||
return CommentsConfig::isBroadcastingEnabled();
|
||||
}
|
||||
|
||||
/** @return array{comment_id: int|string, commentable_type: string, commentable_id: int|string} */
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Relaticle\Comments\Events;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class UserMentioned
|
||||
{
|
||||
|
||||
@@ -3,35 +3,35 @@
|
||||
namespace Relaticle\Comments\Listeners;
|
||||
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Relaticle\Comments\CommentSubscription;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Events\CommentCreated;
|
||||
use Relaticle\Comments\Models\Subscription;
|
||||
use Relaticle\Comments\Notifications\CommentRepliedNotification;
|
||||
|
||||
class SendCommentRepliedNotification
|
||||
{
|
||||
public function handle(CommentCreated $event): void
|
||||
{
|
||||
if (! Config::areNotificationsEnabled()) {
|
||||
if (! CommentsConfig::areNotificationsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$comment = $event->comment;
|
||||
$commentable = $event->commentable;
|
||||
|
||||
if (Config::shouldAutoSubscribe()) {
|
||||
CommentSubscription::subscribe($commentable, $comment->user);
|
||||
if (CommentsConfig::shouldAutoSubscribe()) {
|
||||
Subscription::subscribe($commentable, $comment->commenter);
|
||||
}
|
||||
|
||||
if (! $comment->isReply()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$subscribers = CommentSubscription::subscribersFor($commentable);
|
||||
$subscribers = Subscription::subscribersFor($commentable);
|
||||
|
||||
$recipients = $subscribers->filter(function ($user) use ($comment) {
|
||||
return ! ($user->getMorphClass() === $comment->user->getMorphClass()
|
||||
&& $user->getKey() === $comment->user->getKey());
|
||||
return ! ($user->getMorphClass() === $comment->commenter->getMorphClass()
|
||||
&& $user->getKey() === $comment->commenter->getKey());
|
||||
});
|
||||
|
||||
if ($recipients->isEmpty()) {
|
||||
|
||||
@@ -2,33 +2,33 @@
|
||||
|
||||
namespace Relaticle\Comments\Listeners;
|
||||
|
||||
use Relaticle\Comments\CommentSubscription;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Events\UserMentioned;
|
||||
use Relaticle\Comments\Models\Subscription;
|
||||
use Relaticle\Comments\Notifications\UserMentionedNotification;
|
||||
|
||||
class SendUserMentionedNotification
|
||||
{
|
||||
public function handle(UserMentioned $event): void
|
||||
{
|
||||
if (! Config::areNotificationsEnabled()) {
|
||||
if (! CommentsConfig::areNotificationsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$comment = $event->comment;
|
||||
$mentionedUser = $event->mentionedUser;
|
||||
|
||||
if (Config::shouldAutoSubscribe()) {
|
||||
CommentSubscription::subscribe($comment->commentable, $mentionedUser);
|
||||
if (CommentsConfig::shouldAutoSubscribe()) {
|
||||
Subscription::subscribe($comment->commentable, $mentionedUser);
|
||||
}
|
||||
|
||||
$isSelf = $mentionedUser->getMorphClass() === $comment->user->getMorphClass()
|
||||
&& $mentionedUser->getKey() === $comment->user->getKey();
|
||||
$isSelf = $mentionedUser->getMorphClass() === $comment->commenter->getMorphClass()
|
||||
&& $mentionedUser->getKey() === $comment->commenter->getKey();
|
||||
|
||||
if ($isSelf) {
|
||||
return;
|
||||
}
|
||||
|
||||
$mentionedUser->notify(new UserMentionedNotification($comment, $comment->user));
|
||||
$mentionedUser->notify(new UserMentionedNotification($comment, $comment->commenter));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ use Illuminate\Contracts\View\View;
|
||||
use Livewire\Component;
|
||||
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
|
||||
use Livewire\WithFileUploads;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Contracts\MentionResolver;
|
||||
use Relaticle\Comments\Events\CommentCreated;
|
||||
use Relaticle\Comments\Events\CommentDeleted;
|
||||
use Relaticle\Comments\Events\CommentUpdated;
|
||||
use Relaticle\Comments\Mentions\MentionParser;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class CommentItem extends Component
|
||||
{
|
||||
@@ -106,25 +106,25 @@ class CommentItem extends Component
|
||||
|
||||
$rules = ['replyBody' => ['required', 'string', 'min:1']];
|
||||
|
||||
if (Config::areAttachmentsEnabled()) {
|
||||
$maxSize = Config::getAttachmentMaxSize();
|
||||
$allowedTypes = implode(',', Config::getAttachmentAllowedTypes());
|
||||
if (CommentsConfig::areAttachmentsEnabled()) {
|
||||
$maxSize = CommentsConfig::getAttachmentMaxSize();
|
||||
$allowedTypes = implode(',', CommentsConfig::getAttachmentAllowedTypes());
|
||||
$rules['replyAttachments.*'] = ['nullable', 'file', "max:{$maxSize}", "mimetypes:{$allowedTypes}"];
|
||||
}
|
||||
|
||||
$this->validate($rules);
|
||||
|
||||
$user = Config::resolveAuthenticatedUser();
|
||||
$user = CommentsConfig::resolveAuthenticatedUser();
|
||||
|
||||
$reply = $this->comment->commentable->comments()->create([
|
||||
'body' => $this->replyBody,
|
||||
'parent_id' => $this->comment->id,
|
||||
'user_id' => $user->getKey(),
|
||||
'user_type' => $user->getMorphClass(),
|
||||
'commenter_id' => $user->getKey(),
|
||||
'commenter_type' => $user->getMorphClass(),
|
||||
]);
|
||||
|
||||
if (Config::areAttachmentsEnabled() && ! empty($this->replyAttachments)) {
|
||||
$disk = Config::getAttachmentDisk();
|
||||
if (CommentsConfig::areAttachmentsEnabled() && ! empty($this->replyAttachments)) {
|
||||
$disk = CommentsConfig::getAttachmentDisk();
|
||||
|
||||
foreach ($this->replyAttachments as $file) {
|
||||
$path = $file->store("comments/attachments/{$reply->id}", $disk);
|
||||
@@ -169,7 +169,7 @@ class CommentItem extends Component
|
||||
return $resolver->search($query)
|
||||
->map(fn ($user) => [
|
||||
'id' => $user->getKey(),
|
||||
'name' => $user->getCommentName(),
|
||||
'name' => $user->getCommentDisplayName(),
|
||||
'avatar_url' => $user->getCommentAvatarUrl(),
|
||||
])
|
||||
->values()
|
||||
|
||||
@@ -9,12 +9,12 @@ use Livewire\Attributes\Computed;
|
||||
use Livewire\Component;
|
||||
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
|
||||
use Livewire\WithFileUploads;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\CommentSubscription;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Contracts\MentionResolver;
|
||||
use Relaticle\Comments\Events\CommentCreated;
|
||||
use Relaticle\Comments\Mentions\MentionParser;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
use Relaticle\Comments\Models\Subscription;
|
||||
|
||||
class Comments extends Component
|
||||
{
|
||||
@@ -36,7 +36,7 @@ class Comments extends Component
|
||||
public function mount(Model $model): void
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->perPage = Config::getPerPage();
|
||||
$this->perPage = CommentsConfig::getPerPage();
|
||||
$this->loadedCount = $this->perPage;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class Comments extends Component
|
||||
{
|
||||
return $this->model
|
||||
->topLevelComments()
|
||||
->with(['user', 'mentions', 'attachments', 'reactions.user', 'replies.user', 'replies.mentions', 'replies.attachments', 'replies.reactions.user'])
|
||||
->with(['commenter', 'mentions', 'attachments', 'reactions.commenter', 'replies.commenter', 'replies.mentions', 'replies.attachments', 'replies.reactions.commenter'])
|
||||
->orderBy('created_at', $this->sortDirection)
|
||||
->take($this->loadedCount)
|
||||
->get();
|
||||
@@ -67,27 +67,27 @@ class Comments extends Component
|
||||
#[Computed]
|
||||
public function isSubscribed(): bool
|
||||
{
|
||||
$user = Config::resolveAuthenticatedUser();
|
||||
$user = CommentsConfig::resolveAuthenticatedUser();
|
||||
|
||||
if (! $user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CommentSubscription::isSubscribed($this->model, $user);
|
||||
return Subscription::isSubscribed($this->model, $user);
|
||||
}
|
||||
|
||||
public function toggleSubscription(): void
|
||||
{
|
||||
$user = Config::resolveAuthenticatedUser();
|
||||
$user = CommentsConfig::resolveAuthenticatedUser();
|
||||
|
||||
if (! $user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->isSubscribed) {
|
||||
CommentSubscription::unsubscribe($this->model, $user);
|
||||
Subscription::unsubscribe($this->model, $user);
|
||||
} else {
|
||||
CommentSubscription::subscribe($this->model, $user);
|
||||
Subscription::subscribe($this->model, $user);
|
||||
}
|
||||
|
||||
unset($this->isSubscribed);
|
||||
@@ -97,26 +97,26 @@ class Comments extends Component
|
||||
{
|
||||
$rules = ['newComment' => ['required', 'string', 'min:1']];
|
||||
|
||||
if (Config::areAttachmentsEnabled()) {
|
||||
$maxSize = Config::getAttachmentMaxSize();
|
||||
$allowedTypes = implode(',', Config::getAttachmentAllowedTypes());
|
||||
if (CommentsConfig::areAttachmentsEnabled()) {
|
||||
$maxSize = CommentsConfig::getAttachmentMaxSize();
|
||||
$allowedTypes = implode(',', CommentsConfig::getAttachmentAllowedTypes());
|
||||
$rules['attachments.*'] = ['nullable', 'file', "max:{$maxSize}", "mimetypes:{$allowedTypes}"];
|
||||
}
|
||||
|
||||
$this->validate($rules);
|
||||
|
||||
$this->authorize('create', Config::getCommentModel());
|
||||
$this->authorize('create', CommentsConfig::getCommentModel());
|
||||
|
||||
$user = Config::resolveAuthenticatedUser();
|
||||
$user = CommentsConfig::resolveAuthenticatedUser();
|
||||
|
||||
$comment = $this->model->comments()->create([
|
||||
'body' => $this->newComment,
|
||||
'user_id' => $user->getKey(),
|
||||
'user_type' => $user->getMorphClass(),
|
||||
'commenter_id' => $user->getKey(),
|
||||
'commenter_type' => $user->getMorphClass(),
|
||||
]);
|
||||
|
||||
if (Config::areAttachmentsEnabled() && ! empty($this->attachments)) {
|
||||
$disk = Config::getAttachmentDisk();
|
||||
if (CommentsConfig::areAttachmentsEnabled() && ! empty($this->attachments)) {
|
||||
$disk = CommentsConfig::getAttachmentDisk();
|
||||
|
||||
foreach ($this->attachments as $file) {
|
||||
$path = $file->store("comments/attachments/{$comment->id}", $disk);
|
||||
@@ -163,8 +163,8 @@ class Comments extends Component
|
||||
'commentUpdated' => 'refreshComments',
|
||||
];
|
||||
|
||||
if (Config::isBroadcastingEnabled()) {
|
||||
$prefix = Config::getBroadcastChannelPrefix();
|
||||
if (CommentsConfig::isBroadcastingEnabled()) {
|
||||
$prefix = CommentsConfig::getBroadcastChannelPrefix();
|
||||
$type = $this->model->getMorphClass();
|
||||
$id = $this->model->getKey();
|
||||
$channel = "echo-private:{$prefix}.{$type}.{$id}";
|
||||
@@ -195,7 +195,7 @@ class Comments extends Component
|
||||
return $resolver->search($query)
|
||||
->map(fn ($user) => [
|
||||
'id' => $user->getKey(),
|
||||
'name' => $user->getCommentName(),
|
||||
'name' => $user->getCommentDisplayName(),
|
||||
'avatar_url' => $user->getCommentAvatarUrl(),
|
||||
])
|
||||
->values()
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace Relaticle\Comments\Livewire;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Livewire\Attributes\Computed;
|
||||
use Livewire\Component;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Events\CommentReacted;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class Reactions extends Component
|
||||
{
|
||||
@@ -22,19 +22,19 @@ class Reactions extends Component
|
||||
|
||||
public function toggleReaction(string $reaction): void
|
||||
{
|
||||
$user = Config::resolveAuthenticatedUser();
|
||||
$user = CommentsConfig::resolveAuthenticatedUser();
|
||||
|
||||
if (! $user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! in_array($reaction, Config::getAllowedReactions())) {
|
||||
if (! in_array($reaction, CommentsConfig::getAllowedReactions())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$existing = $this->comment->reactions()
|
||||
->where('user_id', $user->getKey())
|
||||
->where('user_type', $user->getMorphClass())
|
||||
->where('commenter_id', $user->getKey())
|
||||
->where('commenter_type', $user->getMorphClass())
|
||||
->where('reaction', $reaction)
|
||||
->first();
|
||||
|
||||
@@ -44,8 +44,8 @@ class Reactions extends Component
|
||||
event(new CommentReacted($this->comment, $user, $reaction, 'removed'));
|
||||
} else {
|
||||
$this->comment->reactions()->create([
|
||||
'user_id' => $user->getKey(),
|
||||
'user_type' => $user->getMorphClass(),
|
||||
'commenter_id' => $user->getKey(),
|
||||
'commenter_type' => $user->getMorphClass(),
|
||||
'reaction' => $reaction,
|
||||
]);
|
||||
|
||||
@@ -66,13 +66,13 @@ class Reactions extends Component
|
||||
#[Computed]
|
||||
public function reactionSummary(): array
|
||||
{
|
||||
$user = Config::resolveAuthenticatedUser();
|
||||
$user = CommentsConfig::resolveAuthenticatedUser();
|
||||
$userId = $user?->getKey();
|
||||
$userType = $user?->getMorphClass();
|
||||
|
||||
$reactions = $this->comment->reactions()->with('user')->get();
|
||||
$reactions = $this->comment->reactions()->with('commenter')->get();
|
||||
|
||||
$emojiSet = Config::getReactionEmojiSet();
|
||||
$emojiSet = CommentsConfig::getReactionEmojiSet();
|
||||
|
||||
return $reactions
|
||||
->groupBy('reaction')
|
||||
@@ -81,10 +81,10 @@ class Reactions extends Component
|
||||
'reaction' => $key,
|
||||
'emoji' => $emojiSet[$key] ?? $key,
|
||||
'count' => $group->count(),
|
||||
'names' => $group->pluck('user.name')->filter()->take(3)->values()->all(),
|
||||
'names' => $group->pluck('commenter.name')->filter()->take(3)->values()->all(),
|
||||
'total_reactors' => $group->count(),
|
||||
'reacted_by_user' => $group->contains(
|
||||
fn ($r) => $r->user_id == $userId && $r->user_type === $userType
|
||||
fn ($r) => $r->commenter_id == $userId && $r->commenter_type === $userType
|
||||
),
|
||||
];
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Relaticle\Comments\Mentions;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Contracts\MentionResolver;
|
||||
|
||||
class DefaultMentionResolver implements MentionResolver
|
||||
@@ -12,18 +12,18 @@ class DefaultMentionResolver implements MentionResolver
|
||||
/** @return Collection<int, Model> */
|
||||
public function search(string $query): Collection
|
||||
{
|
||||
$model = Config::getCommenterModel();
|
||||
$model = CommentsConfig::getCommenterModel();
|
||||
|
||||
return $model::query()
|
||||
->where('name', 'like', "{$query}%")
|
||||
->limit(Config::getMentionMaxResults())
|
||||
->limit(CommentsConfig::getMentionMaxResults())
|
||||
->get();
|
||||
}
|
||||
|
||||
/** @return Collection<int, Model> */
|
||||
public function resolveByNames(array $names): Collection
|
||||
{
|
||||
$model = Config::getCommenterModel();
|
||||
$model = CommentsConfig::getCommenterModel();
|
||||
|
||||
return $model::query()
|
||||
->whereIn('name', $names)
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
namespace Relaticle\Comments\Mentions;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Contracts\MentionResolver;
|
||||
use Relaticle\Comments\Events\UserMentioned;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class MentionParser
|
||||
{
|
||||
@@ -33,13 +33,13 @@ class MentionParser
|
||||
public function syncMentions(Comment $comment): void
|
||||
{
|
||||
$newMentionIds = $this->parse($comment->body);
|
||||
$existingMentionIds = $comment->mentions()->pluck('comment_mentions.user_id');
|
||||
$existingMentionIds = $comment->mentions()->pluck('comment_mentions.commenter_id');
|
||||
|
||||
$addedIds = $newMentionIds->diff($existingMentionIds);
|
||||
|
||||
$comment->mentions()->sync($newMentionIds->all());
|
||||
|
||||
$commenterModel = Config::getCommenterModel();
|
||||
$commenterModel = CommentsConfig::getCommenterModel();
|
||||
|
||||
$addedIds->each(function ($userId) use ($comment, $commenterModel) {
|
||||
$mentionedUser = $commenterModel::find($userId);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Relaticle\Comments;
|
||||
namespace Relaticle\Comments\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Number;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
|
||||
class CommentAttachment extends Model
|
||||
class Attachment extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'comment_id',
|
||||
@@ -20,12 +21,12 @@ class CommentAttachment extends Model
|
||||
|
||||
public function getTable(): string
|
||||
{
|
||||
return 'comment_attachments';
|
||||
return CommentsConfig::getTableName('attachments');
|
||||
}
|
||||
|
||||
public function comment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Config::getCommentModel());
|
||||
return $this->belongsTo(CommentsConfig::getCommentModel());
|
||||
}
|
||||
|
||||
public function isImage(): bool
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Relaticle\Comments;
|
||||
namespace Relaticle\Comments\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Database\Factories\CommentFactory;
|
||||
|
||||
class Comment extends Model
|
||||
@@ -35,14 +36,14 @@ class Comment extends Model
|
||||
protected $fillable = [
|
||||
'body',
|
||||
'parent_id',
|
||||
'user_id',
|
||||
'user_type',
|
||||
'commenter_id',
|
||||
'commenter_type',
|
||||
'edited_at',
|
||||
];
|
||||
|
||||
public function getTable(): string
|
||||
{
|
||||
return Config::getCommentTable();
|
||||
return CommentsConfig::getCommentTable();
|
||||
}
|
||||
|
||||
/** @return array<string, string> */
|
||||
@@ -63,39 +64,39 @@ class Comment extends Model
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function user(): MorphTo
|
||||
public function commenter(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Config::getCommentModel(), 'parent_id');
|
||||
return $this->belongsTo(CommentsConfig::getCommentModel(), 'parent_id');
|
||||
}
|
||||
|
||||
public function replies(): HasMany
|
||||
{
|
||||
return $this->hasMany(Config::getCommentModel(), 'parent_id');
|
||||
return $this->hasMany(CommentsConfig::getCommentModel(), 'parent_id');
|
||||
}
|
||||
|
||||
public function reactions(): HasMany
|
||||
{
|
||||
return $this->hasMany(CommentReaction::class);
|
||||
return $this->hasMany(Reaction::class);
|
||||
}
|
||||
|
||||
public function attachments(): HasMany
|
||||
{
|
||||
return $this->hasMany(CommentAttachment::class);
|
||||
return $this->hasMany(Attachment::class);
|
||||
}
|
||||
|
||||
public function mentions(): MorphToMany
|
||||
{
|
||||
return $this->morphedByMany(
|
||||
Config::getCommenterModel(),
|
||||
'user',
|
||||
'comment_mentions',
|
||||
CommentsConfig::getCommenterModel(),
|
||||
'commenter',
|
||||
CommentsConfig::getTableName('mentions'),
|
||||
'comment_id',
|
||||
'user_id',
|
||||
'commenter_id',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -121,7 +122,7 @@ class Comment extends Model
|
||||
|
||||
public function canReply(): bool
|
||||
{
|
||||
return $this->depth() < Config::getMaxDepth();
|
||||
return $this->depth() < CommentsConfig::getMaxDepth();
|
||||
}
|
||||
|
||||
public function depth(): int
|
||||
@@ -133,8 +134,8 @@ class Comment extends Model
|
||||
$comment = $comment->parent;
|
||||
$depth++;
|
||||
|
||||
if ($depth >= Config::getMaxDepth()) {
|
||||
return Config::getMaxDepth();
|
||||
if ($depth >= CommentsConfig::getMaxDepth()) {
|
||||
return CommentsConfig::getMaxDepth();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Relaticle\Comments;
|
||||
namespace Relaticle\Comments\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
|
||||
class CommentReaction extends Model
|
||||
class Reaction extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'comment_id',
|
||||
'user_id',
|
||||
'user_type',
|
||||
'commenter_id',
|
||||
'commenter_type',
|
||||
'reaction',
|
||||
];
|
||||
|
||||
public function getTable(): string
|
||||
{
|
||||
return 'comment_reactions';
|
||||
return CommentsConfig::getTableName('reactions');
|
||||
}
|
||||
|
||||
public function comment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Config::getCommentModel());
|
||||
return $this->belongsTo(CommentsConfig::getCommentModel());
|
||||
}
|
||||
|
||||
public function user(): MorphTo
|
||||
public function commenter(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
@@ -1,25 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Relaticle\Comments;
|
||||
namespace Relaticle\Comments\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Illuminate\Support\Collection;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
|
||||
class CommentSubscription extends Model
|
||||
class Subscription extends Model
|
||||
{
|
||||
public const UPDATED_AT = null;
|
||||
|
||||
protected $fillable = [
|
||||
'commentable_type',
|
||||
'commentable_id',
|
||||
'user_type',
|
||||
'user_id',
|
||||
'commenter_type',
|
||||
'commenter_id',
|
||||
];
|
||||
|
||||
public function getTable(): string
|
||||
{
|
||||
return 'comment_subscriptions';
|
||||
return CommentsConfig::getTableName('subscriptions');
|
||||
}
|
||||
|
||||
public function commentable(): MorphTo
|
||||
@@ -27,7 +28,7 @@ class CommentSubscription extends Model
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function user(): MorphTo
|
||||
public function commenter(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
@@ -37,8 +38,8 @@ class CommentSubscription extends Model
|
||||
return static::where([
|
||||
'commentable_type' => $commentable->getMorphClass(),
|
||||
'commentable_id' => $commentable->getKey(),
|
||||
'user_type' => $user->getMorphClass(),
|
||||
'user_id' => $user->getKey(),
|
||||
'commenter_type' => $user->getMorphClass(),
|
||||
'commenter_id' => $user->getKey(),
|
||||
])->exists();
|
||||
}
|
||||
|
||||
@@ -47,8 +48,8 @@ class CommentSubscription extends Model
|
||||
static::firstOrCreate([
|
||||
'commentable_type' => $commentable->getMorphClass(),
|
||||
'commentable_id' => $commentable->getKey(),
|
||||
'user_type' => $user->getMorphClass(),
|
||||
'user_id' => $user->getKey(),
|
||||
'commenter_type' => $user->getMorphClass(),
|
||||
'commenter_id' => $user->getKey(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -57,8 +58,8 @@ class CommentSubscription extends Model
|
||||
static::where([
|
||||
'commentable_type' => $commentable->getMorphClass(),
|
||||
'commentable_id' => $commentable->getKey(),
|
||||
'user_type' => $user->getMorphClass(),
|
||||
'user_id' => $user->getKey(),
|
||||
'commenter_type' => $user->getMorphClass(),
|
||||
'commenter_id' => $user->getKey(),
|
||||
])->delete();
|
||||
}
|
||||
|
||||
@@ -68,6 +69,6 @@ class CommentSubscription extends Model
|
||||
return static::where([
|
||||
'commentable_type' => $commentable->getMorphClass(),
|
||||
'commentable_id' => $commentable->getKey(),
|
||||
])->with('user')->get()->pluck('user')->filter()->values();
|
||||
])->with('commenter')->get()->pluck('commenter')->filter()->values();
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@ namespace Relaticle\Comments\Notifications;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Str;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class CommentRepliedNotification extends Notification
|
||||
{
|
||||
@@ -15,7 +15,7 @@ class CommentRepliedNotification extends Notification
|
||||
/** @return array<int, string> */
|
||||
public function via(mixed $notifiable): array
|
||||
{
|
||||
return Config::getNotificationChannels();
|
||||
return CommentsConfig::getNotificationChannels();
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
@@ -25,14 +25,14 @@ class CommentRepliedNotification extends Notification
|
||||
'comment_id' => $this->comment->id,
|
||||
'commentable_type' => $this->comment->commentable_type,
|
||||
'commentable_id' => $this->comment->commentable_id,
|
||||
'commenter_name' => $this->comment->user->getCommentName(),
|
||||
'commenter_name' => $this->comment->commenter->getCommentDisplayName(),
|
||||
'body' => Str::limit(strip_tags($this->comment->body), 100),
|
||||
];
|
||||
}
|
||||
|
||||
public function toMail(mixed $notifiable): MailMessage
|
||||
{
|
||||
$commenterName = $this->comment->user->getCommentName();
|
||||
$commenterName = $this->comment->commenter->getCommentDisplayName();
|
||||
|
||||
return (new MailMessage)
|
||||
->subject('New reply to your comment')
|
||||
|
||||
@@ -6,8 +6,8 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Str;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Config;
|
||||
use Relaticle\Comments\CommentsConfig;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class UserMentionedNotification extends Notification
|
||||
{
|
||||
@@ -19,7 +19,7 @@ class UserMentionedNotification extends Notification
|
||||
/** @return array<int, string> */
|
||||
public function via(mixed $notifiable): array
|
||||
{
|
||||
return Config::getNotificationChannels();
|
||||
return CommentsConfig::getNotificationChannels();
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
@@ -29,14 +29,14 @@ class UserMentionedNotification extends Notification
|
||||
'comment_id' => $this->comment->id,
|
||||
'commentable_type' => $this->comment->commentable_type,
|
||||
'commentable_id' => $this->comment->commentable_id,
|
||||
'mentioner_name' => $this->mentionedBy->getCommentName(),
|
||||
'mentioner_name' => $this->mentionedBy->getCommentDisplayName(),
|
||||
'body' => Str::limit(strip_tags($this->comment->body), 100),
|
||||
];
|
||||
}
|
||||
|
||||
public function toMail(mixed $notifiable): MailMessage
|
||||
{
|
||||
$mentionerName = $this->mentionedBy->getCommentName();
|
||||
$mentionerName = $this->mentionedBy->getCommentDisplayName();
|
||||
|
||||
return (new MailMessage)
|
||||
->subject('You were mentioned in a comment')
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Relaticle\Comments\Policies;
|
||||
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Models\Comment;
|
||||
|
||||
class CommentPolicy
|
||||
{
|
||||
@@ -19,14 +19,14 @@ class CommentPolicy
|
||||
|
||||
public function update(Authenticatable $user, Comment $comment): bool
|
||||
{
|
||||
return $user->getKey() === $comment->user_id
|
||||
&& $user->getMorphClass() === $comment->user_type;
|
||||
return $user->getKey() === $comment->commenter_id
|
||||
&& $user->getMorphClass() === $comment->commenter_type;
|
||||
}
|
||||
|
||||
public function delete(Authenticatable $user, Comment $comment): bool
|
||||
{
|
||||
return $user->getKey() === $comment->user_id
|
||||
&& $user->getMorphClass() === $comment->user_type;
|
||||
return $user->getKey() === $comment->commenter_id
|
||||
&& $user->getMorphClass() === $comment->commenter_type;
|
||||
}
|
||||
|
||||
public function reply(Authenticatable $user, Comment $comment): bool
|
||||
|
||||
Reference in New Issue
Block a user