Passed
Pull Request — master (#57)
by Kiran
04:35
created

wpinv-item-functions.php ➔ wpinv_item_is_editable()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 1
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
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 'custom_id':
33
            if ( empty( $value ) || empty( $type ) ) {
34
                return false;
35
            }
36
            
37
            $meta_query = array();
38
            $meta_query[] = array(
39
                'key'   => '_wpinv_type',
40
                'value' => $type,
41
            );
42
            $meta_query[] = array(
43
                'key'   => '_wpinv_custom_id',
44
                'value' => $value,
45
            );
46
            
47
            $args = array(
48
                'post_type'      => 'wpi_item',
49
                'posts_per_page' => 1,
50
                'post_status'    => 'any',
51
                'orderby'        => 'ID',
52
                'order'          => 'ASC',
53
                'meta_query'     => array( $meta_query )
54
            );
55
            
56
            $posts = get_posts( $args );
57
58
            break;
59
60
        default:
61
            return false;
62
    }
63
    
64
    if ( !empty( $posts[0] ) ) {
65
        return new WPInv_Item( $posts[0]->ID );
66
    }
67
68
    return false;
69
}
70
71
function wpinv_get_item( $item = 0 ) {
72
    if ( is_numeric( $item ) ) {
73
        $item = get_post( $item );
74
        if ( ! $item || 'wpi_item' !== $item->post_type )
75
            return null;
76
        return $item;
77
    }
78
79
    $args = array(
80
        'post_type'   => 'wpi_item',
81
        'name'        => $item,
82
        'numberposts' => 1
83
    );
84
85
    $item = get_posts($args);
86
87
    if ( $item ) {
88
        return $item[0];
89
    }
90
91
    return null;
92
}
93
94
function wpinv_is_free_item( $item_id = 0 ) {
95
    if( empty( $item_id ) ) {
96
        return false;
97
    }
98
99
    $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...
100
    
101
    return $item->is_free();
102
}
103
104
function wpinv_item_is_editable( $item = 0 ) {
105
    if ( !empty( $item ) && is_a( $item, 'WP_Post' ) ) {
106
        $item = $item->ID;
107
    }
108
        
109
    if ( empty( $item ) ) {
110
        return true;
111
    }
112
113
    $item = new WPInv_Item( $item );
114
    
115
    return (bool) $item->is_editable();
116
}
117
118
function wpinv_get_item_price( $item_id = 0 ) {
119
    if( empty( $item_id ) ) {
120
        return false;
121
    }
122
123
    $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...
124
    
125
    return $item->get_price();
126
}
127
128
function wpinv_is_recurring_item( $item_id = 0 ) {
129
    if( empty( $item_id ) ) {
130
        return false;
131
    }
132
133
    $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...
134
    
135
    return $item->is_recurring();
136
}
137
138
function wpinv_item_price( $item_id = 0 ) {
139
    if( empty( $item_id ) ) {
140
        return false;
141
    }
142
143
    $price = wpinv_get_item_price( $item_id );
144
    $price = wpinv_price( wpinv_format_amount( $price ) );
145
    
146
    return apply_filters( 'wpinv_item_price', $price, $item_id );
147
}
148
149
function wpinv_item_show_price( $item_id = 0, $echo = true ) {
150
    if ( empty( $item_id ) ) {
151
        $item_id = get_the_ID();
152
    }
153
154
    $price = wpinv_item_price( $item_id );
155
156
    $price           = apply_filters( 'wpinv_item_price', wpinv_sanitize_amount( $price ), $item_id );
157
    $formatted_price = '<span class="wpinv_price" id="wpinv_item_' . $item_id . '">' . $price . '</span>';
158
    $formatted_price = apply_filters( 'wpinv_item_price_after_html', $formatted_price, $item_id, $price );
159
160
    if ( $echo ) {
161
        echo $formatted_price;
162
    } else {
163
        return $formatted_price;
164
    }
165
}
166
167
function wpinv_get_item_final_price( $item_id = 0, $amount_override = null ) {
168
    if ( is_null( $amount_override ) ) {
169
        $original_price = get_post_meta( $item_id, '_wpinv_price', true );
170
    } else {
171
        $original_price = $amount_override;
172
    }
173
    
174
    $price = $original_price;
175
176
    return apply_filters( 'wpinv_get_item_final_price', $price, $item_id );
177
}
178
179
function wpinv_item_custom_singular_name( $item_id ) {
180
    if( empty( $item_id ) ) {
181
        return false;
182
    }
183
184
    $item = new WPInv_Item( $item_id );
185
    
186
    return $item->get_custom_singular_name();
187
}
188
189
function wpinv_get_item_types() {
190
    $item_types = array(
191
            'custom'    => __( 'Standard', 'invoicing' ),
192
            'fee'       => __( 'Fee', 'invoicing' ),
193
        );
194
    return apply_filters( 'wpinv_get_item_types', $item_types );
195
}
196
197
function wpinv_item_types() {
198
    $item_types = wpinv_get_item_types();
199
    
200
    return ( !empty( $item_types ) ? array_keys( $item_types ) : array() );
201
}
202
203
function wpinv_get_item_type( $item_id ) {
204
    if( empty( $item_id ) ) {
205
        return false;
206
    }
207
208
    $item = new WPInv_Item( $item_id );
209
    
210
    return $item->get_type();
211
}
212
213
function wpinv_item_type( $item_id ) {
214
    $item_types = wpinv_get_item_types();
215
    
216
    $item_type = wpinv_get_item_type( $item_id );
217
    
218
    if ( empty( $item_type ) ) {
219
        $item_type = '-';
220
    }
221
    
222
    $item_type = isset( $item_types[$item_type] ) ? $item_types[$item_type] : __( $item_type, 'invoicing' );
223
224
    return apply_filters( 'wpinv_item_type', $item_type, $item_id );
225
}
226
227
function wpinv_record_item_in_log( $item_id = 0, $file_id, $user_info, $ip, $invoice_id ) {
228
    global $wpinv_logs;
229
    
230
    if ( empty( $wpinv_logs ) ) {
231
        return false;
232
    }
233
234
    $log_data = array(
235
        'post_parent'	=> $item_id,
236
        'log_type'		=> 'wpi_item'
237
    );
238
239
    $user_id = isset( $user_info['user_id'] ) ? $user_info['user_id'] : (int) -1;
240
241
    $log_meta = array(
242
        'user_info'	=> $user_info,
243
        'user_id'	=> $user_id,
244
        'file_id'	=> (int)$file_id,
245
        'ip'		=> $ip,
246
        'invoice_id'=> $invoice_id,
247
    );
248
249
    $wpinv_logs->insert_log( $log_data, $log_meta );
250
}
251
252
function wpinv_remove_item_logs_on_delete( $item_id = 0 ) {
253
    if ( 'wpi_item' !== get_post_type( $item_id ) )
254
        return;
255
256
    global $wpinv_logs;
257
    
258
    if ( empty( $wpinv_logs ) ) {
259
        return false;
260
    }
261
262
    // Remove all log entries related to this item
263
    $wpinv_logs->delete_logs( $item_id );
264
}
265
add_action( 'delete_post', 'wpinv_remove_item_logs_on_delete' );
266
267
function wpinv_get_random_item( $post_ids = true ) {
268
    wpinv_get_random_items( 1, $post_ids );
269
}
270
271
function wpinv_get_random_items( $num = 3, $post_ids = true ) {
272
    if ( $post_ids ) {
273
        $args = array( 'post_type' => 'wpi_item', 'orderby' => 'rand', 'post_count' => $num, 'fields' => 'ids' );
274
    } else {
275
        $args = array( 'post_type' => 'wpi_item', 'orderby' => 'rand', 'post_count' => $num );
276
    }
277
    
278
    $args  = apply_filters( 'wpinv_get_random_items', $args );
279
    
280
    return get_posts( $args );
281
}
282
283
function wpinv_get_item_token( $url = '' ) {
284
    $args    = array();
285
    $hash    = apply_filters( 'wpinv_get_url_token_algorithm', 'sha256' );
286
    $secret  = apply_filters( 'wpinv_get_url_token_secret', hash( $hash, wp_salt() ) );
287
288
    $parts   = parse_url( $url );
289
    $options = array();
290
291
    if ( isset( $parts['query'] ) ) {
292
        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...
293
294
        if ( ! empty( $query_args['o'] ) ) {
295
            $options = explode( ':', rawurldecode( $query_args['o'] ) );
296
297
            if ( in_array( 'ip', $options ) ) {
298
                $args['ip'] = wpinv_get_ip();
299
            }
300
301
            if ( in_array( 'ua', $options ) ) {
302
                $ua = wpinv_get_user_agent();
303
                $args['user_agent'] = rawurlencode( $ua );
304
            }
305
        }
306
    }
307
308
    $args = apply_filters( 'wpinv_get_url_token_args', $args, $url, $options );
309
310
    $args['secret'] = $secret;
311
    $args['token']  = false;
312
313
    $url   = add_query_arg( $args, $url );
314
    $parts = parse_url( $url );
315
316
    if ( ! isset( $parts['path'] ) ) {
317
        $parts['path'] = '';
318
    }
319
320
    $token = md5( $parts['path'] . '?' . $parts['query'] );
321
322
    return $token;
323
}
324
325
function wpinv_validate_url_token( $url = '' ) {
326
    $ret   = false;
327
    $parts = parse_url( $url );
328
329
    if ( isset( $parts['query'] ) ) {
330
        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...
331
332
        $allowed = apply_filters( 'wpinv_url_token_allowed_params', array(
333
            'item',
334
            'ttl',
335
            'token'
336
        ) );
337
338
        $remove = array();
339
340
        foreach( $query_args as $key => $value ) {
341
            if( false === in_array( $key, $allowed ) ) {
342
                $remove[] = $key;
343
            }
344
        }
345
346
        if( ! empty( $remove ) ) {
347
            $url = remove_query_arg( $remove, $url );
348
        }
349
350
        if ( isset( $query_args['ttl'] ) && current_time( 'timestamp' ) > $query_args['ttl'] ) {
351
            wp_die( apply_filters( 'wpinv_item_link_expired_text', __( 'Sorry but your item link has expired.', 'invoicing' ) ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
352
        }
353
354
        if ( isset( $query_args['token'] ) && $query_args['token'] == wpinv_get_item_token( $url ) ) {
355
            $ret = true;
356
        }
357
358
    }
359
360
    return apply_filters( 'wpinv_validate_url_token', $ret, $url, $query_args );
361
}
362
363
function wpinv_item_in_cart( $item_id = 0, $options = array() ) {
364
    $cart_items = wpinv_get_cart_contents();
365
366
    $ret = false;
367
368
    if ( is_array( $cart_items ) ) {
369
        foreach ( $cart_items as $item ) {
370
            if ( $item['id'] == $item_id ) {
371
                $ret = true;
372
                break;
373
            }
374
        }
375
    }
376
377
    return (bool) apply_filters( 'wpinv_item_in_cart', $ret, $item_id, $options );
378
}
379
380
function wpinv_get_cart_item_tax( $item_id = 0, $subtotal = '', $options = array() ) {
381
    $tax = 0;
382
    if ( ! wpinv_item_is_tax_exclusive( $item_id ) ) {
383
        $country = !empty( $_POST['country'] ) ? $_POST['country'] : false;
384
        $state   = isset( $_POST['state'] ) ? $_POST['state'] : '';
385
386
        $tax = wpinv_calculate_tax( $subtotal, $country, $state, $item_id );
387
    }
388
389
    return apply_filters( 'wpinv_get_cart_item_tax', $tax, $item_id, $subtotal, $options );
390
}
391
392
function wpinv_cart_item_price( $item ) {
393
    $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...
394
    $item_id    = isset( $item['id'] ) ? $item['id'] : 0;
395
    $price      = isset( $item['item_price'] ) ? wpinv_round_amount( $item['item_price'] ) : 0;
396
    $options    = isset( $item['options'] ) ? $item['options'] : array();
397
    $price_id   = isset( $options['price_id'] ) ? $options['price_id'] : false;
398
    $tax        = wpinv_price( wpinv_format_amount( $item['tax'] ) );
399
    
400
    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...
401
        if ( wpinv_prices_show_tax_on_checkout() && !wpinv_prices_include_tax() ) {
402
            $price += $tax;
403
        }
404
        
405
        if( !wpinv_prices_show_tax_on_checkout() && wpinv_prices_include_tax() ) {
406
            $price -= $tax;
407
        }        
408
    }
409
410
    $price = wpinv_price( wpinv_format_amount( $price ) );
411
412
    return apply_filters( 'wpinv_cart_item_price_label', $price, $item );
413
}
414
415
function wpinv_cart_item_subtotal( $item ) {
416
    $subtotal   = isset( $item['subtotal'] ) ? $item['subtotal'] : 0;
417
    $subtotal   = wpinv_price( wpinv_format_amount( $subtotal ) );
418
419
    return apply_filters( 'wpinv_cart_item_subtotal_label', $subtotal, $item );
420
}
421
422
function wpinv_cart_item_tax( $item ) {
423
    $tax        = '';
424
    $tax_rate   = '';
425
    
426 View Code Duplication
    if ( isset( $item['tax'] ) && $item['tax'] > 0 && $item['subtotal'] > 0 ) {
427
        $tax      = wpinv_price( wpinv_format_amount( $item['tax'] ) );
428
        $tax_rate = !empty( $item['vat_rate'] ) ? $item['vat_rate'] : ( $item['tax'] / $item['subtotal'] ) * 100;
429
        $tax_rate = $tax_rate > 0 ? (float)wpinv_round_amount( $tax_rate, 4 ) : '';
430
        $tax_rate = $tax_rate != '' ? ' <small class="tax-rate normal small">(' . $tax_rate . '%)</small>' : '';
431
    }
432
    
433
    $tax        = $tax . $tax_rate;
434
    
435
    if ( $tax === '' ) {
436
        $tax = 0; // Zero tax
437
    }
438
439
    return apply_filters( 'wpinv_cart_item_tax_label', $tax, $item );
440
}
441
442
function wpinv_get_cart_item_price( $item_id = 0, $cart_item = array(), $options = array(), $remove_tax_from_inclusive = false ) {
443
    $price = 0;
444
    
445
    // Set custom price
446
    if ( isset( $cart_item['custom_price'] ) && $cart_item['custom_price'] !== '' ) {
447
        $price = $cart_item['custom_price'];
448
    } else {
449
        $variable_prices = wpinv_has_variable_prices( $item_id );
450
451
        if ( $variable_prices ) {
452
            $prices = wpinv_get_variable_prices( $item_id );
453
454
            if ( $prices ) {
455
                if( ! empty( $options ) ) {
456
                    $price = isset( $prices[ $options['price_id'] ] ) ? $prices[ $options['price_id'] ]['amount'] : false;
457
                } else {
458
                    $price = false;
459
                }
460
            }
461
        }
462
463
        if( ! $variable_prices || false === $price ) {
464
            // Get the standard Item price if not using variable prices
465
            $price = wpinv_get_item_price( $item_id );
466
        }
467
    }
468
469
    if ( $remove_tax_from_inclusive && wpinv_prices_include_tax() ) {
470
        $price -= wpinv_get_cart_item_tax( $item_id, $price, $options );
471
    }
472
473
    return apply_filters( 'wpinv_cart_item_price', $price, $item_id, $cart_item, $options, $remove_tax_from_inclusive );
474
}
475
476
function wpinv_get_cart_item_price_id( $item = array() ) {
477
    if( isset( $item['item_number'] ) ) {
478
        $price_id = isset( $item['item_number']['options']['price_id'] ) ? $item['item_number']['options']['price_id'] : null;
479
    } else {
480
        $price_id = isset( $item['options']['price_id'] ) ? $item['options']['price_id'] : null;
481
    }
482
    return $price_id;
483
}
484
485
function wpinv_get_cart_item_price_name( $item = array() ) {
486
    $price_id = (int)wpinv_get_cart_item_price_id( $item );
487
    $prices   = wpinv_get_variable_prices( $item['id'] );
488
    $name     = ! empty( $prices[ $price_id ] ) ? $prices[ $price_id ]['name'] : '';
489
    return apply_filters( 'wpinv_get_cart_item_price_name', $name, $item['id'], $price_id, $item );
490
}
491
492
function wpinv_get_cart_item_name( $item = array() ) {
493
    $item_title = !empty( $item['name'] ) ? $item['name'] : get_the_title( $item['id'] );
494
495
    if ( empty( $item_title ) ) {
496
        $item_title = $item['id'];
497
    }
498
499
    /*
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...
500
    if ( wpinv_has_variable_prices( $item['id'] ) && false !== wpinv_get_cart_item_price_id( $item ) ) {
501
        $item_title .= ' - ' . wpinv_get_cart_item_price_name( $item );
502
    }
503
    */
504
505
    return apply_filters( 'wpinv_get_cart_item_name', $item_title, $item['id'], $item );
506
}
507
508
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...
509
    return false;
510
}
511
512
function wpinv_get_item_position_in_cart( $item_id = 0, $options = array() ) {
513
    $cart_items = wpinv_get_cart_contents();
514
515
    if ( !is_array( $cart_items ) ) {
516
        return false; // Empty cart
517
    } else {
518
        foreach ( $cart_items as $position => $item ) {
519
            if ( $item['id'] == $item_id ) {
520
                if ( isset( $options['price_id'] ) && isset( $item['options']['price_id'] ) ) {
521
                    if ( (int) $options['price_id'] == (int) $item['options']['price_id'] ) {
522
                        return $position;
523
                    }
524
                } else {
525
                    return $position;
526
                }
527
            }
528
        }
529
    }
530
531
    return false; // Not found
532
}
533
534
function wpinv_get_cart_item_quantity( $item ) {
535
    if ( wpinv_item_quantities_enabled() ) {
536
        $quantity = !empty( $item['quantity'] ) && (int)$item['quantity'] > 0 ? absint( $item['quantity'] ) : 1;
537
    } else {
538
        $quantity = 1;
539
    }
540
    
541
    if ( $quantity < 1 ) {
542
        $quantity = 1;
543
    }
544
    
545
    return apply_filters( 'wpinv_get_cart_item_quantity', $quantity, $item );
546
}
547
548
function wpinv_get_item_suffix( $item, $html = true ) {
549
    if ( empty( $item ) ) {
550
        return NULL;
551
    }
552
    
553
    if ( is_int( $item ) ) {
554
        $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...
555
    }
556
    
557
    if ( !( is_object( $item ) && is_a( $item, 'WPInv_Item' ) ) ) {
558
        return NULL;
559
    }
560
    
561
    $suffix = $item->is_recurring() ? ' <span class="wpi-suffix">' . __( '(r)', 'invoicing' ) . '</span>' : '';
562
    
563
    if ( !$html && $suffix ) {
564
        $suffix = strip_tags( $suffix );
565
    }
566
    
567
    return apply_filters( 'wpinv_get_item_suffix', $suffix, $item, $html );
568
}
569
570
function wpinv_remove_item( $item = 0, $force_delete = false ) {
571
    if ( empty( $item ) ) {
572
        return NULL;
573
    }
574
    
575
    if ( is_int( $item ) ) {
576
        $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...
577
    }
578
    
579
    if ( !( is_object( $item ) && is_a( $item, 'WPInv_Item' ) ) ) {
580
        return NULL;
581
    }
582
    
583
    do_action( 'wpinv_pre_delete_item', $item );
584
585
    wp_delete_post( $item->ID, $force_delete );
586
587
    do_action( 'wpinv_post_delete_item', $item );
588
}
589
590
function wpinv_can_delete_item( $post_id ) {
591
    $return = current_user_can( 'manage_options' ) ? true : false;
592
    
593
    if ( $return && wpinv_item_in_use( $post_id ) ) {
594
        $return = false; // Don't delete item already use in invoices.
595
    }
596
    
597
    return apply_filters( 'wpinv_can_delete_item', $return, $post_id );
598
}
599
600
function wpinv_admin_action_delete() {
601
    $screen = get_current_screen();
602
    
603
    if ( !empty( $screen->post_type ) && $screen->post_type == 'wpi_item' && !empty( $_REQUEST['post'] ) && is_array( $_REQUEST['post'] ) ) {
604
        $post_ids = array();
605
        
606
        foreach ( $_REQUEST['post'] as $post_id ) {
607
            if ( !wpinv_can_delete_item( $post_id ) ) {
608
                continue;
609
            }
610
            
611
            $post_ids[] = $post_id;
612
        }
613
        
614
        $_REQUEST['post'] = $post_ids;
615
    }
616
}
617
add_action( 'admin_action_trash', 'wpinv_admin_action_delete', -10 );
618
add_action( 'admin_action_delete', 'wpinv_admin_action_delete', -10 );
619
620
function wpinv_check_delete_item( $check, $post, $force_delete ) {
621
    if ( $post->post_type == 'wpi_item' ) {
622
        if ( $force_delete && !wpinv_can_delete_item( $post->ID ) ) {
623
            return true;
624
        }
625
    }
626
    
627
    return $check;
628
}
629
add_filter( 'pre_delete_post', 'wpinv_check_delete_item', 10, 3 );
630
631
function wpinv_item_in_use( $item_id ) {
632
    global $wpdb, $wpi_items_in_use;
633
    
634
    if ( !$item_id > 0 ) {
635
        return false;
636
    }
637
    
638
    if ( !empty( $wpi_items_in_use ) ) {
639
        if ( isset( $wpi_items_in_use[$item_id] ) ) {
640
            return $wpi_items_in_use[$item_id];
641
        }
642
    } else {
643
        $wpi_items_in_use = array();
644
    }
645
    
646
    $statuses   = array_keys( wpinv_get_invoice_statuses( true ) );
647
    
648
    $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 )";
