Passed
Pull Request — master (#47)
by Kiran
04:17
created

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

Complexity

Conditions 11
Paths 22

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 18
nc 22
nop 4
dl 0
loc 33
rs 5.2653
c 0
b 0
f 0

How to fix   Complexity   

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