223 lines
7.3 KiB
PHP
223 lines
7.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Messaging;
|
|
|
|
use App\Http\Controllers\Api\BaseApiController;
|
|
use App\Http\Requests\Messaging\MessageIndexRequest;
|
|
use App\Http\Requests\Messaging\MessageSendRequest;
|
|
use App\Http\Requests\Messaging\MessageUpdateRequest;
|
|
use App\Http\Resources\Messaging\MessageCollection;
|
|
use App\Http\Resources\Messaging\MessageResource;
|
|
use App\Http\Resources\Messaging\RecipientResource;
|
|
use App\Models\Message;
|
|
use App\Services\Messaging\MessageCommandService;
|
|
use App\Services\Messaging\MessageQueryService;
|
|
use App\Services\Messaging\MessageRecipientService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class MessagesController extends BaseApiController
|
|
{
|
|
public function __construct(
|
|
private MessageQueryService $queryService,
|
|
private MessageCommandService $commandService,
|
|
private MessageRecipientService $recipientService
|
|
) {
|
|
parent::__construct();
|
|
}
|
|
|
|
public function index(MessageIndexRequest $request): JsonResponse
|
|
{
|
|
$userId = (int) (auth()->id() ?? 0);
|
|
if ($userId <= 0) {
|
|
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
|
}
|
|
|
|
$filters = $request->validated();
|
|
$page = (int) ($filters['page'] ?? 1);
|
|
$perPage = (int) ($filters['per_page'] ?? 20);
|
|
|
|
$this->authorize('viewAny', Message::class);
|
|
|
|
$role = $this->queryService->getUserRoleName($userId);
|
|
$messages = $this->queryService->inbox($userId, $filters, $page, $perPage);
|
|
$collection = new MessageCollection($messages);
|
|
$meta = $collection->with($request)['meta'] ?? null;
|
|
|
|
return $this->success([
|
|
'role' => $role,
|
|
'messages' => $collection->toArray($request),
|
|
'meta' => $meta,
|
|
]);
|
|
}
|
|
|
|
public function inbox(MessageIndexRequest $request): JsonResponse
|
|
{
|
|
return $this->listMessages($request, 'inbox');
|
|
}
|
|
|
|
public function sent(MessageIndexRequest $request): JsonResponse
|
|
{
|
|
return $this->listMessages($request, 'sent');
|
|
}
|
|
|
|
public function drafts(MessageIndexRequest $request): JsonResponse
|
|
{
|
|
return $this->listMessages($request, 'drafts');
|
|
}
|
|
|
|
public function trash(MessageIndexRequest $request): JsonResponse
|
|
{
|
|
return $this->listMessages($request, 'trash');
|
|
}
|
|
|
|
public function show(int $id): JsonResponse
|
|
{
|
|
$message = $this->queryService->findForUser($id);
|
|
if (!$message) {
|
|
return $this->error('Message not found.', Response::HTTP_NOT_FOUND);
|
|
}
|
|
|
|
$this->authorize('view', $message);
|
|
|
|
$userId = (int) (auth()->id() ?? 0);
|
|
if ($message->recipient_id === $userId) {
|
|
$this->commandService->markRead($message);
|
|
$message->refresh();
|
|
}
|
|
|
|
return $this->success([
|
|
'message' => new MessageResource($message),
|
|
]);
|
|
}
|
|
|
|
public function store(MessageSendRequest $request): JsonResponse
|
|
{
|
|
$userId = (int) (auth()->id() ?? 0);
|
|
if ($userId <= 0) {
|
|
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
|
}
|
|
|
|
$this->authorize('create', Message::class);
|
|
|
|
try {
|
|
$message = $this->commandService->create($userId, $request->validated(), $request->file('attachment'));
|
|
} catch (\Throwable $e) {
|
|
Log::error('Message send failed: ' . $e->getMessage());
|
|
return $this->error($e->getMessage(), Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
return $this->success([
|
|
'message' => new MessageResource($message->fresh(['sender', 'recipient'])),
|
|
], 'Message sent.', Response::HTTP_CREATED);
|
|
}
|
|
|
|
public function receive(): JsonResponse
|
|
{
|
|
$userId = (int) (auth()->id() ?? 0);
|
|
if ($userId <= 0) {
|
|
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
|
}
|
|
|
|
$messages = $this->queryService->receivedAndMarkRead($userId);
|
|
|
|
return $this->success([
|
|
'messages' => (new MessageCollection(collect($messages)))->toArray(request()),
|
|
]);
|
|
}
|
|
|
|
public function recipients(string $type): JsonResponse
|
|
{
|
|
$type = strtolower(trim($type));
|
|
$data = match ($type) {
|
|
'teacher' => $this->recipientService->teachers(),
|
|
'parent' => $this->recipientService->parents(),
|
|
default => null,
|
|
};
|
|
|
|
if ($data === null) {
|
|
return $this->error('Invalid recipient type.', Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
$payload = array_map(fn ($row) => (new RecipientResource($row))->toArray(request()), $data);
|
|
|
|
return $this->success([
|
|
'recipients' => $payload,
|
|
]);
|
|
}
|
|
|
|
public function update(MessageUpdateRequest $request, int $id): JsonResponse
|
|
{
|
|
$message = Message::query()->find($id);
|
|
if (!$message) {
|
|
return $this->error('Message not found.', Response::HTTP_NOT_FOUND);
|
|
}
|
|
|
|
$this->authorize('update', $message);
|
|
|
|
try {
|
|
$updated = $this->commandService->update($message, $request->validated());
|
|
} catch (\Throwable $e) {
|
|
Log::error('Message update failed: ' . $e->getMessage());
|
|
return $this->error('Unable to update message.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
return $this->success([
|
|
'message' => new MessageResource($updated->load(['sender', 'recipient'])),
|
|
], 'Message updated.');
|
|
}
|
|
|
|
public function destroy(int $id): JsonResponse
|
|
{
|
|
$message = Message::query()->find($id);
|
|
if (!$message) {
|
|
return $this->error('Message not found.', Response::HTTP_NOT_FOUND);
|
|
}
|
|
|
|
$this->authorize('delete', $message);
|
|
|
|
try {
|
|
$trashed = $this->commandService->trash($message);
|
|
} catch (\Throwable $e) {
|
|
Log::error('Message delete failed: ' . $e->getMessage());
|
|
return $this->error('Unable to delete message.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
if (!$trashed) {
|
|
return $this->error('Unable to delete message.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
return $this->success(null, 'Message deleted.');
|
|
}
|
|
|
|
private function listMessages(MessageIndexRequest $request, string $bucket): JsonResponse
|
|
{
|
|
$userId = (int) (auth()->id() ?? 0);
|
|
if ($userId <= 0) {
|
|
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
|
}
|
|
|
|
$filters = $request->validated();
|
|
$page = (int) ($filters['page'] ?? 1);
|
|
$perPage = (int) ($filters['per_page'] ?? 20);
|
|
|
|
$this->authorize('viewAny', Message::class);
|
|
|
|
$paginator = match ($bucket) {
|
|
'sent' => $this->queryService->sent($userId, $filters, $page, $perPage),
|
|
'drafts' => $this->queryService->drafts($userId, $filters, $page, $perPage),
|
|
'trash' => $this->queryService->trash($userId, $filters, $page, $perPage),
|
|
default => $this->queryService->inbox($userId, $filters, $page, $perPage),
|
|
};
|
|
|
|
$collection = new MessageCollection($paginator);
|
|
$meta = $collection->with($request)['meta'] ?? null;
|
|
|
|
return $this->success([
|
|
'messages' => $collection->toArray($request),
|
|
'meta' => $meta,
|
|
]);
|
|
}
|
|
}
|