Since WooCommerce 3, your actual code is outdated and not convenient… There is multiple ways:
1). The best way: Set up the minimum quantity at product level (for a product category):
// On single product pages
add_filter( 'woocommerce_quantity_input_args', 'min_qty_filter_callback', 20, 2 );
function min_qty_filter_callback( $args, $product ) {
$categories = array('Noten'); // The targeted product category(ies)
$min_qty = 5; // The minimum product quantity
$product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
if( has_term( $categories, 'product_cat', $product_id ) ){
$args['min_value'] = $min_qty;
}
return $args;
}
// On shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_args', 'min_qty_loop_add_to_cart_args', 10, 2 );
function min_qty_loop_add_to_cart_args( $args, $product ) {
$categories = array('Noten'); // The targeted product category
$min_qty = 5; // The minimum product quantity
$product_id = $product->get_id();
if( has_term( $categories, 'product_cat', $product_id ) ){
$args['quantity'] = $min_qty;
}
return $args;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
2). Alternative way: Checking cart items and displaying an error message (similar to your code):
add_action( 'woocommerce_check_cart_items', 'wc_min_item_required_qty' );
function wc_min_item_required_qty() {
$categories = array('Noten'); // The targeted product category
$min_item_qty = 5; // Minimum Qty required (for each item)
$display_error = false; // Initializing
// Loop through cart items
foreach(WC()->cart->get_cart() as $cart_item ) {
$item_quantity = $cart_item['quantity']; // Cart item quantity
$product_id = $cart_item['product_id']; // The product ID
// For cart items remaining to "Noten" producct category
if( has_term( $categories, 'product_cat', $product_id ) && $item_quantity < $min_item_qty ) {
wc_clear_notices(); // Clear all other notices
// Add an error notice (and avoid checkout).
wc_add_notice( sprintf( 'Bitte beachte die Mindestbestellmenge. Du brauchst mindestens %s Notenexemplare pro Arrangement. Aktuell hast du %s Stück in deinem Warenkorb.', $min_item_qty , $item_quantity ), 'error' );
break; // Stop the loop
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
To make it work for parent product category too, you will also add this custom 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;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
Then in the existing code, you will replace:
has_term( $category, 'product_cat', $product_id )
by
has_product_categories( $category, $product_id )
That will allow you to handle parent product categories too.