/**
  * @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;
 }
예제 #2
0
 /**
  * @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());
 }
예제 #3
0
 /**
  * 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>&nbsp;&nbsp;
						<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;
 }