Skip to content
Advertisement

Avoid cart items price update for specific product categories in Woocommerce

I am using below script under my WordPress child theme functions.php to overwrite price, but below code is affecting to all the products.

Can you please help me “not to run” below code if the product is under some specific “shirts”, “games” category?

function calculate_cart_total( $cart_object ) {

    foreach ( WC()->cart->get_cart() as $key => $value ) {
        if(is_array($valueArray)) {
            foreach ( $valueArray as $k => $value ) {
                if($value['wccpf_cost']) {
                    $additionalPrice = $value['wccpf_cost']['user_val'];
                }
            }
        }
    }

    $additionalPrice = $value['wccpf_cost']['user_val'];

    foreach ( WC()->cart->get_cart() as $key => $value ) {
        if( method_exists( $value['data'], "set_price" ) ) {
            $value['data']->set_price( $additionalPrice );
        } else {
            $value['data']->price = ($additionalPrice );
        }     
    }
}
add_action( 'woocommerce_before_calculate_totals', 'calculate_cart_total', 99 );

Above code is working smoothly for all the products but I don’t want to run this code on all products as this code is required

I have tried conditional tags like is_product_category( array( 'shirts', 'games' ) ), but it’s not working.

Or is there any specific way in WordPress instead of functions.php I can run above code to the specific products or category only where it’s required?

I have also done some google search but not able to find perfect solution.

Advertisement

Answer

Your code has some errors and mistakes… As $valueArray is not defined in your code the first foreach loop doesn’t have any effect and code become active after it. To target cart items product categories, you can use WordPress conditional function has_term().

Try the following instead (for Woocommerce 3+):

// Updating cart item prices conditionally
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 100, 1 );
function custom_cart_item_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    
    // Your product categories to avoid
    $categories = array("shirts", "games");

    foreach ( $cart->get_cart() as $cart_item ) {
        if( isset($cart_item['wccpf_cost']['user_val']) && ! has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
            $cart_item['data']->set_price($cart_item['wccpf_cost']['user_val']);
        }
    }
}

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


But if you want to target parent product categories you will need to use has_product_categories() custom conditional function instead in your code:

// 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;
}

// Updating cart item prices conditionally
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 100, 1 );
function custom_cart_item_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    
    // Your product categories to avoid
    $categories = array("shirts", "games");

    foreach ( $cart->get_cart() as $cart_item ) {
        if( isset($cart_item['wccpf_cost']['user_val']) && ! has_product_categories( $cart_item['product_id'], $categories ) ) {
            $cart_item['data']->set_price($cart_item['wccpf_cost']['user_val']);
        }
    }
}

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


Related threads:

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement