-
-
Save DarkAllMan/cffb114eb97c6f26882e54793e023587 to your computer and use it in GitHub Desktop.
| <?php | |
| /** | |
| Plugin Name: WooCommerce - Hide categories where no products are visible to user | |
| Plugin URI: https://www.randall.nl | |
| Description: Excludes categories with no visible products from the WooCommerce category overview in shop | |
| Version: 1.2 | |
| Author: Randall Kam | |
| Author URI: https://www.randall.nl | |
| */ | |
| if ( ! defined( 'ABSPATH' ) ) { | |
| exit; // Exit if accessed directly | |
| } | |
| if ( !class_exists( 'ExcludeCats' ) ) : | |
| class ExcludeCats { | |
| public $version = '1.2', | |
| $do = false, | |
| $exclude = array(); | |
| protected static $_instance = null; | |
| /** | |
| * Main Plugin Instance | |
| * | |
| * Ensures only one instance of plugin is loaded or can be loaded. | |
| */ | |
| public static function instance() { | |
| if ( is_null( self::$_instance ) ) { | |
| self::$_instance = new self(); | |
| } | |
| return self::$_instance; | |
| } | |
| /** | |
| * Constructor | |
| */ | |
| public function __construct() { | |
| add_action('wp action', array( $this, 'checkShopSearch' ), 10, 1 ); | |
| // CHECK CATEGORIES FOR VISIBLE PRODUCTS | |
| add_action('wp_head', array( $this, 'get_excluded_cats' ), 10, 3 ); | |
| // ADD THE SHOP FILTER | |
| add_filter( 'woocommerce_product_subcategories_args', array( $this, 'filter_woocommerce_product_subcategories_args'), 10, 1 ); | |
| // ADD THE WIDGET SIDEBAR FILTER | |
| add_filter( 'woocommerce_product_categories_widget_args', array( $this, 'kfg_exclude_categories_from_widget'), 10, 1 ); | |
| } | |
| // CHECK IF WE NEED TO RUN EVERYTHING | |
| public function checkShopSearch($query){ | |
| if(is_shop() || is_search()){ | |
| $this->do = true; | |
| } | |
| } | |
| // GET CATEGORIES WITH NO VISIBLE PRODUCTS AND PUT IN GLOBAL IF GLOBAL FALSE | |
| public function get_excluded_cats( $terms, $taxonomies = NULL, $args = NULL ) { | |
| if(!$terms){ | |
| return; | |
| } | |
| $current_tax = get_query_var( 'product_cat' ); | |
| $term =get_term_by( 'slug', $current_tax, 'product_cat'); | |
| $term_id = $term->term_id; | |
| $args = array( | |
| 'parent' => $term_id, | |
| 'hide_empty' => false, | |
| 'hierarchical' => false, | |
| ); | |
| $product_categories = get_terms( 'product_cat', $args ); | |
| // if a product category and on the shop page | |
| //if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_shop() ) { | |
| if ( ! is_admin() && is_shop() ) { | |
| foreach ( $product_categories as $key => $term ) { | |
| unset($this->exclude); | |
| if($term->taxonomy=='product_cat'){ | |
| $posts = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => $term->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 ) { | |
| $this->exclude[] = $term->term_id; | |
| } | |
| } | |
| } | |
| } | |
| public function get_parent_cats ($cat_termid, $found = array()) { | |
| array_push ($found, $cat_termid); | |
| $term = get_term_by( 'term_id', $cat_termid, 'product_cat'); | |
| if( !is_object($term) ) { | |
| return $found; | |
| } | |
| if($term->parent > 0){ | |
| return $this->get_parent_cats($term->parent, $found); | |
| } | |
| return $found; | |
| } | |
| // ADD FILTERS FOR CATEGORIES AND EXCLUDE EMPTY | |
| public function filter_woocommerce_product_subcategories_args( $temp_args = array() ) { | |
| $current_tax = get_query_var( 'product_cat' ); | |
| $term =get_term_by( 'slug', $current_tax, 'product_cat'); | |
| if( !is_object($term) ) { | |
| return $temp_args; | |
| } | |
| $term_id = $term->term_id; | |
| $temp_args = array( | |
| 'parent' => $term_id, | |
| 'menu_order' => 'ASC', | |
| 'hide_empty' => 1, | |
| 'hierarchical' => 1, | |
| 'taxonomy' => 'product_cat', | |
| 'pad_counts' => 1, | |
| 'include' => NULl, | |
| 'exclude' => $this->exclude, | |
| ); | |
| return $temp_args; | |
| } | |
| public function kfg_exclude_categories_from_widget( $category_list_args ) { | |
| $current_tax = get_query_var( 'product_cat' ); | |
| $term = get_term_by( 'slug', $current_tax, 'product_cat'); | |
| if( !is_object($term) ) { | |
| return $category_list_args; | |
| } | |
| $term_id = $term->term_id; | |
| $parents = $this->get_parent_cats($term_id); | |
| $args = array( | |
| 'hide_empty' => false, | |
| 'hierarchical' => true, | |
| ); | |
| $product_categories = get_terms( 'product_cat', $args ); | |
| $wexclude = 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 || ( $category->parent > 0 && !in_array($category->parent,$parents) ) ) { | |
| $wexclude[] = $category->term_id; | |
| } | |
| } | |
| if ( ! empty( $wexclude ) ) { | |
| $category_list_args['exclude'] = implode( ',', $wexclude ); | |
| unset( $category_list_args['include'] ); | |
| } | |
| return $category_list_args; | |
| } | |
| } // class ExcludeCats | |
| endif; // class_exists | |
| /** | |
| * Returns the main instance of the plugin class to prevent the need to use globals. | |
| * | |
| * @since 2.0 | |
| * @return WooCommerce_PostcodeAPInu | |
| */ | |
| function ExcludeCats() { | |
| return ExcludeCats::instance(); | |
| } | |
| ExcludeCats(); // load plugin |
It does not hide categories that have items with no stock.
It only hides categories where the visitor has no visible items.
On my site, some products are only visible to a certain group of customers, so the category is only visible to them.
Other users have no visible items in that category and so they do not see it listed anywhere :)
Ah right okay, so not what I was after at all... I'm sorry to have put you to work for no reason! Haha!
Hopefully the updates you made will help others though.
I wonder if I might be able to adapt your plugin for my needs?
Do you think if I were able to change the 'visibility' check to a stock level check it might work?
Regardless of whether your plugin can be adapted, thank you for taking the time to respond to my call for help :)
It probably can be implemented in there, but it will be stressfull on categories with a lot of products, as it will need to check each product for stock.
Ah right, so it could potentially slow the site to a grinding halt trying to check a large number of products... I might need to rethink my requirements.
I was hoping for something that would automatically hide a category when stock ran out... then have it magically reappear if we get more stock in for the category.
Guess I'll need to be a more pro-active with manually monitoring them instead... damn it, more work for me haha!
It's no longer causing a fatal error :)
However it doesn't seem to be be hiding categories with no products in stock though.
Do I perhaps have it set up wrong, or have I misunderstood the plugin? Sorry!
If you look here: https://comicbookshop.co.nz/product-category/comic-supplies/comic-book-boards/
You'll see 'Comic Book Boards - Silver' as a subcategory option, however this doesn't have any in stock items in it.