Newer
Older
<?php
namespace Automattic\WP\Bulk_Edit_Cron_Offload;
class Delete_All {
/**
const CRON_EVENT = 'a8c_bulk_edit_delete_all';
const ADMIN_NOTICE_KEY = 'a8c_bulk_edit_deleted_all';
*/
public static function register_hooks() {
add_action( self::CRON_EVENT, array( __CLASS__, 'process_via_cron' ) );
add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
/**
*
*/
public static function process( $vars ) {
// TODO: Add hook to hide posts when their deletion is pending
$action_scheduled = self::action_next_scheduled( self::CRON_EVENT, $vars->post_type );
if ( empty( $action_scheduled ) ) {
wp_schedule_single_event( time(), self::CRON_EVENT, array( $vars ) );
} else {
self::redirect( false );
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
/**
* Find the next scheduled instance of a given action, regardless of arguments
*
* @param string $action_to_check Hook to search for
* @param string $post_type Post type hook is scheduled for
* @return array
*/
private static function action_next_scheduled( $action_to_check, $post_type ) {
$events = get_option( 'cron' );
if ( ! is_array( $events ) ) {
return array();
}
foreach ( $events as $timestamp => $timestamp_events ) {
// Skip non-event data that Core includes in the option
if ( ! is_numeric( $timestamp ) ) {
continue;
}
foreach ( $timestamp_events as $action => $action_instances ) {
if ( $action !== $action_to_check ) {
continue;
}
foreach ( $action_instances as $instance => $instance_args ) {
$vars = array_shift( $instance_args['args'] );
if ( $post_type === $vars->post_type ) {
return array( 'timestamp' => $timestamp, 'args' => $vars, );
}
}
}
}
// No matching event found
return array();
}
/**
*
*/
public static function process_via_cron( $vars ) {
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;
}
// Take a break periodically
if ( 0 === $count++ % 50 ) {
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;
}
Erick Hitter
committed
/**
* Redirect, including a flag to indicate if the bulk process was scheduled successfully
Erick Hitter
committed
*
* @param bool $succeed Whether or not the bulk-delete was scheduled
Erick Hitter
committed
*/
public static function redirect( $succeed = false ) {
$redirect = wp_unslash( $_SERVER['REQUEST_URI'] );
// Remove arguments that could re-trigger this bulk-edit
$redirect = remove_query_arg( array( '_wp_http_referer', '_wpnonce', 'delete_all', 'delete_all2', ), $redirect );
// Add a flag for the admin notice
$redirect = add_query_arg( self::ADMIN_NOTICE_KEY, $succeed ? 1 : -1, $redirect );
wp_redirect( $redirect );
exit;
Erick Hitter
committed
}
/**
Erick Hitter
committed
*/
public static function admin_notices() {
if ( ! isset( $_REQUEST[ self::ADMIN_NOTICE_KEY ] ) ) {
return;
}
if ( 1 === (int) $_REQUEST[ self::ADMIN_NOTICE_KEY ] ) {
$class = 'notice-success';
$message = __( 'Success! The trash will be emptied soon.', 'automattic-bulk-edit-cron-offload' );
} else {
$class = 'notice-error';
$message = __( 'A request to empty the trash is already pending for this post type.', 'automattic-bulk-edit-cron-offload' );
}
?>
<div class="notice <?php echo esc_attr( $class ); ?>">
<p><?php echo esc_html( $message ); ?></p>
</div>
<?php
Erick Hitter
committed
}
Delete_All::register_hooks();