nektaria
nektaria

Reputation: 37

How can i hide a product category on woocommerce category list menu when all the products under this category are out of stock?

I have checked from Woocommerce--> Inventory the option to hide "out of stock" products from my eshop. Now, i am trying to find out how i can hide a category from category list menu widget that has only out of stock products. Any idea? Thanks in advance. i use iks menu plugin.

I tried

function exclude_categories( $category_list_args ) {

$args = array(
    'hide_empty' => false,
    'hierarchical' => true,
);

$product_categories = get_terms( 'product_cat', $args );

$exclude = array();
foreach ( $product_categories as $category ) {

    $posts         = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => $category->slug, 'fields' => 'ids' ) );
    $show_category = false;

    foreach ( $posts as $post ) {

        $product         = new wC_Product( $post );
        $visible_product = $product->is_visible();

        if ( true === $visible_product ) {
            $show_category = true;
            break;
        }

    }

    if ( false === $show_category ) {
        $exclude[] = $category->term_id;
    }

}

if ( ! empty( $exclude ) ) {
    $category_list_args['exclude'] = implode( ',', $exclude );
    unset( $category_list_args['include'] );
}

return $category_list_args;

}
add_filter( 'woocommerce_product_categories_widget_args', 'exclude_categories', 10, 1 );

Which hook should i use instead of woocommerce_product_categories_widget_args ? I use iks menus plugin to show on accordion the list of products categories. The code above works on Woocommerce Product Categories Widget but not on iks menu widget...

On iks menu plugin, the function that is responsible for showing the categories on widget sidebar is

private function get_WP_terms() {
    $taxonomy = $this->get_taxonomy();

    if ( $taxonomy ) {
        $this->args = [
            "taxonomy" => $taxonomy,
        ];
        $this->save_args( [
            "orderby",
            "order",
            "hide_empty",
            "hierarchical",
            "include",
            "exclude",
            "search",
            "child_of",
            "parent",
            "childless",
        ] );

        if ( version_compare( get_bloginfo( 'version' ), '4.5', '>=' ) ) {
            $items = get_terms( $this->args );
        } else {
            $items = get_terms( $taxonomy, $this->args );
        }

        if ( is_array( $items ) ) {
            if ( ! empty( $items ) ) {
                $index      = 0;
                $show_posts = $this->settings_manager->get_value( "show_posts" );

                /* Posts */
                if ( $show_posts ) {
                    $post_type   = Utils::get_post_type_by_taxonomy( $taxonomy );
                    $include     = $this->settings_manager->get_value( "include" );
                    $has_include = ! empty( $include );

                    $posts = get_posts( [
                        'post_type'        => $post_type,
                        'posts_per_page'   => - 1,
                        'orderby'          => 'date',
                        'order'            => 'DESC',
                        'tax_query'        => [
                            [
                                'taxonomy' => $taxonomy,
                                'operator' => $has_include ? 'IN' : 'EXISTS',
                                'terms'    => $has_include ? Utils::get_terms_ids( $items ) : [],
                            ]
                        ],
                         
                        'suppress_filters' => false // [Fix] WPML compatibility
                    ] );

                    $posts_by_terms = [];
                    foreach ( $posts as $post ) {
                        $terms = get_the_terms( $post, $taxonomy );
                        if ( ! empty( $terms ) ) {
                            foreach ( $terms as $term ) {
                                if ( ! isset( $posts_by_terms[ $term->term_id ] ) ) {
                                    $posts_by_terms[ $term->term_id ] = [];
                                }
                                $posts_by_terms[ $term->term_id ][] = $post;
                            }
                        }
                    }
                }

                foreach ( $items as $key => $item ) {
                    $id   = (int) $item->term_id;
                    $link = get_term_link( $id );

                    $item_data = [
                        "id"                    => $id,
                        "title"                 => $item->name,
                        "link"                  => $link,
                        "parent"                => (int) $item->parent,
                        "is_current"            => $this->is_current_page_url( $link ) || $this->get_queried_object_term_id() === $id,
                        "is_term_includes_post" => $this->is_term_includes_post( $id, $this->get_taxonomy() ),
                        "is_page_includes_post" => false,
                        "index"                 => $index,
                        "is_expanded"           => false,
                        "posts_count"           => $item->count,
                        "is_post"               => false,
                        "target"                => null,
                    ];
                    $index ++;

                    $this->data[] = $item_data;

                    if ( $show_posts ) {
                        if ( isset( $posts_by_terms[ $id ] ) ) {
                            $result_posts = $posts_by_terms[ $id ];
                            foreach ( $result_posts as $post ) {
                                $post_link    = get_permalink( $post->ID );
                                $this->data[] = [
                                    "id"                    => $post->ID,
                                    "title"                 => $post->post_title,
                                    "link"                  => $post_link,
                                    "parent"                => $id,
                                    "is_current"            => $this->is_current_page_url( $post_link ),
                                    "is_term_includes_post" => false,
                                    "is_page_includes_post" => false,
                                    "index"                 => $index,
                                    "is_expanded"           => false,
                                    "posts_count"           => false,
                                    "is_post"               => true,
                                    "target"                => null,
                                ];
                                $index ++;
                            }
                        }
                    }
                }
            }

i suppose that i need something like

  'meta_query' => array(
    array(
        'key' => '_stock_status',
        'value' => 'instock',
        'compare' => '=',
    )
) 

but i am a little bit confused...

Upvotes: 0

Views: 1127

Answers (1)

Fresz
Fresz

Reputation: 1913

The only way we can find the post count per category was by getting all categories (terms) of product_cat. Then we looped through them - each time calling my function get_count and passing term_id. In the get_count we run a query to get all posts associated with it and we also pass post meta _stock_status = instock. This return all products where the stock status is in stock. Then we return found_posts attribute back - the IF statement then checks is the post count is bigger than 0.

The code (tested):

add_shortcode('test_test','test_test');
function test_test() {

    $terms = get_terms('product_cat');

    foreach($terms as $term) {

        $post_count = get_count($term->term_id);

        if($post_count > 0) {
            echo $term->name . '<br>'; //This is where you put your category details
        }  
    }
}

function get_count($cat_id) {

    $args = array(
        'tax_query' => array(
            array(
                'taxonomy' => 'product_cat',
                'field' => 'id',
                'terms' => array($cat_id),
                'include_children' => false
              )
        ),
        'posts_per_page' => -1,
        'post_type' => 'product',
        'post_status' => 'publish',
        'meta_key' => '_stock_status',
        'meta_value' => 'instock',
        'meta_compare' => '='
    );

    $wp_query = new WP_Query($args);

    wp_reset_postdata();

    return $wp_query->found_posts;

}

Upvotes: 0

Related Questions