diff --git a/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.services.yml b/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.services.yml index badcf005..2d2b73ca 100644 --- a/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.services.yml +++ b/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.services.yml @@ -18,4 +18,5 @@ services: - '@logger.channel.os2forms_forloeb' - '@logger.channel.os2forms_forloeb_submission' - '@module_handler' + - '@plugin.manager.entity_print.print_engine' - '@Drupal\os2forms_digital_post\Helper\DigitalPostHelper' diff --git a/web/sites/default/modules/os2forms_forloeb/src/Controller/MaestroNotificationController.php b/web/sites/default/modules/os2forms_forloeb/src/Controller/MaestroNotificationController.php index c626b49e..1264d730 100644 --- a/web/sites/default/modules/os2forms_forloeb/src/Controller/MaestroNotificationController.php +++ b/web/sites/default/modules/os2forms_forloeb/src/Controller/MaestroNotificationController.php @@ -81,9 +81,9 @@ public function preview(Request $request, WebformInterface $webform, string $han $submission = $this->webformSubmissionStorage->load($currentSubmission); $templateTask = []; $maestroQueueID = 0; - [,, - $recipient, - $subject, + [ + 'recipient' => $recipient, + 'subject' => $subject, ] = $this->maestroHelper->renderNotification($submission, $handler->getHandlerId(), $notification_type, $templateTask, $maestroQueueID, $content_type); return [ @@ -107,7 +107,10 @@ public function preview(Request $request, WebformInterface $webform, string $han public function previewRender(Request $request, WebformInterface $webform, string $handler, string $notification_type, string $content_type, WebformSubmissionInterface $submission) { $templateTask = []; $maestroQueueID = 0; - [$content, $contentType] = $this->maestroHelper->renderNotification($submission, $handler, $notification_type, $templateTask, $maestroQueueID, $content_type); + [ + 'content' => $content, + 'contentType' => $contentType, + ] = $this->maestroHelper->renderNotification($submission, $handler, $notification_type, $templateTask, $maestroQueueID, $content_type); $response = new Response($content); if ('pdf' === $contentType) { diff --git a/web/sites/default/modules/os2forms_forloeb/src/Form/SettingsForm.php b/web/sites/default/modules/os2forms_forloeb/src/Form/SettingsForm.php index d2aadbc6..5579af60 100644 --- a/web/sites/default/modules/os2forms_forloeb/src/Form/SettingsForm.php +++ b/web/sites/default/modules/os2forms_forloeb/src/Form/SettingsForm.php @@ -110,19 +110,25 @@ public function buildForm(array $form, FormStateInterface $form_state) { $defaultTemplate = file_exists($templatePath) ? file_get_contents($templatePath) : NULL; $form['templates']['notification_email'] = [ '#type' => 'textarea', - '#rows' => 10, + '#rows' => 20, '#required' => TRUE, '#title' => $this->t('Email template'), '#default_value' => $config->get('templates')['notification_email'] ?? $defaultTemplate, - '#description' => $this->t('HTML template for email notifications. See @template_path'), + '#description' => $this->t('HTML template for email notifications. If the template is a path, e.g. @templatePath, the template will be loaded from this path.', [ + '@templatePath' => $templatePath, + ]), ]; + $templatePath = $this->moduleHandler->getPath('os2forms_forloeb') . '/templates/os2forms-forloeb-notification-message-pdf-html.html.twig'; $form['templates']['notification_pdf'] = [ '#type' => 'textarea', + '#rows' => 20, '#required' => TRUE, '#title' => $this->t('PDF template'), - '#default_value' => $config->get('templates')['notification_pdf'] ?? '', - '#description' => $this->t('HTML template for PDF notifications (digital post)'), + '#default_value' => $config->get('templates')['notification_pdf'] ?? $defaultTemplate, + '#description' => $this->t('HTML template for PDF notifications (digital post). If the template is a path, e.g. @templatePath, the template will be loaded from this path.', [ + '@templatePath' => $templatePath, + ]), ]; return parent::buildForm($form, $form_state); @@ -135,6 +141,7 @@ public function submitForm(array &$form, FormStateInterface $formState) { $this->config(static::SETTINGS) ->set('known_anonymous_roles', $formState->getValue('known_anonymous_roles')) ->set('processing', $formState->getValue('processing')) + ->set('templates', $formState->getValue('templates')) ->save(); parent::submitForm($form, $formState); diff --git a/web/sites/default/modules/os2forms_forloeb/src/MaestroHelper.php b/web/sites/default/modules/os2forms_forloeb/src/MaestroHelper.php index d784352b..5f8a16f4 100644 --- a/web/sites/default/modules/os2forms_forloeb/src/MaestroHelper.php +++ b/web/sites/default/modules/os2forms_forloeb/src/MaestroHelper.php @@ -4,7 +4,6 @@ use DigitalPost\MeMo\Action; use DigitalPost\MeMo\EntryPoint; -use Dompdf\Dompdf; use Drupal\advancedqueue\Entity\QueueInterface; use Drupal\advancedqueue\Job; use Drupal\advancedqueue\JobResult; @@ -19,14 +18,15 @@ use Drupal\Core\Mail\MailManagerInterface; use Drupal\Core\Render\Markup; use Drupal\Core\Url; +use Drupal\entity_print\Plugin\EntityPrintPluginManagerInterface; use Drupal\maestro\Engine\MaestroEngine; use Drupal\maestro\Utility\TaskHandler; use Drupal\os2forms_digital_post\Helper\DigitalPostHelper; use Drupal\os2forms_digital_post\Model\Document; use Drupal\os2forms_forloeb\Exception\RuntimeException; +use Drupal\os2forms_forloeb\Form\SettingsForm; use Drupal\os2forms_forloeb\Plugin\AdvancedQueue\JobType\SendMeastroNotification; use Drupal\os2forms_forloeb\Plugin\EngineTasks\MaestroWebformInheritTask; -use Drupal\os2forms_forloeb\Form\SettingsForm; use Drupal\os2forms_forloeb\Plugin\WebformHandler\MaestroNotificationHandler; use Drupal\webform\WebformSubmissionInterface; use Drupal\webform\WebformSubmissionStorageInterface; @@ -80,6 +80,7 @@ public function __construct( readonly private LoggerChannelInterface $logger, readonly private LoggerChannelInterface $submissionLogger, readonly private ModuleHandlerInterface $moduleHandler, + readonly private EntityPrintPluginManagerInterface $entityPrintPluginManager, readonly private DigitalPostHelper $digitalPostHelper ) { $this->config = $configFactory->get(SettingsForm::SETTINGS); @@ -217,19 +218,19 @@ private function sendNotification( } [ - $content, - $contentType, - $recipient, - $subject, - $taskUrl, - $actionLabel, + 'content' => $content, + 'contentType' => $contentType, + 'recipient' => $recipient, + 'subject' => $subject, + 'taskUrl' => $taskUrl, + 'actionLabel' => $actionLabel, ] = $this->renderNotification($submission, $handler->getHandlerId(), $notificationType, $templateTask, $maestroQueueID); if ('email' === $contentType) { - $this->sendNotificationEmail($recipient, $subject, $content, $submission); + $this->sendNotificationEmail($recipient, $subject, $content, $submission, $notificationType); } else { - $this->sendNotificationDigitalPost($recipient, $subject, $content, $taskUrl, $actionLabel, $submission); + $this->sendNotificationDigitalPost($recipient, $subject, $content, $taskUrl, $actionLabel, $submission, $notificationType); } } } @@ -273,34 +274,47 @@ private function sendNotificationEmail( string $recipient, string $subject, string $body, - WebformSubmissionInterface $submission + WebformSubmissionInterface $submission, + string $notificationType ): void { - $message = [ - 'subject' => $subject, - 'body' => $body, - 'html' => TRUE, - ]; + try { + $message = [ + 'subject' => $subject, + 'body' => $body, + 'html' => TRUE, + ]; - $langcode = $this->languageManager->getCurrentLanguage()->getId(); + $langcode = $this->languageManager->getCurrentLanguage()->getId(); - $result = $this->mailManager->mail( - 'os2forms_forloeb', - 'notification', - $recipient, - $langcode, - $message - ); + $result = $this->mailManager->mail( + 'os2forms_forloeb', + 'notification', + $recipient, + $langcode, + $message + ); - if (!$result['result']) { - throw new RuntimeException(sprintf('Error sending notification email to %s', $recipient)); - } + if (!$result['result']) { + throw new RuntimeException(sprintf('Error sending notification (%s) email to %s', $notificationType, $recipient)); + } - $this->notice('Notification email sent to @recipient', [ - 'webform_submission' => $submission, - '@recipient' => $recipient, - 'handler_id' => 'os2forms_forloeb', - 'operation' => 'notification sent', - ]); + $this->notice('Email notification (@type) sent to @recipient', [ + '@type' => $notificationType, + 'webform_submission' => $submission, + '@recipient' => $recipient, + 'handler_id' => 'os2forms_forloeb', + 'operation' => 'notification sent', + ]); + } + catch (\Exception $exception) { + $this->error('Error sending email notification (@type): @message', [ + '@type' => $notificationType, + '@message' => $exception->getMessage(), + 'webform_submission' => $submission, + 'handler_id' => 'os2forms_forloeb', + 'operation' => 'failed sending notification', + ]); + } } /** @@ -312,7 +326,8 @@ private function sendNotificationDigitalPost( string $content, string $taskUrl, string $actionLabel, - WebformSubmissionInterface $submission + WebformSubmissionInterface $submission, + string $notificationType ): void { if (!$this->moduleHandler->moduleExists('os2forms_digital_post')) { throw new RuntimeException('Cannot send digital post. Module os2forms_digital_post not installed.'); @@ -349,14 +364,16 @@ private function sendNotificationDigitalPost( $submission ); - $this->notice('Digital post sent', [ + $this->notice('Digital post notification sent (@type)', [ + '@type' => $notificationType, 'webform_submission' => $submission, 'handler_id' => 'os2forms_forloeb', 'operation' => 'notification sent', ]); } catch (\Exception $exception) { - $this->error('Error sending digital post: @message', [ + $this->error('Error sending digital post notification (@type): @message', [ + '@type' => $notificationType, '@message' => $exception->getMessage(), 'webform_submission' => $submission, 'handler_id' => 'os2forms_forloeb', @@ -383,13 +400,13 @@ private function sendNotificationDigitalPost( * on the recipient. * * @return array - * The rendered notification as a list - * - Content - * - Content type - * - Recipient - * - Subject - * - Task URL (for digital post) - * - Action label (for digital post) + * The rendered notification with keys + * - content + * - contentType + * - recipient + * - subject + * - taskUrl (for digital post) + * - actionLabel (for digital post) */ public function renderNotification(WebformSubmissionInterface $submission, string $handlerId, string $notificationType, array $templateTask, int $maestroQueueID, string $contentType = NULL): array { $handler = $submission->getWebform()->getHandler($handlerId); @@ -463,16 +480,17 @@ public function renderNotification(WebformSubmissionInterface $submission, strin switch ($contentType) { case 'email': - $content = $this->buildHtml($contentType, $subject, $content, $taskUrl, $actionLabel, $submission); + $content = $this->renderHtml($contentType, $subject, $content, $taskUrl, $actionLabel, $submission); break; case 'pdf': - $pdfContent = $this->buildHtml($contentType, $subject, $content, $taskUrl, $actionLabel, $submission); - $dompdf = new Dompdf(); - $dompdf->loadHtml($pdfContent); - $dompdf->render(); + $pdfContent = $this->renderHtml($contentType, $subject, $content, $taskUrl, $actionLabel, $submission); - $content = $dompdf->output(); + // Get dompdf plugin from entity_print module. + /** @var \Drupal\entity_print\Plugin\EntityPrint\PrintEngine\PdfEngineBase $printer */ + $printer = $this->entityPrintPluginManager->createInstance('dompdf'); + $printer->addPage($pdfContent); + $content = $printer->getBlob(); break; default: @@ -480,12 +498,12 @@ public function renderNotification(WebformSubmissionInterface $submission, strin } return [ - $content, - $contentType, - $recipient, - $subject, - $taskUrl, - $actionLabel, + 'content' => $content, + 'contentType' => $contentType, + 'recipient' => $recipient, + 'subject' => $subject, + 'taskUrl' => $taskUrl, + 'actionLabel' => $actionLabel, ]; } @@ -495,7 +513,7 @@ public function renderNotification(WebformSubmissionInterface $submission, strin /** * Build HTML. */ - private function buildHtml( + private function renderHtml( string $type, string $subject, array $content, @@ -503,19 +521,27 @@ private function buildHtml( string $actionLabel, WebformSubmissionInterface $submission ): string|MarkupInterface { - // Render body as HTML. - $theme = sprintf('os2forms_forloeb_notification_message_%s_html', $type); + $template = $this->config->get('templates')['notification_' . $type] ?? NULL; + if (file_exists($template)) { + $template = file_get_contents($template) ?: NULL; + } + if (NULL === $template) { + $template = 'Missing or invalid template'; + } $build = [ - '#theme' => $theme, - '#message' => [ - 'subject' => $subject, - 'content' => $content, + '#type' => 'inline_template', + '#template' => $template, + '#context' => [ + 'message' => [ + 'subject' => $subject, + 'content' => $content, + ], + 'task_url' => $taskUrl, + 'action_label' => $actionLabel, + 'webform_submission' => $submission, + 'handler' => $this, ], - '#task_url' => $taskUrl, - '#action_label' => $actionLabel, - '#webform_submission' => $submission, - '#handler' => $this, ]; return Markup::create(trim((string) $this->webformThemeManager->renderPlain($build))); diff --git a/web/sites/default/modules/os2forms_forloeb/src/Plugin/WebformHandler/MaestroNotificationHandler.php b/web/sites/default/modules/os2forms_forloeb/src/Plugin/WebformHandler/MaestroNotificationHandler.php index d0f52636..90262dbb 100644 --- a/web/sites/default/modules/os2forms_forloeb/src/Plugin/WebformHandler/MaestroNotificationHandler.php +++ b/web/sites/default/modules/os2forms_forloeb/src/Plugin/WebformHandler/MaestroNotificationHandler.php @@ -273,7 +273,7 @@ public function getEnabledNotifications(): array { MaestroHelper::OS2FORMS_FORLOEB_NOTIFICATION_ESCALATION, ] as $notificationType) { if ($this->configuration[self::NOTIFICATION][$notificationType][self::NOTIFICATION_ENABLE] ?? FALSE) { - $enabledNotificationTypes[] = $notificationType; + $enabledNotificationTypes[$notificationType] = $notificationType; } } @@ -284,7 +284,7 @@ public function getEnabledNotifications(): array { * Check if a notification type is enabled. */ public function isNotificationEnabled(string $notificationType): bool { - return in_array($notificationType, $this->getEnabledNotifications(), TRUE); + return isset($this->getEnabledNotifications()[$notificationType]); } } diff --git a/web/sites/default/modules/os2forms_forloeb/templates/os2forms-forloeb-notification-message-pdf-html.html.twig b/web/sites/default/modules/os2forms_forloeb/templates/os2forms-forloeb-notification-message-pdf-html.html.twig index 25d5b510..15bea629 100644 --- a/web/sites/default/modules/os2forms_forloeb/templates/os2forms-forloeb-notification-message-pdf-html.html.twig +++ b/web/sites/default/modules/os2forms_forloeb/templates/os2forms-forloeb-notification-message-pdf-html.html.twig @@ -1,31 +1,62 @@ {# - Template file for Maestro notification. - - @var array message - @var task_url +/** + * @file + * Template for Maestro notification email. + * + * Available variables: + * - message: The notification message + * - subject: the notification subject + * - contect: the notification content. Must be rendered as `processed_text`, i.e.: + * @code + * {{ { + * '#type': 'processed_text', + * '#text': message.content.value, + * '#format': message.content.format, + * } }} + * @endcode + * - notification_type: The type of notification () + * - task_url: URL of the task. + * - action_label: Optional label for the task action. + */ #} - + {{ message.subject }} - + + header img { + height: 100%; + } + -
+
+ Aarhus Kommune-logo +
+ +
{# @see https://api.drupal.org/api/drupal/core%21modules%21filter%21filter.module/function/check_markup/9 #}
{{ { '#type': 'processed_text', '#text': message.content.value, '#format': message.content.format, } }}
-
+ +