WordPress ordered by two custom fields meta_key’s

I have a Woocomerce query working with one meta_key ( ‘countdown_dateorhour‘ ).

It sorts the products by a custom 'meta_key' => 'countdown_date' or 'hour' and orders them using 'orderby' => 'meta_value_num'.

Read More

I need to join two meta_key's together. (‘hour’ key only returns the first two ints of a 24hr time).

Result required, products ordered by two custom fields countdown_date and hour

$args = array(
            'posts_per_page' => 20,
            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'product_cat',
                    'field' => 'slug',
                    'terms' => 'live-events'
                )),
            'post_type' => 'product',
            'meta_key' => 'countdown_date',
// need to add second meta key here 'meta_key' => 'hour',
             'orderby' => 'meta_value_num',
             'order'   => 'ASC'
            );
        $the_query = new WP_Query( $args );

I’ve looked at loads of similar questions with no results.

Two loops seems overkill and adding the meta_query is not working for me.

Any help would be great. 🙂

Full working code in the answer below from @Rene_Korss

Could i get a hand add this to functions.php so that the archive will sort the same way as the custom loop.

Below is a simplified version of the function i’ve got working. I need to add the two meta_key’s here too.

    add_filter('woocommerce_get_catalog_ordering_args','wdm_change_ordering',10,1);
        function wdm_change_ordering($args) { 
            if(is_product_category()) {

                    $args['meta_key'] = 'countdown_date';
// need to add second meta key here $args['meta_key'] = 'hour', 
                    $args['orderby'] = 'meta_value';
                    $args['order'] = 'ASC';

                } 
    return $args;  
    }

Related posts

1 comment

  1. Add both meta keys to meta_query and set orderby to meta_value. Then you can replace it with posts_orderby hook.

    <?php
    
    // Override orderby if orderby value = 'meta_value'
    function orderby_countdown_date_and_hour( $orderby ){
        return str_replace( 'meta_value', 'meta_value, mt1.meta_value', $orderby );
    }
    
    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => 20,
        'tax_query'      => array(
            'relation'   => 'AND',
            array(
                'taxonomy' => 'product_cat',
                'field'    => 'slug',
                'terms'    => 'live-events'
            )
        ),
        'meta_query' => array(
            array(
                'key'     => 'countdown_date',
                'value'   => '',
                'compare' => '!='
            ),
            array(
                'key'     => 'hour',
                'value'   => '',
                'compare' => '!='
            )
        ),
        'orderby'   => 'meta_value',
        'order'     => 'ASC'
    );
    
    // Replace orderby
    add_filter( 'posts_orderby', 'orderby_countdown_date_and_hour' );
    
    // Query
    $the_query = new WP_Query( $args );
    
    // Remove our orderby
    remove_filter( 'posts_orderby', 'orderby_countdown_date_and_hour' );
    

    This results in

    ORDER BY dbprefix_postmeta.meta_value, mt1.meta_value ASC
    

    which means

    ORDER BY countdown_date, hour ASC
    

Comments are closed.