sarah miller
sarah miller

Reputation: 193

Hide out of stock related products in WooCommerce

In WooCommerce I would like to hide Out of Stock products from Related products in single product pages. Is it possible?

Any track is appreciated.

Upvotes: 9

Views: 5664

Answers (8)

Stefan
Stefan

Reputation: 1

Try this snippet in functions.php

    function exclude_out_of_stock_related_products( $related_posts, $product_id, $args ) {
    // Ensure stock status meta is included in the query
    $args['meta_query'] = isset($args['meta_query']) ? $args['meta_query'] : array();
    $args['meta_query'][] = array(
        'key'     => '_stock_status',
        'value'   => 'outofstock',
        'compare' => '!=',
    );

    // Get related products with the modified arguments
    $related_posts = wc_get_products( $args );

    // Return only the IDs of the in-stock related products
    return wp_list_pluck( $related_posts, 'id' );
}
add_filter( 'woocommerce_related_products', 'exclude_out_of_stock_related_products', 10, 3 );

Upvotes: 0

Muhammad Aslan
Muhammad Aslan

Reputation: 11

You can use the following code to hide out-of-stock related products. This code loops through the related products checks if they are in stock and removes them from the list if they aren't

    function hide_out_of_stock_related_products( $related_posts ) {
    foreach ( $related_posts as $key => $related_post_id ) {
        $product = wc_get_product( $related_post_id );
        if ( ! $product->is_in_stock() ) {
            unset( $related_posts[ $key ] );
        }
    }
    return $related_posts;
}
add_filter( 'woocommerce_related_products', 'hide_out_of_stock_related_products' );

Upvotes: 1

vahid sabet
vahid sabet

Reputation: 583

For those who didn't find solution: Tested on Woocommerce +6

add_filter( 'woocommerce_related_products', 'vahids_related_products', 10, 3 );
function vahids_related_products( $related_posts, $product_id, $args ){
    $in_stock_product_ids = (array) wc_get_products( array(
        'status'       => 'publish',
        'limit'        => -1,
        'stock_status' => 'instock',
        'return'       => 'ids',
     ));

    return $in_stock_product_ids;
}

Upvotes: 2

Ned
Ned

Reputation: 3

This is working code from here. Add this code to your functions.php and you will see that our of stocks products will not be seen in related product block. Code is from here : https://stackoverflow.com/a/60978253/15213069

    add_filter( 'woocommerce_related_products', 'mysite_filter_related_products', 10, 1 );
function mysite_filter_related_products( $related_product_ids ) {

    foreach( $related_product_ids as $key => $value ) {
        $relatedProduct = wc_get_product( $value );
        if( ! $relatedProduct->is_in_stock() ) {
            unset( $related_product_ids["$key"] );
        }
    }

    return $related_product_ids;
}

Upvotes: -1

LoicTheAztec
LoicTheAztec

Reputation: 253773

UPDATE 2021

You can use the following:

add_filter( 'woocommerce_product_related_posts_query', 'alter_product_related_posts_query', 10, 3 );
function alter_product_related_posts_query( $query, $product_id, $args ){
    global $wpdb;

    $query['join']  .= " INNER JOIN {$wpdb->postmeta} as pm ON p.ID = pm.post_id ";
    $query['where'] .= " AND pm.meta_key = '_stock_status' AND meta_value = 'instock' ";
    
    return $query;
}

Code goes in functions.php file of your active child theme (or active theme).

Now we need to remove "related products" cached data deleting the related transients to flush this cache (thanks to @Cody Rees).

There is 2 ways to do it:

1). The easiest way:

Go to admin Woocommerce > Status > Tools > WooCommerce transients and press on "Clear transcients".

2). The other way targeting specific related transients to be deleted:

Add the following code and save:

add_action('init', 'delete_related_products_cached_data');
function delete_related_products_cached_data() {
    global $wpdb;

    $wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE `option_name` LIKE '_transient_wc_related_%'");
}

Code goes in functions.php file of your active child theme (or active theme).

Run it only once by browsing any page of your web site and remove it.

Upvotes: 6

dmoz
dmoz

Reputation: 1265

None of the answers given here worked for me (I believe the woocommerce_output_related_products_args filter mentioned does not accept meta_queries), and I wanted a solution that didn't use an SQL query, so I put together the solution below:

add_filter( 'woocommerce_related_products', 'mysite_filter_related_products', 10, 1 );
function mysite_filter_related_products( $related_product_ids ) {

    foreach( $related_product_ids as $key => $value ) {
        $relatedProduct = wc_get_product( $value );
        if( ! $relatedProduct->is_in_stock() ) {
            unset( $related_product_ids["$key"] );
        }
    }

    return $related_product_ids;
}

Hope that helps someone looking for a similar solution.

Upvotes: 16

thetwopct
thetwopct

Reputation: 1671

Yes it's possible to hide out of stock products from related products.

Add the below to functions.php – this will hide out of stock products from related products.

add_filter( 'woocommerce_output_related_products_args', function( $args )
{
    $args = wp_parse_args( array(
        'posts_per_page' => 4,
        'meta_query' => array (
           'key' => '_stock_status',
           'value' => 'instock'
    )
    ), $args );
    return $args;
});

The posts per page line can be removed, but its useful as a quick of visualising that this has worked on your related products block.

Upvotes: 1

Hritik Pandey
Hritik Pandey

Reputation: 949

create a function and hook it to related products hook of woocommerce like:

function dont_show_outofstock( $is_visible, $id ) {
    $product = new wC_Product( $id );

    if ( ! $product->is_in_stock() && ! $product->backorders_allowed() ) {
    $is_visible = false;
    }

    return $is_visible;
}
add_filter( 'woocommerce_output_related_products_args', 'dont_show_outofstock', 10, 2 );

Upvotes: -2

Related Questions