I am creating a custom sort name "price-asc" which sort products based on highest price.
My solution is:
1- create key_meta called "_highest_price" to store the highest price for each product
2- create a custom "price-asc" in filter woocommerce_catalog_orderby
3- custom "orderby", "order", "meta_key" in filter woocommerce_get_catalog_ordering_args
functions.php
// step 1
function my_save_post_product( $post_id, $post, $update ) {
if( ! $update ) // no further actions if no changes
return;
if( $post->post_status !== 'publish' ) // no further actions if product is not public
return;
$product = wc_get_product( $post_id );
if( $product->product_type == 'variable' ) :
update_post_meta( $post_id, '_highest_price', $product->get_variation_price( 'max', true ) );
elseif( $product->product_type == 'simple' ) :
update_post_meta( $post_id, '_highest_price', $product->get_price() );
endif;
}
add_action( 'save_post_product', 'my_save_post_product', 10, 3 );
// step 2
function my_woocommerce_catalog_orderby( $options ) {
//...
$options['price-asc'] = __( 'A different low to high', 'mytheme' );
return $options;
}
add_filter( 'woocommerce_catalog_orderby', 'my_woocommerce_catalog_orderby' );
// step 3
function my_woocommerce_get_catalog_ordering_args( $args ) {
$orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
if ( $orderby_value == 'price-asc' ) :
$args['orderby'] = 'meta_value_num';
$args['order'] = 'ASC';
$args['meta_key'] = '_highest_price';
endif;
return $args;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'my_woocommerce_get_catalog_ordering_args' );
Then I go to https://example.com/products/?orderby=price-asc
However, the order doesn't display as expected. Product with _highest_price "22092" should displays before product with _highest_price "1177000" as 22092 < 1177000.
Here are my database and display. Please help database display