Search code examples
woocommercehook-woocommercewoocommerce-theming

Hide completely from anywhere on my site any product that has no category. : wooCommerce


In my wooCommerce platform, I do not want to show products that do not have a category selected. I mean which products categories is empty that's products are not display in my site. Is it any way to do that?


Solution

  • There are different ways to retrieve products, and if you want to exclude products which have no category assigned to from everywhere in your site, then you will need to address all of them.

    WP_Query

    You can hook into the pre_get_posts action and modify the tax_query arg in order to exclude products in the uncategorized product category (only when the query post type is product). I'm in fact assuming uncategorized being the slug of the default product category (you will need to amend it to your specific configuration). E.g.:

    function remove_uncategorized_products( $query ) {
      if ( is_admin() ) {
        return;
      }
      if ( 'product' !== $query->get( 'post_type' ) ) {
        return;
      }
      $tax_query = (array) $query->get( 'tax_query' );
      $tax_query[] = array(
        'taxonomy' => 'product_cat',
        'field' => 'slug',
        'terms' => array( 'uncategorized' ),
        'operator' => 'NOT IN',
      );
      $query->set( 'tax_query', $tax_query );
    }
    add_action( 'pre_get_posts', 'remove_uncategorized_products' );
    

    WC_Query

    Similar to WP_Query, you can hook into the woocommerce_product_query action to modify the query. E.g.:

    function custom_pre_get_posts_query( $q ) {
      $tax_query = (array) $q->get( 'tax_query' );
      $tax_query[] = array(
        'taxonomy' => 'product_cat',
        'field' => 'slug',
        'terms' => array( 'uncategorized' ),
        'operator' => 'NOT IN'
      );
      $q->set( 'tax_query', $tax_query );
    }
    add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );
    

    WC_Product_Query (used by wc_get_products)

    In this case, we can't change the query args to exclude certain product categories. We can instead loop through each product returned by the query and check its category. E.g.:

    function filter_uncategorized_products_out( $results, $args ) {
      $products = array();
      foreach ( $results as $p ) {
        $is_uncategorized = false;
        $terms = get_the_terms( $p->get_id(), 'product_cat' );
        foreach ( $terms as $term ) {
          if ( 'uncategorized' === $term->slug ) {
            $is_uncategorized = true;
          }
        }
        if ( ! $is_uncategorized ) {
          $products[] = $p;
        }
      }
      return $products;
    }
    add_filter( 'woocommerce_product_object_query', 'filter_uncategorized_products_out', 10, 2 );
    

    Please note that there are other ways to retrieve products (for example using $wpdb directly). You might need to check all the pages of your site to see if you have covered them all.