/**
  * @param Gravity_Flow_Assignee $assignee
  * @param $new_status
  * @param $form
  *
  * @return bool|string If processed return a message to be displayed to the user.
  */
 public function process_assignee_status($assignee, $new_status, $form)
 {
     $feedback = false;
     if (!in_array($new_status, array('pending', 'approved', 'rejected', 'revert'))) {
         return $feedback;
     }
     $current_user_status = $assignee->get_status();
     $current_role_status = false;
     $role = false;
     foreach (gravity_flow()->get_user_roles() as $role) {
         $current_role_status = $this->get_role_status($role);
         if ($current_role_status == 'pending') {
             break;
         }
     }
     if ($current_user_status != 'pending' && $current_role_status != 'pending') {
         return esc_html__('The status could not be changed because this step has already been processed.', 'gravityflow');
     }
     if ($new_status == 'revert') {
         if ($this->revertEnable) {
             $step = gravity_flow()->get_step($this->revertValue, $this->get_entry());
             if ($step) {
                 $this->end();
                 $note = $this->get_name() . ': ' . esc_html__('Reverted to step', 'gravityflow') . ' - ' . $step->get_label();
                 $user_note = rgpost('gravityflow_note');
                 if (!empty($user_note)) {
                     $note .= sprintf("\n%s: %s", __('Note', 'gravityflow'), $user_note);
                 }
                 $this->add_note($note);
                 $step->start();
                 $feedback = esc_html__('Reverted to step:', 'gravityflow') . ' ' . $step->get_label();
             }
         }
         return $feedback;
     }
     if ($current_user_status == 'pending') {
         $assignee->update_status($new_status);
     }
     if ($current_role_status == 'pending') {
         $this->update_role_status($role, $new_status);
     }
     $note = '';
     if ($new_status == 'approved') {
         $note = $this->get_name() . ': ' . __('Approved.', 'gravityflow');
         $this->send_approval_notification();
     } elseif ($new_status == 'rejected') {
         $note = $this->get_name() . ': ' . __('Rejected.', 'gravityflow');
         $this->send_rejection_notification();
     }
     if (!empty($note)) {
         $user_note = rgpost('gravityflow_note');
         if (!empty($user_note)) {
             $note .= sprintf("\n%s: %s", __('Note', 'gravityflow'), $user_note);
         }
         $user_id = $assignee->get_type() == 'user_id' ? $assignee->get_id() : 0;
         $this->add_note($note, $user_id, $assignee->get_display_name());
     }
     $status = $this->evaluate_status();
     $this->update_step_status($status);
     $entry = $this->refresh_entry();
     GFAPI::send_notifications($form, $entry, 'workflow_approval');
     switch ($new_status) {
         case 'approved':
             $feedback = __('Entry Approved', 'gravityflow');
             break;
         case 'rejected':
             $feedback = __('Entry Rejected', 'gravityflow');
             break;
     }
     return $feedback;
 }
 /**
  * Helper for making the gform_post_payment_action hook available to the various payment interaction methods. Also handles sending notifications for payment events.
  *
  * @param array $entry
  * @param array $action
  */
 public function post_payment_action($entry, $action)
 {
     do_action('gform_post_payment_action', $entry, $action);
     if (has_filter('gform_post_payment_action')) {
         $this->log_debug(__METHOD__ . '(): Executing functions hooked to gform_post_payment_action.');
     }
     $form = GFAPI::get_form($entry['form_id']);
     $supported_events = $this->supported_notification_events($form);
     if (!empty($supported_events)) {
         GFAPI::send_notifications($form, $entry, rgar($action, 'type'));
     }
 }
 public static function send_form_submission_notifications($form, $lead)
 {
     GFAPI::send_notifications($form, $lead);
 }
 /**
  * @param Gravity_Flow_Assignee $assignee
  * @param string $new_status
  * @param array $form
  *
  * @return string|bool If processed return a message to be displayed to the user.
  */
 public function process_assignee_status($assignee, $new_status, $form)
 {
     if ($new_status == 'complete') {
         $current_user_status = $assignee->get_status();
         $current_role_status = false;
         $role = false;
         foreach (gravity_flow()->get_user_roles() as $role) {
             $current_role_status = $this->get_role_status($role);
             if ($current_role_status == 'pending') {
                 break;
             }
         }
         if ($current_user_status == 'pending') {
             $assignee->update_status('complete');
         }
         if ($current_role_status == 'pending') {
             $this->update_role_status($role, 'complete');
         }
         $this->refresh_entry();
     }
     $feedback = $new_status == 'complete' ? __('Entry updated and marked complete.', 'gravityflow') : __('Entry updated - in progress.', 'gravityflow');
     $note = sprintf('%s: %s', $this->get_name(), $feedback);
     $user_note = rgpost('gravityflow_note');
     if (!empty($user_note)) {
         $note .= sprintf("\n%s: %s", esc_html__('Note', 'gravityflow'), $user_note);
     }
     $this->add_note($note);
     $status = $this->evaluate_status();
     $this->update_step_status($status);
     $entry = $this->refresh_entry();
     GFAPI::send_notifications($form, $entry, 'workflow_user_input');
     return $feedback;
 }
 public function process_workflow($form, $entry_id)
 {
     $entry = GFAPI::get_entry($entry_id);
     if (isset($entry['workflow_step'])) {
         $this->log_debug(__METHOD__ . '() - processing. entry id ' . $entry_id);
         $step_id = $entry['workflow_step'];
         $starting_step_id = $step_id;
         if (empty($step_id) && (empty($entry['workflow_final_status']) || $entry['workflow_final_status'] == 'pending')) {
             $this->log_debug(__METHOD__ . '() - not yet started workflow. starting.');
             // Starting workflow
             $form_id = absint($form['id']);
             $step = $this->get_first_step($form_id, $entry);
             $this->log_event('workflow', 'started', $form['id'], $entry_id);
             if ($step) {
                 $step->start();
                 $this->log_debug(__METHOD__ . '() - started.');
             } else {
                 $this->log_debug(__METHOD__ . '() - no first step.');
             }
         } else {
             $this->log_debug(__METHOD__ . '() - resuming workflow.');
             $step = $this->get_step($step_id, $entry);
         }
         $step_complete = false;
         if ($step) {
             $step_id = $step->get_id();
             $step_complete = $step->end_if_complete();
             $this->log_debug(__METHOD__ . '() - step ' . $step_id . ' complete: ' . ($step_complete ? 'yes' : 'no'));
         }
         while ($step_complete && $step) {
             $this->log_debug(__METHOD__ . '() - getting next step.');
             $step = $this->get_next_step($step, $entry, $form);
             $step_complete = false;
             if ($step) {
                 $step_id = $step->get_id();
                 $step_complete = $step->start();
                 if ($step_complete) {
                     $step->end();
                 }
             }
             $entry['workflow_step'] = $step_id;
         }
         if ($step == false) {
             $this->log_debug(__METHOD__ . '() - ending workflow.');
             gform_delete_meta($entry_id, 'workflow_step');
             $step_status = gform_get_meta($entry_id, 'workflow_step_status_' . $step_id);
             if (empty($step_status)) {
                 $step_status = 'complete';
             }
             gform_update_meta($entry_id, 'workflow_final_status', $step_status);
             gform_delete_meta($entry_id, 'workflow_step_status');
             $entry_created_timestamp = strtotime($entry['date_created']);
             $duration = time() - $entry_created_timestamp;
             $this->log_event('workflow', 'ended', $form['id'], $entry_id, $step_status, 0, $duration);
             do_action('gravityflow_workflow_complete', $entry_id, $form, $step_status);
             // Refresh entry after action.
             $entry = GFAPI::get_entry($entry_id);
             GFAPI::send_notifications($form, $entry, 'workflow_complete');
         } else {
             $this->log_debug(__METHOD__ . '() - not ending workflow.');
             $step_id = $step->get_id();
             gform_update_meta($entry_id, 'workflow_step', $step_id);
         }
         do_action('gravityflow_post_process_workflow', $form, $entry_id, $step_id, $starting_step_id);
     }
 }