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' ) ) exit; // Exit if accessed directly
 14 
 15 /**
 16  * WC_Meta_Box_Coupon_Data
 17  */
 18 class WC_Meta_Box_Coupon_Data {
 19 
 20     /**
 21      * Output the metabox
 22      */
 23     public static function output( $post ) {
 24         wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
 25         ?>
 26         <style type="text/css">
 27             #edit-slug-box, #minor-publishing-actions { display:none }
 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                 // Type
 63                 woocommerce_wp_select( array( 'id' => 'discount_type', 'label' => __( 'Discount type', 'woocommerce' ), 'options' => wc_get_coupon_types() ) );
 64 
 65                 // Amount
 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                 // Free Shipping
 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&section=WC_Shipping_Free_Shipping')) ) );
 70 
 71                 // Apply before tax
 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                 // Expiry date
 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                 // minimum spend
 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                 // Individual use
 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                 // Exclude Sale Products
 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                 // Product ids
 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&hellip;', '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                 // Exclude Product ids
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                 // Categories
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                 // Exclude Categories
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                 // Customers
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                 // Usage limit per coupons
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                 // Usage limit per product
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                 // Usage limit per users
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      * Save meta box data
212      */
213     public static function save( $post_id, $post ) {
214         global $wpdb;
215 
216         // Ensure coupon code is correctly formatted
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         // Check for dupe coupons
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         // Add/Replace data to array
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         // Save
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 
WooCommerce API documentation generated by ApiGen 2.8.0