PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.2.85
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.2.85
1.4.15 1.4.14 1.4.13 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.54 1.3.53 1.3.52 1.3.51 1.3.50 1.3.49 1.3.48 1.3.47 1.3.46 All 178 releases
disco / functions / bogo.php

bogo.php in Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO 1.2.85, at functions/bogo.php

187 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:disable
3 /**
4 * Disco
5 *
6 * @package Disco
7 * @author Ohidul Islam <wahid0003@gmail.com>
8 * @link http://domain.tld
9 * @license GPL 2.0+
10 * @copyright 2022 WebAppick
11 */
12
13 // Ensure the file is not accessed directly.
14 if (!defined('ABSPATH')) {
15 exit;
16 }
17
18 use Disco\App\Disco;
19 use Disco\App\Utility\Helper;
20 use Disco\App\Utility\Settings;
21
22 if ( ! function_exists( 'disco_cart_apply_free_items' ) ) {
23 function disco_cart_apply_free_items( $cart ) {
24 if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
25 return;
26 }
27
28 if( Settings::get( 'discount_priority_type' ) === 'woocommerce_coupon' ) {
29 return $cart;
30 }
31
32 if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) {
33 return;
34 }
35
36 if ( $cart->is_empty() ) {
37 return;
38 }
39
40 // Clone cart to avoid free products when calculating discount
41 $cart_copy = new WC_Cart;
42
43 foreach ( $cart->get_cart() as $cart_item ) {
44 if ( ! empty( $cart_item['is_free_product'] ) ) {
45 continue;
46 }
47
48 $cart_copy->add_to_cart(
49 $cart_item['product_id'],
50 $cart_item['quantity'],
51 $cart_item['variation_id'] ?? 0,
52 $cart_item['variation'] ?? array(),
53 $cart_item['cart_item_data'] ?? array()
54 );
55 }
56
57 foreach ( $cart->get_applied_coupons() as $coupon_code ) {
58 $cart_copy->apply_coupon( $coupon_code );
59 }
60
61 $discounts = ( new Disco )->get_cart_items_discount_for_bogo( $cart_copy );
62 $free_ids = $discounts['get_ids'] ?? array();
63 $free_qty = $discounts['get_qty'] ?? 0;
64 $bogo_type = $discounts['bogo_type'] ?? 'products';
65
66 // Remove invalid free items from cart
67 foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
68 if ( ! isset( $cart_item['is_free_product'] ) || ! $cart_item['is_free_product'] ) {
69 continue;
70 }
71
72 $product_id = $cart_item['product_id'];
73
74 if (
75 ( $bogo_type === 'categories' && ! Helper::is_in_category( $product_id, $free_ids ) )
76 || ( $bogo_type !== 'categories' && ! in_array( $product_id, $free_ids, true ) )
77 ) {
78 $cart->remove_cart_item( $cart_item_key );
79 }
80 }
81
82 if ( empty( $free_qty ) || empty( $free_ids ) ) {
83 return;
84 }
85
86 if ( $bogo_type === 'categories' ) {
87 $free_count = 0;
88
89 foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
90 if ( $free_count >= $free_qty ) {
91 break;
92 }
93
94 if ( ! empty( $cart_item['is_free_product'] ) ) {
95 continue;
96 }
97
98 $product_id = $cart_item['product_id'];
99
100 if ( Helper::is_in_category( $product_id, $free_ids ) ) {
101 $remaining_qty = $free_qty - $free_count;
102
103 // Only mark item free if the full quantity fits
104 if ( $cart_item['quantity'] <= $remaining_qty ) {
105 $cart->cart_contents[ $cart_item_key ]['is_free_product'] = true;
106 $free_count += $cart_item['quantity'];
107 } else {
108 continue;
109 }
110 }
111 }
112 } else {
113 // Product-based free items
114 foreach ( $free_ids as $product_id ) {
115 $found = false;
116
117 foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
118 if (
119 intval( $cart_item['product_id'] ) === intval( $product_id )
120 && ! empty( $cart_item['is_free_product'] )
121 ) {
122 $current_qty = $cart_item['quantity'];
123 if ( $current_qty !== $free_qty ) {
124 $cart->set_quantity( $cart_item_key, $free_qty );
125 }
126 $found = true;
127 break;
128 }
129 }
130
131 if ( ! $found ) {
132 $cart->add_to_cart( $product_id, $free_qty, 0, array(), array( 'is_free_product' => true ) );
133 }
134 }
135 }
136 }
137
138 add_action( 'woocommerce_before_calculate_totals', 'disco_cart_apply_free_items', 5 );
139 }
140
141
142 if ( ! function_exists( 'disco_set_free_product_price' ) ) {
143
144 /**
145 * Set the price of free products to zero.
146 *
147 * @param \WC_Cart $cart Cart Object.
148 */
149 function disco_set_free_product_price( $cart ) {
150 if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
151 return;
152 }
153
154 foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
155 if ( empty( $cart_item['is_free_product'] ) ) {
156 continue;
157 }
158
159 // Only process if not already handled
160 if ( empty( $cart_item['free_product_processed'] ) ) {
161 $cart_item['data']->set_price( 0 );
162 $cart_item['data']->set_regular_price( 0 );
163
164 $cart->cart_contents[ $cart_item_key ]['free_product_note'] = __( 'This item is added as free!', 'disco' );
165
166 // Mark as processed to avoid duplicate changes
167 $cart->cart_contents[ $cart_item_key ]['free_product_processed'] = true;
168 }
169 }
170 }
171 add_action( 'woocommerce_before_calculate_totals', 'disco_set_free_product_price', 10 );
172 }
173
174 if ( ! function_exists( 'disco_free_product_label' ) ) {
175 function disco_free_product_label( $item_data, $cart_item ) {
176 if ( ! empty( $cart_item['free_product_note'] ) ) {
177 $item_data[] = array(
178 'key' => __( 'Note', 'disco' ),
179 'value' => $cart_item['free_product_note'],
180 );
181 }
182 return $item_data;
183 }
184
185 add_filter( 'woocommerce_get_item_data', 'disco_free_product_label', 10, 2 );
186 }
187