CluPilotCloud/app/Services/Mail/InboundMailStatus.php

60 lines
2.1 KiB
PHP

<?php
namespace App\Services\Mail;
use App\Support\Settings;
use Illuminate\Support\Carbon;
/**
* When the support mailbox was last reached, and what came back.
*
* A settings row rather than a table: there is exactly one mailbox and exactly
* one last answer, and a table of one row is a table somebody has to prune.
*
* Written by both callers on purpose — the operator's test button and the
* scheduled fetch. Otherwise "last checked" would mean "last time somebody
* pressed the button", which is the least interesting of the two: a mailbox
* that stopped answering at three in the morning is what an operator needs to
* see, and nobody presses a button at three in the morning.
*/
class InboundMailStatus
{
private const KEY = 'inbound_mail.last_check';
/** @param int|null $unseen how many unread messages were waiting, where that was asked */
public function record(bool $ok, string $message = '', ?int $unseen = null): void
{
Settings::set(self::KEY, [
'at' => Carbon::now()->toIso8601String(),
'ok' => $ok,
// Never the password, never the whole exception: this ends up on a
// page, and an IMAP error can quote the command it failed on.
'message' => mb_substr($message, 0, 300),
'unseen' => $unseen,
]);
}
/**
* The last answer, or null if nobody has ever asked.
*
* @return array{at: Carbon, ok: bool, message: string, unseen: int|null}|null
*/
public function last(): ?array
{
$row = Settings::get(self::KEY);
if (! is_array($row) || ! isset($row['at'])) {
return null;
}
return [
// Parsed back into a Carbon so the view can put it on the wall clock
// (R19) rather than printing an ISO string at somebody.
'at' => Carbon::parse((string) $row['at']),
'ok' => (bool) ($row['ok'] ?? false),
'message' => (string) ($row['message'] ?? ''),
'unseen' => isset($row['unseen']) ? (int) $row['unseen'] : null,
];
}
}