Search code examples
phpwordpresswoocommerceordershighperformance

Create a custom filter in WooCommerce Admin Orders list (HPOS)


I've created a plugin that updates a single field with a value of 0 or 1. I want to now add the ability to filter to only orders with that field that equals 1. The field meta data is "manual_order" and I've tweaked this code for the order table:

add_action( 'woocommerce_order_list_table_restrict_manage_orders', 'show_is_first_order_checkbox' );
function show_is_first_order_checkbox() {
    ?>
    <div class="mo_box">
        <p><strong>Manual Orders</strong></p>
        <input type="checkbox" name="manual_order_filter" class="checkbox" id="manual_order_toggle" <?php echo isset( $_GET['manual_order'] ) ? 'checked' : ''; ?>>
        <label for="manual_order_toggle" class="switcher"></label>
    </div>
    <?php
}

add_action( 'woocommerce_order_query_args', 'filter_woocommerce_orders_in_the_table', 99, 1 );
function filter_woocommerce_orders_in_the_table( $query ) {
    if ( ! isset( $_GET['manual_order'] ) ) {
            return $query;
    }
    $meta_query = array(
            array(
                'key' => 'manual_order',
                'value' => 1,
                'compare' => '='
            )
        );
        $query->set( 'meta_query', $meta_query );
    return;
}

The first function works great, 0 issues there! The main issue is the second function, I have not created a query for HPOS ever so I took the old order query system and updated some of the code. Is there something else that needs to be done? As a note all of this code only runs on the HPOS order page. When this filter is activated it results in a critical error just inside of the table template.

Attempted to edit the old code usage to use the new HPOS hooks. The adding of the filter works but the actually query argument results in an error.


Solution

  • There are some mistakes in your code… On admin orders list (with HPOS enabled), is better to use a dropdown to filter metadata than a checkbox.

    As on your previous question, I assume that you want to filter orders that have "manual_order" as meta key and "1" as meta value.

    Try the following instead:

    add_action( 'woocommerce_order_list_table_restrict_manage_orders', 'show_is_first_order_checkbox', 5 );
    function show_is_first_order_checkbox() {
        $selected = isset($_GET['metadata']) ? esc_attr($_GET['metadata']) : '';
        $options  = array(
            ''              => __('By Metadata', 'woocommerce'), 
            'manual_order'  => __('Manual Orders', 'woocommerce')
        );
        
        echo '<select name="metadata" id="dropdown_shop_order_metadata">';
        foreach( $options as $value => $label_name ) {
            printf('<option value="%s" %s>%s</option>', $value, selected($selected, $value, false), $label_name);
        }
        echo '</select>';
    }   
    
    add_filter('woocommerce_order_query_args', 'filter_woocommerce_orders_in_the_table');
    function filter_woocommerce_orders_in_the_table( $query_args ) {
        if ( isset($_GET['metadata']) && $_GET['metadata'] === 'manual_order' ) {
            $query_args['meta_key']   = 'manual_order';
            $query_args['meta_value'] = '1';
        }
        return $query_args;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works on High Performance Orders Storage (HPOS).

    enter image description here