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

WC_Legacy_Coupon   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 228
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 228
rs 8.439
c 0
b 0
f 0
wmc 47
lcom 0
cbo 3

7 Methods

Rating   Name   Duplication   Size   Complexity  
C __get() 0 77 26
A format_array() 0 11 3
A apply_before_tax() 0 4 1
A enable_free_shipping() 0 4 1
A exclude_sale_items() 0 4 1
B __isset() 0 28 2
C get_discount_amount() 0 52 13

How to fix   Complexity   

Complex Class

Complex classes like WC_Legacy_Coupon often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WC_Legacy_Coupon, and based on these observations, apply Extract Interface, too.

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
/**
7
 * Legacy Coupon.
8
 *
9
 * Legacy and deprecated functions are here to keep the WC_Legacy_Coupon class clean.
10
 * This class will be removed in future versions.
11
 *
12
 * @class       WC_Legacy_Coupon
13
 * @version     2.7.0
14
 * @package     WooCommerce/Classes
15
 * @category    Class
16
 * @author      WooThemes
17
 */
18
abstract class WC_Legacy_Coupon extends WC_Data {
19
20
	/**
21
	 * Magic __isset method for backwards compatibility. Legacy properties which could be accessed directly in the past.
22
	 * @param  string $key
23
	 * @return bool
24
	 */
25
	public function __isset( $key ) {
26
		$legacy_keys = array(
27
			'id',
28
			'exists',
29
			'coupon_custom_fields',
30
			'type',
31
			'discount_type',
32
			'amount',
33
			'code',
34
			'individual_use',
35
			'product_ids',
36
			'exclude_product_ids',
37
			'usage_limit',
38
			'usage_limit_per_user',
39
			'limit_usage_to_x_items',
40
			'usage_count',
41
			'expiry_date',
42
			'product_categories',
43
			'exclude_product_categories',
44
			'minimum_amount',
45
			'maximum_amount',
46
			'customer_email',
47
		);
48
		if ( in_array( $key, $legacy_keys ) ) {
49
			return true;
50
		}
51
		return false;
52
	}
53
54
	/**
55
	 * Magic __get method for backwards compatibility. Maps legacy vars to new getters.
56
	 * @param  string $key
57
	 * @return mixed
58
	 */
59
	public function __get( $key ) {
60
		_doing_it_wrong( $key, 'Coupon properties should not be accessed directly.', '2.7' );
61
62
		switch ( $key ) {
63
			case 'id' :
64
				$value = $this->get_id();
65
			break;
66
			case 'exists' :
67
				$value = ( $this->get_id() > 0 ) ? true : false;
68
			break;
69
			case 'coupon_custom_fields' :
70
				$legacy_custom_fields = array();
71
				$custom_fields = $this->get_id() ? $this->get_meta_data() : array();
72
				if ( ! empty( $custom_fields ) ) {
73
					foreach ( $custom_fields as  $cf_value ) {
74
						// legacy only supports 1 key
75
						$legacy_custom_fields[ $cf_value->key ][0] = $cf_value->value;
76
					}
77
				}
78
				$value = $legacy_custom_fields;
79
			break;
80
			case 'type' :
81
			case 'discount_type' :
82
				$value = $this->get_discount_type();
83
			break;
84
			case 'amount' :
85
				$value = $this->get_amount();
86
			break;
87
			case 'code' :
88
				$value = $this->get_code();
89
			break;
90
			case 'individual_use' :
91
				$value = ( true === $this->get_individual_use() ) ? 'yes' : 'no';
92
			break;
93
			case 'product_ids' :
94
				$value = $this->get_product_ids();
95
			break;
96
			case 'exclude_product_ids' :
97
				$value = $this->get_excluded_product_ids();
98
			break;
99
			case 'usage_limit' :
100
				$value = $this->get_usage_limit();
101
			break;
102
			case 'usage_limit_per_user' :
103
				$value = $this->get_usage_limit_per_user();
104
			break;
105
			case 'limit_usage_to_x_items' :
106
				$value = $this->get_limit_usage_to_x_items();
107
			break;
108
			case 'usage_count' :
109
				$value = $this->get_usage_count();
110
			break;
111
			case 'expiry_date' :
112
				$value = $this->get_date_expires();
113
			break;
114
			case 'product_categories' :
115
				$value = $this->get_product_categories();
116
			break;
117
			case 'exclude_product_categories' :
118
				$value = $this->get_excluded_product_categories();
119
			break;
120
			case 'minimum_amount' :
121
				$value = $this->get_minimum_amount();
122
			break;
123
			case 'maximum_amount' :
124
				$value = $this->get_maximum_amount();
125
			break;
126
			case 'customer_email' :
127
				$value = $this->get_email_restrictions();
128
			break;
129
			default :
130
				$value = '';
131
			break;
132
		}
133
134
		return $value;
135
	}
136
137
	/**
138
	 * Format loaded data as array.
139
	 * @param  string|array $array
140
	 * @return array
141
	 */
142
	public function format_array( $array ) {
143
		_deprecated_function( 'format_array', '2.7', '' );
144
		if ( ! is_array( $array ) ) {
145
			if ( is_serialized( $array ) ) {
146
				$array = maybe_unserialize( $array );
147
			} else {
148
				$array = explode( ',', $array );
149
			}
150
		}
151
		return array_filter( array_map( 'trim', array_map( 'strtolower', $array ) ) );
152
	}
153
154
155
	/**
156
	 * Check if coupon needs applying before tax.
157
	 *
158
	 * @return bool
159
	 */
160
	public function apply_before_tax() {
161
		_deprecated_function( 'apply_before_tax', '2.7', '' );
162
		return true;
163
	}
164
165
	/**
166
	 * Check if a coupon enables free shipping.
167
	 *
168
	 * @return bool
169
	 */
170
	public function enable_free_shipping() {
171
		_deprecated_function( 'enable_free_shipping', '2.7', 'get_free_shipping' );
172
		return $this->get_free_shipping();
173
	}
174
175
	/**
176
	 * Check if a coupon excludes sale items.
177
	 *
178
	 * @return bool
179
	 */
180
	public function exclude_sale_items() {
181
		_deprecated_function( 'exclude_sale_items', '2.7', 'get_exclude_sale_items' );
182
		return $this->get_exclude_sale_items();
0 ignored issues
show
Bug introduced by
The method get_exclude_sale_items() does not exist on WC_Legacy_Coupon. Did you maybe mean exclude_sale_items()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
183
	}
184
185
	/**
186
	 * Get discount amount for a cart item.
187
	 *
188
	 * @param  float $discounting_amount Amount the coupon is being applied to
189
	 * @param  array|null $cart_item Cart item being discounted if applicable
190
	 * @param  boolean $single True if discounting a single qty item, false if its the line
191
	 * @return float Amount this coupon has discounted
192
	 */
193
	public function get_discount_amount( $discounting_amount, $cart_item = null, $single = false ) {
194
		_deprecated_function( 'get_discount_amount', '2.7', 'WC_Cart_Totals::get_discounted_price' );
195
		$discount      = 0;
196
		$cart_item_qty = is_null( $cart_item ) ? 1 : $cart_item['quantity'];
197
198
		if ( $this->is_type( array( 'percent_product', 'percent' ) ) ) {
199
			$discount = $this->get_amount() * ( $discounting_amount / 100 );
200
		} elseif ( $this->is_type( 'fixed_cart' ) && ! is_null( $cart_item ) && WC()->cart->get_subtotal() ) {
201
			/**
202
			 * This is the most complex discount - we need to divide the discount between rows based on their price in.
203
			 * proportion to the subtotal. This is so rows with different tax rates get a fair discount, and so rows.
204
			 * with no price (free) don't get discounted.
205
			 *
206
			 * Get item discount by dividing item cost by subtotal to get a %.
207
			 *
208
			 * Uses price inc tax if prices include tax to work around https://github.com/woothemes/woocommerce/issues/7669 and https://github.com/woothemes/woocommerce/issues/8074.
209
			 */
210
			if ( wc_prices_include_tax() ) {
211
				$discount_percent = ( $cart_item['data']->get_price_including_tax() * $cart_item_qty ) / WC()->cart->get_subtotal();
212
			} else {
213
				$discount_percent = ( $cart_item['data']->get_price_excluding_tax() * $cart_item_qty ) / WC()->cart->get_subtotal( false );
214
			}
215
			$discount = ( $this->get_amount() * $discount_percent ) / $cart_item_qty;
216
217
		} elseif ( $this->is_type( 'fixed_product' ) ) {
218
			$discount = min( $this->get_amount(), $discounting_amount );
219
			$discount = $single ? $discount : $discount * $cart_item_qty;
220
		}
221
222
		$discount = min( $discount, $discounting_amount );
223
224
		// Handle the limit_usage_to_x_items option
225
		if ( $this->is_type( array( 'percent_product', 'fixed_product' ) ) ) {
226
			if ( $discounting_amount ) {
227
				if ( '' === $this->get_limit_usage_to_x_items() ) {
228
					$limit_usage_qty = $cart_item_qty;
229
				} else {
230
					$limit_usage_qty = min( $this->get_limit_usage_to_x_items(), $cart_item_qty );
231
					$this->set_limit_usage_to_x_items( max( 0, $this->get_limit_usage_to_x_items() - $limit_usage_qty ) );
232
				}
233
				if ( $single ) {
234
					$discount = ( $discount * $limit_usage_qty ) / $cart_item_qty;
235
				} else {
236
					$discount = ( $discount / $cart_item_qty ) * $limit_usage_qty;
237
				}
238
			}
239
		}
240
241
		$discount = round( $discount, wc_get_rounding_precision() );
242
243
		return apply_filters( 'woocommerce_coupon_get_discount_amount', $discount, $discounting_amount, $cart_item, $single, $this );
244
	}
245
}
246