Skip to content
Snippets Groups Projects
Commit c883389a authored by Erick Hitter's avatar Erick Hitter Committed by GitHub
Browse files

Merge pull request #6 from Automattic/add/edit-support

Add support for bulk edits
parents 9db2eaaa e7b2d374
No related branches found
No related tags found
No related merge requests found
......@@ -21,5 +21,6 @@ require __DIR__ . '/includes/utils.php';
require __DIR__ . '/includes/class-main.php';
require __DIR__ . '/includes/class-delete-all.php';
require __DIR__ . '/includes/class-delete-permanently.php';
require __DIR__ . '/includes/class-edit.php';
require __DIR__ . '/includes/class-move-to-trash.php';
require __DIR__ . '/includes/class-restore-from-trash.php';
<?php
/**
* Offload "Edit"
*
* @package Bulk_Actions_Cron_Offload
*/
namespace Automattic\WP\Bulk_Actions_Cron_Offload;
/**
* Class Edit
*/
class Edit {
/**
* Class constants
*/
const ACTION = 'edit';
const ADMIN_NOTICE_KEY = 'bulk_actions_cron_offload_edit';
/**
* 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_move' ), 999, 2 );
}
/**
* Handle a request to edit some posts
*
* @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 edit requested items
*
* @param object $vars Bulk-request variables.
*/
public static function process_via_cron( $vars ) {
// Nothing to edit.
if ( ! is_array( $vars->posts ) || empty( $vars->posts ) ) {
do_action( 'bulk_actions_cron_offload_edit_request_no_posts', $vars->posts, $vars );
return;
}
// We want to use `bulk_edit_posts()`.
require_once ABSPATH . '/wp-admin/includes/post.php';
// `bulk_edit_posts()` takes an array, normally `$_REQUEST`, so we convert back.
$request_array = get_object_vars( $vars );
unset( $request_array['action'] );
unset( $request_array['user_id'] );
// Modify some keys to match `bulk_edit_post()`'s expectations.
$request_array['post'] = $request_array['posts'];
unset( $request_array['posts'] );
if ( ! is_null( $request_array['post_sticky'] ) ) {
$request_array['sticky'] = $request_array['post_sticky'];
}
unset( $request_array['post_sticky'] );
if ( is_null( $request_array['post_status'] ) || 'all' === $request_array['post_status'] ) {
$request_array['_status'] = -1;
} else {
$request_array['_status'] = $request_array['post_status'];
}
unset( $request_array['post_status'] );
// `bulk_edit_posts()` calls `current_user_can()`, so we make sure it can.
wp_set_current_user( $vars->user_id );
// Perform bulk edit.
$results = bulk_edit_posts( $request_array );
$edited = $results['updated'];
$error = $results['skipped'];
$locked = $results['locked'];
// `bulk_edit_posts()` mixes these without indicating which it was.
$auth_error = $error;
$results = compact( 'edited', 'locked', 'auth_error', 'error' );
do_action( 'bulk_actions_cron_offload_edit_request_completed', $results, $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 edited shortly.', 'bulk-actions-cron-offload' );
} else {
$type = 'error';
$message = __( 'The requested edits are already pending for the chosen posts.', 'bulk-actions-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';
$pending = Main::get_post_ids_for_pending_events( self::ACTION, $screen->post_type, $status );
if ( ! empty( $pending ) ) {
$type = 'warning';
$message = __( 'Some items that would normally be shown here are waiting to be edited. These items are hidden until they are processed.', 'bulk-actions-cron-offload' );
}
}
Main::render_admin_notice( $type, $message );
}
/**
* When an edit 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_move( $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 = Main::get_post_ids_for_pending_events( self::ACTION, $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;
}
}
Edit::register_hooks();
......@@ -87,7 +87,8 @@ class Main {
* Capture relevant variables
*/
private static function capture_vars() {
$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 );
$vars = array_merge( array( 'action', 'user_id' ), self::get_supported_vars() );
$vars = (object) array_fill_keys( $vars, null );
$vars->user_id = get_current_user_id();
......@@ -111,6 +112,10 @@ class Main {
$vars->tax_input = $_REQUEST['tax_input'];
}
if ( isset( $_REQUEST['post_category'] ) && is_array( $_REQUEST['post_category'] ) ) {
$vars->post_category = $_REQUEST['post_category'];
}
if ( isset( $_REQUEST['post_author'] ) && -1 !== (int) $_REQUEST['post_author'] ) {
$vars->post_author = (int) $_REQUEST['post_author'];
}
......@@ -135,14 +140,55 @@ class Main {
$vars->post_format = $_REQUEST['post_format'];
}
if ( isset( $_REQUEST['post_parent'] ) && '-1' !== $_REQUEST['post_parent'] ) {
$vars->post_parent = (int) $_REQUEST['post_parent'];
}
if ( isset( $_REQUEST['page_template'] ) && '-1' !== $_REQUEST['page_template'] ) {
$vars->page_template = $_REQUEST['page_template'];
}
if ( isset( $_REQUEST['post_password'] ) && ! empty( $_REQUEST['post_password'] ) ) {
$vars->post_password = $_REQUEST['post_password'];
}
// Post status is special.
if ( is_null( $vars->post_status ) && isset( $_REQUEST['post_status'] ) && ! empty( $_REQUEST['post_status'] ) ) {
$vars->post_status = $_REQUEST['post_status'];
}
// Another special case, dependent on post status.
if ( isset( $_REQUEST['keep_private'] ) && 'private' === $vars->post_status ) {
$vars->keep_private = true;
}
return $vars;
}
/**
* List allowed $_REQUEST variables
*
* @return array
*/
private static function get_supported_vars() {
return array(
'comment_status',
'keep_private',
'page_template',
'ping_status',
'post_author',
'post_category',
'post_format',
'post_parent',
'post_password',
'post_status',
'post_sticky',
'post_type',
'posts',
'tax_input',
);
}
/**
* Validate action
*
......@@ -153,7 +199,7 @@ class Main {
$allowed_actions = array(
'delete', // class Delete_Permanently.
'delete_all', // class Delete_All.
'edit',
'edit', // class Edit.
'trash', // class Move_To_Trash.
'untrash', // class Restore_From_Trash.
);
......
......@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: Bulk Actions Cron Offload 1.0\n"
"Report-Msgid-Bugs-To: "
"https://wordpress.org/support/plugin/bulk-actions-cron-offload\n"
"POT-Creation-Date: 2017-09-14 18:55:07+00:00\n"
"POT-Creation-Date: 2017-09-14 22:18:30+00:00\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
......@@ -51,6 +51,20 @@ msgid ""
"permanently. These items are hidden until then."
msgstr ""
#: includes/class-edit.php:112
msgid "Success! The selected posts will be edited shortly."
msgstr ""
#: includes/class-edit.php:115
msgid "The requested edits are already pending for the chosen posts."
msgstr ""
#: includes/class-edit.php:127
msgid ""
"Some items that would normally be shown here are waiting to be edited. "
"These items are hidden until they are processed."
msgstr ""
#: includes/class-move-to-trash.php:111
msgid "Success! The selected posts will be moved to the trash shortly."
msgstr ""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment