• SideKick Dan

    (@shout-out-sidekick)


    Hey guys,

    This isn’t as much of a question as it is an answer to one for many of you. I spent hours trolling the net trying to find the answer to how to restrict or hide products and categories in woocommerce from specific user roles. Right now there didn’t seem to be any one place where the answer was located. Some persons showed you how to hide the category link, but the products still showed up. Others showed you how to redirect to another page an unauthorised user who clicked on a restricted category, but the category link was still visible, etc. And of course the only plugins to do such a simple task are kind of pricey 🙂 So here’s what’s worked for me. HOpe it helps some of you.

    Place the following code into your child theme’s function.php file. Comments inline. The category i wanted to ‘hide’ only from unauthorised user roles was ‘specials’. The user roles i wanted to have access to view this category and associated products were ‘customer’ or ‘administrator’.

    // Woocommerce - Redirect unauthorised users from accessing a specified product category when clicked or visited via direct url
    
    function woocommerce_hide_non_registered() {
     if( ( is_product_category('specials') ) && ! ( current_user_can( 'customer' ) || current_user_can( 'administrator' ) ) ) {
    
     wp_redirect( site_url( '/' ) );
    
     exit();
     }
    }
    add_action( 'template_redirect','woocommerce_hide_non_registered' );
    
    // End - Woocommerce - redirect unauthorised users from accessing a specified product category
    
    // Woocommerce - Removes category link from woocommerce product category widgets so they are not seen
    
    add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );
    
    function get_subcategory_terms( $terms, $taxonomies, $args ) {
    
      $new_terms = array();
    
      // if a product category and on the shop page
      if ( in_array( 'product_cat', $taxonomies ) && ! ( current_user_can( 'customer' ) || current_user_can( 'administrator' ) ) && is_shop() ) {
    
        foreach ( $terms as $key => $term ) {
    
          if ( ! in_array( $term->slug, array( 'specials' ) ) ) {
            $new_terms[] = $term;
          }
    
        }
    
        $terms = $new_terms;
      }
    
      return $terms;
    }
    
    // End - Woocommerce - Removes category link from woocommerce product category widgets so they are not seen
    
    // Woocommerce - Remove products from being displayed that belong to a category user is not authorised to visit. Products seem to still be accessible via direct url unfortunately.
    
    add_action( 'pre_get_posts', 'custom_pre_get_posts' );
    
    function custom_pre_get_posts( $q ) {
    
    		if ( ! $q->is_main_query() ) return;
    
    		if ( ! $q->is_post_type_archive() ) return;
    
    		if ( ! ( current_user_can( 'customer' ) || current_user_can( 'administrator' ) ) && is_shop() ) {
    
    			   $q->set( 'tax_query', array(array(
    
    				   'taxonomy' => 'product_cat',
    
    				   'field' => 'slug',
    
    				   'terms' => array( 'specials'), // Don't display products in the private-clients category on the shop page
    
    				   'operator' => 'NOT IN'
    
    			   )));
    
    		}
    
    remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' ); 
    
    }
    
    // End - Woocommerce - Remove products from being displayed that belong to a category user is not authorised to visit. Products seem to still be accessible via direct url unfortunately.
