WC_Meta_Box_Coupon_Data::output()   D
last analyzed

Complexity

Conditions 10
Paths 72

Size

Total Lines 184
Code Lines 108

Duplication

Lines 23
Ratio 12.5 %

Importance

Changes 0
Metric Value
cc 10
eloc 108
nc 72
nop 1
dl 23
loc 184
rs 4.8196
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Coupon Data
4
 *
5
 * Display the coupon data meta box.
6
 *
7
 * @author      WooThemes
8
 * @category    Admin
9
 * @package     WooCommerce/Admin/Meta Boxes
10
 * @version     2.1.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit; // Exit if accessed directly
15
}
16
17
/**
18
 * WC_Meta_Box_Coupon_Data Class.
19
 */
20
class WC_Meta_Box_Coupon_Data {
21
22
	/**
23
	 * Output the metabox.
24
	 *
25
	 * @param WP_Post $post
26
	 */
27
	public static function output( $post ) {
28
		wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
29
		?>
30
		<style type="text/css">
31
			#edit-slug-box, #minor-publishing-actions { display:none }
32
		</style>
33
		<div id="coupon_options" class="panel-wrap coupon_data">
34
35
			<div class="wc-tabs-back"></div>
36
37
			<ul class="coupon_data_tabs wc-tabs" style="display:none;">
38
				<?php
39
					$coupon_data_tabs = apply_filters( 'woocommerce_coupon_data_tabs', array(
40
						'general' => array(
41
							'label'  => __( 'General', 'woocommerce' ),
42
							'target' => 'general_coupon_data',
43
							'class'  => 'general_coupon_data',
44
						),
45
						'usage_restriction' => array(
46
							'label'  => __( 'Usage Restriction', 'woocommerce' ),
47
							'target' => 'usage_restriction_coupon_data',
48
							'class'  => '',
49
						),
50
						'usage_limit' => array(
51
							'label'  => __( 'Usage Limits', 'woocommerce' ),
52
							'target' => 'usage_limit_coupon_data',
53
							'class'  => '',
54
						)
55
					) );
56
57 View Code Duplication
					foreach ( $coupon_data_tabs as $key => $tab ) {
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...
58
						?><li class="<?php echo $key; ?>_options <?php echo $key; ?>_tab <?php echo implode( ' ' , (array) $tab['class'] ); ?>">
59
							<a href="#<?php echo $tab['target']; ?>"><?php echo esc_html( $tab['label'] ); ?></a>
60
						</li><?php
61
					}
62
				?>
63
			</ul>
64
			<div id="general_coupon_data" class="panel woocommerce_options_panel"><?php
65
66
				// Type
67
				woocommerce_wp_select( array( 'id' => 'discount_type', 'label' => __( 'Discount type', 'woocommerce' ), 'options' => wc_get_coupon_types() ) );
68
69
				// Amount
70
				woocommerce_wp_text_input( array( 'id' => 'coupon_amount', 'label' => __( 'Coupon amount', 'woocommerce' ), 'placeholder' => wc_format_localized_price( 0 ), 'description' => __( 'Value of the coupon.', 'woocommerce' ), 'data_type' => 'price', 'desc_tip' => true ) );
71
72
				// Free Shipping
73
				woocommerce_wp_checkbox( array( 'id' => 'free_shipping', 'label' => __( 'Allow free shipping', 'woocommerce' ), 'description' => sprintf( __( 'Check this box if the coupon grants free shipping. The <a href="%s">free shipping method</a> must be enabled and be set to require "a valid free shipping coupon" (see the "Free Shipping Requires" setting).', 'woocommerce' ), admin_url('admin.php?page=wc-settings&tab=shipping&section=WC_Shipping_Free_Shipping')) ) );
74
75
				// Expiry date
76
				woocommerce_wp_text_input( array( 'id' => 'expiry_date', 'label' => __( 'Coupon expiry date', 'woocommerce' ), 'placeholder' => _x( 'YYYY-MM-DD', 'placeholder', 'woocommerce' ), 'description' => '', 'class' => 'date-picker', 'custom_attributes' => array( 'pattern' => "[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" ) ) );
77
78
				do_action( 'woocommerce_coupon_options' );
79
80
			?></div>
81
			<div id="usage_restriction_coupon_data" class="panel woocommerce_options_panel"><?php
82
83
				echo '<div class="options_group">';
84
85
				// minimum spend
86
				woocommerce_wp_text_input( array( 'id' => 'minimum_amount', 'label' => __( 'Minimum spend', 'woocommerce' ), 'placeholder' => __( 'No minimum', 'woocommerce' ), 'description' => __( 'This field allows you to set the minimum spend (subtotal, including taxes) allowed to use the coupon.', 'woocommerce' ), 'data_type' => 'price', 'desc_tip' => true ) );
87
88
				// maximum spend
89
				woocommerce_wp_text_input( array( 'id' => 'maximum_amount', 'label' => __( 'Maximum spend', 'woocommerce' ), 'placeholder' => __( 'No maximum', 'woocommerce' ), 'description' => __( 'This field allows you to set the maximum spend (subtotal, including taxes) allowed when using the coupon.', 'woocommerce' ), 'data_type' => 'price', 'desc_tip' => true ) );
90
91
				// Individual use
92
				woocommerce_wp_checkbox( array( 'id' => 'individual_use', 'label' => __( 'Individual use only', 'woocommerce' ), 'description' => __( 'Check this box if the coupon cannot be used in conjunction with other coupons.', 'woocommerce' ) ) );
93
94
				// Exclude Sale Products
95
				woocommerce_wp_checkbox( array( 'id' => 'exclude_sale_items', 'label' => __( 'Exclude sale items', 'woocommerce' ), 'description' => __( 'Check this box if the coupon should not apply to items on sale. Per-item coupons will only work if the item is not on sale. Per-cart coupons will only work if there are no sale items in the cart.', 'woocommerce' ) ) );
96
97
				echo '</div><div class="options_group">';
98
99
				// Product ids
100
				?>
101
				<p class="form-field"><label><?php _e( 'Products', 'woocommerce' ); ?></label>
102
				<input type="hidden" class="wc-product-search" data-multiple="true" style="width: 50%;" name="product_ids" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-selected="<?php
103
					$product_ids = array_filter( array_map( 'absint', explode( ',', get_post_meta( $post->ID, 'product_ids', true ) ) ) );
104
					$json_ids    = array();
105
106 View Code Duplication
					foreach ( $product_ids as $product_id ) {
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...
107
						$product = wc_get_product( $product_id );
108
						if ( is_object( $product ) ) {
109
							$json_ids[ $product_id ] = wp_kses_post( $product->get_formatted_name() );
110
						}
111
					}
112
113
					echo esc_attr( json_encode( $json_ids ) );
114
					?>" value="<?php echo implode( ',', array_keys( $json_ids ) ); ?>" /> <?php echo wc_help_tip( __( 'Products which need to be in the cart to use this coupon or, for "Product Discounts", which products are discounted.', 'woocommerce' ) ); ?></p>
115
				<?php
116
117
				// Exclude Product ids
118
				?>
119
				<p class="form-field"><label><?php _e( 'Exclude products', 'woocommerce' ); ?></label>
120
				<input type="hidden" class="wc-product-search" data-multiple="true" style="width: 50%;" name="exclude_product_ids" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-selected="<?php
121
					$product_ids = array_filter( array_map( 'absint', explode( ',', get_post_meta( $post->ID, 'exclude_product_ids', true ) ) ) );
122
					$json_ids    = array();
123
124 View Code Duplication
					foreach ( $product_ids as $product_id ) {
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...
125
						$product = wc_get_product( $product_id );
126
						if ( is_object( $product ) ) {
127
							$json_ids[ $product_id ] = wp_kses_post( $product->get_formatted_name() );
128
						}
129
					}
130
131
					echo esc_attr( json_encode( $json_ids ) );
132
				?>" value="<?php echo implode( ',', array_keys( $json_ids ) ); ?>" /> <?php echo wc_help_tip( __( 'Products which must not be in the cart to use this coupon or, for "Product Discounts", which products are not discounted.', 'woocommerce' ) ); ?></p>
133
				<?php
134
135
				echo '</div><div class="options_group">';
136
137
				// Categories
138
				?>
139
				<p class="form-field"><label for="product_categories"><?php _e( 'Product categories', 'woocommerce' ); ?></label>
140
				<select id="product_categories" name="product_categories[]" style="width: 50%;"  class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'Any category', 'woocommerce' ); ?>">
141
					<?php
142
						$category_ids = (array) get_post_meta( $post->ID, 'product_categories', true );
143
						$categories   = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
144
145 View Code Duplication
						if ( $categories ) foreach ( $categories as $cat ) {
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...
146
							echo '<option value="' . esc_attr( $cat->term_id ) . '"' . selected( in_array( $cat->term_id, $category_ids ), true, false ) . '>' . esc_html( $cat->name ) . '</option>';
147
						}
148
					?>
149
				</select> <?php echo wc_help_tip( __( 'A product must be in this category for the coupon to remain valid or, for "Product Discounts", products in these categories will be discounted.', 'woocommerce' ) ); ?></p>
150
				<?php
151
152
				// Exclude Categories
153
				?>
154
				<p class="form-field"><label for="exclude_product_categories"><?php _e( 'Exclude categories', 'woocommerce' ); ?></label>
155
				<select id="exclude_product_categories" name="exclude_product_categories[]" style="width: 50%;"  class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No categories', 'woocommerce' ); ?>">
156
					<?php
157
						$category_ids = (array) get_post_meta( $post->ID, 'exclude_product_categories', true );
158
						$categories   = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
159
160 View Code Duplication
						if ( $categories ) foreach ( $categories as $cat ) {
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...
161
							echo '<option value="' . esc_attr( $cat->term_id ) . '"' . selected( in_array( $cat->term_id, $category_ids ), true, false ) . '>' . esc_html( $cat->name ) . '</option>';
162
						}
163
					?>
164
				</select> <?php echo wc_help_tip( __( 'Product must not be in this category for the coupon to remain valid or, for "Product Discounts", products in these categories will not be discounted.', 'woocommerce' ) ); ?></p>
165
				<?php
166
167
				echo '</div><div class="options_group">';
168
169
				// Customers
170
				woocommerce_wp_text_input( array( 'id' => 'customer_email', 'label' => __( 'Email restrictions', 'woocommerce' ), 'placeholder' => __( 'No restrictions', 'woocommerce' ), 'description' => __( 'List of allowed emails to check against the customer\'s billing email when an order is placed. Separate email addresses with commas.', 'woocommerce' ), 'value' => implode(', ', (array) get_post_meta( $post->ID, 'customer_email', true ) ), 'desc_tip' => true, 'type' => 'email', 'class' => '', 'custom_attributes' => array(
171
						'multiple' 	=> 'multiple'
172
				) ) );
173
174
				echo '</div>';
175
176
				do_action( 'woocommerce_coupon_options_usage_restriction' );
177
178
			?></div>
179
			<div id="usage_limit_coupon_data" class="panel woocommerce_options_panel"><?php
180
181
				echo '<div class="options_group">';
182
183
				// Usage limit per coupons
184
				woocommerce_wp_text_input( array( 'id' => 'usage_limit', 'label' => __( 'Usage limit per coupon', 'woocommerce' ), 'placeholder' => _x('Unlimited usage', 'placeholder', 'woocommerce'), 'description' => __( 'How many times this coupon can be used before it is void.', 'woocommerce' ), 'type' => 'number', 'desc_tip' => true, 'class' => 'short', 'custom_attributes' => array(
185
						'step' 	=> '1',
186
						'min'	=> '0'
187
				) ) );
188
189
				// Usage limit per product
190
				woocommerce_wp_text_input( array( 'id' => 'limit_usage_to_x_items', 'label' => __( 'Limit usage to X items', 'woocommerce' ), 'placeholder' => _x( 'Apply to all qualifying items in cart', 'placeholder', 'woocommerce' ), 'description' => __( 'The maximum number of individual items this coupon can apply to when using product discounts. Leave blank to apply to all qualifying items in cart.', 'woocommerce' ), 'desc_tip' => true, 'class' => 'short', 'type' => 'number', 'custom_attributes' => array(
191
						'step' 	=> '1',
192
						'min'	=> '0'
193
				) ) );
194
195
				// Usage limit per users
196
				woocommerce_wp_text_input( array( 'id' => 'usage_limit_per_user', 'label' => __( 'Usage limit per user', 'woocommerce' ), 'placeholder' => _x( 'Unlimited usage', 'placeholder', 'woocommerce' ), 'description' => __( 'How many times this coupon can be used by an invidual user. Uses billing email for guests, and user ID for logged in users.', 'woocommerce' ), 'desc_tip' => true, 'class' => 'short', 'type' => 'number', 'custom_attributes' => array(
197
						'step' 	=> '1',
198
						'min'	=> '0'
199
				) ) );
200
201
				echo '</div>';
202
203
				do_action( 'woocommerce_coupon_options_usage_limit' );
204
205
			?></div>
206
			<?php do_action( 'woocommerce_coupon_data_panels' ); ?>
207
			<div class="clear"></div>
208
		</div>
209
		<?php
210
	}
