diff --git a/app/Http/Livewire/Comment.php b/app/Http/Livewire/Comment.php index b58134819..f7faab856 100644 --- a/app/Http/Livewire/Comment.php +++ b/app/Http/Livewire/Comment.php @@ -28,6 +28,12 @@ use App\Achievements\UserMade800Comments; use App\Achievements\UserMade900Comments; use App\Achievements\UserMadeComment; use App\Achievements\UserMadeTenComments; +use App\Models\Article; +use App\Models\Collection; +use App\Models\Playlist; +use App\Models\Ticket; +use App\Models\Torrent; +use App\Models\TorrentRequest; use App\Models\User; use App\Notifications\NewComment; use App\Notifications\NewCommentTag; @@ -35,7 +41,6 @@ use App\Repositories\ChatRepository; use App\Traits\CastLivewireProperties; use Illuminate\Support\Facades\Notification; use Livewire\Component; -use voku\helper\AntiXSS; class Comment extends Component { @@ -43,31 +48,28 @@ class Comment extends Component protected ChatRepository $chatRepository; - public $comment; + public null|Article|Collection|Playlist|Ticket|Torrent|TorrentRequest $model; + + public \App\Models\Comment $comment; public bool $anon = false; public ?User $user; + /** + * @var array + */ protected $listeners = [ 'refresh' => '$refresh', ]; - protected $validationAttributes = [ - 'replyState.content' => 'reply', - ]; + public bool $isReplying = false; - public $isReplying = false; + public string $replyState = ''; - public $replyState = [ - 'content' => '', - ]; + public bool $isEditing = false; - public $isEditing = false; - - public $editState = [ - 'content' => '', - ]; + public string $editState = ''; final public function boot(ChatRepository $chatRepository): void { @@ -84,93 +86,93 @@ class Comment extends Component $this->castLivewireProperties($field, $value); } + /** + * @return list + */ final public function taggedUsers(): array { - preg_match_all('/@([\w\-]+)/', implode('', $this->editState), $matches); + preg_match_all('/@([\w\-]+)/', $this->editState, $matches); return $matches[1]; } - final public function updatedIsEditing($isEditing): void + final public function updatedIsEditing(bool $isEditing): void { if (!$isEditing) { return; } - $this->editState = [ - 'content' => $this->comment->content, - ]; + $this->editState = $this->comment->content; } final public function editComment(): void { - if (auth()->id() == $this->comment->user_id || auth()->user()->group->is_modo) { - $this->comment->update((new AntiXSS())->xss_clean($this->editState)); - $this->isEditing = false; - } else { - $this->dispatch('error', type: 'error', message: 'Permission Denied!'); - } + abort_unless(auth()->id() === $this->comment->user_id || auth()->user()->group->is_modo, 403); + + $this->validate([ + 'editState' => 'required' + ]); + + $this->comment->update([ + 'content' => $this->editState, + ]); + + $this->isEditing = false; } final public function deleteComment(): void { - if ((auth()->id() == $this->comment->user_id || auth()->user()->group->is_modo) && $this->comment->children()->doesntExist()) { - $this->comment->delete(); - $this->dispatch('refresh'); - } else { - $this->dispatch('error', type: 'error', message: 'Permission Denied!'); - } + abort_unless((auth()->id() === $this->comment->user_id || auth()->user()->group->is_modo), 403, 'Permission Denied!'); + + abort_if($this->comment->children()->exists(), 403); + + $this->comment->delete(); } final public function postReply(): void { - // Set Polymorphic Model Name - $modelName = str()->snake(class_basename($this->comment->commentable_type), ' '); + abort_if(!$this->model instanceof Ticket && auth()->user()->can_comment === false, 403, __('comment.rights-revoked')); - if ($modelName !== 'ticket' && auth()->user()->can_comment === false) { - $this->dispatch('error', type: 'error', message: __('comment.rights-revoked')); + abort_if($this->model instanceof Torrent && $this->model->status !== Torrent::APPROVED, 403, __('comment.torrent-status')); - return; - } - - if (!$this->comment->isParent()) { - return; - } + abort_if($this->comment->isChild(), 403); $this->validate([ - 'replyState.content' => 'required', + 'replyState' => 'required', + 'anon' => 'bool', ]); - $reply = $this->comment->children()->make((new AntiXSS())->xss_clean($this->replyState)); - $reply->user()->associate(auth()->user()); - $reply->commentable()->associate($this->comment->commentable); - $reply->anon = $this->anon; - $reply->save(); + $reply = $this->comment->children()->create([ + 'content' => $this->replyState, + 'user_id' => auth()->id(), + 'commentable_id' => $this->model->id, + 'commentable_type' => \get_class($this->model), + ]); // New Comment Notification - switch ($modelName) { - case 'ticket': - $ticket = $this->comment->commentable; + switch (true) { + case $this->model instanceof Ticket: + $ticket = $this->model; if ($this->user->id !== $ticket->staff_id && $ticket->staff_id !== null) { - User::find($ticket->staff_id)->notify(new NewComment($modelName, $reply)); + User::find($ticket->staff_id)->notify(new NewComment($this->model, $reply)); } if ($this->user->id !== $ticket->user_id) { - User::find($ticket->user_id)->notify(new NewComment($modelName, $reply)); + User::find($ticket->user_id)->notify(new NewComment($this->model, $reply)); } if (!\in_array($this->comment->user_id, [$ticket->staff_id, $ticket->user_id, $this->user->id])) { - User::find($this->comment->user_id)->notify(new NewComment($modelName, $reply)); + User::find($this->comment->user_id)->notify(new NewComment($this->model, $reply)); } break; - case 'article': - case 'playlist': - case 'torrent request': - case 'torrent': - if ($this->user->id !== $this->comment->user_id) { - User::find($this->comment->user_id)->notify(new NewComment($modelName, $reply)); + case $this->model instanceof Article: + case $this->model instanceof Playlist: + case $this->model instanceof TorrentRequest: + case $this->model instanceof Torrent: + if ($this->user->id !== $this->model->user_id) { + User::find($this->model->user_id)?->notify(new NewComment($this->model, $reply)); } break; @@ -178,63 +180,53 @@ class Comment extends Component // User Tagged Notification $users = User::whereIn('username', $this->taggedUsers())->get(); - Notification::sendNow($users, new NewCommentTag($modelName, $reply)); + Notification::sendNow($users, new NewCommentTag($this->model, $reply)); - // Auto Shout - $profileUrl = href_profile($this->user); + if (!$this->model instanceof Ticket) { + // Auto Shout + $username = $reply->anon ? 'An anonymous user' : '[url='.href_profile($this->user).']'.$this->user->username.'[/url]'; - $modelUrl = match ($modelName) { - 'article' => href_article($this->comment->commentable), - 'collection' => href_collection($this->comment->commentable), - 'playlist' => href_playlist($this->comment->commentable), - 'torrent request' => href_request($this->comment->commentable), - 'torrent' => href_torrent($this->comment->commentable), - default => "#" - }; + switch (true) { + case $this->model instanceof Article: + $this->chatRepository->systemMessage($username.' has left a comment on Article [url='.href_article($this->model).']'.$this->model->title.'[/url]'); - if ($modelName !== 'ticket') { - if ($reply->anon == 0) { - $this->chatRepository->systemMessage( - sprintf( - '[url=%s]%s[/url] has left a comment on '.$modelName.' [url=%s]%s[/url]', - $profileUrl, - $this->user->username, - $modelUrl, - $this->comment->commentable->name ?? $this->comment->commentable->title - ) - ); - } else { - $this->chatRepository->systemMessage( - sprintf( - 'An anonymous user has left a comment on '.$modelName.' [url=%s]%s[/url]', - $modelUrl, - $this->comment->commentable->name ?? $this->comment->commentable->title - ) - ); + break; + case $this->model instanceof Collection: + $this->chatRepository->systemMessage($username.' has left a comment on Collection [url='.href_collection($this->model).']'.$this->model->name.'[/url]'); + + break; + case $this->model instanceof Playlist: + $this->chatRepository->systemMessage($username.' has left a comment on Playlist [url='.href_playlist($this->model).']'.$this->model->name.'[/url]'); + + break; + case $this->model instanceof TorrentRequest: + $this->chatRepository->systemMessage($username.' has left a comment on Torrent Request [url='.href_request($this->model).']'.$this->model->name.'[/url]'); + + break; + case $this->model instanceof Torrent: + $this->chatRepository->systemMessage($username.' has left a comment on Torrent [url='.href_torrent($this->model).']'.$this->model->name.'[/url]'); + + break; + } + + // Achievements + if (!$reply->anon) { + $this->user->unlock(new UserMadeComment()); + $this->user->addProgress(new UserMadeTenComments(), 1); + $this->user->addProgress(new UserMade50Comments(), 1); + $this->user->addProgress(new UserMade100Comments(), 1); + $this->user->addProgress(new UserMade200Comments(), 1); + $this->user->addProgress(new UserMade300Comments(), 1); + $this->user->addProgress(new UserMade400Comments(), 1); + $this->user->addProgress(new UserMade500Comments(), 1); + $this->user->addProgress(new UserMade600Comments(), 1); + $this->user->addProgress(new UserMade700Comments(), 1); + $this->user->addProgress(new UserMade800Comments(), 1); + $this->user->addProgress(new UserMade900Comments(), 1); } } - // Achievements - if ($reply->anon == 0 && $modelName !== 'ticket') { - $this->user->unlock(new UserMadeComment()); - $this->user->addProgress(new UserMadeTenComments(), 1); - $this->user->addProgress(new UserMade50Comments(), 1); - $this->user->addProgress(new UserMade100Comments(), 1); - $this->user->addProgress(new UserMade200Comments(), 1); - $this->user->addProgress(new UserMade300Comments(), 1); - $this->user->addProgress(new UserMade400Comments(), 1); - $this->user->addProgress(new UserMade500Comments(), 1); - $this->user->addProgress(new UserMade600Comments(), 1); - $this->user->addProgress(new UserMade700Comments(), 1); - $this->user->addProgress(new UserMade800Comments(), 1); - $this->user->addProgress(new UserMade900Comments(), 1); - } - - $this->replyState = [ - 'content' => '', - ]; - - $this->isReplying = false; + $this->reset('replyState', 'isReplying'); $this->dispatch('refresh')->self(); } diff --git a/app/Http/Livewire/Comments.php b/app/Http/Livewire/Comments.php index ffd225be1..60cb614a7 100644 --- a/app/Http/Livewire/Comments.php +++ b/app/Http/Livewire/Comments.php @@ -28,7 +28,12 @@ use App\Achievements\UserMade800Comments; use App\Achievements\UserMade900Comments; use App\Achievements\UserMadeComment; use App\Achievements\UserMadeTenComments; +use App\Models\Article; +use App\Models\Collection; +use App\Models\Playlist; +use App\Models\Ticket; use App\Models\Torrent; +use App\Models\TorrentRequest; use App\Models\User; use App\Notifications\NewComment; use App\Notifications\NewCommentTag; @@ -36,9 +41,9 @@ use App\Repositories\ChatRepository; use App\Traits\CastLivewireProperties; use Illuminate\Support\Facades\Notification; use Livewire\Attributes\Computed; +use Livewire\Attributes\Validate; use Livewire\Component; use Livewire\WithPagination; -use voku\helper\AntiXSS; class Comments extends Component { @@ -50,22 +55,27 @@ class Comments extends Component public ?User $user; - public $model; + public null|Article|Collection|Playlist|Ticket|Torrent|TorrentRequest $model; public bool $anon = false; public int $perPage = 10; + /** + * @var array + */ protected $listeners = [ 'refresh' => '$refresh', ]; - public $newCommentState = [ - 'content' => '', - ]; + #[Validate('required')] + public string $newCommentState = ''; + /** + * @var array + */ protected $validationAttributes = [ - 'newCommentState.content' => 'comment', + 'newCommentState' => 'comment', ]; final public function boot(ChatRepository $chatRepository): void @@ -83,9 +93,12 @@ class Comments extends Component $this->castLivewireProperties($field, $value); } + /** + * @return array + */ final public function taggedUsers(): array { - preg_match_all('/@([\w\-]+)/', implode('', $this->newCommentState), $matches); + preg_match_all('/@([\w\-]+)/', $this->newCommentState, $matches); return $matches[1]; } @@ -98,50 +111,39 @@ class Comments extends Component /// TODO: Find a better data structure to avoid this mess of exception cases final public function postComment(): void { - // Set Polymorhic Model Name - $modelName = str()->snake(class_basename($this->model), ' '); + // Authorization + abort_if(!$this->model instanceof Ticket && $this->user->can_comment === false, 403, __('comment.rights-revoked')); - if ($modelName !== 'ticket' && $this->user->can_comment === false) { - $this->dispatch('error', type: 'error', message: __('comment.rights-revoked')); + abort_if($this->model instanceof Torrent && $this->model->status !== Torrent::APPROVED, 403, __('comment.torrent-status')); - return; - } + // Validation + $this->validate(); - if (strtolower(class_basename($this->model)) === 'torrent' && $this->model->status !== Torrent::APPROVED) { - $this->dispatch('error', type: 'error', message: __('comment.torrent-status')); - - return; - } - - $this->validate([ - 'newCommentState.content' => 'required', + $comment = $this->model->comments()->create([ + 'content' => $this->newCommentState, + 'user_id' => auth()->id(), ]); - $comment = $this->model->comments()->make((new AntiXSS())->xss_clean($this->newCommentState)); - $comment->user()->associate($this->user); - $comment->anon = $this->anon; - $comment->save(); - // New Comment Notification - switch ($modelName) { - case 'ticket': + switch (true) { + case $this->model instanceof Ticket: $ticket = $this->model; if ($this->user->id !== $ticket->staff_id && $ticket->staff_id !== null) { - User::find($ticket->staff_id)->notify(new NewComment($modelName, $comment)); + User::find($ticket->staff_id)?->notify(new NewComment($this->model, $comment)); } if ($this->user->id !== $ticket->user_id) { - User::find($ticket->user_id)->notify(new NewComment($modelName, $comment)); + User::find($ticket->user_id)?->notify(new NewComment($this->model, $comment)); } break; - case 'article': - case 'playlist': - case 'torrent request': - case 'torrent': + case $this->model instanceof Article: + case $this->model instanceof Playlist: + case $this->model instanceof TorrentRequest: + case $this->model instanceof Torrent: if ($this->user->id !== $this->model->user_id) { - User::find($this->model->user_id)->notify(new NewComment($modelName, $comment)); + User::find($this->model->user_id)?->notify(new NewComment($this->model, $comment)); } break; @@ -149,67 +151,59 @@ class Comments extends Component // User Tagged Notification $users = User::whereIn('username', $this->taggedUsers())->get(); - Notification::sendNow($users, new NewCommentTag($modelName, $comment)); + Notification::sendNow($users, new NewCommentTag($this->model, $comment)); - // Auto Shout - $profileUrl = href_profile($this->user); + if (!$this->model instanceof Ticket) { + // Auto Shout + $username = $comment->anon ? 'An anonymous user' : '[url='.href_profile($this->user).']'.$this->user->username.'[/url]'; - $modelUrl = match ($modelName) { - 'article' => href_article($this->model), - 'collection' => href_collection($this->model), - 'playlist' => href_playlist($this->model), - 'torrent request' => href_request($this->model), - 'torrent' => href_torrent($this->model), - default => "#" - }; + switch (true) { + case $this->model instanceof Article: + $this->chatRepository->systemMessage($username.' has left a comment on Article [url='.href_article($this->model).']'.$this->model->title.'[/url]'); - if ($modelName !== 'ticket') { - if ($comment->anon == 0) { - $this->chatRepository->systemMessage( - sprintf( - '[url=%s]%s[/url] has left a comment on '.$modelName.' [url=%s]%s[/url]', - $profileUrl, - $this->user->username, - $modelUrl, - $this->model->name ?? $this->model->title - ) - ); - } else { - $this->chatRepository->systemMessage( - sprintf( - 'An anonymous user has left a comment on '.$modelName.' [url=%s]%s[/url]', - $modelUrl, - $this->model->name ?? $this->model->title - ) - ); + break; + case $this->model instanceof Collection: + $this->chatRepository->systemMessage($username.' has left a comment on Collection [url='.href_collection($this->model).']'.$this->model->name.'[/url]'); + + break; + case $this->model instanceof Playlist: + $this->chatRepository->systemMessage($username.' has left a comment on Playlist [url='.href_playlist($this->model).']'.$this->model->name.'[/url]'); + + break; + case $this->model instanceof TorrentRequest: + $this->chatRepository->systemMessage($username.' has left a comment on Torrent Request [url='.href_request($this->model).']'.$this->model->name.'[/url]'); + + break; + case $this->model instanceof Torrent: + $this->chatRepository->systemMessage($username.' has left a comment on Torrent [url='.href_torrent($this->model).']'.$this->model->name.'[/url]'); + + break; + } + + // Achievements + if (!$comment->anon) { + $this->user->unlock(new UserMadeComment()); + $this->user->addProgress(new UserMadeTenComments(), 1); + $this->user->addProgress(new UserMade50Comments(), 1); + $this->user->addProgress(new UserMade100Comments(), 1); + $this->user->addProgress(new UserMade200Comments(), 1); + $this->user->addProgress(new UserMade300Comments(), 1); + $this->user->addProgress(new UserMade400Comments(), 1); + $this->user->addProgress(new UserMade500Comments(), 1); + $this->user->addProgress(new UserMade600Comments(), 1); + $this->user->addProgress(new UserMade700Comments(), 1); + $this->user->addProgress(new UserMade800Comments(), 1); + $this->user->addProgress(new UserMade900Comments(), 1); } } - // Achievements - if ($comment->anon == 0 && $modelName !== 'ticket') { - $this->user->unlock(new UserMadeComment()); - $this->user->addProgress(new UserMadeTenComments(), 1); - $this->user->addProgress(new UserMade50Comments(), 1); - $this->user->addProgress(new UserMade100Comments(), 1); - $this->user->addProgress(new UserMade200Comments(), 1); - $this->user->addProgress(new UserMade300Comments(), 1); - $this->user->addProgress(new UserMade400Comments(), 1); - $this->user->addProgress(new UserMade500Comments(), 1); - $this->user->addProgress(new UserMade600Comments(), 1); - $this->user->addProgress(new UserMade700Comments(), 1); - $this->user->addProgress(new UserMade800Comments(), 1); - $this->user->addProgress(new UserMade900Comments(), 1); - } - - $this->newCommentState = [ - 'content' => '', - ]; + $this->reset('newCommentState'); $this->gotoPage(1); } /** - * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator<\App\Models\Comment> */ #[Computed] final public function comments(): \Illuminate\Contracts\Pagination\LengthAwarePaginator diff --git a/app/Models/Comment.php b/app/Models/Comment.php index 936a23873..7b0a8cb18 100644 --- a/app/Models/Comment.php +++ b/app/Models/Comment.php @@ -23,6 +23,7 @@ use App\Traits\Auditable; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use voku\helper\AntiXSS; /** * App\Models\Comment. @@ -43,14 +44,19 @@ class Comment extends Model use HasFactory; /** - * The attributes that are mass assignable. + * The attributes that aren't mass assignable. * - * @var array + * @var string[] */ - protected $fillable = [ - 'content', - 'user_id', - 'anon', + protected $guarded = []; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'anon' => 'bool', ]; /** @@ -100,6 +106,14 @@ class Comment extends Model $builder->whereNull('parent_id'); } + /** + * Set The Articles Content After Its Been Purified. + */ + public function setContentAttribute(?string $value): void + { + $this->attributes['content'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES); + } + /** * Parse Content And Return Valid HTML. */ diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index 1d576ed87..cdcd0b1ab 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -448,7 +448,7 @@ class Torrent extends Model break; case $payload instanceof Comment: if ($user->acceptsNotification(auth()->user(), $user, 'torrent', 'show_torrent_comment')) { - $user->notify(new NewComment('torrent', $payload)); + $user->notify(new NewComment($this, $payload)); } break; diff --git a/app/Notifications/NewComment.php b/app/Notifications/NewComment.php index 15185b22d..aa2d4c8a4 100644 --- a/app/Notifications/NewComment.php +++ b/app/Notifications/NewComment.php @@ -16,7 +16,13 @@ declare(strict_types=1); namespace App\Notifications; +use App\Models\Article; +use App\Models\Collection; use App\Models\Comment; +use App\Models\Playlist; +use App\Models\Ticket; +use App\Models\Torrent; +use App\Models\TorrentRequest; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; @@ -27,7 +33,7 @@ class NewComment extends Notification /** * NewComment Constructor. */ - public function __construct(public string $type, public Comment $comment) + public function __construct(public Torrent|TorrentRequest|Ticket|Playlist|Collection|Article $model, public Comment $comment) { } @@ -48,98 +54,39 @@ class NewComment extends Notification */ public function toArray(object $notifiable): array { - if ($this->type === 'torrent') { - if ($this->comment->anon == 0) { - return [ - 'title' => 'New Torrent Comment Received', - 'body' => $this->comment->user->username.' has left you a comment on Torrent '.$this->comment->commentable->name, - 'url' => '/torrents/'.$this->comment->commentable->id, - ]; - } + $username = $this->comment->anon ? 'Anonymous' : $this->comment->user->username; - return [ + return match (true) { + $this->model instanceof Torrent => [ 'title' => 'New Torrent Comment Received', - 'body' => 'Anonymous has left you a comment on Torrent '.$this->comment->commentable->name, + 'body' => $username.' has left you a comment on Torrent '.$this->comment->commentable->name, 'url' => '/torrents/'.$this->comment->commentable->id, - ]; - } - - if ($this->type === 'torrent request') { - if ($this->comment->anon == 0) { - return [ - 'title' => 'New Request Comment Received', - 'body' => $this->comment->user->username.' has left you a comment on Torrent Request '.$this->comment->commentable->name, - 'url' => '/requests/'.$this->comment->commentable->id, - ]; - } - - return [ + ], + $this->model instanceof TorrentRequest => [ 'title' => 'New Request Comment Received', - 'body' => 'Anonymous has left you a comment on Torrent Request '.$this->comment->commentable->name, + 'body' => $username.' has left you a comment on Torrent Request '.$this->comment->commentable->name, 'url' => '/requests/'.$this->comment->commentable->id, - ]; - } - - if ($this->type === 'ticket') { - if ($this->comment->anon == 0) { - return [ - 'title' => 'New Ticket Comment Received', - 'body' => $this->comment->user->username.' has left you a comment on Ticket '.$this->comment->commentable->subject, - 'url' => '/tickets/'.$this->comment->commentable->id, - ]; - } - - return [ + ], + $this->model instanceof Ticket => [ 'title' => 'New Ticket Comment Received', - 'body' => 'Anonymous has left you a comment on Ticket '.$this->comment->commentable->subject, + 'body' => $username.' has left you a comment on Ticket '.$this->comment->commentable->subject, 'url' => '/tickets/'.$this->comment->commentable->id, - ]; - } - - if ($this->type === 'playlist') { - if ($this->comment->anon == 0) { - return [ - 'title' => 'New Playlist Comment Received', - 'body' => $this->comment->user->username.' has left you a comment on Playlist '.$this->comment->commentable->name, - 'url' => '/playlists/'.$this->comment->commentable->id, - ]; - } - - return [ + ], + $this->model instanceof Playlist => [ 'title' => 'New Playlist Comment Received', - 'body' => 'Anonymous has left you a comment on Playlist '.$this->comment->commentable->name, + 'body' => $username.' has left you a comment on Playlist '.$this->comment->commentable->name, 'url' => '/playlists/'.$this->comment->commentable->id, - ]; - } - - if ($this->type === 'collection') { - if ($this->comment->anon == 0) { - return [ - 'title' => 'New Collection Comment Received', - 'body' => $this->comment->user->username.' has left you a comment on Collection '.$this->comment->commentable->name, - 'url' => '/mediahub/collections/'.$this->comment->commentable->id, - ]; - } - - return [ + ], + $this->model instanceof Collection => [ 'title' => 'New Collection Comment Received', - 'body' => 'Anonymous has left you a comment on Collection '.$this->comment->commentable->name, + 'body' => $username.' has left you a comment on Collection '.$this->comment->commentable->name, 'url' => '/mediahub/collections/'.$this->comment->commentable->id, - ]; - } - - if ($this->comment->anon == 0) { - return [ + ], + $this->model instanceof Article => [ 'title' => 'New Article Comment Received', - 'body' => $this->comment->user->username.' has left you a comment on Article '.$this->comment->commentable->title, + 'body' => $username.' has left you a comment on Article '.$this->comment->commentable->title, 'url' => '/articles/'.$this->comment->commentable->id, - ]; - } - - return [ - 'title' => 'New Article Comment Received', - 'body' => 'Anonymous has left you a comment on Article '.$this->comment->commentable->title, - 'url' => '/articles/'.$this->comment->commentable->id, - ]; + ], + }; } } diff --git a/app/Notifications/NewCommentTag.php b/app/Notifications/NewCommentTag.php index 23ddc05e1..025146552 100644 --- a/app/Notifications/NewCommentTag.php +++ b/app/Notifications/NewCommentTag.php @@ -16,7 +16,13 @@ declare(strict_types=1); namespace App\Notifications; +use App\Models\Article; +use App\Models\Collection; use App\Models\Comment; +use App\Models\Playlist; +use App\Models\Ticket; +use App\Models\Torrent; +use App\Models\TorrentRequest; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Notification; @@ -28,7 +34,7 @@ class NewCommentTag extends Notification implements ShouldQueue /** * NewCommentTag Constructor. */ - public function __construct(public string $type, public Comment $comment) + public function __construct(public Torrent|TorrentRequest|Ticket|Playlist|Collection|Article $model, public Comment $comment) { } @@ -49,98 +55,40 @@ class NewCommentTag extends Notification implements ShouldQueue */ public function toArray(object $notifiable): array { - if ($this->type === 'torrent') { - if ($this->comment->anon == 0) { - return [ - 'title' => $this->comment->user->username.' Has Tagged You', - 'body' => $this->comment->user->username.' has tagged you in an comment on Torrent '.$this->comment->commentable->name, - 'url' => '/torrents/'.$this->comment->commentable->id, - ]; - } + $username = $this->comment->anon ? 'Anonymous' : $this->comment->user->username; + $title = $this->comment->anon ? 'You Have Been Tagged' : $username.' Has Tagged You'; - return [ - 'title' => 'You Have Been Tagged', - 'body' => 'Anonymous has tagged you in an comment on Torrent '.$this->comment->commentable->name, + return match (true) { + $this->model instanceof Torrent => [ + 'title' => $title, + 'body' => $username.' has tagged you in an comment on Torrent '.$this->comment->commentable->name, 'url' => '/torrents/'.$this->comment->commentable->id, - ]; - } - - if ($this->type === 'torrent request') { - if ($this->comment->anon == 0) { - return [ - 'title' => $this->comment->user->username.' Has Tagged You', - 'body' => $this->comment->user->username.' has tagged you in an comment on Torrent Request '.$this->comment->commentable->name, - 'url' => '/requests/'.$this->comment->commentable->id, - ]; - } - - return [ - 'title' => 'You Have Been Tagged', - 'body' => 'Anonymous has tagged you in an comment on Torrent Request '.$this->comment->commentable->name, + ], + $this->model instanceof TorrentRequest => [ + 'title' => $title, + 'body' => $username.' has tagged you in an comment on Torrent Request '.$this->comment->commentable->name, 'url' => '/requests/'.$this->comment->commentable->id, - ]; - } - - if ($this->type === 'ticket') { - if ($this->comment->anon == 0) { - return [ - 'title' => $this->comment->user->username.' Has Tagged You', - 'body' => $this->comment->user->username.' has tagged you in an comment on Ticket '.$this->comment->commentable->subject, - 'url' => '/tickets/'.$this->comment->commentable->id, - ]; - } - - return [ - 'title' => 'You Have Been Tagged', - 'body' => 'Anonymous has tagged you in an comment on Ticket '.$this->comment->commentable->subject, + ], + $this->model instanceof Ticket => [ + 'title' => $title, + 'body' => $username.' has tagged you in an comment on Ticket '.$this->comment->commentable->subject, 'url' => '/tickets/'.$this->comment->commentable->id, - ]; - } - - if ($this->type === 'playlist') { - if ($this->comment->anon == 0) { - return [ - 'title' => $this->comment->user->username.' Has Tagged You', - 'body' => $this->comment->user->username.' has tagged you in an comment on Playlist '.$this->comment->commentable->name, - 'url' => '/playlists/'.$this->comment->commentable->id, - ]; - } - - return [ - 'title' => 'You Have Been Tagged', - 'body' => 'Anonymous has tagged you in an comment on Playlist '.$this->comment->commentable->name, + ], + $this->model instanceof Playlist => [ + 'title' => $title, + 'body' => $username.' has tagged you in an comment on Playlist '.$this->comment->commentable->name, 'url' => '/playlists/'.$this->comment->commentable->id, - ]; - } - - if ($this->type === 'collection') { - if ($this->comment->anon == 0) { - return [ - 'title' => $this->comment->user->username.' Has Tagged You', - 'body' => $this->comment->user->username.' has tagged you in an comment on Collection '.$this->comment->commentable->name, - 'url' => '/mediahub/collections/'.$this->comment->commentable->id, - ]; - } - - return [ - 'title' => 'You Have Been Tagged', - 'body' => 'Anonymous has tagged you in an comment on Collection '.$this->comment->commentable->name, + ], + $this->model instanceof Collection => [ + 'title' => $title, + 'body' => $username.' has tagged you in an comment on Collection '.$this->comment->commentable->name, 'url' => '/mediahub/collections/'.$this->comment->commentable->id, - ]; - } - - if ($this->comment->anon == 0) { - return [ - 'title' => $this->comment->user->username.' Has Tagged You', - 'body' => $this->comment->user->username.' has tagged you in an comment on Article '.$this->comment->commentable->title, + ], + $this->model instanceof Article => [ + 'title' => $title, + 'body' => $username.' has tagged you in an comment on Article '.$this->comment->commentable->title, 'url' => '/articles/'.$this->comment->commentable->id, - ]; - } - - return [ - 'title' => 'You Have Been Tagged', - 'body' => 'Anonymous has tagged you in an comment on Article '.$this->comment->commentable->title, - 'url' => '/articles/'.$this->comment->commentable->id, - ]; + ], + }; } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 28304353a..64ce32f23 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -645,96 +645,6 @@ parameters: count: 1 path: app/Http/Livewire/BlockIpAddress.php - - - message: "#^Call to an undefined method App\\\\Models\\\\User\\|Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\:\\:notify\\(\\)\\.$#" - count: 4 - path: app/Http/Livewire/Comment.php - - - - message: "#^Method App\\\\Http\\\\Livewire\\\\Comment\\:\\:taggedUsers\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Method App\\\\Http\\\\Livewire\\\\Comment\\:\\:updatedIsEditing\\(\\) has parameter \\$isEditing with no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comment\\:\\:\\$comment has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comment\\:\\:\\$editState has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comment\\:\\:\\$isEditing has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comment\\:\\:\\$isReplying has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comment\\:\\:\\$listeners has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comment\\:\\:\\$replyState has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comment\\:\\:\\$validationAttributes has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comment.php - - - - message: "#^Unable to resolve the template type TXssCleanInput in call to method voku\\\\helper\\\\AntiXSS\\:\\:xss_clean\\(\\)$#" - count: 2 - path: app/Http/Livewire/Comment.php - - - - message: "#^Call to an undefined method App\\\\Models\\\\User\\|Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\:\\:notify\\(\\)\\.$#" - count: 3 - path: app/Http/Livewire/Comments.php - - - - message: "#^Method App\\\\Http\\\\Livewire\\\\Comments\\:\\:taggedUsers\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: app/Http/Livewire/Comments.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comments\\:\\:\\$listeners has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comments.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comments\\:\\:\\$model has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comments.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comments\\:\\:\\$newCommentState has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comments.php - - - - message: "#^Property App\\\\Http\\\\Livewire\\\\Comments\\:\\:\\$validationAttributes has no type specified\\.$#" - count: 1 - path: app/Http/Livewire/Comments.php - - - - message: "#^Unable to resolve the template type TXssCleanInput in call to method voku\\\\helper\\\\AntiXSS\\:\\:xss_clean\\(\\)$#" - count: 1 - path: app/Http/Livewire/Comments.php - - message: "#^Method App\\\\Http\\\\Livewire\\\\InviteLogSearch\\:\\:updatingGroupBy\\(\\) has parameter \\$value with no type specified\\.$#" count: 1 diff --git a/resources/views/livewire/comment.blade.php b/resources/views/livewire/comment.blade.php index 6e1381928..6db372d79 100644 --- a/resources/views/livewire/comment.blade.php +++ b/resources/views/livewire/comment.blade.php @@ -84,17 +84,17 @@ id="edit-comment" class="form__textarea" aria-describedby="edit-comment__textarea-hint" - wire:model="editState.content" + wire:model="editState" required > - @error('editState.content') + @error('editState') {{ $message }} @@ -139,18 +139,18 @@ id="reply-comment" class="form__textarea" aria-describedby="reply-comment__textarea-hint" - wire:model="replyState.content" + wire:model="replyState" required x-on:focus="toggleOn" > - @error('replyState.content') + @error('replyState') {{ $message }} diff --git a/resources/views/livewire/comments.blade.php b/resources/views/livewire/comments.blade.php index 7282e94e2..d127d29b0 100644 --- a/resources/views/livewire/comments.blade.php +++ b/resources/views/livewire/comments.blade.php @@ -11,18 +11,18 @@ id="new-comment__textarea" class="form__textarea" aria-describedby="new-comment__textarea-hint" - wire:model="newCommentState.content" + wire:model="newCommentState" required x-on:focus="toggleOn" > - @error('newCommentState.content') + @error('newCommentState') {{ $message }} @enderror

@@ -39,7 +39,7 @@
    @forelse ($comments as $comment) - + @empty