From dab84519f045b5fe723719182f17494525c06bd1 Mon Sep 17 00:00:00 2001 From: jekuaitk Date: Wed, 7 May 2025 13:47:13 +0200 Subject: [PATCH 1/4] Queued emails: Handle non-submission saving webforms and cleanup --- CHANGELOG.md | 9 ++- .../AdvancedQueue/JobType/QueuedEmail.php | 66 ++++++++++++------- .../src/Plugin/Mail/QueuedSmtpPhpMail.php | 2 + 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b513b32a..3663c841 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ Nedenfor ses dato for release og beskrivelse af opgaver som er implementeret. ## [Under udvikling] +## [4.2.2] 2025-05-07 + +* OS2Forms kø emails + * Håndterede formularer der ikke gemmer indsendelser. + * Opdaterede fejlbeskeder. + ## [4.2.1] 2025-05-06 * Sikrede at OS2Forms attachment elementer bliver detekteret korrekt @@ -633,7 +639,8 @@ og [OS2Forms 3.7.0](https://github.com/OS2Forms/os2forms/releases/tag/3.7.0) * GO borgersager -[Under udvikling]: https://github.com/itk-dev/os2forms_selvbetjening/compare/4.2.1...HEAD +[Under udvikling]: https://github.com/itk-dev/os2forms_selvbetjening/compare/4.2.2...HEAD +[4.2.2]: https://github.com/itk-dev/os2forms_selvbetjening/compare/4.2.1...4.2.2 [4.2.1]: https://github.com/itk-dev/os2forms_selvbetjening/compare/4.2.0...4.2.1 [4.2.0]: https://github.com/itk-dev/os2forms_selvbetjening/compare/4.1.0...4.2.0 [4.1.0]: https://github.com/itk-dev/os2forms_selvbetjening/compare/4.0.1...4.1.0 diff --git a/web/modules/custom/os2forms_queued_email/src/Plugin/AdvancedQueue/JobType/QueuedEmail.php b/web/modules/custom/os2forms_queued_email/src/Plugin/AdvancedQueue/JobType/QueuedEmail.php index e14912ca..46c7ab4d 100644 --- a/web/modules/custom/os2forms_queued_email/src/Plugin/AdvancedQueue/JobType/QueuedEmail.php +++ b/web/modules/custom/os2forms_queued_email/src/Plugin/AdvancedQueue/JobType/QueuedEmail.php @@ -77,9 +77,6 @@ public function process(Job $job): JobResult { $payload = $job->getPayload(); $message = json_decode($payload['message'], TRUE); - // Load the Webform submission entity by ID. - $submission = WebformSubmission::load($payload['submissionId']); - // Gather filenames for os2forms attachments for deletion later. $os2formsAttachmentFilenames = []; @@ -88,10 +85,15 @@ public function process(Job $job): JobResult { // Handle OS2Forms attachments. if (isset($attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME])) { $os2formsAttachmentFilenames[] = $attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME]; + + if (FALSE === file_exists($attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME])) { + throw new \Exception('OS2Forms attachment file not found: ' . $attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME]); + } + $attachment[self::FILECONTENT] = file_get_contents($attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME]); if (FALSE === $attachment[self::FILECONTENT]) { - throw new \Exception('OS2Forms attachment file not found: ' . $attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME]); + throw new \Exception('OS2Forms attachment file cannot be read: ' . $attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME]); } unset($attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME]); @@ -110,42 +112,56 @@ public function process(Job $job): JobResult { } - $this->mailManager->createInstance('SMTPMailSystem')->mail($message); + $result = $this->mailManager->createInstance('SMTPMailSystem')->mail($message); - $logger_context = [ - 'handler_id' => 'os2forms_queued_email', - 'channel' => 'webform_submission', - 'webform_submission' => $submission, - 'operation' => 'email sent', - ]; + // Logging of failed mail is handled in catch. + if (!$result) { + throw new \Exception('Failed sending email'); + } - $this->submissionLogger->notice($this->t('The submission #@serial was successfully delivered', ['@serial' => $submission->serial()]), $logger_context); + // Load the Webform submission entity by ID. + // Be aware that some webforms may be configured to NOT save submissions, + // submission may therefore be null. + $submission = WebformSubmission::load($payload['submissionId']); + + if ($submission) { + $logger_context = [ + 'handler_id' => 'os2forms_queued_email', + 'channel' => 'webform_submission', + 'webform_submission' => $submission, + 'operation' => 'email sent', + ]; + + $this->submissionLogger->notice($this->t('The submission #@serial was successfully delivered', ['@serial' => $submission->serial()]), $logger_context); + } // Remove OS2Forms attachments. foreach ($os2formsAttachmentFilenames as $os2formsAttachmentFilename) { unlink($os2formsAttachmentFilename); } - $msg = sprintf('Email, %s, sent to %s. Webform id: %s.', $message['subject'], $message['to'], $submission->getWebform()->id()); + $msg = sprintf('Email, %s, sent to %s. Webform id: %s.', $payload['subject'] ?? NULL, $payload['to'] ?? NULL, $payload['webformId'] ?? NULL); $this->auditLogger->info('Email', $msg); return JobResult::success(); } catch (\Exception $e) { - $submission = $payload['submissionId'] ? WebformSubmission::load($payload['submissionId']) : NULL; - - $logger_context = [ - 'handler_id' => 'os2forms_queued_email', - 'channel' => 'webform_submission', - 'webform_submission' => $submission, - 'operation' => 'email failed', - ]; + $submission = WebformSubmission::load($payload['submissionId']); - $this->submissionLogger->error($this->t('The submission #@serial failed (@message)', [ - '@serial' => $submission?->serial(), - '@message' => $e->getMessage(), - ]), $logger_context); + if ($submission) { + $logger_context = [ + 'handler_id' => 'os2forms_queued_email', + 'channel' => 'webform_submission', + 'webform_submission' => $submission, + 'operation' => 'email failed', + ]; + + $this->submissionLogger->error($this->t('The submission #@serial failed (@message)', [ + '@serial' => $submission->serial(), + '@message' => $e->getMessage(), + ]), $logger_context); + } return JobResult::failure($e->getMessage()); } diff --git a/web/modules/custom/os2forms_queued_email/src/Plugin/Mail/QueuedSmtpPhpMail.php b/web/modules/custom/os2forms_queued_email/src/Plugin/Mail/QueuedSmtpPhpMail.php index 4ef5e795..bc1e9dab 100644 --- a/web/modules/custom/os2forms_queued_email/src/Plugin/Mail/QueuedSmtpPhpMail.php +++ b/web/modules/custom/os2forms_queued_email/src/Plugin/Mail/QueuedSmtpPhpMail.php @@ -115,7 +115,9 @@ public function mail(array $message) { 'key' => $message['key'], 'to' => $message['to'], 'subject' => $message['subject'], + // Note that submissions may not exist later when job is processed. 'submissionId' => $submission->id(), + 'webformId' => $submission->getWebform()->id(), 'message' => json_encode($message), ]); From f67031332e1dc957fc856515341de04bd2c14705 Mon Sep 17 00:00:00 2001 From: jekuaitk Date: Wed, 7 May 2025 14:41:17 +0200 Subject: [PATCH 2/4] Code cleanup --- .../AdvancedQueue/JobType/QueuedEmail.php | 75 ++++++++++++------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/web/modules/custom/os2forms_queued_email/src/Plugin/AdvancedQueue/JobType/QueuedEmail.php b/web/modules/custom/os2forms_queued_email/src/Plugin/AdvancedQueue/JobType/QueuedEmail.php index 46c7ab4d..d548d1fa 100644 --- a/web/modules/custom/os2forms_queued_email/src/Plugin/AdvancedQueue/JobType/QueuedEmail.php +++ b/web/modules/custom/os2forms_queued_email/src/Plugin/AdvancedQueue/JobType/QueuedEmail.php @@ -23,6 +23,7 @@ */ final class QueuedEmail extends JobTypeBase implements ContainerFactoryPluginInterface { + public const OS2FORMS_QUEUED_EMAIL_LOGGER_CHANNEL = 'os2forms_queued_email_info'; public const OS2FORMS_QUEUED_EMAIL_IS_STATIC_FILE = 'OS2FORMS_QUEUED_EMAIL_IS_STATIC_FILE'; public const OS2FORMS_QUEUED_EMAIL_FILE_PATH = 'private://queued-email-files'; public const OS2FORMS_QUEUED_EMAIL_CONFIG_NAME = 'os2forms_queued_email_file_path'; @@ -36,6 +37,13 @@ final class QueuedEmail extends JobTypeBase implements ContainerFactoryPluginInt */ protected LoggerChannelInterface $submissionLogger; + /** + * The submission logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ + protected LoggerChannelInterface $queuedEmailLogger; + /** * {@inheritdoc} * @@ -51,6 +59,7 @@ public function __construct( ) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->submissionLogger = $loggerFactory->get('webform_submission'); + $this->queuedEmailLogger = $loggerFactory->get(self::OS2FORMS_QUEUED_EMAIL_LOGGER_CHANNEL); } /** @@ -86,7 +95,7 @@ public function process(Job $job): JobResult { if (isset($attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME])) { $os2formsAttachmentFilenames[] = $attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME]; - if (FALSE === file_exists($attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME])) { + if (!file_exists($attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME])) { throw new \Exception('OS2Forms attachment file not found: ' . $attachment[self::OS2FORMS_QUEUED_EMAIL_CONFIG_NAME]); } @@ -119,20 +128,26 @@ public function process(Job $job): JobResult { throw new \Exception('Failed sending email'); } - // Load the Webform submission entity by ID. - // Be aware that some webforms may be configured to NOT save submissions, - // submission may therefore be null. - $submission = WebformSubmission::load($payload['submissionId']); - - if ($submission) { - $logger_context = [ - 'handler_id' => 'os2forms_queued_email', - 'channel' => 'webform_submission', - 'webform_submission' => $submission, - 'operation' => 'email sent', - ]; + try { + // Load the Webform submission entity by ID. + // Beware that some webforms may be configured to NOT save submissions, + // submission may therefore be null. + $submission = WebformSubmission::load($payload['submissionId']); + + if ($submission) { + $logger_context = [ + 'handler_id' => 'os2forms_queued_email', + 'channel' => 'webform_submission', + 'webform_submission' => $submission, + 'operation' => 'email sent', + ]; + + $this->submissionLogger->notice($this->t('The submission #@serial was successfully delivered', ['@serial' => $submission->serial()]), $logger_context); + } - $this->submissionLogger->notice($this->t('The submission #@serial was successfully delivered', ['@serial' => $submission->serial()]), $logger_context); + } + catch (\Exception $e) { + $this->queuedEmailLogger->notice(sprintf('Failed logging to webform_submission logger: %s', $e->getMessage())); } // Remove OS2Forms attachments. @@ -147,20 +162,26 @@ public function process(Job $job): JobResult { } catch (\Exception $e) { - $submission = WebformSubmission::load($payload['submissionId']); - - if ($submission) { - $logger_context = [ - 'handler_id' => 'os2forms_queued_email', - 'channel' => 'webform_submission', - 'webform_submission' => $submission, - 'operation' => 'email failed', - ]; + try { + $submission = WebformSubmission::load($payload['submissionId']); + + if ($submission) { + $logger_context = [ + 'handler_id' => 'os2forms_queued_email', + 'channel' => 'webform_submission', + 'webform_submission' => $submission, + 'operation' => 'email failed', + ]; + + $this->submissionLogger->error($this->t('The submission #@serial failed (@message)', [ + '@serial' => $submission->serial(), + '@message' => $e->getMessage(), + ]), $logger_context); + } - $this->submissionLogger->error($this->t('The submission #@serial failed (@message)', [ - '@serial' => $submission->serial(), - '@message' => $e->getMessage(), - ]), $logger_context); + } + catch (\Exception $e) { + $this->queuedEmailLogger->notice(sprintf('Failed logging to webform_submission logger: %s', $e->getMessage())); } return JobResult::failure($e->getMessage()); From 0ab262daf2c8abcae0f07757e92bd8a01da0188e Mon Sep 17 00:00:00 2001 From: jekuaitk Date: Thu, 8 May 2025 14:17:43 +0200 Subject: [PATCH 3/4] Updated advancedqueue --- CHANGELOG.md | 2 ++ composer.lock | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3663c841..1c831bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ Nedenfor ses dato for release og beskrivelse af opgaver som er implementeret. * OS2Forms kø emails * Håndterede formularer der ikke gemmer indsendelser. * Opdaterede fejlbeskeder. +* Opdaterede til nyeste version af kø-systemet, + [advancedqueue](https://www.drupal.org/project/advancedqueue). ## [4.2.1] 2025-05-06 diff --git a/composer.lock b/composer.lock index 12dd5522..f382b721 100644 --- a/composer.lock +++ b/composer.lock @@ -1469,26 +1469,29 @@ }, { "name": "drupal/advancedqueue", - "version": "1.2.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/advancedqueue.git", - "reference": "8.x-1.2" + "reference": "8.x-1.4" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/advancedqueue-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "373a6c823cbeb4483be2b7968f5dde9163b6e5e1" + "url": "https://ftp.drupal.org/files/projects/advancedqueue-8.x-1.4.zip", + "reference": "8.x-1.4", + "shasum": "9b408d9ad7e13fe1f2afa546a28de054b2abe586" }, "require": { - "drupal/core": "^9.1 || ^10 || ^11" + "drupal/core": "^10.2 || ^11" + }, + "require-dev": { + "drupal/plugin": "^2" }, "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.2", - "datestamp": "1725364658", + "version": "8.x-1.4", + "datestamp": "1745429711", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" From dcf34b2052d4e1582d1f7b82bd0c3caa3a9b61b7 Mon Sep 17 00:00:00 2001 From: jekuaitk Date: Tue, 20 May 2025 13:50:18 +0200 Subject: [PATCH 4/4] Fixed markdown coding standards --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 939ff007..553223bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,6 @@ Nedenfor ses dato for release og beskrivelse af opgaver som er implementeret. * Opdaterede til nyeste version af kø-systemet, [advancedqueue](https://www.drupal.org/project/advancedqueue). - ## [4.2.1] 2025-05-06 * Sikrede at OS2Forms attachment elementer bliver detekteret korrekt