Untitled
unknown
plain_text
7 months ago
2.6 kB
18
Indexable
/**
* WooCommerce - Show In-Stock Products First While Maintaining User Sort Order
*
* This code will:
* 1. Put in-stock products first, followed by out-of-stock products
* 2. Maintain the user's selected sort order (price, popularity, date, etc.)
* 3. Work on main product listings, category pages, and shop-specific product pages
*/
add_filter('woocommerce_get_catalog_ordering_args', 'custom_stock_status_sort', 9999);
function custom_stock_status_sort($args) {
// First, create a meta query for the stock status
$args['meta_query']['stock_status'] = array(
'key' => '_stock_status',
);
// We need to preserve the existing orderby parameters
$orderby_value = isset($args['orderby']) ? $args['orderby'] : 'menu_order';
// If it's an array, we'll work with it differently
if (is_array($orderby_value)) {
// Add stock status as first ordering parameter
$new_args = array(
'stock_status' => 'ASC', // In-stock first (instock comes before outofstock alphabetically)
);
// Then add all existing orderby parameters
foreach ($orderby_value as $key => $value) {
$new_args[$key] = $value;
}
$args['orderby'] = $new_args;
} else {
// For string-based orderby
// Stock status first, then the user-selected sort
$args['orderby'] = array(
'stock_status' => 'ASC', // In-stock first
$orderby_value => $args['order'], // Preserve existing sort order
);
}
return $args;
}
// Also apply this to shortcodes like [products]
add_filter('woocommerce_shortcode_products_query', 'custom_stock_status_sort', 9999);
// For store-specific product pages
add_filter('posts_clauses', 'custom_posts_clauses_sort_by_stock', 10, 2);
function custom_posts_clauses_sort_by_stock($clauses, $wp_query) {
global $wpdb;
// Only apply to WooCommerce product queries on frontend
if (is_admin() || !$wp_query->is_main_query() ||
!is_woocommerce() || !is_shop() && !is_product_category() && !is_product_tag()) {
return $clauses;
}
// Join the postmeta table to get stock status
$clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} as stock_status_meta ON ({$wpdb->posts}.ID = stock_status_meta.post_id AND stock_status_meta.meta_key = '_stock_status') ";
// Add the stock status to the ORDER BY clause, keeping the original ordering
$clauses['orderby'] = "stock_status_meta.meta_value ASC, " . $clauses['orderby'];
return $clauses;
}Editor is loading...
Leave a Comment