0

I have a function hooking into woocommerce_before_calculate_totals that gives people a discount on a certain product, if a specific coupon is applied.

What I don't want is for people to abuse it by changing the quantity of the item, so I want to always reset the quantity of that item to 1.

This is the code I have:

add_action( 'woocommerce_before_calculate_totals', 'change_price_of_product' );


function change_price_of_product() {
    $items = WC()->cart->get_cart();
    $coupons = WC()->cart->applied_coupons;
    
    $only_one_gift = 0;
    
    if (in_array('getmygift', $coupons)) {
        
         foreach($items as $item) {
                if (isset($item['product_id'])) {
                    
                    if ($only_one_gift > 0) {
                        break;
                    }
                    
                    
                    if (($item['product_id']) == 5261) {
                        $only_one_gift++;
                        $item['data']->set_price( 0 );
                        // I WANT TO SET THE QUANTITY TO 1 HERE  
                    }
                }
            }
    }
}

If I include $item['data']->set_quantity(1); or $item->set_quantity(1);, the function breaks.

How can I do it properly?

lastnoob
  • 646
  • 12
  • 28

1 Answers1

1

Figured it out.

Have to edit the foreach to foreach($items as $cart_item_key => $item), and then use WC()->cart->set_quantity( $cart_item_key, 1 );.

Here's the full code:

add_action( 'woocommerce_before_calculate_totals', 'change_price_of_product' );


function change_price_of_product() {
    $items = WC()->cart->get_cart();
    $coupons = WC()->cart->applied_coupons;
    
    $only_one_gift = 0;
    
    if (in_array('getmygift', $coupons)) {
        
         foreach($items as $cart_item_key => $item) {
                if (isset($item['product_id'])) {
                    
                    if ($only_one_gift > 0) {
                        break;
                    }
                    
                    
                    if (($item['product_id']) == 5261) {
                        $only_one_gift++;
                        $item['data']->set_price( 0 );
                        WC()->cart->set_quantity( $cart_item_key, 1 );
                    }
                }
            }
    }
}
lastnoob
  • 646
  • 12
  • 28
  • 1
    [`woocommerce_before_calculate_totals`](https://github.com/woocommerce/woocommerce/blob/76cf1e4e93a9205e5639b5c773f43daff485688a/includes/class-wc-cart.php#L1234) contains the parameter `$this` which is equal to `$cart`, so you could use `$cart->set_quantity( $cart_item_key, 1 );` instead. Also `$cart->get_cart();`, `$cart->get_applied_coupons();`, etc... – 7uc1f3r Aug 07 '20 at 13:15