Skip to content

Commit ac45d5b

Browse files
authored
Merge branch 'develop' into hotfix/add-missing-handler-condition
2 parents 34d667f + 28cedf1 commit ac45d5b

File tree

45 files changed

+1996
-383
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1996
-383
lines changed

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,19 @@ before starting to add changes. Use example [placed in the end of the page](#exa
1111

1212
## [Unreleased]
1313

14-
- Added condition to maestro notification submission handler
14+
- [PR-215](https://github.com/OS2Forms/os2forms/pull/215)
15+
Added condition to maestro notification submission handler
16+
- [PR-101](https://github.com/OS2Forms/os2forms/pull/101)
17+
- Added support for `os2web_key` in Digital post
18+
- Switched from saving settings in key value store to config, i.e
19+
the module needs to be reconfigured.
20+
- Added support for `os2web_key` in Fasit handler.
21+
- Switched from saving settings in key value store to config, i.e
22+
the module needs to be reconfigured.
23+
- [PR-179](https://github.com/OS2Forms/os2forms/pull/179)
24+
Remove unused and abandoned package `webmozart/path-util`.
25+
- [PR-167](https://github.com/OS2Forms/os2forms/pull/167)
26+
Adding os2forms_digital_signature module
1527

1628
## [4.1.0] 2025-06-03
1729

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@
5858
"itk-dev/serviceplatformen": "^1.5",
5959
"mglaman/composer-drupal-lenient": "^1.0",
6060
"os2web/os2web_audit": "^1.0",
61-
"os2web/os2web_datalookup": "^2.0",
61+
"os2web/os2web_datalookup": "^3.0",
62+
"os2web/os2web_key": "^1.0",
6263
"os2web/os2web_nemlogin": "^1.0",
6364
"os2web/os2web_simplesaml": "dev-master",
6465
"php-http/guzzle7-adapter": "^1.0",
6566
"phpoffice/phpword": "^0.18.2",
6667
"symfony/options-resolver": "^5.4 || ^6.0",
67-
"webmozart/path-util": "^2.3",
6868
"wsdltophp/packagebase": "^5.0",
6969
"zaporylie/composer-drupal-optimizations": "^1.2"
7070
},
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
services:
22
os2forms_attachment.print_builder:
33
class: Drupal\os2forms_attachment\Os2formsAttachmentPrintBuilder
4-
arguments: ['@entity_print.renderer_factory', '@event_dispatcher', '@string_translation']
4+
arguments: ['@entity_print.renderer_factory', '@event_dispatcher', '@string_translation', '@file_system']

modules/os2forms_attachment/src/Element/AttachmentElement.php

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public function getInfo() {
2020
return parent::getInfo() + [
2121
'#view_mode' => 'html',
2222
'#export_type' => 'pdf',
23+
'#digital_signature' => FALSE,
2324
'#template' => '',
2425
];
2526
}
@@ -28,6 +29,8 @@ public function getInfo() {
2829
* {@inheritdoc}
2930
*/
3031
public static function getFileContent(array $element, WebformSubmissionInterface $webform_submission) {
32+
$submissionUuid = $webform_submission->uuid();
33+
3134
// Override webform settings.
3235
static::overrideWebformSettings($element, $webform_submission);
3336

@@ -51,18 +54,43 @@ public static function getFileContent(array $element, WebformSubmissionInterface
5154
\Drupal::request()->request->set('_webform_submissions_view_mode', $view_mode);
5255

5356
if ($element['#export_type'] === 'pdf') {
54-
// Get scheme.
55-
$scheme = 'temporary';
56-
57-
// Get filename.
58-
$file_name = 'webform-entity-print-attachment--' . $webform_submission->getWebform()->id() . '-' . $webform_submission->id() . '.pdf';
59-
60-
// Save printable document.
61-
$print_engine = $print_engine_manager->createSelectedInstance($element['#export_type']);
62-
$temporary_file_path = $print_builder->savePrintable([$webform_submission], $print_engine, $scheme, $file_name);
63-
if ($temporary_file_path) {
64-
$contents = file_get_contents($temporary_file_path);
65-
\Drupal::service('file_system')->delete($temporary_file_path);
57+
$file_path = NULL;
58+
59+
// If attachment with digital signatur, check if we already have one.
60+
if (isset($element['#digital_signature']) && $element['#digital_signature']) {
61+
// Get scheme.
62+
$scheme = 'private';
63+
64+
// Get filename.
65+
$file_name = 'webform/' . $webform_submission->getWebform()->id() . '/digital_signature/' . $submissionUuid . '.pdf';
66+
$file_path = "$scheme://$file_name";
67+
}
68+
69+
if (!$file_path || !file_exists($file_path)) {
70+
// Get scheme.
71+
$scheme = 'temporary';
72+
// Get filename.
73+
$file_name = 'webform-entity-print-attachment--' . $webform_submission->getWebform()->id() . '-' . $webform_submission->id() . '.pdf';
74+
75+
// Save printable document.
76+
$print_engine = $print_engine_manager->createSelectedInstance($element['#export_type']);
77+
78+
// Adding digital signature.
79+
if (isset($element['#digital_signature']) && $element['#digital_signature']) {
80+
$file_path = $print_builder->savePrintableDigitalSignature([$webform_submission], $print_engine, $scheme, $file_name);
81+
}
82+
else {
83+
$file_path = $print_builder->savePrintable([$webform_submission], $print_engine, $scheme, $file_name);
84+
}
85+
}
86+
87+
if ($file_path) {
88+
$contents = file_get_contents($file_path);
89+
90+
// Deleting temporary file.
91+
if ($scheme == 'temporary') {
92+
\Drupal::service('file_system')->delete($file_path);
93+
}
6694
}
6795
else {
6896
// Log error.

modules/os2forms_attachment/src/Os2formsAttachmentPrintBuilder.php

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,28 @@
33
namespace Drupal\os2forms_attachment;
44

55
use Drupal\Core\Entity\EntityInterface;
6+
use Drupal\Core\File\FileExists;
7+
use Drupal\Core\File\FileSystemInterface;
8+
use Drupal\Core\StringTranslation\TranslationInterface;
9+
use Drupal\entity_print\Event\PreSendPrintEvent;
10+
use Drupal\entity_print\Event\PrintEvents;
611
use Drupal\entity_print\Plugin\PrintEngineInterface;
712
use Drupal\entity_print\PrintBuilder;
13+
use Drupal\entity_print\Renderer\RendererFactoryInterface;
14+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
815

916
/**
1017
* The OS2Forms attachment print builder service.
1118
*/
1219
class Os2formsAttachmentPrintBuilder extends PrintBuilder {
1320

21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function __construct(RendererFactoryInterface $renderer_factory, EventDispatcherInterface $event_dispatcher, TranslationInterface $string_translation, protected readonly FileSystemInterface $file_system) {
25+
parent::__construct($renderer_factory, $event_dispatcher, $string_translation);
26+
}
27+
1428
/**
1529
* {@inheritdoc}
1630
*/
@@ -27,10 +41,56 @@ public function printHtml(EntityInterface $entity, $use_default_css = TRUE, $opt
2741
return $renderer->generateHtml([$entity], $render, $use_default_css, $optimize_css);
2842
}
2943

44+
/**
45+
* Modified version of the original savePrintable() function.
46+
*
47+
* The only difference is modified call to prepareRenderer with digitalPost
48+
* flag TRUE.
49+
*
50+
* @see PrintBuilder::savePrintable()
51+
*
52+
* @return string
53+
* FALSE or the URI to the file. E.g. public://my-file.pdf.
54+
*/
55+
public function savePrintableDigitalSignature(array $entities, PrintEngineInterface $print_engine, $scheme = 'public', $filename = FALSE, $use_default_css = TRUE) {
56+
$renderer = $this->prepareRenderer($entities, $print_engine, $use_default_css, TRUE);
57+
58+
// Allow other modules to alter the generated Print object.
59+
$this->dispatcher->dispatch(new PreSendPrintEvent($print_engine, $entities), PrintEvents::PRE_SEND);
60+
61+
// If we didn't have a URI passed in the generate one.
62+
if (!$filename) {
63+
$filename = $renderer->getFilename($entities) . '.' . $print_engine->getExportType()->getFileExtension();
64+
}
65+
66+
$uri = "$scheme://$filename";
67+
68+
// Save the file.
69+
return $this->file_system->saveData($print_engine->getBlob(), $uri, FileExists::Replace);
70+
}
71+
3072
/**
3173
* {@inheritdoc}
3274
*/
33-
protected function prepareRenderer(array $entities, PrintEngineInterface $print_engine, $use_default_css) {
75+
76+
/**
77+
* Override prepareRenderer() the print engine with the passed entities.
78+
*
79+
* @param array $entities
80+
* An array of entities.
81+
* @param \Drupal\entity_print\Plugin\PrintEngineInterface $print_engine
82+
* The print engine.
83+
* @param bool $use_default_css
84+
* TRUE if we want the default CSS included.
85+
* @param bool $digitalSignature
86+
* If the digital signature message needs to be added.
87+
*
88+
* @return \Drupal\entity_print\Renderer\RendererInterface
89+
* A print renderer.
90+
*
91+
* @see PrintBuilder::prepareRenderer
92+
*/
93+
protected function prepareRenderer(array $entities, PrintEngineInterface $print_engine, $use_default_css, $digitalSignature = FALSE) {
3494
if (empty($entities)) {
3595
throw new \InvalidArgumentException('You must pass at least 1 entity');
3696
}
@@ -50,6 +110,9 @@ protected function prepareRenderer(array $entities, PrintEngineInterface $print_
50110
// structure. That margin is automatically added in PDF and PDF only.
51111
$generatedHtml = (string) $renderer->generateHtml($entities, $render, $use_default_css, TRUE);
52112
$generatedHtml .= "<style>fieldset legend {margin-left: -12px;}</style>";
113+
if ($digitalSignature) {
114+
$generatedHtml .= $this->t('You can validate the signature on this PDF file via validering.nemlog-in.dk.');
115+
}
53116

54117
$print_engine->addPage($generatedHtml);
55118

modules/os2forms_attachment/src/Plugin/WebformElement/AttachmentElement.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ protected function defineDefaultProperties() {
2727
'view_mode' => 'html',
2828
'template' => '',
2929
'export_type' => '',
30+
'digital_signature' => '',
3031
'exclude_empty' => '',
3132
'exclude_empty_checkbox' => '',
3233
'excluded_elements' => '',
@@ -88,6 +89,11 @@ public function form(array $form, FormStateInterface $form_state) {
8889
'html' => $this->t('HTML'),
8990
],
9091
];
92+
$form['attachment']['digital_signature'] = [
93+
'#type' => 'checkbox',
94+
'#title' => $this->t('Digital signature'),
95+
];
96+
9197
// Set #access so that help is always visible.
9298
WebformElementHelper::setPropertyRecursive($form['attachment']['help'], '#access', TRUE);
9399

modules/os2forms_dawa/src/Plugin/os2web/DataLookup/DatafordelerDataLookup.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
namespace Drupal\os2forms_dawa\Plugin\os2web\DataLookup;
44

55
use Drupal\Component\Utility\NestedArray;
6+
use Drupal\Core\File\FileSystem;
67
use Drupal\Core\Form\FormStateInterface;
78
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
9+
use Drupal\key\KeyRepositoryInterface;
810
use Drupal\os2forms_dawa\Entity\DatafordelerMatrikula;
911
use Drupal\os2web_audit\Service\Logger;
1012
use Drupal\os2web_datalookup\Plugin\os2web\DataLookup\DataLookupBase;
@@ -30,20 +32,31 @@ public function __construct(
3032
$plugin_definition,
3133
protected ClientInterface $httpClient,
3234
Logger $auditLogger,
35+
KeyRepositoryInterface $keyRepository,
36+
FileSystem $fileSystem,
3337
) {
34-
parent::__construct($configuration, $plugin_id, $plugin_definition, $auditLogger);
38+
parent::__construct($configuration, $plugin_id, $plugin_definition, $auditLogger, $keyRepository, $fileSystem);
3539
}
3640

3741
/**
3842
* {@inheritdoc}
3943
*/
4044
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
45+
/** @var \Drupal\os2web_audit\Service\Logger $auditLogger */
46+
$auditLogger = $container->get('os2web_audit.logger');
47+
/** @var \Drupal\key\KeyRepositoryInterface $keyRepository */
48+
$keyRepository = $container->get('key.repository');
49+
/** @var \Drupal\Core\File\FileSystem $fileSystem */
50+
$fileSystem = $container->get('file_system');
51+
4152
return new static(
4253
$configuration,
4354
$plugin_id,
4455
$plugin_definition,
4556
$container->get('http_client'),
46-
$container->get('os2web_audit.logger'),
57+
$auditLogger,
58+
$keyRepository,
59+
$fileSystem,
4760
);
4861
}
4962

modules/os2forms_digital_post/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ examples](modules/os2forms_digital_post_examples/README.md).
3131
Go to `/admin/os2forms_digital_post/settings` to set up global settings for
3232
digital post.
3333

34+
### Key
35+
36+
We use [os2web_key](https://github.com/OS2web/os2web_key) to provide the certificate for sending digital post, and the
37+
key must be of type "[Certificate](https://github.com/os2web/os2web_key?tab=readme-ov-file#certificate)".
38+
3439
### Queue
3540

3641
The actual sending of digital post is handled by jobs in an [Advanced

modules/os2forms_digital_post/os2forms_digital_post.info.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ dependencies:
77
- 'beskedfordeler:beskedfordeler'
88
- 'drupal:advancedqueue'
99
- 'os2web_datalookup:os2web_datalookup'
10+
- 'os2web_key:os2web_key'
1011
- 'webform:webform'
1112
- 'webform:webform_submission_log'
1213
- 'os2web:os2web_audit'

modules/os2forms_digital_post/os2forms_digital_post.install

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,12 @@ use Drupal\os2forms_digital_post\Helper\BeskedfordelerHelper;
1717
function os2forms_digital_post_schema() {
1818
return Drupal::service(BeskedfordelerHelper::class)->schema();
1919
}
20+
21+
/**
22+
* Install OS2Web key module.
23+
*/
24+
function os2forms_digital_post_update_9001(): void {
25+
\Drupal::service('module_installer')->install([
26+
'os2web_key',
27+
], TRUE);
28+
}

0 commit comments

Comments
 (0)