Frithir.com
Frithir.com

Reputation: 295

Wordpress ordered by two custom fields meta_key's

I have a Woocomerce query working with one meta_key ( 'countdown_date' or 'hour' ).

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

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;  
    }

Upvotes: 1

Views: 2274

Answers (1)

Rene Korss
Rene Korss

Reputation: 5494

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

Upvotes: 1

Related Questions