extractMentions((string) ($comment->raw_content ?? $comment->content ?? '')); $mentionedIds = $usernames === [] ? [] : User::query() ->whereIn(DB::raw('LOWER(username)'), $usernames) ->where('is_active', true) ->whereNull('deleted_at') ->pluck('id') ->map(fn ($id) => (int) $id) ->all(); DB::transaction(function () use ($comment, $mentionedIds): void { DB::table('user_mentions') ->where('comment_id', (int) $comment->id) ->delete(); if ($mentionedIds === []) { return; } $rows = collect($mentionedIds) ->reject(fn (int $id) => $id === (int) $comment->user_id) ->unique() ->map(fn (int $mentionedUserId) => [ 'user_id' => (int) $comment->user_id, 'mentioned_user_id' => $mentionedUserId, 'artwork_id' => (int) $comment->artwork_id, 'comment_id' => (int) $comment->id, 'created_at' => $comment->created_at ?? now(), ]) ->values() ->all(); if ($rows !== []) { DB::table('user_mentions')->insert($rows); } }); } public function deleteForComment(int $commentId): void { if (! Schema::hasTable('user_mentions')) { return; } DB::table('user_mentions')->where('comment_id', $commentId)->delete(); } private function extractMentions(string $content): array { preg_match_all('/(^|[^A-Za-z0-9_])@([A-Za-z0-9_-]{3,20})/', $content, $matches); return collect($matches[2] ?? []) ->map(fn ($username) => strtolower((string) $username)) ->unique() ->values() ->all(); } }