WC_API_Coupons

The WooCommerce WC API Coupons class.

Defined (3)

The class is defined in the following location(s).

/includes/api/legacy/v1/class-wc-api-coupons.php  
  1. class WC_API_Coupons extends WC_API_Resource { 
  2.  
  3. /** @var string $base the route base */ 
  4. protected $base = '/coupons'; 
  5.  
  6. /** 
  7. * Register the routes for this class 
  8. * GET /coupons 
  9. * GET /coupons/count 
  10. * GET /coupons/<id> 
  11. * @since 2.1 
  12. * @param array $routes 
  13. * @return array 
  14. */ 
  15. public function register_routes( $routes ) { 
  16.  
  17. # GET /coupons 
  18. $routes[ $this->base ] = array( 
  19. array( array( $this, 'get_coupons' ), WC_API_Server::READABLE ),  
  20. ); 
  21.  
  22. # GET /coupons/count 
  23. $routes[ $this->base . '/count' ] = array( 
  24. array( array( $this, 'get_coupons_count' ), WC_API_Server::READABLE ),  
  25. ); 
  26.  
  27. # GET /coupons/<id> 
  28. $routes[ $this->base . '/(?P<id>\d+)' ] = array( 
  29. array( array( $this, 'get_coupon' ), WC_API_Server::READABLE ),  
  30. ); 
  31.  
  32. # GET /coupons/code/<code>, note that coupon codes can contain spaces, dashes and underscores 
  33. $routes[ $this->base . '/code/(?P<code>\w[\w\s\-]*)' ] = array( 
  34. array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ),  
  35. ); 
  36.  
  37. return $routes; 
  38.  
  39. /** 
  40. * Get all coupons 
  41. * @since 2.1 
  42. * @param string $fields 
  43. * @param array $filter 
  44. * @param int $page 
  45. * @return array 
  46. */ 
  47. public function get_coupons( $fields = null, $filter = array(), $page = 1 ) { 
  48.  
  49. $filter['page'] = $page; 
  50.  
  51. $query = $this->query_coupons( $filter ); 
  52.  
  53. $coupons = array(); 
  54.  
  55. foreach ( $query->posts as $coupon_id ) { 
  56.  
  57. if ( ! $this->is_readable( $coupon_id ) ) 
  58. continue; 
  59.  
  60. $coupons[] = current( $this->get_coupon( $coupon_id, $fields ) ); 
  61.  
  62. $this->server->add_pagination_headers( $query ); 
  63.  
  64. return array( 'coupons' => $coupons ); 
  65.  
  66. /** 
  67. * Get the coupon for the given ID 
  68. * @since 2.1 
  69. * @param int $id the coupon ID 
  70. * @param string $fields fields to include in response 
  71. * @return array|WP_Error 
  72. */ 
  73. public function get_coupon( $id, $fields = null ) { 
  74. $id = $this->validate_request( $id, 'shop_coupon', 'read' ); 
  75.  
  76. if ( is_wp_error( $id ) ) { 
  77. return $id; 
  78.  
  79. $coupon = new WC_Coupon( $id ); 
  80.  
  81. if ( 0 === $coupon->get_id() ) { 
  82. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), 404 ); 
  83.  
  84. $coupon_data = array( 
  85. 'id' => $coupon->get_id(),  
  86. 'code' => $coupon->get_code(),  
  87. 'type' => $coupon->get_discount_type(),  
  88. 'created_at' => $this->server->format_datetime( $coupon->get_date_created() ? $coupon->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. 
  89. 'updated_at' => $this->server->format_datetime( $coupon->get_date_modified() ? $coupon->get_date_modified()->getTimestamp() : 0 ), // API gives UTC times. 
  90. 'amount' => wc_format_decimal( $coupon->get_amount(), 2 ),  
  91. 'individual_use' => $coupon->get_individual_use(),  
  92. 'product_ids' => array_map( 'absint', (array) $coupon->get_product_ids() ),  
  93. 'exclude_product_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_ids() ),  
  94. 'usage_limit' => $coupon->get_usage_limit() ? $coupon->get_usage_limit() : null,  
  95. 'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null,  
  96. 'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),  
  97. 'usage_count' => (int) $coupon->get_usage_count(),  
  98. 'expiry_date' => $this->server->format_datetime( $coupon->get_date_expires() ? $coupon->get_date_expires()->getTimestamp() : 0 ), // API gives UTC times. 
  99. 'enable_free_shipping' => $coupon->get_free_shipping(),  
  100. 'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ),  
  101. 'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ),  
  102. 'exclude_sale_items' => $coupon->get_exclude_sale_items(),  
  103. 'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ),  
  104. 'customer_emails' => $coupon->get_email_restrictions(),  
  105. ); 
  106.  
  107. return array( 'coupon' => apply_filters( 'woocommerce_api_coupon_response', $coupon_data, $coupon, $fields, $this->server ) ); 
  108.  
  109. /** 
  110. * Get the total number of coupons 
  111. * @since 2.1 
  112. * @param array $filter 
  113. * @return array 
  114. */ 
  115. public function get_coupons_count( $filter = array() ) { 
  116.  
  117. $query = $this->query_coupons( $filter ); 
  118.  
  119. if ( ! current_user_can( 'read_private_shop_coupons' ) ) 
  120. return new WP_Error( 'woocommerce_api_user_cannot_read_coupons_count', __( 'You do not have permission to read the coupons count', 'woocommerce' ), array( 'status' => 401 ) ); 
  121.  
  122. return array( 'count' => (int) $query->found_posts ); 
  123.  
  124. /** 
  125. * Get the coupon for the given code 
  126. * @since 2.1 
  127. * @param string $code the coupon code 
  128. * @param string $fields fields to include in response 
  129. * @return int|WP_Error 
  130. */ 
  131. public function get_coupon_by_code( $code, $fields = null ) { 
  132. global $wpdb; 
  133.  
  134. $id = $wpdb->get_var( $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;", $code ) ); 
  135.  
  136. if ( is_null( $id ) ) 
  137. return new WP_Error( 'woocommerce_api_invalid_coupon_code', __( 'Invalid coupon code', 'woocommerce' ), array( 'status' => 404 ) ); 
  138.  
  139. return $this->get_coupon( $id, $fields ); 
  140.  
  141. /** 
  142. * Create a coupon 
  143. * @param array $data 
  144. * @return array 
  145. */ 
  146. public function create_coupon( $data ) { 
  147.  
  148. return array(); 
  149.  
  150. /** 
  151. * Edit a coupon 
  152. * @param int $id the coupon ID 
  153. * @param array $data 
  154. * @return array 
  155. */ 
  156. public function edit_coupon( $id, $data ) { 
  157.  
  158. $id = $this->validate_request( $id, 'shop_coupon', 'edit' ); 
  159.  
  160. if ( is_wp_error( $id ) ) 
  161. return $id; 
  162.  
  163. return $this->get_coupon( $id ); 
  164.  
  165. /** 
  166. * Delete a coupon 
  167. * @param int $id the coupon ID 
  168. * @param bool $force true to permanently delete coupon, false to move to trash 
  169. * @return array 
  170. */ 
  171. public function delete_coupon( $id, $force = false ) { 
  172.  
  173. $id = $this->validate_request( $id, 'shop_coupon', 'delete' ); 
  174.  
  175. if ( is_wp_error( $id ) ) 
  176. return $id; 
  177.  
  178. return $this->delete( $id, 'shop_coupon', ( 'true' === $force ) ); 
  179.  
  180. /** 
  181. * Helper method to get coupon post objects 
  182. * @since 2.1 
  183. * @param array $args request arguments for filtering query 
  184. * @return WP_Query 
  185. */ 
  186. private function query_coupons( $args ) { 
  187.  
  188. // set base query arguments 
  189. $query_args = array( 
  190. 'fields' => 'ids',  
  191. 'post_type' => 'shop_coupon',  
  192. 'post_status' => 'publish',  
  193. ); 
  194.  
  195. $query_args = $this->merge_query_args( $query_args, $args ); 
  196.  
  197. return new WP_Query( $query_args ); 
/includes/api/legacy/v2/class-wc-api-coupons.php  
  1. class WC_API_Coupons extends WC_API_Resource { 
  2.  
  3. /** @var string $base the route base */ 
  4. protected $base = '/coupons'; 
  5.  
  6. /** 
  7. * Register the routes for this class 
  8. * GET /coupons 
  9. * GET /coupons/count 
  10. * GET /coupons/<id> 
  11. * @since 2.1 
  12. * @param array $routes 
  13. * @return array 
  14. */ 
  15. public function register_routes( $routes ) { 
  16.  
  17. # GET/POST /coupons 
  18. $routes[ $this->base ] = array( 
  19. array( array( $this, 'get_coupons' ), WC_API_Server::READABLE ),  
  20. array( array( $this, 'create_coupon' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ),  
  21. ); 
  22.  
  23. # GET /coupons/count 
  24. $routes[ $this->base . '/count' ] = array( 
  25. array( array( $this, 'get_coupons_count' ), WC_API_Server::READABLE ),  
  26. ); 
  27.  
  28. # GET/PUT/DELETE /coupons/<id> 
  29. $routes[ $this->base . '/(?P<id>\d+)' ] = array( 
  30. array( array( $this, 'get_coupon' ), WC_API_Server::READABLE ),  
  31. array( array( $this, 'edit_coupon' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ),  
  32. array( array( $this, 'delete_coupon' ), WC_API_SERVER::DELETABLE ),  
  33. ); 
  34.  
  35. # GET /coupons/code/<code>, note that coupon codes can contain spaces, dashes and underscores 
  36. $routes[ $this->base . '/code/(?P<code>\w[\w\s\-]*)' ] = array( 
  37. array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ),  
  38. ); 
  39.  
  40. # POST|PUT /coupons/bulk 
  41. $routes[ $this->base . '/bulk' ] = array( 
  42. array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),  
  43. ); 
  44.  
  45. return $routes; 
  46.  
  47. /** 
  48. * Get all coupons 
  49. * @since 2.1 
  50. * @param string $fields 
  51. * @param array $filter 
  52. * @param int $page 
  53. * @return array 
  54. */ 
  55. public function get_coupons( $fields = null, $filter = array(), $page = 1 ) { 
  56.  
  57. $filter['page'] = $page; 
  58.  
  59. $query = $this->query_coupons( $filter ); 
  60.  
  61. $coupons = array(); 
  62.  
  63. foreach ( $query->posts as $coupon_id ) { 
  64.  
  65. if ( ! $this->is_readable( $coupon_id ) ) { 
  66. continue; 
  67.  
  68. $coupons[] = current( $this->get_coupon( $coupon_id, $fields ) ); 
  69.  
  70. $this->server->add_pagination_headers( $query ); 
  71.  
  72. return array( 'coupons' => $coupons ); 
  73.  
  74. /** 
  75. * Get the coupon for the given ID 
  76. * @since 2.1 
  77. * @param int $id the coupon ID 
  78. * @param string $fields fields to include in response 
  79. * @return array|WP_Error 
  80. */ 
  81. public function get_coupon( $id, $fields = null ) { 
  82. try { 
  83.  
  84. $id = $this->validate_request( $id, 'shop_coupon', 'read' ); 
  85.  
  86. if ( is_wp_error( $id ) ) { 
  87. return $id; 
  88.  
  89. $coupon = new WC_Coupon( $id ); 
  90.  
  91. if ( 0 === $coupon->get_id() ) { 
  92. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), 404 ); 
  93.  
  94. $coupon_data = array( 
  95. 'id' => $coupon->get_id(),  
  96. 'code' => $coupon->get_code(),  
  97. 'type' => $coupon->get_discount_type(),  
  98. 'created_at' => $this->server->format_datetime( $coupon->get_date_created() ? $coupon->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. 
  99. 'updated_at' => $this->server->format_datetime( $coupon->get_date_modified() ? $coupon->get_date_modified()->getTimestamp() : 0 ), // API gives UTC times. 
  100. 'amount' => wc_format_decimal( $coupon->get_amount(), 2 ),  
  101. 'individual_use' => $coupon->get_individual_use(),  
  102. 'product_ids' => array_map( 'absint', (array) $coupon->get_product_ids() ),  
  103. 'exclude_product_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_ids() ),  
  104. 'usage_limit' => $coupon->get_usage_limit() ? $coupon->get_usage_limit() : null,  
  105. 'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null,  
  106. 'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),  
  107. 'usage_count' => (int) $coupon->get_usage_count(),  
  108. 'expiry_date' => $coupon->get_date_expires() ? $this->server->format_datetime( $coupon->get_date_expires()->getTimestamp() ) : null, // API gives UTC times. 
  109. 'enable_free_shipping' => $coupon->get_free_shipping(),  
  110. 'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ),  
  111. 'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ),  
  112. 'exclude_sale_items' => $coupon->get_exclude_sale_items(),  
  113. 'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ),  
  114. 'maximum_amount' => wc_format_decimal( $coupon->get_maximum_amount(), 2 ),  
  115. 'customer_emails' => $coupon->get_email_restrictions(),  
  116. 'description' => $coupon->get_description(),  
  117. ); 
  118.  
  119. return array( 'coupon' => apply_filters( 'woocommerce_api_coupon_response', $coupon_data, $coupon, $fields, $this->server ) ); 
  120. } catch ( WC_API_Exception $e ) { 
  121. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  122.  
  123. /** 
  124. * Get the total number of coupons 
  125. * @since 2.1 
  126. * @param array $filter 
  127. * @return array 
  128. */ 
  129. public function get_coupons_count( $filter = array() ) { 
  130. try { 
  131. if ( ! current_user_can( 'read_private_shop_coupons' ) ) { 
  132. throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_coupons_count', __( 'You do not have permission to read the coupons count', 'woocommerce' ), 401 ); 
  133.  
  134. $query = $this->query_coupons( $filter ); 
  135.  
  136. return array( 'count' => (int) $query->found_posts ); 
  137. } catch ( WC_API_Exception $e ) { 
  138. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  139.  
  140. /** 
  141. * Get the coupon for the given code 
  142. * @since 2.1 
  143. * @param string $code the coupon code 
  144. * @param string $fields fields to include in response 
  145. * @return int|WP_Error 
  146. */ 
  147. public function get_coupon_by_code( $code, $fields = null ) { 
  148. global $wpdb; 
  149.  
  150. try { 
  151. $id = $wpdb->get_var( $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;", $code ) ); 
  152.  
  153. if ( is_null( $id ) ) { 
  154. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_code', __( 'Invalid coupon code', 'woocommerce' ), 404 ); 
  155.  
  156. return $this->get_coupon( $id, $fields ); 
  157. } catch ( WC_API_Exception $e ) { 
  158. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  159.  
  160. /** 
  161. * Create a coupon 
  162. * @since 2.2 
  163. * @param array $data 
  164. * @return array 
  165. */ 
  166. public function create_coupon( $data ) { 
  167. global $wpdb; 
  168.  
  169. try { 
  170. if ( ! isset( $data['coupon'] ) ) { 
  171. throw new WC_API_Exception( 'woocommerce_api_missing_coupon_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'coupon' ), 400 ); 
  172.  
  173. $data = $data['coupon']; 
  174.  
  175. // Check user permission 
  176. if ( ! current_user_can( 'publish_shop_coupons' ) ) { 
  177. throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_coupon', __( 'You do not have permission to create coupons', 'woocommerce' ), 401 ); 
  178.  
  179. $data = apply_filters( 'woocommerce_api_create_coupon_data', $data, $this ); 
  180.  
  181. // Check if coupon code is specified 
  182. if ( ! isset( $data['code'] ) ) { 
  183. throw new WC_API_Exception( 'woocommerce_api_missing_coupon_code', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'code' ), 400 ); 
  184.  
  185. $coupon_code = wc_format_coupon_code( $data['code'] ); 
  186. $id_from_code = wc_get_coupon_id_by_code( $coupon_code ); 
  187.  
  188. if ( $id_from_code ) { 
  189. throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 ); 
  190.  
  191. $defaults = array( 
  192. 'type' => 'fixed_cart',  
  193. 'amount' => 0,  
  194. 'individual_use' => false,  
  195. 'product_ids' => array(),  
  196. 'exclude_product_ids' => array(),  
  197. 'usage_limit' => '',  
  198. 'usage_limit_per_user' => '',  
  199. 'limit_usage_to_x_items' => '',  
  200. 'usage_count' => '',  
  201. 'expiry_date' => '',  
  202. 'enable_free_shipping' => false,  
  203. 'product_category_ids' => array(),  
  204. 'exclude_product_category_ids' => array(),  
  205. 'exclude_sale_items' => false,  
  206. 'minimum_amount' => '',  
  207. 'maximum_amount' => '',  
  208. 'customer_emails' => array(),  
  209. 'description' => '',  
  210. ); 
  211.  
  212. $coupon_data = wp_parse_args( $data, $defaults ); 
  213.  
  214. // Validate coupon types 
  215. if ( ! in_array( wc_clean( $coupon_data['type'] ), array_keys( wc_get_coupon_types() ) ) ) { 
  216. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ), 400 ); 
  217.  
  218. $new_coupon = array( 
  219. 'post_title' => $coupon_code,  
  220. 'post_content' => '',  
  221. 'post_status' => 'publish',  
  222. 'post_author' => get_current_user_id(),  
  223. 'post_type' => 'shop_coupon',  
  224. 'post_excerpt' => $coupon_data['description'],  
  225. ); 
  226.  
  227. $id = wp_insert_post( $new_coupon, true ); 
  228.  
  229. if ( is_wp_error( $id ) ) { 
  230. throw new WC_API_Exception( 'woocommerce_api_cannot_create_coupon', $id->get_error_message(), 400 ); 
  231.  
  232. // Set coupon meta 
  233. update_post_meta( $id, 'discount_type', $coupon_data['type'] ); 
  234. update_post_meta( $id, 'coupon_amount', wc_format_decimal( $coupon_data['amount'] ) ); 
  235. update_post_meta( $id, 'individual_use', ( true === $coupon_data['individual_use'] ) ? 'yes' : 'no' ); 
  236. update_post_meta( $id, 'product_ids', implode( ', ', array_filter( array_map( 'intval', $coupon_data['product_ids'] ) ) ) ); 
  237. update_post_meta( $id, 'exclude_product_ids', implode( ', ', array_filter( array_map( 'intval', $coupon_data['exclude_product_ids'] ) ) ) ); 
  238. update_post_meta( $id, 'usage_limit', absint( $coupon_data['usage_limit'] ) ); 
  239. update_post_meta( $id, 'usage_limit_per_user', absint( $coupon_data['usage_limit_per_user'] ) ); 
  240. update_post_meta( $id, 'limit_usage_to_x_items', absint( $coupon_data['limit_usage_to_x_items'] ) ); 
  241. update_post_meta( $id, 'usage_count', absint( $coupon_data['usage_count'] ) ); 
  242. update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ) ) ); 
  243. update_post_meta( $id, 'date_expires', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ), true ) ); 
  244. update_post_meta( $id, 'free_shipping', ( true === $coupon_data['enable_free_shipping'] ) ? 'yes' : 'no' ); 
  245. update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $coupon_data['product_category_ids'] ) ) ); 
  246. update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $coupon_data['exclude_product_category_ids'] ) ) ); 
  247. update_post_meta( $id, 'exclude_sale_items', ( true === $coupon_data['exclude_sale_items'] ) ? 'yes' : 'no' ); 
  248. update_post_meta( $id, 'minimum_amount', wc_format_decimal( $coupon_data['minimum_amount'] ) ); 
  249. update_post_meta( $id, 'maximum_amount', wc_format_decimal( $coupon_data['maximum_amount'] ) ); 
  250. update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $coupon_data['customer_emails'] ) ) ); 
  251.  
  252. do_action( 'woocommerce_api_create_coupon', $id, $data ); 
  253.  
  254. $this->server->send_status( 201 ); 
  255.  
  256. return $this->get_coupon( $id ); 
  257. } catch ( WC_API_Exception $e ) { 
  258. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  259.  
  260. /** 
  261. * Edit a coupon 
  262. * @since 2.2 
  263. * @param int $id the coupon ID 
  264. * @param array $data 
  265. * @return array 
  266. */ 
  267. public function edit_coupon( $id, $data ) { 
  268.  
  269. try { 
  270. if ( ! isset( $data['coupon'] ) ) { 
  271. throw new WC_API_Exception( 'woocommerce_api_missing_coupon_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'coupon' ), 400 ); 
  272.  
  273. $data = $data['coupon']; 
  274.  
  275. $id = $this->validate_request( $id, 'shop_coupon', 'edit' ); 
  276.  
  277. if ( is_wp_error( $id ) ) { 
  278. return $id; 
  279.  
  280. $data = apply_filters( 'woocommerce_api_edit_coupon_data', $data, $id, $this ); 
  281.  
  282. if ( isset( $data['code'] ) ) { 
  283. global $wpdb; 
  284.  
  285. $coupon_code = wc_format_coupon_code( $data['code'] ); 
  286. $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); 
  287.  
  288. if ( $id_from_code ) { 
  289. throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 ); 
  290.  
  291. $updated = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code ) ); 
  292.  
  293. if ( 0 === $updated ) { 
  294. throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 ); 
  295.  
  296. if ( isset( $data['description'] ) ) { 
  297. $updated = wp_update_post( array( 'ID' => intval( $id ), 'post_excerpt' => $data['description'] ) ); 
  298.  
  299. if ( 0 === $updated ) { 
  300. throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 ); 
  301.  
  302. if ( isset( $data['type'] ) ) { 
  303. // Validate coupon types 
  304. if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_coupon_types() ) ) ) { 
  305. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ), 400 ); 
  306. update_post_meta( $id, 'discount_type', $data['type'] ); 
  307.  
  308. if ( isset( $data['amount'] ) ) { 
  309. update_post_meta( $id, 'coupon_amount', wc_format_decimal( $data['amount'] ) ); 
  310.  
  311. if ( isset( $data['individual_use'] ) ) { 
  312. update_post_meta( $id, 'individual_use', ( true === $data['individual_use'] ) ? 'yes' : 'no' ); 
  313.  
  314. if ( isset( $data['product_ids'] ) ) { 
  315. update_post_meta( $id, 'product_ids', implode( ', ', array_filter( array_map( 'intval', $data['product_ids'] ) ) ) ); 
  316.  
  317. if ( isset( $data['exclude_product_ids'] ) ) { 
  318. update_post_meta( $id, 'exclude_product_ids', implode( ', ', array_filter( array_map( 'intval', $data['exclude_product_ids'] ) ) ) ); 
  319.  
  320. if ( isset( $data['usage_limit'] ) ) { 
  321. update_post_meta( $id, 'usage_limit', absint( $data['usage_limit'] ) ); 
  322.  
  323. if ( isset( $data['usage_limit_per_user'] ) ) { 
  324. update_post_meta( $id, 'usage_limit_per_user', absint( $data['usage_limit_per_user'] ) ); 
  325.  
  326. if ( isset( $data['limit_usage_to_x_items'] ) ) { 
  327. update_post_meta( $id, 'limit_usage_to_x_items', absint( $data['limit_usage_to_x_items'] ) ); 
  328.  
  329. if ( isset( $data['usage_count'] ) ) { 
  330. update_post_meta( $id, 'usage_count', absint( $data['usage_count'] ) ); 
  331.  
  332. if ( isset( $data['expiry_date'] ) ) { 
  333. update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ) ) ); 
  334. update_post_meta( $id, 'date_expires', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ), true ) ); 
  335.  
  336. if ( isset( $data['enable_free_shipping'] ) ) { 
  337. update_post_meta( $id, 'free_shipping', ( true === $data['enable_free_shipping'] ) ? 'yes' : 'no' ); 
  338.  
  339. if ( isset( $data['product_category_ids'] ) ) { 
  340. update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $data['product_category_ids'] ) ) ); 
  341.  
  342. if ( isset( $data['exclude_product_category_ids'] ) ) { 
  343. update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $data['exclude_product_category_ids'] ) ) ); 
  344.  
  345. if ( isset( $data['exclude_sale_items'] ) ) { 
  346. update_post_meta( $id, 'exclude_sale_items', ( true === $data['exclude_sale_items'] ) ? 'yes' : 'no' ); 
  347.  
  348. if ( isset( $data['minimum_amount'] ) ) { 
  349. update_post_meta( $id, 'minimum_amount', wc_format_decimal( $data['minimum_amount'] ) ); 
  350.  
  351. if ( isset( $data['maximum_amount'] ) ) { 
  352. update_post_meta( $id, 'maximum_amount', wc_format_decimal( $data['maximum_amount'] ) ); 
  353.  
  354. if ( isset( $data['customer_emails'] ) ) { 
  355. update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $data['customer_emails'] ) ) ); 
  356.  
  357. do_action( 'woocommerce_api_edit_coupon', $id, $data ); 
  358.  
  359. return $this->get_coupon( $id ); 
  360. } catch ( WC_API_Exception $e ) { 
  361. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  362.  
  363. /** 
  364. * Delete a coupon 
  365. * @since 2.2 
  366. * @param int $id the coupon ID 
  367. * @param bool $force true to permanently delete coupon, false to move to trash 
  368. * @return array 
  369. */ 
  370. public function delete_coupon( $id, $force = false ) { 
  371.  
  372. $id = $this->validate_request( $id, 'shop_coupon', 'delete' ); 
  373.  
  374. if ( is_wp_error( $id ) ) { 
  375. return $id; 
  376.  
  377. do_action( 'woocommerce_api_delete_coupon', $id, $this ); 
  378.  
  379. return $this->delete( $id, 'shop_coupon', ( 'true' === $force ) ); 
  380.  
  381. /** 
  382. * expiry_date format 
  383. * @since 2.3.0 
  384. * @param string $expiry_date 
  385. * @param bool $as_timestamp (default: false) 
  386. * @return string|int 
  387. */ 
  388. protected function get_coupon_expiry_date( $expiry_date, $as_timestamp = false ) { 
  389. if ( '' != $expiry_date ) { 
  390. if ( $as_timestamp ) { 
  391. return strtotime( $expiry_date ); 
  392.  
  393. return date( 'Y-m-d', strtotime( $expiry_date ) ); 
  394.  
  395. return ''; 
  396.  
  397. /** 
  398. * Helper method to get coupon post objects 
  399. * @since 2.1 
  400. * @param array $args request arguments for filtering query 
  401. * @return WP_Query 
  402. */ 
  403. private function query_coupons( $args ) { 
  404.  
  405. // set base query arguments 
  406. $query_args = array( 
  407. 'fields' => 'ids',  
  408. 'post_type' => 'shop_coupon',  
  409. 'post_status' => 'publish',  
  410. ); 
  411.  
  412. $query_args = $this->merge_query_args( $query_args, $args ); 
  413.  
  414. return new WP_Query( $query_args ); 
  415.  
  416. /** 
  417. * Bulk update or insert coupons 
  418. * Accepts an array with coupons in the formats supported by 
  419. * WC_API_Coupons->create_coupon() and WC_API_Coupons->edit_coupon() 
  420. * @since 2.4.0 
  421. * @param array $data 
  422. * @return array 
  423. */ 
  424. public function bulk( $data ) { 
  425.  
  426. try { 
  427. if ( ! isset( $data['coupons'] ) ) { 
  428. throw new WC_API_Exception( 'woocommerce_api_missing_coupons_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'coupons' ), 400 ); 
  429.  
  430. $data = $data['coupons']; 
  431. $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'coupons' ); 
  432.  
  433. // Limit bulk operation 
  434. if ( count( $data ) > $limit ) { 
  435. throw new WC_API_Exception( 'woocommerce_api_coupons_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); 
  436.  
  437. $coupons = array(); 
  438.  
  439. foreach ( $data as $_coupon ) { 
  440. $coupon_id = 0; 
  441.  
  442. // Try to get the coupon ID 
  443. if ( isset( $_coupon['id'] ) ) { 
  444. $coupon_id = intval( $_coupon['id'] ); 
  445.  
  446. // Coupon exists / edit coupon 
  447. if ( $coupon_id ) { 
  448. $edit = $this->edit_coupon( $coupon_id, array( 'coupon' => $_coupon ) ); 
  449.  
  450. if ( is_wp_error( $edit ) ) { 
  451. $coupons[] = array( 
  452. 'id' => $coupon_id,  
  453. 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ),  
  454. ); 
  455. } else { 
  456. $coupons[] = $edit['coupon']; 
  457. } else { 
  458.  
  459. // Coupon don't exists / create coupon 
  460. $new = $this->create_coupon( array( 'coupon' => $_coupon ) ); 
  461.  
  462. if ( is_wp_error( $new ) ) { 
  463. $coupons[] = array( 
  464. 'id' => $coupon_id,  
  465. 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ),  
  466. ); 
  467. } else { 
  468. $coupons[] = $new['coupon']; 
  469.  
  470. return array( 'coupons' => apply_filters( 'woocommerce_api_coupons_bulk_response', $coupons, $this ) ); 
  471. } catch ( WC_API_Exception $e ) { 
  472. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
/includes/api/legacy/v3/class-wc-api-coupons.php  
  1. class WC_API_Coupons extends WC_API_Resource { 
  2.  
  3. /** @var string $base the route base */ 
  4. protected $base = '/coupons'; 
  5.  
  6. /** 
  7. * Register the routes for this class 
  8. * GET /coupons 
  9. * GET /coupons/count 
  10. * GET /coupons/<id> 
  11. * @since 2.1 
  12. * @param array $routes 
  13. * @return array 
  14. */ 
  15. public function register_routes( $routes ) { 
  16.  
  17. # GET/POST /coupons 
  18. $routes[ $this->base ] = array( 
  19. array( array( $this, 'get_coupons' ), WC_API_Server::READABLE ),  
  20. array( array( $this, 'create_coupon' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ),  
  21. ); 
  22.  
  23. # GET /coupons/count 
  24. $routes[ $this->base . '/count' ] = array( 
  25. array( array( $this, 'get_coupons_count' ), WC_API_Server::READABLE ),  
  26. ); 
  27.  
  28. # GET/PUT/DELETE /coupons/<id> 
  29. $routes[ $this->base . '/(?P<id>\d+)' ] = array( 
  30. array( array( $this, 'get_coupon' ), WC_API_Server::READABLE ),  
  31. array( array( $this, 'edit_coupon' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ),  
  32. array( array( $this, 'delete_coupon' ), WC_API_SERVER::DELETABLE ),  
  33. ); 
  34.  
  35. # GET /coupons/code/<code>, note that coupon codes can contain spaces, dashes and underscores 
  36. $routes[ $this->base . '/code/(?P<code>\w[\w\s\-]*)' ] = array( 
  37. array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ),  
  38. ); 
  39.  
  40. # POST|PUT /coupons/bulk 
  41. $routes[ $this->base . '/bulk' ] = array( 
  42. array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),  
  43. ); 
  44.  
  45. return $routes; 
  46.  
  47. /** 
  48. * Get all coupons 
  49. * @since 2.1 
  50. * @param string $fields 
  51. * @param array $filter 
  52. * @param int $page 
  53. * @return array 
  54. */ 
  55. public function get_coupons( $fields = null, $filter = array(), $page = 1 ) { 
  56.  
  57. $filter['page'] = $page; 
  58.  
  59. $query = $this->query_coupons( $filter ); 
  60.  
  61. $coupons = array(); 
  62.  
  63. foreach ( $query->posts as $coupon_id ) { 
  64.  
  65. if ( ! $this->is_readable( $coupon_id ) ) { 
  66. continue; 
  67.  
  68. $coupons[] = current( $this->get_coupon( $coupon_id, $fields ) ); 
  69.  
  70. $this->server->add_pagination_headers( $query ); 
  71.  
  72. return array( 'coupons' => $coupons ); 
  73.  
  74. /** 
  75. * Get the coupon for the given ID 
  76. * @since 2.1 
  77. * @param int $id the coupon ID 
  78. * @param string $fields fields to include in response 
  79. * @return array|WP_Error 
  80. */ 
  81. public function get_coupon( $id, $fields = null ) { 
  82. try { 
  83.  
  84. $id = $this->validate_request( $id, 'shop_coupon', 'read' ); 
  85.  
  86. if ( is_wp_error( $id ) ) { 
  87. return $id; 
  88.  
  89. $coupon = new WC_Coupon( $id ); 
  90.  
  91. if ( 0 === $coupon->get_id() ) { 
  92. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), 404 ); 
  93.  
  94. $coupon_data = array( 
  95. 'id' => $coupon->get_id(),  
  96. 'code' => $coupon->get_code(),  
  97. 'type' => $coupon->get_discount_type(),  
  98. 'created_at' => $this->server->format_datetime( $coupon->get_date_created() ? $coupon->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. 
  99. 'updated_at' => $this->server->format_datetime( $coupon->get_date_modified() ? $coupon->get_date_modified()->getTimestamp() : 0 ), // API gives UTC times. 
  100. 'amount' => wc_format_decimal( $coupon->get_amount(), 2 ),  
  101. 'individual_use' => $coupon->get_individual_use(),  
  102. 'product_ids' => array_map( 'absint', (array) $coupon->get_product_ids() ),  
  103. 'exclude_product_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_ids() ),  
  104. 'usage_limit' => $coupon->get_usage_limit() ? $coupon->get_usage_limit() : null,  
  105. 'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null,  
  106. 'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),  
  107. 'usage_count' => (int) $coupon->get_usage_count(),  
  108. 'expiry_date' => $coupon->get_date_expires() ? $this->server->format_datetime( $coupon->get_date_expires()->getTimestamp() ) : null, // API gives UTC times. 
  109. 'enable_free_shipping' => $coupon->get_free_shipping(),  
  110. 'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ),  
  111. 'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ),  
  112. 'exclude_sale_items' => $coupon->get_exclude_sale_items(),  
  113. 'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ),  
  114. 'maximum_amount' => wc_format_decimal( $coupon->get_maximum_amount(), 2 ),  
  115. 'customer_emails' => $coupon->get_email_restrictions(),  
  116. 'description' => $coupon->get_description(),  
  117. ); 
  118.  
  119. return array( 'coupon' => apply_filters( 'woocommerce_api_coupon_response', $coupon_data, $coupon, $fields, $this->server ) ); 
  120. } catch ( WC_API_Exception $e ) { 
  121. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  122.  
  123. /** 
  124. * Get the total number of coupons 
  125. * @since 2.1 
  126. * @param array $filter 
  127. * @return array 
  128. */ 
  129. public function get_coupons_count( $filter = array() ) { 
  130. try { 
  131. if ( ! current_user_can( 'read_private_shop_coupons' ) ) { 
  132. throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_coupons_count', __( 'You do not have permission to read the coupons count', 'woocommerce' ), 401 ); 
  133.  
  134. $query = $this->query_coupons( $filter ); 
  135.  
  136. return array( 'count' => (int) $query->found_posts ); 
  137. } catch ( WC_API_Exception $e ) { 
  138. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  139.  
  140. /** 
  141. * Get the coupon for the given code 
  142. * @since 2.1 
  143. * @param string $code the coupon code 
  144. * @param string $fields fields to include in response 
  145. * @return int|WP_Error 
  146. */ 
  147. public function get_coupon_by_code( $code, $fields = null ) { 
  148. global $wpdb; 
  149.  
  150. try { 
  151. $id = $wpdb->get_var( $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;", $code ) ); 
  152.  
  153. if ( is_null( $id ) ) { 
  154. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_code', __( 'Invalid coupon code', 'woocommerce' ), 404 ); 
  155.  
  156. return $this->get_coupon( $id, $fields ); 
  157. } catch ( WC_API_Exception $e ) { 
  158. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  159.  
  160. /** 
  161. * Create a coupon 
  162. * @since 2.2 
  163. * @param array $data 
  164. * @return array 
  165. */ 
  166. public function create_coupon( $data ) { 
  167. global $wpdb; 
  168.  
  169. try { 
  170. if ( ! isset( $data['coupon'] ) ) { 
  171. throw new WC_API_Exception( 'woocommerce_api_missing_coupon_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'coupon' ), 400 ); 
  172.  
  173. $data = $data['coupon']; 
  174.  
  175. // Check user permission 
  176. if ( ! current_user_can( 'publish_shop_coupons' ) ) { 
  177. throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_coupon', __( 'You do not have permission to create coupons', 'woocommerce' ), 401 ); 
  178.  
  179. $data = apply_filters( 'woocommerce_api_create_coupon_data', $data, $this ); 
  180.  
  181. // Check if coupon code is specified 
  182. if ( ! isset( $data['code'] ) ) { 
  183. throw new WC_API_Exception( 'woocommerce_api_missing_coupon_code', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'code' ), 400 ); 
  184.  
  185. $coupon_code = wc_format_coupon_code( $data['code'] ); 
  186. $id_from_code = wc_get_coupon_id_by_code( $coupon_code ); 
  187.  
  188. if ( $id_from_code ) { 
  189. throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 ); 
  190.  
  191. $defaults = array( 
  192. 'type' => 'fixed_cart',  
  193. 'amount' => 0,  
  194. 'individual_use' => false,  
  195. 'product_ids' => array(),  
  196. 'exclude_product_ids' => array(),  
  197. 'usage_limit' => '',  
  198. 'usage_limit_per_user' => '',  
  199. 'limit_usage_to_x_items' => '',  
  200. 'usage_count' => '',  
  201. 'expiry_date' => '',  
  202. 'enable_free_shipping' => false,  
  203. 'product_category_ids' => array(),  
  204. 'exclude_product_category_ids' => array(),  
  205. 'exclude_sale_items' => false,  
  206. 'minimum_amount' => '',  
  207. 'maximum_amount' => '',  
  208. 'customer_emails' => array(),  
  209. 'description' => '',  
  210. ); 
  211.  
  212. $coupon_data = wp_parse_args( $data, $defaults ); 
  213.  
  214. // Validate coupon types 
  215. if ( ! in_array( wc_clean( $coupon_data['type'] ), array_keys( wc_get_coupon_types() ) ) ) { 
  216. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ), 400 ); 
  217.  
  218. $new_coupon = array( 
  219. 'post_title' => $coupon_code,  
  220. 'post_content' => '',  
  221. 'post_status' => 'publish',  
  222. 'post_author' => get_current_user_id(),  
  223. 'post_type' => 'shop_coupon',  
  224. 'post_excerpt' => $coupon_data['description'],  
  225. ); 
  226.  
  227. $id = wp_insert_post( $new_coupon, true ); 
  228.  
  229. if ( is_wp_error( $id ) ) { 
  230. throw new WC_API_Exception( 'woocommerce_api_cannot_create_coupon', $id->get_error_message(), 400 ); 
  231.  
  232. // Set coupon meta 
  233. update_post_meta( $id, 'discount_type', $coupon_data['type'] ); 
  234. update_post_meta( $id, 'coupon_amount', wc_format_decimal( $coupon_data['amount'] ) ); 
  235. update_post_meta( $id, 'individual_use', ( true === $coupon_data['individual_use'] ) ? 'yes' : 'no' ); 
  236. update_post_meta( $id, 'product_ids', implode( ', ', array_filter( array_map( 'intval', $coupon_data['product_ids'] ) ) ) ); 
  237. update_post_meta( $id, 'exclude_product_ids', implode( ', ', array_filter( array_map( 'intval', $coupon_data['exclude_product_ids'] ) ) ) ); 
  238. update_post_meta( $id, 'usage_limit', absint( $coupon_data['usage_limit'] ) ); 
  239. update_post_meta( $id, 'usage_limit_per_user', absint( $coupon_data['usage_limit_per_user'] ) ); 
  240. update_post_meta( $id, 'limit_usage_to_x_items', absint( $coupon_data['limit_usage_to_x_items'] ) ); 
  241. update_post_meta( $id, 'usage_count', absint( $coupon_data['usage_count'] ) ); 
  242. update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ) ) ); 
  243. update_post_meta( $id, 'date_expires', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ), true ) ); 
  244. update_post_meta( $id, 'free_shipping', ( true === $coupon_data['enable_free_shipping'] ) ? 'yes' : 'no' ); 
  245. update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $coupon_data['product_category_ids'] ) ) ); 
  246. update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $coupon_data['exclude_product_category_ids'] ) ) ); 
  247. update_post_meta( $id, 'exclude_sale_items', ( true === $coupon_data['exclude_sale_items'] ) ? 'yes' : 'no' ); 
  248. update_post_meta( $id, 'minimum_amount', wc_format_decimal( $coupon_data['minimum_amount'] ) ); 
  249. update_post_meta( $id, 'maximum_amount', wc_format_decimal( $coupon_data['maximum_amount'] ) ); 
  250. update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $coupon_data['customer_emails'] ) ) ); 
  251.  
  252. do_action( 'woocommerce_api_create_coupon', $id, $data ); 
  253.  
  254. $this->server->send_status( 201 ); 
  255.  
  256. return $this->get_coupon( $id ); 
  257. } catch ( WC_API_Exception $e ) { 
  258. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  259.  
  260. /** 
  261. * Edit a coupon 
  262. * @since 2.2 
  263. * @param int $id the coupon ID 
  264. * @param array $data 
  265. * @return array 
  266. */ 
  267. public function edit_coupon( $id, $data ) { 
  268.  
  269. try { 
  270. if ( ! isset( $data['coupon'] ) ) { 
  271. throw new WC_API_Exception( 'woocommerce_api_missing_coupon_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'coupon' ), 400 ); 
  272.  
  273. $data = $data['coupon']; 
  274.  
  275. $id = $this->validate_request( $id, 'shop_coupon', 'edit' ); 
  276.  
  277. if ( is_wp_error( $id ) ) { 
  278. return $id; 
  279.  
  280. $data = apply_filters( 'woocommerce_api_edit_coupon_data', $data, $id, $this ); 
  281.  
  282. if ( isset( $data['code'] ) ) { 
  283. global $wpdb; 
  284.  
  285. $coupon_code = wc_format_coupon_code( $data['code'] ); 
  286. $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); 
  287.  
  288. if ( $id_from_code ) { 
  289. throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 ); 
  290.  
  291. $updated = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code ) ); 
  292.  
  293. if ( 0 === $updated ) { 
  294. throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 ); 
  295.  
  296. if ( isset( $data['description'] ) ) { 
  297. $updated = wp_update_post( array( 'ID' => intval( $id ), 'post_excerpt' => $data['description'] ) ); 
  298.  
  299. if ( 0 === $updated ) { 
  300. throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 ); 
  301.  
  302. if ( isset( $data['type'] ) ) { 
  303. // Validate coupon types 
  304. if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_coupon_types() ) ) ) { 
  305. throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ), 400 ); 
  306. update_post_meta( $id, 'discount_type', $data['type'] ); 
  307.  
  308. if ( isset( $data['amount'] ) ) { 
  309. update_post_meta( $id, 'coupon_amount', wc_format_decimal( $data['amount'] ) ); 
  310.  
  311. if ( isset( $data['individual_use'] ) ) { 
  312. update_post_meta( $id, 'individual_use', ( true === $data['individual_use'] ) ? 'yes' : 'no' ); 
  313.  
  314. if ( isset( $data['product_ids'] ) ) { 
  315. update_post_meta( $id, 'product_ids', implode( ', ', array_filter( array_map( 'intval', $data['product_ids'] ) ) ) ); 
  316.  
  317. if ( isset( $data['exclude_product_ids'] ) ) { 
  318. update_post_meta( $id, 'exclude_product_ids', implode( ', ', array_filter( array_map( 'intval', $data['exclude_product_ids'] ) ) ) ); 
  319.  
  320. if ( isset( $data['usage_limit'] ) ) { 
  321. update_post_meta( $id, 'usage_limit', absint( $data['usage_limit'] ) ); 
  322.  
  323. if ( isset( $data['usage_limit_per_user'] ) ) { 
  324. update_post_meta( $id, 'usage_limit_per_user', absint( $data['usage_limit_per_user'] ) ); 
  325.  
  326. if ( isset( $data['limit_usage_to_x_items'] ) ) { 
  327. update_post_meta( $id, 'limit_usage_to_x_items', absint( $data['limit_usage_to_x_items'] ) ); 
  328.  
  329. if ( isset( $data['usage_count'] ) ) { 
  330. update_post_meta( $id, 'usage_count', absint( $data['usage_count'] ) ); 
  331.  
  332. if ( isset( $data['expiry_date'] ) ) { 
  333. update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ) ) ); 
  334. update_post_meta( $id, 'date_expires', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ), true ) ); 
  335.  
  336. if ( isset( $data['enable_free_shipping'] ) ) { 
  337. update_post_meta( $id, 'free_shipping', ( true === $data['enable_free_shipping'] ) ? 'yes' : 'no' ); 
  338.  
  339. if ( isset( $data['product_category_ids'] ) ) { 
  340. update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $data['product_category_ids'] ) ) ); 
  341.  
  342. if ( isset( $data['exclude_product_category_ids'] ) ) { 
  343. update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $data['exclude_product_category_ids'] ) ) ); 
  344.  
  345. if ( isset( $data['exclude_sale_items'] ) ) { 
  346. update_post_meta( $id, 'exclude_sale_items', ( true === $data['exclude_sale_items'] ) ? 'yes' : 'no' ); 
  347.  
  348. if ( isset( $data['minimum_amount'] ) ) { 
  349. update_post_meta( $id, 'minimum_amount', wc_format_decimal( $data['minimum_amount'] ) ); 
  350.  
  351. if ( isset( $data['maximum_amount'] ) ) { 
  352. update_post_meta( $id, 'maximum_amount', wc_format_decimal( $data['maximum_amount'] ) ); 
  353.  
  354. if ( isset( $data['customer_emails'] ) ) { 
  355. update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $data['customer_emails'] ) ) ); 
  356.  
  357. do_action( 'woocommerce_api_edit_coupon', $id, $data ); 
  358.  
  359. return $this->get_coupon( $id ); 
  360. } catch ( WC_API_Exception $e ) { 
  361. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  362.  
  363. /** 
  364. * Delete a coupon 
  365. * @since 2.2 
  366. * @param int $id the coupon ID 
  367. * @param bool $force true to permanently delete coupon, false to move to trash 
  368. * @return array 
  369. */ 
  370. public function delete_coupon( $id, $force = false ) { 
  371.  
  372. $id = $this->validate_request( $id, 'shop_coupon', 'delete' ); 
  373.  
  374. if ( is_wp_error( $id ) ) { 
  375. return $id; 
  376.  
  377. do_action( 'woocommerce_api_delete_coupon', $id, $this ); 
  378.  
  379. return $this->delete( $id, 'shop_coupon', ( 'true' === $force ) ); 
  380.  
  381. /** 
  382. * expiry_date format 
  383. * @since 2.3.0 
  384. * @param string $expiry_date 
  385. * @param bool $as_timestamp (default: false) 
  386. * @return string|int 
  387. */ 
  388. protected function get_coupon_expiry_date( $expiry_date, $as_timestamp = false ) { 
  389. if ( '' != $expiry_date ) { 
  390. if ( $as_timestamp ) { 
  391. return strtotime( $expiry_date ); 
  392.  
  393. return date( 'Y-m-d', strtotime( $expiry_date ) ); 
  394.  
  395. return ''; 
  396.  
  397. /** 
  398. * Helper method to get coupon post objects 
  399. * @since 2.1 
  400. * @param array $args request arguments for filtering query 
  401. * @return WP_Query 
  402. */ 
  403. private function query_coupons( $args ) { 
  404.  
  405. // set base query arguments 
  406. $query_args = array( 
  407. 'fields' => 'ids',  
  408. 'post_type' => 'shop_coupon',  
  409. 'post_status' => 'publish',  
  410. ); 
  411.  
  412. $query_args = $this->merge_query_args( $query_args, $args ); 
  413.  
  414. return new WP_Query( $query_args ); 
  415.  
  416. /** 
  417. * Bulk update or insert coupons 
  418. * Accepts an array with coupons in the formats supported by 
  419. * WC_API_Coupons->create_coupon() and WC_API_Coupons->edit_coupon() 
  420. * @since 2.4.0 
  421. * @param array $data 
  422. * @return array 
  423. */ 
  424. public function bulk( $data ) { 
  425.  
  426. try { 
  427. if ( ! isset( $data['coupons'] ) ) { 
  428. throw new WC_API_Exception( 'woocommerce_api_missing_coupons_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'coupons' ), 400 ); 
  429.  
  430. $data = $data['coupons']; 
  431. $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'coupons' ); 
  432.  
  433. // Limit bulk operation 
  434. if ( count( $data ) > $limit ) { 
  435. throw new WC_API_Exception( 'woocommerce_api_coupons_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); 
  436.  
  437. $coupons = array(); 
  438.  
  439. foreach ( $data as $_coupon ) { 
  440. $coupon_id = 0; 
  441.  
  442. // Try to get the coupon ID 
  443. if ( isset( $_coupon['id'] ) ) { 
  444. $coupon_id = intval( $_coupon['id'] ); 
  445.  
  446. if ( $coupon_id ) { 
  447.  
  448. // Coupon exists / edit coupon 
  449. $edit = $this->edit_coupon( $coupon_id, array( 'coupon' => $_coupon ) ); 
  450.  
  451. if ( is_wp_error( $edit ) ) { 
  452. $coupons[] = array( 
  453. 'id' => $coupon_id,  
  454. 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ),  
  455. ); 
  456. } else { 
  457. $coupons[] = $edit['coupon']; 
  458. } else { 
  459.  
  460. // Coupon don't exists / create coupon 
  461. $new = $this->create_coupon( array( 'coupon' => $_coupon ) ); 
  462.  
  463. if ( is_wp_error( $new ) ) { 
  464. $coupons[] = array( 
  465. 'id' => $coupon_id,  
  466. 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ),  
  467. ); 
  468. } else { 
  469. $coupons[] = $new['coupon']; 
  470.  
  471. return array( 'coupons' => apply_filters( 'woocommerce_api_coupons_bulk_response', $coupons, $this ) ); 
  472. } catch ( WC_API_Exception $e ) { 
  473. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );