2026-05-05 16:42:06 +03:00

470 lines
16 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\ReceiveWebmailMessageRequest;
use App\Http\Requests\SendWebmailMessageRequest;
use App\Http\Requests\UpsertUserMailboxSettingRequest;
use App\Http\Requests\UpdateWebmailMessageRequest;
use App\Http\Resources\Webmail\UserMailboxSettingResource;
use App\Http\Resources\Webmail\WebmailMessageResource;
use App\Models\UserMailboxSetting;
use App\Models\WebmailMessage;
use App\Repositories\WebmailMessageRepositoryInterface;
use App\Services\WebmailService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class WebmailController extends Controller
{
public function __construct(
private readonly WebmailMessageRepositoryInterface $webmailRepository,
private readonly WebmailService $webmailService,
) {
}
public function index(Request $request): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$messages = $this->webmailRepository->paginateForUser(
(int) $user->id,
[
'folder' => $request->query('folder'),
'status' => $request->query('status'),
'search' => $request->query('search'),
'unread' => $request->has('unread') ? $request->boolean('unread') : null,
'starred' => $request->has('starred') ? $request->boolean('starred') : null,
],
max(1, (int) $request->integer('per_page', 15)),
);
return response()->json([
'data' => $messages->getCollection()
->map(fn (WebmailMessage $message): array => (new WebmailMessageResource($message))->resolve())
->values(),
'meta' => [
'current_page' => $messages->currentPage(),
'last_page' => $messages->lastPage(),
'per_page' => $messages->perPage(),
'total' => $messages->total(),
],
'message' => 'Messages recuperes avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error fetching webmail messages: ' . $e->getMessage(), [
'exception' => $e,
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la recuperation des messages.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function stats(): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
return response()->json([
'data' => $this->webmailRepository->statsForUser((int) $user->id),
'message' => 'Statistiques webmail recuperees avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error fetching webmail stats: ' . $e->getMessage(), [
'exception' => $e,
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la recuperation des statistiques webmail.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function show(string $id): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$message = $this->webmailRepository->findForUser($id, (int) $user->id);
if (! $message) {
return response()->json([
'message' => 'Message non trouve.',
], 404);
}
return response()->json([
'data' => (new WebmailMessageResource($message))->resolve(),
'message' => 'Message recupere avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error fetching webmail message: ' . $e->getMessage(), [
'exception' => $e,
'message_id' => $id,
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la recuperation du message.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function send(SendWebmailMessageRequest $request): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$message = $this->webmailService->send($request->validated(), $user);
return response()->json([
'data' => (new WebmailMessageResource($message))->resolve(),
'message' => 'Email envoye avec succes.',
], 201);
} catch (\Exception $e) {
Log::error('Error sending webmail message: ' . $e->getMessage(), [
'exception' => $e,
'data' => $request->validated(),
]);
return response()->json([
'message' => 'Une erreur est survenue lors de l\'envoi de l\'email.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function receive(ReceiveWebmailMessageRequest $request): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$message = $this->webmailService->receive($request->validated(), $user);
return response()->json([
'data' => (new WebmailMessageResource($message))->resolve(),
'message' => 'Email recu et enregistre avec succes.',
], 201);
} catch (\Exception $e) {
Log::error('Error receiving webmail message: ' . $e->getMessage(), [
'exception' => $e,
'data' => $request->validated(),
]);
return response()->json([
'message' => 'Une erreur est survenue lors de l\'enregistrement du message recu.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function syncMailtrap(Request $request): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$result = $this->webmailService->syncMailtrapInbox(
$user,
max(1, min(50, (int) $request->integer('limit', 30)))
);
return response()->json([
'data' => $result,
'message' => 'Synchronisation Mailtrap terminee avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error syncing Mailtrap webmail messages: ' . $e->getMessage(), [
'exception' => $e,
'user_id' => Auth::id(),
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la synchronisation Mailtrap.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function sync(Request $request): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$result = $this->webmailService->syncMailbox(
$user->loadMissing('mailboxSetting'),
max(1, min(50, (int) $request->integer('limit', 30)))
);
return response()->json([
'data' => $result,
'message' => 'Synchronisation de la boite mail terminee avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error syncing mailbox webmail messages: ' . $e->getMessage(), [
'exception' => $e,
'user_id' => Auth::id(),
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la synchronisation de la boite mail.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function testSmtp(): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$result = $this->webmailService->testSmtp($user->loadMissing('mailboxSetting'));
return response()->json([
'data' => $result,
'message' => 'Test SMTP envoye avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error testing mailbox SMTP: ' . $e->getMessage(), [
'exception' => $e,
'user_id' => Auth::id(),
]);
return response()->json([
'message' => 'Une erreur est survenue lors du test SMTP.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function mailboxSettings(): JsonResponse
{
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
return response()->json([
'data' => $user->relationLoaded('mailboxSetting')
? ($user->mailboxSetting ? (new UserMailboxSettingResource($user->mailboxSetting))->resolve() : null)
: ($user->mailboxSetting ? (new UserMailboxSettingResource($user->mailboxSetting))->resolve() : null),
'message' => 'Configuration mailbox recuperee avec succes.',
]);
}
public function upsertMailboxSettings(UpsertUserMailboxSettingRequest $request): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$validated = $request->validated();
$clearImapPassword = (bool) ($validated['clear_imap_password'] ?? false);
$clearSmtpPassword = (bool) ($validated['clear_smtp_password'] ?? false);
unset($validated['clear_imap_password'], $validated['clear_smtp_password']);
if ($clearImapPassword) {
$validated['imap_password'] = null;
} elseif (array_key_exists('imap_password', $validated) && $validated['imap_password'] === null) {
unset($validated['imap_password']);
}
if ($clearSmtpPassword) {
$validated['smtp_password'] = null;
} elseif (array_key_exists('smtp_password', $validated) && $validated['smtp_password'] === null) {
unset($validated['smtp_password']);
}
/** @var UserMailboxSetting $settings */
$settings = UserMailboxSetting::query()->updateOrCreate(
['user_id' => $user->id],
$validated,
);
return response()->json([
'data' => (new UserMailboxSettingResource($settings))->resolve(),
'message' => 'Configuration mailbox mise a jour avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error updating mailbox settings: ' . $e->getMessage(), [
'exception' => $e,
'user_id' => Auth::id(),
'data' => $request->validated(),
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la mise a jour de la configuration mailbox.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function update(UpdateWebmailMessageRequest $request, string $id): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$message = $this->webmailRepository->findForUser($id, (int) $user->id);
if (! $message) {
return response()->json([
'message' => 'Message non trouve.',
], 404);
}
$validated = $request->validated();
if (array_key_exists('is_read', $validated)) {
$validated['read_at'] = $validated['is_read'] ? now() : null;
unset($validated['is_read']);
}
if (array_key_exists('is_starred', $validated)) {
$validated['starred_at'] = $validated['is_starred'] ? now() : null;
unset($validated['is_starred']);
}
$updated = $this->webmailRepository->update($id, $validated);
if (! $updated) {
return response()->json([
'message' => 'Echec de la mise a jour du message.',
], 422);
}
/** @var WebmailMessage $freshMessage */
$freshMessage = $this->webmailRepository->findForUser($id, (int) $user->id);
return response()->json([
'data' => (new WebmailMessageResource($freshMessage))->resolve(),
'message' => 'Message mis a jour avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error updating webmail message: ' . $e->getMessage(), [
'exception' => $e,
'message_id' => $id,
'data' => $request->validated(),
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la mise a jour du message.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
public function destroy(string $id): JsonResponse
{
try {
$user = Auth::user();
if (! $user) {
return response()->json([
'message' => 'Utilisateur non authentifie.',
], 401);
}
$message = $this->webmailRepository->findForUser($id, (int) $user->id);
if (! $message) {
return response()->json([
'message' => 'Message non trouve.',
], 404);
}
$deleted = $this->webmailRepository->delete($id);
if (! $deleted) {
return response()->json([
'message' => 'Echec de la suppression du message.',
], 422);
}
return response()->json([
'message' => 'Message supprime avec succes.',
]);
} catch (\Exception $e) {
Log::error('Error deleting webmail message: ' . $e->getMessage(), [
'exception' => $e,
'message_id' => $id,
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la suppression du message.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
}