I am working on having WooCommerce restrict product weight per category and starting from the ability to restrict total weight in cart as shown here.
The function is loaded into the themes functions.php file and works as expected by restricting the weight in cart of all items to 28.34g.
add_action('woocommerce_check_cart_items','check_cart_weight');
function check_cart_weight(){
global $woocommerce;
$weight = $woocommerce->cart->cart_contents_weight;
if( $weight > 28.34 ){
wc_add_notice( sprintf( __( 'You have %sg weight and we allow only one ounce of weight per order.', 'woocommerce' ), $weight ), 'error' );
}
}
The issue I'm having is identifying the right way to make the weight function conditional on category name while allowing different weights per category with each category having independent weight totals.
Meaning that each category can combine with weight limits maxed per category.
Example, restrict weight in cart by:
- Category 1: 30g
- Category 2: 38.34g
- Category 3: 50g
- Category 4: 100g
The initial thought was to use if ( $category = "Category 1")
to start it off but haven't had success in that direction and not sure if a foreach
prior to the if statement would be best direction. Any advice?
CodePudding user response:
When several similar conditions have to be met, it is desirable to use a multidimensional array and foreach loop(s). That way you avoid adding multiple if/else conditions.
Via the $settings
array, multiple settings arrays can be added/removed if desired.
Only 'category'
and 'weight'
need to be set. The 'total'
setting is used as a counter and should therefore remain 0 by default.
So you get:
function action_woocommerce_check_cart_items() {
// Settings (multiple settings arrays can be added/removed if desired)
$settings = array(
array(
'category' => 'category-1',
'weight' => 30,
'total' => 0
),
array(
'category' => 'category-2',
'weight' => 38.34,
'total' => 0
),
array(
'category' => 'category-3',
'weight' => 50,
'total' => 0
),
array(
'category' => 'category-4',
'weight' => 100,
'total' => 0
),
);
// Initialize
$flag = false;
// Collect data - loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// Get weight
$product_weight = $cart_item['data']->get_weight();
// NOT empty
if ( ! empty( $product_weight ) ) {
// Get product ID
$product_id = $cart_item['product_id'];
// Get quantity
$product_quantity = $cart_item['quantity'];
// Loop trough settings array
foreach ( $settings as $key => $setting ) {
// Checks if the current product has any of given terms
if ( has_term( $setting['category'], 'product_cat', $product_id ) ) {
// Add the weight to the total
$settings[$key]['total'] = $product_quantity * $product_weight;
}
}
}
}
// Generate error messages - loop trough settings array
foreach ( $settings as $key => $setting ) {
// When condition is met
if ( $setting['total'] > $setting['weight'] ) {
// Displays a dynamic error warning
wc_add_notice( sprintf(
'You have %s weight for the "%s" category and we allow %s',
wc_format_weight( $setting['total'] ),
$setting['category'],
wc_format_weight( $setting['weight'] )
), 'error' );
// Make true
$flag = true;
}
}
// When true
if ( $flag ) {
// Removing the proceed button, until the condition is met
remove_action( 'woocommerce_proceed_to_checkout','woocommerce_button_proceed_to_checkout', 20 );
}
}
add_action( 'woocommerce_check_cart_items', 'action_woocommerce_check_cart_items', 10 );