Last active
April 29, 2020 18:17
-
-
Save zecka/def5c2e01c353aaa4cf41bcc37fb0946 to your computer and use it in GitHub Desktop.
Make Bulk taks tool in WordPress admin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
USAGE: | |
$task = new WP_Bulk_Task('test-bulk-task', 'product'); | |
$task->set_callback(function($post){ | |
error_log($post->ID); | |
}); | |
$task->set_posts_per_page(1); | |
$task->register(); | |
*/ | |
class WP_Bulk_Task { | |
public $posts_per_page; | |
public function __construct($slug, $post_type, $title=null) { | |
$this->slug = $slug; | |
$this->title = ($title!==null) ? $title : $slug; | |
$this->post_type = $post_type; | |
$this->posts_per_page = 10; | |
$this->capabilities = 'install_plugins'; | |
$this->position = 10; | |
$this->nonce = 'wp-bulk-task'; | |
$this->btn_label = "Run bulk task"; | |
$this->need_confirmation = true; | |
$this->confirmation_message = "Are you sure ?"; | |
} | |
public function set_posts_per_page($posts_per_page) { | |
$this->posts_per_page = $posts_per_page; | |
} | |
public function register() { | |
add_action('admin_init', [$this, 'set_nonce']); | |
add_action('admin_menu', array($this, 'admin_menu')); | |
add_action('wp_ajax_' . $this->slug, [$this, 'ajax_action']); // executed when logged in | |
add_action('wp_ajax_nopriv_' . $this->slug, [$this, 'ajax_action_nopriv']); // executed when logged out | |
} | |
public function set_btn_label($label){ | |
$this->btn_label = $label; | |
} | |
public function set_confirmation($is_needed, $message=null){ | |
if($message!==null){ | |
$this->confirmation_message = $message; | |
} | |
$this->need_confirmation = $is_needed; | |
} | |
public function set_nonce() { | |
$this->nonce = wp_create_nonce($this->slug); | |
} | |
public function ajax_action_nopriv() { | |
return wp_send_json_error(['message' => 'must be logged']); | |
} | |
public function loop_args() { | |
$paged = ($_POST['paged']) ? $_POST['paged'] : 1; | |
$args = [ | |
'post_type' => $this->post_type, | |
'posts_per_page' => $this->posts_per_page, | |
'paged' => $paged, | |
]; | |
$args = apply_filters('wpbt_loops_args', $args); | |
return apply_filters('wpbt_loops_args_'.$this->slug, $args); | |
} | |
public function ajax_action() { | |
$this->validate_ajax_action(); | |
$paged = ($_POST['paged']) ? $_POST['paged'] : 1; | |
$query = new WP_Query($this->loop_args()); | |
$max_num_pages = $query->max_num_pages; | |
$logs = []; | |
if ($query->have_posts()) { | |
while ($query->have_posts()) { | |
$query->the_post(); | |
global $post; | |
$new_logs = call_user_func($this->callback, $post); | |
if (is_array($new_logs)) { | |
$logs = array_merge($logs, $new_logs); | |
} elseif ($new_logs) { | |
$logs = array_merge($logs, [$new_logs]); | |
} | |
} | |
} | |
wp_send_json_success([ | |
'max_num_pages' => $max_num_pages, | |
'paged' => (int)$paged, | |
'logs' => $logs, | |
]); | |
} | |
public function set_callback($callback) { | |
$this->callback = $callback; | |
} | |
public function admin_menu() { | |
$hook = add_management_page( | |
$this->title, | |
$this->title, | |
$this->capabilities, | |
$this->slug, | |
[$this, 'admin_page_content'], | |
$this->position | |
); | |
add_action("load-$hook", array($this, 'admin_page_load')); | |
} | |
public function admin_page_load() { | |
// ... | |
} | |
public function admin_page_content() { | |
$this->admin_page_style(); | |
$this->admin_page_script(); | |
?> | |
<div class="wrap"> | |
<h1><?php echo $this->title ?></h1> | |
<div style="margin-bottom: 20px;"><?php do_action('wpbt_before_content', $this->slug); ?></div> | |
<button id="wpbt-runner" class="button"><?php echo $this->btn_label; ?></button> | |
<div><?php do_action('wpbt_after_button', $this->slug); ?></div> | |
<div class="wpbt-progress__percent">0%</div> | |
<div class="wpbt-progress"> | |
<div class="wpbt-progress__bar" style="width: 0%;"></div> | |
</div> | |
<div class="wpbt-logs"></div> | |
<?php do_action('wpbt_after_content', $this->slug); ?> | |
</div> | |
<?php | |
} | |
public function admin_page_script() { | |
?> | |
<script> | |
jQuery(document).ready(function($){ | |
var wpbtCount = 0; | |
function setPercentage(current, max){ | |
var percent = Math.round(current / max * 100); | |
$('.wpbt-progress__percent').html(percent+'%'); | |
$('.wpbt-progress__bar').css( "width",percent+ "%" ); | |
} | |
function putLogs(logs, currentPage){ | |
for(var i = 0; i < logs.length; i++ ){ | |
wpbtCount++; | |
$('.wpbt-logs').prepend('<div><strong>'+wpbtCount+'</strong> | '+logs[i]+'</div>'); | |
} | |
} | |
function doBulkTask(paged) { | |
var data = { | |
action: "<?php echo $this->slug; ?>", | |
nonce: "<?php echo $this->nonce; ?>", | |
paged: paged | |
}; | |
$.ajax({ | |
type: "post", | |
url: "<?php echo admin_url('admin-ajax.php') ?>", | |
data: data, | |
error: (response, error) => { | |
console.error("response", response); | |
console.error("error", error); | |
}, | |
success: response => { | |
var max_num_pages = response.data.max_num_pages; | |
var currentPage = response.data.paged; | |
if (max_num_pages > currentPage) { | |
setPercentage(currentPage, max_num_pages); | |
currentPage++; | |
doBulkTask(currentPage) | |
} else { | |
setPercentage(currentPage, max_num_pages); | |
} | |
putLogs(response.data.logs, currentPage); | |
} | |
}); | |
} | |
$('#wpbt-runner').on('click', function(){ | |
<?php if($this->need_confirmation): ?> | |
var confrimation = confirm("<?php echo $this->confirmation_message; ?>"); | |
if(!confrimation){ | |
return false; | |
} | |
<?php endif; ?> | |
$(this).prop('disabled', true); | |
doBulkTask(1) | |
}); | |
}); | |
</script> | |
<?php | |
} | |
public function admin_page_style() { | |
?> | |
<style> | |
.wpbt-progress{ | |
margin-top: 20px; | |
width: 100%; | |
height: 40px; | |
border-radius: 10px; | |
background: white; | |
border: 1px solid -internal-root-color; | |
display: flex; | |
overflow: hidden; | |
} | |
.wpbt-progress__bar{ | |
background-color: blue; | |
} | |
.wpbt-progress__percent{ | |
text-align: center; | |
} | |
.wpbt-logs{ | |
background: white; | |
max-height: 400px; | |
overflow-y: auto; | |
} | |
.wpbt-logs > div{ | |
padding: 5px; | |
} | |
</style> | |
<?php | |
} | |
private function validate_ajax_action(){ | |
if ( !wp_verify_nonce($_POST['nonce'], $this->slug)) { | |
wp_send_json_error(['message' => 'Invalid Ajax Action']); | |
die(); | |
} | |
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { | |
return true; | |
} else { | |
wp_send_json_error(['message' => 'Invalid Ajax Action']); | |
die(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment