phpwordpresswoocommercecartcustom-taxonomy

Count custom taxonomy terms in WooCommerce cart and multiply shipping rates by the number


I'm trying to get the WooCommerce cart calculations to multiply the shipping rates by the number of different custom taxonimies terms in cart.

For example, my custom taxonomy name/slug is 'city'. If there are 3 different product taxonomies terms present (eg. Boston, Washington and New York), the current cart rate should be multiplied by 3.

This is my current code:

add_filter( 'woocommerce_package_rates', 'funkcija');
function funkcija ( $rates ) {
    $cart = WC()->cart;
// here I define the array where custom taxonomies will be saved in the foreach loop
    $mojarray = array();
    // the foreach loop that iterates through cart items and saves every taxonomy term in the array
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $product_id = $cart_item['product_id'];
       $terms = wp_get_post_terms( $product_id, 'city' );
        $mojarray[] = $terms;
       
    }
//now here the counter is defined, the array is set to contain only unique values of the taxonomies
     $counter = 0;
$noviarray = array_unique($mojarray);
foreach ($noviarray as $value) {
// for each unique taxonomy present in cart, increase the counter by 1
    ++$counter;
    
}
//here the rates totals are taken and multiplied with $counter
   foreach($rates as $key => $rate ) {
        $currenttotal = $rates[$key]->cost;
        $multipliedtotal = $currenttotal * $counter;
        $rates[$key]->cost =  $multipliedtotal;
    }
    
    return $rates;
}

Unfortunately, this code multiplies the rates for every product in the cart. I've gone through the code multiple times and do not understand why it's not working as intended for unique taxonomy terms.

I believe this is testable on any WooCommerce store with any custom taxonomy. Any advice?


Solution

  • Your code contains some mistakes

    So you get:

    function filter_woocommerce_package_rates( $rates, $package ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return $rates;
    
        // Initialize
        $counter = 0;
        $my_array = array();
    
        // Loop through line items
        foreach ( $package['contents'] as $line_item ) {
            // Get product id
            $product_id = $line_item['product_id'];
    
            // Get terms
            $term_names = wp_get_post_terms( $product_id, 'city', array( 'fields' => 'names' ) );
            
            // Loop through (unique values)
            foreach ( $term_names as $term_name ) {
                // Checks if a value NOT exists in an array
                if ( ! in_array( $term_name, $my_array, true ) ) {
                    // Push one or more elements onto the end of array
                    array_push( $my_array, $term_name );
                }
            }
        }
        
        // Counts all elements in an array
        $counter = count( $my_array );
        
        // Greater than
        if ( $counter > 0 ) {
            // Loop through rates
            foreach ( $rates as $rate_key => $rate ) {
                // Target specific methods, multiple can be added, separated by a comma
                if ( in_array( $rate->method_id, array( 'flat_rate', 'table_rate' ) ) ) {
                    // Get rate cost
                    $cost = $rates[$rate_key]->cost;
                    
                    // Greater than
                    if ( $cost > 0 ) {              
                        // Set rate cost
                        $rates[$rate_key]->cost = $cost * $counter;
                    }
                }
            }
        }
    
        return $rates;
    }
    add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );