6

I need to sort my products by rating in a wp_query loop:

this is my code:

switch($ordering){
    case 'default':
        $meta_key = '';
        $order = 'asc';
        $orderby = 'menu_order title';
        break;
    case 'popularity':
        $meta_key = '';
        $order = 'desc';
        $orderby = 'total_sales';
        break;
    case 'low_to_high':
        $meta_key = '_price';
        $order = 'asc';
        $orderby = 'meta_value_num';
        break;
    case 'high_to_low':
        $meta_key = '_price';
        $order = 'desc';
        $orderby = 'meta_value_num';
        break;
    case 'newness':
        $meta_key = '';
        $order = 'desc';
        $orderby = 'date';
        break;
    case 'rating':
        $meta_key = '';
        $order = 'desc';
        $orderby = 'rating';
        break;
}

$args_products_sorting = array(
    'post_type' => 'product',
    'posts_per_page' => -1,
    'orderby' => $orderby,
    'order' => $order,
    'meta_key' => $meta_key
);

Where is the error ?

If i set in url ?orderby=rating it works correctly.

Thanks.

  • Why is $meta_key for case 'rating' empty? – locomo Feb 29 '16 at 0:16
8
+50

You should use 'orderby' => 'meta_value_num' and 'meta_key' => 'rating' as specified by the WordPress Codec. Using meta_value_num with the assumption your ratings are numeric values

Reference: Orderby Parameters

| improve this answer | |
5

Seems like there are a lot of meta keys you can order by (here is a list I’ve found). However I couldn’t find anything rating related. I searched for rating in the WooCommerce source code and found this line: includes/abstracts/abstract-wc-product.php#L1087

So here is what finally worked for me in the context of using the WooCommerce PHP REST API client:

function getProducts(WP_REST_Request $request) {
    global $wc_api_client;

    $category = $request->get_param('category');
    // $filters = $request->get_param('filters');
    $orderby = $request->get_param('orderby');

    $args = null;

    $wc_query = new WC_Query();
    switch ( $orderby ) {
        case 'date':
            $args = array(
                'filter[limit]' => 6,
                'filter[category]' => $category,
                'filter[orderby]' => 'date',
                'filter[order]' => 'DESC'
            );
            break;
        case 'price':
            $args = array(
                'filter[limit]' => 6,
                'filter[category]' => $category,
                'filter[orderby]' => 'meta_value_num',
                'filter[order]' => 'ASC',
                'filter[orderby_meta_key]' => '_price'
            );
            break;
        case 'price-desc':
            $args = array(
                'filter[limit]' => 6,
                'filter[category]' => $category,
                'filter[orderby]' => 'meta_value_num',
                'filter[order]' => 'DESC',
                'filter[orderby_meta_key]' => '_price'
            );
            break;
        case 'popularity':
            $args = array(
                'filter[limit]' => 6,
                'filter[category]' => $category,
                'filter[orderby]' => 'meta_value_num',
                'filter[order]' => 'DESC',
                'filter[orderby_meta_key]' => 'total_sales'
            );
            break;
        case 'rating':
            $args = array(
                'filter[limit]' => 6,
                'filter[category]' => $category,
                'filter[orderby]' => 'meta_value_num',
                'filter[order]' => 'DESC',
                'filter[orderby_meta_key]' => '_wc_average_rating'
            );
            break;
        default:
            $args = array(
                'filter[limit]' => 6,
                'filter[category]' => $category
            );
    }

    try {
        $raw = $wc_api_client->products->get('', $args);
        return $raw['products'];
    } catch (Exception $e) {
        return new WP_Error('no_products', 'Couldn’t find any products', array('status' => 404));
    }
}
| improve this answer | |
  • 2
    Explaining what you do in your answers is not just the nice thing to do, it is considered mandatory for an answer to be considered as good. So please, add an explanation about the context and why this works - thanks. – Nicolai Feb 29 '16 at 13:43
  • @ialocin A comment would have been enough (see meta.stackexchange.com/questions/2451/…). I added some more info. – borisdiakur Feb 29 '16 at 15:45
  • 1
    I down vote answers not meeting quality standards to give a bigger incentive to better them - that is just it and I always leave a comment with it. And to be honest, I don't care if other people behave differently. Another thing, what about those »filter[---]« parameters, where do they come from? – Nicolai Feb 29 '16 at 16:01
  • @ialocin I've added some more context. I cannot add more links, don’t have enought “internet points” since I’ve spent all of them for the bounty... – borisdiakur Feb 29 '16 at 16:10
  • 1
    See, we are getting there :) thanks. I'd guess it is ok like this, because with the information, everybody themselves can search it. – Nicolai Feb 29 '16 at 16:18
1

I used something like that and it works

switch ($order_by){
                case 'price':
                    $args['orderby'] = 'meta_value_num';
                    $args['meta_key'] = '_price';
                    $args['order'] = 'asc';
                    break;

                case 'price-desc':
                    $args['orderby'] = 'meta_value_num';
                    $args['meta_key'] = '_price';
                    $args['order'] = 'desc';
                    break;

                case 'rating':
                    $args['orderby'] = 'meta_value_num';
                    $args['meta_key'] = '_wc_average_rating';
                    $args['order'] = 'desc';
                    break;

                case 'popularity':
                    $args['orderby'] = 'meta_value_num';
                    $args['meta_key'] = 'total_sales';
                    $args['order'] = 'desc';
                    break;
            }
| improve this answer | |
0

Try this . Use WC_Shortcode_Products to generate the wc loop with sort parameters were used at default wc shop page

for($i=1;$i<=$num;$i++){
    $atts = array_merge(array(
        'columns' => $columns,
        'orderby' => $order_by,
        'order' => $sort_by,//rating , population , price high to low ,....
        'rows' => $rows,
        'page' => $i,
    ));
    $shortcode = new WC_Shortcode_Products($atts, 'recent_products');
    echo $shortcode->get_content();
}
| improve this answer | |

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.