model->newQuery() ->where('user_id', $userId) ->orderByRaw('COALESCE(received_at, sent_at, created_at) DESC'); if (!empty($filters['folder'])) { $query->where('folder', $filters['folder']); } if (!empty($filters['status'])) { $query->where('status', $filters['status']); } if (array_key_exists('unread', $filters) && $filters['unread'] !== null) { $filters['unread'] ? $query->whereNull('read_at') : $query->whereNotNull('read_at'); } if (array_key_exists('starred', $filters) && $filters['starred'] !== null) { $filters['starred'] ? $query->whereNotNull('starred_at') : $query->whereNull('starred_at'); } if (!empty($filters['search'])) { $search = '%' . trim((string) $filters['search']) . '%'; $query->where(function ($builder) use ($search): void { $builder ->where('subject', 'like', $search) ->orWhere('from_email', 'like', $search) ->orWhere('from_name', 'like', $search) ->orWhere('body', 'like', $search) ->orWhere('snippet', 'like', $search); }); } return $query->paginate($perPage); } public function findForUser(int|string $id, int $userId): ?WebmailMessage { $message = $this->model->newQuery() ->where('user_id', $userId) ->find($id); return $message instanceof WebmailMessage ? $message : null; } public function statsForUser(int $userId): array { $baseQuery = $this->model->newQuery()->where('user_id', $userId); return [ 'total' => (clone $baseQuery)->count(), 'inbox' => (clone $baseQuery)->where('folder', 'inbox')->count(), 'sent' => (clone $baseQuery)->where('folder', 'sent')->count(), 'drafts' => (clone $baseQuery)->where('folder', 'drafts')->count(), 'trash' => (clone $baseQuery)->where('folder', 'trash')->count(), 'unread' => (clone $baseQuery)->whereNull('read_at')->count(), 'starred' => (clone $baseQuery)->whereNotNull('starred_at')->count(), ]; } }