From b32d44fe3d3e4dbf64e7fe4420ca83d6c534022e Mon Sep 17 00:00:00 2001
From: Erick Hitter <services@ethitter.com>
Date: Tue, 28 Feb 2017 16:58:01 -0800
Subject: [PATCH] Basic interception and offloading of "Empty Trash" to cron

No user feedback, poor nonce checks, etc.
---
 includes/class-delete-all.php | 78 ++++++++++++++++++++++++++++++++++-
 includes/class-main.php       |  8 +++-
 2 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/includes/class-delete-all.php b/includes/class-delete-all.php
index 128dda2..6b70408 100644
--- a/includes/class-delete-all.php
+++ b/includes/class-delete-all.php
@@ -6,12 +6,86 @@ class Delete_All {
 	/**
 	 *
 	 */
-	private static $vars = null;
+	const CRON_EVENT = 'a8c_bulk_edit_delete_all';
+
+	/**
+	 *
+	 */
+	public static function register_hooks() {
+		add_action( self::CRON_EVENT, array( __CLASS__, 'process_via_cron' ) );
+	}
 
 	/**
 	 *
 	 */
 	public static function process( $vars ) {
-		self::$vars = $vars;
+		// Queue job
+		// Filter redirect
+		// Register admin notices
+		// Add hook to hide posts when their deletion is pending
+
+		// TODO: Insufficient, need to check regardless of args :(
+		$existing_event_ts = wp_next_scheduled( self::CRON_EVENT, array( $vars ) );
+
+		if ( $existing_event_ts ) {
+			// TODO: Notice that event already scheduled
+		} else {
+			wp_schedule_single_event( time(), self::CRON_EVENT, array( $vars ) );
+
+			// TODO: Notice that event scheduled
+		}
+	}
+
+	/**
+	 *
+	 */
+	public static function process_via_cron( $vars ) {
+		// Get posts by type and status
+		// Loop, check perms, delete
+		// What to do about those that fail?
+
+		global $wpdb;
+
+		$post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = %s AND post_status = %s", $vars->post_type, $vars->post_status ) );
+
+		if ( is_array( $post_ids ) && ! empty( $post_ids ) ) {
+			require_once ABSPATH . '/wp-admin/includes/post.php';
+
+			$deleted = $locked = $auth_error = $error = array();
+
+			foreach ( $post_ids as $post_id ) {
+				// Can the user delete this post
+
+				if ( ! user_can( $vars->user_id, 'delete_post', $post_id ) ) {
+					$auth_error[] = $post_id;
+					continue;
+				}
+
+				// Post is locked by someone, so leave it alone
+				if ( false !== wp_check_post_lock( $post_id ) ) {
+					$locked[] = $post_id;
+					continue;
+				}
+
+				//
+				$post_deleted = wp_delete_post( $post_id );
+				if ( $post_deleted ) {
+					$deleted[] = $post_id;
+				} else {
+					$error[] = $post_id;
+				}
+
+				// TODO: stop_the_insanity()
+			}
+
+			// TODO: something meaningful with this data
+			$results = compact( 'deleted', 'locked', 'auth_error', 'error' );
+			return $results;
+		} else {
+			// TODO: What to do here?
+			return false;
+		}
 	}
 }
+
+Delete_All::register_hooks();
diff --git a/includes/class-main.php b/includes/class-main.php
index ca074f9..c1a3e68 100644
--- a/includes/class-main.php
+++ b/includes/class-main.php
@@ -51,10 +51,16 @@ class Main {
 	 * Capture relevant variables
 	 */
 	private static function capture_vars() {
-		$vars = new \stdClass();
+		$vars = (object) array_fill_keys( array( 'user_id', 'action', 'post_type', 'posts', 'tax_input', 'post_author', 'comment_status', 'ping_status', 'post_status', 'post_sticky', 'post_format', ), null );
+
+		// TODO: replace with foreach and switch
+
+		$vars->user_id = get_current_user_id();
 
 		if ( isset( $_REQUEST['delete_all'] ) ) {
 			$vars->action = 'delete_all';
+
+			$vars->post_status = $_REQUEST['post_status'];
 		} elseif ( isset( $_REQUEST['action'] ) && -1 !== (int) $_REQUEST['action'] ) {
 			$vars->action = (int) $_REQUEST['action'];
 		} elseif ( isset( $_REQUEST['action2'] ) && -1 !== (int) $_REQUEST['action2'] ) {
-- 
GitLab