1

I'm using the following code to select products with the following post_metas:

_product_new, _product_almost_new, _product_old

add_action( 'woocommerce_product_query', 'custom_vtp_shop_order' );

function custom_vtp_shop_order($q){
    if ( ! $q->is_main_query() ) return;
    if (! is_admin() && (is_shop() || is_archive) ) {

        $q->set( 'tax_query', array(array(
            'taxonomy' => 'product_cat',
            'field' => 'slug',
            'terms' => array( 'Sold', 'Service' ),  
            'operator' => 'NOT IN'
        )));

        $q->set('meta_query', array(array(
            'relation' => 'OR',
                'product_new' => array(
                    'key' => '_product_new',
                    'value' => '1',
                ),
                'product_almost_new' => array(
                    'key' => '_product_almost_new',
                    'value' => '1',
                ), 
                'product_old' => array(
                    'key' => '_product_old',
                    'value' => '1',
                )
            )));

        /*THIS HAS NO EFFECT*/
        $q->set('orderby', array(array( 
                'product_new' => 'DESC',
                'product_old' => 'DESC',
                'product_almost_new' => 'DESC',
            )        
        ));

    }

}

I want the products to then be displayed in the following order:

  1. product_new
  2. product_old
  3. product_almost_new

I am using $q->set('orderby', array(......) but this is having no effect. My products are ALWAYS being ordered product_old, product_almost_new, product_new.

Any ideas why my 'orderby' is not working? Thanks in advance for any help!

2

With WP_Query it's only possible to sort by a single meta value by setting the meta_key argument to which key you want to be able to sort by, and orderby to meta_value (or meta_value_num if the value is to be sorted numerically).

This is what the arguments would look like:

$args = array(
    'meta_key' => '_product_new',
    'orderby'  => 'meta_value_num',
    'meta_query' = array(
        'relation' => 'OR',
        array(
            'key'   => '_product_new',
            'value' => '1',
        ),
        array(
            'key'   => '_product_almost_new',
            'value' => '1',
        ), 
        array(
            'key'   => '_product_old',
            'value' => '1',
        )
    )
);

That will query all posts that have _product_new, _product_almost_new, or _product_old, and order them so that the ones with _product_new will be at the top or bottom (depending on order).

The problem is that this will only sort by one meta value, _product_new, and ignore the others. But this is just a limitation of WP_Query. It's not possible to sort results by multiple meta values.

A potential solution is to have a single meta key, say _product_age, and set it to a numerical value that represents each of the states you want to sort by. So instead of having _product_new as a boolean, set _product_age to 1, instead of _product_almost_new, set _product_age to 3, and instead of _product_old, set _product_age to 2.

Then you could use these args to sort the way you want;

$args = array(
    'meta_key' => '_product_age',
    'orderby'  => 'meta_value_num',
    'order'    => 'ASC',
    'meta_query' = array(
        array(
            'key'     => '_product_age',
            'value'   => array( 1, 2, 3 ),
            'compare' => 'IN',
        ),
    )
);
0

I know this is old but here is the possible solution:

$q->set('orderby', 'product_new product_old product_almost_new');
$q->set('order', 'DESC');

So just try to pass parameters as a string in required order.

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.