1 <?php
2 3 4 5 6 7 8 9 10
11
12
13 if ( !defined( 'ABSPATH' ) ) exit;
14
15
16 17 18 19 20 21 22 23 24
25 function edd_get_discounts( $args = array() ) {
26 $defaults = array(
27 'post_type' => 'edd_discount',
28 'posts_per_page' => 30,
29 'paged' => null,
30 'post_status' => array( 'active', 'inactive', 'expired' )
31 );
32
33 $args = wp_parse_args( $args, $defaults );
34
35 $discounts = get_posts( $args );
36
37 if ( $discounts )
38 return $discounts;
39
40 return false;
41 }
42
43 44 45 46 47 48 49 50
51 function edd_has_active_discounts() {
52 $has_active = false;
53
54 $discounts = edd_get_discounts();
55
56 if ( $discounts) {
57 foreach ( $discounts as $discount ) {
58 if ( $discount->post_status == 'active' && ! edd_is_discount_expired( edd_get_discount_code( $discount->ID ) ) ) {
59 $has_active = true;
60 break;
61 }
62 }
63 }
64
65 return $has_active;
66 }
67
68
69 70 71 72 73 74 75 76 77
78 function edd_get_discount( $discount_id ) {
79 $discount = get_post( $discount_id );
80
81 if ( get_post_type( $discount_id ) != 'edd_discount' )
82 return false;
83
84 return $discount;
85 }
86
87 88 89 90 91 92 93 94 95 96
97 function edd_get_discount_by_code( $code ) {
98 $discounts = edd_get_discounts( array(
99 'meta_key' => '_edd_discount_code',
100 'meta_value' => $code,
101 'posts_per_page' => 1
102 ) );
103
104 if ( $discounts )
105 return $discounts[0];
106
107 return false;
108 }
109
110 111 112 113 114 115 116 117 118
119 function edd_store_discount( $details, $discount_id = null ) {
120
121 $meta = array(
122 'code' => isset( $details['code'] ) ? $details['code'] : '',
123 'uses' => isset( $details['uses'] ) ? $details['uses'] : '',
124 'max_uses' => isset( $details['max'] ) ? $details['max'] : '',
125 'amount' => isset( $details['amount'] ) ? $details['amount'] : '',
126 'start' => isset( $details['start'] ) ? $details['start'] : false,
127 'expiration' => isset( $details['expiration'] ) ? $details['expiration'] : false,
128 'type' => isset( $details['type'] ) ? $details['type'] : '',
129 'min_price' => isset( $details['min_price'] ) ? $details['min_price'] : '',
130 'product_reqs' => isset( $details['products'] ) ? $details['products'] : array(),
131 'product_condition' => isset( $details['product_condition'] )? $details['product_condition'] : '',
132 'is_not_global' => isset( $details['not_global'] ) ? $details['not_global'] : false,
133 'is_single_use' => isset( $details['use_once'] ) ? $details['use_once'] : false,
134 );
135
136 if( $meta['start'] )
137 $meta['start'] = date( 'm/d/Y H:i:s', strtotime( $meta['start'] ) );
138
139 if( $meta['expiration'] )
140 $meta['expiration'] = date( 'm/d/Y H:i:s', strtotime( date( 'm/d/Y', strtotime( $meta['expiration'] ) ) . ' 23:59:59' ) );
141
142 if ( edd_discount_exists( $discount_id ) && ! empty( $discount_id ) ) {
143
144
145 $details = apply_filters( 'edd_update_discount', $details, $discount_id );
146
147 do_action( 'edd_pre_update_discount', $details, $discount_id );
148
149 wp_update_post( array(
150 'ID' => $discount_id,
151 'post_title' => $details['name'],
152 'post_status' => $details['status']
153 ) );
154
155 foreach( $meta as $key => $value ) {
156 update_post_meta( $discount_id, '_edd_discount_' . $key, $value );
157 }
158
159 do_action( 'edd_post_update_discount', $details, $discount_id );
160
161
162 return true;
163 } else {
164
165
166 $details = apply_filters( 'edd_insert_discount', $details );
167
168 do_action( 'edd_pre_insert_discount', $details );
169
170 $discount_id = wp_insert_post( array(
171 'post_type' => 'edd_discount',
172 'post_title' => isset( $details['name'] ) ? $details['name'] : '',
173 'post_status' => 'active'
174 ) );
175
176 foreach( $meta as $key => $value ) {
177 update_post_meta( $discount_id, '_edd_discount_' . $key, $value );
178 }
179
180 do_action( 'edd_post_insert_discount', $details, $discount_id );
181
182
183 return true;
184 }
185 }
186
187
188 189 190 191 192 193 194
195 function edd_remove_discount( $discount_id = 0 ) {
196 do_action( 'edd_pre_delete_discount', $discount_id );
197
198 wp_delete_post( $discount_id, true );
199
200 do_action( 'edd_post_delete_discount', $discount_id );
201 }
202
203
204 205 206 207 208 209 210 211
212 function edd_update_discount_status( $code_id = 0, $new_status = 'active' ) {
213 $discount = edd_get_discount( $code_id );
214
215 if ( $discount ) {
216 do_action( 'edd_pre_update_discount_status', $code_id, $new_status, $discount->post_status );
217
218 wp_update_post( array( 'ID' => $code_id, 'post_status' => $new_status ) );
219
220 do_action( 'edd_post_update_discount_status', $code_id, $new_status, $discount->post_status );
221
222 return true;
223 }
224
225 return false;
226 }
227
228 229 230 231 232 233 234
235 function edd_discount_exists( $code_id ) {
236 if ( edd_get_discount( $code_id ) )
237 return true;
238
239 return false;
240 }
241
242 243 244 245 246 247 248
249 function edd_is_discount_active( $code_id = null ) {
250 $discount = edd_get_discount( $code_id );
251 $return = false;
252
253 if ( $discount ) {
254 if ( $discount->post_status == 'active' && ! edd_is_discount_expired( $code_id ) ) {
255 $return = true;
256 }
257 }
258
259 return apply_filters( 'edd_is_discount_active', $return, $code_id );
260 }
261
262 263 264 265 266 267 268
269 function edd_get_discount_code( $code_id = null ) {
270 $code = get_post_meta( $code_id, '_edd_discount_code', true );
271
272 return apply_filters( 'edd_get_discount_code', $code, $code_id );
273 }
274
275 276 277 278 279 280 281
282 function edd_get_discount_start_date( $code_id = null ) {
283 $start_date = get_post_meta( $code_id, '_edd_discount_start', true );
284
285 return apply_filters( 'edd_get_discount_start_date', $start_date, $code_id );
286 }
287
288 289 290 291 292 293 294
295 function edd_get_discount_expiration( $code_id = null ) {
296 $expiration = get_post_meta( $code_id, '_edd_discount_expiration', true );
297
298 return apply_filters( 'edd_get_discount_expiration', $expiration, $code_id );
299 }
300
301 302 303 304 305 306 307
308 function edd_get_discount_max_uses( $code_id = null ) {
309 $max_uses = get_post_meta( $code_id, '_edd_discount_max_uses', true );
310
311 return (int) apply_filters( 'edd_get_discount_max_uses', $max_uses, $code_id );
312 }
313
314 315 316 317 318 319 320
321 function edd_get_discount_uses( $code_id = null ) {
322 $uses = get_post_meta( $code_id, '_edd_discount_uses', true );
323
324 return (int) apply_filters( 'edd_get_discount_uses', $uses, $code_id );
325 }
326
327 328 329 330 331 332 333
334 function edd_get_discount_min_price( $code_id = null ) {
335 $min_price = get_post_meta( $code_id, '_edd_discount_min_price', true );
336
337 return (float) apply_filters( 'edd_get_discount_min_price', $min_price, $code_id );
338 }
339
340 341 342 343 344 345 346 347
348 function edd_get_discount_amount( $code_id = null ) {
349 $amount = get_post_meta( $code_id, '_edd_discount_amount', true );
350
351 return (float) apply_filters( 'edd_get_discount_amount', $amount, $code_id );
352 }
353
354 355 356 357 358 359 360 361
362 function edd_get_discount_type( $code_id = null ) {
363 $type = get_post_meta( $code_id, '_edd_discount_type', true );
364
365 return apply_filters( 'edd_get_discount_type', $type, $code_id );
366 }
367
368 369 370 371 372 373 374
375 function edd_get_discount_product_reqs( $code_id = null ) {
376 $product_reqs = get_post_meta( $code_id, '_edd_discount_product_reqs', true );
377
378 if ( empty( $product_reqs ) || ! is_array( $product_reqs ) ) {
379 $product_reqs = array();
380 }
381
382 return (array) apply_filters( 'edd_get_discount_product_reqs', $product_reqs, $code_id );
383 }
384
385 386 387 388 389 390 391 392
393 function edd_get_discount_product_condition( $code_id = 0 ) {
394 return get_post_meta( $code_id, '_edd_discount_product_condition', true );
395 }
396
397 398 399 400 401 402 403 404 405 406 407
408 function edd_is_discount_not_global( $code_id = 0 ) {
409 return (bool) get_post_meta( $code_id, '_edd_discount_is_not_global', true );
410 }
411
412 413 414 415 416 417 418 419 420 421
422 function edd_is_discount_expired( $code_id = null ) {
423 $discount = edd_get_discount( $code_id );
424 $return = false;
425
426 if ( $discount ) {
427 $expiration = edd_get_discount_expiration( $code_id );
428 if ( $expiration ) {
429 $expiration = strtotime( $expiration );
430 if ( $expiration < time() - ( 24 * 60 * 60 ) ) {
431
432 $return = true;
433 }
434 }
435 }
436
437 return apply_filters( 'edd_is_discount_expired', $return, $code_id );
438 }
439
440 441 442 443 444 445 446 447 448
449 function edd_is_discount_started( $code_id = null ) {
450 $discount = edd_get_discount( $code_id );
451 $return = false;
452
453 if ( $discount ) {
454 $start_date = edd_get_discount_start_date( $code_id );
455
456 if ( $start_date ) {
457 $start_date = strtotime( $start_date );
458
459 if ( $start_date < time() ) {
460
461 $return = true;
462 }
463 } else {
464
465 $return = true;
466 }
467 }
468
469 return apply_filters( 'edd_is_discount_started', $return, $code_id );
470 }
471
472 473 474 475 476 477 478 479 480
481 function edd_is_discount_maxed_out( $code_id = null ) {
482 $discount = edd_get_discount( $code_id );
483 $return = false;
484
485 if ( $discount ) {
486 $uses = edd_get_discount_uses( $code_id );
487
488 $max_uses = edd_get_discount_max_uses( $code_id );
489
490 if ( $uses >= $max_uses && ! empty( $max_uses ) ) {
491
492 $return = true;
493 }
494 }
495
496 return apply_filters( 'edd_is_discount_maxed_out', $return, $code_id );
497 }
498
499 500 501 502 503 504 505 506 507
508 function edd_discount_is_min_met( $code_id = null ) {
509 $discount = edd_get_discount( $code_id );
510 $return = false;
511
512 if ( $discount ) {
513 $min = edd_get_discount_min_price( $code_id );
514 $cart_amount = edd_get_cart_subtotal();
515
516 if ( (float) $cart_amount >= (float) $min ) {
517
518 $return = true;
519 }
520 }
521
522 return apply_filters( 'edd_is_discount_min_met', $return, $code_id );
523 }
524
525 526 527 528 529 530 531
532 function edd_discount_is_single_use( $code_id = 0 ) {
533 $single_use = get_post_meta( $code_id, '_edd_discount_is_single_use', true );
534 return (bool) apply_filters( 'edd_is_discount_single_use', $single_use, $code_id );
535 }
536
537 538 539 540 541 542 543
544 function edd_discount_product_reqs_met( $code_id = null ) {
545 $product_reqs = edd_get_discount_product_reqs( $code_id );
546 $condition = edd_get_discount_product_condition( $code_id );
547 $cart_items = edd_get_cart_contents();
548 $ret = false;
549
550 if ( empty( $product_reqs ) )
551 $ret = true;
552
553
554 if ( ! $ret ) :
555 switch( $condition ) :
556 case 'all' :
557
558 $ret = true;
559
560 foreach ( $product_reqs as $download_id ) {
561 if ( ! edd_item_in_cart( $download_id ) ) {
562 $ret = false;
563 break;
564 }
565 }
566
567 break;
568
569 default :
570 foreach ( $product_reqs as $download_id ) {
571 if ( edd_item_in_cart( $download_id ) ) {
572 $ret = true;
573 break;
574 }
575 }
576
577 break;
578
579 endswitch;
580 endif;
581
582 return (bool) apply_filters( 'edd_is_discount_products_req_met', $ret, $code_id, $condition );
583 }
584
585 586 587 588 589 590 591 592 593 594 595 596 597
598 function edd_is_discount_used( $code = null, $user = '', $code_id = 0 ) {
599 $return = false;
600 $user_found = true;
601
602 if ( empty( $code_id ) )
603 $code_id = edd_get_discount_id_by_code( $code );
604
605 if ( edd_discount_is_single_use( $code_id ) ) {
606 if ( is_email( $user ) ) {
607 $user_found = true;
608 $key = '_edd_payment_user_email';
609 $value = $user;
610 } else {
611 $user_data = get_user_by( 'login', $user );
612
613 if ( $user_data ) {
614 $key = '_edd_payment_user_id';
615 $value = $user_data->ID;
616 } else {
617 $user_found = false;
618 }
619 }
620
621 if ( $user_found ) {
622 $query_args = array(
623 'post_type' => 'edd_payment',
624 'meta_query' => array(
625 array(
626 'key' => $key,
627 'value' => $value,
628 'compare' => '='
629 )
630 ),
631 'fields' => 'ids'
632 );
633
634 $payments = get_posts( $query_args );
635
636 if ( $payments ) {
637 foreach ( $payments as $payment ) {
638
639 $payment_meta = edd_get_payment_meta( $payment );
640 $user_info = maybe_unserialize( $payment_meta['user_info'] );
641 if ( $user_info['discount'] == $code ) {
642 $return = true;
643 }
644 }
645 }
646 }
647 }
648
649 return apply_filters( 'edd_is_discount_used', $return, $code, $user );
650 }
651
652 653 654 655 656 657 658 659
660 function edd_is_discount_valid( $code = '', $user = '' ) {
661
662 $return = false;
663 $discount_id = edd_get_discount_id_by_code( $code );
664 $user = trim( $user );
665
666 if ( $discount_id !== false ) {
667 if (
668 edd_is_discount_active( $discount_id ) &&
669 edd_is_discount_started( $discount_id ) &&
670 !edd_is_discount_maxed_out( $discount_id ) &&
671 !edd_is_discount_used( $code, $user, $discount_id ) &&
672 edd_discount_is_min_met( $discount_id ) &&
673 edd_discount_product_reqs_met( $discount_id )
674 ) {
675 $return = true;
676 }
677 }
678
679 return apply_filters( 'edd_is_discount_valid', $return, $discount_id, $code, $user );
680 }
681
682
683 684 685 686 687 688 689 690 691
692 function edd_get_discount_id_by_code( $code ) {
693 $discount = edd_get_discount_by_code( $code );
694 if( $discount )
695 return $discount->ID;
696 return false;
697 }
698
699
700 701 702 703 704 705 706 707 708 709
710 function edd_get_discounted_amount( $code, $base_price ) {
711 $discount_id = edd_get_discount_id_by_code( $code );
712 $type = edd_get_discount_type( $discount_id );
713 $rate = edd_get_discount_amount( $discount_id );
714
715 if ( $type == 'flat' ) {
716
717 $discounted_price = $base_price - $rate;
718 if ( $discounted_price < 0 ) {
719 $discounted_price = 0;
720 }
721
722 } else {
723
724 $discounted_price = $base_price - ( $base_price * ( $rate / 100 ) );
725 }
726
727 return apply_filters( 'edd_discounted_amount', round( $discounted_price, 2 ) );
728 }
729
730 731 732 733 734 735 736 737 738
739 function edd_increase_discount_usage( $code ) {
740 $discount_id = edd_get_discount_id_by_code( $code );
741 $uses = edd_get_discount_uses( $discount_id );
742
743 if ( $uses ) {
744 $uses++;
745 } else {
746 $uses = 1;
747 }
748
749 update_post_meta( $discount_id, '_edd_discount_uses', $uses );
750 return $uses;
751 }
752
753 754 755 756 757 758 759 760
761 function edd_format_discount_rate( $type, $amount ) {
762 if ( $type == 'flat' ) {
763 return edd_currency_filter( edd_format_amount( $amount ) );
764 } else {
765 return $amount . '%';
766 }
767 }
768
769 770 771 772 773 774 775
776 function edd_set_cart_discount( $code = '' ) {
777
778 $discounts = false;
779
780 if ( $discounts ) {
781 $discounts[] = $code;
782 } else {
783 $discounts = array();
784 $discounts[] = $code;
785 }
786
787 setcookie( 'wordpress_edd_cart_discount', implode( '|', $discounts ), time() + 3600, COOKIEPATH, COOKIE_DOMAIN, false );
788
789 return $discounts;
790 }
791
792 793 794 795 796 797 798
799 function edd_unset_cart_discount( $code = '' ) {
800 $discounts = edd_get_cart_discounts();
801
802 if ( $discounts ) {
803 $key = array_search( $code, $discounts );
804 unset( $discounts[ $key ] );
805 $discounts = implode( '|', array_values( $discounts ) );
806
807 setcookie( 'wordpress_edd_cart_discount', $discounts, time()+3600, COOKIEPATH, COOKIE_DOMAIN, false );
808 }
809
810 return $discounts;
811 }
812
813 814 815 816 817 818
819 function edd_unset_all_cart_discounts() {
820 @setcookie( 'wordpress_edd_cart_discount', null, strtotime( '-1 day' ), COOKIEPATH, COOKIE_DOMAIN, false );
821 }
822
823 824 825 826 827 828
829 function edd_get_cart_discounts() {
830 $discounts = isset( $_COOKIE['wordpress_edd_cart_discount'] ) ? explode( '|', $_COOKIE['wordpress_edd_cart_discount'] ) : false;
831 return $discounts;
832 }
833
834 835 836 837 838 839
840 function edd_cart_has_discounts() {
841 $ret = false;
842
843 if ( edd_get_cart_discounts() )
844 $ret = true;
845
846 return apply_filters( 'edd_cart_has_discounts', $ret );
847 }
848
849 850 851 852 853 854 855
856 function edd_get_cart_discounted_amount( $discounts = false ) {
857 if ( empty( $discounts ) )
858 $discounts = edd_get_cart_discounts();
859
860
861 if ( ! empty( $_POST['edd-discount'] ) && empty( $discounts ) ) {
862
863 $posted_discount = isset( $_POST['edd-discount'] ) ? trim( $_POST['edd-discount'] ) : false;
864
865 if ( $posted_discount ) {
866 $discounts = array();
867 $discounts[] = $posted_discount;
868 }
869 }
870
871
872 if ( empty( $discounts ) )
873 return 0.00;
874
875 $subtotal = edd_get_cart_subtotal( $tax = false );
876 $amounts = array();
877 $discounted_items = array();
878 foreach ( $discounts as $discount ) {
879 $code_id = edd_get_discount_id_by_code( $discount );
880 $reqs = edd_get_discount_product_reqs( $code_id );
881
882
883 if ( ! empty( $reqs ) && edd_is_discount_not_global( $code_id ) ) {
884
885
886 $condition = edd_get_discount_product_condition( $code_id );
887 $cart_items = edd_get_cart_contents();
888
889 foreach ( $reqs as $download_id ) {
890 if ( edd_item_in_cart( $download_id ) ) {
891 $cart_key = edd_get_item_position_in_cart( $download_id );
892 $price = edd_get_cart_item_price( $download_id, $cart_items[ $cart_key ]['options'] );
893 $amount = edd_get_discounted_amount( $discount, $price );
894 $discounted_items[] = $price - $amount;
895 }
896 }
897 } else {
898
899 $subtotal = edd_get_cart_subtotal();
900 $amount = edd_get_discounted_amount( $discount, $subtotal );
901 $amounts[] = $subtotal - $amount;
902 }
903 }
904
905
906 $discounted_amount = 0.00;
907 $item_discount = array_sum( $discounted_items );
908 $global_discount = array_sum( $amounts );
909 $discounted_amount += $item_discount;
910 $discounted_amount += $global_discount;
911
912 return apply_filters( 'edd_get_cart_discounted_amount', edd_sanitize_amount( $discounted_amount ) );
913 }
914
915 916 917 918 919 920
921 function edd_cart_discounts_html() {
922 echo edd_get_cart_discounts_html();
923 }
924
925 926 927 928 929 930
931 function edd_get_cart_discounts_html( $discounts = false ) {
932 if ( ! $discounts )
933 $discounts = edd_get_cart_discounts();
934
935 if ( ! $discounts )
936 return;
937
938 $html = '';
939
940 foreach ( $discounts as $discount ) {
941 $discount_id = edd_get_discount_id_by_code( $discount );
942 $rate = edd_format_discount_rate( edd_get_discount_type( $discount_id ), edd_get_discount_amount( $discount_id ) );
943
944 $remove_url = add_query_arg(
945 array(
946 'edd_action' => 'remove_cart_discount',
947 'discount_id' => $discount_id,
948 'discount_code' => $discount
949 ),
950 edd_get_checkout_uri()
951 );
952
953 $html .= "<span class=\"edd_discount\">\n";
954 $html .= "<span class=\"edd_discount_rate\">$discount – $rate</span>\n";
955 $html .= "<a href=\"$remove_url\" data-code=\"$discount\" class=\"edd_discount_remove\"></a>\n";
956 $html .= "</span>\n";
957 }
958
959 return apply_filters( 'edd_get_cart_discounts_html', $html, $discounts, $rate, $remove_url );
960 }
961
962 963 964 965 966 967 968 969
970 function edd_display_cart_discount( $formatted = false, $echo = false ) {
971 $discounts = edd_get_cart_discounts();
972
973 if ( empty( $discounts ) )
974 return false;
975
976 $discount_id = edd_get_discount_id_by_code( $discounts[0] );
977 $amount = edd_format_discount_rate( edd_get_discount_type( $discount_id ), edd_get_discount_amount( $discount_id ) );
978
979 if ( $echo )
980 echo $amount;
981
982 return $amount;
983 }
984
985 986 987 988 989 990
991 function edd_remove_cart_discount() {
992 if ( ! isset( $_GET['discount_id'] ) || ! isset( $_GET['discount_code'] ) )
993 return;
994
995 do_action( 'edd_pre_remove_cart_discount', absint( $_GET['discount_id'] ) );
996
997 edd_unset_cart_discount( urldecode( $_GET['discount_code'] ) );
998
999 do_action( 'edd_post_remove_cart_discount', absint( $_GET['discount_id'] ) );
1000
1001 wp_redirect( edd_get_checkout_uri() ); exit;
1002 }
1003 add_action( 'edd_remove_cart_discount', 'edd_remove_cart_discount' );