I’m developing a WordPress plugin where the goal/ action is to manipulate data in the wp_usermeta table, by extending the WP_List_Table class, and using it in the WPPB.me boilerplate. I’ve been able to get my table to work outside of the boilerplate, for example, if I just put my action functions in the same “wp-list-table-example-page.php”, after the code for the extended class itself. But, I want to use the boilerplate where the _REQUEST’s would be sent to separate pages in the ./partials folder (assuming that’s the correct way). I have both row and bulk actions included by extending the WP_List_Table class. I’m stuck on getting the actions to function properly; to load the custom ./partials pages I created in the boilerplate to perform the requested actions when either a row is clicked, or the bulk action drop down is used with checkboxes in a table column.
Here’s what I’m working with in the file: (edit: fixed file path for clarity) http URL is: www/zapper/wp-admin/admin.php?page=zapper-table
<?php // ./wp-content/plugins/zapper/includes/class-zapper-list-table.php :
if(!defined('PLUGIN_TEXT_DOMAIN')){
define('PLUGIN_TEXT_DOMAIN', 'zapper');
}
if(!class_exists('WP_List_Table')){
require_once( ABSPATH . 'wp-admin/includes/screen.php' );
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}
class Zapper_List_Table extends WP_List_Table
{
/* other extended WP_List_Table stuff withheld */
function get_bulk_actions()
{
$actions = array(
'view_all' => __('View Multi', 'PLUGIN_TEXT_DOMAIN'),
'edit_all' => __('Edit Multi', 'PLUGIN_TEXT_DOMAIN')
);
return $actions;
}
public function handle_table_actions() {
// check for row actions
$the_table_action = $this->current_action();
if ( 'view_meta' === $the_table_action ) {
$nonce = wp_unslash( $_REQUEST['_wpnonce'] );
// verify the nonce.
if ( ! wp_verify_nonce( $nonce, 'view_meta_nonce' ) ) {
$this->invalid_nonce_redirect();
}
else {
$this->page_view_meta( absint( $_REQUEST['user_id']) );
$this->graceful_exit();
}
}
if ( 'add_meta' === $the_table_action ) {
$nonce = wp_unslash( $_REQUEST['_wpnonce'] );
// verify the nonce.
if ( ! wp_verify_nonce( $nonce, 'add_meta_nonce' ) ) {
$this->invalid_nonce_redirect();
}
else {
$this->page_add_meta( absint( $_REQUEST['user_id']) );
$this->graceful_exit();
}
}
// check for bulk actions
if ( ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'bulk-edit' ) || ( isset( $_REQUEST['action2'] ) && $_REQUEST['action2'] === 'bulk-edit' ) ) {
$nonce = wp_unslash( $_REQUEST['_wpnonce'] );
// verify the nonce.
if ( ! wp_verify_nonce( $nonce, 'bulk-users' ) ) {
$this->invalid_nonce_redirect();
}
else {
$this->page_bulk_edit( $_REQUEST['users']);
$this->graceful_exit();
}
}
}
public function page_view_meta( $user_id ) {
$user = get_user_by( 'id', $user_id );
include_once( 'admin/partials/zapper-view-meta.php' );
}
public function page_edit_meta( $user_id ) {
$user = get_user_by( 'id', $user_id );
include_once( 'admin/partials/zapper-edit-meta.php' );
}
public function page_bulk_edit( $bulk_user_ids ) {
include_once( 'admin/partials/zapper-bulk-edit.php' );
}
}
?>
The result when clicking a row action is basically nothing, it just refreshes the page. Using the dropdown for a bulk action– while no error is thrown by WP– it directs to a blank page, with the following in the URL parameters:
?_wpnonce=183ef79f5e
&_wp_http_referer=/zapper/wp-admin/admin.php
?page=zapper-table
&action=edit_all
&paged=1
&element[]=9
&element[]=4
&element[]=11
&action2=edit_all
In my previous, successful tests, I don’t have the &_wp_http_referer or &paged=1 and I don’t understand why it’s there in this trial. And that is only on a bulk action request. Clearly I'm doing something wrong, as I've got two "?" in the URL params.
What have I've done wrong? Thank you!
EDIT:
I changed the include_once './path' to include_once( WP_PLUGIN_DIR .'/... ')
, but i'm getting the same results:
public function page_edit_meta( $user_id ) {
$user = get_user_by( 'id', $user_id );
if(file_exists(WP_PLUGIN_DIR .'/zapper/partials/zapper-edit-meta.php')){
return "<h1>FILE EXISTS!</h1>";
die();
}
else {
return "<h1>FILE NOT EXISTS!</h1>";
die();
}
include_once( WP_PLUGIN_DIR .'/zapper/partials/zapper-edit-meta.php' );
}
Changing that path, and adding die(); did not change the behavior at all. I expected it at least to exit. Now I'm really confused. It has to be going into the function if it's redirecting the page?..
EDIT2: The code in the page it's supposed to go to is as follows (but I don't see how that would be relevant here?).
<?php
/**
* @file '/zapper/partials/zapper-edit-meta.php
*/
if( current_user_can('edit_users' ) ) { ?>
<h2> <?php echo __('Process bulk operations for the selected users: <br>', $this->plugin_text_domain ); ?> </h2>
<h4>
<ul>
<?php
foreach( $bulk_user_ids as $user_id ) {
$user = get_user_by( 'id', $user_id );
echo '<li>' . $user->display_name . ' (' . $user->user_login . ')' . '</li>';
}
?>
</ul>
</h4>
<div class="card">
<h4> HTML Form to Edit Meta goes here </h4>
</div>
<br>
<a href="<?php echo esc_url( add_query_arg( array( 'page' => wp_unslash( $_REQUEST['page'] ) ) , admin_url( 'admin.php' ) ) ); ?>"><?php _e( 'Back', $this->plugin_text_domain ) ?></a>
<?php
}
else {
?>
<p> <?php echo __( 'Not authorized', $this->plugin_text_domain ) ?> </p>
<?php
}
./admin.php?page=zapper-table&action=view_meta&user_id=9
(the actual ID numbers being irrelevant, but apparently i clicked on whoever is ID[9])admin_url( 'admin.php' )
andadmin_url( 'users.php' )
a WP_List_Table tutorial I'd used was going off of users.php. In my case, I haven't noticed any difference for which base file .php was used. I don't understand quite why, but i'm assuming because of the value in the url where "?page= ".