Skip to content

Instantly share code, notes, and snippets.

@RadGH
Last active July 24, 2022 10:17
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save RadGH/332a447cdcdd76c84a48148d596ce5e6 to your computer and use it in GitHub Desktop.
Save RadGH/332a447cdcdd76c84a48148d596ce5e6 to your computer and use it in GitHub Desktop.
Exclude out of stock and hidden products from WooCommerce query with pre_get_posts (plus equivalent filter for Ajax Load More)
<?php
/*
Solution based on a Stack Overflow answer by patrickzdb:
https://stackoverflow.com/a/24514985/470480
Tax query solution for hidden products based on a WordPress Stack Exchange answer by kalle:
https://wordpress.stackexchange.com/a/262628/19105
Please note:
This file includes two functions/filters.
The first is for vanilla WordPress pre_get_posts.
If you do not use Ajax Load More, just copy the first function + action.
The second is specific to Ajax Load More.
If you use Ajax Load More, copy both functions + action/filter.
*/
/**
* WooCommerce by default hides out of stock products AFTER the query.
* This leaves gaps: If you have 16 products per page, but 1 of those products are out of stock, you only see 15.
* This solution excludes out of stock products during the query, so you'll get the expected results even if some of the products are out of stock.
*
* @param $query
*
* @return WP_Query $query
*/
function rs_remove_out_of_stock_products_from_query( $query ) {
if ( is_admin() ) return $query;
// Only affect product archives
// Consider using is_main_query(), although I wouldn't want out of stock products on secondary queries either!.
if ( !$query->is_post_type_archive('product') ) return $query;
// Set up meta query
$meta_query = array();
// If a meta_query already exists, keep it -- require those condntions in addition to the stock query
if ( !empty($query->get('meta_query')) ) {
$meta_query = array(
'relation' => 'AND',
$query->get('meta_query')
);
}
// Exclude out of stock products
$meta_query[] = array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => 'NOT IN'
);
$query->set('meta_query', $meta_query);
return $query;
}
add_action( 'pre_get_posts', 'rs_remove_out_of_stock_products_from_query', 20 );
// AJAX LOAD MORE ONLY:
/**
* (AJAX LOAD MORE VERSION OF rs_remove_out_of_stock_products_from_query)
*
* @param $args
*
* @return array $args
*/
function rs_remove_out_of_stock_products_from_alm( $args ) {
if ( is_admin() ) return $args;
$post_type = false;
// Get post type, which may be an array or string.
if ( !empty($args['post_type']) ) {
if ( is_string($args['post_type']) ) $post_type = $args['post_type'];
else if ( is_array($args['post_type']) && count($args['post_type']) == 1 ) $post_type = $args['post_type'][0];
}
// Only affect products
if ( $post_type !== 'product' ) return $args;
// Set up meta query
$meta_query = array();
// If a meta_query already exists, keep it -- require those condntions in addition to the stock query
if ( !empty($args['meta_query']) ) {
$meta_query = array(
'relation' => 'AND',
$args['meta_query']
);
}
// Exclude out of stock products
$meta_query[] = array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => 'NOT IN'
);
$args['meta_query'] = $meta_query;
return $args;
}
add_filter( 'alm_modify_query_args', 'rs_remove_out_of_stock_products_from_alm', 20 );
@RadGH
Copy link
Author

RadGH commented Jul 13, 2018

Updated to also exclude hidden products, as set in "Catalog Visibility" on the product page

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment