Avoid Add to Cart for Specific Product Categories If User Is Unlogged in Woocommerce

Avoid add to cart for specific product categories if user is unlogged in Woocommerce

The conditional tag is_product_category() only target product category archive pages. Instead you can use WordPress conditional function has_term().

There is 2 ways to avoid specific products being added to cart for no logged user…

1) Using Add to cart validation hook:

// Avoid add to cart conditionally
add_filter( 'woocommerce_add_to_cart_validation', 'avoid_add_to_cart_conditionally', 20, 3 );
function avoid_add_to_cart_conditionally( $passed, $product_id, $quantity) {
// HERE your product categories (can be IDs, slugs or names terms)
$terms = array( 'gekoelde-bier', 'bierkoerier');

if( has_terms( $terms, 'product_cat', $product_id ) && ! is_user_logged_in() ){
// Displaying a custom notice (optional)
wc_add_notice( __('Only logged in users are allowed to purchase this item. Please register.'), 'error' );

$passed = false;
}

return $passed;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Sample Image


2) Using is_purchasable product property (It will remove add to cart button):

add_filter('woocommerce_is_purchasable','conditional_purchasable_products', 20, 2);
function conditional_purchasable_products( $is_purchasable, $product ) {
// HERE your product categories (can be IDs, slugs or names terms)
$terms = array( 'gekoelde-bier', 'bierkoerier');

$product_id = $product->get_id(); // The product ID

if( has_terms( $terms, 'product_cat', $product_id ) && ! is_user_logged_in() ){
$is_purchasable = false;
}

return $is_purchasable;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.



Targeting the parent product category terms too.

You will use the following custom conditional function to replace has_term() Wordpress function:

// Custom conditional function that handle parent product categories too
function has_product_categories( $categories, $product_id = 0 ) {
$parent_term_ids = $categories_ids = array(); // Initializing
$taxonomy = 'product_cat';
$product_id = $product_id == 0 ? get_the_id() : $product_id;

if( is_string( $categories ) ) {
$categories = (array) $categories; // Convert string to array
}

// Convert categories term names and slugs to categories term ids
foreach ( $categories as $category ){
$result = (array) term_exists( $category, $taxonomy );
if ( ! empty( $result ) ) {
$categories_ids[] = reset($result);
}
}

// Loop through the current product category terms to get only parent main category term
foreach( get_the_terms( $product_id, $taxonomy ) as $term ){
if( $term->parent > 0 ){
$parent_term_ids[] = $term->parent; // Set the parent product category
$parent_term_ids[] = $term->term_id; // (and the child)
} else {
$parent_term_ids[] = $term->term_id; // It is the Main category term and we set it.
}
}
return array_intersect( $categories_ids, array_unique($parent_term_ids) ) ? true : false;
}

Then for both hooked functions, you will replace the following line :

if( has_terms( $terms, 'product_cat', $product_id ) && ! is_user_logged_in() ){

By this line:

if( has_product_categories( $terms, $product_id ) && ! is_user_logged_in() ){

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Replace add to cart button for unlogged users in WooCommerce

Update: Added button link on single products to My account login URL

The following will do it all you want in a better way (replacing your code):

// Replacing the button add to cart by a link to the product page in Shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_link', 'replace_loop_add_to_cart_button', 10, 2 );
function replace_loop_add_to_cart_button( $button, $product ) {
// Only for unlogged user
if( ! is_user_logged_in() ){
$button_text = __( "Sign up for pricing", "woocommerce" );
// $button_link = get_permalink( wc_get_page_id( 'myaccount' ) ); // Login Url
$button_link = $product->get_permalink(); // Single product Url
$button = '<a class="button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';
}

return $button;
}

// Replacing the single product button add to cart by a custom button
add_action( 'woocommerce_single_product_summary', 'disabled_single_add_to_cart_button', 1 );
function disabled_single_add_to_cart_button() {
global $product;

// Only for unlogged user
if( ! is_user_logged_in() ){

// For variable product types (keeping attribute select fields)
if( $product->is_type( 'variable' ) ) {
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
add_action( 'woocommerce_single_variation', 'custom_product_button', 20 );
}
// For all other product types
else {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
add_action( 'woocommerce_single_product_summary', 'custom_product_button', 30 );
}
}
}

// The custom replacement button function inked to loggin page
function custom_product_button(){
$login_url = get_permalink( wc_get_page_id( 'myaccount' ) );
echo '<a class="button" href="'.$login_url.'">' . __( "Sign up for pricing", "woocommerce" ) . '</a>';
}

Code goes in functions.php file of your active child theme (active theme). Tested and works.

To make a disabled button on single product page use instead:

// The custom replacement button function with a disabled button
function custom_product_button(){
echo '<a class="button disabled">' . __( "Sign up for pricing", "woocommerce" ) . '</a>';
}

To Hide prices on shop and archive pages:

add_filter( 'woocommerce_after_shop_loop_item_title', 'remove_woocommerce_loop_price', 2 );
function remove_woocommerce_loop_price() {
// Only for unlogged user
if( ! is_user_logged_in() )
remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price', 10 );
}

To remove product price from single product pages:

add_filter( 'woocommerce_single_product_summary', 'remove_woocommerce_single_price', 2 );
function remove_woocommerce_single_price() {
// Only for unlogged user
if( ! is_user_logged_in() )
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
}

// Hide variations price for variable products
add_filter( 'woocommerce_available_variation', 'hide_variations_price_html', 10, 3) ;
function hide_variations_price_html( $data, $product, $variation ) {
// Only for unlogged user
if( ! is_user_logged_in() )
$data['price_html'] = ' ';

return $data;
}

Code goes in functions.php file of your active child theme (active theme). Tested and works.

Disable other product categories for a cart item from specific category in Woocommerce

This code will check for parent product categories, so for a defined product category, it will:

  • Avoid adding to cart other product categories when the defined category is in cart.
  • It will remove cart items from other product categories when a product from the defined category is added to cart.

Improved code:

// Custom conditional function that checks for parent product categories
function has_parent_term( $product_id ) {
// HERE set your targeted product category SLUG
$category_slug = 'beerservice'; // <==== <==== <==== <==== <==== <==== <====

// Convert category term slug to term id
$category_id = get_term_by('slug', $category_slug, 'product_cat')->term_id;
$parent_term_ids = array(); // Initializing

// Loop through the current product category terms to get only parent main category term
foreach( get_the_terms( $product_id, 'product_cat' ) as $term ){
if( $term->parent > 0 ){
$parent_term_ids[] = $term->parent; // Set the parent product category
} else {
$parent_term_ids[] = $term->term_id;
}
}
return in_array( $category_id, $parent_term_ids );
}

// Avoid add to cart others product categories when "beerservice" is in cart
add_filter( 'woocommerce_add_to_cart_validation', 'specific_category_avoid_add_to_cart_others', 20, 3 );
function specific_category_avoid_add_to_cart_others( $passed, $product_id, $quantity) {
if( WC()->cart->is_empty() || has_parent_term( $product_id ) ) {
return $passed;
}

foreach( WC()->cart->get_cart() as $cart_item ){
if( has_parent_term( $cart_item['product_id'] ) ) {
wc_add_notice( __('Alert message 1 (avoid add to cart)', 'woocommerce' ), 'error' ); // Display a custom error notice
return false; // Avoid add to cart
}
}
return $passed;
}

// Remove other items when our specific product is added to cart
add_action( 'woocommerce_add_to_cart', 'conditionally_remove_other_products', 20, 4 );
function conditionally_remove_other_products ( $cart_item_key, $product_id, $quantity, $variation_id ){
if( has_parent_term( $product_id ) ) {
foreach( WC()->cart->get_cart() as $item_key => $cart_item ){
if( ! has_parent_term( $cart_item['product_id'] ) ) {
WC()->cart->remove_cart_item( $item_key );
wc_add_notice( __('Alert message 2 (Item removed from cart)', 'woocommerce' ), 'error' ); // Display a custom error notice
}
}
}
}

Code goes in function.php file of your active child theme (active theme). Tested and works.


Related: Disable shopping when an item from a specific product category is in cart in Woocommerce

Disable add-to-cart for certain categories only matches the first category in array (Woocommerce)

Using the second example here: https://stackoverflow.com/a/53058011/5204226 works (I had to change has_terms to has_term).

function conditional_purchasable_products( $is_purchasable, $product ) {
// HERE your product categories (can be IDs, slugs or names terms)
$terms = array( 'sneakers', 'backpacks');

$product_id = $product->get_id(); // The product ID

if( ! has_term( $terms, 'product_cat', $product_id ) ){
$is_purchasable = false;
}

return $is_purchasable;
}
add_filter('woocommerce_is_purchasable','conditional_purchasable_products', 20, 2);

Remove add to cart button for specific product categories in WooCommerce 3

Updated: (Added compatibility for WooCommerce Product Add-ons plugin in simple products).

Here is the way (for defined product categories for simple and variable product types) to:

  • Optionally, On archives pages: Replace add-to-cart buttons by a linked button to the product.
  • On single product pages: Remove add to cart button (keeping quantities fields)

The code:

// function add back quantities without button (variable product)
function add_back_quantities_variable_products(){
global $product;

?>
<div class="woocommerce-variation-add-to-cart variations_button">
<?php

do_action( 'woocommerce_before_add_to_cart_quantity' );

woocommerce_quantity_input( array(
'min_value' => apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ),
'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : $product->get_min_purchase_quantity(),
) );

do_action( 'woocommerce_after_add_to_cart_quantity' );
?>
<input type="hidden" name="add-to-cart" value="<?php echo absint( $product->get_id() ); ?>" />
<input type="hidden" name="product_id" value="<?php echo absint( $product->get_id() ); ?>" />
<input type="hidden" name="variation_id" class="variation_id" value="0" />
</div>
<?php
}

// function add back quantities without button (simple product)
function add_back_quantities_simple_products(){
global $product;

if ( ! $product->is_purchasable() ) return;

echo wc_get_stock_html( $product );

if ( $product->is_in_stock() ) : ?>

<?php do_action( 'woocommerce_before_add_to_cart_form' ); ?>

<form class="cart" method="post" enctype='multipart/form-data'>
<?php
// For WooCommerce Product add-ons (Update)
do_action( 'woocommerce_before_add_to_cart_button' );

do_action( 'woocommerce_before_add_to_cart_quantity' );

woocommerce_quantity_input( array(
'min_value' => apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ),
'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : $product->get_min_purchase_quantity(),
) );

do_action( 'woocommerce_after_add_to_cart_quantity' );
?>
</form>

<?php
do_action( 'woocommerce_after_add_to_cart_form' );
endif;
}

// Replacing add to cart button and quantities by your custom button in Single product pages
add_action( 'woocommerce_single_product_summary', 'conditionally_replacing_template_single_add_to_cart', 1, 0 );
function conditionally_replacing_template_single_add_to_cart() {
global $product, $post;

// Set HERE your product categories in the array
$terms = array( 't-shirts', 'gloves' );

if( has_term( $terms, 'product_cat' ) ){

// For variable product types
if( $product->is_type( 'variable' ) ){
// Removing add to cart button and quantities
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );

// Add back quantities without button
add_action( 'woocommerce_single_variation', 'add_back_quantities_variable_products', 20 );
}
// For simple product types
else if( $product->is_type( 'simple' ) )
{
// Removing add to cart button and quantities
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );

// Add back quantities without button
add_action( 'woocommerce_single_product_summary', 'add_back_quantities_simple_products', 30 );
}
}
}

