1 <?php
2 3 4 5 6 7 8 9 10 11
12
13 if ( ! defined( 'ABSPATH' ) ) exit;
14
15 16 17
18 class WC_Meta_Box_Coupon_Data {
19
20 21 22
23 public static function output( $post ) {
24 wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
25 ?>
26 <style type="text/css">
27
28 </style>
29 <div id="coupon_options" class="panel-wrap coupon_data">
30
31 <div class="wc-tabs-back"></div>
32
33 <ul class="coupon_data_tabs wc-tabs" style="display:none;">
34 <?php
35 $coupon_data_tabs = apply_filters( 'woocommerce_coupon_data_tabs', array(
36 'general' => array(
37 'label' => __( 'General', 'woocommerce' ),
38 'target' => 'general_coupon_data',
39 'class' => 'general_coupon_data',
40 ),
41 'usage_restriction' => array(
42 'label' => __( 'Usage Restriction', 'woocommerce' ),
43 'target' => 'usage_restriction_coupon_data',
44 'class' => '',
45 ),
46 'usage_limit' => array(
47 'label' => __( 'Usage Limits', 'woocommerce' ),
48 'target' => 'usage_limit_coupon_data',
49 'class' => '',
50 )
51 ) );
52
53 foreach ( $coupon_data_tabs as $key => $tab ) {
54 ?><li class="<?php echo $key; ?>_options <?php echo $key; ?>_tab <?php echo implode( ' ' , (array) $tab['class'] ); ?>">
55 <a href="#<?php echo $tab['target']; ?>"><?php echo esc_html( $tab['label'] ); ?></a>
56 </li><?php
57 }
58 ?>
59 </ul>
60 <div id="general_coupon_data" class="panel woocommerce_options_panel"><?php
61
62
63 woocommerce_wp_select( array( 'id' => 'discount_type', 'label' => __( 'Discount type', 'woocommerce' ), 'options' => wc_get_coupon_types() ) );
64
65
66 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 ) );
67
68
69 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 with the "must use coupon" setting.', 'woocommerce' ), admin_url('admin.php?page=wc-settings&tab=shipping§ion=WC_Shipping_Free_Shipping')) ) );
70
71
72 woocommerce_wp_checkbox( array( 'id' => 'apply_before_tax', 'label' => __( 'Apply before tax', 'woocommerce' ), 'description' => __( 'Check this box if the coupon should be applied before calculating cart tax.', 'woocommerce' ) ) );
73
74
75 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])" ) ) );
76
77 do_action( 'woocommerce_coupon_options' );
78
79 ?></div>
80 <div id="usage_restriction_coupon_data" class="panel woocommerce_options_panel"><?php
81
82 echo '<div class="options_group">';
83
84
85 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 subtotal needed to use the coupon.', 'woocommerce' ), 'data_type' => 'price', 'desc_tip' => true ) );
86
87
88 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' ) ) );
89
90
91 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' ) ) );
92
93 echo '</div><div class="options_group">';
94
95
96 ?>
97 <p class="form-field"><label for="product_ids"><?php _e( 'Products', 'woocommerce' ); ?></label>
98 <select id="product_ids" name="product_ids[]" class="ajax_chosen_select_products_and_variations" multiple="multiple" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>">
99 <?php
100 $product_ids = get_post_meta( $post->ID, 'product_ids', true );
101 if ( $product_ids ) {
102 $product_ids = array_map( 'absint', explode( ',', $product_ids ) );
103 foreach ( $product_ids as $product_id ) {
104
105 $product = get_product( $product_id );
106
107 echo '<option value="' . esc_attr( $product_id ) . '" selected="selected">' . wp_kses_post( $product->get_formatted_name() ) . '</option>';
108 }
109 }
110 ?>
111 </select> <img class="help_tip" data-tip='<?php _e( 'Products which need to be in the cart to use this coupon or, for "Product Discounts", which products are discounted.', 'woocommerce' ); ?>' src="<?php echo WC()->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></p>
112 <?php
113
114
115 ?>
116 <p class="form-field"><label for="exclude_product_ids"><?php _e( 'Exclude products', 'woocommerce' ); ?></label>
117 <select id="exclude_product_ids" name="exclude_product_ids[]" class="ajax_chosen_select_products_and_variations" multiple="multiple" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>">
118 <?php
119 $product_ids = get_post_meta( $post->ID, 'exclude_product_ids', true );
120 if ( $product_ids ) {
121 $product_ids = array_map( 'absint', explode( ',', $product_ids ) );
122 foreach ( $product_ids as $product_id ) {
123
124 $product = get_product( $product_id );
125
126 echo '<option value="' . esc_attr( $product_id ) . '" selected="selected">' . wp_kses_post( $product->get_formatted_name() ) . '</option>';
127 }
128 }
129 ?>
130 </select> <img class="help_tip" data-tip='<?php _e( 'Products which must not be in the cart to use this coupon or, for "Product Discounts", which products are not discounted.', 'woocommerce' ); ?>' src="<?php echo WC()->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></p>
131 <?php
132
133 echo '</div><div class="options_group">';
134
135
136 ?>
137 <p class="form-field"><label for="product_ids"><?php _e( 'Product categories', 'woocommerce' ); ?></label>
138 <select id="product_categories" name="product_categories[]" class="chosen_select" multiple="multiple" data-placeholder="<?php _e( 'Any category', 'woocommerce' ); ?>">
139 <?php
140 $category_ids = (array) get_post_meta( $post->ID, 'product_categories', true );
141
142 $categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
143 if ( $categories ) foreach ( $categories as $cat ) {
144 echo '<option value="' . esc_attr( $cat->term_id ) . '"' . selected( in_array( $cat->term_id, $category_ids ), true, false ) . '>' . esc_html( $cat->name ) . '</option>';
145 }
146 ?>
147 </select> <img class="help_tip" data-tip='<?php _e( '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' ); ?>' src="<?php echo WC()->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></p>
148 <?php
149
150
151 ?>
152 <p class="form-field"><label for="exclude_product_categories"><?php _e( 'Exclude categories', 'woocommerce' ); ?></label>
153 <select id="exclude_product_categories" name="exclude_product_categories[]" class="chosen_select" multiple="multiple" data-placeholder="<?php _e( 'No categories', 'woocommerce' ); ?>">
154 <?php
155 $category_ids = (array) get_post_meta( $post->ID, 'exclude_product_categories', true );
156
157 $categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
158 if ( $categories ) foreach ( $categories as $cat ) {
159 echo '<option value="' . esc_attr( $cat->term_id ) . '"' . selected( in_array( $cat->term_id, $category_ids ), true, false ) . '>' . esc_html( $cat->name ) . '</option>';
160 }
161 ?>
162 </select> <img class="help_tip" data-tip='<?php _e( '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' ) ?>' src="<?php echo WC()->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></p>
163 <?php
164
165 echo '</div><div class="options_group">';
166
167
168 woocommerce_wp_text_input( array( 'id' => 'customer_email', 'label' => __( 'Email restrictions', 'woocommerce' ), 'placeholder' => __( 'No restrictions', 'woocommerce' ), 'description' => __( 'List of 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(
169 'multiple' => 'multiple'
170 ) ) );
171
172 echo '</div>';
173
174 do_action( 'woocommerce_coupon_options_usage_restriction' );
175
176 ?></div>
177 <div id="usage_limit_coupon_data" class="panel woocommerce_options_panel"><?php
178
179 echo '<div class="options_group">';
180
181
182 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(
183 'step' => '1',
184 'min' => '0'
185 ) ) );
186
187
188 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(
189 'step' => '1',
190 'min' => '0'
191 ) ) );
192
193
194 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(
195 'step' => '1',
196 'min' => '0'
197 ) ) );
198
199 echo '</div>';
200
201 do_action( 'woocommerce_coupon_options_usage_limit' );
202
203 ?></div>
204 <?php do_action( 'woocommerce_coupon_data_panels' ); ?>
205 <div class="clear"></div>
206 </div>
207 <?php
208 }
209
210 211 212
213 public static function save( $post_id, $post ) {
214 global $wpdb;
215
216
217 $post->post_title = apply_filters( 'woocommerce_coupon_code', $post->post_title );
218 $wpdb->update( $wpdb->posts, array( 'post_title' => $post->post_title ), array( 'ID' => $post_id ) );
219
220
221 $coupon_found = $wpdb->get_var( $wpdb->prepare( "
222 SELECT $wpdb->posts.ID
223 FROM $wpdb->posts
224 WHERE $wpdb->posts.post_type = 'shop_coupon'
225 AND $wpdb->posts.post_status = 'publish'
226 AND $wpdb->posts.post_title = '%s'
227 AND $wpdb->posts.ID != %s
228 ", $post->post_title, $post_id ) );
229
230 if ( $coupon_found ) {
231 WC_Admin_Meta_Boxes::add_error( __( 'Coupon code already exists - customers will use the latest coupon with this code.', 'woocommerce' ) );
232 }
233
234
235 $type = wc_clean( $_POST['discount_type'] );
236 $amount = wc_format_decimal( $_POST['coupon_amount'] );
237 $usage_limit = empty( $_POST['usage_limit'] ) ? '' : absint( $_POST['usage_limit'] );
238 $usage_limit_per_user = empty( $_POST['usage_limit_per_user'] ) ? '' : absint( $_POST['usage_limit_per_user'] );
239 $limit_usage_to_x_items = empty( $_POST['limit_usage_to_x_items'] ) ? '' : absint( $_POST['limit_usage_to_x_items'] );
240 $individual_use = isset( $_POST['individual_use'] ) ? 'yes' : 'no';
241 $expiry_date = wc_clean( $_POST['expiry_date'] );
242 $apply_before_tax = isset( $_POST['apply_before_tax'] ) ? 'yes' : 'no';
243 $free_shipping = isset( $_POST['free_shipping'] ) ? 'yes' : 'no';
244 $exclude_sale_items = isset( $_POST['exclude_sale_items'] ) ? 'yes' : 'no';
245 $minimum_amount = wc_format_decimal( $_POST['minimum_amount'] );
246 $customer_email = array_filter( array_map( 'trim', explode( ',', wc_clean( $_POST['customer_email'] ) ) ) );
247
248 if ( isset( $_POST['product_ids'] ) ) {
249 $product_ids = implode( ',', array_filter( array_map( 'intval', (array) $_POST['product_ids'] ) ) );
250 } else {
251 $product_ids = '';
252 }
253
254 if ( isset( $_POST['exclude_product_ids'] ) ) {
255 $exclude_product_ids = implode( ',', array_filter( array_map( 'intval', (array) $_POST['exclude_product_ids'] ) ) );
256 } else {
257 $exclude_product_ids = '';
258 }
259
260 $product_categories = isset( $_POST['product_categories'] ) ? array_map( 'intval', $_POST['product_categories'] ) : array();
261 $exclude_product_categories = isset( $_POST['exclude_product_categories'] ) ? array_map( 'intval', $_POST['exclude_product_categories'] ) : array();
262
263
264 update_post_meta( $post_id, 'discount_type', $type );
265 update_post_meta( $post_id, 'coupon_amount', $amount );
266 update_post_meta( $post_id, 'individual_use', $individual_use );
267 update_post_meta( $post_id, 'product_ids', $product_ids );
268 update_post_meta( $post_id, 'exclude_product_ids', $exclude_product_ids );
269 update_post_meta( $post_id, 'usage_limit', $usage_limit );
270 update_post_meta( $post_id, 'usage_limit_per_user', $usage_limit_per_user );
271 update_post_meta( $post_id, 'limit_usage_to_x_items', $limit_usage_to_x_items );
272 update_post_meta( $post_id, 'expiry_date', $expiry_date );
273 update_post_meta( $post_id, 'apply_before_tax', $apply_before_tax );
274 update_post_meta( $post_id, 'free_shipping', $free_shipping );
275 update_post_meta( $post_id, 'exclude_sale_items', $exclude_sale_items );
276 update_post_meta( $post_id, 'product_categories', $product_categories );
277 update_post_meta( $post_id, 'exclude_product_categories', $exclude_product_categories );
278 update_post_meta( $post_id, 'minimum_amount', $minimum_amount );
279 update_post_meta( $post_id, 'customer_email', $customer_email );
280
281 do_action( 'woocommerce_coupon_options_save', $post_id );
282 }
283 }
284