124 lines
3.2 KiB
PHP
124 lines
3.2 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 jsonSerialize(): array {
|
||
|
return [
|
||
|
"id" => $this->getId(),
|
||
|
"from" => $this->from,
|
||
|
"to" => $this->to,
|
||
|
"gpgFingerprint" => $this->gpgFingerprint,
|
||
|
"subject" => $this->subject,
|
||
|
"message" => $this->body,
|
||
|
"status" => $this->status,
|
||
|
"reply" => [
|
||
|
"to" => $this->replyTo,
|
||
|
"name" => $this->replyName,
|
||
|
],
|
||
|
"retryCount" => $this->retryCount,
|
||
|
"nextTry" => $this->nextTry->getTimestamp(),
|
||
|
"errorMessage" => $this->errorMessage,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
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());
|
||
|
return $success;
|
||
|
}
|
||
|
}
|