Based on your last question code, here is the way to count items from different product categories. As you will see, the code is compact, optimized and more efficient.
Also you need to understand how hooks work when using:
The 2 last arguments are optional… By default the priority is 10
and the arguments count is:
0
for an action hook.
1
for a filter hook.
In a filter hook, the first function argument (variable) is always returned at the end of the function.
There are multiple possibilities:
1) Adding multiple fees for each product category count (item quantity count):
add_action( 'woocommerce_cart_calculate_fees', 'custom_packing_fees' );
function custom_packing_fees( $cart ) {
if ( is_admin() && !defined('DOING_AJAX') )
return;
if ( did_action('woocommerce_cart_calculate_fees') >= 2 )
return;
$data = [
['name' => __('Cupcake'), 'threshold' => 4, 'fee' => 15, 'count' => 0],
['name' => __('Cake'), 'threshold' => 3, 'fee' => 11, 'count' => 0],
['name' => __('Macaron'), 'threshold' => 6, 'fee' => 12, 'count' => 0],
];
$fee_text = __('"%s" box fee (%d items)');
foreach ( $cart->get_cart() as $item ) {
foreach ( $data as $key => $values ) {
if ( has_term( $values['name'], 'product_cat', $item['product_id'] ) ) {
$data[$key]['count'] += (int) $item['quantity'];
}
}
}
foreach ( $data as $key => $values ) {
if( $values['count'] >= $values['threshold'] ) {
$cart->add_fee( sprintf( $fee_text, $values['name'], $values['count'] ), $values['fee'], false );
}
}
}
2) Adding multiple fees for each product category count (cart item count, not quantity):
add_action( 'woocommerce_cart_calculate_fees', 'custom_packing_fees' );
function custom_packing_fees( $cart ) {
if ( is_admin() && !defined('DOING_AJAX') )
return;
if ( did_action('woocommerce_cart_calculate_fees') >= 2 )
return;
$data = [
['name' => __('Cupcake'), 'threshold' => 4, 'fee' => 15, 'count' => 0],
['name' => __('Cake'), 'threshold' => 3, 'fee' => 11, 'count' => 0],
['name' => __('Macaron'), 'threshold' => 6, 'fee' => 12, 'count' => 0],
];
$fee_text = __('"%s" box fee (%d items)');
foreach ( $cart->get_cart() as $item ) {
foreach ( $data as $key => $values ) {
if ( has_term( $values['name'], 'product_cat', $item['product_id'] ) ) {
$data[$key]['count'] += 1;
}
}
}
foreach ( $data as $key => $values ) {
if( $values['count'] >= $values['threshold'] ) {
$cart->add_fee( sprintf( $fee_text, $values['name'], $values['count'] ), $values['fee'], false );
}
}
}
3) Adding a unique fee for all product categories count (item quantity count):
add_action( 'woocommerce_cart_calculate_fees', 'custom_packing_fees' );
function custom_packing_fees( $cart ) {
if ( is_admin() && !defined('DOING_AJAX') )
return;
if ( did_action('woocommerce_cart_calculate_fees') >= 2 )
return;
$data = [
['name' => __('Cupcake'), 'threshold' => 4, 'fee' => 15, 'count' => 0],
['name' => __('Cake'), 'threshold' => 3, 'fee' => 11, 'count' => 0],
['name' => __('Macaron'), 'threshold' => 6, 'fee' => 12, 'count' => 0],
];
$fee_text = __('Box fee (%d items)');
$fee_amount = 0;
$total_count = 0;
foreach ( $cart->get_cart() as $item ) {
foreach ( $data as $key => $values ) {
if ( has_term( $values['name'], 'product_cat', $item['product_id'] ) ) {
$data[$key]['count'] += (int) $item['quantity'];
}
}
}
foreach ( $data as $key => $values ) {
if( $values['count'] >= $values['threshold'] ) {
$fee_amount += $values['fee'];
$total_count += $values['count'];
}
}
if ( $fee_amount > 0 ) {
$cart->add_fee( sprintf( $fee_text, $total_count ), $fee_amount, false );
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.