Passed
Pull Request — master (#87)
by Kiran
04:14
created

wpinv-template-functions.php ➔ wpinv_invalid_invoice_content()   D

Complexity

Conditions 10
Paths 7

Size

Total Lines 32
Code Lines 20

Duplication

Lines 12
Ratio 37.5 %

Importance

Changes 0
Metric Value
cc 10
eloc 20
nc 7
nop 0
dl 12
loc 32
rs 4.8196
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
/**
3
 * Contains functions related to Invoicing plugin.
4
 *
5
 * @since 1.0.0
6
 * @package Invoicing
7
 */
8
 
9
// MUST have WordPress.
10
if ( !defined( 'WPINC' ) ) {
11
    exit( 'Do NOT access this file directly: ' . basename( __FILE__ ) );
12
}
13
14
if ( !is_admin() ) {
15
    add_filter( 'template_include', 'wpinv_template', 10, 1 );
16
    add_action( 'wpinv_invoice_print_body_start', 'wpinv_display_invoice_top_bar' );
17
    add_action( 'wpinv_invoice_top_bar_left', 'wpinv_invoice_display_left_actions' );
18
    add_action( 'wpinv_invoice_top_bar_right', 'wpinv_invoice_display_right_actions' );
19
}
20
21
function wpinv_template_path() {
22
    return apply_filters( 'wpinv_template_path', 'invoicing/' );
23
}
24
25
function wpinv_post_class( $classes, $class, $post_id ) {
0 ignored issues
show
Unused Code introduced by
The parameter $class 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...
26
    global $pagenow, $typenow;
27
28
    if ( $pagenow == 'edit.php' && $typenow == 'wpi_item' && get_post_type( $post_id ) == $typenow && get_post_meta( $post_id, '_wpinv_type', true ) == 'package' ) {
29
        $classes[] = 'wpi-gd-package';
30
    }
31
    return $classes;
32
}
33
add_filter( 'post_class', 'wpinv_post_class', 10, 3 );
34
35
function wpinv_display_invoice_top_bar( $invoice ) {
36
    if ( empty( $invoice ) ) {
37
        return;
38
    }
39
    ?>
40
    <div class="row wpinv-top-bar no-print">
41
        <div class="container">
42
            <div class="col-xs-6">
43
                <?php do_action( 'wpinv_invoice_top_bar_left', $invoice );?>
44
            </div>
45
            <div class="col-xs-6 text-right">
46
                <?php do_action( 'wpinv_invoice_top_bar_right', $invoice );?>
47
            </div>
48
        </div>
49
    </div>
50
    <?php
51
}
52
53
function wpinv_invoice_display_left_actions( $invoice ) {
54
    if ( empty( $invoice ) ) {
55
        return; // Exit if invoice is not set.
56
    }
57
    
58
    if ( $invoice->post_type == 'wpi_invoice' ) {
59
        if ( $invoice->needs_payment() ) {
60
            ?> <a class="btn btn-success btn-sm" title="<?php esc_attr_e( 'Pay This Invoice', 'invoicing' ); ?>" href="<?php echo esc_url( $invoice->get_checkout_payment_url() ); ?>"><?php _e( 'Pay For Invoice', 'invoicing' ); ?></a><?php
61
        }
62
    }
63
    do_action('wpinv_invoice_display_left_actions', $invoice);
64
}
65
66
function wpinv_invoice_display_right_actions( $invoice ) {
67
    if ( empty( $invoice ) ) {
68
        return; // Exit if invoice is not set.
69
    }
70
71
    if ( $invoice->post_type == 'wpi_invoice' ) { ?>
72
        <a class="btn btn-primary btn-sm" onclick="window.print();" href="javascript:void(0)"><?php _e( 'Print Invoice', 'invoicing' ); ?></a>
73
        <?php if ( is_user_logged_in() ) { ?>
74
        &nbsp;&nbsp;<a class="btn btn-warning btn-sm" href="<?php echo esc_url( wpinv_get_history_page_uri() ); ?>"><?php _e( 'Invoice History', 'invoicing' ); ?></a>
75
        <?php }
76
    }
77
    do_action('wpinv_invoice_display_right_actions', $invoice);
78
}
79
80 View Code Duplication
function wpinv_before_invoice_content( $content ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
    global $post;
82
83
    if ( !empty( $post ) && $post->post_type == 'wpi_invoice' && is_singular( 'wpi_invoice' ) && is_main_query() ) {
84
        ob_start();
85
        do_action( 'wpinv_before_invoice_content', $post->ID );
86
        $content = ob_get_clean() . $content;
87
    }
88
89
    return $content;
90
}
91
add_filter( 'the_content', 'wpinv_before_invoice_content' );
92
93 View Code Duplication
function wpinv_after_invoice_content( $content ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
94
    global $post;
95
96
    if ( !empty( $post ) && $post->post_type == 'wpi_invoice' && is_singular( 'wpi_invoice' ) && is_main_query() ) {
97
        ob_start();
98
        do_action( 'wpinv_after_invoice_content', $post->ID );
99
        $content .= ob_get_clean();
100
    }
101
102
    return $content;
103
}
104
add_filter( 'the_content', 'wpinv_after_invoice_content' );
105
106
function wpinv_get_templates_dir() {
107
    return WPINV_PLUGIN_DIR . 'templates';
108
}
109
110
function wpinv_get_templates_url() {
111
    return WPINV_PLUGIN_URL . 'templates';
112
}
113
114
function wpinv_get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
115
    if ( ! empty( $args ) && is_array( $args ) ) {
116
		extract( $args );
117
	}
118
119
	$located = wpinv_locate_template( $template_name, $template_path, $default_path );
120
	// Allow 3rd party plugin filter template file from their plugin.
121
	$located = apply_filters( 'wpinv_get_template', $located, $template_name, $args, $template_path, $default_path );
122
123
	if ( ! file_exists( $located ) ) {
124
        _doing_it_wrong( __FUNCTION__, sprintf( '<code>%s</code> does not exist.', $located ), '2.1' );
125
		return;
126
	}
127
128
	do_action( 'wpinv_before_template_part', $template_name, $template_path, $located, $args );
129
130
	include( $located );
131
132
	do_action( 'wpinv_after_template_part', $template_name, $template_path, $located, $args );
133
}
134
135
function wpinv_get_template_html( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
136
	ob_start();
137
	wpinv_get_template( $template_name, $args, $template_path, $default_path );
138
	return ob_get_clean();
139
}
140
141
function wpinv_locate_template( $template_name, $template_path = '', $default_path = '' ) {
142
    if ( ! $template_path ) {
143
        $template_path = wpinv_template_path();
144
    }
145
146
    if ( ! $default_path ) {
147
        $default_path = WPINV_PLUGIN_DIR . 'templates/';
148
    }
149
150
    // Look within passed path within the theme - this is priority.
151
    $template = locate_template(
152
        array(
153
            trailingslashit( $template_path ) . $template_name,
154
            $template_name
155
        )
156
    );
157
158
    // Get default templates/
159
    if ( !$template && $default_path ) {
160
        $template = trailingslashit( $default_path ) . $template_name;
161
    }
162
163
    // Return what we found.
164
    return apply_filters( 'wpinv_locate_template', $template, $template_name, $template_path );
165
}
166
167
function wpinv_get_template_part( $slug, $name = null, $load = true ) {
168
	do_action( 'get_template_part_' . $slug, $slug, $name );
169
170
	// Setup possible parts
171
	$templates = array();
172
	if ( isset( $name ) )
173
		$templates[] = $slug . '-' . $name . '.php';
174
	$templates[] = $slug . '.php';
175
176
	// Allow template parts to be filtered
177
	$templates = apply_filters( 'wpinv_get_template_part', $templates, $slug, $name );
178
179
	// Return the part that is found
180
	return wpinv_locate_tmpl( $templates, $load, false );
181
}
182
183
function wpinv_locate_tmpl( $template_names, $load = false, $require_once = true ) {
184
	// No file found yet
185
	$located = false;
186
187
	// Try to find a template file
188
	foreach ( (array)$template_names as $template_name ) {
189
190
		// Continue if template is empty
191
		if ( empty( $template_name ) )
192
			continue;
193
194
		// Trim off any slashes from the template name
195
		$template_name = ltrim( $template_name, '/' );
196
197
		// try locating this template file by looping through the template paths
198
		foreach( wpinv_get_theme_template_paths() as $template_path ) {
199
200
			if( file_exists( $template_path . $template_name ) ) {
201
				$located = $template_path . $template_name;
202
				break;
203
			}
204
		}
205
206
		if( !empty( $located ) ) {
207
			break;
208
		}
209
	}
210
211
	if ( ( true == $load ) && ! empty( $located ) )
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
212
		load_template( $located, $require_once );
213
214
	return $located;
215
}
216
217
function wpinv_get_theme_template_paths() {
218
	$template_dir = wpinv_get_theme_template_dir_name();
219
220
	$file_paths = array(
221
		1 => trailingslashit( get_stylesheet_directory() ) . $template_dir,
222
		10 => trailingslashit( get_template_directory() ) . $template_dir,
223
		100 => wpinv_get_templates_dir()
224
	);
225
226
	$file_paths = apply_filters( 'wpinv_template_paths', $file_paths );
227
228
	// sort the file paths based on priority
229
	ksort( $file_paths, SORT_NUMERIC );
230
231
	return array_map( 'trailingslashit', $file_paths );
232
}
233
234
function wpinv_get_theme_template_dir_name() {
235
	return trailingslashit( apply_filters( 'wpinv_templates_dir', 'wpinv_templates' ) );
236
}
237
238
function wpinv_checkout_meta_tags() {
239
240
	$pages   = array();
241
	$pages[] = wpinv_get_option( 'success_page' );
242
	$pages[] = wpinv_get_option( 'failure_page' );
243
	$pages[] = wpinv_get_option( 'invoice_history_page' );
244
245
	if( !wpinv_is_checkout() && !is_page( $pages ) ) {
246
		return;
247
	}
248
249
	echo '<meta name="robots" content="noindex,nofollow" />' . "\n";
250
}
251
add_action( 'wp_head', 'wpinv_checkout_meta_tags' );
252
253
function wpinv_add_body_classes( $class ) {
254
	$classes = (array)$class;
255
256
	if( wpinv_is_checkout() ) {
257
		$classes[] = 'wpinv-checkout';
258
		$classes[] = 'wpinv-page';
259
	}
260
261
	if( wpinv_is_success_page() ) {
262
		$classes[] = 'wpinv-success';
263
		$classes[] = 'wpinv-page';
264
	}
265
266
	if( wpinv_is_failed_transaction_page() ) {
267
		$classes[] = 'wpinv-failed-transaction';
268
		$classes[] = 'wpinv-page';
269
	}
270
271
	if( wpinv_is_invoice_history_page() ) {
272
		$classes[] = 'wpinv-history';
273
		$classes[] = 'wpinv-page';
274
	}
275
276
	if( wpinv_is_test_mode() ) {
277
		$classes[] = 'wpinv-test-mode';
278
		$classes[] = 'wpinv-page';
279
	}
280
281
	return array_unique( $classes );
282
}
283
add_filter( 'body_class', 'wpinv_add_body_classes' );
284
285
function wpinv_html_dropdown( $name = 'wpinv_discounts', $selected = 0, $status = '' ) {
286
    $args = array( 'nopaging' => true );
287
288
    if ( ! empty( $status ) )
289
        $args['post_status'] = $status;
290
291
    $discounts = wpinv_get_discounts( $args );
292
    $options   = array();
293
294
    if ( $discounts ) {
295
        foreach ( $discounts as $discount ) {
296
            $options[ absint( $discount->ID ) ] = esc_html( get_the_title( $discount->ID ) );
297
        }
298
    } else {
299
        $options[0] = __( 'No discounts found', 'invoicing' );
300
    }
301
302
    $output = wpinv_html_select( array(
303
        'name'             => $name,
304
        'selected'         => $selected,
305
        'options'          => $options,
306
        'show_option_all'  => false,
307
        'show_option_none' => false,
308
    ) );
309
310
    return $output;
311
}
312
313
function wpinv_html_year_dropdown( $name = 'year', $selected = 0, $years_before = 5, $years_after = 0 ) {
314
    $current     = date( 'Y' );
315
    $start_year  = $current - absint( $years_before );
316
    $end_year    = $current + absint( $years_after );
317
    $selected    = empty( $selected ) ? date( 'Y' ) : $selected;
318
    $options     = array();
319
320
    while ( $start_year <= $end_year ) {
321
        $options[ absint( $start_year ) ] = $start_year;
322
        $start_year++;
323
    }
324
325
    $output = wpinv_html_select( array(
326
        'name'             => $name,
327
        'selected'         => $selected,
328
        'options'          => $options,
329
        'show_option_all'  => false,
330
        'show_option_none' => false
331
    ) );
332
333
    return $output;
334
}
335
336
function wpinv_html_month_dropdown( $name = 'month', $selected = 0 ) {
337
    $month   = 1;
338
    $options = array();
339
    $selected = empty( $selected ) ? date( 'n' ) : $selected;
340
341
    while ( $month <= 12 ) {
342
        $options[ absint( $month ) ] = wpinv_month_num_to_name( $month );
343
        $month++;
344
    }
345
346
    $output = wpinv_html_select( array(
347
        'name'             => $name,
348
        'selected'         => $selected,
349
        'options'          => $options,
350
        'show_option_all'  => false,
351
        'show_option_none' => false
352
    ) );
353
354
    return $output;
355
}
356
357
function wpinv_html_select( $args = array() ) {
358
    $defaults = array(
359
        'options'          => array(),
360
        'name'             => null,
361
        'class'            => '',
362
        'id'               => '',
363
        'selected'         => 0,
364
        'chosen'           => false,
365
        'placeholder'      => null,
366
        'multiple'         => false,
367
        'show_option_all'  => _x( 'All', 'all dropdown items', 'invoicing' ),
368
        'show_option_none' => _x( 'None', 'no dropdown items', 'invoicing' ),
369
        'data'             => array(),
370
        'onchange'         => null,
371
        'required'         => false,
372
        'disabled'         => false,
373
        'readonly'         => false,
374
    );
375
376
    $args = wp_parse_args( $args, $defaults );
377
378
    $data_elements = '';
379
    foreach ( $args['data'] as $key => $value ) {
380
        $data_elements .= ' data-' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
381
    }
382
383
    if( $args['multiple'] ) {
384
        $multiple = ' MULTIPLE';
385
    } else {
386
        $multiple = '';
387
    }
388
389
    if( $args['chosen'] ) {
390
        $args['class'] .= ' wpinv-select-chosen';
391
    }
392
393
    if( $args['placeholder'] ) {
394
        $placeholder = $args['placeholder'];
395
    } else {
396
        $placeholder = '';
397
    }
398
    
399
    $options = '';
400 View Code Duplication
    if( !empty( $args['onchange'] ) ) {
401
        $options .= ' onchange="' . esc_attr( $args['onchange'] ) . '"';
402
    }
403
    
404
    if( !empty( $args['required'] ) ) {
405
        $options .= ' required="required"';
406
    }
407
    
408
    if( !empty( $args['disabled'] ) ) {
409
        $options .= ' disabled';
410
    }
411
    
412
    if( !empty( $args['readonly'] ) ) {
413
        $options .= ' readonly';
414
    }
415
416
    $class  = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['class'] ) ) );
417
    $output = '<select name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" class="wpinv-select ' . $class . '"' . $multiple . ' data-placeholder="' . $placeholder . '" ' . trim( $options ) . $data_elements . '>';
418
419 View Code Duplication
    if ( $args['show_option_all'] ) {
420
        if( $args['multiple'] ) {
421
            $selected = selected( true, in_array( 0, $args['selected'] ), false );
422
        } else {
423
            $selected = selected( $args['selected'], 0, false );
424
        }
425
        $output .= '<option value="all"' . $selected . '>' . esc_html( $args['show_option_all'] ) . '</option>';
426
    }
427
428
    if ( !empty( $args['options'] ) ) {
429
430 View Code Duplication
        if ( $args['show_option_none'] ) {
431
            if( $args['multiple'] ) {
432
                $selected = selected( true, in_array( "", $args['selected'] ), false );
433
            } else {
434
                $selected = selected( $args['selected'] === "", true, false );
435
            }
436
            $output .= '<option value=""' . $selected . '>' . esc_html( $args['show_option_none'] ) . '</option>';
437
        }
438
439
        foreach( $args['options'] as $key => $option ) {
440
441
            if( $args['multiple'] && is_array( $args['selected'] ) ) {
442
                $selected = selected( true, (bool)in_array( $key, $args['selected'] ), false );
443
            } else {
444
                $selected = selected( $args['selected'], $key, false );
445
            }
446
447
            $output .= '<option value="' . esc_attr( $key ) . '"' . $selected . '>' . esc_html( $option ) . '</option>';
448
        }
449
    }
450
451
    $output .= '</select>';
452
453
    return $output;
454
}
455
456
function wpinv_item_dropdown( $args = array() ) {
457
    $defaults = array(
458
        'name'              => 'wpi_item',
459
        'id'                => 'wpi_item',
460
        'class'             => '',
461
        'multiple'          => false,
462
        'selected'          => 0,
463
        'chosen'            => false,
464
        'number'            => 100,
465
        'placeholder'       => __( 'Choose a item', 'invoicing' ),
466
        'data'              => array( 'search-type' => 'item' ),
467
        'show_option_all'   => false,
468
        'show_option_none'  => false,
469
        'with_packages'     => true,
470
        'show_recurring'    => false,
471
    );
472
473
    $args = wp_parse_args( $args, $defaults );
474
475
    $item_args = array(
476
        'post_type'      => 'wpi_item',
477
        'orderby'        => 'title',
478
        'order'          => 'ASC',
479
        'posts_per_page' => $args['number']
480
    );
481
    
482
    if ( !$args['with_packages'] ) {
483
        $item_args['meta_query'] = array(
484
            array(
485
                'key'       => '_wpinv_type',
486
                'compare'   => '!=',
487
                'value'     => 'package'
488
            ),
489
        );
490
    }
491
492
    $items      = get_posts( $item_args );
493
    $options    = array();
494
    if ( $items ) {
495
        foreach ( $items as $item ) {
496
            $title = esc_html( $item->post_title );
497
            
498
            if ( !empty( $args['show_recurring'] ) ) {
499
                $title .= wpinv_get_item_suffix( $item->ID, false );
500
            }
501
            
502
            $options[ absint( $item->ID ) ] = $title;
503
        }
504
    }
505
506
    // This ensures that any selected items are included in the drop down
507
    if( is_array( $args['selected'] ) ) {
508
        foreach( $args['selected'] as $item ) {
509
            if( ! in_array( $item, $options ) ) {
510
                $title = get_the_title( $item );
511
                if ( !empty( $args['show_recurring'] ) ) {
512
                    $title .= wpinv_get_item_suffix( $item, false );
513
                }
514
                $options[$item] = $title;
515
            }
516
        }
517
    } elseif ( is_numeric( $args['selected'] ) && $args['selected'] !== 0 ) {
518
        if ( ! in_array( $args['selected'], $options ) ) {
519
            $title = get_the_title( $args['selected'] );
520
            if ( !empty( $args['show_recurring'] ) ) {
521
                $title .= wpinv_get_item_suffix( $args['selected'], false );
522
            }
523
            $options[$args['selected']] = get_the_title( $args['selected'] );
524
        }
525
    }
526
527
    $output = wpinv_html_select( array(
528
        'name'             => $args['name'],
529
        'selected'         => $args['selected'],
530
        'id'               => $args['id'],
531
        'class'            => $args['class'],
532
        'options'          => $options,
533
        'chosen'           => $args['chosen'],
534
        'multiple'         => $args['multiple'],
535
        'placeholder'      => $args['placeholder'],
536
        'show_option_all'  => $args['show_option_all'],
537
        'show_option_none' => $args['show_option_none'],
538
        'data'             => $args['data'],
539
    ) );
540
541
    return $output;
542
}
543
544
function wpinv_html_checkbox( $args = array() ) {
545
    $defaults = array(
546
        'name'     => null,
547
        'current'  => null,
548
        'class'    => 'wpinv-checkbox',
549
        'options'  => array(
550
            'disabled' => false,
551
            'readonly' => false
552
        )
553
    );
554
555
    $args = wp_parse_args( $args, $defaults );
556
557
    $class = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['class'] ) ) );
558
    $options = '';
559
    if ( ! empty( $args['options']['disabled'] ) ) {
560
        $options .= ' disabled="disabled"';
561
    } elseif ( ! empty( $args['options']['readonly'] ) ) {
562
        $options .= ' readonly';
563
    }
564
565
    $output = '<input type="checkbox"' . $options . ' name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['name'] ) . '" class="' . $class . ' ' . esc_attr( $args['name'] ) . '" ' . checked( 1, $args['current'], false ) . ' />';
566
567
    return $output;
568
}
569
570
function wpinv_html_text( $args = array() ) {
571
    // Backwards compatibility
572
    if ( func_num_args() > 1 ) {
573
        $args = func_get_args();
574
575
        $name  = $args[0];
576
        $value = isset( $args[1] ) ? $args[1] : '';
577
        $label = isset( $args[2] ) ? $args[2] : '';
578
        $desc  = isset( $args[3] ) ? $args[3] : '';
579
    }
580
581
    $defaults = array(
582
        'id'           => '',
583
        'name'         => isset( $name )  ? $name  : 'text',
584
        'value'        => isset( $value ) ? $value : null,
585
        'label'        => isset( $label ) ? $label : null,
586
        'desc'         => isset( $desc )  ? $desc  : null,
587
        'placeholder'  => '',
588
        'class'        => 'regular-text',
589
        'disabled'     => false,
590
        'readonly'     => false,
591
        'required'     => false,
592
        'autocomplete' => '',
593
        'data'         => false
594
    );
595
596
    $args = wp_parse_args( $args, $defaults );
597
598
    $class = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['class'] ) ) );
599
    $options = '';
600
    if( $args['required'] ) {
601
        $options .= ' required="required"';
602
    }
603
    if( $args['readonly'] ) {
604
        $options .= ' readonly';
605
    }
606
    if( $args['readonly'] ) {
607
        $options .= ' readonly';
608
    }
609
610
    $data = '';
611
    if ( !empty( $args['data'] ) ) {
612
        foreach ( $args['data'] as $key => $value ) {
613
            $data .= 'data-' . wpinv_sanitize_key( $key ) . '="' . esc_attr( $value ) . '" ';
614
        }
615
    }
616
617
    $output = '<span id="wpinv-' . wpinv_sanitize_key( $args['name'] ) . '-wrap">';
618
    $output .= '<label class="wpinv-label" for="' . wpinv_sanitize_key( $args['id'] ) . '">' . esc_html( $args['label'] ) . '</label>';
619 View Code Duplication
    if ( ! empty( $args['desc'] ) ) {
620
        $output .= '<span class="wpinv-description">' . esc_html( $args['desc'] ) . '</span>';
621
    }
622
623
    $output .= '<input type="text" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] )  . '" autocomplete="' . esc_attr( $args['autocomplete'] )  . '" value="' . esc_attr( $args['value'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" class="' . $class . '" ' . $data . ' ' . trim( $options ) . '/>';
624
625
    $output .= '</span>';
626
627
    return $output;
628
}
629
630
function wpinv_html_date_field( $args = array() ) {
631
    if( empty( $args['class'] ) ) {
632
        $args['class'] = 'wpiDatepicker';
633
    } elseif( ! strpos( $args['class'], 'wpiDatepicker' ) ) {
634
        $args['class'] .= ' wpiDatepicker';
635
    }
636
637
    return wpinv_html_text( $args );
638
}
639
640
function wpinv_html_textarea( $args = array() ) {
641
    $defaults = array(
642
        'name'        => 'textarea',
643
        'value'       => null,
644
        'label'       => null,
645
        'desc'        => null,
646
        'class'       => 'large-text',
647
        'disabled'    => false
648
    );
649
650
    $args = wp_parse_args( $args, $defaults );
651
652
    $class = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['class'] ) ) );
653
    $disabled = '';
654
    if( $args['disabled'] ) {
655
        $disabled = ' disabled="disabled"';
656
    }
657
658
    $output = '<span id="wpinv-' . wpinv_sanitize_key( $args['name'] ) . '-wrap">';
659
    $output .= '<label class="wpinv-label" for="' . wpinv_sanitize_key( $args['name'] ) . '">' . esc_html( $args['label'] ) . '</label>';
660
    $output .= '<textarea name="' . esc_attr( $args['name'] ) . '" id="' . wpinv_sanitize_key( $args['name'] ) . '" class="' . $class . '"' . $disabled . '>' . esc_attr( $args['value'] ) . '</textarea>';
661
662 View Code Duplication
    if ( ! empty( $args['desc'] ) ) {
663
        $output .= '<span class="wpinv-description">' . esc_html( $args['desc'] ) . '</span>';
664
    }
665
    $output .= '</span>';
666
667
    return $output;
668
}
669
670
function wpinv_html_ajax_user_search( $args = array() ) {
671
    $defaults = array(
672
        'name'        => 'user_id',
673
        'value'       => null,
674
        'placeholder' => __( 'Enter username', 'invoicing' ),
675
        'label'       => null,
676
        'desc'        => null,
677
        'class'       => '',
678
        'disabled'    => false,
679
        'autocomplete'=> 'off',
680
        'data'        => false
681
    );
682
683
    $args = wp_parse_args( $args, $defaults );
684
685
    $args['class'] = 'wpinv-ajax-user-search ' . $args['class'];
686
687
    $output  = '<span class="wpinv_user_search_wrap">';
688
        $output .= wpinv_html_text( $args );
689
        $output .= '<span class="wpinv_user_search_results hidden"><a class="wpinv-ajax-user-cancel" title="' . __( 'Cancel', 'invoicing' ) . '" aria-label="' . __( 'Cancel', 'invoicing' ) . '" href="#">x</a><span></span></span>';
690
    $output .= '</span>';
691
692
    return $output;
693
}
694
695
function wpinv_ip_geolocation() {
696
    global $wpinv_euvat;
697
    
698
    $ip         = !empty( $_GET['ip'] ) ? sanitize_text_field( $_GET['ip'] ) : '';    
699
    $content    = '';
0 ignored issues
show
Unused Code introduced by
$content 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...
700
    $iso        = '';
701
    $country    = '';
702
    $region     = '';
703
    $city       = '';
704
    $longitude  = '';
705
    $latitude   = '';
706
    $credit     = '';
707
    $address    = '';
708
    
709
    if ( wpinv_get_option( 'vat_ip_lookup' ) == 'geoip2' && $geoip2_city = $wpinv_euvat->geoip2_city_record( $ip ) ) {
710
        try {
711
            $iso        = $geoip2_city->country->isoCode;
712
            $country    = $geoip2_city->country->name;
713
            $region     = !empty( $geoip2_city->subdivisions ) && !empty( $geoip2_city->subdivisions[0]->name ) ? $geoip2_city->subdivisions[0]->name : '';
714
            $city       = $geoip2_city->city->name;
715
            $longitude  = $geoip2_city->location->longitude;
716
            $latitude   = $geoip2_city->location->latitude;
717
            $credit     = __( 'Geolocated using the information by MaxMind, available from <a href="http://www.maxmind.com" target="_blank">www.maxmind.com</a>', 'invoicing' );
718
        } catch( Exception $e ) { }
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
719
    }
720
    
721
    if ( !( $iso && $longitude && $latitude ) && function_exists( 'simplexml_load_file' ) ) {
722
        try {
723
            $load_xml = simplexml_load_file( 'http://www.geoplugin.net/xml.gp?ip=' . $ip );
724
            
725
            if ( !empty( $load_xml ) && isset( $load_xml->geoplugin_countryCode ) && !empty( $load_xml->geoplugin_latitude ) && !empty( $load_xml->geoplugin_longitude ) ) {
726
                $iso        = $load_xml->geoplugin_countryCode;
0 ignored issues
show
Bug introduced by
The property geoplugin_countryCode does not seem to exist in SimpleXMLElement.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
727
                $country    = $load_xml->geoplugin_countryName;
0 ignored issues
show
Bug introduced by
The property geoplugin_countryName does not seem to exist in SimpleXMLElement.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
728
                $region     = !empty( $load_xml->geoplugin_regionName ) ? $load_xml->geoplugin_regionName : '';
729
                $city       = !empty( $load_xml->geoplugin_city ) ? $load_xml->geoplugin_city : '';
730
                $longitude  = $load_xml->geoplugin_longitude;
0 ignored issues
show
Bug introduced by
The property geoplugin_longitude does not seem to exist in SimpleXMLElement.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
731
                $latitude   = $load_xml->geoplugin_latitude;
0 ignored issues
show
Bug introduced by
The property geoplugin_latitude does not seem to exist in SimpleXMLElement.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
732
                $credit     = $load_xml->geoplugin_credit;
0 ignored issues
show
Bug introduced by
The property geoplugin_credit does not seem to exist in SimpleXMLElement.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
733
                $credit     = __( 'Geolocated using the information by geoPlugin, available from <a href="http://www.geoplugin.com" target="_blank">www.geoplugin.com</a>', 'invoicing' ) . '<br>' . $load_xml->geoplugin_credit;
734
            }
735
        } catch( Exception $e ) { }
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
736
    }
737
    
738
    if ( $iso && $longitude && $latitude ) {
739
        if ( $city ) {
740
            $address .= $city . ', ';
741
        }
742
        
743
        if ( $region ) {
744
            $address .= $region . ', ';
745
        }
746
        
747
        $address .= $country . ' (' . $iso . ')';
748
        $content = '<p>'. sprintf( __( '<b>Address:</b> %s', 'invoicing' ), $address ) . '</p>';
749
        $content .= '<p>'. $credit . '</p>';
750
    } else {
751
        $content = '<p>'. sprintf( __( 'Unable to find geolocation for the IP address: %s', 'invoicing' ), $ip ) . '</p>';
752
    }
753
    ?>
754
<!DOCTYPE html>
755
<html><head><title><?php echo sprintf( __( 'IP: %s', 'invoicing' ), $ip );?></title><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-rc.1/leaflet.css" /><style>html,body{height:100%;margin:0;padding:0;width:100%}body{text-align:center;background:#fff;color:#222;font-size:small;}body,p{font-family: arial,sans-serif}#map{margin:auto;width:100%;height:calc(100% - 120px);min-height:240px}</style></head>
756
<body>
757
    <?php if ( $latitude && $latitude ) { ?>
758
    <div id="map"></div>
759
        <script src="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-rc.1/leaflet.js"></script>
760
        <script type="text/javascript">
761
        var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
762
            osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
763
            osm = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib}),
764
            latlng = new L.LatLng(<?php echo $latitude;?>, <?php echo $longitude;?>);
765
766
        var map = new L.Map('map', {center: latlng, zoom: 12, layers: [osm]});
767
768
        var marker = new L.Marker(latlng);
769
        map.addLayer(marker);
770
771
        marker.bindPopup("<p><?php esc_attr_e( $address );?></p>");
772
    </script>
773
    <?php } ?>
774
    <div style="height:100px"><?php echo $content; ?></div>
775
</body></html>
776
<?php
777
    exit;
