From 94a639dd89f1f0002d4f044893b70d49f8177e10 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 15 Feb 2021 12:09:16 +0100 Subject: [PATCH] Update the email log entry when delivery succeeds or fails --- .../job/EmailDeliveryBackgroundJob.class.php | 63 ++++++++++++++++++- .../IStatusReportingEmailTransport.class.php | 23 +++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 wcfsetup/install/files/lib/system/email/transport/IStatusReportingEmailTransport.class.php diff --git a/wcfsetup/install/files/lib/system/background/job/EmailDeliveryBackgroundJob.class.php b/wcfsetup/install/files/lib/system/background/job/EmailDeliveryBackgroundJob.class.php index 1194682e41..2930599c80 100644 --- a/wcfsetup/install/files/lib/system/background/job/EmailDeliveryBackgroundJob.class.php +++ b/wcfsetup/install/files/lib/system/background/job/EmailDeliveryBackgroundJob.class.php @@ -7,6 +7,7 @@ use wcf\data\email\log\entry\EmailLogEntryAction; use wcf\system\email\Email; use wcf\system\email\Mailbox; use wcf\system\email\transport\exception\PermanentFailure; +use wcf\system\email\transport\IStatusReportingEmailTransport; use wcf\system\email\UserMailbox; /** @@ -48,6 +49,11 @@ class EmailDeliveryBackgroundJob extends AbstractBackgroundJob */ protected $emailLogEntryId; + /** + * @var string + */ + private $lastErrorMessage = ''; + /** * instance of the default transport * @var \wcf\system\email\transport\IEmailTransport @@ -83,10 +89,39 @@ class EmailDeliveryBackgroundJob extends AbstractBackgroundJob 'recipient' => $this->envelopeTo->getAddress(), 'recipientID' => ($this->envelopeTo instanceof UserMailbox) ? $this->envelopeTo->getUser()->userID : null, 'status' => EmailLogEntry::STATUS_NEW, - ] + ], ]))->executeAction()['returnValues']; } + /** + * Updates the status of the log entry. + */ + final private function updateStatus(string $status, string $message = ''): void + { + (new EmailLogEntryAction([$this->emailLogEntryId], 'update', [ + 'data' => [ + 'status' => $status, + 'message' => $message, + ], + ]))->executeAction(); + } + + /** + * @inheritDoc + */ + public function onFailure() + { + $this->updateStatus(EmailLogEntry::STATUS_TRANSIENT_FAILURE, $this->lastErrorMessage); + } + + /** + * @inheritDoc + */ + public function onFinalFailure() + { + $this->updateStatus(EmailLogEntry::STATUS_PERMANENT_FAILURE, $this->lastErrorMessage); + } + /** * Emails will be sent with an increasing timeout between the tries. * @@ -141,11 +176,35 @@ class EmailDeliveryBackgroundJob extends AbstractBackgroundJob } try { - self::$transport->deliver($this->email, $this->envelopeFrom, $this->envelopeTo); + try { + $return = self::$transport->deliver($this->email, $this->envelopeFrom, $this->envelopeTo); + if (self::$transport instanceof IStatusReportingEmailTransport) { + $successMessage = $return; + } else { + $successMessage = ''; + } + } catch (\Throwable $e) { + // This is a hack, because we can't add additional optional parameters to on(Final)?Failure + // in AbstractBackgroundJob for compatibility reasons. + + $this->lastErrorMessage = $e->getMessage(); + throw $e; + } } catch (PermanentFailure $e) { // no need for retrying. Eat Exception and log the error. \wcf\functions\exception\logThrowable($e); $this->onFinalFailure(); + + return; + } + + // At this point the email delivery succeeded. + + try { + $this->updateStatus(EmailLogEntry::STATUS_SUCCESS, $successMessage); + } catch (\Throwable $e) { + // Ignore all errors, otherwise we might deliver the email multiple times. + \wcf\functions\exception\logThrowable($e); } } } diff --git a/wcfsetup/install/files/lib/system/email/transport/IStatusReportingEmailTransport.class.php b/wcfsetup/install/files/lib/system/email/transport/IStatusReportingEmailTransport.class.php new file mode 100644 index 0000000000..a7b9a6d9be --- /dev/null +++ b/wcfsetup/install/files/lib/system/email/transport/IStatusReportingEmailTransport.class.php @@ -0,0 +1,23 @@ + + * @package WoltLabSuite\Core\System\Email\Transport + * @since 5.4 + */ +interface IStatusReportingEmailTransport extends IEmailTransport +{ + /** + * @inheritDoc + */ + public function deliver(Email $email, Mailbox $envelopeFrom, Mailbox $envelopeTo): string; +} -- 2.20.1