Merge branch 'master' of github.com:woothemes/woocommerce
This commit is contained in:
commit
03c16229e0
|
@ -916,7 +916,7 @@ class WC_Cart {
|
|||
$cart_item_key = $cart_id;
|
||||
|
||||
// Add item after merging with $cart_item_data - hook to allow plugins to modify cart item
|
||||
$this->cart_contents[$cart_item_key] = apply_filters( 'woocommerce_add_cart_item', array_merge( $cart_item_data, array(
|
||||
$this->cart_contents[ $cart_item_key ] = apply_filters( 'woocommerce_add_cart_item', array_merge( $cart_item_data, array(
|
||||
'product_id' => $product_id,
|
||||
'variation_id' => $variation_id,
|
||||
'variation' => $variation,
|
||||
|
@ -978,6 +978,7 @@ class WC_Cart {
|
|||
$this->$key = $default;
|
||||
unset( WC()->session->$key );
|
||||
}
|
||||
do_action( 'woocommerce_cart_reset', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -986,6 +987,7 @@ class WC_Cart {
|
|||
public function calculate_totals() {
|
||||
|
||||
$this->reset();
|
||||
$this->coupons = $this->get_coupons();
|
||||
|
||||
do_action( 'woocommerce_before_calculate_totals', $this );
|
||||
|
||||
|
@ -1663,8 +1665,9 @@ class WC_Cart {
|
|||
foreach ( $this->applied_coupons as $code ) {
|
||||
$coupon = new WC_Coupon( $code );
|
||||
|
||||
if ( $coupon->apply_before_tax() )
|
||||
if ( $coupon->apply_before_tax() ) {
|
||||
$coupons[ $code ] = $coupon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1674,8 +1677,9 @@ class WC_Cart {
|
|||
foreach ( $this->applied_coupons as $code ) {
|
||||
$coupon = new WC_Coupon( $code );
|
||||
|
||||
if ( ! $coupon->apply_before_tax() )
|
||||
if ( ! $coupon->apply_before_tax() ) {
|
||||
$coupons[ $code ] = $coupon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1765,13 +1769,12 @@ class WC_Cart {
|
|||
* @return float price
|
||||
*/
|
||||
public function get_discounted_price( $values, $price, $add_totals = false ) {
|
||||
if ( ! $price )
|
||||
if ( ! $price ) {
|
||||
return $price;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->applied_coupons ) ) {
|
||||
foreach ( $this->applied_coupons as $code ) {
|
||||
$coupon = new WC_Coupon( $code );
|
||||
|
||||
if ( ! empty( $this->coupons ) ) {
|
||||
foreach ( $this->coupons as $code => $coupon ) {
|
||||
if ( $coupon->apply_before_tax() && $coupon->is_valid() ) {
|
||||
if ( $coupon->is_valid_for_product( $values['data'], $values ) || $coupon->is_valid_for_cart() ) {
|
||||
|
||||
|
@ -1799,10 +1802,8 @@ class WC_Cart {
|
|||
public function apply_cart_discounts_after_tax() {
|
||||
$pre_discount_total = round( $this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $this->shipping_total + $this->fee_total, $this->dp );
|
||||
|
||||
if ( $this->applied_coupons ) {
|
||||
foreach ( $this->applied_coupons as $code ) {
|
||||
$coupon = new WC_Coupon( $code );
|
||||
|
||||
if ( $this->coupons ) {
|
||||
foreach ( $this->coupons as $code => $coupon ) {
|
||||
do_action( 'woocommerce_cart_discount_after_tax_' . $coupon->type, $coupon );
|
||||
|
||||
if ( $coupon->is_valid() && ! $coupon->apply_before_tax() && $coupon->is_valid_for_cart() ) {
|
||||
|
@ -1824,10 +1825,8 @@ class WC_Cart {
|
|||
* @param double $price
|
||||
*/
|
||||
public function apply_product_discounts_after_tax( $values, $price ) {
|
||||
if ( ! empty( $this->applied_coupons ) ) {
|
||||
foreach ( $this->applied_coupons as $code ) {
|
||||
$coupon = new WC_Coupon( $code );
|
||||
|
||||
if ( ! empty( $this->coupons ) ) {
|
||||
foreach ( $this->coupons as $code => $coupon ) {
|
||||
do_action( 'woocommerce_product_discount_after_tax_' . $coupon->type, $coupon, $values, $price );
|
||||
|
||||
if ( $coupon->is_valid() && ! $coupon->apply_before_tax() && $coupon->is_valid_for_product( $values['data'] ) ) {
|
||||
|
@ -1848,8 +1847,9 @@ class WC_Cart {
|
|||
* @param double $amount
|
||||
*/
|
||||
private function increase_coupon_discount_amount( $code, $amount ) {
|
||||
if ( empty( $this->coupon_discount_amounts[ $code ] ) )
|
||||
if ( empty( $this->coupon_discount_amounts[ $code ] ) ) {
|
||||
$this->coupon_discount_amounts[ $code ] = 0;
|
||||
}
|
||||
|
||||
$this->coupon_discount_amounts[ $code ] += $amount;
|
||||
}
|
||||
|
@ -1862,8 +1862,9 @@ class WC_Cart {
|
|||
* @param integer $count
|
||||
*/
|
||||
private function increase_coupon_applied_count( $code, $count = 1 ) {
|
||||
if ( empty( $this->coupon_applied_count[ $code ] ) )
|
||||
if ( empty( $this->coupon_applied_count[ $code ] ) ) {
|
||||
$this->coupon_applied_count[ $code ] = 0;
|
||||
}
|
||||
|
||||
$this->coupon_applied_count[ $code ] += $count;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* The WooCommerce coupons class gets coupon data from storage and checks coupon validity
|
||||
*
|
||||
* @class WC_Coupon
|
||||
* @version 2.3.0
|
||||
* @package WooCommerce/Classes
|
||||
* @category Class
|
||||
* @author WooThemes
|
||||
|
@ -31,73 +32,13 @@ class WC_Coupon {
|
|||
const WC_COUPON_REMOVED = 201;
|
||||
|
||||
/** @public string Coupon code. */
|
||||
public $code;
|
||||
public $code = '';
|
||||
|
||||
/** @public int Coupon ID. */
|
||||
public $id;
|
||||
public $id = 0;
|
||||
|
||||
/** @public string Type of discount. */
|
||||
public $type;
|
||||
|
||||
/** @public string Type of discount (alias). */
|
||||
public $discount_type;
|
||||
|
||||
/** @public string Coupon amount. */
|
||||
public $amount;
|
||||
|
||||
/** @public string "Yes" if for individual use. */
|
||||
public $individual_use;
|
||||
|
||||
/** @public array Array of product IDs. */
|
||||
public $product_ids;
|
||||
|
||||
/** @public int Coupon usage limit. */
|
||||
public $usage_limit;
|
||||
|
||||
/** @public int Coupon usage limit per user. */
|
||||
public $usage_limit_per_user;
|
||||
|
||||
/** @public int Coupon usage limit per item. */
|
||||
public $limit_usage_to_x_items;
|
||||
|
||||
/** @public int Coupon usage count. */
|
||||
public $usage_count;
|
||||
|
||||
/** @public string Expiry date. */
|
||||
public $expiry_date;
|
||||
|
||||
/** @public string "yes" if applied before tax. */
|
||||
public $apply_before_tax;
|
||||
|
||||
/** @public string "yes" if coupon grants free shipping. */
|
||||
public $free_shipping;
|
||||
|
||||
/** @public array Array of category ids. */
|
||||
public $product_categories;
|
||||
|
||||
/** @public array Array of category ids. */
|
||||
public $exclude_product_categories;
|
||||
|
||||
/** @public string "yes" if coupon does NOT apply to items on sale. */
|
||||
public $exclude_sale_items;
|
||||
|
||||
/** @public string Minimum cart amount. */
|
||||
public $minimum_amount;
|
||||
|
||||
/** @public string Maximum cart amount. */
|
||||
public $maximum_amount;
|
||||
|
||||
/** @public string Coupon owner's email. */
|
||||
public $customer_email;
|
||||
|
||||
/** @public array Post meta. */
|
||||
public $coupon_custom_fields;
|
||||
|
||||
/** @public string How much the coupon is worth. */
|
||||
public $coupon_amount;
|
||||
|
||||
/** @public string Error message. */
|
||||
public $error_message;
|
||||
/** @public bool Coupon exists */
|
||||
public $exists = false;
|
||||
|
||||
/**
|
||||
* Coupon constructor. Loads coupon data.
|
||||
|
@ -106,127 +47,181 @@ class WC_Coupon {
|
|||
* @param mixed $code code of the coupon to load
|
||||
*/
|
||||
public function __construct( $code ) {
|
||||
global $wpdb;
|
||||
$this->exists = $this->get_coupon( $code );
|
||||
}
|
||||
|
||||
/**
|
||||
* __isset function.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset( $key ) {
|
||||
if ( in_array( $key, array( 'coupon_custom_fields', 'type', 'amount' ) ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* __get function.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $key ) {
|
||||
// Get values or default if not set
|
||||
if ( 'coupon_custom_fields' === $key ) {
|
||||
$value = $this->id ? get_post_meta( $this->id ) : array();
|
||||
} elseif ( 'type' === $key ) {
|
||||
$value = $this->discount_type;
|
||||
} elseif ( 'amount' === $key ) {
|
||||
$value = $this->coupon_amount;
|
||||
} else {
|
||||
$value = '';
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the coupon type.
|
||||
*
|
||||
* @param string $type Array or string of types
|
||||
* @return bool
|
||||
*/
|
||||
public function is_type( $type ) {
|
||||
return ( $this->discount_type == $type || ( is_array( $type ) && in_array( $this->discount_type, $type ) ) ) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an coupon from the database.
|
||||
*
|
||||
* @param string $code
|
||||
* @return bool
|
||||
*/
|
||||
private function get_coupon( $code ) {
|
||||
$this->code = apply_filters( 'woocommerce_coupon_code', $code );
|
||||
|
||||
// Coupon data lets developers create coupons through code
|
||||
$coupon_data = apply_filters( 'woocommerce_get_shop_coupon_data', false, $code );
|
||||
if ( $coupon = apply_filters( 'woocommerce_get_shop_coupon_data', false, $code ) ) {
|
||||
$this->populate( $coupon );
|
||||
return true;
|
||||
} elseif ( ( $this->id = $this->get_coupon_id_from_code( $code ) ) && $this->code === get_the_title( $this->id ) ) {
|
||||
$this->populate();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $coupon_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->id = absint( $coupon_data['id'] );
|
||||
$this->type = esc_html( $coupon_data['type'] );
|
||||
$this->amount = esc_html( $coupon_data['amount'] ? $coupon_data['amount'] : $coupon_data['coupon_amount'] ) ;
|
||||
$this->coupon_amount = $this->amount;
|
||||
$this->individual_use = esc_html( $coupon_data['individual_use'] );
|
||||
$this->product_ids = is_array( $coupon_data['product_ids'] ) ? $coupon_data['product_ids'] : array();
|
||||
$this->exclude_product_ids = is_array( $coupon_data['exclude_product_ids'] ) ? $coupon_data['exclude_product_ids'] : array();
|
||||
$this->usage_limit = absint( $coupon_data['usage_limit'] );
|
||||
$this->usage_limit_per_user = isset( $coupon_data['usage_limit_per_user'] ) ? absint( $coupon_data['usage_limit_per_user'] ) : 0;
|
||||
$this->limit_usage_to_x_items = isset( $coupon_data['limit_usage_to_x_items'] ) ? absint( $coupon_data['limit_usage_to_x_items'] ) : '';
|
||||
$this->usage_count = absint( $coupon_data['usage_count'] );
|
||||
$this->expiry_date = esc_html( $coupon_data['expiry_date'] );
|
||||
$this->apply_before_tax = esc_html( $coupon_data['apply_before_tax'] );
|
||||
$this->free_shipping = esc_html( $coupon_data['free_shipping'] );
|
||||
$this->product_categories = is_array( $coupon_data['product_categories'] ) ? $coupon_data['product_categories'] : array();
|
||||
$this->exclude_product_categories = is_array( $coupon_data['exclude_product_categories'] ) ? $coupon_data['exclude_product_categories'] : array();
|
||||
$this->exclude_sale_items = esc_html( $coupon_data['exclude_sale_items'] );
|
||||
$this->minimum_amount = esc_html( $coupon_data['minimum_amount'] );
|
||||
$this->maximum_amount = esc_html( $coupon_data['maximum_amount'] );
|
||||
$this->customer_email = esc_html( $coupon_data['customer_email'] );
|
||||
/**
|
||||
* Get a coupon ID from it's code
|
||||
* @param string $code
|
||||
* @return int
|
||||
*/
|
||||
private function get_coupon_id_from_code( $code ) {
|
||||
global $wpdb;
|
||||
|
||||
} else {
|
||||
return absint( $wpdb->get_var( $wpdb->prepare( apply_filters( 'woocommerce_coupon_code_query', "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish'" ), $this->code ) ) );
|
||||
}
|
||||
|
||||
$coupon_id = $wpdb->get_var( $wpdb->prepare( apply_filters( 'woocommerce_coupon_code_query', "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish'" ), $this->code ) );
|
||||
/**
|
||||
* Populates an order from the loaded post data.
|
||||
*/
|
||||
private function populate( $data = array() ) {
|
||||
$defaults = array(
|
||||
'discount_type' => 'fixed_cart',
|
||||
'coupon_amount' => 0,
|
||||
'individual_use' => 'no',
|
||||
'product_ids' => array(),
|
||||
'exclude_product_ids' => array(),
|
||||
'usage_limit' => '',
|
||||
'usage_limit_per_user' => '',
|
||||
'limit_usage_to_x_items' => '',
|
||||
'usage_count' => '',
|
||||
'expiry_date' => '',
|
||||
'apply_before_tax' => 'yes',
|
||||
'free_shipping' => 'no',
|
||||
'product_categories' => array(),
|
||||
'exclude_product_categories' => array(),
|
||||
'exclude_sale_items' => 'no',
|
||||
'minimum_amount' => '',
|
||||
'maximum_amount' => '',
|
||||
'customer_email' => array()
|
||||
);
|
||||
|
||||
if ( ! $coupon_id )
|
||||
return;
|
||||
foreach ( $defaults as $key => $value ) {
|
||||
// Try to load from meta if an ID is present
|
||||
if ( $this->id ) {
|
||||
$this->$key = get_post_meta( $this->id, $key, true );
|
||||
} else {
|
||||
$this->$key = ! empty( $data[ $key ] ) ? wc_clean( $data[ $key ] ) : '';
|
||||
|
||||
$coupon = get_post( $coupon_id );
|
||||
$this->post_title = apply_filters( 'woocommerce_coupon_code', $coupon->post_title );
|
||||
// Backwards compat field names @deprecated
|
||||
if ( 'coupon_amount' === $key ) {
|
||||
$this->coupon_amount = ! empty( $data[ 'amount' ] ) ? wc_clean( $data[ 'amount' ] ) : $this->coupon_amount;
|
||||
} elseif ( 'discount_type' === $key ) {
|
||||
$this->discount_type = ! empty( $data[ 'type' ] ) ? wc_clean( $data[ 'type' ] ) : $this->discount_type;
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $coupon ) || $this->code !== $this->post_title )
|
||||
return;
|
||||
|
||||
$this->id = $coupon->ID;
|
||||
$this->coupon_custom_fields = get_post_meta( $this->id );
|
||||
|
||||
$load_data = array(
|
||||
'discount_type' => 'fixed_cart',
|
||||
'coupon_amount' => 0,
|
||||
'individual_use' => 'no',
|
||||
'product_ids' => '',
|
||||
'exclude_product_ids' => '',
|
||||
'usage_limit' => '',
|
||||
'usage_limit_per_user' => '',
|
||||
'limit_usage_to_x_items' => '',
|
||||
'usage_count' => '',
|
||||
'expiry_date' => '',
|
||||
'apply_before_tax' => 'yes',
|
||||
'free_shipping' => 'no',
|
||||
'product_categories' => array(),
|
||||
'exclude_product_categories' => array(),
|
||||
'exclude_sale_items' => 'no',
|
||||
'minimum_amount' => '',
|
||||
'maximum_amount' => '',
|
||||
'customer_email' => array()
|
||||
);
|
||||
|
||||
foreach ( $load_data as $key => $default )
|
||||
$this->$key = isset( $this->coupon_custom_fields[ $key ][0] ) && $this->coupon_custom_fields[ $key ][0] !== '' ? $this->coupon_custom_fields[ $key ][0] : $default;
|
||||
|
||||
// Alias
|
||||
$this->type = $this->discount_type;
|
||||
$this->amount = $this->coupon_amount;
|
||||
|
||||
// Formatting
|
||||
$this->product_ids = array_filter( array_map( 'trim', explode( ',', $this->product_ids ) ) );
|
||||
$this->exclude_product_ids = array_filter( array_map( 'trim', explode( ',', $this->exclude_product_ids ) ) );
|
||||
$this->expiry_date = $this->expiry_date ? strtotime( $this->expiry_date ) : '';
|
||||
$this->product_categories = array_filter( array_map( 'trim', (array) maybe_unserialize( $this->product_categories ) ) );
|
||||
$this->exclude_product_categories = array_filter( array_map( 'trim', (array) maybe_unserialize( $this->exclude_product_categories ) ) );
|
||||
$this->customer_email = array_filter( array_map( 'trim', array_map( 'strtolower', (array) maybe_unserialize( $this->customer_email ) ) ) );
|
||||
if ( empty( $this->$key ) ) {
|
||||
$this->$key = $value;
|
||||
} elseif ( in_array( $key, array( 'product_ids', 'exclude_product_ids', 'product_categories', 'exclude_product_categories', 'customer_email' ) ) ) {
|
||||
$this->$key = $this->format_array( $this->$key );
|
||||
} elseif ( in_array( $key, array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items', 'usage_count' ) ) ) {
|
||||
$this->$key = absint( $this->$key );
|
||||
} elseif( 'expiry_date' === $key ) {
|
||||
$this->expiry_date = $this->expiry_date && ! is_numeric( $this->expiry_date ) ? strtotime( $this->expiry_date ) : $this->expiry_date;
|
||||
}
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_coupon_loaded', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format loaded data as array
|
||||
* @param string|array $array
|
||||
* @return array
|
||||
*/
|
||||
public function format_array( $array ) {
|
||||
if ( ! is_array( $array ) ) {
|
||||
if ( is_serialized( $array ) ) {
|
||||
$array = maybe_unserialize( $array );
|
||||
} else {
|
||||
$array = explode( ',', $array );
|
||||
}
|
||||
}
|
||||
return array_filter( array_map( 'trim', array_map( 'strtolower', $array ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if coupon needs applying before tax.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function apply_before_tax() {
|
||||
return $this->apply_before_tax == 'yes' ? true : false;
|
||||
return 'yes' === $this->apply_before_tax;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a coupon enables free shipping.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function enable_free_shipping() {
|
||||
return $this->free_shipping == 'yes' ? true : false;
|
||||
return 'yes' === $this->free_shipping;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a coupon excludes sale items.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function exclude_sale_items() {
|
||||
return $this->exclude_sale_items == 'yes' ? true : false;
|
||||
return 'yes' === $this->exclude_sale_items;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Increase usage count for current coupon.
|
||||
*
|
||||
|
@ -235,15 +230,15 @@ class WC_Coupon {
|
|||
* @return void
|
||||
*/
|
||||
public function inc_usage_count( $used_by = '' ) {
|
||||
$this->usage_count++;
|
||||
update_post_meta( $this->id, 'usage_count', $this->usage_count );
|
||||
if ( $this->id ) {
|
||||
update_post_meta( $this->id, 'usage_count', ( $this->usage_count ++ ) );
|
||||
|
||||
if ( $used_by ) {
|
||||
add_post_meta( $this->id, '_used_by', strtolower( $used_by ) );
|
||||
if ( $used_by ) {
|
||||
add_post_meta( $this->id, '_used_by', strtolower( $used_by ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decrease usage count for current coupon.
|
||||
*
|
||||
|
@ -252,15 +247,16 @@ class WC_Coupon {
|
|||
* @return void
|
||||
*/
|
||||
public function dcr_usage_count( $used_by = '' ) {
|
||||
global $wpdb;
|
||||
if ( $this->id ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->usage_count--;
|
||||
update_post_meta( $this->id, 'usage_count', $this->usage_count );
|
||||
update_post_meta( $this->id, 'usage_count', ( $this->usage_count -- ) );
|
||||
|
||||
// Delete 1 used by meta
|
||||
$meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_used_by' AND meta_value = %s AND post_id = %d LIMIT 1;", $used_by, $this->id ) );
|
||||
if ( $meta_id ) {
|
||||
delete_metadata_by_mid( 'post', $meta_id );
|
||||
// Delete 1 used by meta
|
||||
$meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_used_by' AND meta_value = %s AND post_id = %d LIMIT 1;", $used_by, $this->id ) );
|
||||
if ( $meta_id ) {
|
||||
delete_metadata_by_mid( 'post', $meta_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,190 +271,229 @@ class WC_Coupon {
|
|||
}
|
||||
|
||||
/**
|
||||
* is_valid function.
|
||||
* Ensure coupon exists or throw exception
|
||||
*/
|
||||
private function validate_exists() {
|
||||
if ( ! $this->exists ) {
|
||||
throw new Exception( self::E_WC_COUPON_NOT_EXIST );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coupon usage limit is valid or throw exception
|
||||
*/
|
||||
private function validate_usage_limit() {
|
||||
if ( $this->usage_limit > 0 && $this->usage_count >= $this->usage_limit ) {
|
||||
throw new Exception( self::E_WC_COUPON_USAGE_LIMIT_REACHED );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coupon user usage limit is valid or throw exception
|
||||
*
|
||||
* Check if a coupon is valid. Return a reason code if invalid. Reason codes:
|
||||
* Per user usage limit - check here if user is logged in (against user IDs)
|
||||
* Checked again for emails later on in WC_Cart::check_customer_coupons()
|
||||
*/
|
||||
private function validate_user_usage_limit() {
|
||||
if ( $this->usage_limit_per_user > 0 && is_user_logged_in() && $this->id ) {
|
||||
$used_by = (array) get_post_meta( $this->id, '_used_by' );
|
||||
$usage_count = sizeof( array_keys( $used_by, get_current_user_id() ) );
|
||||
|
||||
if ( $usage_count >= $this->usage_limit_per_user ) {
|
||||
throw new Exception( self::E_WC_COUPON_USAGE_LIMIT_REACHED );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coupon date is valid or throw exception
|
||||
*/
|
||||
private function validate_expiry_date() {
|
||||
if ( $this->expiry_date && current_time( 'timestamp' ) > $this->expiry_date ) {
|
||||
throw new Exception( $error_code = self::E_WC_COUPON_EXPIRED );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coupon amount is valid or throw exception
|
||||
*/
|
||||
private function validate_minimum_amount() {
|
||||
if ( $this->minimum_amount > 0 && $this->minimum_amount > WC()->cart->subtotal ) {
|
||||
throw new Exception( self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coupon amount is valid or throw exception
|
||||
*/
|
||||
private function validate_maximum_amount() {
|
||||
if ( $this->maximum_amount > 0 && $this->maximum_amount < WC()->cart->subtotal ) {
|
||||
throw new Exception( self::E_WC_COUPON_MAX_SPEND_LIMIT_MET );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coupon is valid for products in the cart is valid or throw exception
|
||||
*/
|
||||
private function validate_product_ids() {
|
||||
if ( sizeof( $this->product_ids ) > 0 ) {
|
||||
$valid_for_cart = false;
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
if ( in_array( $cart_item['product_id'], $this->product_ids ) || in_array( $cart_item['variation_id'], $this->product_ids ) || in_array( $cart_item['data']->get_parent(), $this->product_ids ) ) {
|
||||
$valid_for_cart = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
throw new Exception( self::E_WC_COUPON_NOT_APPLICABLE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coupon is valid for product categories in the cart is valid or throw exception
|
||||
*/
|
||||
private function validate_product_categories() {
|
||||
if ( sizeof( $this->product_categories ) > 0 ) {
|
||||
$valid_for_cart = false;
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
|
||||
$product_cats = wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) );
|
||||
|
||||
if ( sizeof( array_intersect( $product_cats, $this->product_categories ) ) > 0 ) {
|
||||
$valid_for_cart = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
throw new Exception( self::E_WC_COUPON_NOT_APPLICABLE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coupon is valid for sale items in the cart is valid or throw exception
|
||||
*/
|
||||
private function validate_sale_items() {
|
||||
if ( 'yes' === $this->exclude_sale_items && $this->is_type( array( 'fixed_product', 'percent_product' ) ) ) {
|
||||
$valid_for_cart = false;
|
||||
$product_ids_on_sale = wc_get_product_ids_on_sale();
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
if ( sizeof( array_intersect( array( absint( $cart_item['product_id'] ), absint( $cart_item['variation_id'] ), $cart_item['data']->get_parent() ), $product_ids_on_sale ) ) === 0 ) {
|
||||
// not on sale
|
||||
$valid_for_cart = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
throw new Exception( self::E_WC_COUPON_NOT_VALID_SALE_ITEMS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cart discounts cannot be added if non-eligble product is found in cart
|
||||
*/
|
||||
private function validate_cart_excluded_items() {
|
||||
if ( ! $this->is_type( array( 'fixed_product', 'percent_product' ) ) ) {
|
||||
$this->validate_cart_excluded_product_ids();
|
||||
$this->validate_cart_excluded_product_categories();
|
||||
$this->validate_cart_excluded_sale_items();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude products from cart
|
||||
*/
|
||||
private function validate_cart_excluded_product_ids() {
|
||||
// Exclude Products
|
||||
if ( sizeof( $this->exclude_product_ids ) > 0 ) {
|
||||
$valid_for_cart = true;
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
if ( in_array( $cart_item['product_id'], $this->exclude_product_ids ) || in_array( $cart_item['variation_id'], $this->exclude_product_ids ) || in_array( $cart_item['data']->get_parent(), $this->exclude_product_ids ) ) {
|
||||
$valid_for_cart = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
throw new Exception( self::E_WC_COUPON_EXCLUDED_PRODUCTS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude categories from cart
|
||||
*/
|
||||
private function validate_cart_excluded_product_categories() {
|
||||
if ( sizeof( $this->exclude_product_categories ) > 0 ) {
|
||||
$valid_for_cart = true;
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
|
||||
$product_cats = wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) );
|
||||
|
||||
if ( sizeof( array_intersect( $product_cats, $this->exclude_product_categories ) ) > 0 ) {
|
||||
$valid_for_cart = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
throw new Exception( self::E_WC_COUPON_EXCLUDED_CATEGORIES );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude sale items from cart
|
||||
*/
|
||||
private function validate_cart_excluded_sale_items() {
|
||||
if ( $this->exclude_sale_items == 'yes' ) {
|
||||
$valid_for_cart = true;
|
||||
$product_ids_on_sale = wc_get_product_ids_on_sale();
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
if ( in_array( $cart_item['product_id'], $product_ids_on_sale, true ) || in_array( $cart_item['variation_id'], $product_ids_on_sale, true ) || in_array( $cart_item['data']->get_parent(), $product_ids_on_sale, true ) ) {
|
||||
$valid_for_cart = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
throw new Exception( self::E_WC_COUPON_NOT_VALID_SALE_ITEMS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a coupon is valid.
|
||||
*
|
||||
* @access public
|
||||
* @return boolean validity or a WP_Error if not valid
|
||||
* @return boolean validity
|
||||
*/
|
||||
public function is_valid() {
|
||||
try {
|
||||
$this->validate_exists();
|
||||
$this->validate_usage_limit();
|
||||
$this->validate_user_usage_limit();
|
||||
$this->validate_expiry_date();
|
||||
$this->validate_minimum_amount();
|
||||
$this->validate_maximum_amount();
|
||||
$this->validate_product_ids();
|
||||
$this->validate_product_categories();
|
||||
$this->validate_sale_items();
|
||||
$this->validate_cart_excluded_items();
|
||||
|
||||
$error_code = null;
|
||||
$valid = true;
|
||||
$error = false;
|
||||
|
||||
if ( $this->id ) {
|
||||
|
||||
// Usage Limit
|
||||
if ( $this->usage_limit > 0 ) {
|
||||
if ( $this->usage_count >= $this->usage_limit ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_USAGE_LIMIT_REACHED;
|
||||
}
|
||||
if ( ! apply_filters( 'woocommerce_coupon_is_valid', true, $this ) ) {
|
||||
throw new Exception( self::E_WC_COUPON_INVALID_FILTERED );
|
||||
}
|
||||
|
||||
// Per user usage limit - check here if user is logged in (against user IDs)
|
||||
// Checked again for emails later on in WC_Cart::check_customer_coupons()
|
||||
if ( $this->usage_limit_per_user > 0 && is_user_logged_in() ) {
|
||||
$used_by = (array) get_post_meta( $this->id, '_used_by' );
|
||||
$usage_count = sizeof( array_keys( $used_by, get_current_user_id() ) );
|
||||
|
||||
if ( $usage_count >= $this->usage_limit_per_user ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_USAGE_LIMIT_REACHED;
|
||||
}
|
||||
}
|
||||
|
||||
// Expired
|
||||
if ( $this->expiry_date ) {
|
||||
if ( current_time( 'timestamp' ) > $this->expiry_date ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_EXPIRED;
|
||||
}
|
||||
}
|
||||
|
||||
// Minimum spend
|
||||
if ( $this->minimum_amount > 0 ) {
|
||||
if ( $this->minimum_amount > WC()->cart->subtotal ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET;
|
||||
}
|
||||
}
|
||||
|
||||
// Maximum spend
|
||||
if ( $this->maximum_amount > 0 ) {
|
||||
if ( $this->maximum_amount < WC()->cart->subtotal ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_MAX_SPEND_LIMIT_MET;
|
||||
}
|
||||
}
|
||||
|
||||
// Product ids - If a product included is found in the cart then its valid
|
||||
if ( sizeof( $this->product_ids ) > 0 ) {
|
||||
$valid_for_cart = false;
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
|
||||
if ( in_array( $cart_item['product_id'], $this->product_ids ) || in_array( $cart_item['variation_id'], $this->product_ids ) || in_array( $cart_item['data']->get_parent(), $this->product_ids ) )
|
||||
$valid_for_cart = true;
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_NOT_APPLICABLE;
|
||||
}
|
||||
}
|
||||
|
||||
// Category ids - If a product included is found in the cart then its valid
|
||||
if ( sizeof( $this->product_categories ) > 0 ) {
|
||||
$valid_for_cart = false;
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
|
||||
$product_cats = wp_get_post_terms($cart_item['product_id'], 'product_cat', array("fields" => "ids"));
|
||||
|
||||
if ( sizeof( array_intersect( $product_cats, $this->product_categories ) ) > 0 )
|
||||
$valid_for_cart = true;
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_NOT_APPLICABLE;
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude Sale Items check for product coupons - valid if a non-sale item is present
|
||||
if ( 'yes' === $this->exclude_sale_items && in_array( $this->type, array( 'fixed_product', 'percent_product' ) ) ) {
|
||||
$valid_for_cart = false;
|
||||
$product_ids_on_sale = wc_get_product_ids_on_sale();
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
if ( sizeof( array_intersect( array( absint( $cart_item['product_id'] ), absint( $cart_item['variation_id'] ), $cart_item['data']->get_parent() ), $product_ids_on_sale ) ) === 0 ) {
|
||||
// not on sale
|
||||
$valid_for_cart = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_NOT_VALID_SALE_ITEMS;
|
||||
}
|
||||
}
|
||||
|
||||
// Cart discounts cannot be added if non-eligble product is found in cart
|
||||
if ( $this->type != 'fixed_product' && $this->type != 'percent_product' ) {
|
||||
|
||||
// Exclude Products
|
||||
if ( sizeof( $this->exclude_product_ids ) > 0 ) {
|
||||
$valid_for_cart = true;
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
if ( in_array( $cart_item['product_id'], $this->exclude_product_ids ) || in_array( $cart_item['variation_id'], $this->exclude_product_ids ) || in_array( $cart_item['data']->get_parent(), $this->exclude_product_ids ) ) {
|
||||
$valid_for_cart = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_EXCLUDED_PRODUCTS;
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude Sale Items
|
||||
if ( $this->exclude_sale_items == 'yes' ) {
|
||||
$valid_for_cart = true;
|
||||
$product_ids_on_sale = wc_get_product_ids_on_sale();
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
if ( in_array( $cart_item['product_id'], $product_ids_on_sale, true ) || in_array( $cart_item['variation_id'], $product_ids_on_sale, true ) || in_array( $cart_item['data']->get_parent(), $product_ids_on_sale, true ) ) {
|
||||
$valid_for_cart = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_NOT_VALID_SALE_ITEMS;
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude Categories
|
||||
if ( sizeof( $this->exclude_product_categories ) > 0 ) {
|
||||
$valid_for_cart = true;
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
|
||||
$product_cats = wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) );
|
||||
|
||||
if ( sizeof( array_intersect( $product_cats, $this->exclude_product_categories ) ) > 0 ) {
|
||||
$valid_for_cart = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $valid_for_cart ) {
|
||||
$valid = false;
|
||||
$error_code = self::E_WC_COUPON_EXCLUDED_CATEGORIES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$valid = apply_filters( 'woocommerce_coupon_is_valid', $valid, $this );
|
||||
|
||||
if ( $valid ) {
|
||||
return true;
|
||||
} else {
|
||||
if ( is_null( $error_code ) )
|
||||
$error_code = self::E_WC_COUPON_INVALID_FILTERED;
|
||||
}
|
||||
|
||||
} else {
|
||||
$error_code = self::E_WC_COUPON_NOT_EXIST;
|
||||
} catch ( Exception $e ) {
|
||||
$this->error_message = $this->get_coupon_error( $e->getMessage() );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $error_code )
|
||||
$this->error_message = $this->get_coupon_error( $error_code );
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -467,8 +502,7 @@ class WC_Coupon {
|
|||
* @return bool
|
||||
*/
|
||||
public function is_valid_for_cart() {
|
||||
$valid = $this->type != 'fixed_cart' && $this->type != 'percent' ? false : true;
|
||||
return apply_filters( 'woocommerce_coupon_is_valid_for_cart', $valid, $this );
|
||||
return apply_filters( 'woocommerce_coupon_is_valid_for_cart', $this->is_type( array( 'fixed_cart', 'percent' ) ), $this );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -478,8 +512,9 @@ class WC_Coupon {
|
|||
* @return boolean
|
||||
*/
|
||||
public function is_valid_for_product( $product, $values = array() ) {
|
||||
if ( $this->type != 'fixed_product' && $this->type != 'percent_product' )
|
||||
if ( ! $this->is_type( array( 'fixed_product', 'percent_product' ) ) ) {
|
||||
return apply_filters( 'woocommerce_coupon_is_valid_for_product', false, $product, $this, $values );
|
||||
}
|
||||
|
||||
$valid = false;
|
||||
$product_cats = wp_get_post_terms( $product->id, 'product_cat', array( "fields" => "ids" ) );
|
||||
|
@ -487,14 +522,16 @@ class WC_Coupon {
|
|||
// Specific products get the discount
|
||||
if ( sizeof( $this->product_ids ) > 0 ) {
|
||||
|
||||
if ( in_array( $product->id, $this->product_ids ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $this->product_ids ) ) || in_array( $product->get_parent(), $this->product_ids ) )
|
||||
if ( in_array( $product->id, $this->product_ids ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $this->product_ids ) ) || in_array( $product->get_parent(), $this->product_ids ) ) {
|
||||
$valid = true;
|
||||
}
|
||||
|
||||
// Category discounts
|
||||
} elseif ( sizeof( $this->product_categories ) > 0 ) {
|
||||
|
||||
if ( sizeof( array_intersect( $product_cats, $this->product_categories ) ) > 0 )
|
||||
if ( sizeof( array_intersect( $product_cats, $this->product_categories ) ) > 0 ) {
|
||||
$valid = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
// No product ids - all items discounted
|
||||
|
@ -502,21 +539,26 @@ class WC_Coupon {
|
|||
}
|
||||
|
||||
// Specific product ID's excluded from the discount
|
||||
if ( sizeof( $this->exclude_product_ids ) > 0 )
|
||||
if ( in_array( $product->id, $this->exclude_product_ids ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $this->exclude_product_ids ) ) || in_array( $product->get_parent(), $this->exclude_product_ids ) )
|
||||
if ( sizeof( $this->exclude_product_ids ) > 0 ) {
|
||||
if ( in_array( $product->id, $this->exclude_product_ids ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $this->exclude_product_ids ) ) || in_array( $product->get_parent(), $this->exclude_product_ids ) ) {
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Specific categories excluded from the discount
|
||||
if ( sizeof( $this->exclude_product_categories ) > 0 )
|
||||
if ( sizeof( array_intersect( $product_cats, $this->exclude_product_categories ) ) > 0 )
|
||||
if ( sizeof( $this->exclude_product_categories ) > 0 ) {
|
||||
if ( sizeof( array_intersect( $product_cats, $this->exclude_product_categories ) ) > 0 ) {
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Sale Items excluded from discount
|
||||
if ( $this->exclude_sale_items == 'yes' ) {
|
||||
$product_ids_on_sale = wc_get_product_ids_on_sale();
|
||||
|
||||
if ( in_array( $product->id, $product_ids_on_sale, true ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $product_ids_on_sale, true ) ) || in_array( $product->get_parent(), $product_ids_on_sale, true ) )
|
||||
if ( in_array( $product->id, $product_ids_on_sale, true ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $product_ids_on_sale, true ) ) || in_array( $product->get_parent(), $product_ids_on_sale, true ) ) {
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_coupon_is_valid_for_product', $valid, $product, $this, $values );
|
||||
|
@ -533,9 +575,9 @@ class WC_Coupon {
|
|||
public function get_discount_amount( $discounting_amount, $cart_item = null, $single = false ) {
|
||||
$discount = 0;
|
||||
|
||||
if ( $this->type == 'fixed_product') {
|
||||
if ( $this->is_type( 'fixed_product' ) ) {
|
||||
|
||||
$discount = $discounting_amount < $this->amount ? $discounting_amount : $this->amount;
|
||||
$discount = $discounting_amount < $this->coupon_amount ? $discounting_amount : $this->coupon_amount;
|
||||
|
||||
// If dealing with a line and not a single item, we need to multiple fixed discount by cart item qty.
|
||||
if ( ! $single && ! is_null( $cart_item ) ) {
|
||||
|
@ -543,11 +585,11 @@ class WC_Coupon {
|
|||
$discount = $discount * $cart_item['quantity'];
|
||||
}
|
||||
|
||||
} elseif ( $this->type == 'percent_product' || $this->type == 'percent' ) {
|
||||
} elseif ( $this->is_type( array( 'percent_product', 'percent' ) ) ) {
|
||||
|
||||
$discount = round( ( $discounting_amount / 100 ) * $this->amount, WC()->cart->dp );
|
||||
$discount = round( ( $discounting_amount / 100 ) * $this->coupon_amount, WC()->cart->dp );
|
||||
|
||||
} elseif ( $this->type == 'fixed_cart' ) {
|
||||
} elseif ( $this->is_type( 'fixed_cart' ) ) {
|
||||
if ( ! is_null( $cart_item ) ) {
|
||||
/**
|
||||
* This is the most complex discount - we need to divide the discount between rows based on their price in
|
||||
|
@ -562,15 +604,18 @@ class WC_Coupon {
|
|||
$discount_percent = ( $cart_item['data']->get_price_excluding_tax() * $cart_item['quantity'] ) / WC()->cart->subtotal_ex_tax;
|
||||
}
|
||||
|
||||
$discount = min( ( $this->amount * $discount_percent ) / $cart_item['quantity'], $discounting_amount );
|
||||
$discount = min( ( $this->coupon_amount * $discount_percent ) / $cart_item['quantity'], $discounting_amount );
|
||||
} else {
|
||||
$discount = min( $this->amount, $discounting_amount );
|
||||
$discount = min( $this->coupon_amount, $discounting_amount );
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the limit_usage_to_x_items option
|
||||
if ( in_array( $this->type, array( 'percent_product', 'fixed_product' ) ) && ! is_null( $cart_item ) ) {
|
||||
$qty = empty( $this->limit_usage_to_x_items ) ? $cart_item['quantity'] : min( $this->limit_usage_to_x_items, $cart_item['quantity'] );
|
||||
if ( $this->is_type( array( 'percent_product', 'fixed_product' ) ) && ! is_null( $cart_item ) ) {
|
||||
$qty = '' === $this->limit_usage_to_x_items ? $cart_item['quantity'] : min( $this->limit_usage_to_x_items, $cart_item['quantity'] );
|
||||
|
||||
// Reduce limits
|
||||
$this->limit_usage_to_x_items = max( 0, $this->limit_usage_to_x_items - $qty );
|
||||
|
||||
if ( $single ) {
|
||||
$discount = ( $discount * $qty ) / $cart_item['quantity'];
|
||||
|
@ -586,27 +631,24 @@ class WC_Coupon {
|
|||
* Converts one of the WC_Coupon message/error codes to a message string and
|
||||
* displays the message/error.
|
||||
*
|
||||
* @access public
|
||||
* @param int $msg_code Message/error code.
|
||||
* @return void
|
||||
*/
|
||||
public function add_coupon_message( $msg_code ) {
|
||||
|
||||
if ( $msg_code < 200 )
|
||||
if ( $msg_code < 200 ) {
|
||||
wc_add_notice( $this->get_coupon_error( $msg_code ), 'error' );
|
||||
else
|
||||
} else {
|
||||
wc_add_notice( $this->get_coupon_message( $msg_code ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map one of the WC_Coupon message codes to a message string
|
||||
*
|
||||
* @access public
|
||||
* @param integer $msg_code
|
||||
* @return string| Message/error string
|
||||
*/
|
||||
public function get_coupon_message( $msg_code ) {
|
||||
|
||||
switch ( $msg_code ) {
|
||||
case self::WC_COUPON_SUCCESS :
|
||||
$msg = __( 'Coupon code applied successfully.', 'woocommerce' );
|
||||
|
@ -618,19 +660,16 @@ class WC_Coupon {
|
|||
$msg = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_coupon_message', $msg, $msg_code, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Map one of the WC_Coupon error codes to a message string
|
||||
*
|
||||
* @access public
|
||||
* @param int $err_code Message/error code.
|
||||
* @return string| Message/error string
|
||||
*/
|
||||
public function get_coupon_error( $err_code ) {
|
||||
|
||||
switch ( $err_code ) {
|
||||
case self::E_WC_COUPON_INVALID_FILTERED:
|
||||
$err = __( 'Coupon is not valid.', 'woocommerce' );
|
||||
|
@ -666,7 +705,6 @@ class WC_Coupon {
|
|||
$err = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' );
|
||||
break;
|
||||
case self::E_WC_COUPON_EXCLUDED_PRODUCTS:
|
||||
|
||||
// Store excluded products that are in cart in $products
|
||||
$products = array();
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
|
@ -680,7 +718,6 @@ class WC_Coupon {
|
|||
$err = sprintf( __( 'Sorry, this coupon is not applicable to the products: %s.', 'woocommerce' ), implode( ', ', $products ) );
|
||||
break;
|
||||
case self::E_WC_COUPON_EXCLUDED_CATEGORIES:
|
||||
|
||||
// Store excluded categories that are in cart in $categories
|
||||
$categories = array();
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
|
@ -709,7 +746,6 @@ class WC_Coupon {
|
|||
$err = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_coupon_error', $err, $err_code, $this );
|
||||
}
|
||||
|
||||
|
@ -718,12 +754,10 @@ class WC_Coupon {
|
|||
* No coupon instance will be available where a coupon does not exist,
|
||||
* so this static method exists.
|
||||
*
|
||||
* @access public
|
||||
* @param int $err_code Error code
|
||||
* @return string| Error string
|
||||
*/
|
||||
public static function get_generic_coupon_error( $err_code ) {
|
||||
|
||||
switch ( $err_code ) {
|
||||
case self::E_WC_COUPON_NOT_EXIST:
|
||||
$err = __( 'Coupon does not exist!', 'woocommerce' );
|
||||
|
@ -735,9 +769,7 @@ class WC_Coupon {
|
|||
$err = '';
|
||||
break;
|
||||
}
|
||||
|
||||
// When using this static method, there is no $this to pass to filter
|
||||
return apply_filters( 'woocommerce_coupon_error', $err, $err_code, null );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
|
|||
= 2.3.0 =
|
||||
* Feature - Made tax importer expand postcode ranges.
|
||||
* Feature - Print styles for reports.
|
||||
* Feature - Remove products from the cart in the widget.
|
||||
* Refactor - Removed deprecated methods from WC_Frontend_Scripts and rewrote script registration and localization to run once.
|
||||
* Refactor - Routing all email functionality through one send() method.
|
||||
* Refactor - Replaced existing email css inliner with Emogrifier.
|
||||
|
|
Loading…
Reference in New Issue