Passed
Pull Request — master (#250)
by
unknown
05:04
created

wpinv_get_all_discounts()   B

Complexity

Conditions 8
Paths 80

Size

Total Lines 74
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 50
c 0
b 0
f 0
nc 80
nop 1
dl 0
loc 74
rs 7.8464

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Contains functions related to Invoicing plugin.
4
 *
5
 * @since 1.0.0
6
 * @package Invoicing
7
 */
8
 
9
// MUST have WordPress.
10
if ( !defined( 'WPINC' ) ) {
11
    exit( 'Do NOT access this file directly: ' . basename( __FILE__ ) );
12
}
13
14
function wpinv_get_discount_types() {
15
    $discount_types = array(
16
                        'percent'   => __( 'Percentage', 'invoicing' ),
17
                        'flat'     => __( 'Flat Amount', 'invoicing' ),
18
                    );
19
    return (array)apply_filters( 'wpinv_discount_types', $discount_types );
20
}
21
22
function wpinv_get_discount_type_name( $type = '' ) {
23
    $types = wpinv_get_discount_types();
24
    return isset( $types[ $type ] ) ? $types[ $type ] : '';
25
}
26
27
function wpinv_delete_discount( $data ) {
28
    if ( ! isset( $data['_wpnonce'] ) || ! wp_verify_nonce( $data['_wpnonce'], 'wpinv_discount_nonce' ) ) {
29
        wp_die( __( 'Trying to cheat or something?', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
30
    }
31
32
    if( ! wpinv_current_user_can_manage_invoicing() ) {
33
        wp_die( __( 'You do not have permission to delete discount codes', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
34
    }
35
36
    $discount_id = $data['discount'];
37
    wpinv_remove_discount( $discount_id );
38
}
39
add_action( 'wpinv_delete_discount', 'wpinv_delete_discount' );
40
41
function wpinv_activate_discount( $data ) {
42
    if ( ! isset( $data['_wpnonce'] ) || ! wp_verify_nonce( $data['_wpnonce'], 'wpinv_discount_nonce' ) ) {
43
        wp_die( __( 'Trying to cheat or something?', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
44
    }
45
46
    if( ! wpinv_current_user_can_manage_invoicing() ) {
47
        wp_die( __( 'You do not have permission to edit discount codes', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
48
    }
49
50
    $id = absint( $data['discount'] );
51
    wpinv_update_discount_status( $id, 'publish' );
52
}
53
add_action( 'wpinv_activate_discount', 'wpinv_activate_discount' );
54
55
function wpinv_deactivate_discount( $data ) {
56
    if ( ! isset( $data['_wpnonce'] ) || ! wp_verify_nonce( $data['_wpnonce'], 'wpinv_discount_nonce' ) ) {
57
        wp_die( __( 'Trying to cheat or something?', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
58
    }
59
60
    if( ! wpinv_current_user_can_manage_invoicing() ) {
61
        wp_die( __( 'You do not have permission to create discount codes', 'invoicing' ), array( 'response' => 403 ) );
0 ignored issues
show
Bug introduced by
array('response' => 403) of type array<string,integer> is incompatible with the type integer|string expected by parameter $title of wp_die(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
        wp_die( __( 'You do not have permission to create discount codes', 'invoicing' ), /** @scrutinizer ignore-type */ array( 'response' => 403 ) );
Loading history...
62
    }
63
64
    $id = absint( $data['discount'] );
65
    wpinv_update_discount_status( $id, 'pending' );
66
}
67
add_action( 'wpinv_deactivate_discount', 'wpinv_deactivate_discount' );
68
69
function wpinv_get_discounts( $args = array() ) {
70
    $defaults = array(
71
        'post_type'      => 'wpi_discount',
72
        'posts_per_page' => 20,
73
        'paged'          => null,
74
        'post_status'    => array( 'publish', 'pending', 'draft', 'expired' )
75
    );
76
77
    $args = wp_parse_args( $args, $defaults );
78
79
    $discounts = get_posts( $args );
80
81
    if ( $discounts ) {
82
        return $discounts;
83
    }
84
85
    if( ! $discounts && ! empty( $args['s'] ) ) {
86
        $args['meta_key']     = '_wpi_discount_code';
87
        $args['meta_value']   = $args['s'];
88
        $args['meta_compare'] = 'LIKE';
89
        unset( $args['s'] );
90
        $discounts = get_posts( $args );
91
    }
92
93
    if( $discounts ) {
94
        return $discounts;
95
    }
96
97
    return false;
98
}
99
100
function wpinv_get_all_discounts( $args = array() ) {
101
102
    $args = wp_parse_args( $args, array(
103
        'status'         => array( 'publish' ),
104
        'limit'          => get_option( 'posts_per_page' ),
105
        'page'           => 1,
106
        'exclude'        => array(),
107
        'orderby'        => 'date',
108
        'order'          => 'DESC',
109
        'type'           => array_keys( wpinv_get_discount_types() ),
110
        'meta_query'     => array(),
111
        'return'         => 'objects',
112
        'paginate'       => false,
113
    ) );
114
115
    $wp_query_args = array(
116
        'post_type'      => 'wpi_discount',
117
        'post_status'    => $args['status'],
118
        'posts_per_page' => $args['limit'],
119
        'meta_query'     => $args['meta_query'],
120
        'fields'         => 'ids',
121
        'orderby'        => $args['orderby'],
122
        'order'          => $args['order'],
123
        'paged'          => absint( $args['page'] ),
124
    );
125
126
    if ( ! empty( $args['exclude'] ) ) {
127
        $wp_query_args['post__not_in'] = array_map( 'absint', $args['exclude'] );
128
    }
129
130
    if ( ! $args['paginate' ] ) {
131
        $wp_query_args['no_found_rows'] = true;
132
    }
133
134
    if ( ! empty( $args['search'] ) ) {
135
136
        $wp_query_args['meta_query'][] = array(
137
            'key'     => '_wpi_discount_code',
138
            'value'   => $args['search'],
139
            'compare' => 'LIKE',
140
        );
141
142
    }
143
    
144
    if ( ! empty( $args['type'] ) ) {
145
        $types = wpinv_parse_list( $args['type'] );
146
        $wp_query_args['meta_query'][] = array(
147
            'key'     => '_wpi_discount_type',
148
            'value'   => implode( ',', $types ),
149
            'compare' => 'IN',
150
        );
151
    }
152
153
    $wp_query_args = apply_filters('wpinv_get_discount_args', $wp_query_args, $args);
154
155
    // Get results.
156
    $discounts = new WP_Query( $wp_query_args );
157
158
    if ( 'objects' === $args['return'] ) {
159
        $return = array_map( 'get_post', $discounts->posts );
160
    } elseif ( 'self' === $args['return'] ) {
161
        return $discounts;
162
    } else {
163
        $return = $discounts->posts;
164
    }
165
166
    if ( $args['paginate' ] ) {
167
        return (object) array(
168
            'discounts'      => $return,
169
            'total'         => $discounts->found_posts,
170
            'max_num_pages' => $discounts->max_num_pages,
171
        );
172
    } else {
173
        return $return;
174
    }
175
176
}
177
178
function wpinv_has_active_discounts() {
179
    $has_active = false;
180
181
    $discounts  = wpinv_get_discounts();
182
183
    if ( $discounts) {
184
        foreach ( $discounts as $discount ) {
185
            if ( wpinv_is_discount_active( $discount->ID ) ) {
186
                $has_active = true;
187
                break;
188
            }
189
        }
190
    }
191
    return $has_active;
192
}
193
194
function wpinv_get_discount( $discount_id = 0 ) {
195
    if( empty( $discount_id ) ) {
196
        return false;
197
    }
198
    
199
    if ( get_post_type( $discount_id ) != 'wpi_discount' ) {
200
        return false;
201
    }
202
203
    $discount = get_post( $discount_id );
204
205
    return $discount;
206
}
207
208
function wpinv_get_discount_by_code( $code = '' ) {
209
    if( empty( $code ) || ! is_string( $code ) ) {
210
        return false;
211
    }
212
213
    return wpinv_get_discount_by( 'code', $code );
214
}
215
216
function wpinv_get_discount_by( $field = '', $value = '' ) {
217
    if( empty( $field ) || empty( $value ) ) {
218
        return false;
219
    }
220
221
    if( ! is_string( $field ) ) {
222
        return false;
223
    }
224
225
    switch( strtolower( $field ) ) {
226
227
        case 'code':
228
            $meta_query     = array();
229
            $meta_query[]   = array(
230
                'key'     => '_wpi_discount_code',
231
                'value'   => $value,
232
                'compare' => '='
233
            );
234
            
235
            $discount = wpinv_get_discounts( array(
236
                'posts_per_page' => 1,
237
                'post_status'    => 'any',
238
                'meta_query'     => $meta_query,
239
            ) );
240
            
241
            if( $discount ) {
242
                $discount = $discount[0];
243
            }
244
245
            break;
246
247
        case 'id':
248
            $discount = wpinv_get_discount( $value );
249
250
            break;
251
252
        case 'name':
253
            $discount = get_posts( array(
254
                'post_type'      => 'wpi_discount',
255
                'name'           => $value,
256
                'posts_per_page' => 1,
257
                'post_status'    => 'any'
258
            ) );
259
260
            if( $discount ) {
261
                $discount = $discount[0];
262
            }
263
264
            break;
265
266
        default:
267
            return false;
268
    }
269
270
    if( ! empty( $discount ) ) {
271
        return $discount;
272
    }
273
274
    return false;
275
}
276
277
function wpinv_store_discount( $post_id, $data, $post, $update = false ) {
278
    $meta = array(
279
        'code'              => isset( $data['code'] )             ? sanitize_text_field( $data['code'] )              : '',
280
        'type'              => isset( $data['type'] )             ? sanitize_text_field( $data['type'] )              : 'percent',
281
        'amount'            => isset( $data['amount'] )           ? wpinv_sanitize_amount( $data['amount'] )          : '',
282
        'start'             => isset( $data['start'] )            ? sanitize_text_field( $data['start'] )             : '',
283
        'expiration'        => isset( $data['expiration'] )       ? sanitize_text_field( $data['expiration'] )        : '',
284
        'min_total'         => isset( $data['min_total'] )        ? wpinv_sanitize_amount( $data['min_total'] )       : '',
285
        'max_total'         => isset( $data['max_total'] )        ? wpinv_sanitize_amount( $data['max_total'] )       : '',
286
        'max_uses'          => isset( $data['max_uses'] )         ? absint( $data['max_uses'] )                       : '',
287
        'items'             => isset( $data['items'] )            ? $data['items']                                    : array(),
288
        'excluded_items'    => isset( $data['excluded_items'] )   ? $data['excluded_items']                           : array(),
289
        'is_recurring'      => isset( $data['recurring'] )        ? (bool)$data['recurring']                          : false,
290
        'is_single_use'     => isset( $data['single_use'] )       ? (bool)$data['single_use']                         : false,
291
        'uses'              => isset( $data['uses'] )             ? (int)$data['uses']                                : false,
292
    );
293
294
    if ( $meta['type'] == 'percent' && (float)$meta['amount'] > 100 ) {
295
        $meta['amount'] = 100;
296
    }
297
298
    if ( !empty( $meta['start'] ) ) {
299
        $meta['start']      = date_i18n( 'Y-m-d H:i:s', strtotime( $meta['start'] ) );
300
    }
301
302
    if ( !empty( $meta['expiration'] ) ) {
303
        $meta['expiration'] = date_i18n( 'Y-m-d H:i:s', strtotime( $meta['expiration'] ) );
304
305
        if ( !empty( $meta['start'] ) && strtotime( $meta['start'] ) > strtotime( $meta['expiration'] ) ) {
306
            $meta['expiration'] = $meta['start'];
307
        }
308
    }
309
    
310
    if ( $meta['uses'] === false ) {
311
        unset( $meta['uses'] );
312
    }
313
    
314
    if ( ! empty( $meta['items'] ) ) {
315
        foreach ( $meta['items'] as $key => $item ) {
316
            if ( 0 === intval( $item ) ) {
317
                unset( $meta['items'][ $key ] );
318
            }
319
        }
320
    }
321
    
322
    if ( ! empty( $meta['excluded_items'] ) ) {
323
        foreach ( $meta['excluded_items'] as $key => $item ) {
324
            if ( 0 === intval( $item ) ) {
325
                unset( $meta['excluded_items'][ $key ] );
326
            }
327
        }
328
    }
329
    
330
    $meta = apply_filters( 'wpinv_update_discount', $meta, $post_id, $post );
331
    
332
    do_action( 'wpinv_pre_update_discount', $meta, $post_id, $post );
333
    
334
    foreach( $meta as $key => $value ) {
335
        update_post_meta( $post_id, '_wpi_discount_' . $key, $value );
336
    }
337
    
338
    do_action( 'wpinv_post_update_discount', $meta, $post_id, $post );
339
    
340
    return $post_id;
341
}
342
343
function wpinv_remove_discount( $discount_id = 0 ) {
344
    do_action( 'wpinv_pre_delete_discount', $discount_id );
345
346
    wp_delete_post( $discount_id, true );
347
348
    do_action( 'wpinv_post_delete_discount', $discount_id );
349
}
350
351
function wpinv_update_discount_status( $code_id = 0, $new_status = 'publish' ) {
352
    $discount = wpinv_get_discount(  $code_id );
353
354
    if ( $discount ) {
355
        do_action( 'wpinv_pre_update_discount_status', $code_id, $new_status, $discount->post_status );
356
357
        wp_update_post( array( 'ID' => $code_id, 'post_status' => $new_status ) );
358
359
        do_action( 'wpinv_post_update_discount_status', $code_id, $new_status, $discount->post_status );
360
361
        return true;
362
    }
363
364
    return false;
365
}
366
367
function wpinv_discount_exists( $code_id ) {
368
    if ( wpinv_get_discount(  $code_id ) ) {
369
        return true;
370
    }
371
372
    return false;
373
}
374
375
function wpinv_is_discount_active( $code_id = null ) {
376
    $discount = wpinv_get_discount(  $code_id );
377
    $return   = false;
378
379
    if ( $discount ) {
380
        if ( wpinv_is_discount_expired( $code_id ) ) {
381
            if( defined( 'DOING_AJAX' ) ) {
382
                wpinv_set_error( 'wpinv-discount-error', __( 'This discount is expired.', 'invoicing' ) );
383
            }
384
        } elseif ( $discount->post_status == 'publish' ) {
385
            $return = true;
386
        } else {
387
            if( defined( 'DOING_AJAX' ) ) {
388
                wpinv_set_error( 'wpinv-discount-error', __( 'This discount is not active.', 'invoicing' ) );
389
            }
390
        }
391
    }
392
393
    return apply_filters( 'wpinv_is_discount_active', $return, $code_id );
394
}
395
396
function wpinv_get_discount_code( $code_id = null ) {
397
    $code = get_post_meta( $code_id, '_wpi_discount_code', true );
398
399
    return apply_filters( 'wpinv_get_discount_code', $code, $code_id );
400
}
401
402
function wpinv_get_discount_start_date( $code_id = null ) {
403
    $start_date = get_post_meta( $code_id, '_wpi_discount_start', true );
404
405
    return apply_filters( 'wpinv_get_discount_start_date', $start_date, $code_id );
406
}
407
408
function wpinv_get_discount_expiration( $code_id = null ) {
409
    $expiration = get_post_meta( $code_id, '_wpi_discount_expiration', true );
410
411
    return apply_filters( 'wpinv_get_discount_expiration', $expiration, $code_id );
412
}
413
414
function wpinv_get_discount_max_uses( $code_id = null ) {
415
    $max_uses = get_post_meta( $code_id, '_wpi_discount_max_uses', true );
416
417
    return (int) apply_filters( 'wpinv_get_discount_max_uses', $max_uses, $code_id );
418
}
419
420
function wpinv_get_discount_uses( $code_id = null ) {
421
    $uses = get_post_meta( $code_id, '_wpi_discount_uses', true );
422
423
    return (int) apply_filters( 'wpinv_get_discount_uses', $uses, $code_id );
424
}
425
426
function wpinv_get_discount_min_total( $code_id = null ) {
427
    $min_total = get_post_meta( $code_id, '_wpi_discount_min_total', true );
428
429
    return (float) apply_filters( 'wpinv_get_discount_min_total', $min_total, $code_id );
430
}
431
432
function wpinv_get_discount_max_total( $code_id = null ) {
433
    $max_total = get_post_meta( $code_id, '_wpi_discount_max_total', true );
434
435
    return (float) apply_filters( 'wpinv_get_discount_max_total', $max_total, $code_id );
436
}
437
438
function wpinv_get_discount_amount( $code_id = null ) {
439
    $amount = get_post_meta( $code_id, '_wpi_discount_amount', true );
440
441
    return (float) apply_filters( 'wpinv_get_discount_amount', $amount, $code_id );
442
}
443
444
function wpinv_get_discount_type( $code_id = null, $name = false ) {
445
    $type = strtolower( get_post_meta( $code_id, '_wpi_discount_type', true ) );
0 ignored issues
show
Bug introduced by
It seems like get_post_meta($code_id, ...i_discount_type', true) can also be of type false; however, parameter $str of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

445
    $type = strtolower( /** @scrutinizer ignore-type */ get_post_meta( $code_id, '_wpi_discount_type', true ) );
Loading history...
446
    
447
    if ( $name ) {
448
        $name = wpinv_get_discount_type_name( $type );
449
        
450
        return apply_filters( 'wpinv_get_discount_type_name', $name, $code_id );
451
    }
452
453
    return apply_filters( 'wpinv_get_discount_type', $type, $code_id );
454
}
455
456
function wpinv_discount_status( $status ) {
457
    switch( $status ){
458
        case 'expired' :
459
            $name = __( 'Expired', 'invoicing' );
460
            break;
461
        case 'publish' :
462
        case 'active' :
463
            $name = __( 'Active', 'invoicing' );
464
            break;
465
        default :
466
            $name = __( 'Inactive', 'invoicing' );
467
            break;
468
    }
469
    return $name;
470
}
471
472
function wpinv_get_discount_excluded_items( $code_id = null ) {
473
    $excluded_items = get_post_meta( $code_id, '_wpi_discount_excluded_items', true );
474
475
    if ( empty( $excluded_items ) || ! is_array( $excluded_items ) ) {
476
        $excluded_items = array();
477
    }
478
479
    return (array) apply_filters( 'wpinv_get_discount_excluded_items', $excluded_items, $code_id );
480
}
481
482
function wpinv_get_discount_item_reqs( $code_id = null ) {
483
    $item_reqs = get_post_meta( $code_id, '_wpi_discount_items', true );
484
485
    if ( empty( $item_reqs ) || ! is_array( $item_reqs ) ) {
486
        $item_reqs = array();
487
    }
488
489
    return (array) apply_filters( 'wpinv_get_discount_item_reqs', $item_reqs, $code_id );
490
}
491
492
function wpinv_get_discount_item_condition( $code_id = 0 ) {
493
    return get_post_meta( $code_id, '_wpi_discount_item_condition', true );
494
}
495
496
function wpinv_is_discount_not_global( $code_id = 0 ) {
497
    return (bool) get_post_meta( $code_id, '_wpi_discount_is_not_global', true );
498
}
499
500
function wpinv_is_discount_expired( $code_id = null ) {
501
    $discount = wpinv_get_discount(  $code_id );
502
    $return   = false;
503
504
    if ( $discount ) {
505
        $expiration = wpinv_get_discount_expiration( $code_id );
506
        if ( $expiration ) {
507
            $expiration = strtotime( $expiration );
508
            if ( $expiration < current_time( 'timestamp' ) ) {
509
                // Discount is expired
510
                wpinv_update_discount_status( $code_id, 'pending' );
511
                $return = true;
512
            }
513
        }
514
    }
515
516
    return apply_filters( 'wpinv_is_discount_expired', $return, $code_id );
517
}
518
519
function wpinv_is_discount_started( $code_id = null ) {
520
    $discount = wpinv_get_discount(  $code_id );
521
    $return   = false;
522
523
    if ( $discount ) {
524
        $start_date = wpinv_get_discount_start_date( $code_id );
525
526
        if ( $start_date ) {
527
            $start_date = strtotime( $start_date );
528
529
            if ( $start_date < current_time( 'timestamp' ) ) {
530
                // Discount has past the start date
531
                $return = true;
532
            } else {
533
                wpinv_set_error( 'wpinv-discount-error', __( 'This discount is not active yet.', 'invoicing' ) );
534
            }
535
        } else {
536
            // No start date for this discount, so has to be true
537
            $return = true;
538
        }
539
    }
540
541
    return apply_filters( 'wpinv_is_discount_started', $return, $code_id );
542
}
543
544
function wpinv_check_discount_dates( $code_id = null ) {
545
    $discount = wpinv_get_discount(  $code_id );
546
    $return   = false;
547
548
    if ( $discount ) {
549
        $start_date = wpinv_get_discount_start_date( $code_id );
550
551
        if ( $start_date ) {
552
            $start_date = strtotime( $start_date );
553
554
            if ( $start_date < current_time( 'timestamp' ) ) {
555
                // Discount has past the start date
556
                $return = true;
557
            } else {
558
                wpinv_set_error( 'wpinv-discount-error', __( 'This discount is not active yet.', 'invoicing' ) );
559
            }
560
        } else {
561
            // No start date for this discount, so has to be true
562
            $return = true;
563
        }
564
        
565
        if ( $return ) {
566
            $expiration = wpinv_get_discount_expiration( $code_id );
567
            
568
            if ( $expiration ) {
569
                $expiration = strtotime( $expiration );
570
                if ( $expiration < current_time( 'timestamp' ) ) {
571
                    // Discount is expired
572
                    wpinv_update_discount_status( $code_id, 'pending' );
573
                    $return = true;
574
                }
575
            }
576
        }
577
    }
578
    
579
    return apply_filters( 'wpinv_check_discount_dates', $return, $code_id );
580
}
581
582
function wpinv_is_discount_maxed_out( $code_id = null ) {
583
    $discount = wpinv_get_discount(  $code_id );
584
    $return   = false;
585
586
    if ( $discount ) {
587
        $uses = wpinv_get_discount_uses( $code_id );
588
        // Large number that will never be reached
589
        $max_uses = wpinv_get_discount_max_uses( $code_id );
590
        // Should never be greater than, but just in case
591
        if ( $uses >= $max_uses && ! empty( $max_uses ) ) {
592
            // Discount is maxed out
593
            wpinv_set_error( 'wpinv-discount-error', __( 'This discount has reached its maximum usage.', 'invoicing' ) );
594
            $return = true;
595
        }
596
    }
597
598
    return apply_filters( 'wpinv_is_discount_maxed_out', $return, $code_id );
599
}
600
601
function wpinv_discount_is_min_met( $code_id = null ) {
602
    $discount = wpinv_get_discount( $code_id );
603
    $return   = false;
604
605
    if ( $discount ) {
606
        $min         = (float)wpinv_get_discount_min_total( $code_id );
607
        $cart_amount = (float)wpinv_get_cart_discountable_subtotal( $code_id );
608
609
        if ( !$min > 0 || $cart_amount >= $min ) {
610
            // Minimum has been met
611
            $return = true;
612
        } else {
613
            wpinv_set_error( 'wpinv-discount-error', sprintf( __( 'Minimum invoice amount should be %s', 'invoicing' ), wpinv_price( wpinv_format_amount( $min ) ) ) );
614
        }
615
    }
616
617
    return apply_filters( 'wpinv_is_discount_min_met', $return, $code_id );
618
}
619
620
function wpinv_discount_is_max_met( $code_id = null ) {
621
    $discount = wpinv_get_discount( $code_id );
622
    $return   = false;
623
624
    if ( $discount ) {
625
        $max         = (float)wpinv_get_discount_max_total( $code_id );
626
        $cart_amount = (float)wpinv_get_cart_discountable_subtotal( $code_id );
627
628
        if ( !$max > 0 || $cart_amount <= $max ) {
629
            // Minimum has been met
630
            $return = true;
631
        } else {
632
            wpinv_set_error( 'wpinv-discount-error', sprintf( __( 'Maximum invoice amount should be %s', 'invoicing' ), wpinv_price( wpinv_format_amount( $max ) ) ) );
633
        }
634
    }
635
636
    return apply_filters( 'wpinv_is_discount_max_met', $return, $code_id );
637
}
638
639
function wpinv_discount_is_single_use( $code_id = 0 ) {
640
    $single_use = get_post_meta( $code_id, '_wpi_discount_is_single_use', true );
641
    return (bool) apply_filters( 'wpinv_is_discount_single_use', $single_use, $code_id );
642
}
643
644
function wpinv_discount_is_recurring( $code_id = 0, $code = false ) {
645
    if ( $code ) {
646
        $discount = wpinv_get_discount_by_code( $code_id );
647
        
648
        if ( !empty( $discount ) ) {
649
            $code_id = $discount->ID;
650
        }
651
    }
652
    
653
    $recurring = get_post_meta( $code_id, '_wpi_discount_is_recurring', true );
654
    
655
    return (bool) apply_filters( 'wpinv_is_discount_recurring', $recurring, $code_id, $code );
656
}
657
658
function wpinv_discount_item_reqs_met( $code_id = null ) {
659
    $item_reqs    = wpinv_get_discount_item_reqs( $code_id );
660
    $condition    = wpinv_get_discount_item_condition( $code_id );
661
    $excluded_ps  = wpinv_get_discount_excluded_items( $code_id );
662
    $cart_items   = wpinv_get_cart_contents();
663
    $cart_ids     = $cart_items ? wp_list_pluck( $cart_items, 'id' ) : null;
664
    $ret          = false;
665
666
    if ( empty( $item_reqs ) && empty( $excluded_ps ) ) {
667
        $ret = true;
668
    }
669
670
    // Normalize our data for item requirements, exclusions and cart data
671
    // First absint the items, then sort, and reset the array keys
672
    $item_reqs = array_map( 'absint', $item_reqs );
673
    asort( $item_reqs );
674
    $item_reqs = array_values( $item_reqs );
675
676
    $excluded_ps  = array_map( 'absint', $excluded_ps );
677
    asort( $excluded_ps );
678
    $excluded_ps  = array_values( $excluded_ps );
679
680
    $cart_ids     = array_map( 'absint', $cart_ids );
0 ignored issues
show
Bug introduced by
It seems like $cart_ids can also be of type null; however, parameter $arr1 of array_map() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

680
    $cart_ids     = array_map( 'absint', /** @scrutinizer ignore-type */ $cart_ids );
Loading history...
681
    asort( $cart_ids );
682
    $cart_ids     = array_values( $cart_ids );
683
684
    // Ensure we have requirements before proceeding
685
    if ( !$ret && ! empty( $item_reqs ) ) {
686
        switch( $condition ) {
687
            case 'all' :
688
                // Default back to true
689
                $ret = true;
690
691
                foreach ( $item_reqs as $item_id ) {
692
                    if ( !wpinv_item_in_cart( $item_id ) ) {
693
                        wpinv_set_error( 'wpinv-discount-error', __( 'The item requirements for this discount are not met.', 'invoicing' ) );
694
                        $ret = false;
695
                        break;
696
                    }
697
                }
698
699
                break;
700
701
            default : // Any
702
                foreach ( $item_reqs as $item_id ) {
703
                    if ( wpinv_item_in_cart( $item_id ) ) {
704
                        $ret = true;
705
                        break;
706
                    }
707
                }
708
709
                if( ! $ret ) {
710
                    wpinv_set_error( 'wpinv-discount-error', __( 'The item requirements for this discount are not met.', 'invoicing' ) );
711
                }
712
713
                break;
714
        }
715
    } else {
716
        $ret = true;
717
    }
718
719
    if( ! empty( $excluded_ps ) ) {
720
        // Check that there are items other than excluded ones in the cart
721
        if( $cart_ids == $excluded_ps ) {
722
            wpinv_set_error( 'wpinv-discount-error', __( 'This discount is not valid for the cart contents.', 'invoicing' ) );
723
            $ret = false;
724
        }
725
    }
726
727
    return (bool) apply_filters( 'wpinv_is_discount_item_req_met', $ret, $code_id, $condition );
728
}
729
730
function wpinv_is_discount_used( $code = null, $user = '', $code_id = 0 ) {
731
    global $wpi_checkout_id;
732
    
733
    $return = false;
734
735
    if ( empty( $code_id ) ) {
736
        $code_id = wpinv_get_discount_id_by_code( $code );
737
        
738
        if( empty( $code_id ) ) {
739
            return false; // No discount was found
740
        }
741
    }
742
743
    if ( wpinv_discount_is_single_use( $code_id ) ) {
744
        $payments = array();
745
746
        $user_id = 0;
747
        if ( is_int( $user ) ) {
748
            $user_id = absint( $user );
749
        } else if ( is_email( $user ) && $user_data = get_user_by( 'email', $user ) ) {
750
            $user_id = $user_data->ID;
751
        } else if ( $user_data = get_user_by( 'login', $user ) ) {
752
            $user_id = $user_data->ID;
753
        } else if ( absint( $user ) > 0 ) {
754
            $user_id = absint( $user );
755
        }
756
757
        if ( !empty( $user_id ) ) {
758
            $query    = array( 'user' => $user_id, 'limit' => false );
759
            $payments = wpinv_get_invoices( $query ); // Get all payments with matching user id
760
        }
761
762
        if ( $payments ) {
763
            foreach ( $payments as $payment ) {
764
                // Don't count discount used for current invoice chekcout.
765
                if ( !empty( $wpi_checkout_id ) && $wpi_checkout_id == $payment->ID ) {
766
                    continue;
767
                }
768
                
769
                if ( $payment->has_status( array( 'wpi-cancelled', 'wpi-failed' ) ) ) {
770
                    continue;
771
                }
772
773
                $discounts = $payment->get_discounts( true );
774
                if ( empty( $discounts ) ) {
775
                    continue;
776
                }
777
778
                $discounts = $discounts && !is_array( $discounts ) ? explode( ',', $discounts ) : $discounts;
779
780
                if ( !empty( $discounts ) && is_array( $discounts ) ) {
781
                    if ( in_array( strtolower( $code ), array_map( 'strtolower', $discounts ) ) ) {
782
                        wpinv_set_error( 'wpinv-discount-error', __( 'This discount has already been redeemed.', 'invoicing' ) );
783
                        $return = true;
784
                        break;
785
                    }
786
                }
787
            }
788
        }
789
    }
790
791
    return apply_filters( 'wpinv_is_discount_used', $return, $code, $user );
792
}
793
794
function wpinv_is_discount_valid( $code = '', $user = '', $set_error = true ) {
795
    $return      = false;
796
    $discount_id = wpinv_get_discount_id_by_code( $code );
797
    $user        = trim( $user );
798
799
    if ( wpinv_get_cart_contents() ) {
800
        if ( $discount_id ) {
801
            if (
802
                wpinv_is_discount_active( $discount_id ) &&
803
                wpinv_check_discount_dates( $discount_id ) &&
804
                !wpinv_is_discount_maxed_out( $discount_id ) &&
805
                !wpinv_is_discount_used( $code, $user, $discount_id ) &&
806
                wpinv_discount_is_min_met( $discount_id ) &&
807
                wpinv_discount_is_max_met( $discount_id ) &&
808
                wpinv_discount_item_reqs_met( $discount_id )
809
            ) {
810
                $return = true;
811
            }
812
        } elseif( $set_error ) {
813
            wpinv_set_error( 'wpinv-discount-error', __( 'This discount is invalid.', 'invoicing' ) );
814
        }
815
    }
816
817
    return apply_filters( 'wpinv_is_discount_valid', $return, $discount_id, $code, $user );
818
}
819
820
function wpinv_get_discount_id_by_code( $code ) {
821
    $discount = wpinv_get_discount_by_code( $code );
822
    if( $discount ) {
823
        return $discount->ID;
824
    }
825
    return false;
826
}
827
828
function wpinv_get_discounted_amount( $code, $base_price ) {
829
    $amount      = $base_price;
0 ignored issues
show
Unused Code introduced by
The assignment to $amount is dead and can be removed.
Loading history...
830
    $discount_id = wpinv_get_discount_id_by_code( $code );
831
832
    if( $discount_id ) {
833
        $type        = wpinv_get_discount_type( $discount_id );
834
        $rate        = wpinv_get_discount_amount( $discount_id );
835
836
        if ( $type == 'flat' ) {
837
            // Set amount
838
            $amount = $base_price - $rate;
839
            if ( $amount < 0 ) {
840
                $amount = 0;
841
            }
842
843
        } else {
844
            // Percentage discount
845
            $amount = $base_price - ( $base_price * ( $rate / 100 ) );
846
        }
847
848
    } else {
849
850
        $amount = $base_price;
851
852
    }
853
854
    return apply_filters( 'wpinv_discounted_amount', $amount );
855
}
856
857
function wpinv_increase_discount_usage( $code ) {
858
859
    $id   = wpinv_get_discount_id_by_code( $code );
860
    $uses = wpinv_get_discount_uses( $id );
861
862
    if ( $uses ) {
863
        $uses++;
864
    } else {
865
        $uses = 1;
866
    }
867
868
    update_post_meta( $id, '_wpi_discount_uses', $uses );
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type false; however, parameter $post_id of update_post_meta() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

868
    update_post_meta( /** @scrutinizer ignore-type */ $id, '_wpi_discount_uses', $uses );
Loading history...
869
870
    do_action( 'wpinv_discount_increase_use_count', $uses, $id, $code );
871
872
    return $uses;
873
874
}
875
876
function wpinv_decrease_discount_usage( $code ) {
877
878
    $id   = wpinv_get_discount_id_by_code( $code );
879
    $uses = wpinv_get_discount_uses( $id );
880
881
    if ( $uses ) {
882
        $uses--;
883
    }
884
885
    if ( $uses < 0 ) {
886
        $uses = 0;
887
    }
888
889
    update_post_meta( $id, '_wpi_discount_uses', $uses );
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type false; however, parameter $post_id of update_post_meta() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

889
    update_post_meta( /** @scrutinizer ignore-type */ $id, '_wpi_discount_uses', $uses );
Loading history...
890
891
    do_action( 'wpinv_discount_decrease_use_count', $uses, $id, $code );
892
893
    return $uses;
894
895
}
896
897
function wpinv_format_discount_rate( $type, $amount ) {
898
    if ( $type == 'flat' ) {
899
        return wpinv_price( wpinv_format_amount( $amount ) );
900
    } else {
901
        return $amount . '%';
902
    }
903
}
904
905
function wpinv_set_cart_discount( $code = '' ) {    
906
    if ( wpinv_multiple_discounts_allowed() ) {
907
        // Get all active cart discounts
908
        $discounts = wpinv_get_cart_discounts();
909
    } else {
910
        $discounts = false; // Only one discount allowed per purchase, so override any existing
911
    }
912
913
    if ( $discounts ) {
914
        $key = array_search( strtolower( $code ), array_map( 'strtolower', $discounts ) );
915
        if( false !== $key ) {
916
            unset( $discounts[ $key ] ); // Can't set the same discount more than once
917
        }
918
        $discounts[] = $code;
919
    } else {
920
        $discounts = array();
921
        $discounts[] = $code;
922
    }
923
    $discounts = array_values( $discounts );
924
    
925
    $data = wpinv_get_checkout_session();
926
    if ( empty( $data ) ) {
927
        $data = array();
928
    } else {
929
        if ( !empty( $data['invoice_id'] ) && $payment_meta = wpinv_get_invoice_meta( $data['invoice_id'] ) ) {
930
            $payment_meta['user_info']['discount']  = implode( ',', $discounts );
931
            update_post_meta( $data['invoice_id'], '_wpinv_payment_meta', $payment_meta );
932
        }
933
    }
934
    $data['cart_discounts'] = $discounts;
935
    
936
    wpinv_set_checkout_session( $data );
937
    
938
    return $discounts;
939
}
940
941
function wpinv_unset_cart_discount( $code = '' ) {    
942
    $discounts = wpinv_get_cart_discounts();
943
944
    if ( $code && !empty( $discounts ) && in_array( $code, $discounts ) ) {
945
        $key = array_search( $code, $discounts );
946
        unset( $discounts[ $key ] );
947
            
948
        $data = wpinv_get_checkout_session();
949
        $data['cart_discounts'] = $discounts;
950
        if ( !empty( $data['invoice_id'] ) && $payment_meta = wpinv_get_invoice_meta( $data['invoice_id'] ) ) {
951
            $payment_meta['user_info']['discount']  = !empty( $discounts ) ? implode( ',', $discounts ) : '';
952
            update_post_meta( $data['invoice_id'], '_wpinv_payment_meta', $payment_meta );
953
        }
954
        
955
        wpinv_set_checkout_session( $data );
956
    }
957
958
    return $discounts;
959
}
960
961
function wpinv_unset_all_cart_discounts() {
962
    $data = wpinv_get_checkout_session();
963
    
964
    if ( !empty( $data ) && isset( $data['cart_discounts'] ) ) {
965
        unset( $data['cart_discounts'] );
966
        
967
         wpinv_set_checkout_session( $data );
968
         return true;
969
    }
970
    
971
    return false;
972
}
973
974
function wpinv_get_cart_discounts( $items = array() ) {
975
    $session = wpinv_get_checkout_session();
976
    
977
    $discounts = !empty( $session['cart_discounts'] ) ? $session['cart_discounts'] : false;
978
    return $discounts;
979
}
980
981
function wpinv_cart_has_discounts( $items = array() ) {
982
    $ret = false;
983
984
    if ( wpinv_get_cart_discounts( $items ) ) {
985
        $ret = true;
986
    }
987
    
988
    /*
989
    $invoice = wpinv_get_invoice_cart();
990
    if ( !empty( $invoice ) && ( $invoice->get_discount() > 0 || $invoice->get_discount_code() ) ) {
991
        $ret = true;
992
    }
993
    */
994
995
    return apply_filters( 'wpinv_cart_has_discounts', $ret );
996
}
997
998
function wpinv_get_cart_discounted_amount( $items = array(), $discounts = false ) {
999
    $amount = 0.00;
1000
    $items  = !empty( $items ) ? $items : wpinv_get_cart_content_details();
1001
1002
    if ( $items ) {
1003
        $discounts = wp_list_pluck( $items, 'discount' );
1004
1005
        if ( is_array( $discounts ) ) {
0 ignored issues
show
introduced by
The condition is_array($discounts) is always true.
Loading history...
1006
            $discounts = array_map( 'floatval', $discounts );
1007
            $amount    = array_sum( $discounts );
1008
        }
1009
    }
1010
1011
    return apply_filters( 'wpinv_get_cart_discounted_amount', $amount );
1012
}
1013
1014
function wpinv_get_cart_items_discount_amount( $items = array(), $discount = false ) {
1015
    $items  = !empty( $items ) ? $items : wpinv_get_cart_content_details();
1016
    
1017
    if ( empty( $discount ) || empty( $items ) ) {
1018
        return 0;
1019
    }
1020
1021
    $amount = 0;
1022
    
1023
    foreach ( $items as $item ) {
1024
        $amount += wpinv_get_cart_item_discount_amount( $item, $discount );
1025
    }
1026
    
1027
    $amount = wpinv_round_amount( $amount );
1028
1029
    return $amount;
1030
}
1031
1032
function wpinv_get_cart_item_discount_amount( $item = array(), $discount = false ) {
1033
    global $wpinv_is_last_cart_item, $wpinv_flat_discount_total;
1034
    
1035
    $amount = 0;
1036
1037
    if ( empty( $item ) || empty( $item['id'] ) ) {
1038
        return $amount;
1039
    }
1040
1041
    if ( empty( $item['quantity'] ) ) {
1042
        return $amount;
1043
    }
1044
1045
    if ( empty( $item['options'] ) ) {
1046
        $item['options'] = array();
1047
    }
1048
1049
    $price            = wpinv_get_cart_item_price( $item['id'], $item, $item['options'] );
1050
    $discounted_price = $price;
1051
1052
    $discounts = false === $discount ? wpinv_get_cart_discounts() : $discount;
1053
    if ( empty( $discounts ) ) {
1054
        return $amount;
1055
    }
1056
1057
    if ( $discounts ) {
1058
        if ( is_array( $discounts ) ) {
1059
            $discounts = array_values( $discounts );
1060
        } else {
1061
            $discounts = explode( ',', $discounts );
1062
        }
1063
    }
1064
1065
    if( $discounts ) {
1066
        foreach ( $discounts as $discount ) {
1067
            $code_id = wpinv_get_discount_id_by_code( $discount );
1068
1069
            // Check discount exists
1070
            if( ! $code_id ) {
1071
                continue;
1072
            }
1073
1074
            $reqs           = wpinv_get_discount_item_reqs( $code_id );
1075
            $excluded_items = wpinv_get_discount_excluded_items( $code_id );
1076
1077
            // Make sure requirements are set and that this discount shouldn't apply to the whole cart
1078
            if ( !empty( $reqs ) && wpinv_is_discount_not_global( $code_id ) ) {
1079
                foreach ( $reqs as $item_id ) {
1080
                    if ( $item_id == $item['id'] && ! in_array( $item['id'], $excluded_items ) ) {
1081
                        $discounted_price -= $price - wpinv_get_discounted_amount( $discount, $price );
1082
                    }
1083
                }
1084
            } else {
1085
                // This is a global cart discount
1086
                if ( !in_array( $item['id'], $excluded_items ) ) {
1087
                    if ( 'flat' === wpinv_get_discount_type( $code_id ) ) {
1088
                        $items_subtotal    = 0.00;
1089
                        $cart_items        = wpinv_get_cart_contents();
1090
                        
1091
                        foreach ( $cart_items as $cart_item ) {
1092
                            if ( ! in_array( $cart_item['id'], $excluded_items ) ) {
1093
                                $options = !empty( $cart_item['options'] ) ? $cart_item['options'] : array();
1094
                                $item_price      = wpinv_get_cart_item_price( $cart_item['id'], $cart_item, $options );
1095
                                $items_subtotal += $item_price * $cart_item['quantity'];
1096
                            }
1097
                        }
1098
1099
                        $subtotal_percent  = ( ( $price * $item['quantity'] ) / $items_subtotal );
1100
                        $code_amount       = wpinv_get_discount_amount( $code_id );
1101
                        $discounted_amount = $code_amount * $subtotal_percent;
1102
                        $discounted_price -= $discounted_amount;
1103
1104
                        $wpinv_flat_discount_total += round( $discounted_amount, wpinv_currency_decimal_filter() );
1105
1106
                        if ( $wpinv_is_last_cart_item && $wpinv_flat_discount_total < $code_amount ) {
1107
                            $adjustment = $code_amount - $wpinv_flat_discount_total;
1108
                            $discounted_price -= $adjustment;
1109
                        }
1110
                    } else {
1111
                        $discounted_price -= $price - wpinv_get_discounted_amount( $discount, $price );
1112
                    }
1113
                }
1114
            }
1115
        }
1116
1117
        $amount = ( $price - apply_filters( 'wpinv_get_cart_item_discounted_amount', $discounted_price, $discounts, $item, $price ) );
1118
1119
        if ( 'flat' !== wpinv_get_discount_type( $code_id ) ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $code_id seems to be defined by a foreach iteration on line 1066. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
1120
            $amount = $amount * $item['quantity'];
1121
        }
1122
    }
1123
1124
    return $amount;
1125
}
1126
1127
function wpinv_cart_discounts_html( $items = array() ) {
1128
    echo wpinv_get_cart_discounts_html( $items );
1129
}
1130
1131
function wpinv_get_cart_discounts_html( $items = array(), $discounts = false ) {
1132
    global $wpi_cart_columns;
1133
    
1134
    $items  = !empty( $items ) ? $items : wpinv_get_cart_content_details();
1135
    
1136
    if ( !$discounts ) {
1137
        $discounts = wpinv_get_cart_discounts( $items );
1138
    }
1139
1140
    if ( !$discounts ) {
1141
        return;
1142
    }
1143
    
1144
    $discounts = is_array( $discounts ) ? $discounts : array( $discounts );
1145
    
1146
    $html = '';
1147
1148
    foreach ( $discounts as $discount ) {
1149
        $discount_id    = wpinv_get_discount_id_by_code( $discount );
1150
        $discount_value = wpinv_get_discount_amount( $discount_id );
1151
        $rate           = wpinv_format_discount_rate( wpinv_get_discount_type( $discount_id ), $discount_value );
1152
        $amount         = wpinv_get_cart_items_discount_amount( $items, $discount );
1153
        $remove_btn     = '<a title="' . esc_attr__( 'Remove discount', 'invoicing' ) . '" data-code="' . $discount . '" data-value="' . $discount_value . '" class="wpi-discount-remove" href="javascript:void(0);">[<i class="fa fa-times" aria-hidden="true"></i>]</a> ';
1154
        
1155
        $html .= '<tr class="wpinv_cart_footer_row wpinv_cart_discount_row">';
1156
        ob_start();
1157
        do_action( 'wpinv_checkout_table_discount_first', $items );
1158
        $html .= ob_get_clean();
1159
        $html .= '<td class="wpinv_cart_discount_label text-right" colspan="' . $wpi_cart_columns . '">' . $remove_btn . '<strong>' . wpinv_cart_discount_label( $discount, $rate, false ) . '</strong></td><td class="wpinv_cart_discount text-right"><span data-discount="' . $amount . '" class="wpinv_cart_discount_amount">&ndash;' . wpinv_price( wpinv_format_amount( $amount ) ) . '</span></td>';
1160
        ob_start();
1161
        do_action( 'wpinv_checkout_table_discount_last', $items );
1162
        $html .= ob_get_clean();
1163
        $html .= '</tr>';
1164
    }
1165
1166
    return apply_filters( 'wpinv_get_cart_discounts_html', $html, $discounts, $rate );
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $rate seems to be defined by a foreach iteration on line 1148. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
1167
}
1168
1169
function wpinv_display_cart_discount( $formatted = false, $echo = false ) {
1170
    $discounts = wpinv_get_cart_discounts();
1171
1172
    if ( empty( $discounts ) ) {
1173
        return false;
1174
    }
1175
1176
    $discount_id  = wpinv_get_discount_id_by_code( $discounts[0] );
1177
    $amount       = wpinv_format_discount_rate( wpinv_get_discount_type( $discount_id ), wpinv_get_discount_amount( $discount_id ) );
1178
1179
    if ( $echo ) {
1180
        echo $amount;
1181
    }
1182
1183
    return $amount;
1184
}
1185
1186
function wpinv_remove_cart_discount() {
1187
    if ( !isset( $_GET['discount_id'] ) || ! isset( $_GET['discount_code'] ) ) {
1188
        return;
1189
    }
1190
1191
    do_action( 'wpinv_pre_remove_cart_discount', absint( $_GET['discount_id'] ) );
1192
1193
    wpinv_unset_cart_discount( urldecode( $_GET['discount_code'] ) );
1194
1195
    do_action( 'wpinv_post_remove_cart_discount', absint( $_GET['discount_id'] ) );
1196
1197
    wp_redirect( wpinv_get_checkout_uri() ); wpinv_die();
0 ignored issues
show
Bug introduced by
It seems like wpinv_get_checkout_uri() can also be of type false; however, parameter $location of wp_redirect() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1197
    wp_redirect( /** @scrutinizer ignore-type */ wpinv_get_checkout_uri() ); wpinv_die();
Loading history...
1198
}
1199
add_action( 'wpinv_remove_cart_discount', 'wpinv_remove_cart_discount' );
1200
1201
function wpinv_maybe_remove_cart_discount( $cart_key = 0 ) {
1202
    $discounts = wpinv_get_cart_discounts();
1203
1204
    if ( !$discounts ) {
1205
        return;
1206
    }
1207
1208
    foreach ( $discounts as $discount ) {
1209
        if ( !wpinv_is_discount_valid( $discount ) ) {
1210
            wpinv_unset_cart_discount( $discount );
1211
        }
1212
    }
1213
}
1214
add_action( 'wpinv_post_remove_from_cart', 'wpinv_maybe_remove_cart_discount' );
1215
1216
function wpinv_multiple_discounts_allowed() {
1217
    $ret = wpinv_get_option( 'allow_multiple_discounts', false );
1218
    return (bool) apply_filters( 'wpinv_multiple_discounts_allowed', $ret );
1219
}
1220
1221
function wpinv_get_discount_label( $code, $echo = true ) {
1222
    $label = wp_sprintf( __( 'Discount%1$s', 'invoicing' ), ( $code != '' && $code != 'none' ? ' (<code>' . $code . '</code>)': '' ) );
1223
    $label = apply_filters( 'wpinv_get_discount_label', $label, $code );
1224
1225
    if ( $echo ) {
1226
        echo $label;
1227
    } else {
1228
        return $label;
1229
    }
1230
}
1231
1232
function wpinv_cart_discount_label( $code, $rate, $echo = true ) {
1233
    $label = wp_sprintf( __( 'Discount: %s', 'invoicing' ), $code );
1234
    $label = apply_filters( 'wpinv_cart_discount_label', $label, $code, $rate );
1235
1236
    if ( $echo ) {
1237
        echo $label;
1238
    } else {
1239
        return $label;
1240
    }
1241
}
1242
1243
function wpinv_check_delete_discount( $check, $post, $force_delete ) {
1244
    if ( $post->post_type == 'wpi_discount' && wpinv_get_discount_uses( $post->ID ) > 0 ) {
1245
        return true;
1246
    }
1247
    
1248
    return $check;
1249
}
1250
add_filter( 'pre_delete_post', 'wpinv_check_delete_discount', 10, 3 );
1251
1252
function wpinv_checkout_form_validate_discounts() {
1253
    global $wpi_checkout_id;
1254
    
1255
    $discounts = wpinv_get_cart_discounts();
1256
    
1257
    if ( !empty( $discounts ) ) {
1258
        $invalid = false;
1259
        
1260
        foreach ( $discounts as $key => $code ) {
1261
            if ( !wpinv_is_discount_valid( $code, (int)wpinv_get_user_id( $wpi_checkout_id ) ) ) {
1262
                $invalid = true;
1263
                
1264
                wpinv_unset_cart_discount( $code );
1265
            }
1266
        }
1267
        
1268
        if ( $invalid ) {
1269
            $errors = wpinv_get_errors();
1270
            $error  = !empty( $errors['wpinv-discount-error'] ) ? $errors['wpinv-discount-error'] . ' ' : '';
1271
            $error  .= __( 'The discount has been removed from cart.', 'invoicing' );
1272
            wpinv_set_error( 'wpinv-discount-error', $error );
1273
            
1274
            wpinv_recalculate_tax( true );
1275
        }
1276
    }
1277
}
1278
add_action( 'wpinv_before_checkout_form', 'wpinv_checkout_form_validate_discounts', -10 );
1279
1280
function wpinv_discount_amount() {
1281
    $output = 0.00;
1282
    
1283
    return apply_filters( 'wpinv_discount_amount', $output );
1284
}