diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ddc05ab..c4526355 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +This is a hack so the CHANGELOG is messed up. +Generated by build_release.sh # OS2Forms Change Log @@ -11,6 +13,9 @@ before starting to add changes. Use example [placed in the end of the page](#exa ## [Unreleased] +- [PR-325](https://github.com/OS2Forms/os2forms/pull/325) + Added NemID first name, middle name and last name webform elements. + ## [5.1.0] 2026-06-03 - [PR-326](https://github.com/OS2Forms/os2forms/pull/326) diff --git a/build_release.sh b/build_release.sh new file mode 100755 index 00000000..c1f358a2 --- /dev/null +++ b/build_release.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# selvbetjening.aarhuskommune.dk branch +# Setup upstream with OS2Forms CORE +git remote add upstream https://github.com/OS2Forms/os2forms.git +git fetch +git reset --hard 5.1.0 +git merge --no-ff origin/feature/maps-element-display +git checkout --theirs CHANGELOG.md +git add CHANGELOG.md +git commit -m "Merge remote-tracking branch 'origin/feature/maps-element-display' into selvbetjening.aarhuskommune.dk" +git merge --no-ff origin/fix/336-avoid-inheriting-data-on-page-transition +git checkout --theirs CHANGELOG.md +git add CHANGELOG.md +git commit -m "Merge remote-tracking branch 'origin/fix/336-avoid-inheriting-data-on-page-transition' into selvbetjening.aarhuskommune.dk" +git merge --no-ff origin/feature/add-first-middle-and-last-name-nemid-elements +git checkout --theirs CHANGELOG.md +git add CHANGELOG.md +git commit -m "Merge remote-tracking branch 'origin/feature/add-first-middle-and-last-name-nemid-elements' into selvbetjening.aarhuskommune.dk" + +docker run --rm --volume .:/app itkdev/php8.4-fpm:latest sed --in-place '1i This is a hack so the CHANGELOG is messed up. \nGenerated by build_release.sh' CHANGELOG.md +git add CHANGELOG.md +git commit -m "Updated CHANGELOG" diff --git a/composer.json b/composer.json index ba5f18b2..2a8b4388 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,7 @@ "itk-dev/serviceplatformen": "^1.7.1", "mglaman/composer-drupal-lenient": "^1.0", "os2web/os2web_audit": "^1.0", - "os2web/os2web_datalookup": "^3.0", + "os2web/os2web_datalookup": "dev-selvbetjening.aarhuskommune.dk as 3.4.0", "os2web/os2web_key": "^1.0", "os2web/os2web_nemlogin": "^1.0", "os2web/os2web_simplesaml": "dev-master", @@ -76,16 +76,23 @@ "phpunit/phpunit": "^9.5", "wsdltophp/packagegenerator": "^4.0" }, - "repositories": { - "drupal": { + "repositories": [ + { + "name": "os2web/os2web_datalookup", + "type": "vcs", + "url": "https://github.com/itk-dev/os2web_datalookup" + }, + { + "name": "drupal", "type": "composer", "url": "https://packages.drupal.org/8" }, - "assets": { + { + "name": "assets", "type": "composer", "url": "https://asset-packagist.org" } - }, + ], "minimum-stability": "dev", "prefer-stable": true, "config": { @@ -100,6 +107,11 @@ "vaimo/composer-patches": true, "zaporylie/composer-drupal-optimizations": true }, + "policy": { + "advisories": { + "block": false + } + }, "sort-packages": true }, "extra": { diff --git a/modules/os2forms_forloeb/src/Plugin/EngineTasks/MaestroWebformInheritTask.php b/modules/os2forms_forloeb/src/Plugin/EngineTasks/MaestroWebformInheritTask.php index 9544cee5..dd25f1cd 100644 --- a/modules/os2forms_forloeb/src/Plugin/EngineTasks/MaestroWebformInheritTask.php +++ b/modules/os2forms_forloeb/src/Plugin/EngineTasks/MaestroWebformInheritTask.php @@ -144,6 +144,13 @@ public function prepareTaskForSave(array &$form, FormStateInterface $form_state, * Implements hook_webform_submission_form_alter(). */ public static function webformSubmissionFormAlter(array &$form, FormStateInterface $formState, string $formId) { + // Only inherit values on the initial form load. This skip condition is the + // complement of webform's own prepopulate guard. + // @see \Drupal\webform\WebformSubmissionForm::buildForm() + if ($formState->isRebuilding() && !$formState->get('is_ajax_restart')) { + return; + } + // @todo Clean up and align with MaestroHelper::maestroZeroUserNotification(). if ($queueID = self::getQueueIdFromRequest()) { $templateTask = MaestroEngine::getTemplateTaskByQueueID($queueID); diff --git a/modules/os2forms_nemid/src/Element/NemidFirstName.php b/modules/os2forms_nemid/src/Element/NemidFirstName.php new file mode 100644 index 00000000..22be1147 --- /dev/null +++ b/modules/os2forms_nemid/src/Element/NemidFirstName.php @@ -0,0 +1,64 @@ + [ + [$class, 'processNemidFirstName'], + [$class, 'processAjaxForm'], + ], + '#element_validate' => [ + [$class, 'validateNemidFirstName'], + ], + '#pre_render' => [ + [$class, 'preRenderNemidFirstName'], + ], + '#theme' => 'input__os2forms_nemid_first_name', + ]; + } + + /** + * Processes a 'os2forms_nemid_first_name' element. + */ + public static function processNemidFirstName(&$element, FormStateInterface $form_state, &$complete_form) { + // Here you can add and manipulate your element's properties and callbacks. + return $element; + } + + /** + * Webform element validation handler for #type 'os2forms_nemid_first_name'. + */ + public static function validateNemidFirstName(&$element, FormStateInterface $form_state, &$complete_form) { + // Here you can add custom validation logic. + } + + /** + * {@inheritdoc} + */ + public static function preRenderNemidFirstName(array $element) { + $element = parent::prerenderNemidElementBase($element); + static::setAttributes($element, ['form-text', 'os2forms-nemid-first-name']); + return $element; + } + +} diff --git a/modules/os2forms_nemid/src/Element/NemidLastName.php b/modules/os2forms_nemid/src/Element/NemidLastName.php new file mode 100644 index 00000000..251b1144 --- /dev/null +++ b/modules/os2forms_nemid/src/Element/NemidLastName.php @@ -0,0 +1,64 @@ + [ + [$class, 'processNemidLastName'], + [$class, 'processAjaxForm'], + ], + '#element_validate' => [ + [$class, 'validateNemidLastName'], + ], + '#pre_render' => [ + [$class, 'preRenderNemidLastName'], + ], + '#theme' => 'input__os2forms_nemid_last_name', + ]; + } + + /** + * Processes a 'os2forms_nemid_last_name' element. + */ + public static function processNemidLastName(&$element, FormStateInterface $form_state, &$complete_form) { + // Here you can add and manipulate your element's properties and callbacks. + return $element; + } + + /** + * Webform element validation handler for #type 'os2forms_nemid_last_name'. + */ + public static function validateNemidLastName(&$element, FormStateInterface $form_state, &$complete_form) { + // Here you can add custom validation logic. + } + + /** + * {@inheritdoc} + */ + public static function preRenderNemidLastName(array $element) { + $element = parent::prerenderNemidElementBase($element); + static::setAttributes($element, ['form-text', 'os2forms-nemid-last-name']); + return $element; + } + +} diff --git a/modules/os2forms_nemid/src/Element/NemidMiddleName.php b/modules/os2forms_nemid/src/Element/NemidMiddleName.php new file mode 100644 index 00000000..48c038ec --- /dev/null +++ b/modules/os2forms_nemid/src/Element/NemidMiddleName.php @@ -0,0 +1,64 @@ + [ + [$class, 'processNemidMiddleName'], + [$class, 'processAjaxForm'], + ], + '#element_validate' => [ + [$class, 'validateNemidMiddleName'], + ], + '#pre_render' => [ + [$class, 'preRenderNemidMiddleName'], + ], + '#theme' => 'input__os2forms_nemid_middle_name', + ]; + } + + /** + * Processes a 'os2forms_nemid_middle_name' element. + */ + public static function processNemidMiddleName(&$element, FormStateInterface $form_state, &$complete_form) { + // Here you can add and manipulate your element's properties and callbacks. + return $element; + } + + /** + * Webform element validation handler for #type 'os2forms_nemid_middle_name'. + */ + public static function validateNemidMiddleName(&$element, FormStateInterface $form_state, &$complete_form) { + // Here you can add custom validation logic. + } + + /** + * {@inheritdoc} + */ + public static function preRenderNemidMiddleName(array $element) { + $element = parent::prerenderNemidElementBase($element); + static::setAttributes($element, ['form-text', 'os2forms-nemid-middle-name']); + return $element; + } + +} diff --git a/modules/os2forms_nemid/src/Plugin/WebformElement/NemidFirstName.php b/modules/os2forms_nemid/src/Plugin/WebformElement/NemidFirstName.php new file mode 100644 index 00000000..1f0b2468 --- /dev/null +++ b/modules/os2forms_nemid/src/Plugin/WebformElement/NemidFirstName.php @@ -0,0 +1,29 @@ + [ - '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' => '