211
212
	/**
213
	 * Save meta box data.
214
	 *
215
	 * @param int $post_id
216
	 * @param WP_Post $post
217
	 */
218
	public static function save( $post_id, $post ) {
219
		global $wpdb;
220
221
		// Ensure coupon code is correctly formatted
222
		$post->post_title = apply_filters( 'woocommerce_coupon_code', $post->post_title );
223
		$wpdb->update( $wpdb->posts, array( 'post_title' => $post->post_title ), array( 'ID' => $post_id ) );
224
225
		// Check for dupe coupons
226
		$coupon_found = $wpdb->get_var( $wpdb->prepare( "
227
			SELECT $wpdb->posts.ID
228
			FROM $wpdb->posts
229
			WHERE $wpdb->posts.post_type = 'shop_coupon'
230
			AND $wpdb->posts.post_status = 'publish'
231
			AND $wpdb->posts.post_title = '%s'
232
			AND $wpdb->posts.ID != %s
233
		 ", $post->post_title, $post_id ) );
234
235
		if ( $coupon_found ) {
236
			WC_Admin_Meta_Boxes::add_error( __( 'Coupon code already exists - customers will use the latest coupon with this code.', 'woocommerce' ) );
237
		}
238
239
		// Add/Replace data to array
240
		$type                   = wc_clean( $_POST['discount_type'] );
241
		$amount                 = wc_format_decimal( $_POST['coupon_amount'] );
242
		$usage_limit            = empty( $_POST['usage_limit'] ) ? '' : absint( $_POST['usage_limit'] );
243
		$usage_limit_per_user   = empty( $_POST['usage_limit_per_user'] ) ? '' : absint( $_POST['usage_limit_per_user'] );
244
		$limit_usage_to_x_items = empty( $_POST['limit_usage_to_x_items'] ) ? '' : absint( $_POST['limit_usage_to_x_items'] );
245
		$individual_use         = isset( $_POST['individual_use'] ) ? 'yes' : 'no';
246
		$expiry_date            = wc_clean( $_POST['expiry_date'] );
247
		$free_shipping          = isset( $_POST['free_shipping'] ) ? 'yes' : 'no';
248
		$exclude_sale_items     = isset( $_POST['exclude_sale_items'] ) ? 'yes' : 'no';
249
		$minimum_amount         = wc_format_decimal( $_POST['minimum_amount'] );
250
		$maximum_amount         = wc_format_decimal( $_POST['maximum_amount'] );
251
		$customer_email         = array_filter( array_map( 'trim', explode( ',', wc_clean( $_POST['customer_email'] ) ) ) );
252
		$product_ids            = implode( ',', array_filter( array_map( 'intval', explode( ',', $_POST['product_ids'] ) ) ) );
253
		$exclude_product_ids    = implode( ',', array_filter( array_map( 'intval', explode( ',', $_POST['exclude_product_ids'] ) ) ) );
254
255
		$product_categories         = isset( $_POST['product_categories'] ) ? array_map( 'intval', $_POST['product_categories'] ) : array();
256
		$exclude_product_categories = isset( $_POST['exclude_product_categories'] ) ? array_map( 'intval', $_POST['exclude_product_categories'] ) : array();
257
258
		// Save
259
		update_post_meta( $post_id, 'discount_type', $type );
260
		update_post_meta( $post_id, 'coupon_amount', $amount );
261
		update_post_meta( $post_id, 'individual_use', $individual_use );
262
		update_post_meta( $post_id, 'product_ids', $product_ids );
263
		update_post_meta( $post_id, 'exclude_product_ids', $exclude_product_ids );
264
		update_post_meta( $post_id, 'usage_limit', $usage_limit );
265
		update_post_meta( $post_id, 'usage_limit_per_user', $usage_limit_per_user );
266
		update_post_meta( $post_id, 'limit_usage_to_x_items', $limit_usage_to_x_items );
267
		update_post_meta( $post_id, 'expiry_date', $expiry_date );
268
		update_post_meta( $post_id, 'free_shipping', $free_shipping );
269
		update_post_meta( $post_id, 'exclude_sale_items', $exclude_sale_items );
270
		update_post_meta( $post_id, 'product_categories', $product_categories );
271
		update_post_meta( $post_id, 'exclude_product_categories', $exclude_product_categories );
272
		update_post_meta( $post_id, 'minimum_amount', $minimum_amount );
273
		update_post_meta( $post_id, 'maximum_amount', $maximum_amount );
274
		update_post_meta( $post_id, 'customer_email', $customer_email );
275
276
		// Clear cache
277
		WC_Cache_Helper::incr_cache_prefix( 'coupons' );
278
279
		do_action( 'woocommerce_coupon_options_save', $post_id );
280
	}
281
}
282