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:
manukminasyan
2026-03-27 14:53:12 +04:00
parent 43b66f60f3
commit fd5bc5271b
62 changed files with 733 additions and 653 deletions

176
src/CommentsConfig.php Normal file
View File

@@ -0,0 +1,176 @@
<?php
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 CommentsConfig
{
protected static ?Closure $resolveAuthenticatedUser = null;
public static function getCommentModel(): string
{
return config('comments.models.comment', Comment::class);
}
public static function getCommenterModel(): string
{
return config('comments.commenter.model', User::class);
}
public static function getCommentTable(): string
{
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
{
return (int) config('comments.threading.max_depth', 2);
}
public static function getPerPage(): int
{
return (int) config('comments.pagination.per_page', 10);
}
/** @return array<int, array<int, string>> */
public static function getEditorToolbar(): array
{
return (array) config('comments.editor.toolbar', [
['bold', 'italic', 'strike', 'link'],
['bulletList', 'orderedList'],
['codeBlock'],
]);
}
public static function getPolicyClass(): string
{
return config('comments.policy', CommentPolicy::class);
}
public static function getMentionResolver(): string
{
return config('comments.mentions.resolver', DefaultMentionResolver::class);
}
public static function getMentionMaxResults(): int
{
return (int) config('comments.mentions.max_results', 5);
}
/** @return array<string, string> */
public static function getReactionEmojiSet(): array
{
return (array) config('comments.reactions.emoji_set', [
'thumbs_up' => "\u{1F44D}",
'heart' => "\u{2764}\u{FE0F}",
'celebrate' => "\u{1F389}",
'laugh' => "\u{1F604}",
'thinking' => "\u{1F914}",
'sad' => "\u{1F622}",
]);
}
/** @return array<int, string> */
public static function getAllowedReactions(): array
{
return array_keys(static::getReactionEmojiSet());
}
/** @return array<int, string> */
public static function getNotificationChannels(): array
{
return (array) config('comments.notifications.channels', ['database']);
}
public static function areNotificationsEnabled(): bool
{
return (bool) config('comments.notifications.enabled', true);
}
public static function shouldAutoSubscribe(): bool
{
return (bool) config('comments.subscriptions.auto_subscribe', true);
}
public static function areAttachmentsEnabled(): bool
{
return (bool) config('comments.attachments.enabled', true);
}
public static function getAttachmentDisk(): string
{
return (string) config('comments.attachments.disk', 'public');
}
public static function getAttachmentMaxSize(): int
{
return (int) config('comments.attachments.max_size', 10240);
}
/** @return array<int, string> */
public static function getAttachmentAllowedTypes(): array
{
return (array) config('comments.attachments.allowed_types', [
'image/jpeg',
'image/png',
'image/gif',
'image/webp',
'application/pdf',
'text/plain',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
]);
}
public static function isBroadcastingEnabled(): bool
{
return (bool) config('comments.broadcasting.enabled', false);
}
public static function getBroadcastChannelPrefix(): string
{
return (string) config('comments.broadcasting.channel_prefix', 'comments');
}
public static function getPollingInterval(): string
{
return (string) config('comments.polling.interval', '10s');
}
public static function resolveAuthenticatedUser(): ?object
{
if (static::$resolveAuthenticatedUser) {
return call_user_func(static::$resolveAuthenticatedUser);
}
return auth()->user();
}
public static function resolveAuthenticatedUserUsing(Closure $callback): void
{
static::$resolveAuthenticatedUser = $callback;
}
}