/** * @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; }
/** * @param Gravity_Flow_Assignee $assignee * * @return array */ function get_assignee_array($assignee) { return array('key' => $assignee->get_key(), 'id' => $assignee->get_id(), 'type' => $assignee->get_type(), 'display_name' => $assignee->get_display_name(), 'status' => $assignee->get_status()); }
/** * Removes assignees from and/or adds assignees to a step. Call after updating entry values. * Make sure you call get_assignees() before you update the entry or the previous assignees may not get removed. * * @param Gravity_Flow_Assignee[] $previous_assignees The previous assign */ public function maybe_adjust_assignment($previous_assignees) { gravity_flow()->log_debug(__METHOD__ . '(): Starting'); $new_assignees = $this->get_assignees(); $new_assignees_keys = array(); foreach ($new_assignees as $new_assignee) { $new_assignees_keys[] = $new_assignee->get_key(); } $previous_assignees_keys = array(); foreach ($previous_assignees as $previous_assignee) { $previous_assignees_keys[] = $previous_assignee->get_key(); } $assignee_keys_to_add = array_diff($new_assignees_keys, $previous_assignees_keys); $assignee_keys_to_remove = array_diff($previous_assignees_keys, $new_assignees_keys); foreach ($assignee_keys_to_add as $assignee_key_to_add) { $assignee_to_add = new Gravity_Flow_Assignee($assignee_key_to_add, $this); $assignee_to_add->update_status('pending'); } foreach ($assignee_keys_to_remove as $assignee_key_to_remove) { $assignee_to_remove = new Gravity_Flow_Assignee($assignee_key_to_remove, $this); $assignee_to_remove->remove(); } }
public function workflow_detail_status_box($form) { global $current_user; $form_id = absint($form['id']); $status_str = __('Pending Input', 'gravityflow'); $approve_icon = '<i class="fa fa-check" style="color:green"></i>'; $input_step_status = $this->get_status(); if ($input_step_status == 'complete') { $status_str = $approve_icon . __('Complete', 'gravityflow'); } elseif ($input_step_status == 'queued') { $status_str = __('Queued', 'gravityflow'); } ?> <h4 style="margin-bottom:10px;"><?php echo $this->get_name() . ' (' . $status_str . ')'; ?> </h4> <div> <ul> <?php $assignees = $this->get_assignees(); gravity_flow()->log_debug(__METHOD__ . '(): assignee details: ' . print_r($assignees, true)); $editable_fields = array(); foreach ($assignees as $assignee) { gravity_flow()->log_debug(__METHOD__ . '(): showing status for: ' . $assignee->get_key()); $assignee_status = $assignee->get_status(); gravity_flow()->log_debug(__METHOD__ . '(): assignee status: ' . $assignee_status); if (!empty($assignee_status)) { $assignee_type = $assignee->get_type(); $assignee_id = $assignee->get_id(); if ($assignee_type == 'user_id') { $user_info = get_user_by('id', $assignee_id); $status_label = $this->get_status_label($assignee_status); echo sprintf('<li>%s: %s (%s)</li>', esc_html__('User', 'gravityflow'), $user_info->display_name, $status_label); if ($assignee_id == $current_user->ID) { $editable_fields = $assignee->get_editable_fields(); } } elseif ($assignee_type == 'email') { $email = $assignee_id; $status_label = $this->get_status_label($assignee_status); echo sprintf('<li>%s: %s (%s)</li>', esc_html__('Email', 'gravityflow'), $email, $status_label); if ($email == rgget('gflow_access_email')) { $editable_fields = $assignee['editable_fields']; } elseif ($token = gravity_flow()->decode_access_token()) { if ($email == gravity_flow()->parse_token_assignee($token)->get_id()) { $editable_fields = $assignee->get_editable_fields(); } } } elseif ($assignee_type == 'role') { $status_label = $this->get_status_label($assignee_status); $role_name = translate_user_role($assignee_id); echo sprintf('<li>%s: (%s)</li>', esc_html__('Role', 'gravityflow'), $role_name, $status_label); echo '<li>' . $role_name . ': ' . $assignee_status . '</li>'; if (gravity_flow()->check_user_role($assignee_id, $current_user->ID)) { $editable_fields = $assignee->get_editable_fields(); } } } } ?> </ul> <div> <?php if ($token = gravity_flow()->decode_access_token()) { $assignee_key = sanitize_text_field($token['sub']); } else { $assignee_key = 'user_id|' . $current_user->ID; } $assignee = new Gravity_Flow_Assignee($assignee_key, $this); $assignee_status = $assignee->get_status(); $role_status = false; foreach (gravity_flow()->get_user_roles() as $role) { $role_status = $this->get_role_status($role); if ($role_status == 'pending') { break; } } if ($assignee_status == 'pending' || $role_status == 'pending') { $field_ids = array(); if (is_array($editable_fields)) { foreach ($editable_fields as $editable_field) { $field_ids[] = '#field_' . $form_id . '_' . str_replace('.', '_', $editable_field); } } $field_ids_str = join(', ', $field_ids); ?> <script> (function (GFFlowInput, $) { $(document).ready(function () { $('#gravityflow_update_button').prop('disabled', false); //$(<?php echo json_encode($field_ids_str); ?> ).closest('td').addClass('gravityflow-input-required'); }); }(window.GFFlowInput = window.GFFlowInput || {}, jQuery)); </script> <?php } ?> </div> <?php $can_update = $assignee_status == 'pending' || $role_status == 'pending'; if ($can_update) { $default_status = $this->default_status ? $this->default_status : 'complete'; if ($this->note_mode !== 'hidden') { $invalid_note = isset($form['workflow_note']) && is_array($form['workflow_note']) && $form['workflow_note']['failed_validation']; ?> <div> <label id="gravityflow-notes-label" for="gravityflow-note"> <?php esc_html_e('Note', 'gravityflow'); $required_indicator = $this->note_mode == 'required' ? '*' : ''; printf("<span class='gfield_required'>%s</span>", $required_indicator); ?> </label> </div> <textarea id="gravityflow-note" style="width:100%;" rows="4" class="wide" name="gravityflow_note"><?php $posted_note = rgpost('gravityflow_note'); if ($posted_note) { echo esc_html($posted_note); } ?> </textarea> <?php if ($invalid_note) { printf("<div class='gfield_description validation_message'>%s</div>", $form['workflow_note']['validation_message']); } } if ($default_status == 'hidden') { ?> <input type="hidden" id="gravityflow_status_hidden" name="gravityflow_status" value="complete" /> <?php } else { ?> <br /><br /> <div> <label for="gravityflow_in_progress"><input type="radio" id="gravityflow_in_progress" name="gravityflow_status" <?php checked($default_status, 'in_progress'); ?> value="in_progress" /><?php esc_html_e('In progress', 'gravityflow'); ?> </label> <label for="gravityflow_complete"><input type="radio" id="gravityflow_complete" name="gravityflow_status" value="complete" <?php checked($default_status, 'complete'); ?> /><?php esc_html_e('Complete', 'gravityflow'); ?> </label> </div> <?php } ?> <br /> <div style="text-align:right;"> <?php $button_text = esc_html__('Update', 'gravityflow'); $button_text = apply_filters('gravityflow_update_button_text_user_input', $button_text, $form, $this); $update_button_id = 'gravityflow_update_button'; $button_click = "jQuery('#action').val('update'); jQuery('#entry_form').submit(); return false;"; $update_button = '<input id="' . $update_button_id . '" disabled="disabled" class="button button-large button-primary" type="submit" tabindex="4" value="' . $button_text . '" name="save" onclick="' . $button_click . '"/>'; echo apply_filters('gravityflow_update_button_user_input', $update_button); ?> </div> <?php } ?> </div> <?php }
/** * Loosely based on the JWT spec. * * @param Gravity_Flow_Assignee $assignee * @param array $scopes * @param string $expiration_timestamp * * @return string */ public function generate_access_token($assignee, $scopes = array(), $expiration_timestamp = false) { if (empty($scopes)) { $scopes = array('pages' => array('inbox', 'status')); } if (empty($expiration_timestamp)) { $expiration_timestamp = strtotime('+30 days'); } $jti = uniqid(); $token_array = array('iat' => time(), 'exp' => $expiration_timestamp, 'sub' => $assignee->get_key(), 'scopes' => $scopes, 'jti' => $jti); $token = rawurlencode(base64_encode(json_encode($token_array))); $secret = get_option('gravityflow_token_secret'); if (empty($secret)) { $secret = wp_generate_password(64); update_option('gravityflow_token_secret', $secret); } $sig = hash_hmac('sha256', $token, $secret); $token .= '.' . $sig; $this->log_event('token', 'generated', 0, 0, json_encode($token_array), 0, 0, $assignee->get_id(), $assignee->get_type(), $assignee->get_display_name()); return $token; }