diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ddc05ab..8d6b888d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ before starting to add changes. Use example [placed in the end of the page](#exa ## [Unreleased] +- [PR-353](https://github.com/OS2Forms/os2forms/pull/353) + - Moved `WebformInheritTask` data inheriting from + `hook_webform_submission_form_alter` to `hook_entity_prepare_form`. + - Set data on the submission. + ## [5.1.0] 2026-06-03 - [PR-326](https://github.com/OS2Forms/os2forms/pull/326) diff --git a/modules/os2forms_forloeb/os2forms_forloeb.module b/modules/os2forms_forloeb/os2forms_forloeb.module index 4636ec3d..cbdd09ec 100644 --- a/modules/os2forms_forloeb/os2forms_forloeb.module +++ b/modules/os2forms_forloeb/os2forms_forloeb.module @@ -5,6 +5,7 @@ * Install, update and uninstall functions for the os2forms_forloeb. */ +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\maestro\Engine\MaestroEngine; use Drupal\os2forms_forloeb\MaestroHelper; @@ -12,6 +13,7 @@ use Drupal\os2forms_forloeb\Plugin\EngineTasks\MaestroWebformInheritTask; use Drupal\user\Entity\User; use Drupal\webform\Entity\WebformSubmission; use Drupal\webform\WebformInterface; +use Drupal\webform\WebformSubmissionInterface; /** * Implements hook_maestro_interactive_handlers(). @@ -293,10 +295,16 @@ function os2forms_forloeb_preprocess_page(&$variables) { } /** - * Implements hook_webform_submission_form_alter(). + * Implements hook_entity_prepare_form(). + * + * Uses the generic hook rather than hook_webform_submission_prepare_form() + * because core invokes the generic hook first, and the inherited data should + * be set early (@see \Drupal\Core\Entity\EntityForm::init() for details). */ -function os2forms_forloeb_webform_submission_form_alter(array &$form, FormStateInterface $formState, string $formId) { - MaestroWebformInheritTask::webformSubmissionFormAlter($form, $formState, $formId); +function os2forms_forloeb_entity_prepare_form(EntityInterface $entity, string $operation, FormStateInterface $formState) { + if ($entity instanceof WebformSubmissionInterface) { + MaestroWebformInheritTask::webformSubmissionPrepareForm($entity, $operation, $formState); + } } /** diff --git a/modules/os2forms_forloeb/src/Plugin/EngineTasks/MaestroWebformInheritTask.php b/modules/os2forms_forloeb/src/Plugin/EngineTasks/MaestroWebformInheritTask.php index 9544cee5..ea7de0d1 100644 --- a/modules/os2forms_forloeb/src/Plugin/EngineTasks/MaestroWebformInheritTask.php +++ b/modules/os2forms_forloeb/src/Plugin/EngineTasks/MaestroWebformInheritTask.php @@ -2,13 +2,12 @@ namespace Drupal\os2forms_forloeb\Plugin\EngineTasks; -use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormStateInterface; use Drupal\maestro\Engine\MaestroEngine; use Drupal\maestro_webform\Plugin\EngineTasks\MaestroWebformTask; -use Drupal\webform\Entity\Webform; use Drupal\webform\Entity\WebformSubmission; use Drupal\webform\Utility\WebformArrayHelper; +use Drupal\webform\WebformSubmissionInterface; /** * Maestro Webform Task Plugin for Multiple Submissions. @@ -141,39 +140,64 @@ public function prepareTaskForSave(array &$form, FormStateInterface $form_state, } /** - * Implements hook_webform_submission_form_alter(). + * Implements hook_entity_prepare_form() for webform submissions. + * + * Sets inherited data on the webform submission entity. + * + * @see \Drupal\webform\WebformSubmissionForm::populateElements() */ - public static function webformSubmissionFormAlter(array &$form, FormStateInterface $formState, string $formId) { - // @todo Clean up and align with MaestroHelper::maestroZeroUserNotification(). - if ($queueID = self::getQueueIdFromRequest()) { - $templateTask = MaestroEngine::getTemplateTaskByQueueID($queueID); - if (self::isWebformTask($templateTask)) { - if ($inheritWebformUniqueId = ($templateTask['data'][self::INHERIT_WEBFORM_UNIQUE_ID] ?? NULL)) { - $processID = MaestroEngine::getProcessIdFromQueueId($queueID); - $entityIdentifier = MaestroEngine::getAllEntityIdentifiersForProcess($processID)[$inheritWebformUniqueId] ?? NULL; - if ('webform_submission' === ($entityIdentifier['entity_type'] ?? NULL)) { - $submission = WebformSubmission::load($entityIdentifier['entity_id']); - $data = $submission->getData(); - - // The target element may be hidden inside sections or field groups - // on the target form. Therefore, we need to load that form and get - // element information to properly set default element values nested - // inside the form. - if ($targetWebform = Webform::load($form['#webform_id'] ?? NULL)) { - foreach ($data as $key => $value) { - if ($targetElement = $targetWebform->getElement($key)) { - if ($element = &NestedArray::getValue($form['elements'], $targetElement['#webform_parents'])) { - $element['#default_value'] = $value; - } - } - } - } - } - } + public static function webformSubmissionPrepareForm(WebformSubmissionInterface $submission, string $operation, FormStateInterface $formState): void { + if ($source = self::getInheritedSourceSubmission()) { + $webform = $submission->getWebform(); + + // Only inherit values for elements on the target form. + $inheritedData = array_filter( + $source->getData(), + static fn (string $key) => NULL !== $webform->getElement($key), + ARRAY_FILTER_USE_KEY + ); + + if ($inheritedData) { + $submission->setData($inheritedData + $submission->getData()); } } } + /** + * Get the webform submission that the current request's task inherits from. + * + * Resolves the Maestro queue ID from the current request and, if the + * corresponding template task is a webform task configured to inherit + * another task's submission, loads that submission. + * + * @todo Align with MaestroHelper::maestroZeroUserNotification(), which + * resolves the process submission in a similar way. + */ + public static function getInheritedSourceSubmission(): ?WebformSubmissionInterface { + $queueID = self::getQueueIdFromRequest(); + if (NULL === $queueID) { + return NULL; + } + + $templateTask = MaestroEngine::getTemplateTaskByQueueID($queueID); + if (!self::isWebformTask($templateTask)) { + return NULL; + } + + $inheritWebformUniqueId = $templateTask['data'][self::INHERIT_WEBFORM_UNIQUE_ID] ?? NULL; + if (!$inheritWebformUniqueId) { + return NULL; + } + + $processID = MaestroEngine::getProcessIdFromQueueId($queueID); + $entityIdentifier = MaestroEngine::getAllEntityIdentifiersForProcess($processID)[$inheritWebformUniqueId] ?? NULL; + if ('webform_submission' !== ($entityIdentifier['entity_type'] ?? NULL)) { + return NULL; + } + + return WebformSubmission::load($entityIdentifier['entity_id']); + } + /** * Get Maestro queue ID from request. */