[Enhancement]: Add Filters to Cart Coupon Validation Functions
#38,527 建立於 2023年5月30日
倉庫指標
- 星標
- (10,294 顆星)
- PR 合併指標
- (PR 指標待抓取)
描述
Describe the solution you'd like
We have a case where we need to disable some particular coupon validation functions when a coupon is being added to the cart. To be specific, we are adding a coupon via URL but the coupon gets removed right away since some conditions are not met (product ids, coupon minimum amount...).
This is the function responsible to validate coupon when it's being added to the cart: https://github.com/woocommerce/woocommerce/blob/7.6.1/plugins/woocommerce/includes/class-wc-discounts.php#L990-L1024
I think it would make sense that WooCommerce would allow us to hook into each of the validation functions and disable it. In our case, we would only like to validate the coupon on the checkout page.
Functions WC_Discounts->validate_coupon_minimum_amount() and WC_Discounts->validate_coupon_maximum_amount() already have filters that we can use to disable them on demand. But I think it would make sense to do something similar on the other functions as well:
WC_Discounts->validate_coupon_product_ids()WC_Discounts->validate_coupon_product_categories()WC_Discounts->validate_coupon_excluded_items()WC_Discounts->validate_coupon_eligible_items()
So this function:
/**
* Ensure coupon is valid for products in the list is valid or throw exception.
*
* @since 3.2.0
* @throws Exception Error message.
* @param WC_Coupon $coupon Coupon data.
* @return bool
*/
protected function validate_coupon_product_ids( $coupon ) {
if ( count( $coupon->get_product_ids() ) > 0 ) {
$valid = false;
foreach ( $this->get_items_to_validate() as $item ) {
if ( $item->product && ( in_array( $item->product->get_id(), $coupon->get_product_ids(), true ) || in_array( $item->product->get_parent_id(), $coupon->get_product_ids(), true ) ) ) {
$valid = true;
break;
}
}
if ( ! $valid ) {
throw new Exception( __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce' ), 109 );
}
}
return true;
}
Should become:
/**
* Ensure coupon is valid for products in the list is valid or throw exception.
*
* @since 3.2.0
* @throws Exception Error message.
* @param WC_Coupon $coupon Coupon data.
* @return bool
*/
protected function validate_coupon_product_ids( $coupon ) {
if ( count( $coupon->get_product_ids() ) > 0 && apply_filters( 'woocommerce_coupon_should_validate_product_ids', true, $coupon ) ) {
$valid = false;
foreach ( $this->get_items_to_validate() as $item ) {
if ( $item->product && ( in_array( $item->product->get_id(), $coupon->get_product_ids(), true ) || in_array( $item->product->get_parent_id(), $coupon->get_product_ids(), true ) ) ) {
$valid = true;
break;
}
}
if ( ! $valid ) {
throw new Exception( __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce' ), 109 );
}
}
return true;
}
Or this:
/**
* Ensure coupon is valid for products in the list is valid or throw exception.
*
* @since 3.2.0
* @throws Exception Error message.
* @param WC_Coupon $coupon Coupon data.
* @return bool
*/
protected function validate_coupon_product_ids( $coupon ) {
if ( ! apply_filters( 'woocommerce_coupon_should_validate_product_ids', true, $coupon ) ) {
return true;
}
if ( count( $coupon->get_product_ids() ) > 0 ) {
$valid = false;
foreach ( $this->get_items_to_validate() as $item ) {
if ( $item->product && ( in_array( $item->product->get_id(), $coupon->get_product_ids(), true ) || in_array( $item->product->get_parent_id(), $coupon->get_product_ids(), true ) ) ) {
$valid = true;
break;
}
}
if ( ! $valid ) {
throw new Exception( __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce' ), 109 );
}
}
return true;
}
Describe alternatives you've considered
No response
Additional context
No response