Merge pull request #11785 from woothemes/coupon-exceptions

Coupon Exceptions and REST/CRUD improvements
This commit is contained in:
Mike Jolley 2016-08-30 11:44:19 +01:00 committed by GitHub
commit 499e190efb
12 changed files with 735 additions and 825 deletions

View File

@ -26,6 +26,8 @@ class WC_Meta_Box_Coupon_Data {
*/
public static function output( $post ) {
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
$coupon = new WC_Coupon( $post->ID );
?>
<style type="text/css">
#edit-slug-box, #minor-publishing-actions { display:none }
@ -73,7 +75,7 @@ class WC_Meta_Box_Coupon_Data {
woocommerce_wp_checkbox( array( 'id' => 'free_shipping', 'label' => __( 'Allow free shipping', 'woocommerce' ), 'description' => sprintf( __( 'Check this box if the coupon grants free shipping. A <a href="%s">free shipping method</a> must be enabled in your shipping zone and be set to require "a valid free shipping coupon" (see the "Free Shipping Requires" setting).', 'woocommerce' ), 'https://docs.woocommerce.com/document/free-shipping/' ) ) );
// Expiry date
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])" ) ) );
woocommerce_wp_text_input( array( 'id' => 'expiry_date', 'value' => date( 'Y-m-d', $coupon->get_date_expires() ), '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])" ) ) );
do_action( 'woocommerce_coupon_options' );
@ -100,7 +102,7 @@ class WC_Meta_Box_Coupon_Data {
?>
<p class="form-field"><label><?php _e( 'Products', 'woocommerce' ); ?></label>
<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
$product_ids = array_filter( array_map( 'absint', explode( ',', get_post_meta( $post->ID, 'product_ids', true ) ) ) );
$product_ids = $coupon->get_product_ids();
$json_ids = array();
foreach ( $product_ids as $product_id ) {
@ -118,7 +120,7 @@ class WC_Meta_Box_Coupon_Data {
?>
<p class="form-field"><label><?php _e( 'Exclude products', 'woocommerce' ); ?></label>
<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
$product_ids = array_filter( array_map( 'absint', explode( ',', get_post_meta( $post->ID, 'exclude_product_ids', true ) ) ) );
$product_ids = $coupon->get_excluded_product_ids();
$json_ids = array();
foreach ( $product_ids as $product_id ) {
@ -139,7 +141,7 @@ class WC_Meta_Box_Coupon_Data {
<p class="form-field"><label for="product_categories"><?php _e( 'Product categories', 'woocommerce' ); ?></label>
<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' ); ?>">
<?php
$category_ids = (array) get_post_meta( $post->ID, 'product_categories', true );
$category_ids = $coupon->get_product_categories();
$categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
if ( $categories ) foreach ( $categories as $cat ) {
@ -154,7 +156,7 @@ class WC_Meta_Box_Coupon_Data {
<p class="form-field"><label for="exclude_product_categories"><?php _e( 'Exclude categories', 'woocommerce' ); ?></label>
<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' ); ?>">
<?php
$category_ids = (array) get_post_meta( $post->ID, 'exclude_product_categories', true );
$category_ids = $coupon->get_excluded_product_categories();
$categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
if ( $categories ) foreach ( $categories as $cat ) {
@ -181,22 +183,58 @@ class WC_Meta_Box_Coupon_Data {
echo '<div class="options_group">';
// Usage limit per coupons
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(
'step' => '1',
'min' => '0'
) ) );
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(
'step' => 1,
'min' => 0,
),
'value' => $coupon->get_usage_limit() ? $coupon->get_usage_limit() : '',
)
);
// Usage limit per product
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(
'step' => '1',
'min' => '0'
) ) );
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(
'step' => 1,
'min' => 0,
),
'value' => $coupon->get_limit_usage_to_x_items() ? $coupon->get_limit_usage_to_x_items() : '',
)
);
// Usage limit per users
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(
'step' => '1',
'min' => '0'
) ) );
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(
'step' => 1,
'min' => 0,
),
'value' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : '',
)
);
echo '</div>';
@ -218,64 +256,35 @@ class WC_Meta_Box_Coupon_Data {
public static function save( $post_id, $post ) {
global $wpdb;
// Ensure coupon code is correctly formatted
$post->post_title = apply_filters( 'woocommerce_coupon_code', $post->post_title );
$wpdb->update( $wpdb->posts, array( 'post_title' => $post->post_title ), array( 'ID' => $post_id ) );
// Check for dupe coupons
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_type = 'shop_coupon'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_title = '%s'
AND $wpdb->posts.ID != %s
", $post->post_title, $post_id ) );
$coupon_code = apply_filters( 'woocommerce_coupon_code', $post->post_title );
$id_from_code = wc_get_coupon_id_by_code( $coupon_code, $post_id );
if ( $coupon_found ) {
if ( $id_from_code ) {
WC_Admin_Meta_Boxes::add_error( __( 'Coupon code already exists - customers will use the latest coupon with this code.', 'woocommerce' ) );
}
// Add/Replace data to array
$type = wc_clean( $_POST['discount_type'] );
$amount = wc_format_decimal( $_POST['coupon_amount'] );
$usage_limit = empty( $_POST['usage_limit'] ) ? '' : absint( $_POST['usage_limit'] );
$usage_limit_per_user = empty( $_POST['usage_limit_per_user'] ) ? '' : absint( $_POST['usage_limit_per_user'] );
$limit_usage_to_x_items = empty( $_POST['limit_usage_to_x_items'] ) ? '' : absint( $_POST['limit_usage_to_x_items'] );
$individual_use = isset( $_POST['individual_use'] ) ? 'yes' : 'no';
$expiry_date = wc_clean( $_POST['expiry_date'] );
$free_shipping = isset( $_POST['free_shipping'] ) ? 'yes' : 'no';
$exclude_sale_items = isset( $_POST['exclude_sale_items'] ) ? 'yes' : 'no';
$minimum_amount = wc_format_decimal( $_POST['minimum_amount'] );
$maximum_amount = wc_format_decimal( $_POST['maximum_amount'] );
$customer_email = array_filter( array_map( 'trim', explode( ',', wc_clean( $_POST['customer_email'] ) ) ) );
$product_ids = implode( ',', array_filter( array_map( 'intval', explode( ',', $_POST['product_ids'] ) ) ) );
$exclude_product_ids = implode( ',', array_filter( array_map( 'intval', explode( ',', $_POST['exclude_product_ids'] ) ) ) );
$product_categories = isset( $_POST['product_categories'] ) ? array_map( 'intval', $_POST['product_categories'] ) : array();
$exclude_product_categories = isset( $_POST['exclude_product_categories'] ) ? array_map( 'intval', $_POST['exclude_product_categories'] ) : array();
// Save
update_post_meta( $post_id, 'discount_type', $type );
update_post_meta( $post_id, 'coupon_amount', $amount );
update_post_meta( $post_id, 'individual_use', $individual_use );
update_post_meta( $post_id, 'product_ids', $product_ids );
update_post_meta( $post_id, 'exclude_product_ids', $exclude_product_ids );
update_post_meta( $post_id, 'usage_limit', $usage_limit );
update_post_meta( $post_id, 'usage_limit_per_user', $usage_limit_per_user );
update_post_meta( $post_id, 'limit_usage_to_x_items', $limit_usage_to_x_items );
update_post_meta( $post_id, 'expiry_date', $expiry_date );
update_post_meta( $post_id, 'free_shipping', $free_shipping );
update_post_meta( $post_id, 'exclude_sale_items', $exclude_sale_items );
update_post_meta( $post_id, 'product_categories', $product_categories );
update_post_meta( $post_id, 'exclude_product_categories', $exclude_product_categories );
update_post_meta( $post_id, 'minimum_amount', $minimum_amount );
update_post_meta( $post_id, 'maximum_amount', $maximum_amount );
update_post_meta( $post_id, 'customer_email', $customer_email );
// Clear cache
WC_Cache_Helper::incr_cache_prefix( 'coupons' );
$coupon = new WC_Coupon( $post_id );
$coupon->set_props( array(
'code' => $post->post_title,
'discount_type' => wc_clean( $_POST['discount_type'] ),
'amount' => wc_format_decimal( $_POST['coupon_amount'] ),
'date_expires' => wc_clean( $_POST['expiry_date'] ),
'individual_use' => isset( $_POST['individual_use'] ),
'product_ids' => array_filter( array_map( 'intval', explode( ',', $_POST['product_ids'] ) ) ),
'excluded_product_ids' => array_filter( array_map( 'intval', explode( ',', $_POST['exclude_product_ids'] ) ) ),
'usage_limit' => absint( $_POST['usage_limit'] ),
'usage_limit_per_user' => absint( $_POST['usage_limit_per_user'] ),
'limit_usage_to_x_items' => absint( $_POST['limit_usage_to_x_items'] ),
'free_shipping' => isset( $_POST['free_shipping'] ),
'product_categories' => array_filter( array_map( 'intval', (array) $_POST['product_categories'] ) ),
'excluded_product_categories' => array_filter( array_map( 'intval', (array) $_POST['exclude_product_categories'] ) ),
'exclude_sale_items' => isset( $_POST['exclude_sale_items'] ),
'minimum_amount' => wc_format_decimal( $_POST['minimum_amount'] ),
'maximum_amount' => wc_format_decimal( $_POST['maximum_amount'] ),
'email_restrictions' => array_filter( array_map( 'trim', explode( ',', wc_clean( $_POST['customer_email'] ) ) ) ),
) );
$coupon->save();
do_action( 'woocommerce_coupon_options_save', $post_id );
}
}

View File

@ -126,7 +126,6 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
if ( ! empty( $request['code'] ) ) {
$id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish'", $request['code'] ) );
$args['post__in'] = array( $id );
}
@ -141,44 +140,32 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
* @return WP_REST_Response $data
*/
public function prepare_item_for_response( $post, $request ) {
// Get the coupon code.
$code = wc_get_coupon_code_by_id( $post->ID );
$code = wc_get_coupon_code_by_id( $post->ID );
$coupon = new WC_Coupon( $code );
$data = $coupon->get_data();
$format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' );
$format_date = array( 'date_created', 'date_modified', 'date_expires' );
$format_null = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' );
$coupon = new WC_Coupon( $code );
// Format decimal values.
foreach ( $format_decimal as $key ) {
$data[ $key ] = wc_format_decimal( $data[ $key ], 2 );
}
$data = array(
'id' => $coupon->get_id(),
'code' => $coupon->get_code(),
'date_created' => wc_rest_prepare_date_response( $post->post_date_gmt ),
'date_modified' => wc_rest_prepare_date_response( $post->post_modified_gmt ),
'discount_type' => $coupon->get_discount_type(),
'description' => $coupon->get_description(),
'amount' => wc_format_decimal( $coupon->get_amount(), 2 ),
'expiry_date' => $coupon->get_expiry_date() ? wc_rest_prepare_date_response( $coupon->get_expiry_date() ) : null,
'usage_count' => (int) $coupon->get_usage_count(),
'individual_use' => $coupon->get_individual_use(),
'product_ids' => array_map( 'absint', (array) $coupon->get_product_ids() ),
'exclude_product_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_ids() ),
'usage_limit' => $coupon->get_usage_limit() ? $coupon->get_usage_limit() : null,
'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null,
'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),
'free_shipping' => $coupon->get_free_shipping(),
'product_categories' => array_map( 'absint', (array) $coupon->get_product_categories() ),
'excluded_product_categories' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ),
'exclude_sale_items' => $coupon->get_exclude_sale_items(),
'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ),
'maximum_amount' => wc_format_decimal( $coupon->get_maximum_amount(), 2 ),
'email_restrictions' => $coupon->get_email_restrictions(),
'used_by' => $coupon->get_used_by(),
);
// Format date values.
foreach ( $format_date as $key ) {
$data[ $key ] = $data[ $key ] ? wc_rest_prepare_date_response( get_gmt_from_date( date( 'Y-m-d H:i:s', $data[ $key ] ) ) ) : null;
}
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->add_additional_fields_to_object( $data, $request );
$data = $this->filter_response_by_context( $data, $context );
// Format null values.
foreach ( $format_null as $key ) {
$data[ $key ] = $data[ $key ] ? $data[ $key ] : null;
}
// Wrap the data in a response object.
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->add_additional_fields_to_object( $data, $request );
$data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $post ) );
/**
@ -194,6 +181,15 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request );
}
/**
* Only reutrn writeable props from schema.
* @param array $schema
* @return bool
*/
protected function filter_writable_props( $schema ) {
return empty( $schema['readonly'] );
}
/**
* Prepare a single coupon for create or update.
*
@ -203,15 +199,18 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
protected function prepare_item_for_database( $request ) {
global $wpdb;
// ID.
if ( isset( $request['id'] ) ) {
$code = wc_get_coupon_code_by_id( $request['id'] );
$coupon = new WC_Coupon( $code );
} else {
$coupon = new WC_Coupon();
}
$id = isset( $request['id'] ) ? absint( $request['id'] ) : 0;
$coupon = new WC_Coupon( $id );
$schema = $this->get_item_schema();
$data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) );
$schema = $this->get_item_schema();
// BW compat
if ( $request['exclude_product_ids'] ) {
$request['excluded_product_ids'] = $request['exclude_product_ids'];
}
if ( $request['expiry_date'] ) {
$request['date_expires'] = $request['expiry_date'];
}
// Validate required POST fields.
if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) {
@ -220,31 +219,40 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
}
}
// Code.
if ( ! empty( $schema['properties']['code'] ) && ! empty( $request['code'] ) ) {
$coupon_code = apply_filters( 'woocommerce_coupon_code', $request['code'] );
$id = $coupon->get_id() ? $coupon->get_id() : 0;
// Handle all writable props
foreach ( $data_keys as $key ) {
$value = $request[ $key ];
// Check for duplicate coupon codes.
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_type = 'shop_coupon'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_title = '%s'
AND $wpdb->posts.ID != %s
", $coupon_code, $id ) );
if ( ! is_null( $value ) ) {
switch ( $key ) {
case 'code' :
$coupon_code = apply_filters( 'woocommerce_coupon_code', $value );
$id = $coupon->get_id() ? $coupon->get_id() : 0;
$id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id );
if ( $coupon_found ) {
return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) );
if ( $id_from_code ) {
return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) );
}
$coupon->set_code( $coupon_code );
break;
case 'meta_data' :
if ( is_array( $value ) ) {
foreach ( $value as $meta ) {
$coupon->update_meta_data( $meta['key'], $meta['value'], $meta['id'] );
}
}
break;
case 'description' :
$coupon->set_description( wp_filter_post_kses( $value ) );
break;
default :
if ( is_callable( array( $coupon, "set_{$key}" ) ) ) {
$coupon->{"set_{$key}"}( $value );
}
break;
}
}
$coupon->set_code( $coupon_code );
}
// Coupon description (excerpt).
if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) {
$coupon->set_description( wp_filter_post_kses( $request['description'] ) );
}
/**
@ -253,8 +261,7 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
* The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
* prepared for insertion.
*
* @param stdClass $data An object representing a single item prepared
* for inserting or updating the database.
* @param WC_Coupon $coupon The coupon object.
* @param WP_REST_Request $request Request object.
*/
return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request );
@ -305,195 +312,51 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
* @return WP_Error|WP_REST_Response
*/
public function update_item( $request ) {
$post_id = (int) $request['id'];
try {
$post_id = (int) $request['id'];
if ( empty( $post_id ) || $this->post_type !== get_post_type( $post_id ) ) {
return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) );
if ( empty( $post_id ) || $this->post_type !== get_post_type( $post_id ) ) {
return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) );
}
$coupon_id = $this->save_coupon( $request );
if ( is_wp_error( $coupon_id ) ) {
return $coupon_id;
}
$post = get_post( $coupon_id );
$this->update_additional_fields_for_object( $post, $request );
/**
* Fires after a single item is created or updated via the REST API.
*
* @param object $post Inserted object (not a WP_Post object).
* @param WP_REST_Request $request Request object.
* @param boolean $creating True when creating item, false when updating.
*/
do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false );
$request->set_param( 'context', 'edit' );
$response = $this->prepare_item_for_response( $post, $request );
return rest_ensure_response( $response );
} catch ( Exception $e ) {
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
}
$coupon_id = $this->save_coupon( $request );
if ( is_wp_error( $coupon_id ) ) {
return $coupon_id;
}
$post = get_post( $coupon_id );
$this->update_additional_fields_for_object( $post, $request );
$this->update_post_meta_fields( $post, $request );
/**
* Fires after a single item is created or updated via the REST API.
*
* @param object $post Inserted object (not a WP_Post object).
* @param WP_REST_Request $request Request object.
* @param boolean $creating True when creating item, false when updating.
*/
do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false );
$request->set_param( 'context', 'edit' );
$response = $this->prepare_item_for_response( $post, $request );
return rest_ensure_response( $response );
}
/**
* Saves a coupon to the database.
*/
public function save_coupon( $request ) {
$coupon = $this->prepare_item_for_database( $request );
$coupon->save();
return $coupon->get_id();
}
/**
* Expiry date format.
*
* @param string $expiry_date
* @return string
*/
protected function get_coupon_expiry_date( $expiry_date ) {
if ( '' != $expiry_date ) {
return date( 'Y-m-d', strtotime( $expiry_date ) );
}
return '';
}
/**
* Add post meta fields.
*
* @param WP_Post $post
* @param WP_REST_Request $request
* @return bool|WP_Error
*/
protected function add_post_meta_fields( $post, $request ) {
$data = array_filter( $request->get_params() );
$defaults = array(
'discount_type' => 'fixed_cart',
'amount' => 0,
'individual_use' => false,
'product_ids' => array(),
'exclude_product_ids' => array(),
'usage_limit' => '',
'usage_limit_per_user' => '',
'limit_usage_to_x_items' => '',
'usage_count' => '',
'expiry_date' => '',
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '',
'maximum_amount' => '',
'email_restrictions' => array(),
'description' => ''
);
$data = wp_parse_args( $data, $defaults );
if ( ! empty( $post->post_title ) ) {
$coupon = new WC_Coupon( $post->post_title );
// Set coupon meta.
$coupon->set_discount_type( $data['discount_type'] );
$coupon->set_amount( $data['amount'] );
$coupon->set_individual_use( $data['individual_use'] );
$coupon->set_product_ids( $data['product_ids'] );
$coupon->set_excluded_product_ids( $data['exclude_product_ids'] );
$coupon->set_usage_limit( $data['usage_limit'] );
$coupon->set_usage_limit_per_user( $data['usage_limit_per_user'] );
$coupon->set_limit_usage_to_x_items( $data['limit_usage_to_x_items'] );
$coupon->set_usage_count( $data['usage_count'] );
$coupon->set_expiry_date( $data['expiry_date'] );
$coupon->set_free_shipping( $data['free_shipping'] );
$coupon->set_product_categories( $data['product_categories'] );
$coupon->set_excluded_product_categories( $data['excluded_product_categories'] );
$coupon->set_exclude_sale_items( $data['exclude_sale_items'] );
$coupon->set_minimum_amount( $data['minimum_amount'] );
$coupon->set_maximum_amount( $data['maximum_amount'] );
$coupon->set_email_restrictions( $data['email_restrictions'] );
try {
$coupon = $this->prepare_item_for_database( $request );
$coupon->save();
return $coupon->get_id();
} catch ( WC_Data_Exception $e ) {
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
} catch ( WC_REST_Exception $e ) {
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
}
return true;
}
/**
* Update post meta fields.
*
* @param WP_Post $post
* @param WP_REST_Request $request
* @return bool|WP_Error
*/
protected function update_post_meta_fields( $post, $request ) {
$coupon = new WC_Coupon( $post->post_title );
if ( isset( $request['amount'] ) ) {
$coupon->set_amount( $request['amount'] );
}
if ( isset( $request['individual_use'] ) ) {
$coupon->set_individual_use( $request['individual_use'] );
}
if ( isset( $request['product_ids'] ) ) {
$coupon->set_product_ids( $request['product_ids'] );
}
if ( isset( $request['exclude_product_ids'] ) ) {
$coupon->set_excluded_product_ids( $request['exclude_product_ids'] );
}
if ( isset( $request['usage_limit'] ) ) {
$coupon->set_usage_limit( $request['usage_limit'] );
}
if ( isset( $request['usage_limit_per_user'] ) ) {
$coupon->set_usage_limit_per_user( $request['usage_limit_per_user'] );
}
if ( isset( $request['limit_usage_to_x_items'] ) ) {
$coupon->set_limit_usage_to_x_items( $request['limit_usage_to_x_items'] );
}
if ( isset( $request['usage_count'] ) ) {
$coupon->set_usage_count( $request['usage_count'] );
}
if ( isset( $request['expiry_date'] ) ) {
$coupon->set_expiry_date( $request['expiry_date'] );
}
if ( isset( $request['free_shipping'] ) ) {
$coupon->set_free_shipping( $request['free_shipping'] );
}
if ( isset( $request['product_categories'] ) ) {
$coupon->set_product_categories( $request['product_categories'] );
}
if ( isset( $request['excluded_product_categories'] ) ) {
$coupon->set_excluded_product_categories( $request['excluded_product_categories'] );
}
if ( isset( $request['exclude_sale_items'] ) ) {
$coupon->set_exclude_sale_items( $request['exclude_sale_items'] );
}
if ( isset( $request['minimum_amount'] ) ) {
$coupon->set_minimum_amount( $request['minimum_amount'] );
}
if ( isset( $request['maximum_amount'] ) ) {
$coupon->set_maximum_amount( $request['maximum_amount'] );
}
if ( isset( $request['email_restrictions'] ) ) {
$coupon->set_email_restrictions( $request['email_restrictions'] );
}
$coupon->save();
return true;
}
/**
@ -502,7 +365,6 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
* @return array
*/
public function get_item_schema() {
$schema = array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => $this->post_type,
@ -548,7 +410,7 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
'type' => 'string',
'context' => array( 'view', 'edit' ),
),
'expiry_date' => array(
'date_expires' => array(
'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
@ -570,7 +432,7 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
'type' => 'array',
'context' => array( 'view', 'edit' ),
),
'exclude_product_ids' => array(
'excluded_product_ids' => array(
'description' => __( "List of product ID's the coupon cannot be used on.", 'woocommerce' ),
'type' => 'array',
'context' => array( 'view', 'edit' ),
@ -635,7 +497,6 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
),
),
);
return $this->add_additional_fields_schema( $schema );
}
@ -646,14 +507,12 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
*/
public function get_collection_params() {
$params = parent::get_collection_params();
$params['code'] = array(
'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ),
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'validate_callback' => 'rest_validate_request_arg',
);
return $params;
}
}

View File

@ -125,7 +125,7 @@ class WC_API_Coupons extends WC_API_Resource {
'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null,
'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),
'usage_count' => (int) $coupon->get_usage_count(),
'expiry_date' => $this->server->format_datetime( $coupon->get_expiry_date() ),
'expiry_date' => $this->server->format_datetime( $coupon->get_date_expires() ),
'enable_free_shipping' => $coupon->get_free_shipping(),
'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ),
'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ),

View File

@ -134,7 +134,7 @@ class WC_API_Coupons extends WC_API_Resource {
'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null,
'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),
'usage_count' => (int) $coupon->get_usage_count(),
'expiry_date' => $coupon->get_expiry_date() ? $this->server->format_datetime( $coupon->get_expiry_date() ) : null,
'expiry_date' => $coupon->get_date_expires() ? $this->server->format_datetime( $coupon->get_date_expires() ) : null,
'enable_free_shipping' => $coupon->get_free_shipping(),
'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ),
'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ),
@ -225,18 +225,10 @@ class WC_API_Coupons extends WC_API_Resource {
throw new WC_API_Exception( 'woocommerce_api_missing_coupon_code', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'code' ), 400 );
}
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
$id_from_code = wc_get_coupon_id_by_code( $coupon_code );
// Check for duplicate coupon codes
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_type = 'shop_coupon'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_title = '%s'
", $coupon_code ) );
if ( $coupon_found ) {
if ( $id_from_code ) {
throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 );
}
@ -340,19 +332,10 @@ class WC_API_Coupons extends WC_API_Resource {
if ( isset( $data['code'] ) ) {
global $wpdb;
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
$id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id );
// Check for duplicate coupon codes
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_type = 'shop_coupon'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_title = '%s'
AND $wpdb->posts.ID != %s
", $coupon_code, $id ) );
if ( $coupon_found ) {
if ( $id_from_code ) {
throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 );
}

View File

@ -134,7 +134,7 @@ class WC_API_Coupons extends WC_API_Resource {
'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null,
'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),
'usage_count' => (int) $coupon->get_usage_count(),
'expiry_date' => $coupon->get_expiry_date() ? $this->server->format_datetime( $coupon->get_expiry_date() ) : null,
'expiry_date' => $coupon->get_date_expires() ? $this->server->format_datetime( $coupon->get_date_expires() ) : null,
'enable_free_shipping' => $coupon->get_free_shipping(),
'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ),
'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ),
@ -225,18 +225,10 @@ class WC_API_Coupons extends WC_API_Resource {
throw new WC_API_Exception( 'woocommerce_api_missing_coupon_code', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'code' ), 400 );
}
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
$id_from_code = wc_get_coupon_id_by_code( $coupon_code );
// Check for duplicate coupon codes
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_type = 'shop_coupon'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_title = '%s'
", $coupon_code ) );
if ( $coupon_found ) {
if ( $id_from_code ) {
throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 );
}
@ -340,19 +332,10 @@ class WC_API_Coupons extends WC_API_Resource {
if ( isset( $data['code'] ) ) {
global $wpdb;
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
$id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id );
// Check for duplicate coupon codes
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_type = 'shop_coupon'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_title = '%s'
AND $wpdb->posts.ID != %s
", $coupon_code, $id ) );
if ( $coupon_found ) {
if ( $id_from_code ) {
throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 );
}

View File

@ -24,27 +24,29 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @var array
*/
protected $_data = array(
'id' => 0,
'code' => '',
'description' => '',
'discount_type' => 'fixed_cart',
'amount' => 0,
'expiry_date' => '',
'usage_count' => 0,
'used_by' => '',
'individual_use' => false,
'product_ids' => array(),
'exclude_product_ids' => array(),
'usage_limit' => '',
'usage_limit_per_user' => '',
'limit_usage_to_x_items' => '',
'free_shipping' => false,
'product_categories' => array(),
'exclude_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '',
'maximum_amount' => '',
'customer_email' => array(),
'id' => 0,
'code' => '',
'amount' => 0,
'date_created' => '',
'date_modified' => '',
'discount_type' => 'fixed_cart',
'description' => '',
'date_expires' => '',
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'excluded_product_ids' => array(),
'usage_limit' => 0,
'usage_limit_per_user' => 0,
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '',
'maximum_amount' => '',
'email_restrictions' => array(),
'used_by' => '',
);
// Coupon message codes
@ -84,21 +86,26 @@ class WC_Coupon extends WC_Legacy_Coupon {
'usage_limit_per_user', 'limit_usage_to_x_items', 'free_shipping',
'product_categories', 'exclude_product_categories', 'exclude_sale_items',
'minimum_amount', 'maximum_amount', 'customer_email', '_used_by',
'_edit_lock', '_edit_last',
);
/**
* Coupon constructor. Loads coupon data.
* @param mixed $code code of the coupon to load
* @param mixed $data Coupon data, object, ID or code.
*/
public function __construct( $code = '' ) {
if ( $code instanceof WC_Coupon ) {
$this->read( absint( $code->get_id() ) );
} elseif ( $coupon = apply_filters( 'woocommerce_get_shop_coupon_data', false, $code ) ) {
public function __construct( $data = '' ) {
parent::__construct( $data );
if ( $data instanceof WC_Coupon ) {
$this->read( absint( $data->get_id() ) );
} elseif ( $coupon = apply_filters( 'woocommerce_get_shop_coupon_data', false, $data ) ) {
_doing_it_wrong( 'woocommerce_get_shop_coupon_data', 'Reading a manual coupon via woocommerce_get_shop_coupon_data has been deprecated. Please sent an instance of WC_Coupon instead.', '2.7' );
$this->read_manual_coupon( $code, $coupon );
} elseif ( ! empty( $code ) ) {
$this->set_code( $code );
$this->read( absint( self::get_coupon_id_from_code( $code ) ) );
$this->read_manual_coupon( $data, $coupon );
} elseif ( is_numeric( $data ) && 'shop_coupon' === get_post_type( $data ) ) {
$this->read( $data );
} elseif ( ! empty( $data ) ) {
$this->set_code( $data );
$this->read( wc_get_coupon_id_by_code( $data ) );
}
}
@ -126,7 +133,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return integer
*/
public function get_id() {
return absint( $this->_data['id'] );
return $this->_data['id'];
}
/**
@ -135,7 +142,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return string
*/
public function get_code() {
return apply_filters( 'woocommerce_coupon_code', $this->_data['code'] );
return $this->_data['code'];
}
/**
@ -168,10 +175,28 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get coupon expiration date.
* @since 2.7.0
* @return string
* @return int
*/
public function get_expiry_date() {
return $this->_data['expiry_date'] && ! is_numeric( $this->_data['expiry_date'] ) ? strtotime( $this->_data['expiry_date'] ) : $this->_data['expiry_date'];
public function get_date_expires() {
return $this->_data['date_expires'];
}
/**
* Get date_created
* @since 2.7.0
* @return int
*/
public function get_date_created() {
return $this->_data['date_created'];
}
/**
* Get date_modified
* @since 2.7.0
* @return int
*/
public function get_date_modified() {
return $this->_data['date_modified'];
}
/**
@ -180,7 +205,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return integer
*/
public function get_usage_count() {
return absint( $this->_data['usage_count'] );
return $this->_data['usage_count'];
}
/**
@ -189,7 +214,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return bool
*/
public function get_individual_use() {
return (bool) $this->_data['individual_use'];
return $this->_data['individual_use'];
}
/**
@ -207,7 +232,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return array
*/
public function get_excluded_product_ids() {
return $this->_data['exclude_product_ids'];
return $this->_data['excluded_product_ids'];
}
/**
@ -216,7 +241,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return integer
*/
public function get_usage_limit() {
return absint( $this->_data['usage_limit'] );
return $this->_data['usage_limit'];
}
/**
@ -225,7 +250,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return integer
*/
public function get_usage_limit_per_user() {
return absint( $this->_data['usage_limit_per_user'] );
return $this->_data['usage_limit_per_user'];
}
/**
@ -243,7 +268,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return bool
*/
public function get_free_shipping() {
return (bool) $this->_data['free_shipping'];
return $this->_data['free_shipping'];
}
/**
@ -261,7 +286,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return array
*/
public function get_excluded_product_categories() {
return $this->_data['exclude_product_categories'];
return $this->_data['excluded_product_categories'];
}
/**
@ -270,7 +295,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return bool
*/
public function get_exclude_sale_items() {
return (bool) $this->_data['exclude_sale_items'];
return $this->_data['exclude_sale_items'];
}
/**
@ -296,7 +321,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @return array
*/
public function get_email_restrictions() {
return $this->_data['customer_email'];
return $this->_data['email_restrictions'];
}
/**
@ -308,27 +333,6 @@ class WC_Coupon extends WC_Legacy_Coupon {
return $this->_data['used_by'];
}
/**
* Get a coupon ID from it's code.
* @since 2.5.0 woocommerce_coupon_code_query was removed in favour of woocommerce_get_coupon_id_from_code filter on the return. wp_cache was also implemented.
* @param string $code
* @return int
*/
private function get_coupon_id_from_code( $code ) {
global $wpdb;
$coupon_id = wp_cache_get( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $code, 'coupons' );
if ( false === $coupon_id ) {
$sql = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1;", $this->get_code() );
if ( $coupon_id = apply_filters( 'woocommerce_get_coupon_id_from_code', $wpdb->get_var( $sql ), $this->get_code() ) ) {
wp_cache_set( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $code, $coupon_id, 'coupons' );
}
}
return absint( $coupon_id );
}
/**
* Get discount amount for a cart item.
*
@ -400,10 +404,20 @@ class WC_Coupon extends WC_Legacy_Coupon {
|
*/
/**
* Set ID
* @param int $value
* @throws WC_Data_Exception
*/
public function set_id( $value ) {
$this->_data['id'] = absint( $value );
}
/**
* Set coupon code.
* @since 2.7.0
* @param string $code
* @throws WC_Data_Exception
*/
public function set_code( $code ) {
$this->_data['code'] = apply_filters( 'woocommerce_coupon_code', $code );
@ -413,6 +427,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set coupon description.
* @since 2.7.0
* @param string $description
* @throws WC_Data_Exception
*/
public function set_description( $description ) {
$this->_data['description'] = $description;
@ -422,8 +437,12 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set discount type.
* @since 2.7.0
* @param string $discount_type
* @throws WC_Data_Exception
*/
public function set_discount_type( $discount_type ) {
if ( ! in_array( $discount_type, array_keys( wc_get_coupon_types() ) ) ) {
$this->error( 'coupon_invalid_discount_type', __( 'Invalid discount type', 'woocommerce' ) );
}
$this->_data['discount_type'] = $discount_type;
}
@ -431,6 +450,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set amount.
* @since 2.7.0
* @param float $amount
* @throws WC_Data_Exception
*/
public function set_amount( $amount ) {
$this->_data['amount'] = wc_format_decimal( $amount );
@ -439,20 +459,38 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set expiration date.
* @since 2.7.0
* @param string $date
* @param string $timestamp Timestamp
* @throws WC_Data_Exception
*/
public function set_expiry_date( $date ) {
if ( ! is_numeric( $date ) ) {
$this->_data['expiry_date'] = strtotime( $date );
} else {
$this->_data['expiry_date'] = $date;
}
public function set_date_expires( $timestamp ) {
$this->_data['date_expires'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp );
}
/**
* Set date_created
* @since 2.7.0
* @param string $timestamp Timestamp
* @throws WC_Data_Exception
*/
public function set_date_created( $timestamp ) {
$this->_data['date_created'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp );
}
/**
* Set date_modified
* @since 2.7.0
* @param string $timestamp
* @throws WC_Data_Exception
*/
public function set_date_modified( $timestamp ) {
$this->_data['date_modified'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp );
}
/**
* Set how many times this coupon has been used.
* @since 2.7.0
* @param int $usage_count
* @throws WC_Data_Exception
*/
public function set_usage_count( $usage_count ) {
$this->_data['usage_count'] = absint( $usage_count );
@ -462,6 +500,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set if this coupon can only be used once.
* @since 2.7.0
* @param bool $is_individual_use
* @throws WC_Data_Exception
*/
public function set_individual_use( $is_individual_use ) {
$this->_data['individual_use'] = (bool) $is_individual_use;
@ -471,24 +510,27 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set the product IDs this coupon can be used with.
* @since 2.7.0
* @param array $product_ids
* @throws WC_Data_Exception
*/
public function set_product_ids( $product_ids ) {
$this->_data['product_ids'] = $product_ids;
$this->_data['product_ids'] = (array) $product_ids;
}
/**
* Set the product IDs this coupon cannot be used with.
* @since 2.7.0
* @param array $excluded_product_ids
* @throws WC_Data_Exception
*/
public function set_excluded_product_ids( $excluded_product_ids ) {
$this->_data['exclude_product_ids'] = $excluded_product_ids;
$this->_data['excluded_product_ids'] = (array) $excluded_product_ids;
}
/**
* Set the amount of times this coupon can be used.
* @since 2.7.0
* @param int $usage_limit
* @throws WC_Data_Exception
*/
public function set_usage_limit( $usage_limit ) {
$this->_data['usage_limit'] = absint( $usage_limit );
@ -498,6 +540,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set the amount of times this coupon can be used per user.
* @since 2.7.0
* @param int $usage_limit
* @throws WC_Data_Exception
*/
public function set_usage_limit_per_user( $usage_limit ) {
$this->_data['usage_limit_per_user'] = absint( $usage_limit );
@ -507,6 +550,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set usage limit to x number of items.
* @since 2.7.0
* @param int $limit_usage_to_x_items
* @throws WC_Data_Exception
*/
public function set_limit_usage_to_x_items( $limit_usage_to_x_items ) {
$this->_data['limit_usage_to_x_items'] = $limit_usage_to_x_items;
@ -516,6 +560,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set if this coupon enables free shipping or not.
* @since 2.7.0
* @param bool $free_shipping
* @throws WC_Data_Exception
*/
public function set_free_shipping( $free_shipping ) {
$this->_data['free_shipping'] = (bool) $free_shipping;
@ -525,24 +570,27 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set the product category IDs this coupon can be used with.
* @since 2.7.0
* @param array $product_categories
* @throws WC_Data_Exception
*/
public function set_product_categories( $product_categories ) {
$this->_data['product_categories'] = $product_categories;
$this->_data['product_categories'] = (array) $product_categories;
}
/**
* Set the product category IDs this coupon cannot be used with.
* @since 2.7.0
* @param array $excluded_product_categories
* @throws WC_Data_Exception
*/
public function set_excluded_product_categories( $excluded_product_categories ) {
$this->_data['exclude_product_categories'] = $excluded_product_categories;
$this->_data['excluded_product_categories'] = (array) $excluded_product_categories;
}
/**
* Set if this coupon should excluded sale items or not.
* @since 2.7.0
* @param bool $exclude_sale_items
* @throws WC_Data_Exception
*/
public function set_exclude_sale_items( $exclude_sale_items ) {
$this->_data['exclude_sale_items'] = (bool) $exclude_sale_items;
@ -552,6 +600,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set the minimum spend amount.
* @since 2.7.0
* @param float $amount
* @throws WC_Data_Exception
*/
public function set_minimum_amount( $amount ) {
$this->_data['minimum_amount'] = wc_format_decimal( $amount );
@ -561,6 +610,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set the maximum spend amount.
* @since 2.7.0
* @param float $amount
* @throws WC_Data_Exception
*/
public function set_maximum_amount( $amount ) {
$this->_data['maximum_amount'] = wc_format_decimal( $amount );
@ -570,15 +620,23 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Set email restrictions.
* @since 2.7.0
* @param array $emails
* @throws WC_Data_Exception
*/
public function set_email_restrictions( $emails = array() ) {
$this->_data['customer_email'] = array_map( 'sanitize_email', $emails );
$emails = array_filter( array_map( 'sanitize_email', (array) $emails ) );
foreach ( $emails as $email ) {
if ( ! is_email( $email ) ) {
$this->error( 'coupon_invalid_email_address', __( 'Invalid email address restriction', 'woocommerce' ) );
}
}
$this->_data['email_restrictions'] = $emails;
}
/**
* Set which users have used this coupon.
* @since 2.7.0
* @param array $used_by
* @throws WC_Data_Exception
*/
public function set_used_by( $used_by ) {
$this->_data['used_by'] = array_filter( $used_by );
@ -599,57 +657,46 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Reads an coupon from the database and sets its data to the class.
* @since 2.7.0
* @param int $id
* @param int $coupon_id
*/
public function read( $id ) {
if ( 0 === $id ) {
$this->_data['id'] = 0;
public function read( $coupon_id ) {
$this->set_defaults();
if ( ! $coupon_id ) {
return;
}
$post_object = get_post( $id );
$post_object = get_post( $coupon_id );
// Only continue reading if this coupon exists...
if ( empty( $post_object ) || empty( $post_object->ID ) ) {
$this->_data['id'] = 0;
if ( ! $post_object ) {
return;
}
$coupon_id = $this->_data['id'] = absint( $post_object->ID );
// Map standard coupon data
$this->set_code( $post_object->post_title );
$this->set_description( $post_object->post_excerpt );
$this->set_discount_type( get_post_meta( $coupon_id, 'discount_type', true ) );
$this->set_amount( get_post_meta( $coupon_id, 'coupon_amount', true ) );
$this->set_expiry_date( get_post_meta( $coupon_id, 'expiry_date', true ) );
$this->set_usage_count( get_post_meta( $coupon_id, 'usage_count', true ) );
// Map meta data
$individual_use = ( 'yes' === get_post_meta( $coupon_id, 'individual_use', true ) );
$this->set_individual_use( $individual_use );
$product_ids = explode( ',', get_post_meta( $coupon_id, 'product_ids', true ), -1 );
$this->set_product_ids( $product_ids );
$exclude_product_ids = explode( ',', get_post_meta( $coupon_id, 'exclude_product_ids', true ), -1 );
$this->set_excluded_product_ids( $exclude_product_ids );
$this->set_usage_limit( get_post_meta( $coupon_id, 'usage_limit', true ) );
$this->set_usage_limit_per_user( get_post_meta( $coupon_id, 'usage_limit_per_user', true ) );
$this->set_limit_usage_to_x_items( get_post_meta( $coupon_id, 'limit_usage_to_x_items', true ) );
$free_shipping = ( 'yes' === get_post_meta( $coupon_id, 'free_shipping', true ) );
$this->set_free_shipping( $free_shipping );
$product_categories = get_post_meta( $coupon_id, 'product_categories', true );
$product_categories = ( ! empty( $product_categories ) ? $product_categories : array() );
$this->set_product_categories( $product_categories );
$exclude_product_categories = get_post_meta( $coupon_id, 'exclude_product_categories', true );
$exclude_product_categories = ( ! empty( $exclude_product_categories ) ? $exclude_product_categories : array() );
$this->set_excluded_product_categories( $exclude_product_categories );
$exclude_sale_items = ( 'yes' === get_post_meta( $coupon_id, 'exclude_sale_items', true ) );
$this->set_exclude_sale_items( $exclude_sale_items );
$this->set_minimum_amount( get_post_meta( $coupon_id, 'minimum_amount', true ) );
$this->set_maximum_amount( get_post_meta( $coupon_id, 'maximum_amount', true ) );
$email_restrictions = get_post_meta( $coupon_id, 'customer_email', true ) ;
$this->set_email_restrictions( ! empty( $email_restrictions ) ? $email_restrictions : array() );
$this->set_used_by( (array) get_post_meta( $coupon_id, '_used_by' ) );
$this->set_props( array(
'id' => $coupon_id,
'code' => $post_object->post_title,
'description' => $post_object->post_excerpt,
'date_created' => $post_object->post_date,
'date_modified' => $post_object->post_modified,
'date_expires' => get_post_meta( $coupon_id, 'expiry_date', true ),
'discount_type' => get_post_meta( $coupon_id, 'discount_type', true ),
'amount' => get_post_meta( $coupon_id, 'coupon_amount', true ),
'usage_count' => get_post_meta( $coupon_id, 'usage_count', true ),
'individual_use' => 'yes' === get_post_meta( $coupon_id, 'individual_use', true ),
'product_ids' => array_filter( (array) explode( ',', get_post_meta( $coupon_id, 'product_ids', true ) ) ),
'excluded_product_ids' => array_filter( (array) explode( ',', get_post_meta( $coupon_id, 'exclude_product_ids', true ) ) ),
'usage_limit' => get_post_meta( $coupon_id, 'usage_limit', true ),
'usage_limit_per_user' => get_post_meta( $coupon_id, 'usage_limit_per_user', true ),
'limit_usage_to_x_items' => get_post_meta( $coupon_id, 'limit_usage_to_x_items', true ),
'free_shipping' => 'yes' === get_post_meta( $coupon_id, 'free_shipping', true ),
'product_categories' => array_filter( (array) get_post_meta( $coupon_id, 'product_categories', true ) ),
'excluded_product_categories' => array_filter( (array) get_post_meta( $coupon_id, 'exclude_product_categories', true ) ),
'exclude_sale_items' => 'yes' === get_post_meta( $coupon_id, 'exclude_sale_items', true ),
'minimum_amount' => get_post_meta( $coupon_id, 'minimum_amount', true ),
'maximum_amount' => get_post_meta( $coupon_id, 'maximum_amount', true ),
'email_restrictions' => array_filter( (array) get_post_meta( $coupon_id, 'customer_email', true ) ),
'used_by' => array_filter( (array) get_post_meta( $coupon_id, '_used_by' ) ),
) );
$this->read_meta_data();
do_action( 'woocommerce_coupon_loaded', $this );
@ -660,13 +707,17 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @since 2.7.0
*/
public function create() {
$this->set_date_created( current_time( 'timestamp' ) );
$coupon_id = wp_insert_post( apply_filters( 'woocommerce_new_coupon_data', array(
'post_type' => 'shop_coupon',
'post_status' => 'publish',
'post_author' => get_current_user_id(),
'post_title' => $this->get_code(),
'post_content' => '',
'post_excerpt' => $this->get_description(),
'post_type' => 'shop_coupon',
'post_status' => 'publish',
'post_author' => get_current_user_id(),
'post_title' => $this->get_code(),
'post_content' => '',
'post_excerpt' => $this->get_description(),
'post_date' => date( 'Y-m-d H:i:s', $this->get_date_created() ),
'post_date_gmt' => get_gmt_from_date( date( 'Y-m-d H:i:s', $this->get_date_created() ) ),
) ), true );
if ( $coupon_id ) {
@ -685,7 +736,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
$coupon_id = $this->get_id();
$post_data = array(
'ID' => $coupon_id,
'ID' => $coupon_id,
'post_title' => $this->get_code(),
'post_excerpt' => $this->get_description(),
);
@ -701,7 +752,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @since 2.7.0
*/
public function save() {
if ( 0 !== $this->get_id() ) {
if ( $this->get_id() ) {
$this->update();
} else {
$this->create();
@ -727,12 +778,12 @@ class WC_Coupon extends WC_Legacy_Coupon {
update_post_meta( $coupon_id, 'coupon_amount', $this->get_amount() );
update_post_meta( $coupon_id, 'individual_use', ( true === $this->get_individual_use() ) ? 'yes' : 'no' );
update_post_meta( $coupon_id, 'product_ids', implode( ',', array_filter( array_map( 'intval', $this->get_product_ids() ) ) ) );
update_post_meta( $coupon_id, 'exclude_product_ids', implode( ',', array_filter( array_map( 'intval', $this->get_excluded_product_categories() ) ) ) );
update_post_meta( $coupon_id, 'exclude_product_ids', implode( ',', array_filter( array_map( 'intval', $this->get_excluded_product_ids() ) ) ) );
update_post_meta( $coupon_id, 'usage_limit', $this->get_usage_limit() );
update_post_meta( $coupon_id, 'usage_limit_per_user', $this->get_usage_limit_per_user() );
update_post_meta( $coupon_id, 'limit_usage_to_x_items', $this->get_limit_usage_to_x_items() );
update_post_meta( $coupon_id, 'usage_count', $this->get_usage_count() );
update_post_meta( $coupon_id, 'expiry_date', $this->get_expiry_date() );
update_post_meta( $coupon_id, 'expiry_date', $this->get_date_expires() );
update_post_meta( $coupon_id, 'free_shipping', ( true === $this->get_free_shipping() ) ? 'yes' : 'no' );
update_post_meta( $coupon_id, 'product_categories', array_filter( array_map( 'intval', $this->get_product_categories() ) ) );
update_post_meta( $coupon_id, 'exclude_product_categories', array_filter( array_map( 'intval', $this->get_excluded_product_categories() ) ) );
@ -749,23 +800,12 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @param array $coupon Array of coupon properties
*/
public function read_manual_coupon( $code, $coupon ) {
// This will set most of our fields correctly
foreach ( $this->_data as $key => $value ) {
if ( isset( $coupon[ $key ] ) ) {
$this->_data[ $key ] = $coupon[ $key ];
}
}
// product_ids and exclude_product_ids could be passed in as an empty string '', or comma separated values, when it should be an empty array for the new format.
$convert_fields_to_array = array( 'product_ids', 'exclude_product_ids' );
foreach ( $convert_fields_to_array as $field ) {
if ( ! is_array( $coupon[ $field ] ) ) {
_doing_it_wrong( $field, $field . ' should be an array instead of a string.', '2.7' );
if ( empty( $coupon[ $field ] ) ) {
$this->_data[ $field ] = array();
} else {
$this->_data[ $field ] = explode( ',', $coupon[ $field ] );
}
$coupon[ $field ] = array_filter( explode( ',', $coupon[ $field ] ) );
}
}
@ -774,12 +814,20 @@ class WC_Coupon extends WC_Legacy_Coupon {
foreach ( $yes_no_fields as $field ) {
if ( 'yes' === $coupon[ $field ] || 'no' === $coupon[ $field ] ) {
_doing_it_wrong( $field, $field . ' should be true or false instead of yes or no.', '2.7' );
$this->_data[ $field ] = ( 'yes' === $coupon[ $field ] );
$coupon[ $field ] = 'yes' === $coupon[ $field ];
}
}
// set our code
// BW compat
$coupon[ 'date_expires' ] = isset( $coupon[ 'date_expires' ] ) ? $coupon[ 'date_expires' ] : '';
$coupon[ 'date_expires' ] = isset( $coupon[ 'expiry_date' ] ) ? $coupon[ 'expiry_date' ] : $coupon[ 'date_expires' ];
$coupon[ 'excluded_product_ids' ] = isset( $coupon[ 'excluded_product_ids'] ) ? $coupon[ 'excluded_product_ids'] : '';
$coupon[ 'excluded_product_ids' ] = isset( $coupon[ 'exclude_product_ids'] ) ? $coupon[ 'exclude_product_ids'] : $coupon[ 'excluded_product_ids'];
$coupon[ 'excluded_product_categories' ] = isset( $coupon[ 'excluded_product_categories'] ) ? $coupon[ 'excluded_product_categories'] : '';
$coupon[ 'excluded_product_categories' ] = isset( $coupon[ 'exclude_product_categories'] ) ? $coupon[ 'exclude_product_categories'] : $coupon[ 'excluded_product_categories'];
$this->set_code( $code );
$this->set_props( $coupon );
}
/*
@ -895,7 +943,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* @throws Exception
*/
private function validate_expiry_date() {
if ( $this->get_expiry_date() && current_time( 'timestamp' ) > $this->get_expiry_date() ) {
if ( $this->get_date_expires() && current_time( 'timestamp' ) > $this->get_date_expires() ) {
throw new Exception( $error_code = self::E_WC_COUPON_EXPIRED );
}
}

View File

@ -256,7 +256,7 @@ class WC_CLI_Coupon extends WC_CLI_Command {
'usage_limit_per_user' => ( ! empty( $coupon->get_usage_limit_per_user() ) ) ? $coupon->get_usage_limit_per_user() : null,
'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),
'usage_count' => (int) $coupon->get_usage_count(),
'expiry_date' => ( ! empty( $coupon->get_expiry_date() ) ) ? $this->format_datetime( $coupon->get_expiry_date() ) : null,
'expiry_date' => ( ! empty( $coupon->get_date_expires() ) ) ? $this->format_datetime( $coupon->get_date_expires() ) : null,
'enable_free_shipping' => $coupon->get_free_shipping(),
'product_category_ids' => implode( ', ', $coupon->get_product_categories() ),
'exclude_product_category_ids' => implode( ', ', $coupon->get_excluded_product_categories() ),
@ -591,7 +591,7 @@ class WC_CLI_Coupon extends WC_CLI_Command {
'usage_limit_per_user' => ( ! empty( $coupon->get_usage_limit_per_user() ) ) ? $coupon->get_usage_limit_per_user() : null,
'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),
'usage_count' => (int) $coupon->get_usage_count(),
'expiry_date' => ( ! empty( $coupon->get_expiry_date() ) ) ? $this->format_datetime( $coupon->get_expiry_date() ) : null,
'expiry_date' => ( ! empty( $coupon->get_date_expires() ) ) ? $this->format_datetime( $coupon->get_date_expires() ) : null,
'free_shipping' => $coupon->get_free_shipping(),
'product_category_ids' => implode( ', ', is_array( $coupon->get_product_categories() ) ? $coupon->get_product_categories() : array() ),
'exclude_product_category_ids' => implode( ', ', is_array( $coupon->get_excluded_product_categories() ) ? $coupon->get_excluded_product_categories() : array() ),

View File

@ -93,7 +93,7 @@ abstract class WC_Legacy_Coupon extends WC_Data {
$value = $this->get_usage_count();
break;
case 'expiry_date' :
$value = $this->get_expiry_date();
$value = $this->get_date_expires();
break;
case 'product_categories' :
$value = $this->get_product_categories();

View File

@ -75,9 +75,7 @@ function wc_coupons_enabled() {
* Get coupon code by ID.
*
* @since 2.7.0
*
* @param int $id Coupon ID.
*
* @return string
*/
function wc_get_coupon_code_by_id( $id ) {
@ -93,3 +91,30 @@ function wc_get_coupon_code_by_id( $id ) {
return (string) $code;
}
/**
* Get coupon code by ID.
*
* @since 2.7.0
* @param string $code
* @param int $exclude Used to exclude an ID from the check if you're checking existance.
* @return int
*/
function wc_get_coupon_id_by_code( $code, $exclude = 0 ) {
global $wpdb;
$ids = wp_cache_get( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $code, 'coupons' );
if ( false === $ids ) {
$sql = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_date DESC;", $code );
$ids = $wpdb->get_col( $sql );
if ( $ids ) {
wp_cache_set( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $code, $ids, 'coupons' );
}
}
$ids = array_diff( array_filter( array_map( 'absint', (array) $ids ) ), array( $exclude ) );
return apply_filters( 'woocommerce_get_coupon_id_from_code', absint( current( $ids ) ), $code, $exclude );
}

View File

@ -12,65 +12,66 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case {
* Setup test coupon data.
* @since 2.7.0
*/
public function setUp() {
parent::setUp();
$this->endpoint = new WC_REST_Coupons_Controller();
$this->user = $this->factory->user->create( array(
'role' => 'administrator',
) );
}
public function setUp() {
parent::setUp();
$this->endpoint = new WC_REST_Coupons_Controller();
$this->user = $this->factory->user->create( array(
'role' => 'administrator',
) );
}
/**
* Test route registration.
* @since 2.7.0
*/
public function test_register_routes() {
$routes = $this->server->get_routes();
$this->assertArrayHasKey( '/wc/v1/coupons', $routes );
$this->assertArrayHasKey( '/wc/v1/coupons/(?P<id>[\d]+)', $routes );
$this->assertArrayHasKey( '/wc/v1/coupons/batch', $routes );
}
/**
* Test route registration.
* @since 2.7.0
*/
public function test_register_routes() {
$routes = $this->server->get_routes();
$this->assertArrayHasKey( '/wc/v1/coupons', $routes );
$this->assertArrayHasKey( '/wc/v1/coupons/(?P<id>[\d]+)', $routes );
$this->assertArrayHasKey( '/wc/v1/coupons/batch', $routes );
}
/**
* Test getting coupons.
* @since 2.7.0
*/
public function test_get_coupons() {
wp_set_current_user( $this->user );
/**
* Test getting coupons.
* @since 2.7.0
*/
public function test_get_coupons() {
wp_set_current_user( $this->user );
$coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$post_1 = get_post( $coupon_1->get_id() );
$coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' );
$coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$post_1 = get_post( $coupon_1->get_id() );
$coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/coupons' ) );
$coupons = $response->get_data();
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/coupons' ) );
$coupons = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( 2, count( $coupons ) );
$this->assertContains( array(
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( 2, count( $coupons ) );
$this->assertContains( array(
'id' => $coupon_1->get_id(),
'code' => 'dummycoupon-1',
'amount' => '1.00',
'code' => 'dummycoupon-1',
'amount' => '1.00',
'date_created' => wc_rest_prepare_date_response( $post_1->post_date_gmt ),
'date_modified' => wc_rest_prepare_date_response( $post_1->post_modified_gmt ),
'date_modified' => wc_rest_prepare_date_response( $post_1->post_modified_gmt ),
'discount_type' => 'fixed_cart',
'description' => 'This is a dummy coupon',
'expiry_date' => '',
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'exclude_product_ids' => array(),
'usage_limit' => '',
'usage_limit_per_user' => '',
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '0.00',
'maximum_amount' => '0.00',
'email_restrictions' => array(),
'used_by' => array(),
'date_expires' => '',
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'excluded_product_ids' => array(),
'usage_limit' => '',
'usage_limit_per_user' => '',
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '0.00',
'maximum_amount' => '0.00',
'email_restrictions' => array(),
'used_by' => array(),
'meta_data' => array(),
'_links' => array(
'self' => array(
array(
@ -84,278 +85,280 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case {
),
),
), $coupons );
}
}
/**
* Test getting coupons without valid permissions.
* @since 2.7.0
*/
public function test_get_coupons_without_permission() {
wp_set_current_user( 0 );
/**
* Test getting coupons without valid permissions.
* @since 2.7.0
*/
public function test_get_coupons_without_permission() {
wp_set_current_user( 0 );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/coupons' ) );
$this->assertEquals( 401, $response->get_status() );
}
}
/**
* Test getting a single coupon.
* @since 2.7.0
*/
public function test_get_coupon() {
wp_set_current_user( $this->user );
/**
* Test getting a single coupon.
* @since 2.7.0
*/
public function test_get_coupon() {
wp_set_current_user( $this->user );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$post = get_post( $coupon->get_id() );
$post = get_post( $coupon->get_id() );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/coupons/' . $coupon->get_id() ) );
$data = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( array(
'id' => $coupon->get_id(),
'code' => 'dummycoupon-1',
'amount' => '1.00',
'date_created' => wc_rest_prepare_date_response( $post->post_date_gmt ),
'date_modified' => wc_rest_prepare_date_response( $post->post_modified_gmt ),
'discount_type' => 'fixed_cart',
'description' => 'This is a dummy coupon',
'expiry_date' => null,
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'exclude_product_ids' => array(),
'usage_limit' => null,
'usage_limit_per_user' => null,
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '0.00',
'maximum_amount' => '0.00',
'email_restrictions' => array(),
'used_by' => array(),
'id' => $coupon->get_id(),
'code' => 'dummycoupon-1',
'amount' => '1.00',
'date_created' => wc_rest_prepare_date_response( $post->post_date_gmt ),
'date_modified' => wc_rest_prepare_date_response( $post->post_modified_gmt ),
'discount_type' => 'fixed_cart',
'description' => 'This is a dummy coupon',
'date_expires' => null,
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'excluded_product_ids' => array(),
'usage_limit' => null,
'usage_limit_per_user' => null,
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '0.00',
'maximum_amount' => '0.00',
'email_restrictions' => array(),
'used_by' => array(),
'meta_data' => array(),
), $data );
}
}
/**
* Test getting a single coupon with an invalid ID.
* @since 2.7.0
*/
public function test_get_coupon_invalid_id() {
wp_set_current_user( $this->user );
/**
* Test getting a single coupon with an invalid ID.
* @since 2.7.0
*/
public function test_get_coupon_invalid_id() {
wp_set_current_user( $this->user );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/coupons/0' ) );
$this->assertEquals( 404, $response->get_status() );
}
}
/**
* Test getting a single coupon without valid permissions.
* @since 2.7.0
*/
public function test_get_coupon_without_permission() {
wp_set_current_user( 0 );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
/**
* Test getting a single coupon without valid permissions.
* @since 2.7.0
*/
public function test_get_coupon_without_permission() {
wp_set_current_user( 0 );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/coupons/' . $coupon->get_id() ) );
$this->assertEquals( 401, $response->get_status() );
}
}
/**
* Test creating a single coupon.
* @since 2.7.0
*/
public function test_create_coupon() {
wp_set_current_user( $this->user );
$request = new WP_REST_Request( 'POST', '/wc/v1/coupons' );
$request->set_body_params( array(
'code' => 'test',
'amount' => '5.00',
'discount_type' => 'fixed_product',
'description' => 'Test',
'usage_limit' => 10,
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
/**
* Test creating a single coupon.
* @since 2.7.0
*/
public function test_create_coupon() {
wp_set_current_user( $this->user );
$request = new WP_REST_Request( 'POST', '/wc/v1/coupons' );
$request->set_body_params( array(
'code' => 'test',
'amount' => '5.00',
'discount_type' => 'fixed_product',
'description' => 'Test',
'usage_limit' => 10,
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertEquals( 201, $response->get_status() );
$this->assertEquals( array(
'id' => $data['id'],
'code' => 'test',
'amount' => '5.00',
'date_created' => $data['date_created'],
'date_modified' => $data['date_modified'],
'discount_type' => 'fixed_product',
'description' => 'Test',
'expiry_date' => null,
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'exclude_product_ids' => array(),
'usage_limit' => 10,
'usage_limit_per_user' => null,
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '0.00',
'maximum_amount' => '0.00',
'email_restrictions' => array(),
'used_by' => array(),
), $data );
}
$this->assertEquals( 201, $response->get_status() );
$this->assertEquals( array(
'id' => $data['id'],
'code' => 'test',
'amount' => '5.00',
'date_created' => $data['date_created'],
'date_modified' => $data['date_modified'],
'discount_type' => 'fixed_product',
'description' => 'Test',
'date_expires' => null,
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'excluded_product_ids' => array(),
'usage_limit' => 10,
'usage_limit_per_user' => null,
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '0.00',
'maximum_amount' => '0.00',
'email_restrictions' => array(),
'used_by' => array(),
'meta_data' => array(),
), $data );
}
/**
* Test creating a single coupon with invalid fields.
* @since 2.7.0
*/
public function test_create_coupon_invalid_fields() {
wp_set_current_user( $this->user );
/**
* Test creating a single coupon with invalid fields.
* @since 2.7.0
*/
public function test_create_coupon_invalid_fields() {
wp_set_current_user( $this->user );
// test no code...
$request = new WP_REST_Request( 'POST', '/wc/v1/coupons' );
$request->set_body_params( array(
'amount' => '5.00',
'discount_type' => 'fixed_product',
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
// test no code...
$request = new WP_REST_Request( 'POST', '/wc/v1/coupons' );
$request->set_body_params( array(
'amount' => '5.00',
'discount_type' => 'fixed_product',
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertEquals( 400, $response->get_status() );
}
$this->assertEquals( 400, $response->get_status() );
}
/**
* Test creating a single coupon without valid permissions.
* @since 2.7.0
*/
public function test_create_coupon_without_permission() {
wp_set_current_user( 0 );
/**
* Test creating a single coupon without valid permissions.
* @since 2.7.0
*/
public function test_create_coupon_without_permission() {
wp_set_current_user( 0 );
// test no code...
$request = new WP_REST_Request( 'POST', '/wc/v1/coupons' );
$request->set_body_params( array(
'code' => 'fail',
'amount' => '5.00',
'discount_type' => 'fixed_product',
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
// test no code...
$request = new WP_REST_Request( 'POST', '/wc/v1/coupons' );
$request->set_body_params( array(
'code' => 'fail',
'amount' => '5.00',
'discount_type' => 'fixed_product',
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertEquals( 401, $response->get_status() );
}
$this->assertEquals( 401, $response->get_status() );
}
/**
* Test updating a single coupon.
* @since 2.7.0
*/
public function test_update_coupon() {
wp_set_current_user( $this->user );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$post = get_post( $coupon->get_id() );
/**
* Test updating a single coupon.
* @since 2.7.0
*/
public function test_update_coupon() {
wp_set_current_user( $this->user );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$post = get_post( $coupon->get_id() );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/coupons/' . $coupon->get_id() ) );
$data = $response->get_data();
$this->assertEquals( 'This is a dummy coupon', $data['description'] );
$this->assertEquals( 'fixed_cart', $data['discount_type'] );
$this->assertEquals( '1.00', $data['amount'] );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/coupons/' . $coupon->get_id() ) );
$data = $response->get_data();
$this->assertEquals( 'This is a dummy coupon', $data['description'] );
$this->assertEquals( 'fixed_cart', $data['discount_type'] );
$this->assertEquals( '1.00', $data['amount'] );
$request = new WP_REST_Request( 'PUT', '/wc/v1/coupons/' . $coupon->get_id() );
$request->set_body_params( array(
'amount' => '10.00',
'description' => 'New description',
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$request = new WP_REST_Request( 'PUT', '/wc/v1/coupons/' . $coupon->get_id() );
$request->set_body_params( array(
'amount' => '10.00',
'description' => 'New description',
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertEquals( '10.00', $data['amount'] );
$this->assertEquals( 'New description', $data['description'] );
$this->assertEquals( 'fixed_cart', $data['discount_type'] );
}
$this->assertEquals( '10.00', $data['amount'] );
$this->assertEquals( 'New description', $data['description'] );
$this->assertEquals( 'fixed_cart', $data['discount_type'] );
}
/**
* Test updating a single coupon with an invalid ID.
* @since 2.7.0
*/
public function test_update_coupon_invalid_id() {
wp_set_current_user( $this->user );
/**
* Test updating a single coupon with an invalid ID.
* @since 2.7.0
*/
public function test_update_coupon_invalid_id() {
wp_set_current_user( $this->user );
$request = new WP_REST_Request( 'PUT', '/wc/v1/coupons/0' );
$request->set_body_params( array(
'code' => 'tester',
'amount' => '10.00',
'description' => 'New description',
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$request = new WP_REST_Request( 'PUT', '/wc/v1/coupons/0' );
$request->set_body_params( array(
'code' => 'tester',
'amount' => '10.00',
'description' => 'New description',
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertEquals( 400, $response->get_status() );
}
$this->assertEquals( 400, $response->get_status() );
}
/**
* Test updating a single coupon without valid permissions.
* @since 2.7.0
*/
public function test_update_coupon_without_permission() {
wp_set_current_user( 0 );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$post = get_post( $coupon->get_id() );
/**
* Test updating a single coupon without valid permissions.
* @since 2.7.0
*/
public function test_update_coupon_without_permission() {
wp_set_current_user( 0 );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$post = get_post( $coupon->get_id() );
$request = new WP_REST_Request( 'PUT', '/wc/v1/coupons/' . $coupon->get_id() );
$request->set_body_params( array(
'amount' => '10.00',
'description' => 'New description',
) );
$response = $this->server->dispatch( $request );
$request = new WP_REST_Request( 'PUT', '/wc/v1/coupons/' . $coupon->get_id() );
$request->set_body_params( array(
'amount' => '10.00',
'description' => 'New description',
) );
$response = $this->server->dispatch( $request );
$this->assertEquals( 401, $response->get_status() );
}
$this->assertEquals( 401, $response->get_status() );
}
/**
* Test deleting a single coupon.
* @since 2.7.0
*/
public function test_delete_coupon() {
wp_set_current_user( $this->user );
/**
* Test deleting a single coupon.
* @since 2.7.0
*/
public function test_delete_coupon() {
wp_set_current_user( $this->user );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$request = new WP_REST_Request( 'DELETE', '/wc/v1/coupons/' . $coupon->get_id() );
$request->set_param( 'force', true );
$response = $this->server->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );
}
}
/**
* Test deleting a single coupon with an invalid ID.
* @since 2.7.0
*/
public function test_delete_coupon_invalid_id() {
wp_set_current_user( $this->user );
/**
* Test deleting a single coupon with an invalid ID.
* @since 2.7.0
*/
public function test_delete_coupon_invalid_id() {
wp_set_current_user( $this->user );
$request = new WP_REST_Request( 'DELETE', '/wc/v1/coupons/0' );
$request->set_param( 'force', true );
$response = $this->server->dispatch( $request );
$this->assertEquals( 404, $response->get_status() );
}
}
/**
* Test deleting a single coupon without valid permissions.
* @since 2.7.0
*/
public function test_delete_coupon_without_permission() {
wp_set_current_user( 0 );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$request = new WP_REST_Request( 'DELETE', '/wc/v1/coupons/' . $coupon->get_id() );
$response = $this->server->dispatch( $request );
/**
* Test deleting a single coupon without valid permissions.
* @since 2.7.0
*/
public function test_delete_coupon_without_permission() {
wp_set_current_user( 0 );
$coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$request = new WP_REST_Request( 'DELETE', '/wc/v1/coupons/' . $coupon->get_id() );
$response = $this->server->dispatch( $request );
$this->assertEquals( 401, $response->get_status() );
}
$this->assertEquals( 401, $response->get_status() );
}
/**
* Test batch operations on coupons.
* @since 2.7.0
*/
public function test_batch_coupon() {
wp_set_current_user( $this->user );
/**
* Test batch operations on coupons.
* @since 2.7.0
*/
public function test_batch_coupon() {
wp_set_current_user( $this->user );
$coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' );
$coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' );
$coupon_3 = WC_Helper_Coupon::create_coupon( 'dummycoupon-3' );
$coupon_4 = WC_Helper_Coupon::create_coupon( 'dummycoupon-4' );
$coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' );
$coupon_3 = WC_Helper_Coupon::create_coupon( 'dummycoupon-3' );
$coupon_4 = WC_Helper_Coupon::create_coupon( 'dummycoupon-4' );
$request = new WP_REST_Request( 'POST', '/wc/v1/coupons/batch' );
$request->set_body_params( array(
@ -367,7 +370,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case {
),
'delete' => array(
$coupon_2->get_id(),
$coupon_3->get_id(),
$coupon_3->get_id(),
),
'create' => array(
array(
@ -381,7 +384,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case {
$this->assertEquals( '5.15', $data['update'][0]['amount'] );
$this->assertEquals( '11.00', $data['create'][0]['amount'] );
$this->assertEquals( 'new-coupon', $data['create'][0]['code'] );
$this->assertEquals( 'new-coupon', $data['create'][0]['code'] );
$this->assertEquals( $coupon_2->get_id(), $data['delete'][0]['id'] );
$this->assertEquals( $coupon_3->get_id(), $data['delete'][1]['id'] );
@ -390,43 +393,43 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case {
$data = $response->get_data();
$this->assertEquals( 3, count( $data ) );
}
}
/**
* Test coupon schema.
* @since 2.7.0
*/
public function test_coupon_schema() {
wp_set_current_user( $this->user );
/**
* Test coupon schema.
* @since 2.7.0
*/
public function test_coupon_schema() {
wp_set_current_user( $this->user );
$request = new WP_REST_Request( 'OPTIONS', '/wc/v1/coupons' );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$properties = $data['schema']['properties'];
$this->assertEquals( 23, count( $properties ) );
$this->assertArrayHasKey( 'id', $properties );
$this->assertArrayHasKey( 'id', $properties );
$this->assertArrayHasKey( 'code', $properties );
$this->assertArrayHasKey( 'date_created', $properties );
$this->assertArrayHasKey( 'date_modified', $properties );
$this->assertArrayHasKey( 'description', $properties );
$this->assertArrayHasKey( 'discount_type', $properties );
$this->assertArrayHasKey( 'amount', $properties );
$this->assertArrayHasKey( 'expiry_date', $properties );
$this->assertArrayHasKey( 'usage_count', $properties );
$this->assertArrayHasKey( 'individual_use', $properties );
$this->assertArrayHasKey( 'product_ids', $properties );
$this->assertArrayHasKey( 'exclude_product_ids', $properties );
$this->assertArrayHasKey( 'usage_limit', $properties );
$this->assertArrayHasKey( 'usage_limit_per_user', $properties );
$this->assertArrayHasKey( 'limit_usage_to_x_items', $properties );
$this->assertArrayHasKey( 'free_shipping', $properties );
$this->assertArrayHasKey( 'product_categories', $properties );
$this->assertArrayHasKey( 'excluded_product_categories', $properties );
$this->assertArrayHasKey( 'exclude_sale_items', $properties );
$this->assertArrayHasKey( 'minimum_amount', $properties );
$this->assertArrayHasKey( 'maximum_amount', $properties );
$this->assertArrayHasKey( 'email_restrictions', $properties );
$this->assertArrayHasKey( 'used_by', $properties );
}
$this->assertArrayHasKey( 'date_created', $properties );
$this->assertArrayHasKey( 'date_modified', $properties );
$this->assertArrayHasKey( 'description', $properties );
$this->assertArrayHasKey( 'discount_type', $properties );
$this->assertArrayHasKey( 'amount', $properties );
$this->assertArrayHasKey( 'date_expires', $properties );
$this->assertArrayHasKey( 'usage_count', $properties );
$this->assertArrayHasKey( 'individual_use', $properties );
$this->assertArrayHasKey( 'product_ids', $properties );
$this->assertArrayHasKey( 'excluded_product_ids', $properties );
$this->assertArrayHasKey( 'usage_limit', $properties );
$this->assertArrayHasKey( 'usage_limit_per_user', $properties );
$this->assertArrayHasKey( 'limit_usage_to_x_items', $properties );
$this->assertArrayHasKey( 'free_shipping', $properties );
$this->assertArrayHasKey( 'product_categories', $properties );
$this->assertArrayHasKey( 'excluded_product_categories', $properties );
$this->assertArrayHasKey( 'exclude_sale_items', $properties );
$this->assertArrayHasKey( 'minimum_amount', $properties );
$this->assertArrayHasKey( 'maximum_amount', $properties );
$this->assertArrayHasKey( 'email_restrictions', $properties );
$this->assertArrayHasKey( 'used_by', $properties );
}
}

View File

@ -38,7 +38,7 @@ class WC_Tests_API_Legacy_Coupons extends WC_API_Unit_Test_Case {
$this->assertEquals( (int) $coupon->get_usage_limit_per_user(), $response['usage_limit_per_user'] );
$this->assertEquals( (int) $coupon->get_limit_usage_to_x_items(), $response['limit_usage_to_x_items'] );
$this->assertEquals( (int) $coupon->get_usage_count(), $response['usage_count'] );
$this->assertEquals( $coupon->get_expiry_date(), $response['expiry_date'] );
$this->assertEquals( $coupon->get_date_expires(), $response['expiry_date'] );
$this->assertEquals( $coupon->get_free_shipping(), $response['enable_free_shipping'] );
$this->assertEquals( $coupon->get_product_categories(), $response['product_category_ids'] );
$this->assertEquals( $coupon->get_excluded_product_categories(), $response['exclude_product_category_ids'] );

View File

@ -144,7 +144,7 @@ class WC_Tests_CouponCRUD extends WC_Unit_Test_Case {
$this->assertEquals( $coupon->get_usage_limit_per_user(), $coupon->usage_limit_per_user );
$this->assertEquals( $coupon->get_limit_usage_to_x_items(), $coupon->limit_usage_to_x_items );
$this->assertEquals( $coupon->get_usage_count(), $coupon->usage_count );
$this->assertEquals( $coupon->get_expiry_date(), $coupon->expiry_date );
$this->assertEquals( $coupon->get_date_expires(), $coupon->expiry_date );
$this->assertEquals( $coupon->get_product_categories(), $coupon->product_categories );
$this->assertEquals( $coupon->get_excluded_product_categories(), $coupon->exclude_product_categories );
$this->assertEquals( $coupon->get_minimum_amount(), $coupon->minimum_amount );
@ -226,7 +226,7 @@ class WC_Tests_CouponCRUD extends WC_Unit_Test_Case {
$time = time();
$standard_getters_and_setters = array(
'code' => 'test', 'description' => 'hello world', 'discount_type' => 'percent_product',
'amount' => 10.50, 'expiry_date' => time(), 'usage_count' => 5, 'individual_use' => true,
'amount' => 10.50, 'date_expires' => time(), 'usage_count' => 5, 'individual_use' => true,
'product_ids' => array( 5, 10 ), 'exclude_product_ids' => array( 2, 1 ), 'usage_limit' => 2,
'usage_limit_per_user' => 10, 'limit_usage_to_x_items' => 2, 'free_shipping' => true,
'product_categories' => array( 6 ), 'exclude_product_categories' => array( 8 ),