Passed
Push — master ( 215c11...221553 )
by Brian
14:30
created

wpinv_item_max_buyable_quantity()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Contains item functions.
4
 *
5
 * @since 1.0.0
6
 * @package Invoicing
7
 */
8
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * Retrieves an item by it's ID.
13
 *
14
 * @param int the item ID to retrieve.
15
 * @return WPInv_Item|false
16
 */
17
function wpinv_get_item_by_id( $id ) {
18
    $item = wpinv_get_item( $id );
19
    return empty( $item ) || $id != $item->get_id() ? false : $item;
20
}
21
22
/**
23
 * Retrieves an item by it's ID, Name, Slug or custom id.
24
 *
25
 * @return WPInv_Item|false
26
 */
27
function wpinv_get_item_by( $field = '', $value = '', $type = '' ) {
28
29
    if ( 'id' == strtolower( $field ) ) {
30
        return wpinv_get_item_by_id( $field );
31
    }
32
33
    $id = WPInv_Item::get_item_id_by_field( $value, strtolower( $field ), $type );
34
    return empty( $id ) ? false : wpinv_get_item( $id );
35
36
}
37
38
/**
39
 * Retrieves an item by it's ID, name or custom_name.
40
 *
41
 * @param int|WPInv_Item the item to retrieve.
42
 * @return WPInv_Item|false
43
 */
44
function wpinv_get_item( $item = 0 ) {
45
46
    if ( empty( $item ) ) {
47
        return false;
48
    }
49
50
    $item = new WPInv_Item( $item );
51
    return $item->exists() ? $item : false;
52
53
}
54
55
function wpinv_get_all_items( $args = array() ) {
56
57
    $args = wp_parse_args( $args, array(
58
        'status'         => array( 'publish' ),
59
        'limit'          => get_option( 'posts_per_page' ),
60
        'page'           => 1,
61
        'exclude'        => array(),
62
        'orderby'        => 'date',
63
        'order'          => 'DESC',
64
        'type'           => wpinv_item_types(),
65
        'meta_query'     => array(),
66
        'return'         => 'objects',
67
        'paginate'       => false,
68
    ) );
69
70
    $wp_query_args = array(
71
        'post_type'      => 'wpi_item',
72
        'post_status'    => $args['status'],
73
        'posts_per_page' => $args['limit'],
74
        'meta_query'     => $args['meta_query'],
75
        'fields'         => 'ids',
76
        'orderby'        => $args['orderby'],
77
        'order'          => $args['order'],
78
        'paged'          => absint( $args['page'] ),
79
    );
80
81
    if ( ! empty( $args['exclude'] ) ) {
82
        $wp_query_args['post__not_in'] = array_map( 'absint', $args['exclude'] );
83
    }
84
85
    if ( ! $args['paginate' ] ) {
86
        $wp_query_args['no_found_rows'] = true;
87
    }
88
89
    if ( ! empty( $args['search'] ) ) {
90
        $wp_query_args['s'] = $args['search'];
91
    }
92
93
    if ( ! empty( $args['type'] ) && $args['type'] !== wpinv_item_types() ) {
94
        $types = wpinv_parse_list( $args['type'] );
95
        $wp_query_args['meta_query'][] = array(
96
            'key'     => '_wpinv_type',
97
            'value'   => implode( ',', $types ),
98
            'compare' => 'IN',
99
        );
100
    }
101
102
    $wp_query_args = apply_filters('wpinv_get_items_args', $wp_query_args, $args);
103
104
    // Get results.
105
    $items = new WP_Query( $wp_query_args );
106
107
    if ( 'objects' === $args['return'] ) {
108
        $return = array_map( 'wpinv_get_item_by_id', $items->posts );
109
    } elseif ( 'self' === $args['return'] ) {
110
        return $items;
111
    } else {
112
        $return = $items->posts;
113
    }
114
115
    if ( $args['paginate' ] ) {
116
        return (object) array(
117
            'items'      => $return,
118
            'total'         => $items->found_posts,
119
            'max_num_pages' => $items->max_num_pages,
120
        );
121
    } else {
122
        return $return;
123
    }
124
125
}
126
127
function wpinv_is_free_item( $item_id = 0 ) {
128
    if( empty( $item_id ) ) {
129
        return false;
130
    }
131
132
    $item = new WPInv_Item( $item_id );
133
134
    return $item->is_free();
135
}
136
137
/**
138
 * Checks whether an item is editable.
139
 *
140
 * @param WP_Post|WPInv_Item|Int $item The item to check for.
141
 */
142
function wpinv_item_is_editable( $item = 0 ) {
143
144
    // Fetch the item.
145
    $item = new WPInv_Item( $item );
146
147
    // Check if it is editable.
148
    return $item->is_editable();
149
}
150
151
function wpinv_get_item_price( $item_id = 0 ) {
152
    if( empty( $item_id ) ) {
153
        return false;
154
    }
155
156
    $item = new WPInv_Item( $item_id );
157
158
    return $item->get_price();
159
}
160
161
/**
162
 * Checks if the provided item is recurring.
163
 *
164
 * @param WPInv_Item|int $item
165
 */
166
function wpinv_is_recurring_item( $item = 0 ) {
167
    $item = new WPInv_Item( $item );
168
    return $item->is_recurring();
169
}
170
171
function wpinv_item_price( $item_id = 0 ) {
172
    if( empty( $item_id ) ) {
173
        return false;
174
    }
175
176
    $price = wpinv_get_item_price( $item_id );
177
    $price = wpinv_price( $price );
0 ignored issues
show
Bug introduced by
It seems like $price can also be of type false; however, parameter $amount of wpinv_price() does only seem to accept double, 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

177
    $price = wpinv_price( /** @scrutinizer ignore-type */ $price );
Loading history...
178
179
    return apply_filters( 'wpinv_item_price', $price, $item_id );
180
}
181
182
function wpinv_get_item_final_price( $item_id = 0, $amount_override = null ) {
183
    if ( is_null( $amount_override ) ) {
184
        $original_price = get_post_meta( $item_id, '_wpinv_price', true );
185
    } else {
186
        $original_price = $amount_override;
187
    }
188
189
    $price = $original_price;
190
191
    return apply_filters( 'wpinv_get_item_final_price', $price, $item_id );
192
}
193
194
function wpinv_item_custom_singular_name( $item_id ) {
195
    if( empty( $item_id ) ) {
196
        return false;
197
    }
198
199
    $item = new WPInv_Item( $item_id );
200
201
    return $item->get_custom_singular_name();
202
}
203
204
function wpinv_get_item_types() {
205
    $item_types = array(
206
            'custom'    => __( 'Standard', 'invoicing' ),
207
            'fee'       => __( 'Fee', 'invoicing' ),
208
        );
209
    return apply_filters( 'wpinv_get_item_types', $item_types );
210
}
211
212
function wpinv_item_types() {
213
    $item_types = wpinv_get_item_types();
214
215
    return ( !empty( $item_types ) ? array_keys( $item_types ) : array() );
216
}
217
218
function wpinv_get_item_type( $item_id ) {
219
    if( empty( $item_id ) ) {
220
        return false;
221
    }
222
223
    $item = new WPInv_Item( $item_id );
224
225
    return $item->get_type();
226
}
227
228
function wpinv_item_type( $item_id ) {
229
    $item_types = wpinv_get_item_types();
230
231
    $item_type = wpinv_get_item_type( $item_id );
232
233
    if ( empty( $item_type ) ) {
234
        $item_type = '-';
235
    }
236
237
    $item_type = isset( $item_types[$item_type] ) ? $item_types[$item_type] : __( $item_type, 'invoicing' );
238
239
    return apply_filters( 'wpinv_item_type', $item_type, $item_id );
240
}
241
242
function wpinv_get_random_item( $post_ids = true ) {
243
    wpinv_get_random_items( 1, $post_ids );
244
}
245
246
function wpinv_get_random_items( $num = 3, $post_ids = true ) {
247
    if ( $post_ids ) {
248
        $args = array( 'post_type' => 'wpi_item', 'orderby' => 'rand', 'post_count' => $num, 'fields' => 'ids' );
249
    } else {
250
        $args = array( 'post_type' => 'wpi_item', 'orderby' => 'rand', 'post_count' => $num );
251
    }
252
253
    $args  = apply_filters( 'wpinv_get_random_items', $args );
254
255
    return get_posts( $args );
256
}
257
258
/**
259
 * Adds additional information suffixes to an item name.
260
 *
261
 * @param WPInv_Item|int $item
262
 * @param bool $html
263
 */
264
function wpinv_get_item_suffix( $item, $html = true ) {
265
266
    $item   = new WPInv_Item( $item );
267
    $suffix = $item->is_recurring() ? ' ' . __( '(r)', 'invoicing' ) : '';
268
    $suffix = $html ? $suffix : strip_tags( $suffix );
269
270
    return apply_filters( 'wpinv_get_item_suffix', $suffix, $item, $html );
271
}
272
273
/**
274
 * Deletes an invoicing item.
275
 *
276
 * @param WPInv_Item|int $item
277
 * @param bool $force_delete
278
 */
279
function wpinv_remove_item( $item = 0, $force_delete = false ) {
280
    $item = new WPInv_Item( $item );
281
    $item->delete( $force_delete );
282
}
283
284
/**
285
 * Create/Update an item.
286
 *
287
 * @param array $args an array of arguments to create the item.
288
 *
289
 *    Here are all the args (with defaults) that you can set/modify.
290
 *    array(
291
 *		  'ID'                   => 0,           - If specified, the item with that ID will be updated.
292
 *        'parent_id'            => 0,           - Int. Parent item ID.
293
 *		  'status'               => 'draft',     - String. Item status - either draft, pending or publish.
294
 *		  'date_created'         => null,        - String. strtotime() compatible string.
295
 *        'date_modified'        => null,        - String. strtotime() compatible string.
296
 *        'name'                 => '',          - String. Required. Item name.
297
 *        'description'          => '',          - String. Item description.
298
 *        'author'               => 1,           - int. Owner of the item.
299
 *        'price'                => 0,           - float. Item price.
300
 *        'vat_rule'             => 'digital',   - string. VAT rule.
301
 *        'vat_class'            => '_standard', - string. VAT class.
302
 *        'type'                 => 'custom',    - string. Item type.
303
 *        'custom_id'            => null,        - string. Custom item id.
304
 *        'custom_name'          => null,        - string. Custom item name.
305
 *        'custom_singular_name' => null,        - string. Custom item singular name.
306
 *        'is_editable'          => 1,           - int|bool. Whether or not the item is editable.
307
 *        'is_dynamic_pricing'   => 0,           - int|bool. Whether or not users can update the item price.
308
 *        'minimum_price'        => 0,           - float. If dynamic, set the minimum price that a user can set..
309
 *        'is_recurring'         => 0,           - int|bool. Whether or not this item is recurring.
310
 *        'recurring_period'     => 'D',         - string. If recurring, set the recurring period as either days (D), weeks (W), months (M) or years (Y).
311
 *        'recurring_interval'   => 1,           - int. The recurring interval.
312
 *        'recurring_limit'      => 0,           - int. The recurring limit. Enter 0 for unlimited.
313
 *        'is_free_trial'        => false,       - int|bool. Whether or not this item has a free trial.
314
 *        'trial_period'         => 'D',         - string. If it has a free trial, set the trial period as either days (D), weeks (W), months (M) or years (Y).
315
 *        'trial_interval'       => 1,           - int. The trial interval.
316
 *    );
317
 * @param bool $wp_error whether or not to return a WP_Error on failure.
318
 * @return bool|WP_Error|WPInv_Item
319
 */
320
function wpinv_create_item( $args = array(), $wp_error = false ) {
321
322
    // Prepare the item.
323
    if ( ! empty( $args['custom_id'] ) && empty( $args['ID'] ) ) {
324
        $type = empty( $args['type'] ) ? 'custom' : $args['type'];
325
        $item = wpinv_get_item_by( 'custom_id', $args['custom_id'], $type );
326
327
        if ( ! empty( $item ) ) {
328
            $args['ID'] = $item->get_id();
329
        }
330
331
    }
332
333
    // Do we have an item?
334
    if ( ! empty( $args['ID'] ) ) {
335
        $item = new WPInv_Item( $args['ID'] );
336
    } else {
337
        $item = new WPInv_Item();
338
    }
339
340
    // Do we have an error?
341
    if ( ! empty( $item->last_error ) ) {
342
        return $wp_error ? new WP_Error( 'invalid_item', $item->last_error ) : false;
343
    }
344
345
    // Update item props.
346
    $item->set_props( $args );
347
348
    // Save the item.
349
    $item->save();
350
351
    // Do we have an error?
352
    if ( ! empty( $item->last_error ) ) {
353
        return $wp_error ? new WP_Error( 'not_saved', $item->last_error ) : false;
354
    }
355
356
    // Was the item saved?
357
    if ( ! $item->get_id() ) {
358
        return $wp_error ? new WP_Error( 'not_saved', __( 'An error occured while saving the item', 'invoicing' ) ) : false;
359
    }
360
361
    return $item;
362
363
}
364
365
/**
366
 * Updates an item.
367
 *
368
 * @see wpinv_create_item()
369
 */
370
function wpinv_update_item( $args = array(), $wp_error = false ) {
371
    return wpinv_create_item( $args, $wp_error );
372
}
373
374
/**
375
 * Sanitizes a recurring period
376
 */
