You are here

public function MaestroTaskTrait::saveTask in Maestro 8.2

Same name and namespace in other branches
  1. 3.x src/MaestroTaskTrait.php \Drupal\maestro\MaestroTaskTrait::saveTask()

Available for all tasks -- this does the general task construction for us, ensuring we have sanity in the saved Config Entity for the task. Assignments and Notifications are the two main elements this method worries about.

Parameters

array $form: The form submission from the submit handler.

\Drupal\Core\Form\FormStateInterface $form_state: The FormStateInterface from the submit handler.

array $task: The array representation of loading a task from the template via the MaestroEngine::getTemplateTaskByID method.

File

src/MaestroTaskTrait.php, line 493

Class

MaestroTaskTrait
MaestroTaskTrait.

Namespace

Drupal\maestro

Code

public function saveTask(array &$form, FormStateInterface $form_state, array &$task) {
  $result = FALSE;
  $templateMachineName = $form_state
    ->getValue('template_machine_name');
  $taskID = $form_state
    ->getValue('task_id');
  $taskAssignments = $form_state
    ->getValue('edit_task_assignments');
  $taskNotifications = $form_state
    ->getValue('edit_task_notifications');

  // $task holds the loaded task from the template.  We can now perform our general operations on the task
  // to ensure that it contains all of the proper elements in it for use by the engine.
  // the elements of our task that are minimally required are as follows:
  // id, tasktype, label, nextstep, nextfalsestep, top, left, assignby, assignto, assigned
  // first, do a validity check on the task structure
  // These are the keys that SHOULD exist in our task.
  $requiredKeys = [
    'id' => $taskID,
    'tasktype' => '',
    'label' => $form_state
      ->getValue('label'),
    'nextstep' => '',
    'nextfalsestep' => '',
    'top' => 25,
    'left' => 25,
    'assignby' => '',
    'assignto' => '',
    'assigned' => '',
    'runonce' => 0,
    'handler' => '',
    'showindetail' => 1,
    'participate_in_workflow_status_stage' => 0,
    'workflow_status_stage_number' => 0,
    'workflow_status_stage_message' => '',
  ];
  $missingKeys = array_diff_key($requiredKeys, $task);
  foreach ($missingKeys as $key => $val) {

    // Seed the key properly with default values.
    $task[$key] = $val;
  }

  // Now the core fields.
  $task['label'] = $form_state
    ->getValue('label');
  $task['participate_in_workflow_status_stage'] = $form_state
    ->getValue('participate_in_workflow_status_stage');
  $task['workflow_status_stage_number'] = $form_state
    ->getValue('workflow_status_stage_number');
  $task['workflow_status_stage_message'] = $form_state
    ->getValue('workflow_status_stage_message');

  // Now the assignments.
  $executableTask = MaestroEngine::getPluginTask($task['tasktype']);
  if ($executableTask
    ->isInteractive()) {

    // ok, we now manipulate the assignments if we're in here
    // first to detect if we're deleting anything
    // break out the current assignments.
    isset($task['assigned']) ? $currentAssignments = explode(',', $task['assigned']) : ($currentAssignments = []);
    isset($taskAssignments['task_assignment_table']) ? $deleteAssignmentsList = $taskAssignments['task_assignment_table'] : ($deleteAssignmentsList = []);
    if (isset($deleteAssignmentsList) && is_array($deleteAssignmentsList)) {
      foreach ($deleteAssignmentsList as $key => $arr) {

        // The deleteAssignmentsList is a key-for-key alignment with the currentAssignments.
        if ($arr['delete'] == 1) {
          unset($currentAssignments[$key]);
        }
      }
    }
    $task['assigned'] = implode(',', $currentAssignments);
    if (($taskAssignments['select_assigned_role'] != '' || $taskAssignments['select_assigned_user'] != '') && $taskAssignments['select_method'] == 'fixed') {

      // alright, formulate the assignment.
      if ($taskAssignments['select_assigned_user'] != '' && $taskAssignments['select_assign_to'] == 'user') {

        // Need to get the username.
        $account = User::load($taskAssignments['select_assigned_user']);
        $assignee = $account
          ->getAccountName();
      }
      elseif ($taskAssignments['select_assigned_role'] != '' && $taskAssignments['select_assign_to'] == 'role') {

        // Need to strip out the text surrounding the bracketed values.
        preg_match('#\\((.*?)\\)#', $taskAssignments['select_assigned_role'], $match);
        $assignee = $match[1];
      }
      $assignment = $taskAssignments['select_assign_to'] . ':' . $taskAssignments['select_method'] . ':' . $assignee;
    }
    elseif ($taskAssignments['select_method'] == 'variable') {
      $assignment = $taskAssignments['select_assign_to'] . ':' . $taskAssignments['select_method'] . ':' . $taskAssignments['variable'];
    }
    if (isset($assignment) && $assignment != '') {
      if ($task['assigned'] != '') {
        $task['assigned'] .= ',';
      }
      $task['assigned'] .= $assignment;
    }

    // And now notifications
    // we need to parse out the notification form to determine what this person is trying to add in a similar fashion to that of the assignments.
    if (!array_key_exists('notifications', $task)) {

      // Lets just seed the main array key.
      $task['notifications'] = [];
    }
    if (array_key_exists('notification_assignments', $task['notifications'])) {
      $currentNotifications = explode(',', $task['notifications']['notification_assignments']);
      $deleteNotificationsList = $taskNotifications['task_notifications_table'];
      foreach ($deleteNotificationsList as $key => $arr) {

        // The $deleteNotificationsList is a key-for-key alignment with the currentNotifications.
        if ($arr['delete'] == 1) {
          unset($currentNotifications[$key]);
        }
      }
      $task['notifications']['notification_assignments'] = implode(',', $currentNotifications);
    }
    $notifications = '';
    if (($taskNotifications['select_notification_role'] != '' || $taskNotifications['select_notification_user'] != '') && $taskNotifications['select_notification_method'] == 'fixed') {

      // alright, formulate the assignment.
      if ($taskNotifications['select_notification_user'] != '' && $taskNotifications['select_notification_to'] == 'user') {

        // Need to get the username.
        $account = User::load($taskNotifications['select_notification_user']);
        $assignee = $account
          ->getAccountName();
      }
      elseif ($taskNotifications['select_notification_role'] != '' && $taskNotifications['select_notification_to'] == 'role') {

        // Need to strip out the text surrounding the bracketed values.
        preg_match('#\\((.*?)\\)#', $taskNotifications['select_notification_role'], $match);
        $assignee = $match[1];
      }
      $notifications = $taskNotifications['select_notification_to'] . ':' . $taskNotifications['select_notification_method'] . ':' . $assignee . ':' . $taskNotifications['which_notification'];
    }
    elseif ($taskNotifications['select_notification_method'] == 'variable') {
      $notifications = $taskNotifications['select_notification_to'] . ':' . $taskNotifications['select_notification_method'] . ':' . $taskNotifications['variable'] . ':' . $taskNotifications['which_notification'];
    }
    if ($notifications != '') {
      if ($task['notifications']['notification_assignments'] != '') {
        $task['notifications']['notification_assignments'] .= ',';
      }
      $task['notifications']['notification_assignments'] .= $notifications;
    }
  }
  $task['notifications']['notification_assignment_subject'] = $taskNotifications['notification_assignment_subject'];
  $task['notifications']['notification_assignment'] = $taskNotifications['notification_assignment'];
  $task['notifications']['notification_reminder_subject'] = $taskNotifications['notification_reminder_subject'];
  $task['notifications']['notification_reminder'] = $taskNotifications['notification_reminder'];
  $task['notifications']['notification_escalation_subject'] = $taskNotifications['notification_escalation_subject'];
  $task['notifications']['notification_escalation'] = $taskNotifications['notification_escalation'];
  $task['notifications']['reminder_after'] = $taskNotifications['reminder_after'];
  $task['notifications']['escalation_after'] = $taskNotifications['escalation_after'];

  // Let other modules do their own assignments and notifications and any other task mods they want.
  \Drupal::moduleHandler()
    ->invokeAll('maestro_pre_task_save', [
    $templateMachineName,
    $taskID,
    &$task,
    $taskAssignments,
    $taskNotifications,
  ]);

  // Finally save the task.
  $result = MaestroEngine::saveTemplateTask($templateMachineName, $taskID, $task);

  // TODO: What to do with the result if an error exists?
  // we now clear out the form values for a few specific fields we have control over.
  $arr = $form_state
    ->getUserInput();
  $arr['edit_task_assignments']['select_assigned_role'] = '';
  $arr['edit_task_assignments']['select_assigned_user'] = '';
  $arr['edit_task_assignments']['select_assign_to'] = 'user';
  $arr['edit_task_assignments']['select_method'] = 'fixed';
  $arr['edit_task_notifications']['select_notification_role'] = '';
  $arr['edit_task_notifications']['select_notification_user'] = '';
  $arr['edit_task_notifications']['select_notification_to'] = 'user';
  $arr['edit_task_notifications']['select_notification_method'] = 'fixed';
  $arr['edit_task_notifications']['which_notification'] = 'assignment';
  $form_state
    ->setUserInput($arr);
  return $result;
}