'shop_coupon', 'title' => $coupon_code, 'post_status' => 'publish', 'numberposts' => 1, ) ); $coupon = current( $coupons ); $coupon_id = ( ! empty( $coupon->ID ) ) ? $coupon->ID : 0; $coupon = new WC_Coupon( $coupon_id ); if ( ! is_wp_error( $coupon ) ) { if ( $this->is_wc_gte_30() ) { $actions = $coupon->get_meta( 'wc_sc_add_product_details' ); } else { $coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0; $actions = get_post_meta( $coupon_id, 'wc_sc_add_product_details', true ); } return apply_filters( 'wc_sc_coupon_actions', $actions, array( 'coupon_code' => $coupon_code ) ); } return array(); } /** * Modify cart item data * * @param array $cart_item_data The cart item data. * @param integer $product_id The product id. * @param integer $variation_id The variation id. * @param integer $quantity The quantity of product. * @return array $cart_item_data */ public function modify_cart_item_data( $cart_item_data = array(), $product_id = 0, $variation_id = 0, $quantity = 0 ) { if ( empty( $cart_item_data ) || empty( $product_id ) || empty( $quantity ) ) { return $cart_item_data; } if ( ! empty( $cart_item_data['wc_sc_product_source'] ) ) { $coupon_code = $cart_item_data['wc_sc_product_source']; $coupon_actions = $this->get_coupon_actions( $coupon_code ); if ( ! empty( $coupon_actions ) && ! is_scalar( $coupon_actions ) ) { foreach ( $coupon_actions as $product_data ) { if ( ! empty( $product_data['product_id'] ) && in_array( absint( $product_data['product_id'] ), array_map( 'absint', array( $product_id, $variation_id ) ), true ) ) { $discount_amount = ( '' !== $product_data['discount_amount'] ) ? $product_data['discount_amount'] : ''; if ( '' !== $discount_amount ) { if ( ! empty( $variation_id ) ) { $product = wc_get_product( $variation_id ); } else { $product = wc_get_product( $product_id ); } $product_price = $product->get_price(); $regular_price = $product->get_regular_price(); $discount_type = ( ! empty( $product_data['discount_type'] ) ) ? $product_data['discount_type'] : 'percent'; switch ( $discount_type ) { case 'flat': $discount = $this->convert_price( $discount_amount ); break; case 'percent': $discount = ( $product_price * $discount_amount ) / 100; break; } $discount = wc_cart_round_discount( min( $product_price, $discount ), 2 ); $discounted_price = $product_price - $discount; $cart_item_data['data']->set_price( $discounted_price ); $cart_item_data['data']->set_regular_price( $regular_price ); $cart_item_data['data']->set_sale_price( $discounted_price ); } break; } } } } return $cart_item_data; } /** * Modify cart item in WC_Cart::add_to_cart() * * @param array $cart_item_data The cart item data as passed by filter 'woocommerce_add_cart_item'. * @param string $cart_item_key The cart item key. * @return array $cart_item_data */ public function modify_cart_item_data_in_add_to_cart( $cart_item_data = array(), $cart_item_key = '' ) { if ( ! empty( $cart_item_data['wc_sc_product_source'] ) ) { $cart_item_data = $this->modify_cart_item_data( $cart_item_data, $cart_item_data['product_id'], $cart_item_data['variation_id'], $cart_item_data['quantity'] ); } return $cart_item_data; } /** * Modify cart item in session * * @param array $session_data The session data. * @param array $values The cart item. * @param string $key The cart item key. * @return array $session_data */ public function modify_cart_item_in_session( $session_data = array(), $values = array(), $key = '' ) { if ( ! empty( $values['wc_sc_product_source'] ) ) { $session_data['wc_sc_product_source'] = $values['wc_sc_product_source']; $qty = ( ! empty( $session_data['quantity'] ) ) ? absint( $session_data['quantity'] ) : ( ( ! empty( $values['quantity'] ) ) ? absint( $values['quantity'] ) : 1 ); $session_data = $this->modify_cart_item_data( $session_data, $session_data['product_id'], $session_data['variation_id'], $qty ); } return $session_data; } /** * Modify cart item quantity * * @param string $product_quantity The product quantity. * @param string $cart_item_key The cart item key. * @param array $cart_item The cart item. * @return string $product_quantity */ public function modify_cart_item_quantity( $product_quantity = '', $cart_item_key = '', $cart_item = array() ) { if ( ! empty( $cart_item['wc_sc_product_source'] ) ) { $product_quantity = sprintf( '%s ', $cart_item['quantity'], $cart_item_key, $cart_item['quantity'] ); } return $product_quantity; } /** * Modify cart item price * * @param string $product_price The product price. * @param array $cart_item The cart item. * @param string $cart_item_key The cart item key. * @return string $product_price */ public function modify_cart_item_price( $product_price = '', $cart_item = array(), $cart_item_key = '' ) { if ( ( is_array( $cart_item ) && isset( $cart_item['wc_sc_product_source'] ) ) || ( is_object( $cart_item ) && is_callable( array( $cart_item, 'get_meta' ) ) && $cart_item->get_meta( '_wc_sc_product_source' ) ) ) { if ( wc_price( 0 ) === $product_price ) { $product_price = apply_filters( 'wc_sc_price_zero_text', $product_price, array( 'cart_item' => $cart_item, 'cart_item_key' => $cart_item_key, ) ); } } return $product_price; } /** * Remove products added by the coupon from validation * * Since the filter 'woocommerce_coupon_get_items_to_validate' is added in WooCommerce 3.4.0, this function will work only in WC 3.4.0+ * Otherwise, the products added by coupon might get double discounts applied * * @param array $items The cart/order items. * @param WC_Discounts $discounts The discounts object. * @return mixed $items */ public function remove_products_from_validation( $items = array(), $discounts = null ) { if ( ! empty( $items ) && ! is_scalar( $items ) ) { foreach ( $items as $index => $item ) { $coupon_code = ''; if ( is_array( $item->object ) && isset( $item->object['wc_sc_product_source'] ) ) { $coupon_code = $item->object['wc_sc_product_source']; } elseif ( is_a( $item->object, 'WC_Order_Item' ) && is_callable( array( $item->object, 'get_meta' ) ) && $item->object->get_meta( '_wc_sc_product_source' ) ) { $coupon_code = $item->object->get_meta( '_wc_sc_product_source' ); } if ( ! empty( $coupon_code ) ) { $item_product_id = ( is_a( $item->product, 'WC_Product' ) && is_callable( array( $item->product, 'get_id' ) ) ) ? $item->product->get_id() : 0; $coupon_actions = $this->get_coupon_actions( $coupon_code ); if ( ! empty( $coupon_actions ) && ! is_scalar( $coupon_actions ) ) { foreach ( $coupon_actions as $product_data ) { if ( ! empty( $product_data['product_id'] ) && absint( $product_data['product_id'] ) === absint( $item_product_id ) ) { $discount_amount = ( '' !== $product_data['discount_amount'] ) ? $product_data['discount_amount'] : ''; if ( '' !== $discount_amount ) { unset( $items[ $index ] ); } } } } } } } return $items; } /** * Apply coupons actions * * @param string $coupon_code The coupon code. * @param WC_Order $order WooCommerce order instance. */ public function coupon_action( $coupon_code = '', $order = null ) { if ( empty( $coupon_code ) ) { return; } if ( $coupon_code instanceof WC_Coupon && is_callable( array( $coupon_code, 'get_code' ) ) ) { $coupon_code = $coupon_code->get_code(); } $coupon_actions = $this->get_coupon_actions( $coupon_code ); if ( ! empty( $coupon_actions ) && ! is_scalar( $coupon_actions ) ) { $product_names = array(); foreach ( $coupon_actions as $coupon_action ) { if ( empty( $coupon_action['product_id'] ) ) { continue; } $id = absint( $coupon_action['product_id'] ); $product = wc_get_product( $id ); $product_data = $this->get_product_data( $product ); $product_id = ( ! empty( $product_data['product_id'] ) ) ? absint( $product_data['product_id'] ) : 0; $variation_id = ( ! empty( $product_data['variation_id'] ) ) ? absint( $product_data['variation_id'] ) : 0; $variation = array(); if ( ! empty( $variation_id ) ) { $variation = $product->get_variation_attributes(); } $quantity = absint( $coupon_action['quantity'] ); $cart_item_data = array( 'wc_sc_product_source' => $coupon_code, ); if ( $order instanceof WC_Abstract_Order ) { $product_exists = false; $order_items = $order->get_items(); foreach ( $order_items as $order_item ) { if ( absint( $order_item->get_product_id() ) === $product_id ) { $product_exists = true; // Exit if the product is already in the order. break; } } if ( ! $product_exists ) { // Add a line item to the order. $item = new WC_Order_Item_Product(); $discount_amount = ( '' !== $product_data['discount_amount'] ) ? $coupon_action['discount_amount'] : ''; $discount_type = ( ! empty( $coupon_action['discount_type'] ) ) ? $coupon_action['discount_type'] : 'percent'; switch ( $discount_type ) { case 'flat': $discount = $this->convert_price( $discount_amount ); break; case 'percent': $discount = ( $product->get_price() * $discount_amount ) / 100; break; } // Calculated the discounted amount. $discounted_price = ( $product->get_price() - $discount ) * $quantity; $item->set_props( array( 'name' => $product->get_name(), 'product_id' => $product_id, // ID of the product to add. 'quantity' => $quantity, // Quantity of the product. 'variation_id' => $variation_id, // ID of the product variation (if applicable). ) ); $item->set_subtotal( $discounted_price ); $item->add_meta_data( '_wc_sc_product_source', $coupon_code ); $item->set_order_id( $order->get_id() ); // Add the item to the order. $order->add_item( $item ); } } else { $cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation, $cart_item_data ); if ( ! empty( $cart_item_key ) ) { if ( $this->is_wc_gte_30() ) { $product_names[] = ( is_object( $product ) && is_callable( array( $product, 'get_name' ) ) ) ? $product->get_name() : ''; } else { $product_names[] = ( is_object( $product ) && is_callable( array( $product, 'get_title' ) ) ) ? $product->get_title() : ''; } } } } if ( ! ( $order instanceof WC_Abstract_Order ) && ! empty( $product_names ) ) { /* translators: 1. Product title */ wc_add_notice( sprintf( __( '%s has been added to your cart!', 'woocommerce-smart-coupons' ), implode( ', ', $product_names ) ) ); } } } /** * Remove products from cart if the coupon, which added the product, is removed * * @param string $coupon_code The coupon code. */ public function remove_product_from_cart( $coupon_code = '' ) { if ( is_admin() ) { return; } if ( ! empty( $coupon_code ) ) { foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { if ( isset( $cart_item['wc_sc_product_source'] ) && $cart_item['wc_sc_product_source'] === $coupon_code ) { // Action 'woocommerce_before_calculate_totals' is hooked by WooCommerce Subscription while removing coupons in local WooCommerce Cart variable in which we don't need to remove added cart item. if ( ! doing_action( 'woocommerce_before_calculate_totals' ) ) { WC()->cart->set_quantity( $cart_item_key, 0 ); } } } } } /** * Remove products added by coupon actions when the coupon is removed from the order. */ public function remove_product_from_order() { $action = ( ! empty( $_POST['action'] ) ) ? wc_clean( wp_unslash( $_POST['action'] ) ) : ''; // phpcs:ignore $coupon_code = ( ! empty( $_POST['coupon'] ) ) ? wc_clean( wp_unslash( $_POST['coupon'] ) ) : ''; // phpcs:ignore $order_id = ( ! empty( $_POST['order_id'] ) ) ? wc_clean( wp_unslash( $_POST['order_id'] ) ) : 0; // phpcs:ignore if ( 'woocommerce_remove_order_coupon' !== $action || empty( $order_id ) || empty( $coupon_code ) ) { return; } $order = wc_get_order( $order_id ); if ( ! $order instanceof WC_Order ) { return; } foreach ( $order->get_items() as $item_id => $item ) { if ( $item->get_meta( '_wc_sc_product_source', true ) === $coupon_code ) { $order->remove_item( $item_id ); } } $order->calculate_totals(); // Recalculate totals. $order->save(); // Save the order. } /** * Review cart items */ public function review_cart_items() { $cart = ( is_object( WC() ) && isset( WC()->cart ) ) ? WC()->cart : null; $applied_coupons = isset( $cart->applied_coupons ) ? (array) $cart->applied_coupons : array(); $products = array(); if ( $cart instanceof WC_Cart && is_callable( array( $cart, 'get_cart' ) ) ) { foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) { if ( ! empty( $cart_item['wc_sc_product_source'] ) && ! in_array( $cart_item['wc_sc_product_source'], $applied_coupons, true ) ) { $cart->set_quantity( $cart_item_key, 0 ); $coupon_code = $cart_item['wc_sc_product_source']; if ( empty( $products[ $coupon_code ] ) || ! is_array( $products[ $coupon_code ] ) ) { $products[ $coupon_code ] = array(); } $products[ $coupon_code ][] = ( is_object( $cart_item['data'] ) && is_callable( array( $cart_item['data'], 'get_name' ) ) ) ? $cart_item['data']->get_name() : ''; $products[ $coupon_code ] = array_filter( $products[ $coupon_code ] ); } } } if ( ! empty( $products ) && ! is_scalar( $products ) ) { foreach ( $products as $coupon_code => $product_names ) { /* translators: 1. Product/s 2. Product names 3. is/are 4. Coupons code */ wc_add_notice( sprintf( __( '%1$s %2$s %3$s removed because coupon %4$s is removed.', 'woocommerce-smart-coupons' ), _n( 'Product', 'Products', count( $products[ $coupon_code ] ), 'woocommerce-smart-coupons' ), '' . implode( ', ', $products[ $coupon_code ] ) . '', _n( 'is', 'are', count( $products[ $coupon_code ] ), 'woocommerce-smart-coupons' ), '' . $coupon_code . '' ), 'error' ); } } } /** * Add product source in order item meta * * @param mixed $item The item. * @param string $cart_item_key The cart item key. * @param array $values The cart item. * @param WC_Order $order The order. */ public function add_product_source_in_order_item_meta( $item = null, $cart_item_key = '', $values = array(), $order = null ) { if ( isset( $values['wc_sc_product_source'] ) ) { $item->add_meta_data( '_wc_sc_product_source', $values['wc_sc_product_source'], true ); } } /** * Get product data * * @param mixed $product The product object. * @return array */ public function get_product_data( $product = null ) { if ( empty( $product ) ) { return array(); } if ( $this->is_wc_gte_30() ) { $product_id = ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) ) ? $product->get_id() : 0; } else { $product_id = ( ! empty( $product->id ) ) ? $product->id : 0; } $product_type = ( is_object( $product ) && is_callable( array( $product, 'get_type' ) ) ) ? $product->get_type() : ''; if ( 'variation' === $product_type ) { $variation_id = $product_id; if ( $this->is_wc_gte_30() ) { $parent_id = ( is_object( $product ) && is_callable( array( $product, 'get_parent_id' ) ) ) ? $product->get_parent_id() : 0; $variation_data = wc_get_product_variation_attributes( $variation_id ); } else { $parent_id = ( is_object( $product ) && is_callable( array( $product, 'get_parent' ) ) ) ? $product->get_parent() : 0; $variation_data = ( ! empty( $product->variation_data ) ) ? $product->variation_data : array(); } $product_id = $parent_id; } else { $variation_id = 0; $variation_data = array(); } $product_data = array( 'product_id' => $product_id, 'variation_id' => $variation_id, 'variation_data' => $variation_data, ); return apply_filters( 'wc_sc_product_data', $product_data, array( 'product_obj' => $product ) ); } /** * Add action's meta in export headers * * @param array $headers Existing headers. * @return array */ public function export_headers( $headers = array() ) { $action_headers = array( 'wc_sc_add_product_details' => __( 'Add product details', 'woocommerce-smart-coupons' ), ); return array_merge( $headers, $action_headers ); } /** * Function to handle coupon meta data during export of existing coupons * * @param mixed $meta_value The meta value. * @param array $args Additional arguments. * @return string Processed meta value */ public function export_coupon_meta_data( $meta_value = '', $args = array() ) { $index = ( ! empty( $args['index'] ) ) ? $args['index'] : -1; $meta_keys = ( ! empty( $args['meta_keys'] ) ) ? $args['meta_keys'] : array(); $meta_values = ( ! empty( $args['meta_values'] ) ) ? $args['meta_values'] : array(); if ( $index >= 0 && ! empty( $meta_keys[ $index ] ) && 'wc_sc_add_product_details' === $meta_keys[ $index ] ) { if ( ! empty( $meta_value ) && is_array( $meta_value ) ) { $product_details = array(); foreach ( $meta_value as $value ) { $product_details[] = implode( ',', $value ); } $meta_value = implode( '|', $product_details ); } } return $meta_value; } /** * Post meta defaults for action's meta * * @param array $defaults Existing postmeta defaults. * @return array */ public function postmeta_defaults( $defaults = array() ) { $actions_defaults = array( 'wc_sc_add_product_details' => '', ); return array_merge( $defaults, $actions_defaults ); } /** * Add action's meta with value in coupon meta * * @param array $data The row data. * @param array $post The POST values. * @return array Modified data */ public function generate_coupon_meta( $data = array(), $post = array() ) { if ( isset( $post['wc_sc_add_product_ids'] ) ) { if ( $this->is_wc_gte_30() ) { $product_ids = wc_clean( wp_unslash( $post['wc_sc_add_product_ids'] ) ); // phpcs:ignore } else { $product_ids = array_filter( array_map( 'trim', explode( ',', sanitize_text_field( wp_unslash( $post['wc_sc_add_product_ids'] ) ) ) ) ); // phpcs:ignore } $add_product_details = array(); if ( ! empty( $product_ids ) && ! is_scalar( $product_ids ) ) { $quantity = ( isset( $post['wc_sc_add_product_qty'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_add_product_qty'] ) ) : 1; $discount_amount = ( isset( $post['wc_sc_product_discount_amount'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_product_discount_amount'] ) ) : ''; $discount_type = ( isset( $post['wc_sc_product_discount_type'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_product_discount_type'] ) ) : ''; foreach ( $product_ids as $id ) { $product_data = array(); $product_data['product_id'] = $id; $product_data['quantity'] = $quantity; $product_data['discount_amount'] = $discount_amount; $product_data['discount_type'] = $discount_type; $add_product_details[] = implode( ',', $product_data ); } } $data['wc_sc_add_product_details'] = implode( '|', $add_product_details ); } return $data; } /** * Make meta data of SC actions, protected * * @param bool $protected Is protected. * @param string $meta_key The meta key. * @param string $meta_type The meta type. * @return bool $protected */ public function make_action_meta_protected( $protected, $meta_key, $meta_type ) { $sc_meta = array( 'wc_sc_add_product_details', ); if ( in_array( $meta_key, $sc_meta, true ) ) { return true; } return $protected; } /** * Function to copy coupon action meta in newly generated coupon * * @param array $args The arguments. */ public function copy_coupon_action_meta( $args = array() ) { $new_coupon_id = ( ! empty( $args['new_coupon_id'] ) ) ? absint( $args['new_coupon_id'] ) : 0; $coupon = ( ! empty( $args['ref_coupon'] ) ) ? $args['ref_coupon'] : false; if ( empty( $new_coupon_id ) || empty( $coupon ) ) { return; } $add_product_details = array(); if ( $this->is_wc_gte_30() ) { $add_product_details = $coupon->get_meta( 'wc_sc_add_product_details' ); } else { $old_coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0; $add_product_details = get_post_meta( $old_coupon_id, 'wc_sc_add_product_details', true ); } $this->update_post_meta( $new_coupon_id, 'wc_sc_add_product_details', $add_product_details ); } /** * Function to validate whether to show the coupon or not * * @param boolean $is_show Show or not. * @param array $args Additional arguments. * @return boolean */ public function show_coupon_with_actions( $is_show = false, $args = array() ) { $coupon = ( ! empty( $args['coupon'] ) ) ? $args['coupon'] : null; if ( empty( $coupon ) ) { return $is_show; } if ( $this->is_wc_gte_30() ) { $coupon_code = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : ''; } else { $coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : ''; } $coupon_actions = $this->get_coupon_actions( $coupon_code ); if ( ! empty( $coupon_actions ) ) { return true; } return $is_show; } /** * Allow auto-generate of coupon with coupon action * * @param boolean $is_auto_generate Whether to auto-generate or not. * @param array $args Additional parameters. * @return boolean $is_auto_generate */ public function auto_generate_coupon_with_actions( $is_auto_generate = false, $args = array() ) { $coupon = ( ! empty( $args['coupon_obj'] ) && $args['coupon_obj'] instanceof WC_Coupon ) ? $args['coupon_obj'] : false; $coupon_id = ( ! empty( $args['coupon_id'] ) ) ? $args['coupon_id'] : false; if ( ! empty( $coupon ) && ! empty( $coupon_id ) ) { if ( $this->is_wc_gte_30() ) { $coupon_code = $coupon->get_code(); } else { $coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : ''; } if ( ! empty( $coupon_code ) ) { $actions = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_add_product_details' ) : get_post_meta( $coupon_id, 'wc_sc_add_product_details', true ); $coupon_actions = apply_filters( 'wc_sc_coupon_actions', $actions, array( 'coupon_code' => $coupon_code, 'source' => $this, ) ); if ( ! empty( $coupon_actions ) ) { return true; } } } return $is_auto_generate; } /** * Validate coupon having actions but without an amount * * @param boolean $is_valid_coupon_amount Whether the amount is validate or not. * @param array $args Additional parameters. * @return boolean */ public function validate_coupon_amount( $is_valid_coupon_amount = true, $args = array() ) { if ( ! $is_valid_coupon_amount ) { $coupon_amount = ( ! empty( $args['coupon_amount'] ) ) ? $args['coupon_amount'] : 0; $discount_type = ( ! empty( $args['discount_type'] ) ) ? $args['discount_type'] : ''; $coupon_code = ( ! empty( $args['coupon_code'] ) ) ? $args['coupon_code'] : ''; $coupon_actions = ( ! empty( $coupon_code ) ) ? $this->get_coupon_actions( $coupon_code ) : array(); if ( 'smart_coupon' === $discount_type && $coupon_amount <= 0 && ! empty( $coupon_actions ) ) { return true; } } return $is_valid_coupon_amount; } /** * Handle coupon actions when the cart is empty * * @param boolean $is_hold Whether to hold the coupon in cookie. * @param array $args Additional arguments. * @return boolean */ public function maybe_run_coupon_actions( $is_hold = true, $args = array() ) { $cart = ( is_object( WC() ) && isset( WC()->cart ) ) ? WC()->cart : null; if ( empty( $cart ) || WC()->cart->is_empty() ) { $coupons_data = ( ! empty( $args['coupons_data'] ) ) ? $args['coupons_data'] : array(); if ( ! empty( $coupons_data ) && ! is_scalar( $coupons_data ) ) { foreach ( $coupons_data as $coupon_data ) { $coupon_code = ( ! empty( $coupon_data['coupon-code'] ) ) ? $coupon_data['coupon-code'] : ''; if ( ! empty( $coupon_code ) ) { $coupon = new WC_Coupon( $coupon_code ); $coupon_actions = $this->get_coupon_actions( $coupon_code ); $coupon_products = ( ! empty( $coupon_actions ) ) ? wp_list_pluck( $coupon_actions, 'product_id' ) : array(); if ( ! empty( $coupon_products ) ) { if ( $this->is_valid( $coupon ) && ! WC()->cart->has_discount( $coupon_code ) ) { WC()->cart->add_discount( trim( $coupon_code ) ); $is_hold = false; } } } } } } return $is_hold; } /** * Stop product update option for action tab products. * * @param string $cart_item_key contains the id of the cart item. * @param int $quantity Current quantity of the item. * @param int $old_quantity Old quantity of the item. * @param WC_Cart $cart Cart object. * @return void */ public function stop_cart_item_quantity_update( $cart_item_key = '', $quantity = 1, $old_quantity = 1, $cart = object ) { if ( empty( $cart_item_key ) || ! is_object( $cart ) || ! is_a( $cart, 'WC_Cart' ) ) { return; } $cart_data = is_callable( array( $cart, 'get_cart' ) ) ? $cart->get_cart() : array(); $cart_item = ( ! empty( $cart_data[ $cart_item_key ] ) ) ? $cart_data[ $cart_item_key ] : array(); if ( empty( $cart_item ) ) { return; } $applied_coupons = is_callable( array( $cart, 'get_applied_coupons' ) ) ? $cart->get_applied_coupons() : array(); if ( ! empty( $cart_item['wc_sc_product_source'] ) && in_array( $cart_item['wc_sc_product_source'], $applied_coupons, true ) ) { $cart->cart_contents[ $cart_item_key ]['quantity'] = $old_quantity; } } } } WC_SC_Coupon_Actions::get_instance();