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; } }