death-notifier/src/main/php/com/fwdekker/deathnotifier/mailer/ProcessEmailQueueAction.php

117 lines
3.4 KiB
PHP

<?php
namespace com\fwdekker\deathnotifier\mailer;
use com\fwdekker\deathnotifier\Action;
use com\fwdekker\deathnotifier\ActionException;
use com\fwdekker\deathnotifier\Config;
use com\fwdekker\deathnotifier\LoggerUtil;
use com\fwdekker\deathnotifier\validator\IsEqualToRule;
use Monolog\Logger;
use PHPMailer\PHPMailer\Exception as PHPMailerException;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
/**
* Processes the queue of emails to send.
*/
class ProcessEmailQueueAction extends Action
{
/**
* @var Logger the logger to log with
*/
private readonly Logger $logger;
/**
* @var MailManager the manager to process the queue with
*/
private readonly MailManager $mail_manager;
/**
* Constructs a new `ProcessEmailQueueAction`.
*
* @param MailManager $mail_manager the manager to process the queue with
*/
public function __construct(MailManager $mail_manager)
{
parent::__construct(
rule_lists: [
"password" => [new IsEqualToRule(Config::get()["admin"]["cli_secret"], "Incorrect password.")]
],
);
$this->logger = LoggerUtil::with_name($this::class);
$this->mail_manager = $mail_manager;
}
/**
* Processes the queue.
*
* @param array<int|string, mixed> $inputs ignored
* @return null
* @throws ActionException if the mailer could not be created or if an email could not be sent
*/
public function handle(array $inputs): mixed
{
$emails = $this->mail_manager->get_queue();
$mailer = $this->create_mailer();
foreach ($emails as $email) {
$mailer->Subject = $email["subject"];
$mailer->Body = $email["body"];
try {
$mailer->addAddress($email["recipient"]);
$mailer->send();
} catch (PHPMailerException $exception) {
$mailer->getSMTPInstance()->reset();
$this->logger->error("Failed to send email.", ["cause" => $exception]);
throw new ActionException("Failed to send mail.");
}
$mailer->clearAddresses();
}
$this->mail_manager->unqueue_emails($emails);
return null;
}
/**
* Creates a mailer object to send emails with.
*
* @throws ActionException if the mailer could not be created
*/
private function create_mailer(): PHPMailer
{
$config = Config::get();
$mailer = new PHPMailer();
$mailer->IsSMTP();
$mailer->CharSet = "UTF-8";
$mailer->SMTPAuth = true;
$mailer->SMTPDebug = SMTP::DEBUG_OFF;
$mailer->SMTPKeepAlive = true;
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mailer->Host = $config["mail"]["host"];
$mailer->Port = $config["mail"]["port"];
$mailer->Username = $config["mail"]["username"];
$mailer->Password = $config["mail"]["password"];
try {
$mailer->setFrom($config["mail"]["username"], $config["mail"]["from_name"]);
} catch (PHPMailerException $exception) {
$mailer->smtpClose();
$this->logger->error("Failed to set 'from' address while processing email queue.", ["cause" => $exception]);
throw new ActionException("Failed to set 'from' address while processing queue.");
}
return $mailer;
}
}