118 lines
3.6 KiB
PHP
118 lines
3.6 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(type_key TEXT NOT NULL,
|
|
recipient 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);
|
|
}
|
|
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
/**
|
|
* Adds {@see Email Emails} to the queue.
|
|
*
|
|
* {@see emails} are added to the database, with the primary keys determined by {@see Email::$type_key} and
|
|
* {@see Email::$recipient}. If an {@see Email} with this key is already in the queue, it is replaced with
|
|
* {@see $emails}.
|
|
*
|
|
* @param array<Email> $emails the emails to queue
|
|
* @return void
|
|
*/
|
|
public function enqueue(array $emails): void
|
|
{
|
|
$stmt = $this->database->conn->prepare("INSERT OR REPLACE INTO email_tasks (type_key, recipient, subject, body)
|
|
VALUES (:type_key, :recipient, :subject, :body);");
|
|
$stmt->bindParam(":recipient", $recipient);
|
|
$stmt->bindParam(":type_key", $type_key);
|
|
$stmt->bindParam(":subject", $subject);
|
|
$stmt->bindParam(":body", $body);
|
|
|
|
foreach ($emails as $email) {
|
|
$recipient = $email->recipient;
|
|
$type_key = $email->type_key;
|
|
$subject = $email->get_subject();
|
|
$body = $email->get_body();
|
|
|
|
$stmt->execute();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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(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();
|
|
}
|
|
}
|