diff --git a/.gitignore b/.gitignore index 93aceb7..f50545c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ # Ignore IntelliJ -.idea/* \ No newline at end of file +.idea/* + +composer.lock +vendor diff --git a/CHANGELOG.md b/CHANGELOG.md index c97a7c5..8c07960 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,14 @@ before starting to add changes. ## [Unreleased] +## 2.5.0 - 11.10.2022 + +### Added +- retry task controller action +- Added support for inheriting values without creating a submission + +## 2.4.0 + ### Added - Github CI action for checking Drupal Coding standards with PHP Code Sniffer - Fixed coding standards issues diff --git a/composer.json b/composer.json index 4c22192..fe2ada9 100644 --- a/composer.json +++ b/composer.json @@ -79,9 +79,6 @@ }, "drupal/coc_forms_auto_export": { "3240592 - Problem with phpseclib requirement in 2.x (https://www.drupal.org/project/coc_forms_auto_export/issues/3240592)": "https://www.drupal.org/files/issues/2021-10-04/requirement-namespace-3240592-1.patch" - }, - "drupal/smtp": { - "Duplicated attachments in emails generated by Webform: (https://www.drupal.org/project/smtp/issues/2995290)": "https://www.drupal.org/files/issues/2021-11-02/smtp-2995290-23.patch" } } }, @@ -100,6 +97,12 @@ ] }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "simplesamlphp/composer-module-installer": true, + "dealerdirect/phpcodesniffer-composer-installer": true, + "cweagans/composer-patches": true, + "zaporylie/composer-drupal-optimizations": true + } } } diff --git a/os2forms_forloeb.module b/os2forms_forloeb.module index 3296639..1d70c11 100644 --- a/os2forms_forloeb.module +++ b/os2forms_forloeb.module @@ -13,8 +13,10 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\Url; use Drupal\maestro\Engine\MaestroEngine; +use Drupal\os2forms_forloeb\Plugin\EngineTasks\MaestroWebformInheritTask; use Drupal\webform\Entity\WebformSubmission; use Drupal\user\Entity\User; +use Drupal\webform\WebformSubmissionInterface; /** * Implements hook_maestro_interactive_handlers(). @@ -96,7 +98,7 @@ function os2forms_forloeb_workflow_maestro_reassign_form_submit(&$form, &$form_s */ function os2forms_forloeb_maestro_batch_handlers() { return [ - 'end_notification_batch_function' => t('Batch function to send out flow completion notification to initiator.'), + '_os2forms_forloeb_end_notification_batch_function' => t('Batch function to send out flow completion notification to initiator.'), ]; } @@ -108,7 +110,7 @@ function os2forms_forloeb_maestro_batch_handlers() { * @param int $queueID * The Maestro queue ID. */ -function end_notification_batch_function($processID, $queueID) { +function _os2forms_forloeb_end_notification_batch_function($processID, $queueID) { /* * Pseudocode for handling this: @@ -343,3 +345,10 @@ function os2forms_forloeb_maestro_post_fetch_assigned_queue_tasks($userID, &$que $queueIDs = array_unique($queueIDs); } } + +/** + * Implements hook_ENTITY_TYPE_prepare_form(). + */ +function os2forms_forloeb_webform_submission_prepare_form(WebformSubmissionInterface $webform_submission, string $operation, FormStateInterface $form_state) { + MaestroWebformInheritTask::webformSubmissionPrepareForm($webform_submission, $operation, $form_state); +} diff --git a/os2forms_forloeb.routing.yml b/os2forms_forloeb.routing.yml index 5754153..8304af4 100644 --- a/os2forms_forloeb.routing.yml +++ b/os2forms_forloeb.routing.yml @@ -7,3 +7,13 @@ os2forms_forloeb.forloeb_task_console_controller_execute: _permission: 'access content' options: no_cache: TRUE + +os2forms_forloeb.forloeb_task_console_controller_execute_retry: + path: 'os2forms-forloeb/execute-task-retry' + defaults: + _controller: '\Drupal\os2forms_forloeb\Controller\ForloebTaskConsoleController::retry' + _title: 'Task not yet ready' + requirements: + _permission: 'access content' + options: + no_cache: TRUE diff --git a/src/Controller/ForloebTaskConsoleController.php b/src/Controller/ForloebTaskConsoleController.php index 8f9d7b7..62beb7c 100644 --- a/src/Controller/ForloebTaskConsoleController.php +++ b/src/Controller/ForloebTaskConsoleController.php @@ -5,6 +5,7 @@ use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\maestro\Engine\MaestroEngine; use Drupal\maestro\Utility\TaskHandler; @@ -19,6 +20,8 @@ */ class ForloebTaskConsoleController extends ControllerBase { + use StringTranslationTrait; + /** * Update manager service. * @@ -82,6 +85,12 @@ public function execute() { $token = $this->requestStack->getCurrentRequest()->query->get('os2forms-forloeb-ws-token', ''); if ($token) { $queueRecord = $this->forloebTaskConsole->getQueueIdByWebformSubmissionToken($token); + if (empty($queueRecord)) { + return new RedirectResponse( + Url::fromRoute('os2forms_forloeb.forloeb_task_console_controller_execute_retry', + ['referrer' => \Drupal::request()->getRequestUri()])->toString() + ); + } } else { // For empty token there is user last task from taskconsole queue. @@ -150,4 +159,18 @@ public function execute() { return new RedirectResponse($redirect_to->toString()); } + /** + * Show message about task not yet ready. + * + * @return array + * The render array. + */ + public function retry() { + $referrer = $this->requestStack->getCurrentRequest()->query->get('referrer', '#'); + + return [ + '#markup' => $this->t('Your task is not yet ready. Please try again in 5 minutes.', [':referrer' => $referrer]), + ]; + } + } diff --git a/src/Plugin/EngineTasks/MaestroWebformInheritTask.php b/src/Plugin/EngineTasks/MaestroWebformInheritTask.php index 83dbdb9..5d6642a 100644 --- a/src/Plugin/EngineTasks/MaestroWebformInheritTask.php +++ b/src/Plugin/EngineTasks/MaestroWebformInheritTask.php @@ -9,6 +9,7 @@ use Drupal\maestro\Form\MaestroExecuteInteractive; use Drupal\maestro\Engine\MaestroEngine; use Drupal\Core\Form\FormStateInterface; +use Drupal\webform\WebformSubmissionInterface; use Symfony\Component\HttpFoundation\RedirectResponse; /** @@ -74,6 +75,12 @@ public function getTaskEditForm(array $task, $templateMachineName) { '#default_value' => $task['data']['inherit_webform_unique_id'] ?? '', '#required' => TRUE, ]; + $form['inherit_webform_create_submission'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Create submission'), + '#description' => $this->t('Create submission'), + '#default_value' => $task['data']['inherit_webform_create_submission'] ?? FALSE, + ]; return $form; } @@ -86,6 +93,7 @@ public function prepareTaskForSave(array &$form, FormStateInterface $form_state, parent::prepareTaskForSave($form, $form_state, $task); // Add custom field(s) to the inherited prepareTaskForSave method. $task['data']['inherit_webform_unique_id'] = $form_state->getValue('inherit_webform_unique_id'); + $task['data']['inherit_webform_create_submission'] = $form_state->getValue('inherit_webform_create_submission'); } /** @@ -120,48 +128,121 @@ public function getExecutableForm($modal, MaestroExecuteInteractive $parent) { } // Now create webform submission, submit and attach to current process. $templateTask = MaestroEngine::getTemplateTaskByQueueID($this->queueID); - $taskUniqueSubmissionId = $templateTask['data']['unique_id']; $webformMachineName = $templateTask['data']['webform_machine_name']; $values = []; $values['webform_id'] = $webformMachineName; $values['data'] = $field_values; - // Create submission. - $new_submission = WebformSubmission::create($values); + $createSubmission = (bool) ($task['data']['inherit_webform_create_submission'] ?? FALSE); + if ($createSubmission) { + // Create submission. + $new_submission = WebformSubmission::create($values); + + // Submit the webform submission. + $submission = WebformSubmissionForm::submitWebformSubmission($new_submission); + + // WebformSubmissionForm::submitWebformSubmission returns an array + // if the submission is not valid. + if (is_array($submission)) { + \Drupal::logger('os2forms_forloeb')->error( + "Can't create new submission: " . json_encode($submission) + ); + \Drupal::messenger()->addError('Webform data is invalid and could not be submitted.'); + return FALSE; + } - // Submit the webform submission. - $submission = WebformSubmissionForm::submitWebformSubmission($new_submission); + $taskUniqueSubmissionId = $templateTask['data']['unique_id']; - // WebformSubmissionForm::submitWebformSubmission returns an array - // if the submission is not valid. - if (is_array($submission)) { - \Drupal::logger('os2forms_forloeb')->error( - "Can't create new submission: " . json_encode($submission) + // Attach it to the Maestro process. + $sid = $new_submission->id(); + MaestroEngine::createEntityIdentifier( + $this->processID, $new_submission->getEntityTypeId(), + $new_submission->bundle(), $taskUniqueSubmissionId, $sid ); - \Drupal::messenger()->addError('Webform data is invalid and could not be submitted.'); - return FALSE; - } - // Attach it to the Maestro process. - $sid = $new_submission->id(); - MaestroEngine::createEntityIdentifier( - $this->processID, $new_submission->getEntityTypeId(), - $new_submission->bundle(), $taskUniqueSubmissionId, $sid - ); - - $form = parent::getExecutableForm($modal, $parent); - // Catch os2forms-forloeb access token and pass it further. - if ($form instanceof RedirectResponse && $token = \Drupal::request()->query->get('os2forms-forloeb-ws-token')) { - // Check token to previous submission and update it to new one. - if ($token === $webform_submission->getToken()) { - $token = $new_submission->getToken(); - $url = Url::fromUserInput($form->getTargetUrl(), ['query' => ['os2forms-forloeb-ws-token' => $token]]); - $form = new RedirectResponse($url->toString()); + // Important: Apparently the form must be generated after calling + // MaestroEngine::createEntityIdentifier for this to work. + $form = parent::getExecutableForm($modal, $parent); + // Catch os2forms-forloeb access token and pass it further. + if ($form instanceof RedirectResponse && $token = \Drupal::request()->query->get('os2forms-forloeb-ws-token')) { + // Check token to previous submission and update it to new one. + if ($token === $webform_submission->getToken()) { + $token = $new_submission->getToken(); + $url = Url::fromUserInput($form->getTargetUrl(), ['query' => ['os2forms-forloeb-ws-token' => $token]]); + $form = new RedirectResponse($url->toString()); + } } } + else { + // Store values in session. + $values['processID'] = $this->processID; + $values['queueID'] = $this->queueID; + $values['webformInheritID'] = $webformInheritID; + + self::setTaskValues($this->queueID, $values); + + $form = parent::getExecutableForm($modal, $parent); + } return $form; } + /** + * Implements hook_ENTITY_TYPE_prepare_form(). + */ + public static function webformSubmissionPrepareForm(WebformSubmissionInterface $webformSubmission, string $operation, FormStateInterface $formState): void { + $request = \Drupal::request(); + $isMaestro = (bool) $request->query->get('maestro', 0); + $queueID = (int) $request->query->get('queueid', 0); + if ($isMaestro && $queueID > 0) { + $values = self::getTaskValues($queueID); + if (isset($values['data'])) { + foreach ($values['data'] as $name => $value) { + $webformSubmission->setElementData($name, $value); + } + } + } + } + + /** + * Get task values from session. + * + * @param int $queueID + * The queue ID. + * + * @return array + * The task values if any. + */ + private static function getTaskValues($queueID) { + $sessionKey = self::formatTaskValuesSessionKey($queueID); + return \Drupal::request()->getSession()->get($sessionKey); + } + + /** + * Set task values in session. + * + * @param int $queueID + * The queue ID. + * @param array $values + * The values. + */ + private static function setTaskValues($queueID, array $values) { + $sessionKey = self::formatTaskValuesSessionKey($queueID); + \Drupal::request()->getSession()->set($sessionKey, $values); + } + + /** + * Format task values session key. + * + * @param int $queueID + * The queue ID. + * + * @return string + * The formatted session key. + */ + private static function formatTaskValuesSessionKey($queueID) { + return sprintf('os2forms_forloeb_inherited_values_%s', $queueID); + } + }