Reputation: 439
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' );
}
Upvotes: 1
Views: 886
Reputation: 29624
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 );
Upvotes: 2