377
function getpaid_sanitize_recurring_period( $period, $full = false ) {
378
379
    $periods = array(
380
        'D' => 'day',
381
        'W' => 'week',
382
        'M' => 'month',
383
        'Y' => 'year',
384
    );
385
386
    if ( ! isset( $periods[ $period ] ) ) {
387
        $period = 'D';
388
    }
389
390
    return $full ? $periods[ $period ] : $period;
391
392
}
393
394
function wpinv_item_max_buyable_quantity( $item_id ) {
395
    return apply_filters( 'wpinv_item_max_buyable_quantity', 5, $item_id );
396
}
397
398
/**
399
 * Retrieves recurring price description.
400
 *
401
 * @param WPInv_Item|GetPaid_Form_Item $item
402
 */
403
function getpaid_item_recurring_price_help_text( $item, $currency = '', $_initial_price = false, $_recurring_price = false ) {
404
405
    // Abort if it is not recurring.
406
    if ( ! $item->is_recurring() ) {
407
        return '';
408
    }
409
410
    $initial_price   = false === $_initial_price ? wpinv_price( $item->get_initial_price(), $currency ) : $_initial_price;
411
    $recurring_price = false === $_recurring_price ? wpinv_price( $item->get_recurring_price(), $currency ) : $_recurring_price;
412
    $period          = getpaid_get_subscription_period_label( $item->get_recurring_period(), $item->get_recurring_interval(), '' );
413
    $initial_class   = 'getpaid-item-initial-price';
414
    $recurring_class = 'getpaid-item-recurring-price';
415
    $bill_times      = $item->get_recurring_limit();
416
417
    if ( ! empty( $bill_times ) ) {
418
		$bill_times = $item->get_recurring_interval() * $bill_times;
419
		$bill_times = getpaid_get_subscription_period_label( $item->get_recurring_period(), $bill_times );
420
	}
421
422
    if ( $item instanceof GetPaid_Form_Item && false === $_initial_price ) {
423
        $initial_price   = wpinv_price( $item->get_sub_total(), $currency );
424
        $recurring_price = wpinv_price( $item->get_recurring_sub_total(), $currency );
425
    }
426
427
    if ( wpinv_price( 0, $currency ) == $initial_price && wpinv_price( 0, $currency ) == $recurring_price ) {
428
        return __( 'Free forever', 'invoicing' );
429
    }
430
431
    // For free trial items.
432
    if ( $item->has_free_trial() ) {
433
        $trial_period = getpaid_get_subscription_period_label( $item->get_trial_period(), $item->get_trial_interval() );
434
435
        if ( wpinv_price( 0, $currency ) == $initial_price ) {
436
437
            if ( empty( $bill_times ) ) {
438
439
                return sprintf(
440
441
                    // translators: $1: is the trial period, $2: is the recurring price, $3: is the susbcription period
442
                    _x( 'Free for %1$s then %2$s / %3$s', 'Item subscription amount. (e.g.: Free for 1 month then $120 / year)', 'invoicing' ),
443
                    "<span class='getpaid-item-trial-period'>$trial_period</span>",
444
                    "<span class='$recurring_class'>$recurring_price</span>",
445
                    "<span class='getpaid-item-recurring-period'>$period</span>"
446
447
                );
448
449
            }
450
451
            return sprintf(
452
453
                // translators: $1: is the trial period, $2: is the recurring price, $3: is the susbcription period, $4: is the bill times
454
                _x( 'Free for %1$s then %2$s / %3$s for %4$s', 'Item subscription amount. (e.g.: Free for 1 month then $120 / year for 4 years)', 'invoicing' ),
455
                "<span class='getpaid-item-trial-period'>$trial_period</span>",
456
                "<span class='$recurring_class'>$recurring_price</span>",
457
                "<span class='getpaid-item-recurring-period'>$period</span>",
458
                "<span class='getpaid-item-recurring-bill-times'>$bill_times</span>"
459
460
            );
461
462
        }
463
464
        if ( empty( $bill_times ) ) {
465
466
            return sprintf(
467
468
                // translators: $1: is the initial price, $2: is the trial period, $3: is the recurring price, $4: is the susbcription period
469
                _x( '%1$s for %2$s then %3$s / %4$s', 'Item subscription amount. (e.g.: $7 for 1 month then $120 / year)', 'invoicing' ),
470
                "<span class='$initial_class'>$initial_price</span>",
471
                "<span class='getpaid-item-trial-period'>$trial_period</span>",
472
                "<span class='$recurring_class'>$recurring_price</span>",
473
                "<span class='getpaid-item-recurring-period'>$period</span>"
474
475
            );
476
477
        }
478
479
        return sprintf(
480
481
            // translators: $1: is the initial price, $2: is the trial period, $3: is the recurring price, $4: is the susbcription period, $4: is the susbcription bill times
482
            _x( '%1$s for %2$s then %3$s / %4$s for %5$s', 'Item subscription amount. (e.g.: $7 for 1 month then $120 / year for 5 years)', 'invoicing' ),
483
            "<span class='$initial_class'>$initial_price</span>",
484
            "<span class='getpaid-item-trial-period'>$trial_period</span>",
485
            "<span class='$recurring_class'>$recurring_price</span>",
486
            "<span class='getpaid-item-recurring-period'>$period</span>",
487
            "<span class='getpaid-item-recurring-bill-times'>$bill_times</span>"
488
489
        );
490
491
    }
492
493
    if ( $initial_price == $recurring_price ) {
494
495
        if ( empty( $bill_times ) ) {
496
497
            return sprintf(
498
499
                // translators: $1: is the recurring price, $2: is the susbcription period
500
                _x( '%1$s / %2$s', 'Item subscription amount. (e.g.: $120 / year)', 'invoicing' ),
501
                "<span class='$recurring_class'>$recurring_price</span>",
502
                "<span class='getpaid-item-recurring-period'>$period</span>"
503
504
            );
505
506
        }
507
508
        return sprintf(
509
510
            // translators: $1: is the recurring price, $2: is the susbcription period, $3: is the susbcription bill times
511
            _x( '%1$s / %2$s for %3$s', 'Item subscription amount. (e.g.: $120 / year for 5 years)', 'invoicing' ),
512
            "<span class='$recurring_class'>$recurring_price</span>",
513
            "<span class='getpaid-item-recurring-period'>$period</span>",
514
            "<span class='getpaid-item-recurring-bill-times'>$bill_times</span>"
515
516
        );
517
518
    }
519
520
    if ( $initial_price == wpinv_price( 0, $currency ) ) {
521
522
        if ( empty( $bill_times ) ) {
523
524
            return sprintf(
525
526
                // translators: $1: is the recurring period, $2: is the recurring price
527
                _x( 'Free for %1$s then %2$s / %1$s', 'Item subscription amount. (e.g.: Free for 3 months then $7 / 3 months)', 'invoicing' ),
528
                "<span class='getpaid-item-recurring-period'>$period</span>",
529
                "<span class='$recurring_class'>$recurring_price</span>"
530
531
            );
532
533
        }
534
535
        return sprintf(
536
537
            // translators: $1: is the recurring period, $2: is the recurring price, $3: is the bill times
538
            _x( 'Free for %1$s then %2$s / %1$s for %3$s', 'Item subscription amount. (e.g.: Free for 3 months then $7 / 3 months for 12 months)', 'invoicing' ),
539
            "<span class='getpaid-item-recurring-period'>$period</span>",
540
            "<span class='$recurring_class'>$recurring_price</span>",
541
            "<span class='getpaid-item-recurring-bill-times'>$bill_times</span>"
542
543
        );
544
545
    }
546
547
    if ( empty( $bill_times ) ) {
548
549
        return sprintf(
550
551
            // translators: $1: is the initial price, $2: is the recurring price, $3: is the susbcription period
552
            _x( 'Initial payment of %1$s then %2$s / %3$s', 'Item subscription amount. (e.g.: Initial payment of $7 then $120 / year)', 'invoicing' ),
553
            "<span class='$initial_class'>$initial_price</span>",
554
            "<span class='$recurring_class'>$recurring_price</span>",
555
            "<span class='getpaid-item-recurring-period'>$period</span>"
556
557
        );
558
559
    }
560
561
    return sprintf(
562
563
        // translators: $1: is the initial price, $2: is the recurring price, $3: is the susbcription period, $4: is the susbcription bill times
564
        _x( 'Initial payment of %1$s then %2$s / %3$s for %4$s', 'Item subscription amount. (e.g.: Initial payment of $7 then $120 / year for 4 years)', 'invoicing' ),
565
        "<span class='$initial_class'>$initial_price</span>",
566
        "<span class='$recurring_class'>$recurring_price</span>",
567
        "<span class='getpaid-item-recurring-period'>$period</span>",
568
        "<span class='getpaid-item-recurring-bill-times'>$bill_times</span>"
569
570
    );
571
572
}
573