Skip to content

Commit e6a339e

Browse files
authored
Merge pull request #240 from OS2Forms/develop
Release 5.0.0
2 parents 123d488 + 1ebcd35 commit e6a339e

File tree

49 files changed

+2051
-392
lines changed

Some content is hidden

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

49 files changed

+2051
-392
lines changed

.github/opgavebeskrivelse.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
name: Opgavebeskrivelse
3+
description: Standard skabelon for definition af opgaver
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
---
8+
9+
# Kort titel, der repræsenterer opgaven, påkrævet
10+
11+
**Opgavebeskrivelse**: {venligst henvis til eventuelle danske ord, der bruges til at definere aktiviteten i omfanget.}
12+
13+
**Møde eller møderække**: {en eventuel henvisning til mødet, hvor opgaven blev aftalt, inklusive dato og tidspunkt.}
14+
15+
**Opdragsgiver**: {henvis til beslutningsorganet, der er enige om opgaven.}
16+
17+
## Overordnet opgavebeskrivelse
18+
19+
{Beskriv konteksten og problemstillingen, fx i fri form med to til tre sætninger eller i form af en illustrativ historie.}
20+
21+
## Kontekst og problem at løse
22+
23+
{Beskriv konteksten og problemstillingen, fx i fri form med to til tre sætninger eller i form af en illustrativ historie.}
24+
25+
## Vigtige milepæle
26+
27+
* {titel på milepæl 1}
28+
* {titel på milepæl 2}
29+
30+
## Aktiviteter eller underopgaver (sub-issues)
31+
32+
* [ ] {titel på opgave 1}
33+
* [ ] {titel på opgave 2}
34+
* [ ] {titel på opgave 3}
35+
36+
## Accept kriterier
37+
38+
{Beskriv med enkle ord, hvornår opgaven betragtes som fuldført, og angiv eventuelle formelle godkendelseskrav.}
39+
40+
## Risici & konsekvenser, hvis opgaven ikke udføres
41+
42+
{Beskriv med enkle ord, hvilke risici og konsekvenser det har, hvis opgaven ikke udføres.}

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,34 @@ before starting to add changes. Use example [placed in the end of the page](#exa
1111

1212
## [Unreleased]
1313

14+
## [5.0.0] 2025-11-18
15+
16+
- [PR-192](https://github.com/OS2Forms/os2forms/pull/192)
17+
Fix bug in MitidChildrenSelectAjaxBehaviour.php
18+
- [PR-228](https://github.com/OS2Forms/os2forms/pull/228)
19+
Added Drupal Core patch ensuring conditionals based upon computed twig
20+
works as intended.
21+
- [PR-215](https://github.com/OS2Forms/os2forms/pull/215)
22+
Added condition to maestro notification submission handler
23+
- [PR-101](https://github.com/OS2Forms/os2forms/pull/101)
24+
- Added support for `os2web_key` in Digital post
25+
- Switched from saving settings in key value store to config, i.e
26+
the module needs to be reconfigured.
27+
- Added support for `os2web_key` in Fasit handler.
28+
- Switched from saving settings in key value store to config, i.e
29+
the module needs to be reconfigured.
30+
- [PR-179](https://github.com/OS2Forms/os2forms/pull/179)
31+
Remove unused and abandoned package `webmozart/path-util`.
32+
- [PR-167](https://github.com/OS2Forms/os2forms/pull/167)
33+
Adding os2forms_digital_signature module
34+
- [PR-223](https://github.com/OS2Forms/os2forms/pull/223)
35+
Moved GitHub feature template to GitHub folder
36+
- [PR-184](https://github.com/OS2Forms/os2forms/pull/184)
37+
- Patches `coc_forms_auto_export` to ensure settings can be saved upon initial
38+
attempt, cf. [Unable to save initial settings due to unfocusable form control](https://www.drupal.org/project/coc_forms_auto_export/issues/3531004)
39+
- [PR-222](https://github.com/OS2Forms/os2forms/pull/222)
40+
Correctly sets sender label on Maestro digital post notifications.
41+
- [OS-199] Remove modules that are not used and not covered by central maintenance from OS2forms
1442
- Avoid double-saving submissions when handling name and address protection.
1543
- [PR-191](https://github.com/OS2Forms/os2forms/pull/191)
1644
Re-throws exception to ensure failed status during Maestro notification job.

composer.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212
"drupal/admin_toolbar": "^3.0",
1313
"drupal/advancedqueue": "^1.0",
1414
"drupal/cache_control_override": "^1.1 || ^2.0",
15-
"drupal/clientside_validation": "^4.0",
1615
"drupal/coc_forms_auto_export": "^3.0@alpha",
1716
"drupal/config_entity_revisions": "2.0.x-dev",
1817
"drupal/diff": "^1.0",
19-
"drupal/embed": "^1.4",
2018
"drupal/entity_print": "^2.1",
2119
"drupal/eu_cookie_compliance": "^1.8",
2220
"drupal/events_logging": "^2.0@beta",
@@ -58,13 +56,13 @@
5856
"itk-dev/serviceplatformen": "^1.7.1",
5957
"mglaman/composer-drupal-lenient": "^1.0",
6058
"os2web/os2web_audit": "^1.0",
61-
"os2web/os2web_datalookup": "^2.0",
59+
"os2web/os2web_datalookup": "^3.0",
60+
"os2web/os2web_key": "^1.0",
6261
"os2web/os2web_nemlogin": "^1.0",
6362
"os2web/os2web_simplesaml": "dev-master",
6463
"php-http/guzzle7-adapter": "^1.0",
6564
"phpoffice/phpword": "^0.18.2",
6665
"symfony/options-resolver": "^5.4 || ^6.0",
67-
"webmozart/path-util": "^2.3",
6866
"wsdltophp/packagebase": "^5.0",
6967
"zaporylie/composer-drupal-optimizations": "^1.2"
7068
},
@@ -115,7 +113,11 @@
115113
"enable-patching": true,
116114
"patches": {
117115
"drupal/coc_forms_auto_export": {
118-
"3256951: - Unable to receive attachments in emails sent": "https://git.drupalcode.org/project/coc_forms_auto_export/-/merge_requests/11.diff"
116+
"3256951: - Unable to receive attachments in emails sent": "https://git.drupalcode.org/project/coc_forms_auto_export/-/merge_requests/11.diff",
117+
"3531004: Unable to save initial settings due to unfocusable form control": "https://www.drupal.org/files/issues/2025-06-19/text_area_with_text_edit_always_fails_reqired_set_via_states.patch"
118+
},
119+
"drupal/core": {
120+
"Allow conditionals based on computed twig (https://www.drupal.org/project/webform/issues/3481569)": "https://www.drupal.org/files/issues/2024-11-05/revert-core-states.patch"
119121
},
120122
"drupal/entity_print": {
121123
"2733781 - Add Export to Word Support": "https://www.drupal.org/files/issues/2019-11-22/2733781-47.patch"
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'

0 commit comments

Comments
 (0)