feat: add community activity feed and mentions
This commit is contained in:
78
app/Services/UserMentionSyncService.php
Normal file
78
app/Services/UserMentionSyncService.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ArtworkComment;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
final class UserMentionSyncService
|
||||
{
|
||||
public function syncForComment(ArtworkComment $comment): void
|
||||
{
|
||||
if (! Schema::hasTable('user_mentions')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$usernames = $this->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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user