Skip to content

Instantly share code, notes, and snippets.

@mlbd
Created September 3, 2025 21:34
Show Gist options
  • Save mlbd/29a0d2f9b38d539d25cf2e8eea423f5f to your computer and use it in GitHub Desktop.
Save mlbd/29a0d2f9b38d539d25cf2e8eea423f5f to your computer and use it in GitHub Desktop.
Automatically reject the task for all assignees if any one assignee rejects or disapproves it.
add_filter('owf_review_step_total_reviews', function ($total_reviews, $review_setting, $action_history_id, $step_id) {
global $wpdb;
/**
* NEW: For steps requiring "everyone" to approve, if ANY reviewer has rejected (unable),
* auto-reject all remaining "assignment" reviews immediately so the failure branch proceeds now.
* We also persist these changes so inbox/reminders are cleaned up.
*/
if ( ! empty( $total_reviews ) ) {
if ( $review_setting === 'everyone' ) {
$action_table = OW_Utility::instance()->get_action_table_name();
$formated_total_reviews = $total_reviews;
// 1) Find the first rejector (unable) row, if any.
$reject_row = null;
foreach ( $total_reviews as $r ) {
if ( isset( $r->review_status ) && $r->review_status === 'unable' ) {
$reject_row = $r;
break;
}
}
// 2) If we have a rejector and there are still pending assignments, flip them to unable.
if ( $reject_row ) {
$rejector_user = get_userdata( intval( $reject_row->actor_id ) );
$rejector_name = $rejector_user ? $rejector_user->display_name : __( 'another reviewer', 'oasisworkflow' );
$now_time = current_time( 'mysql' );
$ow_email_local = new OW_Email();
foreach ( $total_reviews as $id => $r ) {
if ( isset( $r->review_status ) && $r->review_status === 'assignment' ) {
// Build/append auto-comment (JSON shape you requested).
$existing = array();
if ( ! empty( $r->comments ) ) {
$decoded = json_decode( $r->comments, true );
if ( is_array( $decoded ) ) {
$existing = $decoded;
}
}
$existing[] = array(
'send_id' => intval( $r->actor_id ), // as per your example
'comment' => sprintf( __( 'Auto-rejected: another reviewer (%s) rejected this step.', 'oasisworkflow' ), $rejector_name ),
'comment_timestamp' => $now_time,
);
$new_comments_json = wp_json_encode( $existing );
$formated_total_reviews[ $id ]->review_status = 'unable';
$formated_total_reviews[ $id ]->comments = $new_comments_json;
$formated_total_reviews[ $id ]->step_id = $new_comments_json;
// Clone critical fields from the rejector row to align failure path.
$new_step_id = isset( $reject_row->step_id ) ? $reject_row->step_id : $r->step_id;
$new_next_assign_json = isset( $reject_row->next_assign_actors ) ? $reject_row->next_assign_actors : $r->next_assign_actors;
$new_due_date = isset( $reject_row->due_date ) ? $reject_row->due_date : $r->due_date;
// Clone critical fields from the rejector row to align failure path.
$formated_total_reviews[ $id ]->step_id = $new_step_id;
$formated_total_reviews[ $id ]->next_assign_actors = $new_next_assign_json;
$formated_total_reviews[ $id ]->due_date = $new_due_date;
// Update the row.
$wpdb->update( $action_table, (array) $formated_total_reviews[ $id ], array(
"actor_id" => $formated_total_reviews[ $id ]->actor_id,
"action_history_id" => $formated_total_reviews[ $id ]->action_history_id
) );
// Clear reminder emails for this user on this action.
$ow_email_local->delete_step_email( intval( $r->action_history_id ), intval( $r->actor_id ) );
}
}
// No return here; let the normal tally/decision logic proceed now that no "assignment" remains.
}
$total_reviews = $formated_total_reviews;
error_log( "total_reviews (adjusted): " . print_r( $total_reviews, true ) );
}
}
return $total_reviews;
}, 10, 4); // priority 10, and 4 args
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment