diff --git a/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.module b/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.module
index fa6289ea..ac30e6ed 100644
--- a/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.module
+++ b/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.module
@@ -329,6 +329,22 @@ function os2forms_forloeb_mail_alter(&$message) {
* Implements hook_theme().
*/
function os2forms_forloeb_theme(array &$variables) {
+ $theme['os2forms_forloeb_notification_preview'] = [
+ 'variables' => [
+ 'webform' => NULL,
+ 'handler' => NULL,
+ 'type' => NULL,
+ 'submission' => NULL,
+ 'return_url' => NULL,
+ 'render_url' => NULL,
+ 'preview_urls' => [
+ 'prev' => NULL,
+ 'self' => NULL,
+ 'next' => NULL,
+ ],
+ ],
+ ];
+
$theme['os2forms_forloeb_notification_message_email_html'] = [
'variables' => [
'message' => [
diff --git a/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.routing.yml b/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.routing.yml
index 44803e50..7f0c28d8 100644
--- a/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.routing.yml
+++ b/web/sites/default/modules/os2forms_forloeb/os2forms_forloeb.routing.yml
@@ -5,3 +5,37 @@ os2forms_forloeb.settings:
_title: 'OS2Forms forløb'
requirements:
_permission: 'administer site configuration'
+
+os2forms_forloeb.meastro_notification.preview:
+ path: '/admin/structure/webform/manage/{webform}/os2forms_forloeb/{handler}/preview/{content_type}'
+ defaults:
+ _controller: '\Drupal\os2forms_forloeb\Controller\MaestroNotificationController::preview'
+ _title: 'Maestro notification preview'
+ options:
+ parameters:
+ webform:
+ type: 'entity:webform'
+ requirements:
+ _permission: 'view any webform submission'
+
+os2forms_forloeb.meastro_notification.preview_render:
+ path: '/admin/structure/webform/manage/{webform}/os2forms_forloeb/{handler}/preview/{content_type}/render/{submission}'
+ defaults:
+ _controller: '\Drupal\os2forms_forloeb\Controller\MaestroNotificationController::previewRender'
+ _title: 'Maestro notification render preview'
+ options:
+ parameters:
+ webform:
+ type: 'entity:webform'
+ submission:
+ type: 'entity:webform_submission'
+ requirements:
+ _permission: 'view any webform submission'
+
+os2forms_forloeb.meastro_notification.preview_message:
+ path: '/os2forms_forloeb/notification/message'
+ defaults:
+ _controller: '\Drupal\os2forms_forloeb\Controller\MaestroNotificationController::message'
+ _title: 'Maestro notification message'
+ requirements:
+ _permission: 'view any webform submission'
diff --git a/web/sites/default/modules/os2forms_forloeb/src/Controller/MaestroNotificationController.php b/web/sites/default/modules/os2forms_forloeb/src/Controller/MaestroNotificationController.php
new file mode 100644
index 00000000..b7e966d9
--- /dev/null
+++ b/web/sites/default/modules/os2forms_forloeb/src/Controller/MaestroNotificationController.php
@@ -0,0 +1,119 @@
+get('entity_type.manager')->getStorage('webform_submission'),
+ $container->get(MaestroHelper::class)
+ );
+ }
+
+ /**
+ * Preview action.
+ */
+ public function preview(Request $request, WebformInterface $webform, string $handler, string $content_type, RouteMatchInterface $routeMatch) {
+ $submissionIds = array_keys($this->webformSubmissionStorage->getQuery()
+ ->condition('webform_id', $webform->id())
+ ->sort('created', 'DESC')
+ ->execute());
+ $currentSubmission = (int) $request->query->get('submission');
+ $index = array_search($currentSubmission, $submissionIds);
+ if (FALSE === $index) {
+ $currentSubmission = reset($submissionIds) ?: NULL;
+ $index = array_search($currentSubmission, $submissionIds);
+ }
+
+ $previewUrls = array_map(
+ static fn ($submission) => Url::fromRoute('os2forms_forloeb.meastro_notification.preview', [
+ 'webform' => $webform->id(),
+ 'handler' => $handler,
+ 'content_type' => $content_type,
+ 'submission' => $submission,
+ ]),
+ array_filter([
+ 'prev' => $submissionIds[$index + 1] ?? NULL,
+ 'self' => $currentSubmission,
+ 'next' => $submissionIds[$index - 1] ?? NULL,
+ ])
+ );
+
+ $renderUrl = NULL !== $currentSubmission
+ ? Url::fromRoute('os2forms_forloeb.meastro_notification.preview_render', [
+ 'webform' => $webform->id(),
+ 'handler' => $handler,
+ 'content_type' => $content_type,
+ 'submission' => $currentSubmission,
+ ])
+ : NULL;
+
+ return [
+ '#theme' => 'os2forms_forloeb_notification_preview',
+ '#webform' => $webform,
+ '#handler' => $handler,
+ '#type' => $content_type,
+ '#submission' => $currentSubmission,
+ '#return_url' => $webform->toUrl('handlers'),
+ '#render_url' => $renderUrl,
+ '#preview_urls' => $previewUrls,
+ ];
+ }
+
+ /**
+ * Render notification preview.
+ */
+ public function previewRender(Request $request, WebformInterface $webform, string $handler, string $content_type, WebformSubmissionInterface $submission) {
+ $templateTask = [];
+ $maestroQueueID = 0;
+ [$content, $contentType] = $this->maestroHelper->renderNotification($submission, $handler, $templateTask, $maestroQueueID, $content_type);
+
+ $response = new Response($content);
+ if ('pdf' === $contentType) {
+ $response->headers->set('content-type', Document::MIME_TYPE_PDF);
+ }
+
+ return $response;
+ }
+
+ /**
+ * Message action.
+ */
+ public function message(Request $request): Response {
+ $content[] = '
' . $request->get('message') . '
';
+ if ($referer = $request->headers->get('referer')) {
+ $content[] = sprintf('Go back', $referer);
+ }
+
+ return new Response(implode(PHP_EOL, $content));
+ }
+
+}
diff --git a/web/sites/default/modules/os2forms_forloeb/src/MaestroHelper.php b/web/sites/default/modules/os2forms_forloeb/src/MaestroHelper.php
index a1672d9d..44e2f505 100644
--- a/web/sites/default/modules/os2forms_forloeb/src/MaestroHelper.php
+++ b/web/sites/default/modules/os2forms_forloeb/src/MaestroHelper.php
@@ -18,6 +18,7 @@
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Core\Render\Markup;
+use Drupal\Core\Url;
use Drupal\maestro\Engine\MaestroEngine;
use Drupal\maestro\Utility\TaskHandler;
use Drupal\os2forms_digital_post\Helper\DigitalPostHelper;
@@ -205,56 +206,26 @@ private function sendNotification(
];
try {
- $data = $submission->getData();
- $webform = $submission->getWebform();
- $handlers = $webform->getHandlers();
+ $handlers = $submission->getWebform()->getHandlers();
foreach ($handlers as $handler) {
if (!($handler instanceof MaestroNotificationHandler) || $handler->isDisabled() || $handler->isExcluded()) {
continue;
}
- $settings = $handler->getSettings();
- $notificationSetting = $settings[MaestroNotificationHandler::NOTIFICATION];
- $recipientElement = $notificationSetting[MaestroNotificationHandler::RECIPIENT_ELEMENT] ?? NULL;
- $recipient =
- // Handle os2forms_person_lookup element.
- $data[$recipientElement]['cpr_number']
- // Simple element.
- ?? $data[$recipientElement]
- ?? NULL;
- if (NULL !== $recipient) {
- // Lifted from MaestroEngine.
- $maestroTokenData = [
- 'maestro' => [
- 'task' => $templateTask,
- 'queueID' => $maestroQueueID,
- ],
- ];
-
- $subject = $this->tokenManager->replace(
- $notificationSetting[MaestroNotificationHandler::NOTIFICATION_SUBJECT],
- $submission,
- $maestroTokenData
- );
-
- $content = $notificationSetting[MaestroNotificationHandler::NOTIFICATION_CONTENT];
- if (isset($content['value'])) {
- // Process tokens in content.
- $content['value'] = $this->tokenManager->replace(
- $content['value'],
- $submission,
- $maestroTokenData
- );
- }
-
- $taskUrl = TaskHandler::getHandlerURL($maestroQueueID);
- $actionLabel = $notificationSetting[MaestroNotificationHandler::NOTIFICATION_ACTION_LABEL];
- if (filter_var($recipient, FILTER_VALIDATE_EMAIL)) {
- $this->sendNotificationEmail($recipient, $subject, $content, $taskUrl, $actionLabel, $submission);
- }
- else {
- $this->sendNotificationDigitalPost($recipient, $subject, $content, $taskUrl, $actionLabel, $submission);
- }
+ [
+ $content,
+ $contentType,
+ $recipient,
+ $subject,
+ $taskUrl,
+ $actionLabel,
+ ] = $this->renderNotification($submission, $handler->getHandlerId(), $templateTask, $maestroQueueID);
+
+ if ('email' === $contentType) {
+ $this->sendNotificationEmail($recipient, $subject, $content, $submission);
+ }
+ else {
+ $this->sendNotificationDigitalPost($recipient, $subject, $content, $taskUrl, $actionLabel, $submission);
}
}
}
@@ -297,13 +268,9 @@ private function loadQueue(): QueueInterface {
private function sendNotificationEmail(
string $recipient,
string $subject,
- array $content,
- string $taskUrl,
- string $actionLabel,
+ string $body,
WebformSubmissionInterface $submission
): void {
- $body = $this->buildHtml('os2forms_forloeb_notification_message_email_html', $subject, $content, $taskUrl, $actionLabel, $submission);
-
$message = [
'subject' => $subject,
'body' => $body,
@@ -338,26 +305,18 @@ private function sendNotificationEmail(
private function sendNotificationDigitalPost(
string $recipient,
string $subject,
- array $content,
+ string $content,
string $taskUrl,
string $actionLabel,
WebformSubmissionInterface $submission
- ): void
- {
+ ): void {
if (!$this->moduleHandler->moduleExists('os2forms_digital_post')) {
throw new RuntimeException('Cannot send digital post. Module os2forms_digital_post not installed.');
}
try {
- $pdfBody = $this->buildHtml('os2forms_forloeb_notification_message_pdf_html', $subject, $content, $taskUrl,
- $actionLabel, $submission);
- $dompdf = new Dompdf();
- $dompdf->loadHtml($pdfBody);
- $dompdf->render();
- $pdfContent = $dompdf->output();
-
$document = new Document(
- $pdfContent,
+ $content,
Document::MIME_TYPE_PDF,
$subject . '.pdf'
);
@@ -371,8 +330,8 @@ private function sendNotificationDigitalPost(
->setActionCode(SF1601::ACTION_SELVBETJENING)
->setEntryPoint((new EntryPoint())
->setUrl($taskUrl)
- )
- ->setLabel($actionLabel)
+ )
+ ->setLabel($actionLabel),
];
$message = $this->digitalPostHelper->getMeMoHelper()->buildMessage($recipientLookupResult, $senderLabel,
@@ -391,7 +350,8 @@ private function sendNotificationDigitalPost(
'handler_id' => 'os2forms_forloeb',
'operation' => 'notification sent',
]);
- } catch (\Exception $exception) {
+ }
+ catch (\Exception $exception) {
$this->error('Error sending digital post: @message', [
'@message' => $exception->getMessage(),
'webform_submission' => $submission,
@@ -401,11 +361,128 @@ private function sendNotificationDigitalPost(
}
}
+ /**
+ * Render notification.
+ *
+ * @param \Drupal\webform\WebformSubmissionInterface $submission
+ * The submission.
+ * @param string $handlerId
+ * The handler ID.
+ * @param array $templateTask
+ * The Maestro template task.
+ * @param int $maestroQueueID
+ * The Maestro queue ID.
+ * @param string|null $contentType
+ * Optional content type. If not set the content type will be compoted based
+ * 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)
+ */
+ public function renderNotification(WebformSubmissionInterface $submission, string $handlerId, array $templateTask, int $maestroQueueID, string $contentType = NULL): array {
+ $handler = $submission->getWebform()->getHandler($handlerId);
+ $settings = $handler->getSettings();
+ $notificationSetting = $settings[MaestroNotificationHandler::NOTIFICATION];
+
+ $data = $submission->getData();
+ $recipientElement = $notificationSetting[MaestroNotificationHandler::RECIPIENT_ELEMENT] ?? NULL;
+ // Handle os2forms_person_lookup element.
+ $recipient = $data[$recipientElement]['cpr_number']
+ // Simple element.
+ ?? $data[$recipientElement]
+ ?? NULL;
+
+ if (NULL !== $recipient) {
+ // Lifted from MaestroEngine.
+ $maestroTokenData = [
+ 'maestro' => [
+ 'task' => $templateTask,
+ 'queueID' => $maestroQueueID,
+ ],
+ ];
+
+ $processValue = static fn (string $value) => $value;
+
+ // Handle a preview, i.e. not a real Maestro context.
+ if (empty($templateTask) || 0 === $maestroQueueID) {
+ $taskUrl = Url::fromRoute('os2forms_forloeb.meastro_notification.preview_message', ['message' => 'This is just a preview'])->toString(TRUE)->getGeneratedUrl();
+
+ $processValue = static function (string $value) use ($taskUrl) {
+ // Replace href="[maestro:task-url]" with href="«$taskUrl»".
+ $value = preg_replace('/href\s*=\s*["\']\[maestro:task-url\]["\']/', sprintf('href="%s"', htmlspecialchars($taskUrl)), $value);
+ $value = preg_replace('/\[(maestro:[^]]+)\]/', '[\1]', $value);
+
+ return $value;
+ };
+ }
+ else {
+ $taskUrl = TaskHandler::getHandlerURL($maestroQueueID);
+ }
+
+ $subject = $this->tokenManager->replace(
+ $processValue($notificationSetting[MaestroNotificationHandler::NOTIFICATION_SUBJECT]),
+ $submission,
+ $maestroTokenData
+ );
+
+ $content = $notificationSetting[MaestroNotificationHandler::NOTIFICATION_CONTENT];
+ if (isset($content['value'])) {
+ // Process tokens in content.
+ $content['value'] = $this->tokenManager->replace(
+ $processValue($content['value']),
+ $submission,
+ $maestroTokenData
+ );
+ }
+
+ $actionLabel = $this->tokenManager->replace($notificationSetting[MaestroNotificationHandler::NOTIFICATION_ACTION_LABEL], $submission);
+
+ if (NULL === $contentType) {
+ $contentType = filter_var($recipient, FILTER_VALIDATE_EMAIL) ? 'email' : 'pdf';
+ }
+
+ switch ($contentType) {
+ case 'email':
+ $content = $this->buildHtml($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();
+
+ $content = $dompdf->output();
+ break;
+
+ default:
+ throw new RuntimeException(sprintf('Invalid content type: %s', $contentType));
+ }
+
+ return [
+ $content,
+ $contentType,
+ $recipient,
+ $subject,
+ $taskUrl,
+ $actionLabel,
+ ];
+ }
+
+ throw new RuntimeException();
+ }
+
/**
* Build HTML.
*/
private function buildHtml(
- string $theme,
+ string $type,
string $subject,
array $content,
string $taskUrl,
@@ -413,6 +490,8 @@ private function buildHtml(
WebformSubmissionInterface $submission
): string|MarkupInterface {
// Render body as HTML.
+ $theme = sprintf('os2forms_forloeb_notification_message_%s_html', $type);
+
$build = [
'#theme' => $theme,
'#message' => [
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 37dfb8f9..445b164f 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
@@ -3,6 +3,7 @@
namespace Drupal\os2forms_forloeb\Plugin\WebformHandler;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Link;
use Drupal\webform\Plugin\WebformHandlerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -63,9 +64,25 @@ public static function create(ContainerInterface $container, array $configuratio
*/
public function getSummary() {
return [
- '#markup' => $this->t('Sends notification when triggered by Maestro. The notification will be sent to the person identified by the value of the %element element.', [
- '%element' => $this->configuration[self::NOTIFICATION][self::RECIPIENT_ELEMENT] ?? NULL,
- ]),
+ 'info' => [
+ '#prefix' => '',
+ '#suffix' => '
',
+ '#markup' => $this->t('Sends notification when triggered by Maestro. The notification will be sent to the person identified by the value of the %element element.', [
+ '%element' => $this->configuration[self::NOTIFICATION][self::RECIPIENT_ELEMENT] ?? NULL,
+ ]),
+ ],
+ 'preview' => [
+ '#prefix' => '',
+ '#suffix' => '
',
+ ]
+ + Link::createFromRoute(
+ $this->t('Preview notifications'),
+ 'os2forms_forloeb.meastro_notification.preview', [
+ 'webform' => $this->getWebform()->id(),
+ 'handler' => $this->getHandlerId(),
+ 'content_type' => 'email',
+ ]
+ )->toRenderable(),
];
}
diff --git a/web/sites/default/modules/os2forms_forloeb/templates/os2forms-forloeb-notification-preview.html.twig b/web/sites/default/modules/os2forms_forloeb/templates/os2forms-forloeb-notification-preview.html.twig
new file mode 100644
index 00000000..7871a016
--- /dev/null
+++ b/web/sites/default/modules/os2forms_forloeb/templates/os2forms-forloeb-notification-preview.html.twig
@@ -0,0 +1,56 @@
+{#
+ /**
+ * @file
+ * Template for Maestro notification preview.
+ *
+ * Available variables:
+ * - preview_urls: The preview URLs
+ * - prev: Previous submission preview URL (if any)
+ * - self: The current preview URL (if any)
+ * - next: Next submission preview URL (if any)
+ * - webform: The webform
+ * - handler: The handler ID
+ * - content_type: The content type (email, pdf)
+ * - submission: The submission ID
+ * - return_url: The return URL (to list of webform handlers)
+ * - render_url: The render URL to render the actual preview
+ */
+ #}
+