1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279:
<?php
/**
* Gravity Flow API
*
* @package GravityFlow
* @subpackage Classes/API
* @copyright Copyright (c) 2015-2018, Steven Henty S.L.
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public Licenses
* @since 1.0
*/
if ( ! class_exists( 'GFForms' ) ) {
die();
}
/**
* The future-proof way to interact with the high level functions in Gravity Flow.
*
* Class Gravity_Flow_API
*
* @since 1.0
*/
class Gravity_Flow_API {
/**
* The ID of the Form to be used throughout the Gravity Flow API.
*
* @var int
*/
public $form_id = null;
/**
* The constructor for the API. Requires a Form ID.
*
* @param int $form_id The current form ID.
*/
public function __construct( $form_id ) {
$this->form_id = $form_id;
}
/**
* Adds a Workflow step to the form with the given settings. The following settings are required:
* - step_name (string)
* - step_type (string)
* - description (string)
*
* @param array $step_settings The step settings (aka feed meta).
*
* @return mixed
*/
public function add_step( $step_settings ) {
return GFAPI::add_feed( $this->form_id, $step_settings, 'gravityflow' );
}
/**
* Returns the step with the given step ID. Optionally pass an Entry object to perform entry-specific functions.
*
* @param int $step_id The current step ID.
* @param null|array $entry The current entry.
*
* @return Gravity_Flow_Step|bool Returns the Step. False if not found.
*/
public function get_step( $step_id, $entry = null ) {
return gravity_flow()->get_step( $step_id, $entry );
}
/**
* Returns all the steps for current form.
*
* @return Gravity_Flow_Step[]
*/
public function get_steps() {
return gravity_flow()->get_steps( $this->form_id );
}
/**
* Returns the current step for the given entry.
*
* @param array $entry The current entry.
*
* @return Gravity_Flow_Step|bool
*/
public function get_current_step( $entry ) {
$form = GFAPI::get_form( $this->form_id );
return gravity_flow()->get_current_step( $form, $entry );
}
/**
* Processes the workflow for the given Entry ID. Handles the step orchestration - moving the workflow through the steps and ending the workflow.
* Not generally required unless there's been a change to the entry outside the usual workflow orchestration.
*
* @param int $entry_id The ID of the current entry.
*/
public function process_workflow( $entry_id ) {
$form = GFAPI::get_form( $this->form_id );
gravity_flow()->process_workflow( $form, $entry_id );
}
/**
* Cancels the workflow for the given Entry ID. Removes the assignees, adds a note in the entry's timeline and logs the event.
*
* @param array $entry The current entry.
*
* @return bool True for success. False if not currently in a workflow.
*/
public function cancel_workflow( $entry ) {
$entry_id = absint( $entry['id'] );
$form = GFAPI::get_form( $this->form_id );
$step = $this->get_current_step( $entry );
if ( ! $step ) {
return false;
}
/**
* Fires before a workflow is cancelled.
*
* @param array $entry The current entry.
* @param array $form The current form.
* @param Gravity_Flow_Step $step The current step object.
*/
do_action( 'gravityflow_pre_cancel_workflow', $entry, $form, $step );
$step->purge_assignees();
gform_update_meta( $entry_id, 'workflow_final_status', 'cancelled' );
gform_delete_meta( $entry_id, 'workflow_step' );
$feedback = esc_html__( 'Workflow cancelled.', 'gravityflow' );
gravity_flow()->add_timeline_note( $entry_id, $feedback );
gravity_flow()->log_event( 'workflow', 'cancelled', $form['id'], $entry_id );
GFAPI::send_notifications( $form, $entry, 'workflow_cancelled' );
return true;
}
/**
* Restarts the current step for the given entry, adds a note in the entry's timeline and logs the activity.
*
* @param array $entry The current entry.
*
* @return bool True for success. False if the entry doesn't have a current step.
*/
public function restart_step( $entry ) {
$step = $this->get_current_step( $entry );
if ( ! $step ) {
return false;
}
$entry_id = $entry['id'];
$this->log_activity( 'step', 'restarted', $this->form_id, $entry_id );
$step->purge_assignees();
$step->restart_action();
$step->start();
$feedback = esc_html__( 'Workflow Step restarted.', 'gravityflow' );
$this->add_timeline_note( $entry_id, $feedback );
return true;
}
/**
* Restarts the workflow for an entry, adds a note in the entry's timeline and logs the activity.
*
* @param array $entry The current entry.
*/
public function restart_workflow( $entry ) {
$current_step = $this->get_current_step( $entry );
$entry_id = absint( $entry['id'] );
$form = GFAPI::get_form( $this->form_id );
/**
* Fires just before the workflow restarts for an entry.
*
* @since 1.4.3
*
* @param array $entry The current entry.
* @param array $form The current form.
*/
do_action( 'gravityflow_pre_restart_workflow', $entry, $form );
if ( $current_step ) {
$current_step->purge_assignees();
}
$steps = $this->get_steps();
foreach ( $steps as $step ) {
// Create a step based on the entry and use it to reset the status.
$step_for_entry = $this->get_step( $step->get_id(), $entry );
$step_for_entry->update_step_status( 'pending' );
$step_for_entry->restart_action();
}
$feedback = esc_html__( 'Workflow restarted.', 'gravityflow' );
$this->add_timeline_note( $entry_id, $feedback );
gform_update_meta( $entry_id, 'workflow_final_status', 'pending' );
gform_update_meta( $entry_id, 'workflow_step', false );
$this->log_activity( 'workflow', 'restarted', $form['id'], $entry_id );
$this->process_workflow( $entry_id );
}
/**
* Returns the workflow status for the current entry.
*
* @param array $entry The current entry.
*
* @return string|bool The status.
*/
public function get_status( $entry ) {
$current_step = $this->get_current_step( $entry );
if ( false === $current_step ) {
$status = gform_get_meta( $entry['id'], 'workflow_final_status' );
} else {
$status = $current_step->evaluate_status();
}
return $status;
}
/**
* Sends an entry to the specified step.
*
* @param array $entry The current entry.
* @param int $step_id The ID of the step the entry is to be sent to.
*/
public function send_to_step( $entry, $step_id ) {
$current_step = $this->get_current_step( $entry );
if ( $current_step ) {
$current_step->purge_assignees();
$current_step->update_step_status( 'cancelled' );
}
$entry_id = $entry['id'];
$new_step = $this->get_step( $step_id, $entry );
$feedback = sprintf( esc_html__( 'Sent to step: %s', 'gravityflow' ), $new_step->get_name() );
$this->add_timeline_note( $entry_id, $feedback );
$this->log_activity( 'workflow', 'sent_to_step', $this->form_id, $entry_id, $step_id );
gform_update_meta( $entry_id, 'workflow_final_status', 'pending' );
$new_step->start();
$this->process_workflow( $entry_id );
}
/**
* Add a note to the timeline of the specified entry.
*
* @param int $entry_id The ID of the current entry.
* @param string $note The note to be added to the timeline.
*/
public function add_timeline_note( $entry_id, $note ) {
gravity_flow()->add_timeline_note( $entry_id, $note );
}
/**
* Registers activity event in the activity log. The activity log is used to generate reports.
*
* @param string $log_type The object of the event: 'workflow', 'step', 'assignee'.
* @param string $event The event which occurred: 'started', 'ended', 'status'.
* @param int $form_id The form ID.
* @param int $entry_id The Entry ID.
* @param string $log_value The value to log.
* @param int $step_id The Step ID.
* @param int $duration The duration in seconds - if applicable.
* @param int $assignee_id The assignee ID - if applicable.
* @param string $assignee_type The Assignee type - if applicable.
* @param string $display_name The display name of the User.
*/
public function log_activity( $log_type, $event, $form_id = 0, $entry_id = 0, $log_value = '', $step_id = 0, $duration = 0, $assignee_id = 0, $assignee_type = '', $display_name = '' ) {
gravity_flow()->log_event( $log_type, $event, $form_id, $entry_id, $log_value, $step_id, $duration, $assignee_id, $assignee_type, $display_name );
}
/**
* Returns the timeline for the specified entry with simple formatting.
*
* @param array $entry The current entry.
*
* @return string
*/
public function get_timeline( $entry ) {
return gravity_flow()->get_timeline( $entry );
}
}