649
    $in_use = $wpdb->get_var( $query ) > 0 ? true : false;
650
    
651
    $wpi_items_in_use[$item_id] = $in_use;
652
    
653
    return $in_use;
654
}
655
656
function wpinv_create_item( $args = array(), $wp_error = false, $force_update = false ) {
657
    // Set some defaults
658
    $defaults = array(
659
        'type'                 => 'custom',                                                // Optional. Item type. Default 'custom'.
660
        'title'                => '',                                                      // Required. Item title.
661
        'custom_id'            => 0,                                                       // Optional. Any integer or non numeric id. Must be unique within item type.
662
        'price'                => '0.00',                                                  // Optional. Item price. Default '0.00'.
663
        'status'               => 'pending',                                               // Optional. pending, publish
664
        'custom_name'          => '',                                                      // Optional. Plural sub title for item.
665
        'custom_singular_name' => '',                                                      // Optional. Singular sub title for item.
666
        'vat_rule'             => 'digital',                                               // Optional. digital => Digital item, physical => Physical item
667
        'editable'             => true,                                                    // Optional. Item editable from Items list page? Default true.
668
        'excerpt'              => '',                                                      // Optional. Item short description
669
        /* Recurring item fields */
670
        'is_recurring'         => 0,                                                       // Optional. 1 => Allow recurring or 0 => Don't allow recurring
671
        'recurring_period'     => 'M',                                                     // Optional. D => Daily, W => Weekly, M => Monthly, Y => Yearly
672
        'recurring_interval'   => 0,                                                       // Optional. Integer value between 1 - 90.
673
        'recurring_limit'      => 0,                                                       // Optional. Any integer number. 0 for recurring forever until cancelled.
674
        'free_trial'           => 0,                                                       // Optional. 1 => Allow free trial or 0 => Don't free trial
675
        'trial_period'         => 'M',                                                     // Optional. D => Daily, W => Weekly, M => Monthly, Y => Yearly
676
        'trial_interval'       => 0,                                                       // Optional. Any integer number.
677
    );
678
    
679
    $data = wp_parse_args( $args, $defaults );
680
    
681
    if ( empty( $data['type'] ) ) {
682
        $data['type'] = 'custom';
683
    }
684
    
685
    if ( !empty( $data['custom_id'] ) ) {
686
        $item = wpinv_get_item_by( 'custom_id', $data['custom_id'], $data['type'] );
687
    } else {
688
        $item = NULL;
689
    }
690
    
691
    if ( !$force_update && !empty( $item ) ) {
692
        return $item;
693
    }
694
        
695
    $meta                           = array();
696
    $meta['type']                   = $data['type'];
697
    $meta['custom_id']              = $data['custom_id'];
698
    $meta['custom_singular_name']   = $data['custom_singular_name'];
699
    $meta['custom_name']            = $data['custom_name'];
700
    $meta['price']                  = wpinv_round_amount( $data['price'] );
701
    $meta['editable']               = (int)$data['editable'];
702
    $meta['vat_rule']               = $data['vat_rule'];
703
    $meta['vat_class']              = '_standard';
704
    
705
    if ( !empty( $data['is_recurring'] ) ) {
706
        $meta['is_recurring']       = $data['is_recurring'];
707
        $meta['recurring_period']   = $data['recurring_period'];
708
        $meta['recurring_interval'] = absint( $data['recurring_interval'] );
709
        $meta['recurring_limit']    = absint( $data['recurring_limit'] );
710
        $meta['free_trial']         = $data['free_trial'];
711
        $meta['trial_period']       = $data['trial_period'];
712
        $meta['trial_interval']     = absint( $data['trial_interval'] );
713 View Code Duplication
    } else {
714
        $meta['is_recurring']       = 0;
715
        $meta['recurring_period']   = '';
716
        $meta['recurring_interval'] = '';
717
        $meta['recurring_limit']    = '';
718
        $meta['free_trial']         = 0;
719
        $meta['trial_period']       = '';
720
        $meta['trial_interval']     = '';
721
    }
722
    
723
    $post_data  = array( 
724
        'post_title'    => $data['title'],
725
        'post_excerpt'  => $data['excerpt'],
726
        'post_status'   => $data['status'],
727
        'meta'          => $meta
728
    );
729
730
    if ( !empty( $item ) ) {
731
        $item->update( $post_data, $wp_error );
732
    } else {
733
        $item = new WPInv_Item();
734
        $item->create( $post_data, $wp_error );
735
    }
736
    
737
    return $item;
738
}