web-base/Core/Objects/DatabaseEntity/MailQueueItem.class.php
2023-01-09 14:21:11 +01:00

105 lines
2.7 KiB
PHP

<?php
namespace Core\Objects\DatabaseEntity;
use Core\API\Mail\Send;
use Core\Driver\SQL\Expression\CurrentTimeStamp;
use Core\Objects\Context;
use Core\Objects\DatabaseEntity\Attribute\DefaultValue;
use Core\Objects\DatabaseEntity\Attribute\EnumArr;
use Core\Objects\DatabaseEntity\Attribute\MaxLength;
use Core\Objects\DatabaseEntity\Controller\DatabaseEntity;
class MailQueueItem extends DatabaseEntity {
protected static array $entityLogConfig = [
"update" => true,
"delete" => true,
"insert" => true,
"lifetime" => 30
];
const STATUS_WAITING = "waiting";
const STATUS_SUCCESS = "success";
const STATUS_ERROR = "error";
const STATUS_ITEMS = [self::STATUS_WAITING, self::STATUS_SUCCESS, self::STATUS_ERROR];
#[MaxLength(64)]
private string $from;
#[MaxLength(64)]
private string $to;
private string $subject;
private string $body;
#[MaxLength(64)]
private ?string $replyTo;
#[MaxLength(64)]
private ?string $replyName;
#[MaxLength(64)]
private ?string $gpgFingerprint;
#[EnumArr(self::STATUS_ITEMS)]
#[DefaultValue(self::STATUS_WAITING)]
private string $status;
#[DefaultValue(5)]
private int $retryCount;
#[DefaultValue(CurrentTimeStamp::class)]
private \DateTime $nextTry;
private ?string $errorMessage;
public function __construct(string $fromMail, string $toMail, string $subject, string $body,
?string $replyTo, ?string $replyName, ?string $gpgFingerprint) {
parent::__construct();
$this->from = $fromMail;
$this->to = $toMail;
$this->subject = $subject;
$this->body = $body;
$this->replyTo = $replyTo;
$this->replyName = $replyName;
$this->gpgFingerprint = $gpgFingerprint;
$this->retryCount = 5;
$this->nextTry = new \DateTime();
$this->errorMessage = null;
$this->status = self::STATUS_WAITING;
}
public function send(Context $context): bool {
$args = [
"to" => $this->to,
"subject" => $this->subject,
"body" => $this->body,
"replyTo" => $this->replyTo,
"replyName" => $this->replyName,
"gpgFingerprint" => $this->gpgFingerprint,
"async" => false
];
$req = new Send($context);
$success = $req->execute($args);
$this->errorMessage = $req->getLastError();
$delay = [0, 720, 360, 60, 30, 1];
$minutes = $delay[max(0, min(count($delay) - 1, $this->retryCount))];
if ($this->retryCount > 0) {
$this->retryCount--;
$this->nextTry = (new \DateTime())->modify("+$minutes minute");
} else if (!$success) {
$this->status = self::STATUS_ERROR;
}
if ($success) {
$this->status = self::STATUS_SUCCESS;
}
$this->save($context->getSQL(), ["status", "retryCount", "nextTry", "errorMessage"]);
return $success;
}
}