PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, March 2, 2022

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

 March 02, 2022     custom-taxonomy, php, product, woocommerce, wordpress     No comments   

Issue

In Woocommerce, I am trying to disable specific product categories to be added to the cart for users that aren't logged in. i'm looking for a solution the last couple of days and after frustrated deleting the last code I found this but also doesn't do the job.

I'm using a certain plugin (TZ product tabs) to show products on other pages (so not only on the category and product page (this i know how to disable))

add_action( 'woocommerce_after_shop_loop_item', 'remove_add_to_cart_buttons', 1 );

function remove_add_to_cart_buttons() {
    // replace a_category and another_category with the slugs of the categories you'd like to have the button removed from
    if( is_product_category( array( 'gekoelde-bier', 'bierkoerier'))) { 
        remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart' );            
    // add_filter( 'woocommerce_is_purchasable', false );
    }
}

Referenced from https://gist.github.com/rynaldos/560c621714b9680433cddf18e6a50305

My best guess is to check the category of the product when the "add to cart" button is pressed and based on that the product can be added to the cart or not.

Thanks in advance.


Solution

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.

enter image description here


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.



Answered By - LoicTheAztec
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home
View mobile version

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing