110 lines
3.4 KiB
PHP
110 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace com\fwdekker\deathnotifier\mailer;
|
|
|
|
use com\fwdekker\deathnotifier\Database;
|
|
use PDO;
|
|
|
|
|
|
/**
|
|
* A queue of {@see Email Emails}, stored in a {@see Database}.
|
|
*/
|
|
class EmailQueue
|
|
{
|
|
/**
|
|
* @var Database the database to store the queue in
|
|
*/
|
|
private readonly Database $database;
|
|
|
|
|
|
/**
|
|
* Constructs a new `EmailQueue`.
|
|
*
|
|
* @param Database $database the database to store the queue in
|
|
*/
|
|
public function __construct(Database $database)
|
|
{
|
|
$this->database = $database;
|
|
}
|
|
|
|
|
|
/**
|
|
* Populates the {@see Database} with the necessary structures for an `EmailQueue`.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function install(): void
|
|
{
|
|
$conn = $this->database->conn;
|
|
$conn->exec("CREATE TABLE email_tasks(recipient TEXT NOT NULL,
|
|
type_key TEXT NOT NULL,
|
|
subject TEXT NOT NULL,
|
|
body TEXT NOT NULL,
|
|
PRIMARY KEY (type_key, recipient));");
|
|
}
|
|
|
|
/**
|
|
* Executes {@see $lambda} within a single database transaction.
|
|
*
|
|
* @param callable(): void $lambda the function to execute within a transaction
|
|
* @return void
|
|
* @see Database::transaction()
|
|
*/
|
|
public function transaction(callable $lambda): void
|
|
{
|
|
$this->database->transaction($lambda);
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds an {@see Email} to the queue.
|
|
*
|
|
* {@see email} is added to the database, with its primary key determined by {@see Email::$type_key} and
|
|
* {@see Email::$recipient}. If an {@see Email} with this key is already in this queue, it is replaced with
|
|
* {@see $email}.
|
|
*
|
|
* @param Email $email the email to queue
|
|
* @return void
|
|
*/
|
|
public function queue_email(Email $email): void
|
|
{
|
|
$stmt = $this->database->conn->prepare("INSERT OR REPLACE INTO email_tasks (recipient, type_key, subject, body)
|
|
VALUES (:recipient, :type_key, :subject, :body);");
|
|
$stmt->bindValue(":recipient", $email->recipient);
|
|
$stmt->bindValue(":type_key", $email->type_key);
|
|
$stmt->bindValue(":subject", $email->get_subject());
|
|
$stmt->bindValue(":body", $email->get_body());
|
|
$stmt->execute();
|
|
}
|
|
|
|
/**
|
|
* Returns all queued emails.
|
|
*
|
|
* @return array<array{"type_key": string, "recipient": string, "subject": string, "body": string}> all queued
|
|
* emails
|
|
*/
|
|
public function get_queue(): array
|
|
{
|
|
$stmt = $this->database->conn->prepare("SELECT type_key, recipient, subject, body FROM email_tasks;");
|
|
$stmt->execute();
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
/**
|
|
* Removes mails from the queue.
|
|
*
|
|
* @param array<array{"type_key": string, "recipient": string}> $emails the emails to remove from the queue
|
|
* @return void
|
|
*/
|
|
public function unqueue_emails(array $emails): void
|
|
{
|
|
$stmt = $this->database->conn->prepare("DELETE FROM email_tasks
|
|
WHERE type_key=:type_key AND recipient=:recipient;");
|
|
$stmt->bindParam(":type_key", $type_key);
|
|
$stmt->bindParam(":recipient", $recipient);
|
|
|
|
foreach ($emails as ["type_key" => $type_key, "recipient" => $recipient])
|
|
$stmt->execute();
|
|
}
|
|
}
|