commentsAreEnabled()) { throw ValidationException::withMessages([ 'body' => 'Comments are disabled for this article.', ]); } $trimmedBody = trim($body); $errors = ContentSanitizer::validate($trimmedBody); if ($errors !== []) { throw ValidationException::withMessages([ 'body' => $errors, ]); } $comment = NewsArticleComment::query()->create([ 'article_id' => (int) $article->id, 'user_id' => (int) $actor->id, 'parent_id' => $parent?->id, 'author_name' => trim((string) ($actor->name ?: $actor->username)), 'body' => $trimmedBody, 'rendered_body' => ContentSanitizer::sanitizeRenderedHtml( ContentSanitizer::render($trimmedBody), $this->actorCanPublishLinks($actor) ), 'status' => 'visible', ]); $this->news->invalidatePublicCache(); return $comment->fresh(['user.profile', 'replies.user.profile']); } public function delete(NewsArticleComment $comment, User $actor): void { $article = $comment->article()->with('author')->first(); if (! $article || ! $this->canDelete($comment, $article, $actor)) { throw ValidationException::withMessages([ 'comment' => 'You are not allowed to remove this comment.', ]); } if ($comment->trashed()) { return; } $comment->delete(); $this->news->invalidatePublicCache(); } private function canDelete(NewsArticleComment $comment, NewsArticle $article, User $actor): bool { return (int) $comment->user_id === (int) $actor->id || (int) $article->author_id === (int) $actor->id || $actor->isAdmin() || $actor->isModerator(); } private function actorCanPublishLinks(User $actor): bool { $level = (int) ($actor->level ?? 1); $rank = strtolower((string) ($actor->rank ?? 'Newbie')); return $level > 1 && $rank !== 'newbie'; } }