I’ve been working with the wp_list_table class and creating my custom theme pages with add/edit/delete features on the row options. The problem i am having is with the bulk actions. The row actions are working just fine. Now here is where it gets weird.
If I am looking at my table in admin and I select the checkbox on a few rows, switch to bulk-delete action, then hit apply, I will not get any post data for those checkboxes. What I mean by that is the checkboxes are named as an array bulk-delete[] in html. and if I do a print_r($_request); the bulk-delete key is no present.
Now when I select a few checkboxes, and this time NOT switch to bulk-delete I just leave it saying “Bulk Actions”, then hit apply, I will get the bulk-delete array but all the keys are empty.
For me totally freaking bazaar. But I am sure there is something really stupid that I missed. So here is the class in it’s entirety. Please let me know what I missed.
[a secondary issue – I’d like to also show an “Country has been added” success message. Could you guys point me in the right direction for knowledge to read up on that]
Thanks in advance.
<?php
class country_class {
var $page_name = "lp-manage-countries";
public function __construct(){
//make sure the wp_list_table class has been loaded
if (!class_exists('WP_List_Table')) {
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
}
add_action( 'admin_post_add_country', array( $this, 'lp_admin_add_country') );
add_filter('set-screen-option', array( $this, 'lp_save_screen_options') , 10, 3);
//add_action( 'admin_post_bulk_action', array( $this, 'process_bulk_action') );
}
/**
* Sets the screen options up for table paging
*/
public function lp_screen_options() {
$lp_manage_countries_page = "toplevel_page_" . $this->page_name;
$screen = get_current_screen();
// get out of here if we are not on our settings page
if(!is_object($screen) || $screen->id != $lp_manage_countries_page)
return;
$args = array(
'label' => __('Countries per page'),
'default' => 25,
'option' => 'countries_per_page'
);
add_screen_option( 'per_page', $args );
}
/**
* Saves the screen option to the object class
*/
function lp_save_screen_options($status, $option, $value) {
if ( 'countries_per_page' == $option ) return $value;
return $status;
}
/**
* Installs the page and screen options
*/
public function install_countries_page(){
//Add the screen options first
add_action("load-toplevel_page_" . $this->page_name, array( $this, "lp_screen_options") );
add_menu_page('LP Countries', 'LP Countries', 'manage_options', 'lp-manage-countries', array($this, 'show_country_page'));
}
public function lp_admin_add_country(){
global $wpdb;
if( isset( $_REQUEST['country_name'] ) and !empty( $_REQUEST['country_name'] )){
$result = $wpdb->insert(
'countries',
array(
'name' => $_REQUEST['country_name']
)
);
if( $result !== false ){
wp_redirect(admin_url("admin.php?page=" . $this->page_name) );
exit;
}
}
}
/**
* Displays the page data
*/
public function show_country_page(){
if( isset( $_GET['action']) && ( $_REQUEST['action'] == "add" || $_REQUEST['action'] == "edit" )){
echo "<div class='wrap'>
<h1>Add Country</h1>
<form action='" . admin_url("admin-post.php", "http") . "' method='post'>
<input type="hidden" name="action" value="add_country">
<table class="form-table">
<tbody>
<tr>
<th scope="row"><label for='country_name' xmlns="http://www.w3.org/1999/html">Country Name:</label></th>
<td><input id='country_name' required class='regular-text type='text' value='' name='country_name'></input></td>
</tr>
</tbody>
</table>
<p class='submit'>
<input id='submit' class='button button-primary' type='submit' value='Save Country' name='submit'></input>
</p>
</form>";
} else {
echo "<div class="wrap">
<h1>Manage Countries<a class="page-title-action" href="".admin_url("admin.php?page=".$this->page_name."&action=add")."">Add New</a></h1>
<form method='post'>";
//echo "<input type="hidden" name="action" value="bulk_action">";
//Prepare Table of elements
$categories_list_table = new category_list_table();
$categories_list_table->prepare_items();
//Table of elements
$categories_list_table->display();
echo "</form>";
}
}
/**
* Creates the database for this page
*/
public function create_countries_table(){
global $wpdb;
$charset = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS `countries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`parent_id` int(11) DEFAULT NULL,
`image` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) $charset; ";
$wpdb->query( $sql );
}
/**
* removes the page database when uninstalled
*/
public function drop_countries_table(){
global $wpdb;
$sql = "DROP TABLE `countries`;";
$wpdb->query($sql);
}
}
class category_list_table extends WP_List_Table {
public function __construct(){
parent::__construct( array(
'singular' => 'Country',
'plural' => 'Countries',
'ajax' => false)
);
}
public function get_columns(){
return $columns = array(
'cb' => '<input name="bulk-delete[]" type="checkbox" />',
'name' => __('Name'),
'parent_id' => __('Parent ID'),
'image' => __('Image')
);
}
function column_name($item) {
// create a nonce
$delete_nonce = wp_create_nonce( 'lp_delete_country' );
$edit_nonce = wp_create_nonce( 'lp_delete_country' );
$actions = array(
'edit' => sprintf('<a href="?page=%s&action=%s&country=%s&_wpnonce=%s">Edit</a>', $_REQUEST['page'], 'edit', $item['id'], $edit_nonce),
'delete' => sprintf('<a href="?page=%s&action=%s&country=%s&_wpnonce=%s">Delete</a>', $_REQUEST['page'], 'delete', $item['id'], $delete_nonce),
);
return sprintf('%1$s %2$s', $item['name'], $this->row_actions($actions) );
}
public function get_sortable_columns(){
return $sortable = array(
'id' => array('id',false),
'name' => array('name',false),
'parent_id' => array('parent_id', false),
'image' => array('image', false)
);
}
public function get_hidden_columns( ){
$screen = get_current_screen();
if ( is_string( $screen ) )
$screen = convert_to_screen( $screen );
return (array) get_user_option( 'manage' . $screen->id . 'columnshidden' );
}
public function prepare_items(){
global $wpdb, $_wp_column_headers;
$screen = get_current_screen();
/** Process bulk action */
$this->process_bulk_action();
/* Prepare the query */
$query = "SELECT * FROM `countries`";
/* Order Parameters */
$orderby = !empty($_GET["orderby"]) ? mysql_real_escape_string($_GET["orderby"]) : 'ASC';
$order = !empty($_GET["order"]) ? mysql_real_escape_string($_GET["order"]) : '';
if(!empty($orderby) & !empty($order)){ $query.=' ORDER BY '.$orderby.' '.$order; }
/* Pagination Params */
//Number of elements in your table?
$totalitems = $wpdb->query($query); //return the total number of affected rows
//How many to display per page?
$perpage = get_user_meta( get_current_user_id() , 'countries_per_page', true);
if( empty($perpage)){
$perpage = 25;
}
//Which page is this?
$paged = !empty($_GET["paged"]) ? mysql_real_escape_string($_GET["paged"]) : '';
//Page Number
if(empty($paged) || !is_numeric($paged) || $paged<=0 ){ $paged=1; }
//How many pages do we have in total?
$totalpages = ceil($totalitems/$perpage);
//adjust the query to take pagination into account
if(!empty($paged) && !empty($perpage)){
$offset=($paged-1)*$perpage;
$query.=' LIMIT '.(int)$offset.','.(int)$perpage;
}
/* Register pagination */
$this->set_pagination_args( array(
"total_items" => $totalitems,
"total_pages" => $totalpages,
"per_page" => $perpage
)
);
/* register the columns */
$columns = $this->get_columns();
$_wp_column_headers[$screen->id]=$columns;
/* Get the items */
$this->items = $wpdb->get_results($query, 'ARRAY_A');
$hidden_columns = $this->get_hidden_columns();
$sortable_columns = $this->get_sortable_columns();
parent::get_column_info();
$this->_column_headers = array( $columns, $hidden_columns, $sortable_columns);
}
public function column_default($item, $column_name) {
//return $item[$column_name];
switch ( $column_name ) {
case 'cb':
case 'name':
case 'parent_id':
case 'image':
return $item[ $column_name ];
default:
return $item[ $column_name ];
}
}
function no_items() {
_e( 'No Countries Found.' );
}
function column_cb( $item ) {
return sprintf(
'<input type="checkbox" name="bulk-delete[]" value="%s" />', $item['ID']
);
}
public function get_bulk_actions() {
$actions = [
'bulk-delete' => 'Delete'
];
return $actions;
}
public function process_bulk_action() {
$action = $this->current_action();
echo "action is [" . $action . "]";
if( !empty( $action ) ){
switch ($action){
case 'delete':
// In our file that handles the request, verify the nonce.
$nonce = esc_attr( $_REQUEST['_wpnonce'] );
if ( ! wp_verify_nonce( $nonce, 'lp_delete_country' ) ) {
die( 'Go get a life script kiddies' );
} else {
echo " running delete";
self::delete_country( absint( $_GET['country'] ) );
wp_redirect( esc_url( add_query_arg() ) );
exit;
}
case 'edit':
echo "we should be editing";
case 'bulk-delete':
// If the delete bulk action is triggered
echo "we triggered a bulk delete";
echo "<pre>";
print_r( $_REQUEST );
echo "</pre>";
if ( !empty( $_POST['bulk-delete'] ) ) {
$delete_ids = esc_sql( $_POST['bulk-delete'] );
// loop over the array of record IDs and delete them
foreach ( $delete_ids as $id ) {
$this->delete_country( $id );
}
wp_redirect( esc_url( add_query_arg() ) );
exit;
} else {
echo "Fucking empty";
}
default:
echo "<pre>";
print_r( $_REQUEST );
echo "</pre>";
//quietly exit;
}
} else {
echo "<pre>";
print_r( $_REQUEST );
echo "</pre>";
}
}
function delete_country( $id ) {
global $wpdb;
$wpdb->delete(
"countries",
[ 'id' => $id ]
);
}
}