Search code examples
wordpresswoocommercebackendmetadataorders

How to Sort the Orders Table by Ship To Column in Woocommerce?


I am attempting to make the "Ship to" column in the Woocommerce Orders table sortable by "Ship To" address.

I understand that the the Ship to values are aggregated from multiple form fields, but I cannot get them to sort by Shipping Address 1.

How does one go about making the "Ship to" address sortable in the Orders Table in WooCommerce?

Thanks in advance for your help.

Best I have currently is an attempt to make the shipping_address_1 (the street address in the USA) sortable:

// Make sorting by column
add_action('pre_get_posts', 'custom_street_address_orderby');
function custom_street_address_orderby($query)
{
    if (!is_admin()) return;
    
    $orderby = $query->get('orderby');
    if ('_shipping_address_1' == $orderby) {
        $query->set('meta_key', '_shipping_address_1');
        $query->set('orderby', 'meta_value_num');
    }
}

Solution

  • In WooCommerce admin orders, you can make the "Ship to" column sortable (based on '_shipping_address_1' meta_key) using the following:

    // Make existing "Ship to" column sortable on admin orders list
    add_filter( "manage_edit-shop_order_sortable_columns", 'shop_order_column_meta_field_sortable' );
    function shop_order_column_meta_field_sortable( $columns )
    {
        $meta_key = '_shipping_address_1';
        return wp_parse_args( array('shipping_address' => $meta_key), $columns );
    }
    
    // Make "Ship to" sorting properly (by numerical values)
    add_action('pre_get_posts', 'shop_order_column_meta_field_sortable_orderby' );
    function shop_order_column_meta_field_sortable_orderby( $query ) {
        global $pagenow;
    
        // Targeting WooCommerce admin orders list only
        if ( 'edit.php' === $pagenow && isset($_GET['post_type']) && 'shop_order' === $_GET['post_type'] ){
    
            $orderby  = $query->get( 'orderby');
            $meta_key = '_shipping_address_1';
    
            if ('_shipping_address_1' === $orderby){
              $query->set('meta_key', $meta_key);
              $query->set('orderby', 'meta_value_num'); // Or using 'meta_value'
            }
        }
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.