PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/woocommerce/includes/class-wc-coupon.php

https://bitbucket.org/theshipswakecreative/psw
PHP | 703 lines | 414 code | 118 blank | 171 comment | 110 complexity | df979af38dcb48634377b5fd5c435b17 MD5 | raw file
Possible License(s): LGPL-3.0, Apache-2.0
  1. <?php
  2. /**
  3. * WooCommerce coupons
  4. *
  5. * The WooCommerce coupons class gets coupon data from storage and checks coupon validity
  6. *
  7. * @class WC_Coupon
  8. * @package WooCommerce/Classes
  9. * @category Class
  10. * @author WooThemes
  11. */
  12. class WC_Coupon {
  13. // Coupon message codes
  14. const E_WC_COUPON_INVALID_FILTERED = 100;
  15. const E_WC_COUPON_INVALID_REMOVED = 101;
  16. const E_WC_COUPON_NOT_YOURS_REMOVED = 102;
  17. const E_WC_COUPON_ALREADY_APPLIED = 103;
  18. const E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY = 104;
  19. const E_WC_COUPON_NOT_EXIST = 105;
  20. const E_WC_COUPON_USAGE_LIMIT_REACHED = 106;
  21. const E_WC_COUPON_EXPIRED = 107;
  22. const E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET = 108;
  23. const E_WC_COUPON_NOT_APPLICABLE = 109;
  24. const E_WC_COUPON_NOT_VALID_SALE_ITEMS = 110;
  25. const E_WC_COUPON_PLEASE_ENTER = 111;
  26. const E_WC_COUPON_MAX_SPEND_LIMIT_MET = 112;
  27. const WC_COUPON_SUCCESS = 200;
  28. const WC_COUPON_REMOVED = 201;
  29. /** @public string Coupon code. */
  30. public $code;
  31. /** @public int Coupon ID. */
  32. public $id;
  33. /** @public string Type of discount. */
  34. public $type;
  35. /** @public string Type of discount (alias). */
  36. public $discount_type;
  37. /** @public string Coupon amount. */
  38. public $amount;
  39. /** @public string "Yes" if for individual use. */
  40. public $individual_use;
  41. /** @public array Array of product IDs. */
  42. public $product_ids;
  43. /** @public int Coupon usage limit. */
  44. public $usage_limit;
  45. /** @public int Coupon usage limit per user. */
  46. public $usage_limit_per_user;
  47. /** @public int Coupon usage limit per item. */
  48. public $limit_usage_to_x_items;
  49. /** @public int Coupon usage count. */
  50. public $usage_count;
  51. /** @public string Expiry date. */
  52. public $expiry_date;
  53. /** @public string "yes" if applied before tax. */
  54. public $apply_before_tax;
  55. /** @public string "yes" if coupon grants free shipping. */
  56. public $free_shipping;
  57. /** @public array Array of category ids. */
  58. public $product_categories;
  59. /** @public array Array of category ids. */
  60. public $exclude_product_categories;
  61. /** @public string "yes" if coupon does NOT apply to items on sale. */
  62. public $exclude_sale_items;
  63. /** @public string Minimum cart amount. */
  64. public $minimum_amount;
  65. /** @public string Maximum cart amount. */
  66. public $maximum_amount;
  67. /** @public string Coupon owner's email. */
  68. public $customer_email;
  69. /** @public array Post meta. */
  70. public $coupon_custom_fields;
  71. /** @public string How much the coupon is worth. */
  72. public $coupon_amount;
  73. /** @public string Error message. */
  74. public $error_message;
  75. /**
  76. * Coupon constructor. Loads coupon data.
  77. *
  78. * @access public
  79. * @param mixed $code code of the coupon to load
  80. */
  81. public function __construct( $code ) {
  82. global $wpdb;
  83. $this->code = apply_filters( 'woocommerce_coupon_code', $code );
  84. // Coupon data lets developers create coupons through code
  85. $coupon_data = apply_filters( 'woocommerce_get_shop_coupon_data', false, $code );
  86. if ( $coupon_data ) {
  87. $this->id = absint( $coupon_data['id'] );
  88. $this->type = esc_html( $coupon_data['type'] );
  89. $this->amount = esc_html( $coupon_data['amount'] ? $coupon_data['amount'] : $coupon_data['coupon_amount'] ) ;
  90. $this->coupon_amount = $this->amount;
  91. $this->individual_use = esc_html( $coupon_data['individual_use'] );
  92. $this->product_ids = is_array( $coupon_data['product_ids'] ) ? $coupon_data['product_ids'] : array();
  93. $this->exclude_product_ids = is_array( $coupon_data['exclude_product_ids'] ) ? $coupon_data['exclude_product_ids'] : array();
  94. $this->usage_limit = absint( $coupon_data['usage_limit'] );
  95. $this->usage_limit_per_user = isset( $coupon_data['usage_limit_per_user'] ) ? absint( $coupon_data['usage_limit_per_user'] ) : 0;
  96. $this->limit_usage_to_x_items = isset( $coupon_data['limit_usage_to_x_items'] ) ? absint( $coupon_data['limit_usage_to_x_items'] ) : '';
  97. $this->usage_count = absint( $coupon_data['usage_count'] );
  98. $this->expiry_date = esc_html( $coupon_data['expiry_date'] );
  99. $this->apply_before_tax = esc_html( $coupon_data['apply_before_tax'] );
  100. $this->free_shipping = esc_html( $coupon_data['free_shipping'] );
  101. $this->product_categories = is_array( $coupon_data['product_categories'] ) ? $coupon_data['product_categories'] : array();
  102. $this->exclude_product_categories = is_array( $coupon_data['exclude_product_categories'] ) ? $coupon_data['exclude_product_categories'] : array();
  103. $this->exclude_sale_items = esc_html( $coupon_data['exclude_sale_items'] );
  104. $this->minimum_amount = esc_html( $coupon_data['minimum_amount'] );
  105. $this->maximum_amount = esc_html( $coupon_data['maximum_amount'] );
  106. $this->customer_email = esc_html( $coupon_data['customer_email'] );
  107. } else {
  108. $coupon_id = $wpdb->get_var( $wpdb->prepare( apply_filters( 'woocommerce_coupon_code_query', "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish'" ), $this->code ) );
  109. if ( ! $coupon_id )
  110. return;
  111. $coupon = get_post( $coupon_id );
  112. $this->post_title = apply_filters( 'woocommerce_coupon_code', $coupon->post_title );
  113. if ( empty( $coupon ) || $this->code !== $this->post_title )
  114. return;
  115. $this->id = $coupon->ID;
  116. $this->coupon_custom_fields = get_post_meta( $this->id );
  117. $load_data = array(
  118. 'discount_type' => 'fixed_cart',
  119. 'coupon_amount' => 0,
  120. 'individual_use' => 'no',
  121. 'product_ids' => '',
  122. 'exclude_product_ids' => '',
  123. 'usage_limit' => '',
  124. 'usage_limit_per_user' => '',
  125. 'limit_usage_to_x_items' => '',
  126. 'usage_count' => '',
  127. 'expiry_date' => '',
  128. 'apply_before_tax' => 'yes',
  129. 'free_shipping' => 'no',
  130. 'product_categories' => array(),
  131. 'exclude_product_categories' => array(),
  132. 'exclude_sale_items' => 'no',
  133. 'minimum_amount' => '',
  134. 'maximum_amount' => '',
  135. 'customer_email' => array()
  136. );
  137. foreach ( $load_data as $key => $default )
  138. $this->$key = isset( $this->coupon_custom_fields[ $key ][0] ) && $this->coupon_custom_fields[ $key ][0] !== '' ? $this->coupon_custom_fields[ $key ][0] : $default;
  139. // Alias
  140. $this->type = $this->discount_type;
  141. $this->amount = $this->coupon_amount;
  142. // Formatting
  143. $this->product_ids = array_filter( array_map( 'trim', explode( ',', $this->product_ids ) ) );
  144. $this->exclude_product_ids = array_filter( array_map( 'trim', explode( ',', $this->exclude_product_ids ) ) );
  145. $this->expiry_date = $this->expiry_date ? strtotime( $this->expiry_date ) : '';
  146. $this->product_categories = array_filter( array_map( 'trim', (array) maybe_unserialize( $this->product_categories ) ) );
  147. $this->exclude_product_categories = array_filter( array_map( 'trim', (array) maybe_unserialize( $this->exclude_product_categories ) ) );
  148. $this->customer_email = array_filter( array_map( 'trim', array_map( 'strtolower', (array) maybe_unserialize( $this->customer_email ) ) ) );
  149. }
  150. do_action( 'woocommerce_coupon_loaded', $this );
  151. }
  152. /**
  153. * Check if coupon needs applying before tax.
  154. *
  155. * @access public
  156. * @return bool
  157. */
  158. public function apply_before_tax() {
  159. return $this->apply_before_tax == 'yes' ? true : false;
  160. }
  161. /**
  162. * Check if a coupon enables free shipping.
  163. *
  164. * @access public
  165. * @return bool
  166. */
  167. public function enable_free_shipping() {
  168. return $this->free_shipping == 'yes' ? true : false;
  169. }
  170. /**
  171. * Check if a coupon excludes sale items.
  172. *
  173. * @access public
  174. * @return bool
  175. */
  176. public function exclude_sale_items() {
  177. return $this->exclude_sale_items == 'yes' ? true : false;
  178. }
  179. /**
  180. * Increase usage count fo current coupon.
  181. *
  182. * @access public
  183. * @param string $used_by Either user ID or billing email
  184. * @return void
  185. */
  186. public function inc_usage_count( $used_by = '' ) {
  187. $this->usage_count++;
  188. update_post_meta( $this->id, 'usage_count', $this->usage_count );
  189. if ( $used_by ) {
  190. add_post_meta( $this->id, '_used_by', strtolower( $used_by ) );
  191. }
  192. }
  193. /**
  194. * Decrease usage count fo current coupon.
  195. *
  196. * @access public
  197. * @param string $used_by Either user ID or billing email
  198. * @return void
  199. */
  200. public function dcr_usage_count( $used_by = '' ) {
  201. global $wpdb;
  202. $this->usage_count--;
  203. update_post_meta( $this->id, 'usage_count', $this->usage_count );
  204. // Delete 1 used by meta
  205. $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_used_by' AND meta_value = %s AND post_id = %d LIMIT 1;", $used_by, $this->id ) );
  206. if ( $meta_id ) {
  207. delete_metadata_by_mid( 'post', $meta_id );
  208. }
  209. }
  210. /**
  211. * Returns the error_message string
  212. *
  213. * @access public
  214. * @return string
  215. */
  216. public function get_error_message() {
  217. return $this->error_message;
  218. }
  219. /**
  220. * is_valid function.
  221. *
  222. * Check if a coupon is valid. Return a reason code if invalid. Reason codes:
  223. *
  224. * @access public
  225. * @return boolean validity or a WP_Error if not valid
  226. */
  227. public function is_valid() {
  228. $error_code = null;
  229. $valid = true;
  230. $error = false;
  231. if ( $this->id ) {
  232. // Usage Limit
  233. if ( $this->usage_limit > 0 ) {
  234. if ( $this->usage_count >= $this->usage_limit ) {
  235. $valid = false;
  236. $error_code = self::E_WC_COUPON_USAGE_LIMIT_REACHED;
  237. }
  238. }
  239. // Per user usage limit - check here if user is logged in (against user IDs)
  240. // Checked again for emails later on in WC_Cart::check_customer_coupons()
  241. if ( $this->usage_limit_per_user > 0 && is_user_logged_in() ) {
  242. $used_by = (array) get_post_meta( $this->id, '_used_by' );
  243. $usage_count = sizeof( array_keys( $used_by, get_current_user_id() ) );
  244. if ( $usage_count >= $this->usage_limit_per_user ) {
  245. $valid = false;
  246. $error_code = self::E_WC_COUPON_USAGE_LIMIT_REACHED;
  247. }
  248. }
  249. // Expired
  250. if ( $this->expiry_date ) {
  251. if ( current_time( 'timestamp' ) > $this->expiry_date ) {
  252. $valid = false;
  253. $error_code = self::E_WC_COUPON_EXPIRED;
  254. }
  255. }
  256. // Minimum spend
  257. if ( $this->minimum_amount > 0 ) {
  258. if ( $this->minimum_amount > WC()->cart->subtotal ) {
  259. $valid = false;
  260. $error_code = self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET;
  261. }
  262. }
  263. // Maximum spend
  264. if ( $this->maximum_amount > 0 ) {
  265. if ( $this->maximum_amount < WC()->cart->subtotal ) {
  266. $valid = false;
  267. $error_code = self::E_WC_COUPON_MAX_SPEND_LIMIT_MET;
  268. }
  269. }
  270. // Product ids - If a product included is found in the cart then its valid
  271. if ( sizeof( $this->product_ids ) > 0 ) {
  272. $valid_for_cart = false;
  273. if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
  274. foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
  275. if ( in_array( $cart_item['product_id'], $this->product_ids ) || in_array( $cart_item['variation_id'], $this->product_ids ) || in_array( $cart_item['data']->get_parent(), $this->product_ids ) )
  276. $valid_for_cart = true;
  277. }
  278. }
  279. if ( ! $valid_for_cart ) {
  280. $valid = false;
  281. $error_code = self::E_WC_COUPON_NOT_APPLICABLE;
  282. }
  283. }
  284. // Category ids - If a product included is found in the cart then its valid
  285. if ( sizeof( $this->product_categories ) > 0 ) {
  286. $valid_for_cart = false;
  287. if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
  288. foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
  289. $product_cats = wp_get_post_terms($cart_item['product_id'], 'product_cat', array("fields" => "ids"));
  290. if ( sizeof( array_intersect( $product_cats, $this->product_categories ) ) > 0 )
  291. $valid_for_cart = true;
  292. }
  293. }
  294. if ( ! $valid_for_cart ) {
  295. $valid = false;
  296. $error_code = self::E_WC_COUPON_NOT_APPLICABLE;
  297. }
  298. }
  299. // Exclude Sale Items check for product coupons - valid if a non-sale item is present
  300. if ( 'yes' === $this->exclude_sale_items && in_array( $this->type, array( 'fixed_product', 'percent_product' ) ) ) {
  301. $valid_for_cart = false;
  302. $product_ids_on_sale = wc_get_product_ids_on_sale();
  303. if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
  304. foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
  305. if ( sizeof( array_intersect( array( absint( $cart_item['product_id'] ), absint( $cart_item['variation_id'] ), $cart_item['data']->get_parent() ), $product_ids_on_sale ) ) === 0 ) {
  306. // not on sale
  307. $valid_for_cart = true;
  308. }
  309. }
  310. }
  311. if ( ! $valid_for_cart ) {
  312. $valid = false;
  313. $error_code = self::E_WC_COUPON_NOT_VALID_SALE_ITEMS;
  314. }
  315. }
  316. // Cart discounts cannot be added if non-eligble product is found in cart
  317. if ( $this->type != 'fixed_product' && $this->type != 'percent_product' ) {
  318. // Exclude Products
  319. if ( sizeof( $this->exclude_product_ids ) > 0 ) {
  320. $valid_for_cart = true;
  321. if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
  322. foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
  323. if ( in_array( $cart_item['product_id'], $this->exclude_product_ids ) || in_array( $cart_item['variation_id'], $this->exclude_product_ids ) || in_array( $cart_item['data']->get_parent(), $this->exclude_product_ids ) ) {
  324. $valid_for_cart = false;
  325. }
  326. }
  327. }
  328. if ( ! $valid_for_cart ) {
  329. $valid = false;
  330. $error_code = self::E_WC_COUPON_NOT_APPLICABLE;
  331. }
  332. }
  333. // Exclude Sale Items
  334. if ( $this->exclude_sale_items == 'yes' ) {
  335. $valid_for_cart = true;
  336. $product_ids_on_sale = wc_get_product_ids_on_sale();
  337. if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
  338. foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
  339. if ( in_array( $cart_item['product_id'], $product_ids_on_sale, true ) || in_array( $cart_item['variation_id'], $product_ids_on_sale, true ) || in_array( $cart_item['data']->get_parent(), $product_ids_on_sale, true ) ) {
  340. $valid_for_cart = false;
  341. }
  342. }
  343. }
  344. if ( ! $valid_for_cart ) {
  345. $valid = false;
  346. $error_code = self::E_WC_COUPON_NOT_VALID_SALE_ITEMS;
  347. }
  348. }
  349. // Exclude Categories
  350. if ( sizeof( $this->exclude_product_categories ) > 0 ) {
  351. $valid_for_cart = true;
  352. if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
  353. foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
  354. $product_cats = wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) );
  355. if ( sizeof( array_intersect( $product_cats, $this->exclude_product_categories ) ) > 0 )
  356. $valid_for_cart = false;
  357. }
  358. }
  359. if ( ! $valid_for_cart ) {
  360. $valid = false;
  361. $error_code = self::E_WC_COUPON_NOT_APPLICABLE;
  362. }
  363. }
  364. }
  365. $valid = apply_filters( 'woocommerce_coupon_is_valid', $valid, $this );
  366. if ( $valid ) {
  367. return true;
  368. } else {
  369. if ( is_null( $error_code ) )
  370. $error_code = self::E_WC_COUPON_INVALID_FILTERED;
  371. }
  372. } else {
  373. $error_code = self::E_WC_COUPON_NOT_EXIST;
  374. }
  375. if ( $error_code )
  376. $this->error_message = $this->get_coupon_error( $error_code );
  377. return false;
  378. }
  379. /**
  380. * Check if a coupon is valid
  381. *
  382. * @return bool
  383. */
  384. public function is_valid_for_cart() {
  385. $valid = $this->type != 'fixed_cart' && $this->type != 'percent' ? false : true;
  386. return apply_filters( 'woocommerce_coupon_is_valid_for_cart', $valid, $this );
  387. }
  388. /**
  389. * Check if a coupon is valid for a product
  390. *
  391. * @param WC_Product $product
  392. * @return boolean
  393. */
  394. public function is_valid_for_product( $product ) {
  395. if ( $this->type != 'fixed_product' && $this->type != 'percent_product' )
  396. return apply_filters( 'woocommerce_coupon_is_valid_for_product', false, $product, $this );
  397. $valid = false;
  398. $product_cats = wp_get_post_terms( $product->id, 'product_cat', array( "fields" => "ids" ) );
  399. // Specific products get the discount
  400. if ( sizeof( $this->product_ids ) > 0 ) {
  401. if ( in_array( $product->id, $this->product_ids ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $this->product_ids ) ) || in_array( $product->get_parent(), $this->product_ids ) )
  402. $valid = true;
  403. // Category discounts
  404. } elseif ( sizeof( $this->product_categories ) > 0 ) {
  405. if ( sizeof( array_intersect( $product_cats, $this->product_categories ) ) > 0 )
  406. $valid = true;
  407. } else {
  408. // No product ids - all items discounted
  409. $valid = true;
  410. }
  411. // Specific product ID's excluded from the discount
  412. if ( sizeof( $this->exclude_product_ids ) > 0 )
  413. if ( in_array( $product->id, $this->exclude_product_ids ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $this->exclude_product_ids ) ) || in_array( $product->get_parent(), $this->exclude_product_ids ) )
  414. $valid = false;
  415. // Specific categories excluded from the discount
  416. if ( sizeof( $this->exclude_product_categories ) > 0 )
  417. if ( sizeof( array_intersect( $product_cats, $this->exclude_product_categories ) ) > 0 )
  418. $valid = false;
  419. // Sale Items excluded from discount
  420. if ( $this->exclude_sale_items == 'yes' ) {
  421. $product_ids_on_sale = wc_get_product_ids_on_sale();
  422. if ( in_array( $product->id, $product_ids_on_sale, true ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $product_ids_on_sale, true ) ) || in_array( $product->get_parent(), $product_ids_on_sale, true ) )
  423. $valid = false;
  424. }
  425. return apply_filters( 'woocommerce_coupon_is_valid_for_product', $valid, $product, $this );
  426. }
  427. /**
  428. * Get discount amount for a cart item
  429. *
  430. * @param float $discounting_amount Amount the coupon is being applied to
  431. * @param array|null $cart_item Cart item being discounted if applicable
  432. * @param boolean $single True if discounting a single qty item, false if its the line
  433. * @return float Amount this coupon has discounted
  434. */
  435. public function get_discount_amount( $discounting_amount, $cart_item = null, $single = false ) {
  436. $discount = 0;
  437. if ( $this->type == 'fixed_product') {
  438. $discount = $discounting_amount < $this->amount ? $discounting_amount : $this->amount;
  439. // If dealing with a line and not a single item, we need to multiple fixed discount by cart item qty.
  440. if ( ! $single && ! is_null( $cart_item ) ) {
  441. // Discount for the line.
  442. $discount = $discount * $cart_item['quantity'];
  443. }
  444. } elseif ( $this->type == 'percent_product' || $this->type == 'percent' ) {
  445. $discount = round( ( $discounting_amount / 100 ) * $this->amount, WC()->cart->dp );
  446. } elseif ( $this->type == 'fixed_cart' ) {
  447. if ( ! is_null( $cart_item ) ) {
  448. /**
  449. * This is the most complex discount - we need to divide the discount between rows based on their price in
  450. * proportion to the subtotal. This is so rows with different tax rates get a fair discount, and so rows
  451. * with no price (free) don't get discounted.
  452. *
  453. * Get item discount by dividing item cost by subtotal to get a %
  454. */
  455. $discount_percent = 0;
  456. if ( WC()->cart->subtotal_ex_tax ) {
  457. $discount_percent = ( $cart_item['data']->get_price_excluding_tax() * $cart_item['quantity'] ) / WC()->cart->subtotal_ex_tax;
  458. }
  459. $discount = min( ( $this->amount * $discount_percent ) / $cart_item['quantity'], $discounting_amount );
  460. } else {
  461. $discount = min( $this->amount, $discounting_amount );
  462. }
  463. }
  464. // Handle the limit_usage_to_x_items option
  465. if ( in_array( $this->type, array( 'percent_product', 'fixed_product' ) ) && ! is_null( $cart_item ) ) {
  466. $qty = empty( $this->limit_usage_to_x_items ) ? $cart_item['quantity'] : min( $this->limit_usage_to_x_items, $cart_item['quantity'] );
  467. if ( $single ) {
  468. $discount = ( $discount * $qty ) / $cart_item['quantity'];
  469. } else {
  470. $discount = ( $discount / $cart_item['quantity'] ) * $qty;
  471. }
  472. }
  473. return apply_filters( 'woocommerce_coupon_get_discount_amount', $discount, $discounting_amount, $cart_item, $single, $this );
  474. }
  475. /**
  476. * Converts one of the WC_Coupon message/error codes to a message string and
  477. * displays the message/error.
  478. *
  479. * @access public
  480. * @param int $msg_code Message/error code.
  481. * @return void
  482. */
  483. public function add_coupon_message( $msg_code ) {
  484. if ( $msg_code < 200 )
  485. wc_add_notice( $this->get_coupon_error( $msg_code ), 'error' );
  486. else
  487. wc_add_notice( $this->get_coupon_message( $msg_code ) );
  488. }
  489. /**
  490. * Map one of the WC_Coupon message codes to a message string
  491. *
  492. * @access public
  493. * @param integer $msg_code
  494. * @return string| Message/error string
  495. */
  496. public function get_coupon_message( $msg_code ) {
  497. switch ( $msg_code ) {
  498. case self::WC_COUPON_SUCCESS :
  499. $msg = __( 'Coupon code applied successfully.', 'woocommerce' );
  500. break;
  501. case self::WC_COUPON_REMOVED :
  502. $msg = __( 'Coupon code removed successfully.', 'woocommerce' );
  503. break;
  504. default:
  505. $msg = '';
  506. break;
  507. }
  508. return apply_filters( 'woocommerce_coupon_message', $msg, $msg_code, $this );
  509. }
  510. /**
  511. * Map one of the WC_Coupon error codes to a message string
  512. *
  513. * @access public
  514. * @param int $err_code Message/error code.
  515. * @return string| Message/error string
  516. */
  517. public function get_coupon_error( $err_code ) {
  518. switch ( $err_code ) {
  519. case self::E_WC_COUPON_INVALID_FILTERED:
  520. $err = __( 'Coupon is not valid.', 'woocommerce' );
  521. break;
  522. case self::E_WC_COUPON_NOT_EXIST:
  523. $err = __( 'Coupon does not exist!', 'woocommerce' );
  524. break;
  525. case self::E_WC_COUPON_INVALID_REMOVED:
  526. $err = sprintf( __( 'Sorry, it seems the coupon "%s" is invalid - it has now been removed from your order.', 'woocommerce' ), $this->code );
  527. break;
  528. case self::E_WC_COUPON_NOT_YOURS_REMOVED:
  529. $err = sprintf( __( 'Sorry, it seems the coupon "%s" is not yours - it has now been removed from your order.', 'woocommerce' ), $this->code );
  530. break;
  531. case self::E_WC_COUPON_ALREADY_APPLIED:
  532. $err = __( 'Coupon code already applied!', 'woocommerce' );
  533. break;
  534. case self::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY:
  535. $err = sprintf( __( 'Sorry, coupon "%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce' ), $this->code );
  536. break;
  537. case self::E_WC_COUPON_USAGE_LIMIT_REACHED:
  538. $err = __( 'Coupon usage limit has been reached.', 'woocommerce' );
  539. break;
  540. case self::E_WC_COUPON_EXPIRED:
  541. $err = __( 'This coupon has expired.', 'woocommerce' );
  542. break;
  543. case self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET:
  544. $err = sprintf( __( 'The minimum spend for this coupon is %s.', 'woocommerce' ), wc_price( $this->minimum_amount ) );
  545. break;
  546. case self::E_WC_COUPON_MAX_SPEND_LIMIT_MET:
  547. $err = sprintf( __( 'The maximum spend for this coupon is %s.', 'woocommerce' ), wc_price( $this->maximum_amount ) );
  548. break;
  549. case self::E_WC_COUPON_NOT_APPLICABLE:
  550. $err = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' );
  551. break;
  552. case self::E_WC_COUPON_NOT_VALID_SALE_ITEMS:
  553. $err = __( 'Sorry, this coupon is not valid for sale items.', 'woocommerce' );
  554. break;
  555. default:
  556. $err = '';
  557. break;
  558. }
  559. return apply_filters( 'woocommerce_coupon_error', $err, $err_code, $this );
  560. }
  561. /**
  562. * Map one of the WC_Coupon error codes to an error string
  563. * No coupon instance will be available where a coupon does not exist,
  564. * so this static method exists.
  565. *
  566. * @access public
  567. * @param int $err_code Error code
  568. * @return string| Error string
  569. */
  570. public static function get_generic_coupon_error( $err_code ) {
  571. switch ( $err_code ) {
  572. case self::E_WC_COUPON_NOT_EXIST:
  573. $err = __( 'Coupon does not exist!', 'woocommerce' );
  574. break;
  575. case self::E_WC_COUPON_PLEASE_ENTER:
  576. $err = __( 'Please enter a coupon code.', 'woocommerce' );
  577. break;
  578. default:
  579. $err = '';
  580. break;
  581. }
  582. // When using this static method, there is no $this to pass to filter
  583. return apply_filters( 'woocommerce_coupon_error', $err, $err_code, null );
  584. }
  585. }