Woocommerce > Hide products that are out of stock BUT skip products with certain tag

Viewed 84

I would like to hide products that are out of stock on archive pages. But products containing tag "backorder" should be skipped. I tried many options but the problem is that I can't combine meta_query and tax_query to do this.

Does anyone have suggestion on how to do this?

This is my current status:

add_filter( 'woocommerce_product_query_meta_query', 'shop_only_instock_products', 10, 2 );
function shop_only_instock_products( $meta_query, $query ) {
    if( is_admin() || is_search() || ! is_shop()) return $meta_query;
    $meta_query[] = array(
        'key' => '_stock_status',
        'value' => 'outofstock',
        'compare' => '!='
    );
    print_r($meta_query);
}

add_filter( 'woocommerce_product_query_tax_query', 'filter_products_with_specific_product_tags', 9, 2 );
function filter_products_with_specific_product_tags( $tax_query, $query ) {
     if( is_admin() || is_search() || ! is_shop()) return $tax_query;
    $tax_query[] = array(
         'taxonomy' => 'product_tag',
         'field' => 'name',
         'terms' => array('backorder'),
     );
    return $tax_query;
 };
2 Answers

You can try woocommerce_product_query hook. I've not tested this code yet.

add_action( 'woocommerce_product_query', 'action_product_query', 10, 2 );
function action_product_query( $q, $query ) {
    
    // Ignore this condition and test the behind codes firstly
    // if( is_admin() || is_search() || ! is_shop()) return;

    // Get any existing Tax query
    $tax_query = $q->get( 'tax_query');
    
    // Get any existing meta query
    $meta_query = $q->get( 'meta_query');
    
    // Define an additional tax query 
    $tax_query = array(
        'taxonomy' => 'product_tag',
        'field'    => 'name', // backorder looks like slug
        'terms'   => array('backorder'),
        'compare' => 'IN',
    );
    
    // Define an additional meta query 
    $meta_query = array(
        'key'     => '_stock_status',
        'value'   => 'outofstock',
        'compare' => '!=',
    );
    
    // Set the new merged tax query
    $q->set( 'tax_query', $tax_query );
    
    // Set the new merged meta query
    $q->set( 'meta_query', $meta_query );
}

You should use on backorder setting in your product inverntory. Set Out of stock visibility to true in your Woocommerce > Settings > Product > Inventory . You dont need any additional code for this.

Related