0) { audit('message.' . $action, ['target_type' => 'message', 'target_id' => $id]); } if ($id > 0) { switch ($action) { case 'retry': // Back to 'pending' with the attempt counter cleared, then sent // inline so the operator sees the outcome now rather than // waiting for the next cron tick. db_retry_message($pdo, $id); $notice = flush_message($id) ? "Mensagem #{$id} enviada." : "Mensagem #{$id} voltou a falhar — veja o erro na linha."; break; case 'cancel': db_cancel_message($pdo, $id); $notice = "Mensagem #{$id} cancelada."; break; case 'delete': db_soft_delete_message($pdo, $id); $notice = "Mensagem #{$id} arquivada."; break; case 'restore': db_restore_message($pdo, $id); $notice = "Mensagem #{$id} restaurada."; break; } } } $status = (string) ($_GET['status'] ?? ''); $channel = (string) ($_GET['channel'] ?? ''); $search = trim((string) ($_GET['q'] ?? '')); $trash = !empty($_GET['trash']); $detail = (int) ($_GET['id'] ?? 0); $counts = db_count_messages_by_status($pdo, 30); // db_get_messages() takes a `statuses` ARRAY and `only_deleted`, not the // singular/`trash` names the query string uses. $messages = db_get_messages($pdo, [ 'statuses' => $status !== '' ? [$status] : [], 'channel' => $channel ?: null, 'search' => $search ?: null, 'only_deleted' => $trash, 'limit' => 200, ]); $row = $detail > 0 ? db_get_message($pdo, $detail) : false; $page_title = 'Mensagens'; include __DIR__ . '/../../includes/header.php'; ?>

Mensagens

Configuração SMTP
'Em espera', 'sending' => 'A enviar', 'sent' => 'Enviadas', 'failed' => 'Falhadas', 'cancelled' => 'Canceladas'] as $k => $lbl): ?>
>

# ·

Para
Estado
· / tentativas
Contexto
Último erro
Corpo da mensagem

Sem mensagens.

#CanalParaAssunto EstadoCriadaAções
#

Mostradas até 200. A fila é drenada pelo cron.php; as falhas voltam a ser tentadas com espera exponencial até max_attempts.