From 20278b8de6cd49d8e93630603a3037684eb2eb97 Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Fri, 10 Jan 2025 12:56:38 +0600 Subject: [PATCH 01/10] update: refactor the coupon validation and add new filter to extend it --- includes/Order/Hooks.php | 70 +++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index dc2e1abecf..6e35f0ea82 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -46,7 +46,7 @@ public function __construct() { add_action( 'dokan_checkout_update_order_meta', 'dokan_sync_insert_order' ); // prevent non-vendor coupons from being added - add_filter( 'woocommerce_coupon_is_valid', [ $this, 'ensure_vendor_coupon' ], 10, 3 ); + add_filter( 'woocommerce_coupon_is_valid', [ $this, 'ensure_is_coupon_valid' ], 10, 3 ); if ( is_admin() ) { add_action( 'woocommerce_process_shop_order_meta', 'dokan_sync_insert_order', 60 ); @@ -407,35 +407,29 @@ public function split_vendor_orders( $parent_order_id ) { * sure a product of the admin is in the cart. Otherwise it wouldn't be * possible to distribute the coupon in sub orders. * - * @param boolean $valid - * @param \WC_Coupon $coupon - * @param \WC_Discounts $discount + * @since DOKAN_SINCE Refactored to make it more flexible, and added filter + * + * @param boolean $valid The validity of the coupon. + * @param \WC_Coupon $coupon The coupon object. + * @param \WC_Discounts $discount The discount object, which contains the order details. * * @throws Exception * @return boolean|Exception */ - public function ensure_vendor_coupon( $valid, $coupon, $discount ) { + public function ensure_is_coupon_valid( $valid, $coupon, $discount ) { $available_vendors = []; $available_products = []; - if ( WC()->cart && ! WC()->cart->is_empty() ) { - foreach ( WC()->cart->get_cart() as $item ) { - $product_id = $item['data']->get_id(); - $available_vendors[] = (int) dokan_get_vendor_by_product( $product_id, true ); - $available_products[] = $product_id; - } - } else { - foreach ( $discount->get_items() as $item ) { - if ( ! isset( $item->product ) || ! $item->product instanceof \WC_Product ) { - continue; - } + foreach ( $discount->get_items() as $item ) { + if ( ! isset( $item->product ) || ! $item->product instanceof \WC_Product ) { + continue; + } - $item_id = $item->product->get_id(); + $item_id = $item->product->get_id(); - $available_vendors[] = (int) dokan_get_vendor_by_product( $item_id, true ); - $available_products[] = $item_id; - } - } + $available_vendors[] = (int) dokan_get_vendor_by_product( $item_id, true ); + $available_products[] = $item_id; + } $available_vendors = array_unique( $available_vendors ); @@ -443,26 +437,20 @@ public function ensure_vendor_coupon( $valid, $coupon, $discount ) { throw new Exception( esc_html__( 'This coupon is invalid for multiple vendors.', 'dokan-lite' ) ); } - // Make sure applied coupon created by admin - if ( apply_filters( 'dokan_ensure_admin_have_create_coupon', $valid, $coupon, $available_vendors, $available_products ) ) { - return true; - } - - if ( ! apply_filters( 'dokan_ensure_vendor_coupon', true ) ) { - return $valid; - } - - // A coupon must be bound with a product - if ( ! dokan()->is_pro_exists() && count( $coupon->get_product_ids() ) === 0 ) { - throw new Exception( esc_html__( 'A coupon must be restricted with a vendor product.', 'dokan-lite' ) ); - } - - $coupon_id = $coupon->get_id(); - $vendor_id = intval( get_post_field( 'post_author', $coupon_id ) ); - - if ( ! in_array( $vendor_id, $available_vendors, true ) ) { - return false; - } + /** + * Filter the validity of a coupon. + * + * @since DOKAN_SINCE + * + * @param boolean $valid The validity of the coupon. + * @param \WC_Coupon $coupon The coupon object. + * @param array $available_vendors List of available vendors. + * @param array $available_products List of available products. + * @param \WC_Discounts $discount The discount object, which contains the order details. + */ + if ( apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $available_vendors, $available_products, $discount ) ) { + return true; + } return $valid; } From fd5671e437abcd1f50c2657275c3ddd9c8a950f9 Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:34:29 +0600 Subject: [PATCH 02/10] update: doc blocks --- includes/Order/Hooks.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index 6e35f0ea82..132b8a003c 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -409,12 +409,12 @@ public function split_vendor_orders( $parent_order_id ) { * * @since DOKAN_SINCE Refactored to make it more flexible, and added filter * - * @param boolean $valid The validity of the coupon. - * @param \WC_Coupon $coupon The coupon object. - * @param \WC_Discounts $discount The discount object, which contains the order details. + * @param boolean $valid Whether the coupon is currently considered valid. + * @param \WC_Coupon $coupon The coupon object being validated. + * @param \WC_Discounts $discount The discount object containing cart/order items being validated. * - * @throws Exception - * @return boolean|Exception + * @return boolean True if the coupon is valid, false otherwise + * @throws \Exception When the coupon is invalid for multiple vendors */ public function ensure_is_coupon_valid( $valid, $coupon, $discount ) { $available_vendors = []; From 7ee67f57d8cafdbbc6b7c958eb892df2f59a3e7b Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:47:04 +0600 Subject: [PATCH 03/10] update: doc blocks --- includes/Order/Hooks.php | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index 132b8a003c..1a17b1fb91 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -3,7 +3,10 @@ namespace WeDevs\Dokan\Order; use Exception; +use WC_Coupon; +use WC_Discounts; use WC_Order; +use WC_Product; // don't call the file directly if ( ! defined( 'ABSPATH' ) ) { @@ -409,19 +412,19 @@ public function split_vendor_orders( $parent_order_id ) { * * @since DOKAN_SINCE Refactored to make it more flexible, and added filter * - * @param boolean $valid Whether the coupon is currently considered valid. - * @param \WC_Coupon $coupon The coupon object being validated. - * @param \WC_Discounts $discount The discount object containing cart/order items being validated. + * @param boolean $valid Whether the coupon is currently considered valid. + * @param WC_Coupon $coupon The coupon object being validated. + * @param WC_Discounts $discounts The discount object containing cart/order items being validated. * * @return boolean True if the coupon is valid, false otherwise - * @throws \Exception When the coupon is invalid for multiple vendors + * @throws Exception When the coupon is invalid for multiple vendors */ - public function ensure_is_coupon_valid( $valid, $coupon, $discount ) { + public function ensure_is_coupon_valid( bool $valid, WC_Coupon $coupon, WC_Discounts $discounts ): bool { $available_vendors = []; $available_products = []; - foreach ( $discount->get_items() as $item ) { - if ( ! isset( $item->product ) || ! $item->product instanceof \WC_Product ) { + foreach ( $discounts->get_items() as $item ) { + if ( ! isset( $item->product ) || ! $item->product instanceof WC_Product ) { continue; } @@ -442,13 +445,13 @@ public function ensure_is_coupon_valid( $valid, $coupon, $discount ) { * * @since DOKAN_SINCE * - * @param boolean $valid The validity of the coupon. - * @param \WC_Coupon $coupon The coupon object. - * @param array $available_vendors List of available vendors. - * @param array $available_products List of available products. - * @param \WC_Discounts $discount The discount object, which contains the order details. + * @param boolean $valid The validity of the coupon. + * @param WC_Coupon $coupon The coupon object. + * @param array $available_vendors List of available vendors. + * @param array $available_products List of available products. + * @param WC_Discounts $discounts The discount object, which contains the order details. */ - if ( apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $available_vendors, $available_products, $discount ) ) { + if ( apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $available_vendors, $available_products, $discounts ) ) { return true; } From 2ee47295339ab4c2b588ea1adbc0cf783c6be190 Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:53:40 +0600 Subject: [PATCH 04/10] update: filter integration on return for validation --- includes/Order/Hooks.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index 1a17b1fb91..937208dc5f 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -451,11 +451,7 @@ public function ensure_is_coupon_valid( bool $valid, WC_Coupon $coupon, WC_Disco * @param array $available_products List of available products. * @param WC_Discounts $discounts The discount object, which contains the order details. */ - if ( apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $available_vendors, $available_products, $discounts ) ) { - return true; - } - - return $valid; + return apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $available_vendors, $available_products, $discounts ); } /** From 2624bee5633b4e85aa84f803072985d78cb74ea4 Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:07:32 +0600 Subject: [PATCH 05/10] update: the proper naming convension for method name --- includes/Order/Hooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index 937208dc5f..038d110b8b 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -49,7 +49,7 @@ public function __construct() { add_action( 'dokan_checkout_update_order_meta', 'dokan_sync_insert_order' ); // prevent non-vendor coupons from being added - add_filter( 'woocommerce_coupon_is_valid', [ $this, 'ensure_is_coupon_valid' ], 10, 3 ); + add_filter( 'woocommerce_coupon_is_valid', [ $this, 'ensure_coupon_is_valid' ], 10, 3 ); if ( is_admin() ) { add_action( 'woocommerce_process_shop_order_meta', 'dokan_sync_insert_order', 60 ); @@ -419,7 +419,7 @@ public function split_vendor_orders( $parent_order_id ) { * @return boolean True if the coupon is valid, false otherwise * @throws Exception When the coupon is invalid for multiple vendors */ - public function ensure_is_coupon_valid( bool $valid, WC_Coupon $coupon, WC_Discounts $discounts ): bool { + public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Discounts $discounts ): bool { $available_vendors = []; $available_products = []; From 974c0d69861f050f28333c17b1c4a492f4b9be53 Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:36:10 +0600 Subject: [PATCH 06/10] add: new filters to validate the minimum and maximum amount --- includes/Order/Hooks.php | 68 +++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index 038d110b8b..d2e99f2ecf 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -440,17 +440,63 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco throw new Exception( esc_html__( 'This coupon is invalid for multiple vendors.', 'dokan-lite' ) ); } - /** - * Filter the validity of a coupon. - * - * @since DOKAN_SINCE - * - * @param boolean $valid The validity of the coupon. - * @param WC_Coupon $coupon The coupon object. - * @param array $available_vendors List of available vendors. - * @param array $available_products List of available products. - * @param WC_Discounts $discounts The discount object, which contains the order details. - */ + /** + * Filter to customize minimum amount validation for vendor coupons. + * + * Allows modifying whether a coupon should be valid based on the minimum order amount requirement. + * + * @since DOKAN_SINCE + * + * @param bool $is_valid True if the minimum amount requirement is met + * @param WC_Coupon $coupon The coupon object being validated + * @param float $subtotal The current order subtotal + * @param WC_Discounts $discounts The WC_Discounts object containing cart/order details + */ + if ( ! apply_filters( 'dokan_coupon_validate_minimum_amount', true, $coupon, $discounts ) ) { + throw new Exception( + sprintf( + /* translators: %s: minimum spend amount for coupon */ + esc_html__( 'The minimum spend for this coupon is %s', 'dokan' ), + esc_html( wc_price( $coupon->get_minimum_amount() ) ) + ), + 108 + ); + } + + /** + * Filter to customize maximum amount validation for vendor coupons. + * + * Allows modifying whether a coupon should be valid based on the maximum order amount requirement. + * + * @since DOKAN_SINCE + * + * @param bool $is_valid True if the maximum amount requirement is met + * @param WC_Coupon $coupon The coupon object being validated + * @param float $subtotal The current order subtotal + * @param WC_Discounts $discounts The WC_Discounts object containing cart/order details + */ + if ( ! apply_filters( 'dokan_coupon_validate_maximum_amount', true, $coupon, $discounts ) ) { + throw new Exception( + sprintf( + /* translators: %s: maximum spend amount for coupon */ + esc_html__( 'The maximum spend for this coupon is %s', 'dokan' ), + esc_html( wc_price( $coupon->get_maximum_amount() ) ) + ), + 108 + ); + } + + /** + * Filter the validity of a coupon. + * + * @since DOKAN_SINCE + * + * @param boolean $valid The validity of the coupon. + * @param \WC_Coupon $coupon The coupon object. + * @param array $available_vendors List of available vendors. + * @param array $available_products List of available products. + * @param \WC_Discounts $discounts The discount object, which contains the order details. + */ return apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $available_vendors, $available_products, $discounts ); } From de6e176df01329242ad7e23bc00b3d67f87aa7dd Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed Date: Tue, 14 Jan 2025 00:19:08 +0600 Subject: [PATCH 07/10] Update text domain from 'dokan' to 'dokan-lite' --- includes/Order/Hooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index d2e99f2ecf..e6de47669b 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -456,7 +456,7 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco throw new Exception( sprintf( /* translators: %s: minimum spend amount for coupon */ - esc_html__( 'The minimum spend for this coupon is %s', 'dokan' ), + esc_html__( 'The minimum spend for this coupon is %s', 'dokan-lite' ), esc_html( wc_price( $coupon->get_minimum_amount() ) ) ), 108 @@ -479,7 +479,7 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco throw new Exception( sprintf( /* translators: %s: maximum spend amount for coupon */ - esc_html__( 'The maximum spend for this coupon is %s', 'dokan' ), + esc_html__( 'The maximum spend for this coupon is %s', 'dokan-lite' ), esc_html( wc_price( $coupon->get_maximum_amount() ) ) ), 108 From e10d98f9e0d720e51b563adb0c14a2a4aa9ef878 Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:39:48 +0600 Subject: [PATCH 08/10] update: doc blocks for apply filters --- includes/Order/Hooks.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index e6de47669b..c3b8556254 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -449,7 +449,6 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco * * @param bool $is_valid True if the minimum amount requirement is met * @param WC_Coupon $coupon The coupon object being validated - * @param float $subtotal The current order subtotal * @param WC_Discounts $discounts The WC_Discounts object containing cart/order details */ if ( ! apply_filters( 'dokan_coupon_validate_minimum_amount', true, $coupon, $discounts ) ) { @@ -472,7 +471,6 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco * * @param bool $is_valid True if the maximum amount requirement is met * @param WC_Coupon $coupon The coupon object being validated - * @param float $subtotal The current order subtotal * @param WC_Discounts $discounts The WC_Discounts object containing cart/order details */ if ( ! apply_filters( 'dokan_coupon_validate_maximum_amount', true, $coupon, $discounts ) ) { @@ -492,10 +490,10 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco * @since DOKAN_SINCE * * @param boolean $valid The validity of the coupon. - * @param \WC_Coupon $coupon The coupon object. + * @param WC_Coupon $coupon The coupon object. * @param array $available_vendors List of available vendors. * @param array $available_products List of available products. - * @param \WC_Discounts $discounts The discount object, which contains the order details. + * @param WC_Discounts $discounts The discount object, which contains the order details. */ return apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $available_vendors, $available_products, $discounts ); } From 21b13d2318ba6aa13fa262095495705e76dafe48 Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Wed, 15 Jan 2025 11:46:54 +0600 Subject: [PATCH 09/10] remove: filters and update params for `dokan_coupon_is_valid` hook --- includes/Order/Hooks.php | 48 ++-------------------------------------- 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index c3b8556254..8af4820c46 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -440,50 +440,6 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco throw new Exception( esc_html__( 'This coupon is invalid for multiple vendors.', 'dokan-lite' ) ); } - /** - * Filter to customize minimum amount validation for vendor coupons. - * - * Allows modifying whether a coupon should be valid based on the minimum order amount requirement. - * - * @since DOKAN_SINCE - * - * @param bool $is_valid True if the minimum amount requirement is met - * @param WC_Coupon $coupon The coupon object being validated - * @param WC_Discounts $discounts The WC_Discounts object containing cart/order details - */ - if ( ! apply_filters( 'dokan_coupon_validate_minimum_amount', true, $coupon, $discounts ) ) { - throw new Exception( - sprintf( - /* translators: %s: minimum spend amount for coupon */ - esc_html__( 'The minimum spend for this coupon is %s', 'dokan-lite' ), - esc_html( wc_price( $coupon->get_minimum_amount() ) ) - ), - 108 - ); - } - - /** - * Filter to customize maximum amount validation for vendor coupons. - * - * Allows modifying whether a coupon should be valid based on the maximum order amount requirement. - * - * @since DOKAN_SINCE - * - * @param bool $is_valid True if the maximum amount requirement is met - * @param WC_Coupon $coupon The coupon object being validated - * @param WC_Discounts $discounts The WC_Discounts object containing cart/order details - */ - if ( ! apply_filters( 'dokan_coupon_validate_maximum_amount', true, $coupon, $discounts ) ) { - throw new Exception( - sprintf( - /* translators: %s: maximum spend amount for coupon */ - esc_html__( 'The maximum spend for this coupon is %s', 'dokan-lite' ), - esc_html( wc_price( $coupon->get_maximum_amount() ) ) - ), - 108 - ); - } - /** * Filter the validity of a coupon. * @@ -491,11 +447,11 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco * * @param boolean $valid The validity of the coupon. * @param WC_Coupon $coupon The coupon object. + * @param WC_Discounts $discounts The discount object, which contains the order details. * @param array $available_vendors List of available vendors. * @param array $available_products List of available products. - * @param WC_Discounts $discounts The discount object, which contains the order details. */ - return apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $available_vendors, $available_products, $discounts ); + return apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $discounts, $available_vendors, $available_products ); } /** From b1d0195d34e51d7ed265cfe24d3b4fdb7255a97d Mon Sep 17 00:00:00 2001 From: Al Amin Ahamed <34349365+mralaminahamed@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:00:16 +0600 Subject: [PATCH 10/10] update: params for `dokan_coupon_is_valid` hook --- includes/Order/Hooks.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/includes/Order/Hooks.php b/includes/Order/Hooks.php index 8af4820c46..7ead1e25ee 100644 --- a/includes/Order/Hooks.php +++ b/includes/Order/Hooks.php @@ -421,17 +421,13 @@ public function split_vendor_orders( $parent_order_id ) { */ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Discounts $discounts ): bool { $available_vendors = []; - $available_products = []; foreach ( $discounts->get_items() as $item ) { if ( ! isset( $item->product ) || ! $item->product instanceof WC_Product ) { continue; } - $item_id = $item->product->get_id(); - - $available_vendors[] = (int) dokan_get_vendor_by_product( $item_id, true ); - $available_products[] = $item_id; + $available_vendors[] = (int) dokan_get_vendor_by_product( $item->product->get_id(), true ); } $available_vendors = array_unique( $available_vendors ); @@ -445,13 +441,11 @@ public function ensure_coupon_is_valid( bool $valid, WC_Coupon $coupon, WC_Disco * * @since DOKAN_SINCE * - * @param boolean $valid The validity of the coupon. - * @param WC_Coupon $coupon The coupon object. - * @param WC_Discounts $discounts The discount object, which contains the order details. - * @param array $available_vendors List of available vendors. - * @param array $available_products List of available products. + * @param boolean $valid The validity of the coupon. + * @param WC_Coupon $coupon The coupon object. + * @param WC_Discounts $discounts The discount object, which contains the order details. */ - return apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $discounts, $available_vendors, $available_products ); + return apply_filters( 'dokan_coupon_is_valid', $valid, $coupon, $discounts ); } /**