Viewing 11 replies - 1 through 11 (of 11 total)
  • Hey Dan,

    Thank you for posting this. This is exactly what I need but for some reason it does not seem to be hiding the category from the woocommerce product category widget. Any ideas?

    -Category i’m trying to hide ‘display’
    -I would like the Category ‘display’ to be visable only to ‘wholesale customer’ and ‘administrator’

    -website link here

    Here is the code I have.

    // Woocommerce - Redirect unauthorised users from accessing a specified product category when clicked or visited via direct url
    
    function woocommerce_hide_non_registered() {
     if( ( is_product_category('display') ) && ! ( current_user_can( 'wholesale customer' ) || current_user_can( 'administrator' ) ) ) {
     wp_redirect( site_url( '/' ));
     exit();
     }
    }
    add_action( 'template_redirect','woocommerce_hide_non_registered' );
    // End - Woocommerce - redirect unauthorised users from accessing a specified product category
    // Woocommerce - Removes category link from woocommerce product category widgets so they are not seen
    add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );
    function get_subcategory_terms( $terms, $taxonomies, $args ) {
      $new_terms = array();
      // if a product category and on the shop page
      if ( in_array( 'product_cat', $taxonomies ) && ! ( current_user_can( 'wholesale customer' ) || current_user_can( 'administrator' ) ) && is_shop() ) {
        foreach ( $terms as $key => $term ) {
          if ( ! in_array( $term->slug, array( 'display' ) ) ) {
            $new_terms[] = $term;
          }
        }
        $terms = $new_terms;
      }
      return $terms;
    }
    // End - Woocommerce - Removes category link from woocommerce product category widgets so they are not seen
    // Woocommerce - Remove products from being displayed that belong to a category user is not authorised to visit. Products seem to still be accessible via direct url unfortunately.
    add_action( 'pre_get_posts', 'custom_pre_get_posts' );
    function custom_pre_get_posts( $q ) {
    		if ( ! $q->is_main_query() ) return;
    		if ( ! $q->is_post_type_archive() ) return;
    		if ( ! ( current_user_can( 'wholesale customer' ) || current_user_can( 'administrator' ) ) && is_shop() ) {
    			   $q->set( 'tax_query', array(array(
    				   'taxonomy' => 'product_cat',
    				   'field' => 'slug',
    				   'terms' => array( 'display'), // Don't display products in the private-clients category on the shop page
    				   'operator' => 'NOT IN'
    			   )));
    		}
    remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
    }
    // End - Woocommerce - Remove products from being displayed that belong to a category user is not authorised to visit. Products seem to still be accessible via direct url unfortunately.

    Hi Sidekick Dan and Stan_Joco,

    I just started a new thread that is similar to your post here :
    https://wordpress.org/support/topic/function-to-hide-product-ids-from-seperate-user-ids

    Would it be possible for your code to hide product iDs for everyone, but be only visible to a few user IDs ?

    The store is password protected so I wouldn’t use the redirect portion of the code.

    I can’t find any info anywhere. Your post is the closest so far !!

    Thanks in advance

    @jgoug:
    I think it will work correctly if you assigned the few users into a specific user role such as “subscriber” or “author”

    You might have to customize the user privileges to match your needs.

    Huge thanks to SideKick Dan for posting the original code!!!

    Here is a copy of the final code I used.
    Changes I made to the original code:
    1. Changed the product category slug from ‘specials’ to ‘display’
    2. Changed one of the users that could view the hidden prod. category from
    ‘customer’ to ‘wholesale_customer’
    3. Removed ‘&& is_shop()’ from the if statement (this appears twice in the original code). The original code left the category visible in the woocommerce widget.

    My revised Code.

    // Woocommerce - Redirect unauthorised users from accessing a specified product category when clicked or visited via direct url
    
    function woocommerce_hide_non_registered() {
     if( ( is_product_category('display') ) && ! ( current_user_can( 'wholesale_customer' ) || current_user_can( 'administrator' ) ) ) {
     wp_redirect( site_url( '/' ));
     exit();
     }
    }
    add_action( 'template_redirect','woocommerce_hide_non_registered' );
    // End - Woocommerce - redirect unauthorised users from accessing a specified product category
    // Woocommerce - Removes category link from woocommerce product category widgets so they are not seen
    add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );
    function get_subcategory_terms( $terms, $taxonomies, $args ) {
      $new_terms = array();
      // if a product category and on the shop page
      if ( in_array( 'product_cat', $taxonomies ) && ! ( current_user_can( 'wholesale_customer' ) || current_user_can( 'administrator' ) ) ) {
        foreach ( $terms as $key => $term ) {
          if ( ! in_array( $term->slug, array( 'display' ) ) ) {
            $new_terms[] = $term;
          }
        }
        $terms = $new_terms;
      }
      return $terms;
    }
    // End - Woocommerce - Removes category link from woocommerce product category widgets so they are not seen
    // Woocommerce - Remove products from being displayed that belong to a category user is not authorised to visit. Products seem to still be accessible via direct url unfortunately.
    add_action( 'pre_get_posts', 'custom_pre_get_posts' );
    function custom_pre_get_posts( $q ) {
    		if ( ! $q->is_main_query() ) return;
    		if ( ! $q->is_post_type_archive() ) return;
    		if ( ! ( current_user_can( 'wholesale_customer' ) || current_user_can( 'administrator' ) ) ) {
    			   $q->set( 'tax_query', array(array(
    				   'taxonomy' => 'product_cat',
    				   'field' => 'slug',
    				   'terms' => array( 'display'), // Don't display products in the private-clients category on the shop page
    				   'operator' => 'NOT IN'
    			   )));
    		}
    remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
    }
    // End - Woocommerce - Remove products from being displayed that belong to a category user is not authorised to visit. Products seem to still be accessible via direct url unfortunately.
    ballyhoot

    (@ballyhoot)

    This code is perfect for what I needed. Out of the box it worked except for when a non-logged-in user searches directly for a product.So, just copy and pasted the if statement in your first function for every subcategory or product I needed restricted.

    function woocommerce_hide_non_registered() {
    if( ( is_product_category(‘display’) ) && ! ( current_user_can( ‘wholesale_customer’ ) || current_user_can( ‘administrator’ ) ) ) {
    wp_redirect( site_url( ‘/’ ));
    exit();
    }

    I changed is_product_category to is_product and it worked for products to. If you have a lot of products you have to do an if statement for every one.

    ballyhoot

    (@ballyhoot)

    After I slept on it the code started to redirect from every product page, not just products I wanted to be hidden.

    Hi,

    I used the code from: Stan_Joco(which is originally from SideKick Dan.

    Only changed the categoryname (specials) and User-role “wholesale-user” changed to “customer”.

    Unfortunately the specials-category (and it’s products) are still visible.

    Is there someone that can help me with this?
    Thanks?


    Code I have added to the functions.php of the theme.

    ——

    // Woocommerce – Redirect unauthorised users from accessing a specified product category when clicked or visited via direct url
    function woocommerce_hide_non_registered() {
    if( ( is_product_category(‘specials’) ) && ! ( current_user_can( ‘staffel_g_klanten’ ) || current_user_can( ‘administrator’ ) ) ) {

    wp_redirect( site_url( ‘/’ ) );

    exit();
    }
    }
    add_action( ‘template_redirect’,’woocommerce_hide_non_registered’ );
    // End – Woocommerce – redirect unauthorised users from accessing a specified product category
    // Woocommerce – Removes category link from woocommerce product category widgets so they are not seen
    add_filter( ‘get_terms’, ‘get_subcategory_terms’, 10, 3 );
    function get_subcategory_terms( $terms, $taxonomies, $args ) {
    $new_terms = array();
    // if a product category and on the shop page
    if ( in_array( ‘product_cat’, $taxonomies ) && ! ( current_user_can( ‘staffel_g_klanten’ ) || current_user_can( ‘administrator’ ) ) && is_shop() ) {
    foreach ( $terms as $key => $term ) {
    if ( ! in_array( $term->slug, array( ‘specials’ ) ) ) {
    $new_terms[] = $term;
    }
    }
    $terms = $new_terms;
    }
    return $terms;
    }
    // End – Woocommerce – Removes category link from woocommerce product category widgets so they are not seen
    // Woocommerce – Remove products from being displayed that belong to a category user is not authorised to visit. Products seem to still be accessible via direct url unfortunately.
    add_action( ‘pre_get_posts’, ‘custom_pre_get_posts’ );

    function custom_pre_get_posts( $q ) {

    if ( ! $q->is_main_query() ) return;

    if ( ! $q->is_post_type_archive() ) return;

    if ( ! ( current_user_can( ‘staffel_g_klanten’ ) || current_user_can( ‘administrator’ ) ) && is_shop() ) {

    $q->set( ‘tax_query’, array(array(

    ‘taxonomy’ => ‘product_cat’,

    ‘field’ => ‘slug’,

    ‘terms’ => array( ‘specials’), // Don’t display products in the private-clients category on the shop page

    ‘operator’ => ‘NOT IN’

    )));

    }

    remove_action( ‘pre_get_posts’, ‘custom_pre_get_posts_query’ );

    }
    // End – Woocommerce – Remove products from being displayed that belong to a category user is not authorised to visit. Products seem to still be accessible via direct url unfortunately.
    //to do figure out how to restrict a product located in an unauthorised category based on the url

    Minor change:
    Not “customer” but staffel_g_klanten”” , which is the customergroup (Role) I want to make the “specials” visible to.

    Minor change:
    Not “customer” but staffel_g_klanten”” , which is the customergroup (Role) I want to make the “specials” visible to.

    Hi Stan_Joco

    I used your code and got it working.
    HOWEVER it seems that the filtered/hidden shows up in the product-categories sidebar widget once you have visited a product.

    Can you please give me some advise how to solve this?

    Thanks
    Bram

    You can use the WooCommerce Products Visibility plugin.

    This plugin hides the selected products, categories and tags from your whole website, eg. from the menus, the widgets and even from the theme you use, as long as the theme is using WordPress filters.

Viewing 11 replies - 1 through 11 (of 11 total)
  • The topic ‘Woocommerce Restrict or Hide Products and Categories from specific user roles’ is closed to new replies.