0

enter image description here

I don't want the "Registered customer" filter option for the Admin Orders page.

I have tried to search for how to remove it. I have been inside the WooCommerce codes to see how it's implemented.

And I can see that it's implemented inside the class WC_Admin_List_Table_Orders which extends WC_Admin_List_Table. The WC_Admin_List_Table_Orders class is located in:

/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php

From the _construct method in WC_Admin_List_Table there is an add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ) );.

So in WC_Admin_List_Table_Orders we'll find an restrict_manage_posts method calling the next method render_filter():

/**
 * See if we should render search filters or not.
 */
public function restrict_manage_posts() {
    global $typenow;

    if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ), true ) ) {
        $this->render_filters();
    }
}

/**
 * Render any custom filters and search inputs for the list table.
 */
protected function render_filters() {
    $user_string = '';
    $user_id     = '';

    if ( ! empty( $_GET['_customer_user'] ) ) { // phpcs:disable  WordPress.Security.NonceVerification.NoNonceVerification
        $user_id = absint( $_GET['_customer_user'] ); // WPCS: input var ok, sanitization ok.
        $user    = get_user_by( 'id', $user_id );

        $user_string = sprintf(
            /* translators: 1: user display name 2: user ID 3: user email */
            esc_html__( '%1$s (#%2$s – %3$s)', 'woocommerce' ),
            $user->display_name,
            absint( $user->ID ),
            $user->user_email
        );
    }
    ?>
    <select class="wc-customer-search" name="_customer_user" data-placeholder="<?php esc_attr_e( 'Filter by registered customer', 'woocommerce' ); ?>" data-allow_clear="true">
        <option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo htmlspecialchars( wp_kses_post( $user_string ) ); // htmlspecialchars to prevent XSS when rendered by selectWoo. ?><option>
    </select>
    <?php
}

So, the question now is just how to prevent any of these to be called. I like that there is an add_action hook included in the process. Cause that usually means that there's possible to use remove_action(). And that's what I have tried to do. Without success.

What Iv'e tried:

Following example with both WC_Admin_List_Table and WC_Admin_List_Table_Orders:

remove_action( 'restrict_manage_posts', array( 'WC_Admin_List_Table', 'restrict_manage_posts' ) );

Above but with priority with everything from 10 to 9999999:

remove_action( 'restrict_manage_posts', array( 'WC_Admin_List_Table', 'restrict_manage_posts' ), 10 );

Wrapping it to wp_loaded with a $wc_admin_post_types global variable. Found this from an online search. I also tried with another global variable, $wc_list_table. Tried it both with and without priority in the end:

add_action('wp_loaded', function() {
    global $wc_admin_post_types;
    remove_action( 'restrict_manage_posts', array($wc_admin_post_types, 'restrict_manage_posts'), 10, 2 );
});

And I have also tried with woocommerce_loaded and woocommerce_init. I have also tried above examples inside these init and loaded actions.

Nothing works.

Does anyone knows how to do?

  • Have you checked the answer? Did it work? – Sally CJ May 13 at 19:52
  • @SallyCJ Sorry for the late respond! It works great! Apparently it was a little bit too complicated for me to figure out by myself. But when I see your answer I do somehow understand. And the solution, the code you did is so simple. I like that, thanks! – Peter Westerlund May 15 at 11:14
  • You're welcome! And actually, the answer is basically saying, "use the global $wc_list_table to disable the filter; but make sure $wc_list_table is an instance of the WC_Admin_List_Table_Orders class". :) (And you may also want to check if the current screen's ID is edit-shop_order. See get_current_screen().) – Sally CJ May 15 at 12:06
1

I can see that it's implemented inside the class WC_Admin_List_Table_Orders which extends WC_Admin_List_Table.

Yes, that's correct.

And the orders list table is setup via WC_Admin_Post_Types::setup_screen() where the method is called via these hooks: (see WC_Admin_Post_Types::__construct())

// Load correct list table classes for current screen.
add_action( 'current_screen', array( $this, 'setup_screen' ) );
add_action( 'check_ajax_referer', array( $this, 'setup_screen' ) );

And in that setup_screen() method, the list table is instantiated like so where the instance is put into a global variable — $wc_list_table:

include_once 'list-tables/class-wc-admin-list-table-orders.php';
$wc_list_table = new WC_Admin_List_Table_Orders();

So you can remove the filter like so:

// Be sure to rename this function..
function my_func() {
    global $wc_list_table;
    if ( $wc_list_table instanceof WC_Admin_List_Table_Orders ) {
        remove_action( 'restrict_manage_posts', array( $wc_list_table, 'restrict_manage_posts' ) );
    }
}
add_action( 'current_screen', 'my_func', 11 );
add_action( 'check_ajax_referer', 'my_func', 11 );

Tried and tested working on WooCommerce 3.6.2.

  • PS: You can also check if the ID of the current screen is 'edit-shop_order'. – Sally CJ May 10 at 21:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.