diff --git a/CHANGELOG.md b/CHANGELOG.md index f5613cf4..253f9bf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ before starting to add changes. Use example [placed in the end of the page](#exa ## [Unreleased] +- [PR-301](https://github.com/OS2Forms/os2forms/pull/301) + Add address information to Digital Post shipments to ensure "*fjernprint*" + can be sent. +- Add option to add return address to Digital Post shipments. +- [PR-315](https://github.com/OS2Forms/os2forms/pull/315) + Added “Display on“ options to Map element - [PR-317](https://github.com/OS2Forms/os2forms/pull/317) Updated code analysis script. - [PR-306](https://github.com/OS2Forms/os2forms/pull/306) diff --git a/modules/os2forms_digital_post/README.md b/modules/os2forms_digital_post/README.md index 999d87c7..471bd6e6 100644 --- a/modules/os2forms_digital_post/README.md +++ b/modules/os2forms_digital_post/README.md @@ -80,3 +80,182 @@ of recipients: ``` shell drush os2forms-digital-post:test:send --help ``` + +## Fjernprint (physical digital post) + +To comply with the address placement in the envelope window (kuvert-rude) an +[event subscriber](src/EventSubscriber/Os2formsDigitalPostSubscriber.php) is +used to inject an address information element into the generated HTML before it is +converted to a PDF. + +We are only guaranteed to have the necessary information when in a digital +post context. For that reason, the injection of address information is only +done when in a digital post context. Note also that the information is only +injected – it is not styled. This allows flexibility across installations but +also means that it is up to individual installations to style it correctly. +This should be done in OS2Forms Attachment-templates, see +[Overwriting templates](https://github.com/OS2Forms/os2forms/tree/develop/modules/os2forms_attachment#overwriting-templates). + +Furthermore, a single-line sender address may be configured on the handler. +The value of this field will be injected into the HTML as a sender address, +which should be placed within the envelope window just above the recipient +address. As with the recipient information, it is up to individual +installations to style it correctly. + +To see the exact requirements for address and sender placement, see +[digst_a4_farve_ej_til_kant_demo_ny_rudeplacering.pdf](docs/digst_a4_farve_ej_til_kant_demo_ny_rudeplacering.pdf). + +### The injected HTML + +Variations of the injected HTML include extended addresses, c/o and sender +address. + +Without extended address information, c/o or sender address: + +```html +
+
+
Jeppe
+
Test vej HouseNr
+
2100 Copenhagen
+
+
+``` + +With just an extended address: + +```html +
+
+
Jeppe
+
Test vej HouseNr Floor AppartmentNr
+
2100 Copenhagen
+
+
+``` + +With just c/o: + +```html +
+
+
Jeppe
+
c/o Mikkel
Test vej HouseNr
+
2100 Copenhagen
+
+
+``` + +With just the sender address: + +```html +
+
Dokk1, Hack Kampmanns Plads 2, 8000 Aarhus C
+
+
Jeppe
+
Test vej HouseNr
+
2100 Copenhagen
+
+
+``` + + +With extended address information, c/o and sender address: + +```html +
+
Dokk1, Hack Kampmanns Plads 2, 8000 Aarhus C
+
+
Jeppe
+
c/o Mikkel
+
Test vej HouseNr Floor AppartmentNr
+
2100 Copenhagen
+
+
+``` + +### Styling of the HTML + +The following [SCSS](https://sass-lang.com/) can be used to style the injected HTML accordingly: + +```scss +$margin-top: 25mm; +// There is no exact measurement for margin right in the specifications +$margin-right: 10mm; +$margin-bottom: 20mm; +$margin-left: 17mm; +$page-width: 210mm; +$page-height: 297mm; +$envelope-window-height: 89mm; +$envelope-window-width: 115mm; +$recipient-window-height: 21mm; +$recipient-window-width: 59mm; + +@page { + size: A4; + margin: 0; +} + +body { + margin-top: $margin-top; + margin-right: $margin-right; + margin-bottom: $margin-bottom; + margin-left: $margin-left; +} + +header { + position: fixed; + top: 0; + height: $margin-top; + width: calc($page-width - $margin-left - $margin-right); + font-size: 12px; +} + +footer { + position: fixed; + bottom: 0; + height: $margin-bottom; + width: calc($page-width - $margin-left - $margin-right); + font-size: 12px; +} + +// Style the envelope window that may be injected by Digital Post. +// Note that top/left is made from the assumption that @page has margin 0. +// @see \Drupal\os2forms_digital_post\EventSubscriber\Os2formsDigitalPostSubscriber:onPrintRender +#envelope-window-digital-post { + position: absolute; + top: $margin-top; + left: $margin-left; + height: $envelope-window-height; + width: $envelope-window-width; + background: white +} + +// If envelope window is present, move webform content down +// @see os2forms_digital_post +#envelope-window-digital-post ~ * .webform-entity-print-body { + margin-top: $envelope-window-height; +} + +// Style the h-card div +#envelope-window-digital-post > .h-card { + position: absolute; + top: 16mm; + left: 4mm; + font-size: 10px; + height: $recipient-window-height; + width: $recipient-window-width; +} + +// Style the sender address div +#envelope-window-digital-post > #sender-address-digital-post { + position: absolute; + top: 12mm; + left: 4mm; + font-size: 8px; + height: 4mm; + width: 71mm; +} + +// More custom styling... +``` diff --git a/modules/os2forms_digital_post/docs/digst_a4_farve_ej_til_kant_demo_ny_rudeplacering.pdf b/modules/os2forms_digital_post/docs/digst_a4_farve_ej_til_kant_demo_ny_rudeplacering.pdf new file mode 100644 index 00000000..9f381c7a Binary files /dev/null and b/modules/os2forms_digital_post/docs/digst_a4_farve_ej_til_kant_demo_ny_rudeplacering.pdf differ diff --git a/modules/os2forms_digital_post/os2forms_digital_post.services.yml b/modules/os2forms_digital_post/os2forms_digital_post.services.yml index 745b88d2..aefb2d97 100644 --- a/modules/os2forms_digital_post/os2forms_digital_post.services.yml +++ b/modules/os2forms_digital_post/os2forms_digital_post.services.yml @@ -21,12 +21,14 @@ services: - "@Drupal\\os2forms_digital_post\\Helper\\Settings" - "@plugin.manager.element_info" - "@webform.token_manager" + - "@Drupal\\os2forms_digital_post\\EventSubscriber\\Os2formsDigitalPostSubscriber" Drupal\os2forms_digital_post\Helper\ForsendelseHelper: arguments: - "@Drupal\\os2forms_digital_post\\Helper\\Settings" - "@plugin.manager.element_info" - "@webform.token_manager" + - "@Drupal\\os2forms_digital_post\\EventSubscriber\\Os2formsDigitalPostSubscriber" Drupal\os2forms_digital_post\Helper\DigitalPostHelper: arguments: @@ -69,3 +71,9 @@ services: - '@database' - '@Drupal\os2forms_digital_post\Helper\MeMoHelper' - '@logger.channel.os2forms_digital_post' + + Drupal\os2forms_digital_post\EventSubscriber\Os2formsDigitalPostSubscriber: + arguments: + - '@session' + tags: + - { name: 'event_subscriber' } diff --git a/modules/os2forms_digital_post/src/EventSubscriber/Os2formsDigitalPostSubscriber.php b/modules/os2forms_digital_post/src/EventSubscriber/Os2formsDigitalPostSubscriber.php new file mode 100644 index 00000000..e4b686bb --- /dev/null +++ b/modules/os2forms_digital_post/src/EventSubscriber/Os2formsDigitalPostSubscriber.php @@ -0,0 +1,143 @@ +getHtml(); + + // Only modify HTML if there is exactly one submission. + if (count($event->getEntities()) === 1) { + $submission = $event->getEntities()[0]; + if ($submission instanceof WebformSubmissionInterface) { + // Check whether generation is for digital post. + if ($context = $this->getDigitalPostContext($submission)) { + $lookupResult = $context['lookupResult'] ?? NULL; + if (!$lookupResult instanceof CprLookupResult && !$lookupResult instanceof CompanyLookupResult) { + return; + } + + $senderAddress = $context['senderAddress'] ?? ''; + if (!is_string($senderAddress)) { + $senderAddress = ''; + } + + // Combine address parts. + $streetAddress = $lookupResult->getStreet(); + + if ($lookupResult->getHouseNr()) { + $streetAddress .= ' ' . $lookupResult->getHouseNr(); + } + + $extendedAddress = ''; + + if ($lookupResult->getFloor()) { + // Add a comma to align with danish address specifications. + $streetAddress .= ','; + $extendedAddress = $lookupResult->getFloor(); + } + if ($lookupResult->getApartmentNr()) { + $extendedAddress .= ' ' . $lookupResult->getApartmentNr(); + } + + // Generate address HTML. + $addressHtml = '
'; + if (!empty($senderAddress)) { + $addressHtml .= '
' . htmlspecialchars($senderAddress) . '
'; + } + $addressHtml .= '
'; + $addressHtml .= '
' . htmlspecialchars($lookupResult->getName()) . '
'; + if ($lookupResult instanceof CprLookupResult && $lookupResult->getCoName()) { + $addressHtml .= '
c/o ' . htmlspecialchars($lookupResult->getCoName()) . '
'; + } + $addressHtml .= '
'; + $addressHtml .= '' . htmlspecialchars($streetAddress) . ''; + if (!empty($extendedAddress)) { + $addressHtml .= ' ' . htmlspecialchars($extendedAddress) . ''; + } + $addressHtml .= '
'; + $addressHtml .= '
'; + $addressHtml .= '' . htmlspecialchars($lookupResult->getPostalCode()) . ''; + $addressHtml .= ' ' . htmlspecialchars($lookupResult->getCity()) . ''; + $addressHtml .= '
'; + $addressHtml .= '
'; + $addressHtml .= '
'; + + // Insert address HTML immediately after body opening tag. + $html = preg_replace('@]*>@', '${0}' . $addressHtml, $html); + } + } + } + + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents(): array { + return [ + PrintEvents::POST_RENDER => ['onPrintRender'], + ]; + } + + /** + * Indicate Digital Post context in the current session. + */ + public function setDigitalPostContext(WebformSubmissionInterface $submission, CompanyLookupResult|CprLookupResult $lookupResult, string $senderAddress = ''): void { + $key = $this->createSessionKeyFromSubmission($submission); + $this->session->set($key, [ + 'lookupResult' => $lookupResult, + 'senderAddress' => $senderAddress, + ]); + } + + /** + * Check for Digital Post context in the current session. + */ + public function getDigitalPostContext(WebformSubmissionInterface $submission): ?array { + $key = $this->createSessionKeyFromSubmission($submission); + + return $this->session->get($key); + } + + /** + * Delete Digital Post context from the current request. + */ + public function deleteDigitalPostContext(WebformSubmissionInterface $submission): bool { + $key = $this->createSessionKeyFromSubmission($submission); + + return (bool) $this->session->remove($key); + } + + /** + * Create a session key from a submission that is unique to the submission. + */ + public function createSessionKeyFromSubmission(WebformSubmissionInterface $submission): string { + // Due to cloning of submission during attachment logic, we cannot use + // submission id or uuid. Webform serial, however, is copied along, so a + // combination of webform id and serial is used for uniqueness. + // @see \Drupal\os2forms_attachment\Element\AttachmentElement::overrideWebformSettings + return 'digital_post_context_' . $submission->getWebform()->id() . '_' . $submission->serial(); + } + +} diff --git a/modules/os2forms_digital_post/src/Helper/AbstractMessageHelper.php b/modules/os2forms_digital_post/src/Helper/AbstractMessageHelper.php index c2f2b990..368ac1ac 100644 --- a/modules/os2forms_digital_post/src/Helper/AbstractMessageHelper.php +++ b/modules/os2forms_digital_post/src/Helper/AbstractMessageHelper.php @@ -4,9 +4,12 @@ use DigitalPost\MeMo\Message; use Drupal\Core\Render\ElementInfoManager; +use Drupal\os2forms_digital_post\EventSubscriber\Os2formsDigitalPostSubscriber; use Drupal\os2forms_digital_post\Exception\InvalidAttachmentElementException; use Drupal\os2forms_digital_post\Model\Document; use Drupal\os2forms_digital_post\Plugin\WebformHandler\WebformHandlerSF1601; +use Drupal\os2web_datalookup\LookupResult\CompanyLookupResult; +use Drupal\os2web_datalookup\LookupResult\CprLookupResult; use Drupal\webform\WebformSubmissionInterface; use Drupal\webform\WebformTokenManagerInterface; use Drupal\webform_attachment\Element\WebformAttachmentBase; @@ -28,6 +31,7 @@ public function __construct( readonly protected ElementInfoManager $elementInfoManager, #[Autowire(service: 'webform.token_manager')] readonly protected WebformTokenManagerInterface $webformTokenManager, + readonly protected Os2formsDigitalPostSubscriber $digitalPostSubscriber, ) { } @@ -38,7 +42,7 @@ public function __construct( * * @phpstan-param array $handlerSettings */ - protected function getMainDocument(WebformSubmissionInterface $submission, array $handlerSettings): Document { + protected function getMainDocument(WebformSubmissionInterface $submission, array $handlerSettings, CprLookupResult|CompanyLookupResult $recipientData): Document { // Lifted from Drupal\webform_attachment\Controller\WebformAttachmentController::download. $element = $handlerSettings[WebformHandlerSF1601::MEMO_MESSAGE][WebformHandlerSF1601::ATTACHMENT_ELEMENT]; $element = $submission->getWebform()->getElement($element) ?: []; @@ -51,7 +55,16 @@ protected function getMainDocument(WebformSubmissionInterface $submission, array $fileName = $instance::getFileName($element, $submission); $mimeType = $instance::getFileMimeType($element, $submission); + + // The way to alter html generated from entities is through the + // PrintEvents::POST_RENDER event. See: + // @Drupal\entity_print\Renderer::generateHtml, + // To indicate digital post context and get the necessary information, + // we add a flag to the session. + $senderAddress = $handlerSettings[WebformHandlerSF1601::MEMO_MESSAGE][WebformHandlerSF1601::SENDER_ADDRESS] ?? ''; + $this->digitalPostSubscriber->setDigitalPostContext($submission, $recipientData, $senderAddress); $content = $instance::getFileContent($element, $submission); + $this->digitalPostSubscriber->deleteDigitalPostContext($submission); return new Document( $content, diff --git a/modules/os2forms_digital_post/src/Helper/ForsendelseHelper.php b/modules/os2forms_digital_post/src/Helper/ForsendelseHelper.php index 42cbbea1..6254b63a 100644 --- a/modules/os2forms_digital_post/src/Helper/ForsendelseHelper.php +++ b/modules/os2forms_digital_post/src/Helper/ForsendelseHelper.php @@ -61,7 +61,7 @@ public function buildForsendelse(CprLookupResult|CompanyLookupResult $recipientD */ public function buildSubmissionForsendelse(WebformSubmissionInterface $submission, array $options, array $handlerSettings, CprLookupResult|CompanyLookupResult $recipientData): ForsendelseI { $label = $this->replaceTokens($options[WebformHandlerSF1601::MESSAGE_HEADER_LABEL], $submission); - $document = $this->getMainDocument($submission, $handlerSettings); + $document = $this->getMainDocument($submission, $handlerSettings, $recipientData); return $this->buildForsendelse($recipientData, $label, $document); } diff --git a/modules/os2forms_digital_post/src/Helper/MeMoHelper.php b/modules/os2forms_digital_post/src/Helper/MeMoHelper.php index f32c567d..b3b66749 100644 --- a/modules/os2forms_digital_post/src/Helper/MeMoHelper.php +++ b/modules/os2forms_digital_post/src/Helper/MeMoHelper.php @@ -97,10 +97,11 @@ public function buildMessage(CprLookupResult|CompanyLookupResult $recipientData, * @phpstan-param array $options * @phpstan-param array $handlerSettings */ - public function buildWebformSubmissionMessage(WebformSubmissionInterface $submission, array $options, array $handlerSettings, CprLookupResult|CompanyLookupResult|null $recipientData = NULL): Message { + public function buildWebformSubmissionMessage(WebformSubmissionInterface $submission, array $options, array $handlerSettings, CprLookupResult|CompanyLookupResult $recipientData): Message { $senderLabel = $this->replaceTokens($options[WebformHandlerSF1601::SENDER_LABEL], $submission); $messageLabel = $this->replaceTokens($options[WebformHandlerSF1601::MESSAGE_HEADER_LABEL], $submission); - $document = $this->getMainDocument($submission, $handlerSettings); + $document = $this->getMainDocument($submission, $handlerSettings, $recipientData); + $actions = []; if (isset($handlerSettings[WebformHandlerSF1601::MEMO_ACTIONS]['actions'])) { foreach ($handlerSettings[WebformHandlerSF1601::MEMO_ACTIONS]['actions'] as $spec) { diff --git a/modules/os2forms_digital_post/src/Helper/WebformHelperSF1601.php b/modules/os2forms_digital_post/src/Helper/WebformHelperSF1601.php index 60fae6a2..3d079fe1 100644 --- a/modules/os2forms_digital_post/src/Helper/WebformHelperSF1601.php +++ b/modules/os2forms_digital_post/src/Helper/WebformHelperSF1601.php @@ -163,7 +163,9 @@ public function sendDigitalPost(WebformSubmissionInterface $submission, array $h WebformHandlerSF1601::SENDER_LABEL => $handlerMessageSettings[WebformHandlerSF1601::SENDER_LABEL], WebformHandlerSF1601::MESSAGE_HEADER_LABEL => $handlerMessageSettings[WebformHandlerSF1601::MESSAGE_HEADER_LABEL], ]; + $message = $this->meMoHelper->buildWebformSubmissionMessage($submission, $messageOptions, $handlerSettings, $lookupResult); + $forsendelseOptions = [ self::RECIPIENT_IDENTIFIER_TYPE => $recipientIdentifierType, self::RECIPIENT_IDENTIFIER => $recipientIdentifier, @@ -175,6 +177,7 @@ public function sendDigitalPost(WebformSubmissionInterface $submission, array $h WebformHandlerSF1601::SENDER_LABEL => $handlerMessageSettings[WebformHandlerSF1601::SENDER_LABEL], WebformHandlerSF1601::MESSAGE_HEADER_LABEL => $handlerMessageSettings[WebformHandlerSF1601::MESSAGE_HEADER_LABEL], ]; + $forsendelse = $this->forsendelseHelper->buildSubmissionForsendelse($submission, $forsendelseOptions, $handlerSettings, $lookupResult); $type = $handlerMessageSettings[WebformHandlerSF1601::TYPE] ?? SF1601::TYPE_DIGITAL_POST; diff --git a/modules/os2forms_digital_post/src/Plugin/WebformHandler/WebformHandlerSF1601.php b/modules/os2forms_digital_post/src/Plugin/WebformHandler/WebformHandlerSF1601.php index 0b1dc219..6f0e06a9 100644 --- a/modules/os2forms_digital_post/src/Plugin/WebformHandler/WebformHandlerSF1601.php +++ b/modules/os2forms_digital_post/src/Plugin/WebformHandler/WebformHandlerSF1601.php @@ -31,12 +31,18 @@ final class WebformHandlerSF1601 extends WebformHandlerBase { public const MESSAGE_HEADER_LABEL = 'message_header_label'; public const RECIPIENT_ELEMENT = 'recipient_element'; public const ATTACHMENT_ELEMENT = 'attachment_element'; + public const SENDER_ADDRESS = 'sender_address'; /** * Maximum length of sender label. */ private const SENDER_LABEL_MAX_LENGTH = 64; + /** + * Maximum length of sender address. + */ + private const SENDER_ADDRESS_MAX_LENGTH = 70; + /** * Maximum length of header label. */ @@ -131,6 +137,15 @@ public function buildConfigurationForm(array $form, FormStateInterface $formStat '#maxlength' => self::MESSAGE_HEADER_LABEL_MAX_LENGTH, ]; + $form[self::MEMO_MESSAGE][self::SENDER_ADDRESS] = [ + '#type' => 'textfield', + '#title' => $this->t('Sender address'), + '#description' => $this->t('Optional sender address shown on the printed document. Displayed as a single line above the recipient name. Maximum @max characters.', ['@max' => self::SENDER_ADDRESS_MAX_LENGTH]), + '#required' => FALSE, + '#default_value' => $this->configuration[self::MEMO_MESSAGE][self::SENDER_ADDRESS] ?? NULL, + '#maxlength' => self::SENDER_ADDRESS_MAX_LENGTH, + ]; + $form[self::MEMO_ACTIONS] = [ '#type' => 'fieldset', '#title' => $this->t('Actions'), diff --git a/modules/os2forms_webform_maps/README.md b/modules/os2forms_webform_maps/README.md index c36b901e..d93aa5d4 100644 --- a/modules/os2forms_webform_maps/README.md +++ b/modules/os2forms_webform_maps/README.md @@ -14,3 +14,58 @@ the map. The data can be exported to PDF. ## Installation The module can be installed using the standard Drupal installation procedure. + +## Fetching GeoJSON using the API + +Assume that we have a webform with ID `my_webform` and the webform has a Map element with ID `my_map`. We can then fetch +the data for a submission with UUID `c34d01c5-7bd9-4b15-8b01-5787959453c0` on the webform with a HTTP `GET` request (cf. +[OS2Forms REST API](https://github.com/OS2Forms/os2forms_rest_api/blob/main/README.md)): + +``` shell name=api-fetch-submission-data +curl --silent --location --header 'api-key: my-api-key' http://127.0.0.1:8000/webform_rest/my_webform/submission/c34d01c5-7bd9-4b15-8b01-5787959453c0 +# {"entity":{"serial":[{"value":1}],"sid":[{"value":2}],"uuid":[{"value":"c34d01c5-7bd9-4b15-8b01-5787959453c0"}],…``` +``` + +The result, however, contains a lot of data and we need a little more work the extract just the GeoJSON data. + +Using [`jq`](https://jqlang.org/) (or similar tools), we can drill down into the full submission data to extract just +the GeoJSON data from the Map element (JSON decoding twice along the way): + +``` shell name=api-extract-map-element-data +curl --silent --location --header 'api-key: my-api-key' http://127.0.0.1:8000/webform_rest/my_webform/submission/c34d01c5-7bd9-4b15-8b01-5787959453c0 | jq '.data.my_map | fromjson | .geojson | fromjson' +``` + +The final result will be something like + +``` json +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 10.193674, + 56.158929 + ], + [ + 10.241758, + 56.155296 + ], + [ + 10.242788, + 56.130048 + ], + [ + 10.189209, + 56.129283 + ] + ] + } + } + ] +} +``` diff --git a/modules/os2forms_webform_maps/os2forms_webform_maps.module b/modules/os2forms_webform_maps/os2forms_webform_maps.module index af545a5d..17d33aab 100644 --- a/modules/os2forms_webform_maps/os2forms_webform_maps.module +++ b/modules/os2forms_webform_maps/os2forms_webform_maps.module @@ -5,22 +5,6 @@ * Module file for os2forms_webform_maps. */ -/** - * Implements hook_theme(). - */ -function os2forms_webform_maps_theme() { - return [ - 'webform_element_base_html__webform_map_field' => [ - 'variables' => [ - 'element' => [], - 'value' => NULL, - 'webform_submission' => NULL, - 'options' => [], - ], - ], - ]; -} - /** * Implements hook_locale_translation_projects_alter(). */ @@ -29,31 +13,3 @@ function os2forms_webform_maps_locale_translation_projects_alter(&$projects) { $path = $module_handler->getModule('os2forms_webform_maps')->getPath(); $projects['os2forms_webform_maps']['info']['interface translation server pattern'] = $path . '/translations/%language.po'; } - -/** - * Implements hook_preprocess_webform_element_base_html__webform_map_field(). - */ -function os2forms_webform_maps_preprocess_webform_element_base_html__webform_map_field(array &$variables) { - // Decode the plain text value once. - $decoded_value = json_decode($variables['value']['#plain_text']); - - // Use the decoded geojson property. - $variables['value']['#plain_text'] = $decoded_value->geojson; - - // Load the webform element base HTML template. - \Drupal::moduleHandler()->loadInclude('webform', 'inc', 'includes/webform.theme.template'); - template_preprocess_webform_element_base_html($variables); - - // Generate a unique ID for the map image. - $map_image_id = 'map-image-' . $variables['element']['#webform_key']; - - $variables['map_image'] = [ - '#type' => 'html_tag', - '#tag' => 'img', - '#attributes' => [ - 'class' => ['handler-help-message'], - 'id' => [$map_image_id], - 'src' => $decoded_value->image ?? '', - ], - ]; -} diff --git a/modules/os2forms_webform_maps/src/Plugin/WebformElement/WebformLeafletMapField.php b/modules/os2forms_webform_maps/src/Plugin/WebformElement/WebformLeafletMapField.php index 3b6aa405..00327dcf 100644 --- a/modules/os2forms_webform_maps/src/Plugin/WebformElement/WebformLeafletMapField.php +++ b/modules/os2forms_webform_maps/src/Plugin/WebformElement/WebformLeafletMapField.php @@ -5,6 +5,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\leaflet\LeafletSettingsElementsTrait; use Drupal\webform\Plugin\WebformElementBase; +use Drupal\webform\WebformSubmissionInterface; /** * Provides a 'webform_map_field' element. @@ -70,6 +71,9 @@ public function defineDefaultProperties(): array { 'circle_color' => '#3388FF', 'rectangle_color' => '#3388FF', + // Display settings. + 'display_image_on' => ['email', 'html', 'pdf'], + 'display_geojson_on' => ['text', 'html'], ] + parent::defineDefaultProperties(); } @@ -344,7 +348,120 @@ public function form(array $form, FormStateInterface $form_state) { ], ]; + $form['display_settings'] = [ + '#type' => 'fieldset', + '#title' => $this->t('Display settings'), + ]; + $form['display_settings']['display_settings_container'] = [ + 'display_image_on' => [ + '#type' => 'checkboxes', + '#title' => $this->t('Display image on'), + '#options' => [ + 'email' => $this->t('Email'), + 'html' => $this->t('HTML'), + 'pdf' => $this->t('PDF'), + ], + ], + + 'display_geojson_on' => [ + '#type' => 'checkboxes', + '#title' => $this->t('Display GeoJSON on'), + '#options' => [ + 'email' => $this->t('Email'), + 'html' => $this->t('HTML'), + 'pdf' => $this->t('PDF'), + 'text' => $this->t('Text'), + ], + ], + ]; + return $form; } + /** + * {@inheritdoc} + */ + protected function formatHtmlItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []): array { + $value = $this->getMapValue($element, $webform_submission, $options); + + $imageId = 'map-image-' . $this->getKey($element); + + $build = []; + + $viewMode = $options['view_mode'] ?? 'results'; + if ('table' === $viewMode) { + $viewMode = 'html'; + } + elseif ($options['email'] ?? FALSE) { + $viewMode = 'email'; + } + elseif ($options['pdf'] ?? FALSE) { + $viewMode = 'pdf'; + } + + // @todo Is this (i.e. $element['#display_image_on']) really the way to get element configuration? + $showImageOn = array_filter((array) ($element['#display_image_on'] ?? NULL)); + $includeImage = isset($showImageOn[$viewMode]); + + $showGeoJsonOn = array_filter((array) ($element['#display_geojson_on'] ?? NULL)); + $includeGeoJson = isset($showGeoJsonOn[$viewMode]); + + if ($includeImage) { + $build['image'] = [ + '#type' => 'html_tag', + '#tag' => 'img', + '#attributes' => [ + 'class' => ['handler-help-message'], + 'id' => $imageId, + 'src' => $value['image'], + ], + '#prefix' => '
', + '#suffix' => '
', + ]; + } + + if ($includeGeoJson) { + $build['geojson'] = [ + '#markup' => $value['geojson'], + '#prefix' => '
', + '#suffix' => '
', + ]; + } + + return $build; + } + + /** + * {@inheritdoc} + */ + protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) { + $value = $this->getMapValue($element, $webform_submission, $options); + + return $value['geojson']; + } + + /** + * Get structured map value. + * + * @return array{ + * image: string, + * geojson: string + * } + */ + private function getMapValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []): array { + $value = $this->getValue($element, $webform_submission, $options); + + try { + $data = json_decode($value, associative: TRUE, flags: JSON_THROW_ON_ERROR); + } + catch (\JsonException) { + $data = []; + } + + return $data + [ + 'image' => '', + 'geojson' => 'null', + ]; + } + } diff --git a/modules/os2forms_webform_maps/templates/webform-element-base-html--webform-map-field.html.twig b/modules/os2forms_webform_maps/templates/webform-element-base-html--webform-map-field.html.twig deleted file mode 100644 index cd3a19bd..00000000 --- a/modules/os2forms_webform_maps/templates/webform-element-base-html--webform-map-field.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -{# -/** - * @file - * Default theme implementation for a webform base element as html. - * - * Available variables: - * - element: The element. - * - title: The label for the element. - * - value: The content for the element. - * - item: The form item used to display the element. - * - options Associative array of options for element. - * - multiline: Flag to determine if value spans multiple lines. - * - email: Flag to determine if element is for an email. - */ -#} - {{ map_image }} - {{ item }} -