Passed
Push — master ( 12017d...94dde4 )
by Stiofan
27s
created

wpinv-item-functions.php ➔ wpinv_create_item()   C

Complexity

Conditions 8
Paths 12

Size

Total Lines 84
Code Lines 64

Duplication

Lines 9
Ratio 10.71 %

Importance

Changes 0
Metric Value
cc 8
eloc 64
nc 12
nop 3
dl 9
loc 84
rs 5.8442
c 0
b 0
f 0

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
// Exit if accessed directly
3
if ( ! defined( 'ABSPATH' ) ) exit;
4
5
function wpinv_get_item_by( $field = '', $value = '', $type = '' ) {
6
    if( empty( $field ) || empty( $value ) ) {
7
        return false;
8
    }
9
    
10
    $posts = array();
11
12
    switch( strtolower( $field ) ) {
13
        case 'id':
14
            $item = get_post( $value );
15
16
            if( get_post_type( $item ) != 'wpi_item' ) {
17
                return false;
18
            }
19
20
            break;
21
22
        case 'slug':
23
        case 'name':
24
            $posts = get_posts( array(
25
                'post_type'      => 'wpi_item',
26
                'name'           => $value,
27
                'posts_per_page' => 1,
28
                'post_status'    => 'any'
29
            ) );
30
31
            break;
32
        case 'package_id':
33
            $posts = get_posts( array(
34
                'post_type'      => 'wpi_item',
35
                'posts_per_page' => 1,
36
                'post_status'    => 'any',
37
                'orderby'        => 'ID',
38
                'order'          => 'ASC',
39
                'meta_query'     => array(
40
                    array(
41
                        'key'   => '_wpinv_' . $field,
42
                        'value' => $value,
43
                    ),
44
                    array(
45
                        'key'   => '_wpinv_type',
46
                        'value' => 'package',
47
                    )
48
                )
49
            ) );
50
            
51
            break;
52 View Code Duplication
        case 'item_id':
53
            if ( empty( $value ) ) {
54
                return false;
55
            }
56
            
57
            $meta_query = array();
58
            $meta_query[] = array(
59
                'key'   => '_wpinv_post_id',
60
                'value' => $value,
61
            );
62
            if ( !empty( $type ) ) {
63
                $meta_query[] = array(
64
                    'key'   => '_wpinv_type',
65
                    'value' => $type,
66
                );
67
            }
68
            
69
            $args = array(
70
                'post_type'      => 'wpi_item',
71
                'posts_per_page' => 1,
72
                'post_status'    => 'any',
73
                'orderby'        => 'ID',
74
                'order'          => 'ASC',
75
                'meta_query'     => array( $meta_query )
76
            );
77
            
78
            $posts = get_posts( $args );
79
80
            break;
81 View Code Duplication
        case 'custom':
82
            if ( empty( $value ) || empty( $type ) ) {
83
                return false;
84
            }
85
            
86
            $meta_query = array();
87
            $meta_query[] = array(
88
                'key'   => '_wpinv_post_id',
89
                'value' => $value,
90
            );
91
            $meta_query[] = array(
92
                'key'   => '_wpinv_type',
93
                'value' => $type,
94
            );
95
            
96
            $args = array(
97
                'post_type'      => 'wpi_item',
98
                'posts_per_page' => 1,
99
                'post_status'    => 'any',
100
                'orderby'        => 'ID',
101
                'order'          => 'ASC',
102
                'meta_query'     => array( $meta_query )
103
            );
104
            
105
            $posts = get_posts( $args );
106
107
            break;
108
109
        default:
110
            return false;
111
    }
112
    
113
    if ( !empty( $posts[0] ) ) {
114
        return new WPInv_Item( $posts[0]->ID );
115
    }
116
117
    return false;
118
}
119
120
function wpinv_get_item( $item = 0 ) {
121
    if ( is_numeric( $item ) ) {
122
        $item = get_post( $item );
123
        if ( ! $item || 'wpi_item' !== $item->post_type )
124
            return null;
125
        return $item;
126
    }
127
128
    $args = array(
129
        'post_type'   => 'wpi_item',
130
        'name'        => $item,
131
        'numberposts' => 1
132
    );
133
134
    $item = get_posts($args);
135
136
    if ( $item ) {
137
        return $item[0];
138
    }
139
140
    return null;
141
}
142
143
function wpinv_is_free_item( $item_id = 0 ) {
144
    if( empty( $item_id ) ) {
145
        return false;
146
    }
147
148
    $item = new WPInv_Item( $item_id );
0 ignored issues
show
Documentation introduced by
$item_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
149
    
150
    return $item->is_free();
151
}
152
153
function wpinv_get_item_price( $item_id = 0 ) {
154
    if( empty( $item_id ) ) {
155
        return false;
156
    }
157
158
    $item = new WPInv_Item( $item_id );
0 ignored issues
show
Documentation introduced by
$item_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
159
    
160
    return $item->get_price();
161
}
162
163
function wpinv_is_recurring_item( $item_id = 0 ) {
164
    if( empty( $item_id ) ) {
165
        return false;
166
    }
167
168
    $item = new WPInv_Item( $item_id );
0 ignored issues
show
Documentation introduced by
$item_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
169
    
170
    return $item->is_recurring();
171
}
172
173
function wpinv_item_price( $item_id = 0 ) {
174
    if( empty( $item_id ) ) {
175
        return false;
176
    }
177
178
    $price = wpinv_get_item_price( $item_id );
179
    $price = wpinv_price( wpinv_format_amount( $price ) );
180
    
181
    return apply_filters( 'wpinv_item_price', $price, $item_id );
182
}
183
184
function wpinv_item_show_price( $item_id = 0, $echo = true ) {
185
    if ( empty( $item_id ) ) {
186
        $item_id = get_the_ID();
187
    }
188
189
    $price = wpinv_item_price( $item_id );
190
191
    $price           = apply_filters( 'wpinv_item_price', wpinv_sanitize_amount( $price ), $item_id );
192
    $formatted_price = '<span class="wpinv_price" id="wpinv_item_' . $item_id . '">' . $price . '</span>';
193
    $formatted_price = apply_filters( 'wpinv_item_price_after_html', $formatted_price, $item_id, $price );
194
195
    if ( $echo ) {
196
        echo $formatted_price;
197
    } else {
198
        return $formatted_price;
199
    }
200
}
201
202
function wpinv_get_item_final_price( $item_id = 0, $amount_override = null ) {
203
    if ( is_null( $amount_override ) ) {
204
        $original_price = get_post_meta( $item_id, '_wpinv_price', true );
205
    } else {
206
        $original_price = $amount_override;
207
    }
208
    
209
    $price = $original_price;
210
211
    return apply_filters( 'wpinv_get_item_final_price', $price, $item_id );
212
}
213
214
function wpinv_item_cpt_singular_name( $item_id ) {
215
    if( empty( $item_id ) ) {
216
        return false;
217
    }
218
219
    $item = new WPInv_Item( $item_id );
220
    
221
    return $item->get_cpt_singular_name();
222
}
223
224
function wpinv_get_item_types() {
225
    $item_types = array(
226
            'custom'    => __( 'Standard', 'invoicing' ),
227
            'fee'       => __( 'Fee', 'invoicing' ),
228
        );
229
    return apply_filters( 'wpinv_get_item_types', $item_types );
230
}
231
232
function wpinv_item_types() {
233
    $item_types = wpinv_get_item_types();
234
    
235
    return ( !empty( $item_types ) ? array_keys( $item_types ) : array() );
236
}
237
238
function wpinv_get_item_type( $item_id ) {
239
    if( empty( $item_id ) ) {
240
        return false;
241
    }
242
243
    $item = new WPInv_Item( $item_id );
244
    
245
    return $item->get_type();
246
}
247
248
function wpinv_item_type( $item_id ) {
249
    $item_types = wpinv_get_item_types();
250
    
251
    $item_type = wpinv_get_item_type( $item_id );
252
    
253
    if ( empty( $item_type ) ) {
254
        $item_type = '-';
255
    }
256
    
257
    $item_type = isset( $item_types[$item_type] ) ? $item_types[$item_type] : __( $item_type, 'invoicing' );
258
259
    return apply_filters( 'wpinv_item_type', $item_type, $item_id );
260
}
261
262
function wpinv_record_item_in_log( $item_id = 0, $file_id, $user_info, $ip, $invoice_id ) {
263
    global $wpinv_logs;
264
    
265
    if ( empty( $wpinv_logs ) ) {
266
        return false;
267
    }
268
269
    $log_data = array(
270
        'post_parent'	=> $item_id,
271
        'log_type'		=> 'wpi_item'
272
    );
273
274
    $user_id = isset( $user_info['user_id'] ) ? $user_info['user_id'] : (int) -1;
275
276
    $log_meta = array(
277
        'user_info'	=> $user_info,
278
        'user_id'	=> $user_id,
279
        'file_id'	=> (int)$file_id,
280
        'ip'		=> $ip,
281
        'invoice_id'=> $invoice_id,
282
    );
283
284
    $wpinv_logs->insert_log( $log_data, $log_meta );
285
}
286
287
function wpinv_remove_item_logs_on_delete( $item_id = 0 ) {
288
    if ( 'wpi_item' !== get_post_type( $item_id ) )
289
        return;
290
291
    global $wpinv_logs;
292
    
293
    if ( empty( $wpinv_logs ) ) {
294
        return false;
295
    }
296
297
    // Remove all log entries related to this item
298
    $wpinv_logs->delete_logs( $item_id );
299
}
300
add_action( 'delete_post', 'wpinv_remove_item_logs_on_delete' );
301
302
function wpinv_get_random_item( $post_ids = true ) {
303
    wpinv_get_random_items( 1, $post_ids );
304
}
305
306
function wpinv_get_random_items( $num = 3, $post_ids = true ) {
307
    if ( $post_ids ) {
308
        $args = array( 'post_type' => 'wpi_item', 'orderby' => 'rand', 'post_count' => $num, 'fields' => 'ids' );
309
    } else {
310
        $args = array( 'post_type' => 'wpi_item', 'orderby' => 'rand', 'post_count' => $num );
311
    }
312
    
313
    $args  = apply_filters( 'wpinv_get_random_items', $args );
314
    
315
    return get_posts( $args );
316
}
317
318
function wpinv_get_item_token( $url = '' ) {
319
    $args    = array();
320
    $hash    = apply_filters( 'wpinv_get_url_token_algorithm', 'sha256' );
321
    $secret  = apply_filters( 'wpinv_get_url_token_secret', hash( $hash, wp_salt() ) );
322
323
    $parts   = parse_url( $url );
324
    $options = array();
325
326
    if ( isset( $parts['query'] ) ) {
327
        wp_parse_str( $parts['query'], $query_args );
0 ignored issues
show
Bug introduced by
The variable $query_args does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
328
329
        if ( ! empty( $query_args['o'] ) ) {
330
            $options = explode( ':', rawurldecode( $query_args['o'] ) );
331
332
            if ( in_array( 'ip', $options ) ) {
333
                $args['ip'] = wpinv_get_ip();
334
            }
335
336
            if ( in_array( 'ua', $options ) ) {
337
                $ua = wpinv_get_user_agent();
338
                $args['user_agent'] = rawurlencode( $ua );
339
            }
340
        }
341
    }
342
343
    $args = apply_filters( 'wpinv_get_url_token_args', $args, $url, $options );
344
345
    $args['secret'] = $secret;
346
    $args['token']  = false;
347
348
    $url   = add_query_arg( $args, $url );
349
    $parts = parse_url( $url );
350
351
    if ( ! isset( $parts['path'] ) ) {
352
        $parts['path'] = '';
353
    }
354
355
    $token = md5( $parts['path'] . '?' . $parts['query'] );
356
357
    return $token;
358
}
359
360
function wpinv_validate_url_token( $url = '' ) {
361
    $ret   = false;
362
    $parts = parse_url( $url );
363
364
    if ( isset( $parts['query'] ) ) {
365
        wp_parse_str( $parts['query'], $query_args );
0 ignored issues
show
Bug introduced by
The variable $query_args does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
366
367
        $allowed = apply_filters( 'wpinv_url_token_allowed_params', array(
368
            'item',
369
            'ttl',
370
            'token'
371
        ) );
372
373
        $remove = array();
374
375
        foreach( $query_args as $key => $value ) {
376
            if( false === in_array( $key, $allowed ) ) {
377
                $remove[] = $key;
378
            }
379
        }
380
381
        if( ! empty( $remove ) ) {
382
            $url = remove_query_arg( $remove, $url );
383
        }
384
385
        if ( isset( $query_args['ttl'] ) && current_time( 'timestamp' ) > $query_args['ttl'] ) {
386
            wp_die( apply_filters( 'wpinv_item_link_expired_text', __( 'Sorry but your item link has expired.', 'invoicing' ) ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
387
        }
388
389
        if ( isset( $query_args['token'] ) && $query_args['token'] == wpinv_get_item_token( $url ) ) {
390
            $ret = true;
391
        }
392
393
    }
394
395
    return apply_filters( 'wpinv_validate_url_token', $ret, $url, $query_args );
396
}
397
398
function wpinv_item_in_cart( $item_id = 0, $options = array() ) {
399
    $cart_items = wpinv_get_cart_contents();
400
401
    $ret = false;
402
403
    if ( is_array( $cart_items ) ) {
404
        foreach ( $cart_items as $item ) {
405
            if ( $item['id'] == $item_id ) {
406
                $ret = true;
407
                break;
408
            }
409
        }
410
    }
411
412
    return (bool) apply_filters( 'wpinv_item_in_cart', $ret, $item_id, $options );
413
}
414
415
function wpinv_get_cart_item_tax( $item_id = 0, $subtotal = '', $options = array() ) {
416
    $tax = 0;
417
    if ( ! wpinv_item_is_tax_exclusive( $item_id ) ) {
418
        $country = !empty( $_POST['country'] ) ? $_POST['country'] : false;
419
        $state   = isset( $_POST['state'] ) ? $_POST['state'] : '';
420
421
        $tax = wpinv_calculate_tax( $subtotal, $country, $state, $item_id );
422
    }
423
424
    return apply_filters( 'wpinv_get_cart_item_tax', $tax, $item_id, $subtotal, $options );
425
}
426
427
function wpinv_cart_item_price( $item ) {
428
    $use_taxes  = wpinv_use_taxes();
0 ignored issues
show
Unused Code introduced by
$use_taxes is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
429
    $item_id    = isset( $item['id'] ) ? $item['id'] : 0;
430
    $price      = isset( $item['item_price'] ) ? wpinv_format_amount( $item['item_price'] ) : 0;
431
    $options    = isset( $item['options'] ) ? $item['options'] : array();
432
    $price_id   = isset( $options['price_id'] ) ? $options['price_id'] : false;
433
    $tax        = wpinv_price( wpinv_format_amount( $item['tax'] ) );
434
    
435
    if ( !wpinv_is_free_item( $item_id, $price_id ) && !wpinv_item_is_tax_exclusive( $item_id ) ) {
0 ignored issues
show
Unused Code introduced by
The call to wpinv_is_free_item() has too many arguments starting with $price_id.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
436
        if ( wpinv_prices_show_tax_on_checkout() && !wpinv_prices_include_tax() ) {
437
            $price += $tax;
438
        }
439
        
440
        if( !wpinv_prices_show_tax_on_checkout() && wpinv_prices_include_tax() ) {
441
            $price -= $tax;
442
        }        
443
    }
444
445
    $price = wpinv_price( wpinv_format_amount( $price ) );
446
447
    return apply_filters( 'wpinv_cart_item_price_label', $price, $item );
448
}
449
450
function wpinv_cart_item_subtotal( $item ) {
451
    $subtotal   = isset( $item['subtotal'] ) ? $item['subtotal'] : 0;
452
    $subtotal   = wpinv_price( wpinv_format_amount( $subtotal ) );
453
454
    return apply_filters( 'wpinv_cart_item_subtotal_label', $subtotal, $item );
455
}
456
457
function wpinv_cart_item_tax( $item ) {
458
    $tax        = '';
459
    $tax_rate   = '';
460
    
461 View Code Duplication
    if ( isset( $item['tax'] ) && $item['tax'] > 0 && $item['subtotal'] > 0 ) {
462
        $tax      = wpinv_price( wpinv_format_amount( $item['tax'] ) );
463
        $tax_rate = !empty( $item['vat_rate'] ) ? $item['vat_rate'] : ( $item['tax'] / $item['subtotal'] ) * 100;
464
        $tax_rate = $tax_rate > 0 ? (float)wpinv_format_amount( $tax_rate, 2 ) : '';
465
        $tax_rate = $tax_rate != '' ? ' <small class="tax-rate normal small">(' . $tax_rate . '%)</small>' : '';
466
    }
467
    
468
    $tax        = $tax . $tax_rate;
469
    
470
    if ( $tax === '' ) {
471
        $tax = 0; // Zero tax
472
    }
473
474
    return apply_filters( 'wpinv_cart_item_tax_label', $tax, $item );
475
}
476
477
function wpinv_get_cart_item_price( $item_id = 0, $options = array(), $remove_tax_from_inclusive = false ) {
478
    $price = 0;
479
    $variable_prices = wpinv_has_variable_prices( $item_id );
480
481
    if ( $variable_prices ) {
482
        $prices = wpinv_get_variable_prices( $item_id );
483
484
        if ( $prices ) {
485
            if( ! empty( $options ) ) {
486
                $price = isset( $prices[ $options['price_id'] ] ) ? $prices[ $options['price_id'] ]['amount'] : false;
487
            } else {
488
                $price = false;
489
            }
490
        }
491
    }
492
493
    if( ! $variable_prices || false === $price ) {
494
        // Get the standard Item price if not using variable prices
495
        $price = wpinv_get_item_price( $item_id );
496
    }
497
498
    if ( $remove_tax_from_inclusive && wpinv_prices_include_tax() ) {
499
        $price -= wpinv_get_cart_item_tax( $item_id, $price, $options );
500
    }
501
502
    return apply_filters( 'wpinv_cart_item_price', $price, $item_id, $options );
503
}
504
505
function wpinv_get_cart_item_price_id( $item = array() ) {
506
    if( isset( $item['item_number'] ) ) {
507
        $price_id = isset( $item['item_number']['options']['price_id'] ) ? $item['item_number']['options']['price_id'] : null;
508
    } else {
509
        $price_id = isset( $item['options']['price_id'] ) ? $item['options']['price_id'] : null;
510
    }
511
    return $price_id;
512
}
513
514
function wpinv_get_cart_item_price_name( $item = array() ) {
515
    $price_id = (int)wpinv_get_cart_item_price_id( $item );
516
    $prices   = wpinv_get_variable_prices( $item['id'] );
517
    $name     = ! empty( $prices[ $price_id ] ) ? $prices[ $price_id ]['name'] : '';
518
    return apply_filters( 'wpinv_get_cart_item_price_name', $name, $item['id'], $price_id, $item );
519
}
520
521
function wpinv_get_cart_item_name( $item = array() ) {
522
    $item_title = !empty( $item['name'] ) ? $item['name'] : get_the_title( $item['id'] );
523
524
    if ( empty( $item_title ) ) {
525
        $item_title = $item['id'];
526
    }
527
528
    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
529
    if ( wpinv_has_variable_prices( $item['id'] ) && false !== wpinv_get_cart_item_price_id( $item ) ) {
530
        $item_title .= ' - ' . wpinv_get_cart_item_price_name( $item );
531
    }
532
    */
533
534
    return apply_filters( 'wpinv_get_cart_item_name', $item_title, $item['id'], $item );
535
}
536
537
function wpinv_has_variable_prices( $item_id = 0 ) {
0 ignored issues
show
Unused Code introduced by
The parameter $item_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
538
    return false;
539
}
540
541
function wpinv_get_item_position_in_cart( $item_id = 0, $options = array() ) {
542
    $cart_items = wpinv_get_cart_contents();
543
544
    if ( !is_array( $cart_items ) ) {
545
        return false; // Empty cart
546
    } else {
547
        foreach ( $cart_items as $position => $item ) {
548
            if ( $item['id'] == $item_id ) {
549
                if ( isset( $options['price_id'] ) && isset( $item['options']['price_id'] ) ) {
550
                    if ( (int) $options['price_id'] == (int) $item['options']['price_id'] ) {
551
                        return $position;
552
                    }
553
                } else {
554
                    return $position;
555
                }
556
            }
557
        }
558
    }
559
560
    return false; // Not found
561
}
562
563
function wpinv_get_cart_item_quantity( $item ) {
564
    if ( wpinv_item_quantities_enabled() ) {
565
        $quantity = !empty( $item['quantity'] ) && (int)$item['quantity'] > 0 ? absint( $item['quantity'] ) : 1;
566
    } else {
567
        $quantity = 1;
568
    }
569
    
570
    if ( $quantity < 1 ) {
571
        $quantity = 1;
572
    }
573
    
574
    return apply_filters( 'wpinv_get_cart_item_quantity', $quantity, $item );
575
}
576
577
function wpinv_get_item_suffix( $item, $html = true ) {
578
    if ( empty( $item ) ) {
579
        return NULL;
580
    }
581
    
582
    if ( is_int( $item ) ) {
583
        $item = new WPInv_Item( $item );
0 ignored issues
show
Documentation introduced by
$item is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
584
    }
585
    
586
    if ( !( is_object( $item ) && is_a( $item, 'WPInv_Item' ) ) ) {
587
        return NULL;
588
    }
589
    
590
    $suffix = $item->is_recurring() ? ' <span class="wpi-suffix">' . __( '(r)', 'invoicing' ) . '</span>' : '';
591
    
592
    if ( !$html && $suffix ) {
593
        $suffix = strip_tags( $suffix );
594
    }
595
    
596
    return apply_filters( 'wpinv_get_item_suffix', $suffix, $item, $html );
597
}
598
599
function wpinv_remove_item( $item = 0, $force_delete = false ) {
600
    if ( empty( $item ) ) {
601
        return NULL;
602
    }
603
    
604
    if ( is_int( $item ) ) {
605
        $item = new WPInv_Item( $item );
0 ignored issues
show
Documentation introduced by
$item is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
606
    }
607
    
608
    if ( !( is_object( $item ) && is_a( $item, 'WPInv_Item' ) ) ) {
609
        return NULL;
610
    }
611
    
612
    do_action( 'wpinv_pre_delete_item', $item );
613
614
    wp_delete_post( $item->ID, $force_delete );
615
616
    do_action( 'wpinv_post_delete_item', $item );
617
}
618
619
function wpinv_can_delete_item( $post_id ) {
620
    $return = current_user_can( 'manage_options' ) ? true : false;
621
    
622
    if ( $return && wpinv_item_in_use( $post_id ) ) {
623
        $return = false; // Don't delete item already use in invoices.
624
    }
625
    
626
    return apply_filters( 'wpinv_can_delete_item', $return, $post_id );
627
}
628
629
function wpinv_admin_action_delete() {
630
    $screen = get_current_screen();
631
    
632
    if ( !empty( $screen->post_type ) && $screen->post_type == 'wpi_item' && !empty( $_REQUEST['post'] ) && is_array( $_REQUEST['post'] ) ) {
633
        $post_ids = array();
634
        
635
        foreach ( $_REQUEST['post'] as $post_id ) {
636
            if ( !wpinv_can_delete_item( $post_id ) ) {
637
                continue;
638
            }
639
            
640
            $post_ids[] = $post_id;
641
        }
642
        
643
        $_REQUEST['post'] = $post_ids;
644
    }
645
}
646
add_action( 'admin_action_trash', 'wpinv_admin_action_delete', -10 );
647
add_action( 'admin_action_delete', 'wpinv_admin_action_delete', -10 );
648
649
function wpinv_check_delete_item( $check, $post, $force_delete ) {
650
    if ( $post->post_type == 'wpi_item' ) {
651
        if ( $force_delete && !wpinv_can_delete_item( $post->ID ) ) {
652
            return true;
653
        }
654
    }
655
    
656
    return $check;
657
}
658
add_filter( 'pre_delete_post', 'wpinv_check_delete_item', 10, 3 );
659
660
function wpinv_item_in_use( $item_id ) {
661
    global $wpdb, $wpi_items_in_use;
662
    
663
    if ( !$item_id > 0 ) {
664
        return false;
665
    }
666
    
667
    if ( !empty( $wpi_items_in_use ) ) {
668
        if ( isset( $wpi_items_in_use[$item_id] ) ) {
669
            return $wpi_items_in_use[$item_id];
670
        }
671
    } else {
672
        $wpi_items_in_use = array();
673
    }
674
    
675
    $statuses   = array_keys( wpinv_get_invoice_statuses( true ) );
676
    
677
    $query  = "SELECT p.ID FROM " . $wpdb->posts . " AS p INNER JOIN " . $wpdb->postmeta . " AS pm ON p.ID = pm.post_id WHERE p.post_type = 'wpi_invoice' AND p.post_status IN( '" . implode( "','", $statuses ) . "' ) AND pm.meta_key = '_wpinv_item_ids' AND FIND_IN_SET( '" . (int)$item_id . "', pm.meta_value )";
678
    $in_use = $wpdb->get_var( $query ) > 0 ? true : false;
679
    
680
    $wpi_items_in_use[$item_id] = $in_use;
681
    
682
    return $in_use;
683
}
684
685
function wpinv_create_item( $args = array(), $wp_error = false, $force_update = false ) {
686
    // Set some defaults
687
    $defaults = array(
688
        'type'               => 'custom',                                                // Optional. Item type. Default 'custom'.
689
        'item_id'            => 0,                                                       // Required. Any integer number. Must be unique within item type.
690
        'title'              => '',                                                      // Required. Item title.
691
        'price'              => '0.00',                                                  // Optional. Item price. Default '0.00'.
692
        'status'             => 'pending',                                               // Optional. pending, publish
693
        'vat_rule'           => 'digital',                                               // Optional. digital => Digital item, physical => Physical item
694
        'cpt_singular_name'  => '',                                                      // Optional. Sub title for item. Should be singular.
695
        'cpt_name'           => '',                                                      // Optional. Sub title for item. Should be plural.
696
        'is_recurring'       => 0,                                                       // Optional. 1 => Allow recurring or 0 => Don't allow recurring
697
        'recurring_period'   => 'M',                                                     // Optional. D => Daily, W => Weekly, M => Monthly, Y => Yearly
698
        'recurring_interval' => 0,                                                       // Optional. Integer value between 1 - 90.
699
        'recurring_limit'    => 0,                                                       // Optional. Any integer number. 0 for recurring forever until cancelled.
700
        'free_trial'         => 0,                                                       // Optional. 1 => Allow free trial or 0 => Don't free trial
701
        'trial_period'       => 'M',                                                     // Optional. D => Daily, W => Weekly, M => Monthly, Y => Yearly
702
        'trial_interval'     => 0,                                                       // Optional. Any integer number.
703
        'excerpt'            => '',                                                      // Optional. Item short description
704
    );
705
    
706
    $data = wp_parse_args( $args, $defaults );
707
    
708
    if ( empty( $data['item_id'] ) ) {
709
        if ( $wp_error ) {
710
            return new WP_Error( 'invalid_item_id', __( 'Invalid item ID.' ) );
711
        } else {
712
            return false;
713
        }
714
    }
715
    
716
    if ( empty( $data['type'] ) ) {
717
        $data['type'] = 'custom';
718
    }
719
    
720
    $item = wpinv_get_item_by( 'item_id', $data['item_id'], $data['type'] );
721
        
722
    if ( !$force_update && !empty( $item ) ) {
723
        return $item;
724
    }
725
        
726
    $meta                       = array();
727
    $meta['type']               = $data['type'];
728
    $meta['post_id']            = $data['item_id'];
729
    $meta['cpt_singular_name']  = $data['cpt_singular_name'];
730
    $meta['cpt_name']           = $data['cpt_name'];
731
    $meta['price']              = wpinv_format_amount( $data['price'], NULL, true );
732
    $meta['vat_rule']           = $data['vat_rule'];
733
    $meta['vat_class']          = '_standard';
734
    
735
    if ( !empty( $data['is_recurring'] ) ) {
736
        $meta['is_recurring']       = $data['is_recurring'];
737
        $meta['recurring_period']   = $data['recurring_period'];
738
        $meta['recurring_interval'] = absint( $data['recurring_interval'] );
739
        $meta['recurring_limit']    = absint( $data['recurring_limit'] );
740
        $meta['free_trial']         = $data['free_trial'];
741
        $meta['trial_period']       = $data['trial_period'];
742
        $meta['trial_interval']     = absint( $data['trial_interval'] );
743 View Code Duplication
    } else {
744
        $meta['is_recurring']       = 0;
745
        $meta['recurring_period']   = '';
746
        $meta['recurring_interval'] = '';
747
        $meta['recurring_limit']    = '';
748
        $meta['free_trial']         = 0;
749
        $meta['trial_period']       = '';
750
        $meta['trial_interval']     = '';
751
    }
752
    
753
    $post_data  = array( 
754
        'post_title'    => $data['title'],
755
        'post_excerpt'  => $data['excerpt'],
756
        'post_status'   => $data['status'],
757
        'meta'          => $meta
758
    );
759
760
    if ( !empty( $item ) ) {
761
        $item->update( $post_data, $wp_error );
762
    } else {
763
        $item = new WPInv_Item();
764
        $item->create( $post_data, $wp_error );
765
    }
766
    
767
    return $item;
768
}