778
}
779
add_action( 'wp_ajax_wpinv_ip_geolocation', 'wpinv_ip_geolocation' );
780
add_action( 'wp_ajax_nopriv_wpinv_ip_geolocation', 'wpinv_ip_geolocation' );
781
782
// Set up the template for the invoice.
783
function wpinv_template( $template ) {
784
    global $post, $wp_query;
785
    
786
    if ( ( is_single() || is_404() ) && !empty( $post->ID ) && (get_post_type( $post->ID ) == 'wpi_invoice' or get_post_type( $post->ID ) == 'wpi_quote')) {
787
        if ( wpinv_user_can_view_invoice( $post->ID ) ) {
788
            $template = wpinv_get_template_part( 'wpinv-invoice-print', false, false );
789
        } else {
790
            $template = wpinv_get_template_part( 'wpinv-invalid-access', false, false );
791
        }
792
    }
793
794
    return $template;
795
}
796
797
function wpinv_get_business_address() {
798
    $business_address   = wpinv_store_address();
799
    $business_address   = !empty( $business_address ) ? wpautop( wp_kses_post( $business_address ) ) : '';
800
    
801
    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
49% 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...
802
    $default_country    = wpinv_get_default_country();
803
    $default_state      = wpinv_get_default_state();
804
    
805
    $address_fields = array();
806
    if ( !empty( $default_state ) ) {
807
        $address_fields[] = wpinv_state_name( $default_state, $default_country );
808
    }
809
    
810
    if ( !empty( $default_country ) ) {
811
        $address_fields[] = wpinv_country_name( $default_country );
812
    }
813
    
814
    if ( !empty( $address_fields ) ) {
815
        $address_fields = implode( ", ", $address_fields );
816
                
817
        $business_address .= wpautop( wp_kses_post( $address_fields ) );
818
    }
819
    */
820
    
821
    $business_address = $business_address ? '<div class="address">' . $business_address . '</div>' : '';
822
    
823
    return apply_filters( 'wpinv_get_business_address', $business_address );
824
}
825
826
function wpinv_display_from_address() {
827
    global $wpinv_euvat;
828
    
829
    $from_name = $wpinv_euvat->get_company_name();
830
    if (empty($from_name)) {
831
        $from_name = wpinv_get_business_name();
832
    }
833
    ?><div class="from col-xs-2"><strong><?php _e( 'From:', 'invoicing' ) ?></strong></div>
834
    <div class="wrapper col-xs-10">
835
        <div class="name"><?php echo esc_html( $from_name ); ?></div>
836
        <?php if ( $address = wpinv_get_business_address() ) { ?>
837
        <div class="address"><?php echo wpautop( wp_kses_post( $address ) );?></div>
838
        <?php } ?>
839
        <?php if ( $email_from = wpinv_mail_get_from_address() ) { ?>
840
        <div class="email_from"><?php echo wp_sprintf( __( 'Email: %s' ), $email_from );?></div>
841
        <?php } ?>
842
    </div>
843
    <?php
844
}
845
846
function wpinv_watermark( $id = 0 ) {
847
    $output = wpinv_get_watermark( $id );
848
    
849
    return apply_filters( 'wpinv_get_watermark', $output, $id );
850
}
851
852
function wpinv_get_watermark( $id ) {
853
    if ( !$id > 0 ) {
854
        return NULL;
855
    }
856
    $invoice = wpinv_get_invoice( $id );
857
    
858
    if ( !empty( $invoice ) && "wpi_invoice" === $invoice->post_type ) {
859
        if ( $invoice->is_paid() ) {
860
            return __( 'Paid', 'invoicing' );
861
        }
862
        if ( $invoice->is_refunded() ) {
863
            return __( 'Refunded', 'invoicing' );
864
        }
865
        if ( $invoice->has_status( array( 'wpi-cancelled' ) ) ) {
866
            return __( 'Cancelled', 'invoicing' );
867
        }
868
    }
869
    
870
    return NULL;
871
}
872
873
function wpinv_display_invoice_details( $invoice ) {
874
    global $wpinv_euvat;
875
    
876
    $invoice_id = $invoice->ID;
877
    $vat_name   = $wpinv_euvat->get_vat_name();
878
    $use_taxes  = wpinv_use_taxes();
879
    
880
    $invoice_status = wpinv_get_invoice_status( $invoice_id );
881
    
882
    if($invoice->post_type == 'wpi_invoice') $type = 'Invoice';
883
    elseif($invoice->post_type == 'wpi_quote') $type = 'Quote';
884
    ?>
885
    <table class="table table-bordered table-sm">
886
        <?php if ( $invoice_number = wpinv_get_invoice_number( $invoice_id ) ) { ?>
887
            <tr class="wpi-row-number">
888
                <th><?php echo sprintf(__( '%s Number', 'invoicing' ), $type); ?></th>
0 ignored issues
show
Bug introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
889
                <td><?php echo esc_html( $invoice_number ); ?></td>
890
            </tr>
891
        <?php } ?>
892
        <tr class="wpi-row-status">
893
            <th><?php echo wp_sprintf(__( '%s Status', 'invoicing' ), $type); ?></th>
894
            <td><?php echo wpinv_invoice_status_label( $invoice_status, wpinv_get_invoice_status( $invoice_id, true ) ); ?></td>
895
        </tr>
896
        <?php if ( $invoice->is_renewal() ) { ?>
897
        <tr class="wpi-row-parent">
898
            <th><?php echo wp_sprintf(__( 'Parent %s', 'invoicing' ), $type); ?></th>
899
            <td><?php echo wpinv_invoice_link( $invoice->parent_invoice ); ?></td>
900
        </tr>
901
        <?php } ?>
902
        <tr class="wpi-row-gateway">
903
            <th><?php _e( 'Payment Method', 'invoicing' ); ?></th>
904
            <td><?php echo wpinv_get_payment_gateway_name( $invoice_id ); ?></td>
905
        </tr>
906
        <?php if ( $invoice_date = wpinv_get_invoice_date( $invoice_id ) ) { ?>
907
            <tr class="wpi-row-date">
908
                <th><?php echo wp_sprintf(__( '%s Date', 'invoicing' ), $type); ?></th>
909
                <td><?php echo $invoice_date; ?></td>
910
            </tr>
911
        <?php } ?>
912
        <?php if ( wpinv_get_option( 'overdue_active' ) && $invoice->needs_payment() && ( $due_date = $invoice->get_due_date( true ) ) ) { ?>
913
            <tr class="wpi-row-date">
914
                <th><?php _e( 'Due Date', 'invoicing' ); ?></th>
915
                <td><?php echo $due_date; ?></td>
916
            </tr>
917
        <?php } ?>
918
        <?php if ( $owner_vat_number = $wpinv_euvat->get_vat_number() ) { ?>
919
            <tr class="wpi-row-ovatno">
920
                <th><?php echo wp_sprintf( __( 'Owner %s Number', 'invoicing' ), $vat_name ); ?></th>
921
                <td><?php echo $owner_vat_number; ?></td>
922
            </tr>
923
        <?php } ?>
924
        <?php if ( $use_taxes && $user_vat_number = wpinv_get_invoice_vat_number( $invoice_id ) ) { ?>
925
            <tr class="wpi-row-uvatno">
926
                <th><?php echo wp_sprintf( __( 'Your %s Number', 'invoicing' ), $vat_name ); ?></th>
927
                <td><?php echo $user_vat_number; ?></td>
928
            </tr>
929
        <?php } ?>
930
        <tr class="table-active tr-total wpi-row-total">
931
            <th><strong><?php _e( 'Total Amount', 'invoicing' ) ?></strong></th>
932
            <td><strong><?php echo wpinv_payment_total( $invoice_id, true ); ?></strong></td>
933
        </tr>
934
    </table>
935
<?php
936
}
937
938
function wpinv_display_to_address( $invoice_id = 0 ) {
939
    $invoice = wpinv_get_invoice( $invoice_id );
940
    
941
    if ( empty( $invoice ) ) {
942
        return NULL;
943
    }
944
    
945
    $billing_details = $invoice->get_user_info();
946
    $output = '<div class="to col-xs-2"><strong>' . __( 'To:', 'invoicing' ) . '</strong></div>';
947
    $output .= '<div class="wrapper col-xs-10">';
948
    
949
    ob_start();
950
    do_action( 'wpinv_display_to_address_top', $invoice );
951
    $output .= ob_get_clean();
952
    
953
    $output .= '<div class="name">' . esc_html( trim( $billing_details['first_name'] . ' ' . $billing_details['last_name'] ) ) . '</div>';
954
    if ( $company = $billing_details['company'] ) {
955
        $output .= '<div class="company">' . wpautop( wp_kses_post( $company ) ) . '</div>';
956
    }
957
    $address_row = '';
958
    if ( $address = $billing_details['address'] ) {
959
        $address_row .= wpautop( wp_kses_post( $address ) );
960
    }
961
    
962
    $address_fields = array();
963
    if ( !empty( $billing_details['city'] ) ) {
964
        $address_fields[] = $billing_details['city'];
965
    }
966
    
967
    $billing_country = !empty( $billing_details['country'] ) ? $billing_details['country'] : '';
968
    if ( !empty( $billing_details['state'] ) ) {
969
        $address_fields[] = wpinv_state_name( $billing_details['state'], $billing_country );
970
    }
971
    
972
    if ( !empty( $billing_country ) ) {
973
        $address_fields[] = wpinv_country_name( $billing_country );
974
    }
975
    
976 View Code Duplication
    if ( !empty( $address_fields ) ) {
977
        $address_fields = implode( ", ", $address_fields );
978
        
979
        if ( !empty( $billing_details['zip'] ) ) {
980
            $address_fields .= ' ' . $billing_details['zip'];
981
        }
982
        
983
        $address_row .= wpautop( wp_kses_post( $address_fields ) );
984
    }
985
    
986
    if ( $address_row ) {
987
        $output .= '<div class="address">' . $address_row . '</div>';
988
    }
989
    
990 View Code Duplication
    if ( $phone = $invoice->get_phone() ) {
991
        $output .= '<div class="phone">' . wp_sprintf( __( 'Phone: %s', 'invoicing' ), esc_html( $phone ) ) . '</div>';
992
    }
993 View Code Duplication
    if ( $email = $invoice->get_email() ) {
994
        $output .= '<div class="email">' . wp_sprintf( __( 'Email: %s' , 'invoicing'), esc_html( $email ) ) . '</div>';
995
    }
996
    
997
    ob_start();
998
    do_action( 'wpinv_display_to_address_bottom', $invoice );
999
    $output .= ob_get_clean();
1000
    
1001
    $output .= '</div>';
1002
    $output = apply_filters( 'wpinv_display_to_address', $output, $invoice );
1003
1004
    echo $output;
1005
}
1006
1007
function wpinv_display_line_items( $invoice_id = 0 ) {
1008
    global $wpinv_euvat, $ajax_cart_details;
1009
    $invoice            = wpinv_get_invoice( $invoice_id );
1010
    $quantities_enabled = wpinv_item_quantities_enabled();
1011
    $use_taxes          = wpinv_use_taxes();
1012
    $zero_tax           = !(float)$invoice->get_tax() > 0 ? true : false;
1013
    $tax_label           = $use_taxes && $invoice->has_vat() ? $wpinv_euvat->get_vat_name() : __( 'Tax', 'invoicing' );
1014
    $tax_title          = !$zero_tax && $use_taxes ? ( wpinv_prices_include_tax() ? wp_sprintf( __( '(%s Incl.)', 'invoicing' ), $tax_label ) : wp_sprintf( __( '(%s Excl.)', 'invoicing' ), $tax_label ) ) : '';
1015
    
1016
    $cart_details       = $invoice->get_cart_details();
1017
    $ajax_cart_details  = $cart_details;
1018
    ob_start();
1019
    ?>
1020
    <table class="table table-sm table-bordered table-responsive">
1021
        <thead>
1022
            <tr>
1023
                <th class="name"><strong><?php _e( "Item Name", "invoicing" );?></strong></th>
1024
                <th class="rate"><strong><?php _e( "Price", "invoicing" );?></strong></th>
1025
                <?php if ($quantities_enabled) { ?>
1026
                    <th class="qty"><strong><?php _e( "Qty", "invoicing" );?></strong></th>
1027
                <?php } ?>
1028
                <?php if ($use_taxes && !$zero_tax) { ?>
1029
                    <th class="tax"><strong><?php echo $tax_label . ' <span class="normal small">(%)</span>'; ?></strong></th>
1030
                <?php } ?>
1031
                <th class="total"><strong><?php echo __( "Item Total", "invoicing" ) . ' <span class="normal small">' . $tax_title . '<span>';?></strong></th>
1032
            </tr>
1033
        </thead>
1034
        <tbody>
1035
        <?php 
1036
            if ( !empty( $cart_details ) ) {
1037
                do_action( 'wpinv_display_line_items_start', $invoice );
1038
                
1039
                $count = 0;
1040
                $cols  = 3;
1041
                foreach ( $cart_details as $key => $cart_item ) {
1042
                    $item_id    = !empty($cart_item['id']) ? absint( $cart_item['id'] ) : '';
1043
                    $item_price = isset($cart_item["item_price"]) ? wpinv_round_amount( $cart_item["item_price"] ) : 0;
1044
                    $line_total = isset($cart_item["subtotal"]) ? wpinv_round_amount( $cart_item["subtotal"] ) : 0;
1045
                    $quantity   = !empty($cart_item['quantity']) && (int)$cart_item['quantity'] > 0 ? absint( $cart_item['quantity'] ) : 1;
1046
                    
1047
                    $item       = $item_id ? new WPInv_Item( $item_id ) : NULL;
1048
                    $summary    = '';
1049
                    $cols       = 3;
1050
                    if ( !empty($item) ) {
1051
                        $item_name  = $item->get_name();
1052
                        $summary    = $item->get_summary();
1053
                    }
1054
                    $item_name  = !empty($cart_item['name']) ? $cart_item['name'] : $item_name;
0 ignored issues
show
Bug introduced by
The variable $item_name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1055
                    
1056 View Code Duplication
                    if (!empty($item) && $item->is_package() && !empty($cart_item['meta']['post_id'])) {
1057
                        $post_link = '<a href="' . get_edit_post_link( $cart_item['meta']['post_id'] ) .'" target="_blank">' . (!empty($cart_item['meta']['invoice_title']) ? $cart_item['meta']['invoice_title'] : get_the_title( $cart_item['meta']['post_id']) ) . '</a>';
1058
                        $summary = wp_sprintf( __( '%s: %s', 'invoicing' ), $item->get_custom_singular_name(), $post_link );
1059
                    }
1060
                    $summary = apply_filters( 'wpinv_print_invoice_line_item_summary', $summary, $cart_item, $item, $invoice );
1061
                    
1062
                    $item_tax       = '';
1063
                    $tax_rate       = '';
1064 View Code Duplication
                    if ( $use_taxes && $cart_item['tax'] > 0 && $cart_item['subtotal'] > 0 ) {
1065
                        $item_tax = wpinv_price( wpinv_format_amount( $cart_item['tax'] ) );
1066
                        $tax_rate = !empty( $cart_item['vat_rate'] ) ? $cart_item['vat_rate'] : ( $cart_item['tax'] / $cart_item['subtotal'] ) * 100;
1067
                        $tax_rate = $tax_rate > 0 ? (float)wpinv_round_amount( $tax_rate, 4 ) : '';
1068
                        $tax_rate = $tax_rate != '' ? ' <small class="tax-rate">(' . $tax_rate . '%)</small>' : '';
1069
                    }
1070
                    
1071
                    $line_item_tax = $item_tax . $tax_rate;
1072
                    
1073
                    if ( $line_item_tax === '' ) {
1074
                        $line_item_tax = 0; // Zero tax
1075
                    }
1076
                    
1077
                    $line_item = '<tr class="row-' . ( ($count % 2 == 0) ? 'even' : 'odd' ) . ' wpinv-item">';
1078
                        $line_item .= '<td class="name">' . esc_html__( $item_name, 'invoicing' ) . wpinv_get_item_suffix( $item );
1079
                        if ( $summary !== '' ) {
1080
                            $line_item .= '<br/><small class="meta">' . wpautop( wp_kses_post( $summary ) ) . '</small>';
1081
                        }
1082
                        $line_item .= '</td>';
1083
                        
1084
                        $line_item .= '<td class="rate">' . esc_html__( wpinv_price( wpinv_format_amount( $item_price ), $invoice->get_currency() ) ) . '</td>';
1085
                        if ($quantities_enabled) {
1086
                            $cols++;
1087
                            $line_item .= '<td class="qty">' . $quantity . '</td>';
1088
                        }
1089
                        if ($use_taxes && !$zero_tax) {
1090
                            $cols++;
1091
                            $line_item .= '<td class="tax">' . $line_item_tax . '</td>';
1092
                        }
1093
                        $line_item .= '<td class="total">' . esc_html__( wpinv_price( wpinv_format_amount( $line_total ), $invoice->get_currency() ) ) . '</td>';
1094
                    $line_item .= '</tr>';
1095
                    
1096
                    echo apply_filters( 'wpinv_display_line_item', $line_item, $cart_item, $invoice, $cols );
1097
1098
                    $count++;
1099
                }
1100
                
1101
                do_action( 'wpinv_display_before_subtotal', $invoice, $cols );
1102
                ?>
1103
                <tr class="row-sub-total row_odd">
1104
                    <td class="rate" colspan="<?php echo ( $cols - 1 ); ?>"><?php echo apply_filters( 'wpinv_print_cart_subtotal_label', '<strong>' . __( 'Sub Total', 'invoicing' ) . ':</strong>', $invoice ); ?></td>
1105
                    <td class="total"><strong><?php _e( wpinv_subtotal( $invoice_id, true ) ) ?></strong></td>
1106
                </tr>
1107
                <?php
1108
                do_action( 'wpinv_display_after_subtotal', $invoice, $cols );
1109
                
1110 View Code Duplication
                if ( wpinv_discount( $invoice_id, false ) > 0 ) {
1111
                    do_action( 'wpinv_display_before_discount', $invoice, $cols );
1112
                    ?>
1113
                        <tr class="row-discount">
1114
                            <td class="rate" colspan="<?php echo ( $cols - 1 ); ?>"><?php wpinv_get_discount_label( wpinv_discount_code( $invoice_id ) ); ?>:</td>
1115
                            <td class="total"><?php echo wpinv_discount( $invoice_id, true, true ); ?></td>
1116
                        </tr>
1117
                    <?php
1118
                    do_action( 'wpinv_display_after_discount', $invoice, $cols );
1119
                }
1120
                
1121
                if ( $use_taxes ) {
1122
                    do_action( 'wpinv_display_before_tax', $invoice, $cols );
1123
                    ?>
1124
                    <tr class="row-tax">
1125
                        <td class="rate" colspan="<?php echo ( $cols - 1 ); ?>"><?php echo apply_filters( 'wpinv_print_cart_tax_label', '<strong>' . $tax_label . ':</strong>', $invoice ); ?></td>
1126
                        <td class="total"><?php _e( wpinv_tax( $invoice_id, true ) ) ?></td>
1127
                    </tr>
1128
                    <?php
1129
                    do_action( 'wpinv_display_after_tax', $invoice, $cols );
1130
                }
1131
                
1132
                do_action( 'wpinv_display_before_total', $invoice, $cols );
1133
                ?>
1134
                <tr class="table-active row-total">
1135
                    <td class="rate" colspan="<?php echo ( $cols - 1 ); ?>"><?php echo apply_filters( 'wpinv_print_cart_total_label', '<strong>' . __( 'Total', 'invoicing' ) . ':</strong>', $invoice ); ?></td>
1136
                    <td class="total"><strong><?php _e( wpinv_payment_total( $invoice_id, true ) ) ?></strong></td>
1137
                </tr>
1138
                <?php
1139
                do_action( 'wpinv_display_after_total', $invoice, $cols );
1140
                
1141
                do_action( 'wpinv_display_line_end', $invoice, $cols );
1142
            }
1143
        ?>
1144
        </tbody>
1145
    </table>
1146
    <?php
1147
    echo ob_get_clean();
1148
}
1149
1150
function wpinv_display_invoice_totals( $invoice_id = 0 ) {    
1151
    $use_taxes = wpinv_use_taxes();
1152
    
1153
    do_action( 'wpinv_before_display_totals_table', $invoice_id ); 
1154
    ?>
1155
    <table class="table table-sm table-bordered table-responsive">
1156
        <tbody>
1157
            <?php do_action( 'wpinv_before_display_totals' ); ?>
1158
            <tr class="row-sub-total">
1159
                <td class="rate"><strong><?php _e( 'Sub Total', 'invoicing' ); ?></strong></td>
1160
                <td class="total"><strong><?php _e( wpinv_subtotal( $invoice_id, true ) ) ?></strong></td>
1161
            </tr>
1162
            <?php do_action( 'wpinv_after_display_totals' ); ?>
1163
            <?php if ( wpinv_discount( $invoice_id, false ) > 0 ) { ?>
1164
                <tr class="row-discount">
1165
                    <td class="rate"><?php wpinv_get_discount_label( wpinv_discount_code( $invoice_id ) ); ?></td>
1166
                    <td class="total"><?php echo wpinv_discount( $invoice_id, true, true ); ?></td>
1167
                </tr>
1168
            <?php do_action( 'wpinv_after_display_discount' ); ?>
1169
            <?php } ?>
1170
            <?php if ( $use_taxes ) { ?>
1171
            <tr class="row-tax">
1172
                <td class="rate"><?php _e( 'Tax', 'invoicing' ); ?></td>
1173
                <td class="total"><?php _e( wpinv_tax( $invoice_id, true ) ) ?></td>
1174
            </tr>
1175
            <?php do_action( 'wpinv_after_display_tax' ); ?>
1176
            <?php } ?>
1177
            <?php if ( $fees = wpinv_get_fees( $invoice_id ) ) { ?>
1178
                <?php foreach ( $fees as $fee ) { ?>
1179
                    <tr class="row-fee">
1180
                        <td class="rate"><?php echo $fee['label']; ?></td>
1181
                        <td class="total"><?php echo $fee['amount_display']; ?></td>
1182
                    </tr>
1183
                <?php } ?>
1184
            <?php } ?>
1185
            <tr class="table-active row-total">
1186
                <td class="rate"><strong><?php _e( 'Total', 'invoicing' ) ?></strong></td>
1187
                <td class="total"><strong><?php _e( wpinv_payment_total( $invoice_id, true ) ) ?></strong></td>
1188
            </tr>
1189
            <?php do_action( 'wpinv_after_totals' ); ?>
1190
        </tbody>
1191
1192
    </table>
1193
1194
    <?php do_action( 'wpinv_after_totals_table' );
1195
}
1196
1197
function wpinv_display_payments_info( $invoice_id = 0, $echo = true ) {
1198
    $invoice = wpinv_get_invoice( $invoice_id );
1199
    
1200
    ob_start();
1201
    do_action( 'wpinv_before_display_payments_info', $invoice_id );
1202
    if ( ( $gateway_title = $invoice->get_gateway_title() ) || $invoice->is_paid() || $invoice->is_refunded() ) {
1203
        ?>
1204
        <div class="wpi-payment-info">
1205
            <p class="wpi-payment-gateway"><?php echo wp_sprintf( __( 'Payment via %s', 'invoicing' ), $gateway_title ? $gateway_title : __( 'Manually', 'invoicing' ) ); ?></p>
1206
            <?php if ( $gateway_title ) { ?>
1207
            <p class="wpi-payment-transid"><?php echo wp_sprintf( __( 'Transaction ID: %s', 'invoicing' ), $invoice->get_transaction_id() ); ?></p>
1208
            <?php } ?>
1209
        </div>
1210
        <?php
1211
    }
1212
    do_action( 'wpinv_after_display_payments_info', $invoice_id );
1213
    $outout = ob_get_clean();
1214
    
1215
    if ( $echo ) {
1216
        echo $outout;
1217
    } else {
1218
        return $outout;
1219
    }
1220
}
1221
1222
function wpinv_display_style( $invoice ) {
0 ignored issues
show
Unused Code introduced by
The parameter $invoice 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...
1223
    wp_register_style( 'wpinv-single-style', WPINV_PLUGIN_URL . 'assets/css/invoice.css', array(), WPINV_VERSION );
1224
    
1225
    wp_print_styles( 'open-sans' );
1226
    wp_print_styles( 'wpinv-single-style' );
1227
}
1228
add_action( 'wpinv_invoice_print_head', 'wpinv_display_style' );
1229
add_action( 'wpinv_invalid_invoice_head', 'wpinv_display_style' );
1230
1231
function wpinv_checkout_billing_details() {  
1232
    $invoice_id = (int)wpinv_get_invoice_cart_id();
1233
    if (empty($invoice_id)) {
1234
        wpinv_error_log( 'Invoice id not found', 'ERROR', __FILE__, __LINE__ );
1235
        return null;
1236
    }
1237
    
1238
    $invoice = wpinv_get_invoice_cart( $invoice_id );
1239
    if (empty($invoice)) {
1240
        wpinv_error_log( 'Invoice not found', 'ERROR', __FILE__, __LINE__ );
1241
        return null;
1242
    }
1243
    $user_id        = $invoice->get_user_id();
1244
    $user_info      = $invoice->get_user_info();
1245
    $address_info   = wpinv_get_user_address( $user_id );
1246
    
1247 View Code Duplication
    if ( empty( $user_info['first_name'] ) && !empty( $user_info['first_name'] ) ) {
1248
        $user_info['first_name'] = $user_info['first_name'];
1249
        $user_info['last_name'] = $user_info['last_name'];
1250
    }
1251
    
1252
    if ( ( ( empty( $user_info['country'] ) && !empty( $address_info['country'] ) ) || ( empty( $user_info['state'] ) && !empty( $address_info['state'] ) && $user_info['country'] == $address_info['country'] ) ) ) {
1253
        $user_info['country']   = $address_info['country'];
1254
        $user_info['state']     = $address_info['state'];
1255
        $user_info['city']      = $address_info['city'];
1256
        $user_info['zip']       = $address_info['zip'];
1257
    }
1258
    
1259
    $address_fields = array(
1260
        'user_id',
1261
        'company',
1262
        'vat_number',
1263
        'email',
1264
        'phone',
1265
        'address'
1266
    );
1267
    
1268
    foreach ( $address_fields as $field ) {
1269
        if ( empty( $user_info[$field] ) ) {
1270
            $user_info[$field] = $address_info[$field];
1271
        }
1272
    }
1273
    
1274
    return apply_filters( 'wpinv_checkout_billing_details', $user_info, $invoice );
1275
}
1276
1277
function wpinv_admin_get_line_items($invoice = array()) {
1278
    $item_quantities    = wpinv_item_quantities_enabled();
1279
    $use_taxes          = wpinv_use_taxes();
1280
    
1281
    if ( empty( $invoice ) ) {
1282
        return NULL;
1283
    }
1284
    
1285
    $cart_items = $invoice->get_cart_details();
0 ignored issues
show
Bug introduced by
The method get_cart_details cannot be called on $invoice (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1286
    if ( empty( $cart_items ) ) {
1287
        return NULL;
1288
    }
1289
    ob_start();
1290
    
1291
    do_action( 'wpinv_admin_before_line_items', $cart_items, $invoice );
1292
    
1293
    $count = 0;
1294
    foreach ( $cart_items as $key => $cart_item ) {
1295
        $item_id    = $cart_item['id'];
1296
        $wpi_item   = $item_id > 0 ? new WPInv_Item( $item_id ) : NULL;
1297
        
1298
        if (empty($wpi_item)) {
1299
            continue;
1300
        }
1301
        
1302
        $item_price     = wpinv_price( wpinv_format_amount( $cart_item['item_price'] ) );
1303
        $quantity       = !empty( $cart_item['quantity'] ) && $cart_item['quantity'] > 0 ? $cart_item['quantity'] : 1;
1304
        $item_subtotal  = wpinv_price( wpinv_format_amount( $cart_item['subtotal'] ) );
1305
        $can_remove     = true;
1306
        
1307
        $summary = '';
1308 View Code Duplication
        if ($wpi_item->is_package() && !empty($cart_item['meta']['post_id'])) {
1309
            $post_link = '<a href="' . get_edit_post_link( $cart_item['meta']['post_id'] ) .'" target="_blank">' . (!empty($cart_item['meta']['invoice_title']) ? $cart_item['meta']['invoice_title'] : get_the_title( $cart_item['meta']['post_id']) ) . '</a>';
1310
            $summary = wp_sprintf( __( '%s: %s', 'invoicing' ), $wpi_item->get_custom_singular_name(), $post_link );
1311
        }
1312
        $summary = apply_filters( 'wpinv_admin_invoice_line_item_summary', $summary, $cart_item, $wpi_item, $invoice );
1313
        
1314
        $item_tax       = '';
1315
        $tax_rate       = '';
1316 View Code Duplication
        if ( $cart_item['tax'] > 0 && $cart_item['subtotal'] > 0 ) {
1317
            $item_tax = wpinv_price( wpinv_format_amount( $cart_item['tax'] ) );
1318
            $tax_rate = !empty( $cart_item['vat_rate'] ) ? $cart_item['vat_rate'] : ( $cart_item['tax'] / $cart_item['subtotal'] ) * 100;
1319
            $tax_rate = $tax_rate > 0 ? (float)wpinv_round_amount( $tax_rate, 4 ) : '';
1320
            $tax_rate = $tax_rate != '' ? ' <span class="tax-rate">(' . $tax_rate . '%)</span>' : '';
1321
        }
1322
        $line_item_tax = $item_tax . $tax_rate;
1323
        
1324
        if ( $line_item_tax === '' ) {
1325
            $line_item_tax = 0; // Zero tax
1326
        }
1327
1328
        $line_item = '<tr class="item item-' . ( ($count % 2 == 0) ? 'even' : 'odd' ) . '" data-item-id="' . $item_id . '">';
1329
            $line_item .= '<td class="id">' . $item_id . '</td>';
1330
            $line_item .= '<td class="title"><a href="' . get_edit_post_link( $item_id ) . '" target="_blank">' . $cart_item['name'] . '</a>' . wpinv_get_item_suffix( $wpi_item );
1331
            if ( $summary !== '' ) {
1332
                $line_item .= '<span class="meta">' . wpautop( wp_kses_post( $summary ) ) . '</span>';
1333
            }
1334
            $line_item .= '</td>';
1335
            $line_item .= '<td class="price">' . $item_price . '</td>';
1336
            
1337
            if ( $item_quantities ) {
1338
                if ( count( $cart_items ) == 1 && $quantity <= 1 ) {
1339
                    $can_remove = false;
1340
                }
1341
                $line_item .= '<td class="qty" data-quantity="' . $quantity . '">&nbsp;&times;&nbsp;' . $quantity . '</td>';
1342
            } else {
1343
                if ( count( $cart_items ) == 1 ) {
1344
                    $can_remove = false;
1345
                }
1346
            }
1347
            $line_item .= '<td class="total">' . $item_subtotal . '</td>';
1348
            
1349
            if ( $use_taxes ) {
1350
                $line_item .= '<td class="tax">' . $line_item_tax . '</td>';
1351
            }
1352
            $line_item .= '<td class="action">';
1353
            if ( !$invoice->is_paid() && !$invoice->is_refunded() && $can_remove ) {
0 ignored issues
show
Bug introduced by
The method is_paid cannot be called on $invoice (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug introduced by
The method is_refunded cannot be called on $invoice (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1354
                $line_item .= '<i class="fa fa-remove wpinv-item-remove"></i>';
1355
            }
1356
            $line_item .= '</td>';
1357
        $line_item .= '</tr>';
1358
        
1359
        echo apply_filters( 'wpinv_admin_line_item', $line_item, $cart_item, $invoice );
1360
        
1361
        $count++;
1362
    } 
1363
    
1364
    do_action( 'wpinv_admin_after_line_items', $cart_items, $invoice );
1365
    
1366
    return ob_get_clean();
1367
}
1368
1369
function wpinv_checkout_form() {
1370
    global $wpi_checkout_id;
1371
    
1372
    // Set current invoice id.
1373
    $wpi_checkout_id = wpinv_get_invoice_cart_id();
1374
    
1375
    $form_action  = esc_url( wpinv_get_checkout_uri() );
1376
1377
    ob_start();
1378
        echo '<div id="wpinv_checkout_wrap">';
1379
        
1380
        if ( wpinv_get_cart_contents() || wpinv_cart_has_fees() ) {
1381
            ?>
1382
            <div id="wpinv_checkout_form_wrap" class="wpinv_clearfix table-responsive">
1383
                <?php do_action( 'wpinv_before_checkout_form' ); ?>
1384
                <form id="wpinv_checkout_form" class="wpi-form" action="<?php echo $form_action; ?>" method="POST">
1385
                    <?php
1386
                    do_action( 'wpinv_checkout_form_top' );
1387
                    do_action( 'wpinv_checkout_billing_info' );
1388
                    do_action( 'wpinv_checkout_cart' );
1389
                    do_action( 'wpinv_payment_mode_select'  );
1390
                    do_action( 'wpinv_checkout_form_bottom' )
1391
                    ?>
1392
                </form>
1393
                <?php do_action( 'wpinv_after_purchase_form' ); ?>
1394
            </div><!--end #wpinv_checkout_form_wrap-->
1395
        <?php
1396
        } else {
1397
            do_action( 'wpinv_cart_empty' );
1398
        }
1399
        echo '</div><!--end #wpinv_checkout_wrap-->';
1400
    return ob_get_clean();
1401
}
1402
1403
function wpinv_checkout_cart( $cart_details = array(), $echo = true ) {
1404
    global $ajax_cart_details;
1405
    $ajax_cart_details = $cart_details;
1406
    /*
1407
    // Check if the Update cart button should be shown
1408
    if( wpinv_item_quantities_enabled() ) {
1409
        add_action( 'wpinv_cart_footer_buttons', 'wpinv_update_cart_button' );
1410
    }
1411
    
1412
    // Check if the Save Cart button should be shown
1413
    if( !wpinv_is_cart_saving_disabled() ) {
1414
        add_action( 'wpinv_cart_footer_buttons', 'wpinv_save_cart_button' );
1415
    }
1416
    */
1417
    ob_start();
1418
    do_action( 'wpinv_before_checkout_cart' );
1419
    echo '<div id="wpinv_checkout_cart_form" method="post">';
1420
        echo '<div id="wpinv_checkout_cart_wrap">';
1421
            wpinv_get_template_part( 'wpinv-checkout-cart' );
1422
        echo '</div>';
1423
    echo '</div>';
1424
    do_action( 'wpinv_after_checkout_cart' );
1425
    $content = ob_get_clean();
1426
    
1427
    if ( $echo ) {
1428
        echo $content;
1429
    } else {
1430
        return $content;
1431
    }
1432
}
1433
add_action( 'wpinv_checkout_cart', 'wpinv_checkout_cart', 10 );
1434
1435
function wpinv_empty_cart_message() {
1436
	return apply_filters( 'wpinv_empty_cart_message', '<span class="wpinv_empty_cart">' . __( 'Your cart is empty.', 'invoicing' ) . '</span>' );
1437
}
1438
1439
/**
1440
 * Echoes the Empty Cart Message
1441
 *
1442
 * @since 1.0
1443
 * @return void
1444
 */
1445
function wpinv_empty_checkout_cart() {
1446
	echo wpinv_empty_cart_message();
1447
}
1448
add_action( 'wpinv_cart_empty', 'wpinv_empty_checkout_cart' );
1449
1450
function wpinv_save_cart_button() {
1451
    if ( wpinv_is_cart_saving_disabled() )
1452
        return;
1453
?>
1454
    <a class="wpinv-cart-saving-button wpinv-submit button" id="wpinv-save-cart-button" href="<?php echo esc_url( add_query_arg( 'wpi_action', 'save_cart' ) ); ?>"><?php _e( 'Save Cart', 'invoicing' ); ?></a>
1455
<?php
1456
}
1457
1458
function wpinv_update_cart_button() {
1459
    if ( !wpinv_item_quantities_enabled() )
1460
        return;
1461
?>
1462
    <input type="submit" name="wpinv_update_cart_submit" class="wpinv-submit wpinv-no-js button" value="<?php _e( 'Update Cart', 'invoicing' ); ?>"/>
1463
    <input type="hidden" name="wpi_action" value="update_cart"/>
1464
<?php
1465
}
1466
1467
function wpinv_checkout_cart_columns() {
1468
    $default = 3;
1469
    if ( wpinv_item_quantities_enabled() ) {
1470
        $default++;
1471
    }
1472
    
1473
    if ( wpinv_use_taxes() ) {
1474
        $default++;
1475
    }
1476
1477
    return apply_filters( 'wpinv_checkout_cart_columns', $default );
1478
}
1479
1480
function wpinv_display_cart_messages() {
1481
    global $wpi_session;
1482
1483
    $messages = $wpi_session->get( 'wpinv_cart_messages' );
1484
1485
    if ( $messages ) {
1486
        foreach ( $messages as $message_id => $message ) {
1487
            // Try and detect what type of message this is
1488
            if ( strpos( strtolower( $message ), 'error' ) ) {
1489
                $type = 'error';
1490
            } elseif ( strpos( strtolower( $message ), 'success' ) ) {
1491
                $type = 'success';
1492
            } else {
1493
                $type = 'info';
1494
            }
1495
1496
            $classes = apply_filters( 'wpinv_' . $type . '_class', array( 'wpinv_errors', 'wpinv-alert', 'wpinv-alert-' . $type ) );
1497
1498
            echo '<div class="' . implode( ' ', $classes ) . '">';
1499
                // Loop message codes and display messages
1500
                    echo '<p class="wpinv_error" id="wpinv_msg_' . $message_id . '">' . $message . '</p>';
1501
            echo '</div>';
1502
        }
1503
1504
        // Remove all of the cart saving messages
1505
        $wpi_session->set( 'wpinv_cart_messages', null );
1506
    }
1507
}
1508
add_action( 'wpinv_before_checkout_cart', 'wpinv_display_cart_messages' );
1509
1510
function wpinv_discount_field() {
1511
    if ( isset( $_GET['wpi-gateway'] ) && wpinv_is_ajax_disabled() ) {
1512
        return; // Only show before a payment method has been selected if ajax is disabled
1513
    }
1514
1515
    if ( !wpinv_is_checkout() ) {
1516
        return;
1517
    }
1518
1519
    if ( wpinv_has_active_discounts() && wpinv_get_cart_total() ) {
1520
    ?>
1521
    <div id="wpinv-discount-field" class="panel panel-default">
1522
        <div class="panel-body">
1523
            <p>
1524
                <label class="wpinv-label" for="wpinv_discount_code"><strong><?php _e( 'Discount', 'invoicing' ); ?></strong></label>
1525
                <span class="wpinv-description"><?php _e( 'Enter a discount code if you have one.', 'invoicing' ); ?></span>
1526
            </p>
1527
            <div class="form-group row">
1528
                <div class="col-sm-4">
1529
                    <input class="wpinv-input form-control" type="text" id="wpinv_discount_code" name="wpinv_discount_code" placeholder="<?php _e( 'Enter discount code', 'invoicing' ); ?>"/>
1530
                </div>
1531
                <div class="col-sm-3">
1532
                    <button id="wpi-apply-discount" type="button" class="btn btn-success btn-sm"><?php _e( 'Apply Discount', 'invoicing' ); ?></button>
1533
                </div>
1534
                <div style="clear:both"></div>
1535
                <div class="col-sm-12 wpinv-discount-msg">
1536
                    <div class="alert alert-success"><i class="fa fa-check-circle"></i><span class="wpi-msg"></span></div>
1537
                    <div class="alert alert-error"><i class="fa fa-warning"></i><span class="wpi-msg"></span></div>
1538
                </div>
1539
            </div>
1540
        </div>
1541
    </div>
1542
<?php
1543
    }
1544
}
1545
add_action( 'wpinv_after_checkout_cart', 'wpinv_discount_field', -10 );
1546
1547
function wpinv_agree_to_terms_js() {
1548
    if ( wpinv_get_option( 'show_agree_to_terms', false ) ) {
1549
?>
1550
<script type="text/javascript">
1551
    jQuery(document).ready(function($){
1552
        $( document.body ).on('click', '.wpinv_terms_links', function(e) {
1553
            //e.preventDefault();
1554
            $('#wpinv_terms').slideToggle();
1555
            $('.wpinv_terms_links').toggle();
1556
            return false;
1557
        });
1558
    });
1559
</script>
1560
<?php
1561
    }
1562
}
1563
add_action( 'wpinv_checkout_form_top', 'wpinv_agree_to_terms_js' );
1564
1565
function wpinv_payment_mode_select() {
1566
    $gateways = wpinv_get_enabled_payment_gateways( true );
1567
    $gateways = apply_filters( 'wpinv_payment_gateways_on_cart', $gateways );
1568
    $page_URL = wpinv_get_current_page_url();
0 ignored issues
show
Unused Code introduced by
$page_URL 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...
1569
    $invoice = wpinv_get_invoice( 0, true );
1570
    
1571
    do_action('wpinv_payment_mode_top');
1572
    $invoice_id = (int)$invoice->ID;
1573
    $chosen_gateway = wpinv_get_chosen_gateway( $invoice_id );
1574
    ?>
1575
    <div id="wpinv_payment_mode_select" data-gateway="<?php echo $chosen_gateway; ?>" <?php echo ( $invoice->is_free() ? 'style="display:none;"' : '' ); ?>>
1576
            <?php do_action( 'wpinv_payment_mode_before_gateways_wrap' ); ?>
1577
            <div id="wpinv-payment-mode-wrap" class="panel panel-default">
1578
                <div class="panel-heading"><h3 class="panel-title"><?php _e( 'Select Payment Method', 'invoicing' ); ?></h3></div>
1579
                <div class="panel-body list-group wpi-payment_methods">
1580
                    <?php
1581
                    do_action( 'wpinv_payment_mode_before_gateways' );
1582
                    
1583
                    if(!empty($gateways)){
1584
	                    foreach ( $gateways as $gateway_id => $gateway ) {
1585
		                    $checked = checked( $gateway_id, $chosen_gateway, false );
1586
		                    $button_label = wpinv_get_gateway_button_label( $gateway_id );
1587
		                    $description = wpinv_get_gateway_description( $gateway_id );
1588
		                    ?>
1589
		                    <div class="list-group-item">
1590
			                    <div class="radio">
1591
				                    <label><input type="radio" data-button-text="<?php echo esc_attr( $button_label );?>" value="<?php echo esc_attr( $gateway_id ) ;?>" <?php echo $checked ;?> id="wpi_gateway_<?php echo esc_attr( $gateway_id );?>" name="wpi-gateway" class="wpi-pmethod"><?php echo esc_html( $gateway['checkout_label'] ); ?></label>
1592
			                    </div>
1593
			                    <div style="display:none;" class="payment_box wpi_gateway_<?php echo esc_attr( $gateway_id );?>" role="alert">
1594
				                    <?php if ( !empty( $description ) ) { ?>
1595
					                    <div class="wpi-gateway-desc alert alert-info"><?php echo $description;?></div>
1596
				                    <?php } ?>
1597
				                    <?php do_action( 'wpinv_' . $gateway_id . '_cc_form', $invoice_id ) ;?>
1598
			                    </div>
1599
		                    </div>
1600
		                    <?php
1601
	                    }
1602
                    }else{
1603
	                    echo '<div class="alert alert-warning">'. __('No payment gateway active','invoicing') .'</div>';
1604
                    }
1605
1606
                    do_action( 'wpinv_payment_mode_after_gateways' );
1607
                    ?>
1608
                </div>
1609
            </div>
1610
            <?php do_action( 'wpinv_payment_mode_after_gateways_wrap' ); ?>
1611
    </div>
1612
    <?php
1613
    do_action('wpinv_payment_mode_bottom');
1614
}
1615
add_action( 'wpinv_payment_mode_select', 'wpinv_payment_mode_select' );
1616
1617
function wpinv_checkout_billing_info() {    
1618
    if ( wpinv_is_checkout() ) {
1619
        $logged_in          = is_user_logged_in();
0 ignored issues
show
Unused Code introduced by
$logged_in 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...
1620
        $billing_details    = wpinv_checkout_billing_details();
1621
        $selected_country   = !empty( $billing_details['country'] ) ? $billing_details['country'] : wpinv_default_billing_country();
1622
        ?>
1623
        <div id="wpinv-fields" class="clearfix">
1624
            <div id="wpi-billing" class="wpi-billing clearfix panel panel-default">
1625
                <div class="panel-heading"><h3 class="panel-title"><?php _e( 'Billing Details', 'invoicing' );?></h3></div>
1626
                <div id="wpinv-fields-box" class="panel-body">
1627
                    <?php do_action( 'wpinv_checkout_billing_fields_first', $billing_details ); ?>
1628
                    <p class="wpi-cart-field wpi-col2 wpi-colf">
1629
                        <label for="wpinv_first_name" class="wpi-label"><?php _e( 'First Name', 'invoicing' );?><?php if ( wpinv_get_option( 'fname_mandatory' ) ) { echo '<span class="wpi-required">*</span>'; } ?></label>
1630
                        <?php
1631
                        echo wpinv_html_text( array(
1632
                                'id'            => 'wpinv_first_name',
1633
                                'name'          => 'wpinv_first_name',
1634
                                'value'         => $billing_details['first_name'],
1635
                                'class'         => 'wpi-input form-control',
1636
                                'placeholder'   => __( 'First name', 'invoicing' ),
1637
                                'required'      => (bool)wpinv_get_option( 'fname_mandatory' ),
1638
                            ) );
1639
                        ?>
1640
                    </p>
1641
                    <p class="wpi-cart-field wpi-col2 wpi-coll">
1642
                        <label for="wpinv_last_name" class="wpi-label"><?php _e( 'Last Name', 'invoicing' );?><?php if ( wpinv_get_option( 'lname_mandatory' ) ) { echo '<span class="wpi-required">*</span>'; } ?></label>
1643
                        <?php
1644
                        echo wpinv_html_text( array(
1645
                                'id'            => 'wpinv_last_name',
1646
                                'name'          => 'wpinv_last_name',
1647
                                'value'         => $billing_details['last_name'],
1648
                                'class'         => 'wpi-input form-control',
1649
                                'placeholder'   => __( 'Last name', 'invoicing' ),
1650
                                'required'      => (bool)wpinv_get_option( 'lname_mandatory' ),
1651
                            ) );
1652
                        ?>
1653
                    </p>
1654
                    <p class="wpi-cart-field wpi-col2 wpi-colf">
1655
                        <label for="wpinv_address" class="wpi-label"><?php _e( 'Address', 'invoicing' );?><?php if ( wpinv_get_option( 'address_mandatory' ) ) { echo '<span class="wpi-required">*</span>'; } ?></label>
1656
                        <?php
1657
                        echo wpinv_html_text( array(
1658
                                'id'            => 'wpinv_address',
1659
                                'name'          => 'wpinv_address',
1660
                                'value'         => $billing_details['address'],
1661
                                'class'         => 'wpi-input form-control',
1662
                                'placeholder'   => __( 'Address', 'invoicing' ),
1663
                                'required'      => (bool)wpinv_get_option( 'address_mandatory' ),
1664
                            ) );
1665
                        ?>
1666
                    </p>
1667
                    <p class="wpi-cart-field wpi-col2 wpi-coll">
1668
                        <label for="wpinv_city" class="wpi-label"><?php _e( 'City', 'invoicing' );?><?php if ( wpinv_get_option( 'city_mandatory' ) ) { echo '<span class="wpi-required">*</span>'; } ?></label>
1669
                        <?php
1670
                        echo wpinv_html_text( array(
1671
                                'id'            => 'wpinv_city',
1672
                                'name'          => 'wpinv_city',
1673
                                'value'         => $billing_details['city'],
1674
                                'class'         => 'wpi-input form-control',
1675
                                'placeholder'   => __( 'City', 'invoicing' ),
1676
                                'required'      => (bool)wpinv_get_option( 'city_mandatory' ),
1677
                            ) );
1678
                        ?>
1679
                    </p>
1680
                    <p id="wpinv_country_box" class="wpi-cart-field wpi-col2 wpi-colf">
1681
                        <label for="wpinv_country" class="wpi-label"><?php _e( 'Country', 'invoicing' );?><?php if ( wpinv_get_option( 'country_mandatory' ) ) { echo '<span class="wpi-required">*</span>'; } ?></label>
1682
                        <?php echo wpinv_html_select( array(
1683
                            'options'          => wpinv_get_country_list(),
1684
                            'name'             => 'wpinv_country',
1685
                            'id'               => 'wpinv_country',
1686
                            'selected'         => $selected_country,
1687
                            'show_option_all'  => false,
1688
                            'show_option_none' => false,
1689
                            'class'            => 'wpi-input form-control',
1690
                            'placeholder'      => __( 'Choose a country', 'invoicing' ),
1691
                            'required'         => (bool)wpinv_get_option( 'country_mandatory' ),
1692
                        ) ); ?>
1693
                    </p>
1694
                    <p id="wpinv_state_box" class="wpi-cart-field wpi-col2 wpi-coll">
1695
                        <label for="wpinv_state" class="wpi-label"><?php _e( 'State / Province', 'invoicing' );?><?php if ( wpinv_get_option( 'state_mandatory' ) ) { echo '<span class="wpi-required">*</span>'; } ?></label>
1696
                        <?php
1697
                        $states = wpinv_get_country_states( $selected_country );
1698
                        if( !empty( $states ) ) {
1699
                            echo wpinv_html_select( array(
1700
                                'options'          => $states,
1701
                                'name'             => 'wpinv_state',
1702
                                'id'               => 'wpinv_state',
1703
                                'selected'         => $billing_details['state'],
1704
                                'show_option_all'  => false,
1705
                                'show_option_none' => false,
1706
                                'class'            => 'wpi-input form-control',
1707
                                'placeholder'      => __( 'Choose a state', 'invoicing' ),
1708
                                'required'         => (bool)wpinv_get_option( 'state_mandatory' ),
1709
                            ) );
1710
                        } else {
1711
                            echo wpinv_html_text( array(
1712
                                'name'          => 'wpinv_state',
1713
                                'value'         => $billing_details['state'],
1714
                                'id'            => 'wpinv_state',
1715
                                'class'         => 'wpi-input form-control',
1716
                                'placeholder'   => __( 'State / Province', 'invoicing' ),
1717
                                'required'      => (bool)wpinv_get_option( 'state_mandatory' ),
1718
                            ) );
1719
                        }
1720
                        ?>
1721
                    </p>
1722
                    <p class="wpi-cart-field wpi-col2 wpi-colf">
1723
                        <label for="wpinv_zip" class="wpi-label"><?php _e( 'ZIP / Postcode', 'invoicing' );?><?php if ( wpinv_get_option( 'zip_mandatory' ) ) { echo '<span class="wpi-required">*</span>'; } ?></label>
1724
                        <?php
1725
                        echo wpinv_html_text( array(
1726
                                'name'          => 'wpinv_zip',
1727
                                'value'         => $billing_details['zip'],
1728
                                'id'            => 'wpinv_zip',
1729
                                'class'         => 'wpi-input form-control',
1730
                                'placeholder'   => __( 'ZIP / Postcode', 'invoicing' ),
1731
                                'required'      => (bool)wpinv_get_option( 'zip_mandatory' ),
1732
                            ) );
1733
                        ?>
1734
                    </p>
1735
                    <p class="wpi-cart-field wpi-col2 wpi-coll">
1736
                        <label for="wpinv_phone" class="wpi-label"><?php _e( 'Phone', 'invoicing' );?><?php if ( wpinv_get_option( 'phone_mandatory' ) ) { echo '<span class="wpi-required">*</span>'; } ?></label>
1737
                        <?php
1738
                        echo wpinv_html_text( array(
1739
                                'id'            => 'wpinv_phone',
1740
                                'name'          => 'wpinv_phone',
1741
                                'value'         => $billing_details['phone'],
1742
                                'class'         => 'wpi-input form-control',
1743
                                'placeholder'   => __( 'Phone', 'invoicing' ),
1744
                                'required'      => (bool)wpinv_get_option( 'phone_mandatory' ),
1745
                            ) );
1746
                        ?>
1747
                    </p>
1748
                    <?php do_action( 'wpinv_checkout_billing_fields_last', $billing_details ); ?>
1749
                    <div class="clearfix"></div>
1750
                </div>
1751
            </div>
1752
            <?php do_action( 'wpinv_after_billing_fields', $billing_details ); ?>
1753
        </div>
1754
        <?php
1755
    }
1756
}
1757
add_action( 'wpinv_checkout_billing_info', 'wpinv_checkout_billing_info' );
1758
1759
function wpinv_checkout_hidden_fields() {
1760
?>
1761
    <?php if ( is_user_logged_in() ) { ?>
1762
    <input type="hidden" name="wpinv_user_id" value="<?php echo get_current_user_id(); ?>"/>
1763
    <?php } ?>
1764
    <input type="hidden" name="wpi_action" value="payment" />
1765
<?php
1766
}
1767
1768
function wpinv_checkout_button_purchase() {
1769
    ob_start();
1770
?>
1771
    <input type="submit" class="btn btn-success wpinv-submit" id="wpinv-payment-button" data-value="<?php esc_attr_e( 'Proceed to Pay', 'invoicing' ) ?>" name="wpinv_payment" value="<?php esc_attr_e( 'Proceed to Pay', 'invoicing' ) ?>"/>
1772
<?php
1773
    return apply_filters( 'wpinv_checkout_button_purchase', ob_get_clean() );
1774
}
1775
1776
function wpinv_checkout_total() {
1777
    global $cart_total;
1778
?>
1779
<div id="wpinv_checkout_total" class="panel panel-info">
1780
    <div class="panel-body">
1781
    <?php
1782
    do_action( 'wpinv_purchase_form_before_checkout_total' );
1783
    ?>
1784
    <strong><?php _e( 'Invoice Total:', 'invoicing' ) ?></strong> <span class="wpinv-chdeckout-total"><?php echo $cart_total;?></span>
1785
    <?php
1786
    do_action( 'wpinv_purchase_form_after_checkout_total' );
1787
    ?>
1788
    </div>
1789
</div>
1790
<?php
1791
}
1792
add_action( 'wpinv_checkout_form_bottom', 'wpinv_checkout_total', 9998 );
1793
1794
function wpinv_checkout_submit() {
1795
?>
1796
<div id="wpinv_purchase_submit" class="panel panel-success">
1797
    <div class="panel-body text-center">
1798
    <?php
1799
    do_action( 'wpinv_purchase_form_before_submit' );
1800
    wpinv_checkout_hidden_fields();
1801
    echo wpinv_checkout_button_purchase();
1802
    do_action( 'wpinv_purchase_form_after_submit' );
1803
    ?>
1804
    </div>
1805
</div>
1806
<?php
1807
}
1808
add_action( 'wpinv_checkout_form_bottom', 'wpinv_checkout_submit', 9999 );
1809
1810
function wpinv_receipt_billing_address( $invoice_id = 0 ) {
1811
    $invoice = wpinv_get_invoice( $invoice_id );
1812
    
1813
    if ( empty( $invoice ) ) {
1814
        return NULL;
1815
    }
1816
    
1817
    $billing_details = $invoice->get_user_info();
1818
    $address_row = '';
1819
    if ( $address = $billing_details['address'] ) {
1820
        $address_row .= wpautop( wp_kses_post( $address ) );
1821
    }
1822
    
1823
    $address_fields = array();
1824
    if ( !empty( $billing_details['city'] ) ) {
1825
        $address_fields[] = $billing_details['city'];
1826
    }
1827
    
1828
    $billing_country = !empty( $billing_details['country'] ) ? $billing_details['country'] : '';
1829
    if ( !empty( $billing_details['state'] ) ) {
1830
        $address_fields[] = wpinv_state_name( $billing_details['state'], $billing_country );
1831
    }
1832
    
1833
    if ( !empty( $billing_country ) ) {
1834
        $address_fields[] = wpinv_country_name( $billing_country );
1835
    }
1836
    
1837 View Code Duplication
    if ( !empty( $address_fields ) ) {
1838
        $address_fields = implode( ", ", $address_fields );
1839
        
1840
        if ( !empty( $billing_details['zip'] ) ) {
1841
            $address_fields .= ' ' . $billing_details['zip'];
1842
        }
1843
        
1844
        $address_row .= wpautop( wp_kses_post( $address_fields ) );
1845
    }
1846
    ob_start();
1847
    ?>
1848
    <table class="table table-bordered table-sm wpi-billing-details">
1849
        <tbody>
1850
            <tr class="wpi-receipt-name">
1851
                <th class="text-left"><?php _e( 'Name', 'invoicing' ); ?></th>
1852
                <td><?php echo esc_html( trim( $billing_details['first_name'] . ' ' . $billing_details['last_name'] ) ) ;?></td>
1853
            </tr>
1854
            <tr class="wpi-receipt-email">
1855
                <th class="text-left"><?php _e( 'Email', 'invoicing' ); ?></th>
1856
                <td><?php echo $billing_details['email'] ;?></td>
1857
            </tr>
1858 View Code Duplication
            <?php if ( $billing_details['company'] ) { ?>
1859
            <tr class="wpi-receipt-company">
1860
                <th class="text-left"><?php _e( 'Company', 'invoicing' ); ?></th>
1861
                <td><?php echo esc_html( $billing_details['company'] ) ;?></td>
1862
            </tr>
1863
            <?php } ?>
1864
            <tr class="wpi-receipt-address">
1865
                <th class="text-left"><?php _e( 'Address', 'invoicing' ); ?></th>
1866
                <td><?php echo $address_row ;?></td>
1867
            </tr>
1868 View Code Duplication
            <?php if ( $billing_details['phone'] ) { ?>
1869
            <tr class="wpi-receipt-phone">
1870
                <th class="text-left"><?php _e( 'Phone', 'invoicing' ); ?></th>
1871
                <td><?php echo esc_html( $billing_details['phone'] ) ;?></td>
1872
            </tr>
1873
            <?php } ?>
1874
        </tbody>
1875
    </table>
1876
    <?php
1877
    $output = ob_get_clean();
1878
    
1879
    $output = apply_filters( 'wpinv_receipt_billing_address', $output, $invoice_id );
1880
1881
    echo $output;
1882
}
1883
1884
function wpinv_filter_success_page_content( $content ) {
1885
    if ( isset( $_GET['payment-confirm'] ) && wpinv_is_success_page() ) {
1886
        if ( has_filter( 'wpinv_payment_confirm_' . sanitize_text_field( $_GET['payment-confirm'] ) ) ) {
1887
            $content = apply_filters( 'wpinv_payment_confirm_' . sanitize_text_field( $_GET['payment-confirm'] ), $content );
1888
        }
1889
    }
1890
1891
    return $content;
1892
}
1893
add_filter( 'the_content', 'wpinv_filter_success_page_content', 99999 );
1894
1895
function wpinv_receipt_actions( $invoice ) {
1896
    if ( !empty( $invoice ) ) {
1897
        $actions = array();
1898
1899
        if ( wpinv_user_can_view_invoice( $invoice->ID ) ) {
1900
            $actions['print']   = array(
1901
                'url'  => $invoice->get_view_url( true ),
1902
                'name' => __( 'Print Invoice', 'invoicing' ),
1903
                'class' => 'btn-primary',
1904
            );
1905
        }
1906
1907
        if ( is_user_logged_in() ) {
1908
            $actions['history'] = array(
1909
                'url'  => wpinv_get_history_page_uri(),
1910
                'name' => __( 'Invoice History', 'invoicing' ),
1911
                'class' => 'btn-warning',
1912
            );
1913
        }
1914
1915
        $actions = apply_filters( 'wpinv_invoice_receipt_actions', $actions, $invoice );
1916
        
1917
        if ( !empty( $actions ) ) {
1918
        ?>
1919
        <div class="wpinv-receipt-actions text-right">
1920
            <?php foreach ( $actions as $key => $action ) { $class = !empty($action['class']) ? sanitize_html_class( $action['class'] ) : ''; ?>
1921
            <a href="<?php echo esc_url( $action['url'] );?>" class="btn btn-sm <?php echo $class . ' ' . sanitize_html_class( $key );?>" <?php echo ( !empty($action['attrs']) ? $action['attrs'] : '' ) ;?>><?php echo esc_html( $action['name'] );?></a>
1922
            <?php } ?>
1923
        </div>
1924
        <?php
1925
        }
1926
    }
1927
}
1928
add_action( 'wpinv_receipt_start', 'wpinv_receipt_actions', -10, 1 );
1929
1930
function wpinv_invoice_link( $invoice_id ) {
1931
    $invoice = wpinv_get_invoice( $invoice_id );
1932
    
1933
    if ( empty( $invoice ) ) {
1934
        return NULL;
1935
    }
1936
    
1937
    $invoice_link = '<a href="' . esc_url( $invoice->get_view_url() ) . '">' . $invoice->get_number() . '</a>';
1938
    
1939
    return apply_filters( 'wpinv_get_invoice_link', $invoice_link, $invoice );
1940
}
1941
1942
function wpinv_invoice_subscription_details( $invoice ) {
1943
    if ( !empty( $invoice ) && $invoice->is_recurring() && !wpinv_is_subscription_payment( $invoice ) ) {
1944
        $total_payments = (int)$invoice->get_total_payments();
1945
        $payments       = $invoice->get_child_payments();
1946
        
1947
        $subscription   = $invoice->get_subscription_data();
1948
        
1949
        if ( !( !empty( $subscription ) && !empty( $subscription['item_id'] ) ) ) {
1950
            return;
1951
        }
1952
        
1953
        $billing_cycle  = wpinv_get_billing_cycle( $subscription['initial_amount'], $subscription['recurring_amount'], $subscription['period'], $subscription['interval'], $subscription['bill_times'], $subscription['trial_period'], $subscription['trial_interval'], $invoice->get_currency() );
1954
        $times_billed   = $total_payments . ' / ' . ( ( (int)$subscription['bill_times'] == 0 ) ? __( 'Until cancelled', 'invoicing' ) : $subscription['bill_times'] );
1955
        
1956
        $subscription_status = $invoice->get_subscription_status();
1957
        
1958
        $status_desc = '';
1959
        if ( $subscription_status == 'trialing' && $trial_end_date = $invoice->get_trial_end_date() ) {
1960
            $status_desc = wp_sprintf( __( 'Until: %s', 'invoicing' ), $trial_end_date );
1961
        } else if ( $subscription_status == 'cancelled' && $cancelled_date = $invoice->get_cancelled_date() ) {
1962
            $status_desc = wp_sprintf( __( 'On: %s', 'invoicing' ), $cancelled_date );
1963
        }
1964
        $status_desc = $status_desc != '' ? '<span class="meta">' . $status_desc . '</span>' : '';
1965
        ?>
1966
        <div class="wpinv-subscriptions-details">
1967
            <h3 class="wpinv-subscriptions-t"><?php echo apply_filters( 'wpinv_subscription_details_title', __( 'Subscription Details', 'invoicing' ) ); ?></h3>
1968
            <table class="table">
1969
                <thead>
1970
                    <tr>
1971
                        <th><?php _e( 'Billing Cycle', 'invoicing' ) ;?></th>
1972
                        <th><?php _e( 'Start Date', 'invoicing' ) ;?></th>
1973
                        <th><?php _e( 'Expiration Date', 'invoicing' ) ;?></th>
1974
                        <th class="text-center"><?php _e( 'Times Billed', 'invoicing' ) ;?></th>
1975
                        <th class="text-center"><?php _e( 'Status', 'invoicing' ) ;?></th>
1976
                    </tr>
1977
                </thead>
1978
                <tbody>
1979
                    <tr>
1980
                        <td><?php echo $billing_cycle; ?></td>
1981
                        <td><?php echo $invoice->get_subscription_start(); ?></td>
1982
                        <td><?php echo $invoice->get_subscription_end(); ?></td>
1983
                        <td class="text-center"><?php echo $times_billed; ?></td>
1984
                        <td class="text-center wpi-sub-status"><?php echo $invoice->get_subscription_status_label() ;?>
1985
                        <?php echo $status_desc; ?>
1986
                        </td>
1987
                    </tr>
1988
                </tbody>
1989
            </table>
1990
        </div>
1991
        <?php if ( !empty( $payments ) ) { ?>
1992
        <div class="wpinv-renewal-payments">
1993
            <h3 class="wpinv-renewals-t"><?php echo apply_filters( 'wpinv_renewal_payments_title', __( 'Renewal Payments', 'invoicing' ) ); ?></h3>
1994
            <table class="table">
1995
                <thead>
1996
                    <tr>
1997
                        <th>#</th>
1998
                        <th><?php _e( 'Invoice', 'invoicing' ) ;?></th>
1999
                        <th><?php _e( 'Date', 'invoicing' ) ;?></th>
2000
                        <th class="text-right"><?php _e( 'Amount', 'invoicing' ) ;?></th>
2001
                    </tr>
2002
                </thead>
2003
                <tbody>
2004
                    <?php foreach ( $payments as $key => $invoice_id ) { ?>
2005
                    <tr>
2006
                        <th scope="row"><?php echo ( $key + 1 );?></th>
2007
                        <td><?php echo wpinv_invoice_link( $invoice_id ) ;?></td>
2008
                        <td><?php echo wpinv_get_invoice_date( $invoice_id ); ?></td>
2009
                        <td class="text-right"><?php echo wpinv_payment_total( $invoice_id, true ); ?></td>
2010
                    </tr>
2011
                    <?php } ?>
2012
                    <tr><td colspan="4" style="padding:0"></td></tr>
2013
                </tbody>
2014
            </table>
2015
        </div>
2016
        <?php } ?>
2017
        <?php
2018
    }
2019
}
2020
2021
function wpinv_cart_total_label( $label, $invoice ) {
2022
    if ( empty( $invoice ) ) {
2023
        return $label;
2024
    }
2025
    
2026
    $prefix_label = '';
2027
    if ( $invoice->is_parent() && $item_id = $invoice->get_recurring() ) {        
2028
        $prefix_label   = '<span class="label label-primary label-recurring">' . __( 'Recurring Payment', 'invoicing' ) . '</span> ' . wpinv_subscription_payment_desc( $invoice );
2029
    } else if ( $invoice->is_renewal() ) {
2030
        $prefix_label   = '<span class="label label-primary label-renewal">' . __( 'Renewal Payment', 'invoicing' ) . '</span> ';        
2031
    }
2032
    
2033
    if ( $prefix_label != '' ) {
2034
        $label  = '<span class="wpinv-cart-sub-desc">' . $prefix_label . '</span> ' . $label;
2035
    }
2036
    
2037
    return $label;
2038
}
2039
add_filter( 'wpinv_cart_total_label', 'wpinv_cart_total_label', 10, 2 );
2040
add_filter( 'wpinv_email_cart_total_label', 'wpinv_cart_total_label', 10, 2 );
2041
add_filter( 'wpinv_print_cart_total_label', 'wpinv_cart_total_label', 10, 2 );
2042
2043
add_action( 'wpinv_invoice_print_middle', 'wpinv_invoice_subscription_details', 10, 1 );
2044
2045
function wpinv_invoice_print_description( $invoice ) {
2046
    if ( empty( $invoice ) ) {
2047
        return NULL;
2048
    }
2049
    if ( $description = wpinv_get_invoice_description( $invoice->ID ) ) {
2050
        ?>
2051
        <div class="row wpinv-lower">
2052
            <div class="col-sm-12 wpinv-description">
2053
                <?php echo wpautop( $description ); ?>
2054
            </div>
2055
        </div>
2056
        <?php
2057
    }
2058
}
2059
add_action( 'wpinv_invoice_print_middle', 'wpinv_invoice_print_description', 10.1, 1 );
2060
2061
function wpinv_invoice_print_payment_info( $invoice ) {
2062
    if ( empty( $invoice ) ) {
2063
        return NULL;
2064
    }
2065
    
2066
    if ( $payments_info = wpinv_display_payments_info( $invoice->ID, false ) ) {
2067
        ?>
2068
        <div class="row wpinv-payments">
2069
            <div class="col-sm-12">
2070
                <?php echo $payments_info; ?>
2071
            </div>
2072
        </div>
2073
        <?php 
2074
    }
2075
}
2076
// add_action( 'wpinv_invoice_print_after_line_items', 'wpinv_invoice_print_payment_info', 10, 1 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
2077
2078
function wpinv_get_invoice_note_line_item( $note, $echo = true ) {
2079
    if ( empty( $note ) ) {
2080
        return NULL;
2081
    }
2082
    
2083
    if ( is_int( $note ) ) {
2084
        $note = get_comment( $note );
2085
    }
2086
    
2087
    if ( !( is_object( $note ) && is_a( $note, 'WP_Comment' ) ) ) {
2088
        return NULL;
2089
    }
2090
    
2091
    $note_classes   = array( 'note' );
2092
    $note_classes[] = get_comment_meta( $note->comment_ID, '_wpi_customer_note', true ) ? 'customer-note' : '';
2093
    $note_classes[] = $note->comment_author === __( 'System', 'invoicing' ) ? 'system-note' : '';
2094
    $note_classes   = apply_filters( 'wpinv_invoice_note_class', array_filter( $note_classes ), $note );
2095
    $note_classes   = !empty( $note_classes ) ? implode( ' ', $note_classes ) : '';
2096
    
2097
    ob_start();
2098
    ?>
2099
    <li rel="<?php echo absint( $note->comment_ID ) ; ?>" class="<?php echo esc_attr( $note_classes ); ?>">
2100
        <div class="note_content">
2101
            <?php echo wpautop( wptexturize( wp_kses_post( $note->comment_content ) ) ); ?>
2102
        </div>
2103
        <p class="meta">
2104
            <abbr class="exact-date" title="<?php echo $note->comment_date; ?>"><?php printf( __( '%1$s - %2$s at %3$s', 'invoicing' ), $note->comment_author, date_i18n( get_option( 'date_format' ), strtotime( $note->comment_date ) ), date_i18n( get_option( 'time_format' ), strtotime( $note->comment_date ) ) ); ?></abbr>&nbsp;&nbsp;
2105
            <?php if($note->comment_author !== 'System') {?>
2106
                <a href="#" class="delete_note"><?php _e( 'Delete note', 'invoicing' ); ?></a>
2107
            <?php } ?>
2108
        </p>
2109
    </li>
2110
    <?php
2111
    $note_content = ob_get_clean();
2112
    $note_content = apply_filters( 'wpinv_get_invoice_note_line_item', $note_content, $note, $echo );
2113
    
2114
    if ( $echo ) {
2115
        echo $note_content;
2116
    } else {
2117
        return $note_content;
2118
    }
2119
}
2120
2121
function wpinv_invalid_invoice_content() {
2122
    global $post;
2123
2124
    $invoice = wpinv_get_invoice( $post->ID );
2125
2126
    $error = __( 'This invoice is only viewable by clicking on the invoice link that sent to you via email.', 'invoicing' );
2127
    if ( !empty( $invoice->ID ) && $invoice->has_status( array_keys( wpinv_get_invoice_statuses() ) ) ) {
2128
        if ( is_user_logged_in() ) {
2129 View Code Duplication
            if ( wpinv_require_login_to_checkout() ) {
2130
                if ( isset( $_GET['invoice_key'] ) && $_GET['invoice_key'] === $invoice->get_key() ) {
2131
                    $error = __( 'You are not allowed to view this invoice.', 'invoicing' );
2132
                }
2133
            }
2134 View Code Duplication
        } else {
2135
            if ( wpinv_require_login_to_checkout() ) {
2136
                if ( isset( $_GET['invoice_key'] ) && $_GET['invoice_key'] === $invoice->get_key() ) {
2137
                    $error = __( 'You must be logged in to view this invoice.', 'invoicing' );
2138
                }
2139
            }
2140
        }
2141
    } else {
2142
        $error = __( 'This invoice is deleted or does not exist.', 'invoicing' );
2143
    }
2144
    ?>
2145
    <div class="row wpinv-row-invalid">
2146
        <div class="col-md-6 col-md-offset-3 wpinv-message error">
2147
            <h3><?php _e( 'Access Denied', 'invoicing' ); ?></h3>
2148
            <p class="wpinv-msg-text"><?php echo $error; ?></p>
2149
        </div>
2150
    </div>
2151
    <?php
2152
}
2153
add_action( 'wpinv_invalid_invoice_content', 'wpinv_invalid_invoice_content' );