I’m trying to add a sorting option for woocommerce products’s list.
The goal is to sort products by a meta value with meta key called _rating.
For now I generate this meta value with a function executed at plugin’s activation.
Issue :
Products are not sorted by meta value but by ID instead
My plugin :
<?php /* Plugin Name: Sort by meta value Description: Add sort option in product list by meta ratings Author: Aurélien Version: 1.0.0 Text Domain: sort-by-meta Domain Path: /languages */ /** * Check if WooCommerce is active **/ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) { class Sort_By_Meta{ public static function init() { //Add custom fields for every product $all_ids = get_posts( array( 'post_type' => 'product', 'numberposts' => -1, 'post_status' => 'publish', 'fields' => 'ids', ) ); foreach ( $all_ids as $id ) { update_post_meta($id,"_rating", Sort_By_Meta::generateRandomString()); } } //Function which generates random string public function generateRandomString($length = 10) { $characters = 'abcdefghijklmnopqrstuvwxyz'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } } register_activation_hook( __FILE__, array('Sort_By_Meta', 'init' )); function add_postmeta_ordering_args( $sort_args ) { $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); switch( $orderby_value ) { case 'rating': $sort_args['orderby'] = 'meta_value'; $sort_args['order'] = 'DESC'; $sort_args['meta_key'] = '_rating'; break; } return $sort_args; } add_filter( 'woocommerce_get_catalog_ordering_args', 'add_postmeta_ordering_args' ); function add_new_postmeta_orderby( $sortby ) { $sortby['rating'] = "rating"; return $sortby; } add_filter( 'woocommerce_default_catalog_orderby_options', 'add_new_postmeta_orderby' ); add_filter( 'woocommerce_catalog_orderby', 'add_new_postmeta_orderby' ); }
Advertisement
Answer
I tested your code and at first sight nothing seemed wrong but the desired result was not forthcoming. When I replaced rating
with something like rank
this seems to work.
This is because rating
is already in use by “Sort by average rating”
function add_postmeta_ordering_args( $sort_args ) { $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); switch( $orderby_value ) { case 'rank': $sort_args['orderby'] = 'meta_value'; $sort_args['order'] = 'ASC'; $sort_args['meta_key'] = '_rating'; break; } return $sort_args; } add_filter( 'woocommerce_get_catalog_ordering_args', 'add_postmeta_ordering_args', 10, 1 ); function add_new_postmeta_orderby( $sortby ) { $sortby['rank'] = 'Rating'; return $sortby; } add_filter( 'woocommerce_default_catalog_orderby_options', 'add_new_postmeta_orderby', 10, 1 ); add_filter( 'woocommerce_catalog_orderby', 'add_new_postmeta_orderby', 10, 1 );