diff --git a/modules/os2forms_forloeb/os2forms_forloeb.module b/modules/os2forms_forloeb/os2forms_forloeb.module index 4636ec3..477a0d8 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,18 @@ 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() */ -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 9544cee..c1e2838 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,10 +140,41 @@ 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 webformSubmissionPrepareForm(WebformSubmissionInterface $submission, string $operation, FormStateInterface $formState): void { + if ($source = self::getInheritedSourceSubmission()) { + $webform = $submission->getWebform(); + + // Only inherit values for elements on the target form. + $data = []; + foreach ($source->getData() as $key => $value) { + if ($webform->getElement($key)) { + $data[$key] = $value; + } + } + + if ($data) { + $submission->setData($data + $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 webformSubmissionFormAlter(array &$form, FormStateInterface $formState, string $formId) { - // @todo Clean up and align with MaestroHelper::maestroZeroUserNotification(). + public static function getInheritedSourceSubmission(): ?WebformSubmissionInterface { if ($queueID = self::getQueueIdFromRequest()) { $templateTask = MaestroEngine::getTemplateTaskByQueueID($queueID); if (self::isWebformTask($templateTask)) { @@ -152,26 +182,13 @@ public static function webformSubmissionFormAlter(array &$form, FormStateInterfa $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; - } - } - } - } + return WebformSubmission::load($entityIdentifier['entity_id']); } } } } + + return NULL; } /**