This code is saved in ./child-theme/includes/show_coupon_usage.php
and then in functions.php
it's required if the user is an admin.
<?php
if (!defined('ABSPATH')) {
exit;
}
//Our class extends the WP_List_Table class, so we need to make sure that it's there
if (!class_exists('WP_List_Table')) {
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
}
class Coupon_Usage_Table extends WP_List_Table
{
/**
* Constructor, we override the parent to pass our own arguments
* We usually focus on three parameters: singular and plural labels, as well as whether the class supports AJAX.
*/
function __construct()
{
parent::__construct(array(
'singular'=> 'coupon_usage', //Singular label
'plural' => 'coupon_usages', //plural label, also this well be one of the table css class
'ajax' => false //We won't support Ajax for this table
));
$this->prepare_items();
$this->display();
}
function no_items()
{
_e('This coupon hasn\'t been used yet.');
}
/**
* Prepare the table with different parameters, pagination, columns and table elements
*/
function prepare_items()
{
global $thepostid, $post, $wpdb, $_wp_column_headers;
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$thepostid = empty($thepostid) ? $post->ID : $thepostid;
// Get username, user ID and how many times did they use this coupon.
$query = $wpdb->prepare("SELECT u.user_login as username, pm.meta_value as user_id, COUNT(1) as timesused FROM {$wpdb->prefix}_posts p LEFT JOIN {$wpdb->prefix}_postmeta pm ON p.ID = pm.post_id LEFT JOIN {$wpdb->prefix}_users u ON u.ID = pm.meta_value WHERE p.post_type = 'shop_coupon' AND p.ID = %d AND pm.meta_key = '_used_by' GROUP BY pm.meta_value;", array($thepostid));
$this->items = $wpdb->get_results($query);
$this->_column_headers = array($columns, $hidden, $sortable);
}
/**
* Define the columns that are going to be used in the table
* @return array $columns, the array of columns to use with the table
*/
function get_columns()
{
return $columns = array(
'username'=>__('Name'),
'timesused'=>__('Times Used')
);
}
/**
* Define which columns are hidden
*
* @return Array
*/
public function get_hidden_columns()
{
return array();
}
/**
* Define the sortable columns
*
* @return Array
*/
public function get_sortable_columns()
{
return array();
}
function column_default($item, $column_name)
{
switch ($column_name) {
case 'username':
$actions = array(
'edit' => sprintf('<a href="/wp-admin/user-edit.php?user_id=%s">Edit</a>', $item->user_id),
'orders' => sprintf('<a href="/wp-admin/edit.php?post_status=all&post_type=shop_order&_customer_user=%s">Orders</a>', $item->user_id),
);
return sprintf('%1$s %2$s', $item->username, $this->row_actions($actions));
case 'timesused':
return sprintf('%1$s', $item->timesused);
default:
return print_r($item, true).' - '.print_r($column_name, true) ;
}
}
}
add_filter('woocommerce_coupon_data_tabs', 'admin_coupon_options_tabs', 20, 1);
add_action('woocommerce_coupon_data_panels', 'admin_coupon_options_panels', 10, 0);
//Add tabs to the coupon option page
function admin_coupon_options_tabs($tabs)
{
$tabs['show_who_used'] = array(
'label' => __('Who used it?', 'woocommerce-coupon-usage'),
'target' => 'woocommerce_coupon_usage',
'class' => 'woocommerce_coupon_usage',
);
return $tabs;
}
//Add panels to the coupon option page
function admin_coupon_options_panels()
{
echo '<div id="woocommerce_coupon_usage" class="panel woocommerce_options_panel">';
$wp_list_table = new Coupon_Usage_Table();
echo '</div>';
}
The code works fine, I can see the data I want in coupons that have already been created programatically. The problem is when I go to create one via the "Add Coupon" button or if I try to edit an existing one.
I get the The link you followed has expired.
error.
Google only shows stuff about upload_max_size
, post_max_size
and max_execution_time
but it doesn't seems to have anything to do with my case.
I also don't use a nonce in my code since it's purely presenting information, it takes no input.
Anyone knows what might be going on? WP_DEBUG doesn't show anything useful.
Edit: Checking the POST data sent with and without the code active on the same coupon I see this:
This is with my code active
_wp_original_http_referer:
_wpnonce: 4d92197b82
_wpnonce: e5b47d577d
referredby:
This is with my code inactive
_wp_original_http_referer: .php?post_type=shop_coupon
_wpnonce: e5b47d577d
referredby: .php?post_type=shop_coupon
This code is saved in ./child-theme/includes/show_coupon_usage.php
and then in functions.php
it's required if the user is an admin.
<?php
if (!defined('ABSPATH')) {
exit;
}
//Our class extends the WP_List_Table class, so we need to make sure that it's there
if (!class_exists('WP_List_Table')) {
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
}
class Coupon_Usage_Table extends WP_List_Table
{
/**
* Constructor, we override the parent to pass our own arguments
* We usually focus on three parameters: singular and plural labels, as well as whether the class supports AJAX.
*/
function __construct()
{
parent::__construct(array(
'singular'=> 'coupon_usage', //Singular label
'plural' => 'coupon_usages', //plural label, also this well be one of the table css class
'ajax' => false //We won't support Ajax for this table
));
$this->prepare_items();
$this->display();
}
function no_items()
{
_e('This coupon hasn\'t been used yet.');
}
/**
* Prepare the table with different parameters, pagination, columns and table elements
*/
function prepare_items()
{
global $thepostid, $post, $wpdb, $_wp_column_headers;
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$thepostid = empty($thepostid) ? $post->ID : $thepostid;
// Get username, user ID and how many times did they use this coupon.
$query = $wpdb->prepare("SELECT u.user_login as username, pm.meta_value as user_id, COUNT(1) as timesused FROM {$wpdb->prefix}_posts p LEFT JOIN {$wpdb->prefix}_postmeta pm ON p.ID = pm.post_id LEFT JOIN {$wpdb->prefix}_users u ON u.ID = pm.meta_value WHERE p.post_type = 'shop_coupon' AND p.ID = %d AND pm.meta_key = '_used_by' GROUP BY pm.meta_value;", array($thepostid));
$this->items = $wpdb->get_results($query);
$this->_column_headers = array($columns, $hidden, $sortable);
}
/**
* Define the columns that are going to be used in the table
* @return array $columns, the array of columns to use with the table
*/
function get_columns()
{
return $columns = array(
'username'=>__('Name'),
'timesused'=>__('Times Used')
);
}
/**
* Define which columns are hidden
*
* @return Array
*/
public function get_hidden_columns()
{
return array();
}
/**
* Define the sortable columns
*
* @return Array
*/
public function get_sortable_columns()
{
return array();
}
function column_default($item, $column_name)
{
switch ($column_name) {
case 'username':
$actions = array(
'edit' => sprintf('<a href="/wp-admin/user-edit.php?user_id=%s">Edit</a>', $item->user_id),
'orders' => sprintf('<a href="/wp-admin/edit.php?post_status=all&post_type=shop_order&_customer_user=%s">Orders</a>', $item->user_id),
);
return sprintf('%1$s %2$s', $item->username, $this->row_actions($actions));
case 'timesused':
return sprintf('%1$s', $item->timesused);
default:
return print_r($item, true).' - '.print_r($column_name, true) ;
}
}
}
add_filter('woocommerce_coupon_data_tabs', 'admin_coupon_options_tabs', 20, 1);
add_action('woocommerce_coupon_data_panels', 'admin_coupon_options_panels', 10, 0);
//Add tabs to the coupon option page
function admin_coupon_options_tabs($tabs)
{
$tabs['show_who_used'] = array(
'label' => __('Who used it?', 'woocommerce-coupon-usage'),
'target' => 'woocommerce_coupon_usage',
'class' => 'woocommerce_coupon_usage',
);
return $tabs;
}
//Add panels to the coupon option page
function admin_coupon_options_panels()
{
echo '<div id="woocommerce_coupon_usage" class="panel woocommerce_options_panel">';
$wp_list_table = new Coupon_Usage_Table();
echo '</div>';
}
The code works fine, I can see the data I want in coupons that have already been created programatically. The problem is when I go to create one via the "Add Coupon" button or if I try to edit an existing one.
I get the The link you followed has expired.
error.
Google only shows stuff about upload_max_size
, post_max_size
and max_execution_time
but it doesn't seems to have anything to do with my case.
I also don't use a nonce in my code since it's purely presenting information, it takes no input.
Anyone knows what might be going on? WP_DEBUG doesn't show anything useful.
Edit: Checking the POST data sent with and without the code active on the same coupon I see this:
This is with my code active
_wp_original_http_referer:
_wpnonce: 4d92197b82
_wpnonce: e5b47d577d
referredby:
This is with my code inactive
_wp_original_http_referer: https://example/wp-admin/edit.php?post_type=shop_coupon
_wpnonce: e5b47d577d
referredby: https://example/wp-admin/edit.php?post_type=shop_coupon
Share
Improve this question
edited Nov 21, 2020 at 17:09
Daviid
asked Nov 21, 2020 at 17:02
DaviidDaviid
1631 silver badge9 bronze badges
1 Answer
Reset to default 0The problem was the nonce, answered by @Daniel Antunes here.
Let me help you! Overwrite the parent method display_tablenav of WP_List_Table class removing the wp_nonce_field execution.
/** * Generates the table navigation above or bellow the table and removes the * _wp_http_referrer and _wpnonce because it generates a error about URL too large * * @param string $which * @return void */ function display_tablenav( $which ) { ?> <div class="tablenav <?php echo esc_attr( $which ); ?>"> <div class="alignleft actions"> <?php $this->bulk_actions(); ?> </div> <?php $this->extra_tablenav( $which ); $this->pagination( $which ); ?> <br class="clear" /> </div> <?php }
I'm not sure how to do this "Repeated question" thing to link to his answer, feel free to do that if you know how.