126 lines
3.8 KiB
PHP
126 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Messaging;
|
|
|
|
use App\Models\Message;
|
|
use App\Services\System\GlobalConfigService;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\DB;
|
|
use RuntimeException;
|
|
|
|
class MessageCommandService
|
|
{
|
|
public function __construct(private GlobalConfigService $configService) {}
|
|
|
|
public function create(int $senderId, array $payload, ?UploadedFile $attachment = null): Message
|
|
{
|
|
$recipientId = $payload['recipient_id'] ?? null;
|
|
if (! $recipientId && ! empty($payload['recipient_role'])) {
|
|
$recipientId = $this->recipientIdFromRole($payload['recipient_role']);
|
|
}
|
|
|
|
if (! $recipientId) {
|
|
throw new RuntimeException('Recipient is required.');
|
|
}
|
|
|
|
if ((int) $recipientId === $senderId) {
|
|
throw new RuntimeException('Cannot send a message to yourself.');
|
|
}
|
|
|
|
return DB::transaction(function () use ($senderId, $payload, $recipientId, $attachment) {
|
|
$path = null;
|
|
if ($attachment) {
|
|
$path = $attachment->store('messages', ['disk' => 'public']);
|
|
}
|
|
|
|
$message = Message::query()->create([
|
|
'sender_id' => $senderId,
|
|
'recipient_id' => (int) $recipientId,
|
|
'subject' => (string) $payload['subject'],
|
|
'message' => (string) $payload['message'],
|
|
'sent_datetime' => now(),
|
|
'read_status' => 0,
|
|
'message_number' => 'MSG-'.now()->format('YmdHis'),
|
|
'priority' => $payload['priority'] ?? 'normal',
|
|
'attachment' => $path,
|
|
'status' => $payload['status'] ?? 'sent',
|
|
'semester' => $payload['semester'] ?? $this->configService->getSemester() ?? '',
|
|
'school_year' => $payload['school_year'] ?? $this->configService->getSchoolYear() ?? '',
|
|
]);
|
|
|
|
if (! $message) {
|
|
throw new RuntimeException('Failed to send message.');
|
|
}
|
|
|
|
return $message;
|
|
});
|
|
}
|
|
|
|
public function update(Message $message, array $payload): Message
|
|
{
|
|
return DB::transaction(function () use ($message, $payload) {
|
|
$updates = [];
|
|
if (array_key_exists('status', $payload)) {
|
|
$updates['status'] = $payload['status'];
|
|
}
|
|
if (array_key_exists('priority', $payload)) {
|
|
$updates['priority'] = $payload['priority'];
|
|
}
|
|
if (array_key_exists('read_status', $payload)) {
|
|
$read = (int) $payload['read_status'];
|
|
$updates['read_status'] = $read;
|
|
if ($read === 1) {
|
|
$updates['read_datetime'] = now();
|
|
}
|
|
}
|
|
|
|
if (! empty($updates)) {
|
|
$message->fill($updates);
|
|
$message->save();
|
|
}
|
|
|
|
return $message->fresh();
|
|
});
|
|
}
|
|
|
|
public function trash(Message $message): bool
|
|
{
|
|
return DB::transaction(function () use ($message) {
|
|
$message->status = 'trashed';
|
|
|
|
return (bool) $message->save();
|
|
});
|
|
}
|
|
|
|
public function markRead(Message $message): bool
|
|
{
|
|
if ($message->read_status) {
|
|
return true;
|
|
}
|
|
|
|
$message->read_status = 1;
|
|
$message->read_datetime = now();
|
|
|
|
return (bool) $message->save();
|
|
}
|
|
|
|
private function recipientIdFromRole(string $roleName): int
|
|
{
|
|
$map = [
|
|
'teacher' => 1,
|
|
'parent' => 2,
|
|
'admin' => 3,
|
|
'student' => 4,
|
|
'guest' => 5,
|
|
'administrator' => 6,
|
|
];
|
|
|
|
$key = strtolower(trim($roleName));
|
|
if (! isset($map[$key])) {
|
|
throw new RuntimeException('Invalid recipient role.');
|
|
}
|
|
|
|
return $map[$key];
|
|
}
|
|
}
|