I have revisited your code as there was some mistakes (everything is commented in the code). Also:
-
You can use
current_user_can()
to check a user role for the current user. -
You can use
has_term()
conditional function to check for post terms of any taxonomy.
The following code will hide products that belongs to a specific product category from user that have not a specific user role. If they try to access that specific products, they will be redirected to shop page with a custom notice…
Additionally the ajax add to cart button or the “Read more” button is replaced on all products loop for that specific products by a disable greyed button (in front end only).
Here is the code:
// Hide specific products from shop and archives pages
add_action( 'woocommerce_product_query', 'wcpp_hide_product' );
function wcpp_hide_product( $q ) {
// skip for main query and on admin
if ( ! $q->is_main_query() || is_admin() )
return;
// Hide specific products for unlogged users or users without PRIVATE_MEMBER user role
if ( is_user_logged_in() || ! current_user_can('PRIVATE_MEMBER') ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'term_id', // it's not 'id' but 'term_id' (or 'name' or 'slug')
'terms' => 'PRIVATE_CATEGORY',
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );
}
}
// Replace add to cart button by a disabled button on specific products in Shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_link', 'wcpp_replace_loop_add_to_cart_button', 10, 2 );
function wcpp_replace_loop_add_to_cart_button( $button, $product ) {
if ( ( is_user_logged_in() || ! current_user_can('PRIVATE_MEMBER') )
&& has_term( 'PRIVATE_CATEGORY', 'product_cat', $product->get_id() ) ) {;
$button = '<a class="button alt disabled">' . __( "Private", "woocommerce" ) . '</a>';
}
return $button;
}
// On single product pages, redirect to shop and display a custom notice for specific products
add_action( 'template_redirect', 'wcpp_redirect_hiding_product_detail' );
function wcpp_redirect_hiding_product_detail() {
if ( ( is_user_logged_in() || ! current_user_can('PRIVATE_MEMBER') )
&& has_term( 'PRIVATE_CATEGORY', 'product_cat' ) && is_product() ) {
// Add a notice (optional)
wc_add_notice(__("Sorry, but you are not allowed yet to see this product."), 'notice' );
// Shop redirection url
$redirect_url = get_permalink( get_option('woocommerce_shop_page_id') );
wp_redirect($redirect_url); // Redirect to shop
exit(); // Always exit
}
}
Code goes in function.php file of your active child theme (or active theme), or in a plugin file.
Tested and works.