Completed
Pull Request — master (#11889)
by Mike
12:12
created

WC_Cart_Coupons::check_customer_limits()   C

Complexity

Conditions 7
Paths 14

Size

Total Lines 33
Code Lines 22

Duplication

Lines 8
Ratio 24.24 %

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 14
nop 1
dl 8
loc 33
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
if ( ! defined( 'ABSPATH' ) ) {
4
	exit; // Exit if accessed directly
5
}
6
7
/**
8
 * Cart Coupons.
9
 *
10
 * @class 		WC_Cart_Coupons
11
 * @version		2.7.0
12
 * @package		WooCommerce/Classes
13
 * @category	Class
14
 * @author 		WooThemes
15
 */
16
class WC_Cart_Coupons {
17
18
	/**
19
	 * An array of coupon objects.
20
	 * @var object[]
21
	 */
22
	private $coupons = array();
23
24
	/**
25
	 * Constructor.
26
	 */
27
	public function __construct() {
28
		add_action( 'woocommerce_check_cart_items', array( $this, 'check_coupons' ), 1 );
29
		add_action( 'woocommerce_after_checkout_validation', array( $this, 'check_customer_restriction' ), 1 );
30
		add_action( 'woocommerce_after_checkout_validation', array( $this, 'check_customer_limits' ), 1 );
31
		add_action( 'woocommerce_applied_coupon', array( $this, 'applied_coupon' ), 10, 2 );
32
	}
33
34
	/**
35
	 * Get coupons.
36
	 * @return array
37
	 */
38
	public function get_coupons() {
39
		return $this->coupons;
40
	}
41
42
	/**
43
	 * Set coupons.
44
	 * @param array $set
45
	 */
46
	public function set_coupons( $set ) {
47
		$set           = array_filter( (array) $set );
48
		$this->coupons = array();
49
50
		foreach ( $set as $code => $coupon ) {
51
			if ( is_object( $coupon ) ) {
52
				$this->coupons[ $code ] = $coupon;
53
			} else {
54
				$this->coupons[ $coupon ] = new WC_Coupon( $coupon );
55
			}
56
		}
57
	}
58
59
	/**
60
	 * Remove a single coupon by code.
61
	 * @param  string $coupon_code Code of the coupon to remove
62
	 */
63
	public function remove_coupon( $coupon_code ) {
64
		$coupon_code = wc_format_coupon_code( $coupon_code );
65
		unset( $this->coupons[ $coupon_code ] );
66
		do_action( 'woocommerce_removed_coupon', $coupon_code );
67
	}
68
69
	/**
70
	 * Check cart coupons for errors.
71
	 */
72
	public function check_coupons() {
73
		foreach ( $this->coupons as $code => $coupon ) {
74 View Code Duplication
			if ( ! $coupon->is_valid() ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
				$coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_INVALID_REMOVED );
76
				$this->remove_coupon( $code );
77
				WC()->session->set( 'refresh_totals', true );
78
			}
79
		}
80
	}
81
82
	/**
83
	 * Check for user coupons (now that we have billing email). If a coupon is invalid, add an error.
84
	 * @param array $posted
85
	 */
86
	public function check_customer_restriction( $posted ) {
87
		foreach ( $this->coupons as $code => $coupon ) {
88
			if ( sizeof( $coupon->get_email_restrictions() ) > 0 ) {
89
				$check_emails = array(
90
					$posted['billing_email']
91
				);
92
				if ( is_user_logged_in() ) {
93
					$current_user   = wp_get_current_user();
94
					$check_emails[] = $current_user->user_email;
95
				}
96
				$check_emails = array_map( 'sanitize_email', array_map( 'strtolower', $check_emails ) );
97
98
				if ( 0 == sizeof( array_intersect( $check_emails, $coupon->get_email_restrictions() ) ) ) {
99
					$coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_NOT_YOURS_REMOVED );
100
					$this->remove_coupon( $code );
101
					WC()->session->set( 'refresh_totals', true );
102
				}
103
			}
104
		}
105
	}
106
107
	/**
108
	 * Check for user coupons (now that we have billing email). If a coupon is invalid, add an error.
109
	 * @param array $posted
110
	 */
111
	public function check_customer_limits( $posted ) {
112
		foreach ( $this->coupons as $code => $coupon ) {
113
			// Usage limits per user - check against billing and user email and user ID
114
			if ( $coupon->get_usage_limit_per_user() > 0 ) {
115
				$check_emails = array();
116
				$used_by      = $coupon->get_used_by();
117
118
				if ( is_user_logged_in() ) {
119
					$current_user   = wp_get_current_user();
120
					$check_emails[] = sanitize_email( $current_user->user_email );
121
					$usage_count    = sizeof( array_keys( $used_by, get_current_user_id() ) );
122
				} else {
123
					$check_emails[] = sanitize_email( $posted['billing_email'] );
124
					$user           = get_user_by( 'email', $posted['billing_email'] );
125
					if ( $user ) {
126
						$usage_count = sizeof( array_keys( $used_by, $user->ID ) );
127
					} else {
128
						$usage_count = 0;
129
					}
130
				}
131
132
				foreach ( $check_emails as $check_email ) {
133
					$usage_count = $usage_count + sizeof( array_keys( $used_by, $check_email ) );
134
				}
135
136 View Code Duplication
				if ( $usage_count >= $coupon->get_usage_limit_per_user() ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
137
					$coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_USAGE_LIMIT_REACHED );
138
					$this->remove_coupon( $code );
139
					WC()->session->set( 'refresh_totals', true );
140
				}
141
			}
142
		}
143
	}
144
145
	/**
146
	 * Add a message for the applied coupon.
147
	 * @param  string $code
148
	 * @param  WC_Coupon $coupon
149
	 */
150
	public function applied_coupon( $code, $coupon ) {
151
		$coupon->add_coupon_message( WC_Coupon::WC_COUPON_SUCCESS );
152
		if ( $coupon->get_free_shipping() ) {
153
			WC()->session->set( 'chosen_shipping_methods', null );
154
		}
155
	}
156
}
157