diff --git a/os2forms_forloeb.module b/os2forms_forloeb.module index 2002cf8..155fcf9 100644 --- a/os2forms_forloeb.module +++ b/os2forms_forloeb.module @@ -2,6 +2,8 @@ use Drupal\webform\WebformInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Render\BubbleableMetadata; +use Drupal\Core\Url; use Drupal\maestro\Engine\MaestroEngine; use Drupal\webform\Entity\WebformSubmission; use Drupal\user\Entity\User; @@ -201,7 +203,7 @@ function os2forms_forloeb_spv_fetch_entity_username($uniqueWebformIdentifier, $w /** * Returns array of custom task-types for OS2forms - * + * */ function os2forms_forloeb_get_custom_task_types() { return ['MaestroWebformMultiple', 'MaestroWebformInherit']; @@ -268,3 +270,59 @@ function os2forms_forloeb_form_alter(&$form, FormStateInterface $form_state, $fo function os2forms_forloeb_preprocess_page(&$variables) { $variables['#attached']['library'][] = 'os2forms_forloeb/os2forms_forloeb'; } + +/** + * Implements hook_token_info_alter(). + */ +function os2forms_forloeb_token_info_alter(&$data) { + $data['tokens']['webform_submission']['os2forms_forloeb_execute_task'] = [ + 'name' => t('Execute task path for webform submission'), + 'description' => t("The token that can be user to get path for webform submission redirect URL."), + 'type' => 'webform_submission', + ]; +} + +/** + * Implements hook_tokens(). + * + * Provides token value for webform_submission:os2forms_forloeb_execute_task. + */ +function os2forms_forloeb_tokens($type, array $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { + $replacements = []; + + if ($type === 'webform_submission' && !empty($data['webform_submission']) && isset($tokens['os2forms_forloeb_execute_task'])) { + $replacements[$tokens['os2forms_forloeb_execute_task']] = Url::fromRoute( + 'os2forms_forloeb.forloeb_task_console_controller_execute', + ['os2forms-forloeb-ws-token' => $data['webform_submission']->getToken()], + ['absolute' => TRUE] + )->toString(TRUE)->getGeneratedUrl(); + } + + return $replacements; +} + +/** + * Implements hook_entity_access(). + * Allows requests with tokens to view the entity. + */ +function os2forms_forloeb_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) { + if ($operation == 'update' && $entity instanceof WebformSubmission) { + $token = \Drupal::request()->query->get('os2forms-forloeb-ws-token'); + if ($token && $token === $entity->getToken()) { + return \Drupal\Core\Access\AccessResult::allowed(); + } + } +} + +/** + * Implements hook_maestro_post_fetch_assigned_queue_tasks(). + */ +function os2forms_forloeb_maestro_post_fetch_assigned_queue_tasks($userID, &$queueIDs) { + $token = \Drupal::request()->query->get('os2forms-forloeb-ws-token', ''); + if ($token) { + $forloebTaskConsole = Drupal::service('os2forms_forloeb.task_console'); + $queueRecord = $forloebTaskConsole->getQueueIdByWebformSubmissionToken($token); + $queueIDs[] = $queueRecord->id(); + $queueIDs = array_unique($queueIDs); + } +} diff --git a/os2forms_forloeb.routing.yml b/os2forms_forloeb.routing.yml index 0686d1b..5754153 100644 --- a/os2forms_forloeb.routing.yml +++ b/os2forms_forloeb.routing.yml @@ -4,6 +4,6 @@ os2forms_forloeb.forloeb_task_console_controller_execute: _controller: '\Drupal\os2forms_forloeb\Controller\ForloebTaskConsoleController::execute' _title: 'Execute task' requirements: - _permission: 'view maestro task console' + _permission: 'access content' options: no_cache: TRUE diff --git a/os2forms_forloeb.services.yml b/os2forms_forloeb.services.yml index 9e939cf..eb0fa89 100644 --- a/os2forms_forloeb.services.yml +++ b/os2forms_forloeb.services.yml @@ -4,4 +4,4 @@ services: arguments: ['os2forms_forloeb'] os2forms_forloeb.task_console: class: Drupal\os2forms_forloeb\ForloebTaskConsole - arguments: ['@entity_type.manager'] + arguments: ['@entity_type.manager', '@logger.channel.os2forms_forloeb'] diff --git a/src/Controller/ForloebTaskConsoleController.php b/src/Controller/ForloebTaskConsoleController.php index c8fb5d5..0666915 100644 --- a/src/Controller/ForloebTaskConsoleController.php +++ b/src/Controller/ForloebTaskConsoleController.php @@ -67,7 +67,7 @@ public function execute() { $redirect_to = Url::fromRoute('maestro_taskconsole.taskconsole'); // Check webform submission token. - $token = \Drupal::request()->query->get('token', ''); + $token = \Drupal::request()->query->get('os2forms-forloeb-ws-token', ''); if ($token) { $queueRecord = $this->forloebTaskConsole->getQueueIdByWebformSubmissionToken($token); } @@ -126,6 +126,9 @@ public function execute() { break; case 'function': + if ($token) { + $query_options['os2forms-forloeb-ws-token'] = $token; + } $redirect_to = Url::fromRoute('maestro.execute', $query_options); break; } diff --git a/src/ForloebTaskConsole.php b/src/ForloebTaskConsole.php index 2fc2c6c..ef7340c 100644 --- a/src/ForloebTaskConsole.php +++ b/src/ForloebTaskConsole.php @@ -2,14 +2,20 @@ namespace Drupal\os2forms_forloeb; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\maestro\Engine\MaestroEngine; +use Drupal\maestro\Entity\MaestroEntityIdentifiers; +use Drupal\maestro\Entity\MaestroProcess; use Drupal\webform\Entity\WebformSubmission; +use Psr\Log\LoggerInterface; /** * Class ForloebTaskConsole. */ class ForloebTaskConsole { + use StringTranslationTrait; + /** * Drupal\Core\Entity\EntityTypeManagerInterface definition. * @@ -17,13 +23,22 @@ class ForloebTaskConsole { */ protected $entityTypeManager; + /** + * Logger. + * + * @var \Psr\Log\LoggerInterface + */ + protected $logger; + /** * Constructs a new ForloebTaskConsole object. */ - public function __construct(EntityTypeManagerInterface $entity_type_manager) { + public function __construct(EntityTypeManagerInterface $entity_type_manager, LoggerInterface $logger) { $this->entityTypeManager = $entity_type_manager; + $this->logger = $logger; } + /** * Gets MaestroQueue record by webforms submission token. * @@ -36,31 +51,32 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager) { * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ public function getQueueIdByWebformSubmissionToken($token = '') { - $engine = new MaestroEngine(); - // Fetch the user's queue items. - $queueIDs = $engine->getAssignedTaskQueueIds(\Drupal::currentUser()->id()); + /** @var WebformSubmission $webform_submission */ + $webform_submissions = $this->entityTypeManager->getStorage('webform_submission')->loadByProperties(['token' => $token]); - foreach ($queueIDs as $queueID) { - $this->entityTypeManager->getStorage('maestro_queue')->resetCache([$queueID]); - /** @var \Drupal\maestro\Entity\MaestroQueue $queueRecord */ - $queueRecord = $this->entityTypeManager->getStorage('maestro_queue')->load($queueID); - $processID = $engine->getProcessIdFromQueueId($queueID); - $templateMachineName = $engine->getTemplateIdFromProcessId($processID); - - // Get user input from 'inherit_webform_unique_id' - $taskMachineName = $engine->getTaskIdFromQueueId($queueID); - $task = $engine->getTemplateTaskByID($templateMachineName, $taskMachineName); - - // Load its corresponding webform submission. - $sid = $engine->getEntityIdentiferByUniqueID($processID, $task['data']['inherit_webform_unique_id'] ?? ''); - $webform_submission = $sid ? WebformSubmission::load($sid) : NULL; + if (empty($webform_submissions)) { + $this->logger->warning($this->t('Submission with token @token not found', ['@token' => $token])); + return NULL; + } - // Compare webform submission with token from request. - if ($webform_submission && $webform_submission->getToken() == $token) { - return $queueRecord; - } + $webform_submission = reset($webform_submissions); + /** @var MaestroEntityIdentifiers $maestro_entity_identifier */ + $maestro_entity_identifiers = $this->entityTypeManager->getStorage('maestro_entity_identifiers')->loadByProperties(['entity_type' => 'webform_submission', 'entity_id' => $webform_submission->id(),]); + $maestro_entity_identifier = reset($maestro_entity_identifiers); + $processIDs = $maestro_entity_identifier->process_id->referencedEntities(); + if (empty($processIDs)) { + $this->logger->warning($this->t('Process with entity type: webform_submission and entity_id: @entity_id not found', ['@entity_id' => $webform_submission->id()])); + return NULL; } - return NULL; + $processID = reset($processIDs); + $maestro_queues = $this->entityTypeManager->getStorage('maestro_queue')->loadByProperties(['process_id' => $processID->id(), 'task_class_name' => 'MaestroWebformInherit',]); + if (empty($maestro_queues)) { + $this->logger->warning($this->t('Maestro queue with task_class_name: MaestroWebformInherit and process_id: @process_id not found', ['@process_id' => $processID->id()])); + return NULL; + } + $maestro_queue = reset($maestro_queues); + return $maestro_queue; } + } diff --git a/src/Plugin/EngineTasks/MaestroWebformInheritTask.php b/src/Plugin/EngineTasks/MaestroWebformInheritTask.php index e0bad7c..ecdceaf 100644 --- a/src/Plugin/EngineTasks/MaestroWebformInheritTask.php +++ b/src/Plugin/EngineTasks/MaestroWebformInheritTask.php @@ -2,6 +2,7 @@ namespace Drupal\os2forms_forloeb\Plugin\EngineTasks; +use Drupal\Core\Url; use Drupal\webform\Entity\WebformSubmission; use Drupal\webform\WebformSubmissionForm; use Drupal\maestro_webform\Plugin\EngineTasks\MaestroWebformTask; @@ -12,6 +13,7 @@ use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\ReplaceCommand; use Drupal\Core\Messenger; +use Symfony\Component\HttpFoundation\RedirectResponse; /** * Maestro Webform Task Plugin for Multiple Submissions. @@ -83,7 +85,7 @@ public function getTaskEditForm(array $task, $templateMachineName) { * {@inheritDoc} */ public function prepareTaskForSave(array &$form, FormStateInterface $form_state, array &$task) { - + // Inherit from parent parent::prepareTaskForSave($form, $form_state, $task); // Add custom field(s) to the inherited prepareTaskForSave method. @@ -102,7 +104,7 @@ public function getExecutableForm($modal, MaestroExecuteInteractive $parent) { // Get user input from 'inherit_webform_unique_id' $webformInheritID = $task['data']['inherit_webform_unique_id']; - + // Load its corresponding webform submission. $sid = MaestroEngine::getEntityIdentiferByUniqueID($this->processID, $webformInheritID); if ($sid) { @@ -151,6 +153,17 @@ public function getExecutableForm($modal, MaestroExecuteInteractive $parent) { $new_submission->bundle(), $taskUniqueSubmissionId, $sid ); - return parent::getExecutableForm($modal, $parent); + $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()); + } + } + + return $form; } }