WooCommerce – add ‘Sort by On Sale’ option on archive pages
For a recent project I’m working on I needed an additional option adding to the ‘Sort by’ dropdown that WooCommerce comes with out the box on archive pages.
What I found was, that with 3 filters, it was possible but it only returned Simple product results and skipped Variable ones.
Below is my modified version that includes Variable products – it may need tweaking to allow for other $_GET variables to be in the current URL (like native filter options) but as it stands, it orders the products by that are on sale first…
functions.php
/**
* Add the 'Sort by Sale' option to the select box
*/
add_filter( 'woocommerce_catalog_orderby', 'add_order_by_on_sale');
add_filter( 'woocommerce_default_catalog_orderby_options', 'add_order_by_on_sale' );
function add_order_by_on_sale($sortby) {
$sortby['on_sale'] = 'Sort by on sale';
return $sortby;
}
/**
* Modify archive query for products on sale
*/
add_filter( 'woocommerce_get_catalog_ordering_args', 'order_by_on_sale');
function order_by_on_sale($args) {
$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ));
if ( 'on_sale' == $orderby_value ) {
$args['meta_query'] = array(
'relation' => 'OR',
array( // Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
),
array( // Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
);
}
return $args;
}