Tell me more ×
WordPress Answers is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

WooCommerce includes a handy Layered Nav widget. This allows you to filter the catalog items based on attributes that you've set, including for variations of items (like different sizes.)

However, if you select a variation that's out of stock, it is still returned. I've been trying to alter the widget code, but it's proving extremely complicated for my little brain.

Here's the widget code: https://github.com/woothemes/woocommerce/blob/master/widgets/widget-layered_nav.php

If anyone could provide any pointers, it would be much appreciated.

share|improve this question

2 Answers

isn't there a setting in wooCommerce that allows you to not show an item if it is out of stock? I do believe there is. I would start in the settings for the theme rather than trying to alter the code.

share|improve this answer
There is (Out of stock visibility), but WooCommerce doesn't obey it when showing results from the Layered Nav widget. – Magnakai Apr 2 at 15:24
up vote 0 down vote accepted

It's not easy, but a colleague and I did it.

Some of this is specific to our use case, and it will not be very performant on larger catalogues, but it technically works. As there's not way of telling if this is the case before fetching the items, we display all items on a page and simply display:none on the out of stock items. Again, this is a workaround but works for our purposes.

function product_in_stock($post, $product) {
    if ($_GET['filtering'] == 1 && $_GET['filter_size'] > 0 ) {
        $STOCK = FALSE;
        $slugmap = array();
        $attribs = $product->get_variation_attributes();
        $terms = get_terms( sanitize_title( 'pa_size' ));
        if($terms)foreach($terms as $term)$slugmap[$term->slug]=$term->term_id;
        $available = $product->get_available_variations();
        if($available)foreach($available as $instockitem){
            if(isset($instockitem["attributes"]["attribute_pa_size"])){
                if(isset($slugmap[$instockitem["attributes"]["attribute_pa_size"]])){
                    if($slugmap[$instockitem["attributes"]["attribute_pa_size"]] == $_GET["filter_size"]){
                        $STOCK = TRUE;
                    }
                }
            }
        }
        return $STOCK;
    } else {
        return true;
    }
}

function check_if_out_of_stock(){
    global $post,$product;
    $stock = product_in_stock($post,$product);

    $output = '<div class="';
    $output .= $stock?"instock":"outofstock";
    $output .= '">';
    echo $output;
}

add_action( 'woocommerce_before_shop_loop_item', 'check_if_out_of_stock');

function close_out_of_stock(){
    echo "</div>";
}

add_action( 'woocommerce_after_shop_loop_item', 'close_out_of_stock');
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.