Passed
Push — master ( 5d2154...beaeba )
by Brian
03:53
created

wpinv_get_item_suffix()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 7
rs 10
cc 3
nc 4
nop 2
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 $id ? wpinv_get_item( $id ) : false;
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->get_id() ? $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( wpinv_format_amount( $price ) );
0 ignored issues
show
Bug introduced by
wpinv_format_amount($price) of type string is incompatible with the type double expected by parameter $amount of wpinv_price(). ( 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 */ wpinv_format_amount( $price ) );
Loading history...
Bug introduced by
It seems like $price can also be of type false; however, parameter $amount of wpinv_format_amount() 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( wpinv_format_amount( /** @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
function wpinv_get_item_token( $url = '' ) {
259
    $args    = array();
260
    $hash    = apply_filters( 'wpinv_get_url_token_algorithm', 'sha256' );
261
    $secret  = apply_filters( 'wpinv_get_url_token_secret', hash( $hash, wp_salt() ) );
262
263
    $parts   = parse_url( $url );
264
    $options = array();
265
266
    if ( isset( $parts['query'] ) ) {
267
        wp_parse_str( $parts['query'], $query_args );
268
269
        if ( ! empty( $query_args['o'] ) ) {
270
            $options = explode( ':', rawurldecode( $query_args['o'] ) );
271
272
            if ( in_array( 'ip', $options ) ) {
273
                $args['ip'] = wpinv_get_ip();
274
            }
275
276
            if ( in_array( 'ua', $options ) ) {
277
                $ua = wpinv_get_user_agent();
278
                $args['user_agent'] = rawurlencode( $ua );
279
            }
280
        }
281
    }
282
283
    $args = apply_filters( 'wpinv_get_url_token_args', $args, $url, $options );
284
285
    $args['secret'] = $secret;
286
    $args['token']  = false;
287
288
    $url   = add_query_arg( $args, $url );
289
    $parts = parse_url( $url );
290
291
    if ( ! isset( $parts['path'] ) ) {
292
        $parts['path'] = '';
293
    }
294
295
    $token = md5( $parts['path'] . '?' . $parts['query'] );
296
297
    return $token;
298
}
299
300
function wpinv_validate_url_token( $url = '' ) {
301
    $ret   = false;
302
    $parts = parse_url( $url );
303
304
    if ( isset( $parts['query'] ) ) {
305
        wp_parse_str( $parts['query'], $query_args );
306
307
        $allowed = apply_filters( 'wpinv_url_token_allowed_params', array(
308
            'item',
309
            'ttl',
310
            'token'
311
        ) );
312
313
        $remove = array();
314
315
        foreach( $query_args as $key => $value ) {
316
            if( false === in_array( $key, $allowed ) ) {
317
                $remove[] = $key;
318
            }
319
        }
320
321
        if( ! empty( $remove ) ) {
322
            $url = remove_query_arg( $remove, $url );
323
        }
324
325
        if ( isset( $query_args['ttl'] ) && current_time( 'timestamp' ) > $query_args['ttl'] ) {
326
            wp_die( apply_filters( 'wpinv_item_link_expired_text', __( 'Sorry but your item link has expired.', 'invoicing' ) ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
327
        }
328
329
        if ( isset( $query_args['token'] ) && $query_args['token'] == wpinv_get_item_token( $url ) ) {
330
            $ret = true;
331
        }
332
333
    }
334
335
    return apply_filters( 'wpinv_validate_url_token', $ret, $url, $query_args );
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $query_args does not seem to be defined for all execution paths leading up to this point.
Loading history...
336
}
337
338
function wpinv_item_in_cart( $item_id = 0, $options = array() ) {
339
    $cart_items = wpinv_get_cart_contents();
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_get_cart_contents() has been deprecated. ( Ignorable by Annotation )

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

339
    $cart_items = /** @scrutinizer ignore-deprecated */ wpinv_get_cart_contents();
Loading history...
340
341
    $ret = false;
342
343
    if ( is_array( $cart_items ) ) {
0 ignored issues
show
introduced by
The condition is_array($cart_items) is always true.
Loading history...
344
        foreach ( $cart_items as $item ) {
345
            if ( $item['id'] == $item_id ) {
346
                $ret = true;
347
                break;
348
            }
349
        }
350
    }
351
352
    return (bool) apply_filters( 'wpinv_item_in_cart', $ret, $item_id, $options );
353
}
354
355
function wpinv_get_cart_item_tax( $item_id = 0, $subtotal = '', $options = array() ) {
356
    $tax = 0;
357
    if ( ! wpinv_item_is_tax_exclusive( $item_id ) ) {
358
        $country = !empty( $_POST['country'] ) ? $_POST['country'] : false;
359
        $state   = isset( $_POST['state'] ) ? $_POST['state'] : '';
360
361
        $tax = wpinv_calculate_tax( $subtotal, $country, $state, $item_id );
362
    }
363
364
    return apply_filters( 'wpinv_get_cart_item_tax', $tax, $item_id, $subtotal, $options );
365
}
366
367
function wpinv_cart_item_price( $item, $currency = '' ) {
368
369
    if( empty( $currency ) ) {
370
        $currency = wpinv_get_currency();
371
    }
372
373
    $item_id    = isset( $item['id'] ) ? $item['id'] : 0;
374
    $price      = isset( $item['item_price'] ) ? wpinv_round_amount( $item['item_price'] ) : 0;
375
    $tax        = wpinv_price( wpinv_format_amount( $item['tax'] ) );
0 ignored issues
show
Bug introduced by
wpinv_format_amount($item['tax']) of type string is incompatible with the type double expected by parameter $amount of wpinv_price(). ( Ignorable by Annotation )

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

375
    $tax        = wpinv_price( /** @scrutinizer ignore-type */ wpinv_format_amount( $item['tax'] ) );
Loading history...
376
    
377
    if ( !wpinv_is_free_item( $item_id ) && !wpinv_item_is_tax_exclusive( $item_id ) ) {
378
        if ( wpinv_prices_show_tax_on_checkout() && !wpinv_prices_include_tax() ) {
379
            $price += $tax;
380
        }
381
        
382
        if( !wpinv_prices_show_tax_on_checkout() && wpinv_prices_include_tax() ) {
383
            $price -= $tax;
384
        }        
385
    }
386
387
    $price = wpinv_price( wpinv_format_amount( $price ), $currency );
388
389
    return apply_filters( 'wpinv_cart_item_price_label', $price, $item );
390
}
391
392
function wpinv_cart_item_subtotal( $item, $currency = '' ) {
393
394
    if( empty( $currency ) ) {
395
        $currency = wpinv_get_currency();
396
    }
397
398
    $subtotal   = isset( $item['subtotal'] ) ? $item['subtotal'] : 0;
399
    $subtotal   = wpinv_price( wpinv_format_amount( $subtotal ), $currency );
0 ignored issues
show
Bug introduced by
wpinv_format_amount($subtotal) of type string is incompatible with the type double expected by parameter $amount of wpinv_price(). ( Ignorable by Annotation )

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

399
    $subtotal   = wpinv_price( /** @scrutinizer ignore-type */ wpinv_format_amount( $subtotal ), $currency );
Loading history...
400
401
    return apply_filters( 'wpinv_cart_item_subtotal_label', $subtotal, $item );
402
}
403
404
function wpinv_cart_item_tax( $item, $currency = '' ) {
405
    $tax        = '';
406
    $tax_rate   = '';
407
408
    if( empty( $currency ) ) {
409
        $currency = wpinv_get_currency();
410
    }
411
    
412
    if ( isset( $item['tax'] ) && $item['tax'] > 0 && $item['subtotal'] > 0 ) {
413
        $tax      = wpinv_price( wpinv_format_amount( $item['tax'] ), $currency );
0 ignored issues
show
Bug introduced by
wpinv_format_amount($item['tax']) of type string is incompatible with the type double expected by parameter $amount of wpinv_price(). ( Ignorable by Annotation )

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

413
        $tax      = wpinv_price( /** @scrutinizer ignore-type */ wpinv_format_amount( $item['tax'] ), $currency );
Loading history...
414
        $tax_rate = !empty( $item['vat_rate'] ) ? $item['vat_rate'] : ( $item['tax'] / $item['subtotal'] ) * 100;
415
        $tax_rate = $tax_rate > 0 ? (float)wpinv_round_amount( $tax_rate, 4 ) : '';
416
        $tax_rate = $tax_rate != '' ? ' <small class="tax-rate normal small">(' . $tax_rate . '%)</small>' : '';
417
    }
418
    
419
    $tax        = $tax . $tax_rate;
420
    
421
    if ( $tax === '' ) {
422
        $tax = 0; // Zero tax
423
    }
424
425
    return apply_filters( 'wpinv_cart_item_tax_label', $tax, $item );
426
}
427
428
/**
429
 * Adds additional information suffixes to an item name.
430
 *
431
 * @param WPInv_Item|int $item
432
 * @param bool $html
433
 */
434
function wpinv_get_item_suffix( $item, $html = true ) {
435
436
    $item   = new WPInv_Item( $item );
437
    $suffix = $item->is_recurring() ? ' <span class="wpi-suffix">' . __( '(r)', 'invoicing' ) . '</span>' : '';
438
    $suffix = $html ? $suffix : strip_tags( $suffix );
439
440
    return apply_filters( 'wpinv_get_item_suffix', $suffix, $item, $html );
441
}
442
443
/**
444
 * Deletes an invoicing item.
445
 * 
446
 * @param WPInv_Item|int $item
447
 * @param bool $force_delete
448
 */
449
function wpinv_remove_item( $item = 0, $force_delete = false ) {
450
    $item = new WPInv_Item( $item );
451
    $item->delete( $force_delete );
452
}
453
454
/**
455
 * Create/Update an item.
456
 * 
457
 * @param array $args an array of arguments to create the item.
458
 * 
459
 *    Here are all the args (with defaults) that you can set/modify.
460
 *    array(
461
 *		  'ID'                   => 0,           - If specified, the item with that ID will be updated.
462
 *        'parent_id'            => 0,           - Int. Parent item ID.
463
 *		  'status'               => 'draft',     - String. Item status - either draft, pending or publish.
464
 *		  'date_created'         => null,        - String. strtotime() compatible string.
465
 *        'date_modified'        => null,        - String. strtotime() compatible string.
466
 *        'name'                 => '',          - String. Required. Item name.
467
 *        'description'          => '',          - String. Item description.
468
 *        'author'               => 1,           - int. Owner of the item.
469
 *        'price'                => 0,           - float. Item price.
470
 *        'vat_rule'             => 'digital',   - string. VAT rule.
471
 *        'vat_class'            => '_standard', - string. VAT class.
472
 *        'type'                 => 'custom',    - string. Item type.
473
 *        'custom_id'            => null,        - string. Custom item id.
474
 *        'custom_name'          => null,        - string. Custom item name.
475
 *        'custom_singular_name' => null,        - string. Custom item singular name.
476
 *        'is_editable'          => 1,           - int|bool. Whether or not the item is editable.
477
 *        'is_dynamic_pricing'   => 0,           - int|bool. Whether or not users can update the item price.
478
 *        'minimum_price'        => 0,           - float. If dynamic, set the minimum price that a user can set..
479
 *        'is_recurring'         => 0,           - int|bool. Whether or not this item is recurring.
480
 *        'recurring_period'     => 'D',         - string. If recurring, set the recurring period as either days (D), weeks (W), months (M) or years (Y).
481
 *        'recurring_interval'   => 1,           - int. The recurring interval.
482
 *        'recurring_limit'      => 0,           - int. The recurring limit. Enter 0 for unlimited.
483
 *        'is_free_trial'        => false,       - int|bool. Whether or not this item has a free trial.
484
 *        '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).
485
 *        'trial_interval'       => 1,           - int. The trial interval.
486
 *    );
487
 * @param bool $wp_error whether or not to return a WP_Error on failure.
488
 * @return bool|WP_Error|WPInv_Item
489
 */
490
function wpinv_create_item( $args = array(), $wp_error = false ) {
491
492
    // Prepare the item.
493
    if ( ! empty( $args['custom_id'] ) && empty( $args['ID'] ) ) {
494
        $type = empty( $args['type'] ) ? 'custom' : $args['type'];
495
        $item = wpinv_get_item_by( 'custom_id', $args['custom_id'], $type );
496
497
        if ( ! empty( $item ) ) {
498
            $args['ID'] = $item->get_id();
499
        }
500
501
    }
502
503
    // Do we have an item?
504
    if ( ! empty( $args['ID'] ) ) {
505
        $item = new WPInv_Item( $args['ID'] );
506
    } else {
507
        $item = new WPInv_Item();
508
    }
509
510
    // Do we have an error?
511
    if ( ! empty( $item->last_error ) ) {
512
        return $wp_error ? new WP_Error( 'invalid_item', $item->last_error ) : false;
513
    }
514
515
    // Update item props.
516
    $item->set_props( $args );
517
518
    // Save the item.
519
    $item->save();
520
521
    // Do we have an error?
522
    if ( ! empty( $item->last_error ) ) {
523
        return $wp_error ? new WP_Error( 'not_saved', $item->last_error ) : false;
524
    }
525
526
    // Was the item saved?
527
    if ( ! $item->get_id() ) {
528
        return $wp_error ? new WP_Error( 'not_saved', __( 'An error occured while saving the item', 'invoicing' ) ) : false;
529
    }
530
531
    return $item;
532
533
}
534
535
/**
536
 * Updates an item.
537
 * 
538
 * @see wpinv_create_item()
539
 */
540
function wpinv_update_item( $args = array(), $wp_error = false ) {
541
    return wpinv_create_item( $args, $wp_error );
542
}
543
544
/**
545
 * Sanitizes a recurring period
546
 */
547
function getpaid_sanitize_recurring_period( $period, $full = false ) {
548
549
    $periods = array(
550
        'D' => 'day',
551
        'W' => 'week',
552
        'M' => 'month',
553
        'Y' => 'year',
554
    );
555
556
    if ( ! isset( $periods[ $period ] ) ) {
557
        $period = 'D';
558
    }
559
560
    return $full ? $periods[ $period ] : $period;
561
562
}
563
564
/**
565
 * Retrieves recurring price description.
566
 * 
567
 * @param WPInv_Item|GetPaid_Form_Item $item
568
 */
569
function getpaid_item_recurring_price_help_text( $item, $currency = '' ) {
570
571
    // Abort if it is not recurring.
572
    if ( ! $item->is_recurring() ) {
573
        return '';
574
    }
575
576
    $initial_price   = wpinv_price( $item->get_initial_price(), $currency );
577
    $recurring_price = wpinv_price( $item->get_recurring_price(), $currency );
578
    $period          = getpaid_get_subscription_period_label( $item->get_recurring_period(), $item->get_recurring_interval(), '' );
579
    $initial_class   = 'getpaid-item-initial-price';
580
    $recurring_class = 'getpaid-item-recurring-price';
581
582
    if ( $item instanceof GetPaid_Form_Item ) {
583
        $initial_price   = wpinv_price( $item->get_sub_total(), $currency );
584
        $recurring_price = wpinv_price( $item->get_recurring_sub_total(), $currency );
585
    }
586
587
    // For free trial items.
588
    if ( $item->has_free_trial() ) {
589
        $trial_period = getpaid_get_subscription_period_label( $item->get_trial_period(), $item->get_trial_interval() );
590
591
        if ( 0 == $item->get_initial_price() ) {
592
593
            return sprintf(
594
595
                // translators: $1: is the trial period, $2: is the recurring price, $3: is the susbcription period
596
                _x( 'Free for %1$s then %2$s / %3$s', 'Item subscription amount. (e.g.: Free for 1 month then $120 / year)', 'invoicing' ),
597
                $trial_period,
598
                "<span class='$recurring_class'>$recurring_price</span>",
599
                $period
600
601
            );
602
603
        }
604
605
        return sprintf(
606
607
            // translators: $1: is the initial price, $2: is the trial period, $3: is the recurring price, $4: is the susbcription period
608
            _x( '%1$s for %2$s then %3$s / %4$s', 'Item subscription amount. (e.g.: $7 for 1 month then $120 / year)', 'invoicing' ),
609
            "<span class='$initial_class'>$initial_price</span>",
610
            $trial_period,
611
            "<span class='$recurring_class'>$recurring_price</span>",
612
            $period
613
614
        );
615
616
    }
617
618
    if ( $initial_price == $recurring_price ) {
619
620
        return sprintf(
621
622
            // translators: $1: is the recurring price, $2: is the susbcription period
623
            _x( '%1$s / %2$s', 'Item subscription amount. (e.g.: $120 / year)', 'invoicing' ),
624
            "<span class='$recurring_class'>$recurring_price</span>",
625
            $period
626
627
        );
628
629
    }
630
631
    return sprintf(
632
633
        // translators: $1: is the initial price, $2: is the recurring price, $3: is the susbcription period
634
        _x( 'Initial payment of %1$s then %2$s / %3$s', 'Item subscription amount. (e.g.: Initial payment of $7 then $120 / year)', 'invoicing' ),
635
        "<span class='$initial_class'>$initial_price</span>",
636
        "<span class='$recurring_class'>$recurring_price</span>",
637
        $period
638
639
    );
640
641
}
642