Take the 2-minute tour ×
WordPress Development Stack Exchange 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
    
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. –  Jamie Sep 26 '12 at 15:41
    
There is (Out of stock visibility), but WooCommerce doesn't obey it when showing results from the Layered Nav widget. –  Magnakai Apr 2 '13 at 15:24
add comment

closed as off-topic by kaiser Mar 16 at 16:36

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

2 Answers

// Out of stock for general woocommerce - might help someone

            function product_in_stock($post, $product) {

                    if (!$product->is_in_stock()) {

                        $STOCK = TRUE;
                        return $STOCK;

                } else {
                    return false;
                }
            }

            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>";
            }
share|improve this answer
1  
Please explain what you are doing here, and why this will/should work. Your code makes not much sense to me - at least uncommented/unexplained. –  t f Feb 5 at 18:40
    
This wraps a div with a class of outofstock or instock around the product. You can then style each of these classes. Eg. .outofstock {display:none;} –  raison Mar 6 at 14:36
add comment
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
    
This code does not work anymore - see this question. –  kaiser Mar 16 at 16:37
add comment

protected by Community Mar 15 at 23:13

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

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