Home > Software design >  Restrict cart weight per individual product category in WooCommerce
Restrict cart weight per individual product category in WooCommerce

Time:07-01

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 );
  • Related