Skip to content
Snippets Groups Projects
Commit 2186ffbe authored by Erick Hitter's avatar Erick Hitter
Browse files

Rough version of "Restore from Trash"

parent b9551357
No related branches found
No related tags found
No related merge requests found
......@@ -21,3 +21,4 @@ require __DIR__ . '/includes/utils.php';
require __DIR__ . '/includes/class-main.php';
require __DIR__ . '/includes/class-delete-all.php';
require __DIR__ . '/includes/class-move-to-trash.php';
require __DIR__ . '/includes/class-restore-from-trash.php';
......@@ -151,11 +151,11 @@ class Main {
*/
public static function bulk_action_allowed( $action ) {
$allowed_actions = array(
'delete',
'delete_all',
'delete', // TODO: "Delete permantently" in Trash.
'delete_all', // class Delete_All.
'edit',
'trash',
'untrash',
'trash', // class Move_To_trash.
'untrash', // class Restore_From_Trash.
);
return in_array( $action, $allowed_actions, true );
......
<?php
/**
* Offload "Restore from Trash"
*
* @package Bulk_Edit_Cron_Offload
*/
namespace Automattic\WP\Bulk_Edit_Cron_Offload;
/**
* Class Restore_From_Trash
*/
class Restore_From_Trash {
/**
* Class constants
*/
const ACTION = 'untrash';
const ADMIN_NOTICE_KEY = 'bulk_edit_cron_offload_restore_from_trash';
/**
* Register this bulk process' hooks
*/
public static function register_hooks() {
add_action( Main::build_hook( self::ACTION ), array( __CLASS__, 'process' ) );
add_action( Main::build_cron_hook( self::ACTION ), array( __CLASS__, 'process_via_cron' ) );
add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
add_filter( 'posts_where', array( __CLASS__, 'hide_posts_pending_restore' ), 999, 2 );
}
/**
* Handle a request to restore some posts from the trash
*
* @param object $vars Bulk-request variables.
*/
public static function process( $vars ) {
$action_scheduled = Main::next_scheduled( $vars );
if ( empty( $action_scheduled ) ) {
Main::schedule_processing( $vars );
Main::do_admin_redirect( self::ADMIN_NOTICE_KEY, true );
} else {
Main::do_admin_redirect( self::ADMIN_NOTICE_KEY, false );
}
}
/**
* Cron callback to restore requested items from trash
*
* @param object $vars Bulk-request variables.
*/
public static function process_via_cron( $vars ) {
$count = 0;
if ( is_array( $vars->posts ) && ! empty( $vars->posts ) ) {
require_once ABSPATH . '/wp-admin/includes/post.php';
$restored = array();
$locked = array();
$auth_error = array();
$error = array();
foreach ( $vars->posts as $post_id ) {
// Can the user restore 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;
}
// Try restoring.
$post_restored = wp_untrash_post( $post_id );
if ( $post_restored ) {
$restored[] = $post_id;
} else {
$error[] = $post_id;
}
// Take a break periodically.
if ( 0 === $count++ % 50 ) {
stop_the_insanity();
sleep( 3 );
}
}
$results = compact( 'restored', 'locked', 'auth_error', 'error' );
do_action( 'bulk_edit_cron_offload_restore_from_trash_request_completed', $results, $vars );
} else {
do_action( 'bulk_edit_cron_offload_restore_from_trash_request_no_posts', $vars->posts, $vars );
}
}
/**
* Let the user know what's going on
*/
public static function admin_notices() {
$screen = get_current_screen();
$type = '';
$message = '';
if ( isset( $_REQUEST[ self::ADMIN_NOTICE_KEY ] ) ) {
if ( 1 === (int) $_REQUEST[ self::ADMIN_NOTICE_KEY ] ) {
$type = 'success';
$message = __( 'Success! The selected posts will be restored shortly.', 'bulk-edit-cron-offload' );
} else {
$type = 'error';
$message = __( 'The selected posts are already scheduled to be restored.', 'bulk-edit-cron-offload' );
}
} //elseif ( 'edit' === $screen->base ) {
// if ( isset( $_REQUEST['post_status'] ) && 'trash' === $_REQUEST['post_status'] ) {
// return;
// }
//
// $status = isset( $_REQUEST['post_status'] ) ? $_REQUEST['post_status'] : 'all';
//
// if ( self::get_all_pending_actions( $screen->post_type, $status ) ) {
// $type = 'warning';
// $message = __( 'Some items that would normally be shown here are waiting to be moved to the trash. These items are hidden until they are moved.', 'bulk-edit-cron-offload' );
// }
// }
Main::render_admin_notice( $type, $message );
}
/**
* When a restore is pending for a given post type, hide those posts in the admin
*
* @param string $where Posts' WHERE clause.
* @param object $q WP_Query object.
* @return string
*/
public static function hide_posts_pending_restore( $where, $q ) {
if ( ! is_admin() || ! $q->is_main_query() ) {
return $where;
}
if ( 'edit' !== get_current_screen()->base ) {
return $where;
}
if ( 'trash' !== $q->get( 'post_status' ) ) {
return $where;
}
$post__not_in = self::get_post_ids_pending_move( $q->get( 'post_type' ), $q->get( 'post_status' ) );
if ( ! empty( $post__not_in ) ) {
$post__not_in = implode( ',', $post__not_in );
$where .= ' AND ID NOT IN(' . $post__not_in . ')';
}
return $where;
}
/**
* Gather all pending events for a given post type
*
* @param string $post_type Post type needing exclusion.
* @param string $post_status Post status to filter by.
* @return array
*/
private static function get_all_pending_actions( $post_type, $post_status ) {
$events = get_option( 'cron' );
if ( ! is_array( $events ) ) {
return array();
}
$ids = 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 ( Main::CRON_EVENT !== $action ) {
continue;
}
foreach ( $action_instances as $instance => $instance_args ) {
$vars = array_shift( $instance_args['args'] );
if ( self::ACTION === $vars->action && $post_type === $vars->post_type ) {
if ( $post_status === $vars->post_status || 'all' === $vars->post_status || 'all' === $post_status ) {
$ids[] = array(
'timestamp' => $timestamp,
'args' => $vars,
);
}
}
}
}
}
return $ids;
}
/**
* Gather IDs of objects pending move to trash, with given post type
*
* @param string $post_type Post type needing exclusion.
* @param string $post_status Post status to filter by.
* @return array
*/
private static function get_post_ids_pending_move( $post_type, $post_status ) {
$events = wp_list_pluck( self::get_all_pending_actions( $post_type, $post_status ), 'args' );
$events = wp_list_pluck( $events, 'posts' );
$ids = array();
foreach ( $events as $ids_to_merge ) {
$ids = array_merge( $ids, $ids_to_merge );
}
if ( ! empty( $ids ) ) {
$ids = array_map( 'absint', $ids );
$ids = array_unique( $ids );
}
return $ids;
}
}
Restore_From_Trash::register_hooks();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment