Merge pull request #8940 from woothemes/issues/8482
Tidy up how we're dealing with coupon postmeta around `_used_by` which can get big.
This commit is contained in:
commit
3e55364e3a
|
@ -1615,7 +1615,7 @@ class WC_Cart {
|
|||
// Usage limits per user - check against billing and user email and user ID
|
||||
if ( $coupon->usage_limit_per_user > 0 ) {
|
||||
$check_emails = array();
|
||||
$used_by = array_filter( (array) get_post_meta( $coupon->id, '_used_by' ) );
|
||||
$used_by = $coupon->get_used_by();
|
||||
|
||||
if ( is_user_logged_in() ) {
|
||||
$current_user = wp_get_current_user();
|
||||
|
|
|
@ -172,10 +172,19 @@ class WC_Coupon {
|
|||
'customer_email' => array()
|
||||
);
|
||||
|
||||
if ( ! empty( $this->id ) ) {
|
||||
$postmeta = get_post_meta( $this->id );
|
||||
}
|
||||
|
||||
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 );
|
||||
if ( ! empty( $this->id ) ) {
|
||||
/**
|
||||
* By not calling `get_post_meta()` individually, we may be breaking compatibility with
|
||||
* some plugins that filter on `get_post_metadata` and erroneously override based solely
|
||||
* on $meta_key -- but don't override when querying for all as $meta_key is empty().
|
||||
*/
|
||||
$this->$key = isset( $postmeta[ $key ] ) ? maybe_unserialize( array_shift( $postmeta[ $key ] ) ) : '';
|
||||
} else {
|
||||
$this->$key = ! empty( $data[ $key ] ) ? wc_clean( $data[ $key ] ) : '';
|
||||
|
||||
|
@ -271,14 +280,31 @@ class WC_Coupon {
|
|||
$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 );
|
||||
if ( $used_by ) {
|
||||
/**
|
||||
* We're doing this the long way because `delete_post_meta( $id, $key, $value )` deletes
|
||||
* all instances where the key and value match, and we only want to delete one.
|
||||
*/
|
||||
$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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get records of all users who have used the current coupon.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function get_used_by() {
|
||||
$_used_by = (array) get_post_meta( $this->id, '_used_by' );
|
||||
// Strip out any null values.
|
||||
return array_filter( $_used_by );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error_message string
|
||||
*
|
||||
|
@ -312,11 +338,20 @@ class WC_Coupon {
|
|||
*
|
||||
* 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()
|
||||
*
|
||||
* @param int $user_id
|
||||
*/
|
||||
private function validate_user_usage_limit() {
|
||||
private function validate_user_usage_limit( $user_id = null ) {
|
||||
if ( ! $user_id ) {
|
||||
$user_id = get_current_user_id();
|
||||
}
|
||||
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() ) );
|
||||
global $wpdb;
|
||||
$wpdb->get_var( $wpdb->prepare( "SELECT COUNT( `meta_id` )
|
||||
FROM {$wpdb->postmeta}
|
||||
WHERE `post_id` = %d
|
||||
AND `meta_key` = '_used_by'
|
||||
AND `meta_value` = %d", $this->id, $user_id ) );
|
||||
|
||||
if ( $usage_count >= $this->usage_limit_per_user ) {
|
||||
throw new Exception( self::E_WC_COUPON_USAGE_LIMIT_REACHED );
|
||||
|
|
Loading…
Reference in New Issue