.= 'tag.htm'; break; case 'flag': $pre .= $default_pre .= 'flag.htm'; break; case 'my': $pre .= $default_pre .= 'my.htm'; break; case 'my_password': $pre .= $default_pre .= 'my_password.htm'; break; case 'my_bind': $pre .= $default_pre .= 'my_bind.htm'; break; case 'my_avatar': $pre .= $default_pre .= 'my_avatar.htm'; break; case 'home_article': $pre .= $default_pre .= 'home_article.htm'; break; case 'home_comment': $pre .= $default_pre .= 'home_comment.htm'; break; case 'user': $pre .= $default_pre .= 'user.htm'; break; case 'user_login': $pre .= $default_pre .= 'user_login.htm'; break; case 'user_create': $pre .= $default_pre .= 'user_create.htm'; break; case 'user_resetpw': $pre .= $default_pre .= 'user_resetpw.htm'; break; case 'user_resetpw_complete': $pre .= $default_pre .= 'user_resetpw_complete.htm'; break; case 'user_comment': $pre .= $default_pre .= 'user_comment.htm'; break; case 'single_page': $pre .= $default_pre .= 'single_page.htm'; break; case 'search': $pre .= $default_pre .= 'search.htm'; break; case 'operate_sticky': $pre .= $default_pre .= 'operate_sticky.htm'; break; case 'operate_close': $pre .= $default_pre .= 'operate_close.htm'; break; case 'operate_delete': $pre .= $default_pre .= 'operate_delete.htm'; break; case 'operate_move': $pre .= $default_pre .= 'operate_move.htm'; break; case '404': $pre .= $default_pre .= '404.htm'; break; case 'read_404': $pre .= $default_pre .= 'read_404.htm'; break; case 'list_404': $pre .= $default_pre .= 'list_404.htm'; break; default: $pre .= $default_pre .= theme_mode_pre(); break; } if ($config['theme']) { $conffile = APP_PATH . 'view/template/' . $config['theme'] . '/conf.json'; $json = is_file($conffile) ? xn_json_decode(file_get_contents($conffile)) : array(); } !empty($json['installed']) and $path_file = APP_PATH . 'view/template/' . $config['theme'] . '/htm/' . ($id ? $id . '_' : '') . $pre; (empty($path_file) || !is_file($path_file)) and $path_file = APP_PATH . 'view/template/' . $config['theme'] . '/htm/' . $pre; if (!empty($config['theme_child']) && is_array($config['theme_child'])) { foreach ($config['theme_child'] as $theme) { if (empty($theme) || is_array($theme)) continue; $path_file = APP_PATH . 'view/template/' . $theme . '/htm/' . ($id ? $id . '_' : '') . $pre; !is_file($path_file) and $path_file = APP_PATH . 'view/template/' . $theme . '/htm/' . $pre; } } !is_file($path_file) and $path_file = APP_PATH . ($dir ? 'plugin/' . $dir . '/view/htm/' : 'view/htm/') . $default_pre; return $path_file; } function theme_mode_pre($type = 0) { global $config; $mode = $config['setting']['website_mode']; $pre = ''; if (1 == $mode) { $pre .= 2 == $type ? 'portal_category.htm' : 'portal.htm'; } elseif (2 == $mode) { $pre .= 2 == $type ? 'flat_category.htm' : 'flat.htm'; } else { $pre .= 2 == $type ? 'index_category.htm' : 'index.htm'; } return $pre; } ?>woocommerce offtopic - Custom Tab in Coupons causes "the link you followed has expired" error
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

woocommerce offtopic - Custom Tab in Coupons causes "the link you followed has expired" error

programmeradmin1浏览0评论

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
Add a comment  | 

1 Answer 1

Reset to default 0

The 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.

发布评论

评论列表(0)

  1. 暂无评论