And optionally (for archives pages):

// Replacing the button add to cart by a link to the product in Shop and archives pages
// For variable and simple products
add_filter( 'woocommerce_loop_add_to_cart_link', 'replace_loop_add_to_cart_button', 10, 2 );
function replace_loop_add_to_cart_button( $button, $product ) {
// Set HERE your product categories in the array
$terms = array( 't-shirts', 'gloves' );

// Only for simple products
if( ! $product->is_type( 'variable' ) ) return;

if( has_term( $terms, 'product_cat', $product->get_id() ) ){
$button_text = __( "View product", "woocommerce" );
$button = '<a class="button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';
}
return $button;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested under WooCommerce 3+ and works.


For Product tags - If you want that to work with product tags, you will replace:

if( has_term( $terms, 'product_cat' ) ){

by

if( has_term( $terms, 'product_tag' ) ){

Hide specific products from unlogged users based in product category in WooCommerce

The following code will hide products from a specific product category for unlogged users only. You will have to define in the code the product category SLUG to be excluded in 'terms' array:

// Hide some products from unlogged users and a specific product category
add_filter( 'woocommerce_product_query_tax_query', 'exclude_products_fom_unlogged_users', 10, 2 );
function exclude_products_fom_unlogged_users( $tax_query, $query ) {
// On frontend for unlogged users
if( ! is_user_logged_in() ){
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array('t-shirts'), // <=== HERE the product category slug
'operator' => 'NOT IN'
);
}
return $tax_query;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.



Related Topics



Leave a reply



Submit