69 lines
1.9 KiB
PHP
69 lines
1.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\Messaging;
|
|
|
|
use App\Models\Conversation;
|
|
use App\Models\ConversationParticipant;
|
|
use App\Models\Message;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class MessageNotificationService
|
|
{
|
|
public function notifyNewMessage(Conversation $conversation, Message $message, User $sender): void
|
|
{
|
|
if (! DB::getSchemaBuilder()->hasTable('notifications')) {
|
|
return;
|
|
}
|
|
|
|
$recipientIds = ConversationParticipant::query()
|
|
->where('conversation_id', $conversation->id)
|
|
->whereNull('left_at')
|
|
->where('user_id', '!=', $sender->id)
|
|
->where('is_muted', false)
|
|
->where('is_archived', false)
|
|
->pluck('user_id')
|
|
->all();
|
|
|
|
if (empty($recipientIds)) {
|
|
return;
|
|
}
|
|
|
|
$recipientRows = User::query()
|
|
->whereIn('id', $recipientIds)
|
|
->get()
|
|
->filter(fn (User $recipient) => $recipient->allowsMessagesFrom($sender))
|
|
->pluck('id')
|
|
->map(fn ($id) => (int) $id)
|
|
->values()
|
|
->all();
|
|
|
|
if (empty($recipientRows)) {
|
|
return;
|
|
}
|
|
|
|
$preview = Str::limit((string) $message->body, 120, '…');
|
|
$now = now();
|
|
|
|
$rows = array_map(static fn (int $recipientId) => [
|
|
'user_id' => $recipientId,
|
|
'type' => 'message',
|
|
'data' => json_encode([
|
|
'conversation_id' => $conversation->id,
|
|
'sender_id' => $sender->id,
|
|
'sender_name' => $sender->username,
|
|
'preview' => $preview,
|
|
'message_id' => $message->id,
|
|
], JSON_UNESCAPED_UNICODE),
|
|
'read_at' => null,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
], $recipientRows);
|
|
|
|
DB::table('notifications')->insert($rows);
|
|
}
|
|
}
|