Passed
Pull Request — master (#222)
by
unknown
03:03
created

wpinv-template-functions.php ➔ wpinv_checkout_form()   C

Complexity

Conditions 13
Paths 14

Size

Total Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
nc 14
nop 0
dl 0
loc 79
rs 5.7515
c 0
b 0
f 0

How to fix   Long Method    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', wpinv_get_theme_template_dir_name() );
23
}
24
25
function wpinv_display_invoice_top_bar( $invoice ) {
26
    if ( empty( $invoice ) ) {
27
        return;
28
    }
29
    ?>
30
    <div class="row wpinv-top-bar no-print">
31
        <div class="container">
32
            <div class="col-xs-6">
33
                <?php do_action( 'wpinv_invoice_top_bar_left', $invoice );?>
34
            </div>
35
            <div class="col-xs-6 text-right">
36
                <?php do_action( 'wpinv_invoice_top_bar_right', $invoice );?>
37
            </div>
38
        </div>
39
    </div>
40
    <?php
41
}
42
43
function wpinv_invoice_display_left_actions( $invoice ) {
44
    if ( empty( $invoice ) ) {
45
        return; // Exit if invoice is not set.
46
    }
47
    
48
    if ( $invoice->post_type == 'wpi_invoice' ) {
49
        if ( $invoice->needs_payment() ) {
50
            ?> <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
51
        }
52
    }
53
    do_action('wpinv_invoice_display_left_actions', $invoice);
54
}
55
56
function wpinv_invoice_display_right_actions( $invoice ) {
57
    if ( empty( $invoice ) ) {
58
        return; // Exit if invoice is not set.
59
    }
60
61
    if ( $invoice->post_type == 'wpi_invoice' ) { ?>
62
        <a class="btn btn-primary btn-sm btn-print-invoice" onclick="window.print();" href="javascript:void(0)"><?php _e( 'Print Invoice', 'invoicing' ); ?></a>
63
        <?php if ( is_user_logged_in() ) { ?>
64
        &nbsp;&nbsp;<a class="btn btn-warning btn-sm btn-invoice-history" href="<?php echo esc_url( wpinv_get_history_page_uri() ); ?>"><?php _e( 'Invoice History', 'invoicing' ); ?></a>
65
        <?php }
66
    }
67
    do_action('wpinv_invoice_display_right_actions', $invoice);
68
}
69
70 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...
71
    global $post;
72
73
    if ( !empty( $post ) && $post->post_type == 'wpi_invoice' && is_singular( 'wpi_invoice' ) && is_main_query() ) {
74
        ob_start();
75
        do_action( 'wpinv_before_invoice_content', $post->ID );
76
        $content = ob_get_clean() . $content;
77
    }
78
79
    return $content;
80
}
81
add_filter( 'the_content', 'wpinv_before_invoice_content' );
82
83 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...
84
    global $post;
85
86
    if ( !empty( $post ) && $post->post_type == 'wpi_invoice' && is_singular( 'wpi_invoice' ) && is_main_query() ) {
87
        ob_start();
88
        do_action( 'wpinv_after_invoice_content', $post->ID );
89
        $content .= ob_get_clean();
90
    }
91
92
    return $content;
93
}
94
add_filter( 'the_content', 'wpinv_after_invoice_content' );
95
96
function wpinv_get_templates_dir() {
97
    return WPINV_PLUGIN_DIR . 'templates';
98
}
99
100
function wpinv_get_templates_url() {
101
    return WPINV_PLUGIN_URL . 'templates';
102
}
103
104
function wpinv_get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
105
    if ( ! empty( $args ) && is_array( $args ) ) {
106
		extract( $args );
107
	}
108
109
	$located = wpinv_locate_template( $template_name, $template_path, $default_path );
110
	// Allow 3rd party plugin filter template file from their plugin.
111
	$located = apply_filters( 'wpinv_get_template', $located, $template_name, $args, $template_path, $default_path );
112
113
	if ( ! file_exists( $located ) ) {
114
        _doing_it_wrong( __FUNCTION__, sprintf( '<code>%s</code> does not exist.', $located ), '2.1' );
115
		return;
116
	}
117
118
	do_action( 'wpinv_before_template_part', $template_name, $template_path, $located, $args );
119
120
	include( $located );
121
122
	do_action( 'wpinv_after_template_part', $template_name, $template_path, $located, $args );
123
}
124
125
function wpinv_get_template_html( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
126
	ob_start();
127
	wpinv_get_template( $template_name, $args, $template_path, $default_path );
128
	return ob_get_clean();
129
}
130
131
function wpinv_locate_template( $template_name, $template_path = '', $default_path = '' ) {
132
    if ( ! $template_path ) {
133
        $template_path = wpinv_template_path();
134
    }
135
136
    if ( ! $default_path ) {
137
        $default_path = WPINV_PLUGIN_DIR . 'templates/';
138
    }
139
140
    // Look within passed path within the theme - this is priority.
141
    $template = locate_template(
142
        array(
143
            trailingslashit( $template_path ) . $template_name,
144
            $template_name
145
        )
146
    );
147
148
    // Get default templates/
149
    if ( !$template && $default_path ) {
150
        $template = trailingslashit( $default_path ) . $template_name;
151
    }
152
153
    // Return what we found.
154
    return apply_filters( 'wpinv_locate_template', $template, $template_name, $template_path );
155
}
156
157
function wpinv_get_template_part( $slug, $name = null, $load = true ) {
158
	do_action( 'get_template_part_' . $slug, $slug, $name );
159
160
	// Setup possible parts
161
	$templates = array();
162
	if ( isset( $name ) )
163
		$templates[] = $slug . '-' . $name . '.php';
164
	$templates[] = $slug . '.php';
165
166
	// Allow template parts to be filtered
167
	$templates = apply_filters( 'wpinv_get_template_part', $templates, $slug, $name );
168
169
	// Return the part that is found
170
	return wpinv_locate_tmpl( $templates, $load, false );
171
}
172
173
function wpinv_locate_tmpl( $template_names, $load = false, $require_once = true ) {
174
	// No file found yet
175
	$located = false;
176
177
	// Try to find a template file
178
	foreach ( (array)$template_names as $template_name ) {
179
180
		// Continue if template is empty
181
		if ( empty( $template_name ) )
182
			continue;
183
184
		// Trim off any slashes from the template name
185
		$template_name = ltrim( $template_name, '/' );
186
187
		// try locating this template file by looping through the template paths
188
		foreach( wpinv_get_theme_template_paths() as $template_path ) {
189
190
			if( file_exists( $template_path . $template_name ) ) {
191
				$located = $template_path . $template_name;
192
				break;
193
			}
194
		}
195
196
		if( !empty( $located ) ) {
197
			break;
198
		}
199
	}
200
201
	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...
202
		load_template( $located, $require_once );
203
204
	return $located;
205
}
206
207
function wpinv_get_theme_template_paths() {
208
	$template_dir = wpinv_get_theme_template_dir_name();
209
210
	$file_paths = array(
211
		1 => trailingslashit( get_stylesheet_directory() ) . $template_dir,
212
		10 => trailingslashit( get_template_directory() ) . $template_dir,
213
		100 => wpinv_get_templates_dir()
214
	);
215
216
	$file_paths = apply_filters( 'wpinv_template_paths', $file_paths );
217
218
	// sort the file paths based on priority
219
	ksort( $file_paths, SORT_NUMERIC );
220
221
	return array_map( 'trailingslashit', $file_paths );
222
}
223
224
function wpinv_get_theme_template_dir_name() {
225
	return trailingslashit( apply_filters( 'wpinv_templates_dir', 'invoicing' ) );
226
}
227
228
function wpinv_checkout_meta_tags() {
229
230
	$pages   = array();
231
	$pages[] = wpinv_get_option( 'success_page' );
232
	$pages[] = wpinv_get_option( 'failure_page' );
233
	$pages[] = wpinv_get_option( 'invoice_history_page' );
234
	$pages[] = wpinv_get_option( 'invoice_subscription_page' );
235
236
	if( !wpinv_is_checkout() && !is_page( $pages ) ) {
237
		return;
238
	}
239
240
	echo '<meta name="robots" content="noindex,nofollow" />' . "\n";
241
}
242
add_action( 'wp_head', 'wpinv_checkout_meta_tags' );
243
244
function wpinv_add_body_classes( $class ) {
245
	$classes = (array)$class;
246
247
	if( wpinv_is_checkout() ) {
248
		$classes[] = 'wpinv-checkout';
249
		$classes[] = 'wpinv-page';
250
	}
251
252
	if( wpinv_is_success_page() ) {
253
		$classes[] = 'wpinv-success';
254
		$classes[] = 'wpinv-page';
255
	}
256
257
	if( wpinv_is_failed_transaction_page() ) {
258
		$classes[] = 'wpinv-failed-transaction';
259
		$classes[] = 'wpinv-page';
260
	}
261
262
	if( wpinv_is_invoice_history_page() ) {
263
		$classes[] = 'wpinv-history';
264
		$classes[] = 'wpinv-page';
265
	}
266
267
	if( wpinv_is_subscriptions_history_page() ) {
268
		$classes[] = 'wpinv-subscription';
269
		$classes[] = 'wpinv-page';
270
	}
271
272
	if( wpinv_is_test_mode() ) {
273
		$classes[] = 'wpinv-test-mode';
274
		$classes[] = 'wpinv-page';
275
	}
276
277
	return array_unique( $classes );
278
}
279
add_filter( 'body_class', 'wpinv_add_body_classes' );
280
281
function wpinv_html_dropdown( $name = 'wpinv_discounts', $selected = 0, $status = '' ) {
282
    $args = array( 'nopaging' => true );
283
284
    if ( ! empty( $status ) )
285
        $args['post_status'] = $status;
286
287
    $discounts = wpinv_get_discounts( $args );
288
    $options   = array();
289
290
    if ( $discounts ) {
291
        foreach ( $discounts as $discount ) {
292
            $options[ absint( $discount->ID ) ] = esc_html( get_the_title( $discount->ID ) );
293
        }
294
    } else {
295
        $options[0] = __( 'No discounts found', 'invoicing' );
296
    }
297
298
    $output = wpinv_html_select( array(
299
        'name'             => $name,
300
        'selected'         => $selected,
301
        'options'          => $options,
302
        'show_option_all'  => false,
303
        'show_option_none' => false,
304
    ) );
305
306
    return $output;
307
}
308
309
function wpinv_html_year_dropdown( $name = 'year', $selected = 0, $years_before = 5, $years_after = 0 ) {
310
    $current     = date( 'Y' );
311
    $start_year  = $current - absint( $years_before );
312
    $end_year    = $current + absint( $years_after );
313
    $selected    = empty( $selected ) ? date( 'Y' ) : $selected;
314
    $options     = array();
315
316
    while ( $start_year <= $end_year ) {
317
        $options[ absint( $start_year ) ] = $start_year;
318
        $start_year++;
319
    }
320
321
    $output = wpinv_html_select( array(
322
        'name'             => $name,
323
        'selected'         => $selected,
324
        'options'          => $options,
325
        'show_option_all'  => false,
326
        'show_option_none' => false
327
    ) );
328
329
    return $output;
330
}
331
332
function wpinv_html_month_dropdown( $name = 'month', $selected = 0 ) {
333
    $month   = 1;
334
    $options = array();
335
    $selected = empty( $selected ) ? date( 'n' ) : $selected;
336
337
    while ( $month <= 12 ) {
338
        $options[ absint( $month ) ] = wpinv_month_num_to_name( $month );
339
        $month++;
340
    }
341
342
    $output = wpinv_html_select( array(
343
        'name'             => $name,
344
        'selected'         => $selected,
345
        'options'          => $options,
346
        'show_option_all'  => false,
347
        'show_option_none' => false
348
    ) );
349
350
    return $output;
351
}
352
353
function wpinv_html_select( $args = array() ) {
354
    $defaults = array(
355
        'options'          => array(),
356
        'name'             => null,
357
        'class'            => '',
358
        'id'               => '',
359
        'selected'         => 0,
360
        'placeholder'      => null,
361
        'multiple'         => false,
362
        'show_option_all'  => _x( 'All', 'all dropdown items', 'invoicing' ),
363
        'show_option_none' => _x( 'None', 'no dropdown items', 'invoicing' ),
364
        'data'             => array(),
365
        'onchange'         => null,
366
        'required'         => false,
367
        'disabled'         => false,
368
        'readonly'         => false,
369
    );
370
371
    $args = wp_parse_args( $args, $defaults );
372
373
    $data_elements = '';
374
    foreach ( $args['data'] as $key => $value ) {
375
        $data_elements .= ' data-' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
376
    }
377
378
    if( $args['multiple'] ) {
379
        $multiple = ' MULTIPLE';
380
    } else {
381
        $multiple = '';
382
    }
383
384
    if( $args['placeholder'] ) {
385
        $placeholder = $args['placeholder'];
386
    } else {
387
        $placeholder = '';
388
    }
389
    
390
    $options = '';
391 View Code Duplication
    if( !empty( $args['onchange'] ) ) {
392
        $options .= ' onchange="' . esc_attr( $args['onchange'] ) . '"';
393
    }
394
    
395
    if( !empty( $args['required'] ) ) {
396
        $options .= ' required="required"';
397
    }
398
    
399
    if( !empty( $args['disabled'] ) ) {
400
        $options .= ' disabled';
401
    }
402
    
403
    if( !empty( $args['readonly'] ) ) {
404
        $options .= ' readonly';
405
    }
406
407
    $class  = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['class'] ) ) );
408
    $output = '<select name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" class="wpinv-select ' . $class . '"' . $multiple . ' data-placeholder="' . $placeholder . '" ' . trim( $options ) . $data_elements . '>';
409
410 View Code Duplication
    if ( $args['show_option_all'] ) {
411
        if( $args['multiple'] ) {
412
            $selected = selected( true, in_array( 0, $args['selected'] ), false );
413
        } else {
414
            $selected = selected( $args['selected'], 0, false );
415
        }
416
        $output .= '<option value="all"' . $selected . '>' . esc_html( $args['show_option_all'] ) . '</option>';
417
    }
418
419
    if ( !empty( $args['options'] ) ) {
420
421 View Code Duplication
        if ( $args['show_option_none'] ) {
422
            if( $args['multiple'] ) {
423
                $selected = selected( true, in_array( "", $args['selected'] ), false );
424
            } else {
425
                $selected = selected( $args['selected'] === "", true, false );
426
            }
427
            $output .= '<option value=""' . $selected . '>' . esc_html( $args['show_option_none'] ) . '</option>';
428
        }
429
430
        foreach( $args['options'] as $key => $option ) {
431
432
            if( $args['multiple'] && is_array( $args['selected'] ) ) {
433
                $selected = selected( true, (bool)in_array( $key, $args['selected'] ), false );
434
            } else {
435
                $selected = selected( $args['selected'], $key, false );
436
            }
437
438
            $output .= '<option value="' . esc_attr( $key ) . '"' . $selected . '>' . esc_html( $option ) . '</option>';
439
        }
440
    }
441
442
    $output .= '</select>';
443
444
    return $output;
445
}
446
447
function wpinv_item_dropdown( $args = array() ) {
448
    $defaults = array(
449
        'name'              => 'wpi_item',
450
        'id'                => 'wpi_item',
451
        'class'             => '',
452
        'multiple'          => false,
453
        'selected'          => 0,
454
        'number'            => 100,
455
        'placeholder'       => __( 'Choose a item', 'invoicing' ),
456
        'data'              => array( 'search-type' => 'item' ),
457
        'show_option_all'   => false,
458
        'show_option_none'  => false,
459
        'show_recurring'    => false,
460
    );
461
462
    $args = wp_parse_args( $args, $defaults );
463
464
    $item_args = array(
465
        'post_type'      => 'wpi_item',
466
        'orderby'        => 'title',
467
        'order'          => 'ASC',
468
        'posts_per_page' => $args['number']
469
    );
470
    
471
    $item_args  = apply_filters( 'wpinv_item_dropdown_query_args', $item_args, $args, $defaults );
472
473
    $items      = get_posts( $item_args );
474
    $options    = array();
475
    if ( $items ) {
476
        foreach ( $items as $item ) {
477
            $title = esc_html( $item->post_title );
478
            
479
            if ( !empty( $args['show_recurring'] ) ) {
480
                $title .= wpinv_get_item_suffix( $item->ID, false );
481
            }
482
            
483
            $options[ absint( $item->ID ) ] = $title;
484
        }
485
    }
486
487
    // This ensures that any selected items are included in the drop down
488
    if( is_array( $args['selected'] ) ) {
489
        foreach( $args['selected'] as $item ) {
490
            if( ! in_array( $item, $options ) ) {
491
                $title = get_the_title( $item );
492
                if ( !empty( $args['show_recurring'] ) ) {
493
                    $title .= wpinv_get_item_suffix( $item, false );
494
                }
495
                $options[$item] = $title;
496
            }
497
        }
498
    } elseif ( is_numeric( $args['selected'] ) && $args['selected'] !== 0 ) {
499
        if ( ! in_array( $args['selected'], $options ) ) {
500
            $title = get_the_title( $args['selected'] );
501
            if ( !empty( $args['show_recurring'] ) ) {
502
                $title .= wpinv_get_item_suffix( $args['selected'], false );
503
            }
504
            $options[$args['selected']] = get_the_title( $args['selected'] );
505
        }
506
    }
507
508
    $output = wpinv_html_select( array(
509
        'name'             => $args['name'],
510
        'selected'         => $args['selected'],
511
        'id'               => $args['id'],
512
        'class'            => $args['class'],
513
        'options'          => $options,
514
        'multiple'         => $args['multiple'],
515
        'placeholder'      => $args['placeholder'],
516
        'show_option_all'  => $args['show_option_all'],
517
        'show_option_none' => $args['show_option_none'],
518
        'data'             => $args['data'],
519
    ) );
520
521
    return $output;
522
}
523
524
function wpinv_html_checkbox( $args = array() ) {
525
    $defaults = array(
526
        'name'     => null,
527
        'current'  => null,
528
        'class'    => 'wpinv-checkbox',
529
        'options'  => array(
530
            'disabled' => false,
531
            'readonly' => false
532
        )
533
    );
534
535
    $args = wp_parse_args( $args, $defaults );
536
537
    $class = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['class'] ) ) );
538
    $options = '';
539
    if ( ! empty( $args['options']['disabled'] ) ) {
540
        $options .= ' disabled="disabled"';
541
    } elseif ( ! empty( $args['options']['readonly'] ) ) {
542
        $options .= ' readonly';
543
    }
544
545
    $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 ) . ' />';
546
547
    return $output;
548
}
549
550
function wpinv_html_text( $args = array() ) {
551
    // Backwards compatibility
552
    if ( func_num_args() > 1 ) {
553
        $args = func_get_args();
554
555
        $name  = $args[0];
556
        $value = isset( $args[1] ) ? $args[1] : '';
557
        $label = isset( $args[2] ) ? $args[2] : '';
558
        $desc  = isset( $args[3] ) ? $args[3] : '';
559
    }
560
561
    $defaults = array(
562
        'id'           => '',
563
        'name'         => isset( $name )  ? $name  : 'text',
564
        'value'        => isset( $value ) ? $value : null,
565
        'label'        => isset( $label ) ? $label : null,
566
        'desc'         => isset( $desc )  ? $desc  : null,
567
        'placeholder'  => '',
568
        'class'        => 'regular-text',
569
        'disabled'     => false,
570
        'readonly'     => false,
571
        'required'     => false,
572
        'autocomplete' => '',
573
        'data'         => false
574
    );
575
576
    $args = wp_parse_args( $args, $defaults );
577
578
    $class = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['class'] ) ) );
579
    $options = '';
580
    if( $args['required'] ) {
581
        $options .= ' required="required"';
582
    }
583
    if( $args['readonly'] ) {
584
        $options .= ' readonly';
585
    }
586
    if( $args['readonly'] ) {
587
        $options .= ' readonly';
588
    }
589
590
    $data = '';
591
    if ( !empty( $args['data'] ) ) {
592
        foreach ( $args['data'] as $key => $value ) {
593
            $data .= 'data-' . wpinv_sanitize_key( $key ) . '="' . esc_attr( $value ) . '" ';
594
        }
595
    }
596
597
    $output = '<span id="wpinv-' . wpinv_sanitize_key( $args['name'] ) . '-wrap">';
598
    $output .= '<label class="wpinv-label" for="' . wpinv_sanitize_key( $args['id'] ) . '">' . esc_html( $args['label'] ) . '</label>';
599 View Code Duplication
    if ( ! empty( $args['desc'] ) ) {
600
        $output .= '<span class="wpinv-description">' . esc_html( $args['desc'] ) . '</span>';
601
    }
602
603
    $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 ) . '/>';
604
605
    $output .= '</span>';
606
607
    return $output;
608
}
609
610
function wpinv_html_date_field( $args = array() ) {
611
    if( empty( $args['class'] ) ) {
612
        $args['class'] = 'wpiDatepicker';
613
    } elseif( ! strpos( $args['class'], 'wpiDatepicker' ) ) {
614
        $args['class'] .= ' wpiDatepicker';
615
    }
616
617
    return wpinv_html_text( $args );
618
}
619
620
function wpinv_html_textarea( $args = array() ) {
621
    $defaults = array(
622
        'name'        => 'textarea',
623
        'value'       => null,
624
        'label'       => null,
625
        'desc'        => null,
626
        'class'       => 'large-text',
627
        'disabled'    => false
628
    );
629
630
    $args = wp_parse_args( $args, $defaults );
631
632
    $class = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['class'] ) ) );
633
    $disabled = '';
634
    if( $args['disabled'] ) {
635
        $disabled = ' disabled="disabled"';
636
    }
637
638
    $output = '<span id="wpinv-' . wpinv_sanitize_key( $args['name'] ) . '-wrap">';
639
    $output .= '<label class="wpinv-label" for="' . wpinv_sanitize_key( $args['name'] ) . '">' . esc_html( $args['label'] ) . '</label>';
640
    $output .= '<textarea name="' . esc_attr( $args['name'] ) . '" id="' . wpinv_sanitize_key( $args['name'] ) . '" class="' . $class . '"' . $disabled . '>' . esc_attr( $args['value'] ) . '</textarea>';
641
642 View Code Duplication
    if ( ! empty( $args['desc'] ) ) {
643
        $output .= '<span class="wpinv-description">' . esc_html( $args['desc'] ) . '</span>';
644
    }
645
    $output .= '</span>';
646
647
    return $output;
648
}
649
650
function wpinv_html_ajax_user_search( $args = array() ) {
651
    $defaults = array(
652
        'name'        => 'user_id',
653
        'value'       => null,
654
        'placeholder' => __( 'Enter username', 'invoicing' ),
655
        'label'       => null,
656
        'desc'        => null,
657
        'class'       => '',
658
        'disabled'    => false,
659
        'autocomplete'=> 'off',
660
        'data'        => false
661
    );
662
663
    $args = wp_parse_args( $args, $defaults );
664
665
    $args['class'] = 'wpinv-ajax-user-search ' . $args['class'];
666
667
    $output  = '<span class="wpinv_user_search_wrap">';
668
        $output .= wpinv_html_text( $args );
669
        $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>';
670
    $output .= '</span>';
671
672
    return $output;
673
}
674
675
function wpinv_ip_geolocation() {
676
    global $wpinv_euvat;
677
    
678
    $ip         = !empty( $_GET['ip'] ) ? sanitize_text_field( $_GET['ip'] ) : '';    
679
    $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...
680
    $iso        = '';
681
    $country    = '';
682
    $region     = '';
683
    $city       = '';
684
    $longitude  = '';
685
    $latitude   = '';
686
    $credit     = '';
687
    $address    = '';
688
    
689
    if ( wpinv_get_option( 'vat_ip_lookup' ) == 'geoip2' && $geoip2_city = $wpinv_euvat->geoip2_city_record( $ip ) ) {
690
        try {
691
            $iso        = $geoip2_city->country->isoCode;
692
            $country    = $geoip2_city->country->name;
693
            $region     = !empty( $geoip2_city->subdivisions ) && !empty( $geoip2_city->subdivisions[0]->name ) ? $geoip2_city->subdivisions[0]->name : '';
694
            $city       = $geoip2_city->city->name;
695
            $longitude  = $geoip2_city->location->longitude;
696
            $latitude   = $geoip2_city->location->latitude;
697
            $credit     = __( 'Geolocated using the information by MaxMind, available from <a href="http://www.maxmind.com" target="_blank">www.maxmind.com</a>', 'invoicing' );
698
        } catch( Exception $e ) { }
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
699
    }
700
    
701
    if ( !( $iso && $longitude && $latitude ) && function_exists( 'simplexml_load_file' ) ) {
702
        try {
703
            $load_xml = simplexml_load_file( 'http://www.geoplugin.net/xml.gp?ip=' . $ip );
704
            
705
            if ( !empty( $load_xml ) && isset( $load_xml->geoplugin_countryCode ) && !empty( $load_xml->geoplugin_latitude ) && !empty( $load_xml->geoplugin_longitude ) ) {
706
                $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...
707
                $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...
708
                $region     = !empty( $load_xml->geoplugin_regionName ) ? $load_xml->geoplugin_regionName : '';
709
                $city       = !empty( $load_xml->geoplugin_city ) ? $load_xml->geoplugin_city : '';
710
                $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...
711
                $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...
712
                $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...
713
                $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;
714
            }
715
        } catch( Exception $e ) { }
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
716
    }
717
    
718
    if ( $iso && $longitude && $latitude ) {
719
        if ( $city ) {
720
            $address .= $city . ', ';
721
        }
722
        
723
        if ( $region ) {
724
            $address .= $region . ', ';
725
        }
726
        
727
        $address .= $country . ' (' . $iso . ')';
728
        $content = '<p>'. sprintf( __( '<b>Address:</b> %s', 'invoicing' ), $address ) . '</p>';
729
        $content .= '<p>'. $credit . '</p>';
730
    } else {
731
        $content = '<p>'. sprintf( __( 'Unable to find geolocation for the IP address: %s', 'invoicing' ), $ip ) . '</p>';
732
    }
733
    ?>
734
<!DOCTYPE html>
735
<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>
736
<body>
737
    <?php if ( $latitude && $latitude ) { ?>
738
    <div id="map"></div>
739
        <script src="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-rc.1/leaflet.js"></script>
740
        <script type="text/javascript">
741
        var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
742
            osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
743
            osm = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib}),
744
            latlng = new L.LatLng(<?php echo $latitude;?>, <?php echo $longitude;?>);
745
746
        var map = new L.Map('map', {center: latlng, zoom: 12, layers: [osm]});
747
748
        var marker = new L.Marker(latlng);
749
        map.addLayer(marker);
750
751
        marker.bindPopup("<p><?php esc_attr_e( $address );?></p>");
752
    </script>
753
    <?php } ?>
754
    <div style="height:100px"><?php echo $content; ?></div>
755
</body></html>
756
<?php
757
    exit;
758
}
759
add_action( 'wp_ajax_wpinv_ip_geolocation', 'wpinv_ip_geolocation' );
760
add_action( 'wp_ajax_nopriv_wpinv_ip_geolocation', 'wpinv_ip_geolocation' );
761
762
// Set up the template for the invoice.
763
function wpinv_template( $template ) {
764
    global $post, $wp_query;
765
    
766
    if ( ( is_single() || is_404() ) && !empty( $post->ID ) && (get_post_type( $post->ID ) == 'wpi_invoice' or get_post_type( $post->ID ) == 'wpi_quote')) {
767
        if ( wpinv_user_can_view_invoice( $post->ID ) ) {
768
            $template = wpinv_get_template_part( 'wpinv-invoice-print', false, false );
769
        } else {
770
            $template = wpinv_get_template_part( 'wpinv-invalid-access', false, false );
771
        }
772
    }
773
774
    return $template;
775
}
776
777
function wpinv_get_business_address() {
778
    $business_address   = wpinv_store_address();
779
    $business_address   = !empty( $business_address ) ? wpautop( wp_kses_post( $business_address ) ) : '';
780
    
781
    /*
782
    $default_country    = wpinv_get_default_country();
783
    $default_state      = wpinv_get_default_state();
784
    
785
    $address_fields = array();
786
    if ( !empty( $default_state ) ) {
787
        $address_fields[] = wpinv_state_name( $default_state, $default_country );
788
    }
789
    
790
    if ( !empty( $default_country ) ) {
791
        $address_fields[] = wpinv_country_name( $default_country );
792
    }
793
    
794
    if ( !empty( $address_fields ) ) {
795
        $address_fields = implode( ", ", $address_fields );
796
                
797
        $business_address .= wpautop( wp_kses_post( $address_fields ) );
798
    }
799
    */
800
    
801
    $business_address = $business_address ? '<div class="address">' . $business_address . '</div>' : '';
802
    
803
    return apply_filters( 'wpinv_get_business_address', $business_address );
804
}
805
806
function wpinv_display_from_address() {
807
    global $wpinv_euvat;
808
    
809
    $from_name = $wpinv_euvat->get_company_name();
810
    if (empty($from_name)) {
811
        $from_name = wpinv_get_business_name();
812
    }
813
    ?><div class="from col-xs-2"><strong><?php _e( 'From:', 'invoicing' ) ?></strong></div>
814
    <div class="wrapper col-xs-10">
815
        <div class="name"><?php echo esc_html( $from_name ); ?></div>
816
        <?php if ( $address = wpinv_get_business_address() ) { ?>
817
        <div class="address"><?php echo wpautop( wp_kses_post( $address ) );?></div>
818
        <?php } ?>
819
        <?php if ( $email_from = wpinv_mail_get_from_address() ) { ?>
820
        <div class="email_from"><?php echo wp_sprintf( __( 'Email: %s', 'invoicing' ), $email_from );?></div>
821
        <?php } ?>
822
    </div>
823
    <?php
824
}
825
826
function wpinv_watermark( $id = 0 ) {
827
    $output = wpinv_get_watermark( $id );
828
    
829
    return apply_filters( 'wpinv_get_watermark', $output, $id );
830
}
831
832
function wpinv_get_watermark( $id ) {
833
    if ( !$id > 0 ) {
834
        return NULL;
835
    }
836
    $invoice = wpinv_get_invoice( $id );
837
    
838
    if ( !empty( $invoice ) && "wpi_invoice" === $invoice->post_type ) {
839
        if ( $invoice->is_paid() ) {
840
            return __( 'Paid', 'invoicing' );
841
        }
842
        if ( $invoice->is_refunded() ) {
843
            return __( 'Refunded', 'invoicing' );
844
        }
845
        if ( $invoice->has_status( array( 'wpi-cancelled' ) ) ) {
846
            return __( 'Cancelled', 'invoicing' );
847
        }
848
    }
849
    
850
    return NULL;
851
}
852
853
function wpinv_display_invoice_details( $invoice ) {
854
    global $wpinv_euvat;
855
    
856
    $invoice_id = $invoice->ID;
857
    $vat_name   = $wpinv_euvat->get_vat_name();
858
    $use_taxes  = wpinv_use_taxes();
859
    
860
    $invoice_status = wpinv_get_invoice_status( $invoice_id );
861
    ?>
862
    <table class="table table-bordered table-sm">
863 View Code Duplication
        <?php if ( $invoice_number = wpinv_get_invoice_number( $invoice_id ) ) { ?>
864
            <tr class="wpi-row-number">
865
                <th><?php echo apply_filters( 'wpinv_invoice_number_label', __( 'Invoice Number', 'invoicing' ), $invoice ); ?></th>
866
                <td><?php echo esc_html( $invoice_number ); ?></td>
867
            </tr>
868
        <?php } ?>
869
        <tr class="wpi-row-status">
870
            <th><?php echo apply_filters( 'wpinv_invoice_status_label', __( 'Invoice Status', 'invoicing' ), $invoice ); ?></th>
871
            <td><?php echo wpinv_invoice_status_label( $invoice_status, wpinv_get_invoice_status( $invoice_id, true ) ); ?></td>
872
        </tr>
873 View Code Duplication
        <?php if ( $invoice->is_renewal() ) { ?>
874
        <tr class="wpi-row-parent">
875
            <th><?php echo apply_filters( 'wpinv_invoice_parent_invoice_label', __( 'Parent Invoice', 'invoicing' ), $invoice ); ?></th>
876
            <td><?php echo wpinv_invoice_link( $invoice->parent_invoice ); ?></td>
877
        </tr>
878
        <?php } ?>
879 View Code Duplication
        <?php if ( ( $gateway_name = wpinv_get_payment_gateway_name( $invoice_id ) ) && ( $invoice->is_paid() || $invoice->is_refunded() ) ) { ?>
880
            <tr class="wpi-row-gateway">
881
                <th><?php echo apply_filters( 'wpinv_invoice_payment_method_label', __( 'Payment Method', 'invoicing' ), $invoice ); ?></th>
882
                <td><?php echo $gateway_name; ?></td>
883
            </tr>
884
        <?php } ?>
885
        <?php if ( $invoice_date = wpinv_get_invoice_date( $invoice_id ) ) { ?>
886
            <tr class="wpi-row-date">
887
                <th><?php echo apply_filters( 'wpinv_invoice_date_label', __( 'Invoice Date', 'invoicing' ), $invoice ); ?></th>
888
                <td><?php echo $invoice_date; ?></td>
889
            </tr>
890
        <?php } ?>
891
        <?php if ( wpinv_get_option( 'overdue_active' ) && $invoice->needs_payment() && ( $due_date = $invoice->get_due_date( true ) ) ) { ?>
892
            <tr class="wpi-row-date">
893
                <th><?php echo apply_filters( 'wpinv_invoice_due_date_label', __( 'Due Date', 'invoicing' ), $invoice ); ?></th>
894
                <td><?php echo $due_date; ?></td>
895
            </tr>
896
        <?php } ?>
897
        <?php do_action( 'wpinv_display_details_after_due_date', $invoice_id ); ?>
898 View Code Duplication
        <?php if ( $owner_vat_number = $wpinv_euvat->get_vat_number() ) { ?>
899
            <tr class="wpi-row-ovatno">
900
                <th><?php echo apply_filters( 'wpinv_invoice_owner_vat_number_label', wp_sprintf( __( 'Owner %s Number', 'invoicing' ), $vat_name ), $invoice, $vat_name ); ?></th>
901
                <td><?php echo $owner_vat_number; ?></td>
902
            </tr>
903
        <?php } ?>
904
        <?php do_action( 'wpinv_display_details_after_due_date', $invoice_id ); ?>
905 View Code Duplication
        <?php if ( $use_taxes && ( $user_vat_number = wpinv_get_invoice_vat_number( $invoice_id ) ) ) { ?>
906
            <tr class="wpi-row-uvatno">
907
                <th><?php echo apply_filters( 'wpinv_invoice_user_vat_number_label', wp_sprintf( __( 'Invoice %s Number', 'invoicing' ), $vat_name ), $invoice, $vat_name ); ?></th>
908
                <td><?php echo $user_vat_number; ?></td>
909
            </tr>
910
        <?php } ?>
911
        <tr class="table-active tr-total wpi-row-total">
912
            <th><strong><?php _e( 'Total Amount', 'invoicing' ) ?></strong></th>
913
            <td><strong><?php echo wpinv_payment_total( $invoice_id, true ); ?></strong></td>
914
        </tr>
915
    </table>
916
<?php
917
}
918
919
function wpinv_display_to_address( $invoice_id = 0 ) {
920
    $invoice = wpinv_get_invoice( $invoice_id );
921
    
922
    if ( empty( $invoice ) ) {
923
        return NULL;
924
    }
925
    
926
    $billing_details = $invoice->get_user_info();
927
    $output = '<div class="to col-xs-2"><strong>' . __( 'To:', 'invoicing' ) . '</strong></div>';
928
    $output .= '<div class="wrapper col-xs-10">';
929
    
930
    ob_start();
931
    do_action( 'wpinv_display_to_address_top', $invoice );
932
    $output .= ob_get_clean();
933
    
934
    $output .= '<div class="name">' . esc_html( trim( $billing_details['first_name'] . ' ' . $billing_details['last_name'] ) ) . '</div>';
935
    if ( $company = $billing_details['company'] ) {
936
        $output .= '<div class="company">' . wpautop( wp_kses_post( $company ) ) . '</div>';
937
    }
938
    $address_row = '';
939
    if ( $address = $billing_details['address'] ) {
940
        $address_row .= wpautop( wp_kses_post( $address ) );
941
    }
942
    
943
    $address_fields = array();
944
    if ( !empty( $billing_details['city'] ) ) {
945
        $address_fields[] = $billing_details['city'];
946
    }
947
    
948
    $billing_country = !empty( $billing_details['country'] ) ? $billing_details['country'] : '';
949
    if ( !empty( $billing_details['state'] ) ) {
950
        $address_fields[] = wpinv_state_name( $billing_details['state'], $billing_country );
951
    }
952
953
    if ( !empty( $billing_country ) ) {
954
        $address_fields[] = wpinv_country_name( $billing_country );
955
    }
956
957 View Code Duplication
    if ( !empty( $address_fields ) ) {
958
        $address_fields = implode( ", ", $address_fields );
959
        
960
        if ( !empty( $billing_details['zip'] ) ) {
961
            $address_fields .= ' ' . $billing_details['zip'];
962
        }
963
964
        $address_row .= wpautop( wp_kses_post( $address_fields ) );
965
    }
966
    
967
    if ( $address_row ) {
968
        $output .= '<div class="address">' . $address_row . '</div>';
969
    }
970
971 View Code Duplication
    if ( $phone = $invoice->get_phone() ) {
972
        $output .= '<div class="phone">' . wp_sprintf( __( 'Phone: %s', 'invoicing' ), esc_html( $phone ) ) . '</div>';
973
    }
974 View Code Duplication
    if ( $email = $invoice->get_email() ) {
975
        $output .= '<div class="email">' . wp_sprintf( __( 'Email: %s' , 'invoicing'), esc_html( $email ) ) . '</div>';
976
    }
977
978
    ob_start();
979
    do_action( 'wpinv_display_to_address_bottom', $invoice );
980
    $output .= ob_get_clean();
981
    
982
    $output .= '</div>';
983
    $output = apply_filters( 'wpinv_display_to_address', $output, $invoice );
984
985
    echo $output;
986
}
987
988
function wpinv_display_line_items( $invoice_id = 0 ) {
989
    global $wpinv_euvat, $ajax_cart_details;
990
    $invoice            = wpinv_get_invoice( $invoice_id );
991
    $quantities_enabled = wpinv_item_quantities_enabled();
992
    $use_taxes          = wpinv_use_taxes();
993
    if ( !$use_taxes && (float)$invoice->get_tax() > 0 ) {
994
        $use_taxes = true;
995
    }
996
    $zero_tax           = !(float)$invoice->get_tax() > 0 ? true : false;
997
    $tax_label           = $use_taxes && $invoice->has_vat() ? $wpinv_euvat->get_vat_name() : __( 'Tax', 'invoicing' );
998
    $tax_title          = !$zero_tax && $use_taxes ? ( wpinv_prices_include_tax() ? wp_sprintf( __( '(%s Incl.)', 'invoicing' ), $tax_label ) : wp_sprintf( __( '(%s Excl.)', 'invoicing' ), $tax_label ) ) : '';
999
1000
    $cart_details       = $invoice->get_cart_details();
1001
    $ajax_cart_details  = $cart_details;
1002
    ob_start();
1003
    ?>
1004
    <table class="table table-sm table-bordered table-responsive">
1005
        <thead>
1006
            <tr>
1007
                <th class="name"><strong><?php _e( "Item Name", "invoicing" );?></strong></th>
1008
                <th class="rate"><strong><?php _e( "Price", "invoicing" );?></strong></th>
1009
                <?php if ($quantities_enabled) { ?>
1010
                    <th class="qty"><strong><?php _e( "Qty", "invoicing" );?></strong></th>
1011
                <?php } ?>
1012
                <?php if ($use_taxes && !$zero_tax) { ?>
1013
                    <th class="tax"><strong><?php echo $tax_label . ' <span class="normal small">(%)</span>'; ?></strong></th>
1014
                <?php } ?>
1015
                <th class="total"><strong><?php echo __( "Item Total", "invoicing" ) . ' <span class="normal small">' . $tax_title . '<span>';?></strong></th>
1016
            </tr>
1017
        </thead>
1018
        <tbody>
1019
        <?php 
1020
            if ( !empty( $cart_details ) ) {
1021
                do_action( 'wpinv_display_line_items_start', $invoice );
1022
1023
                $count = 0;
1024
                $cols  = 3;
1025
                foreach ( $cart_details as $key => $cart_item ) {
1026
                    $item_id    = !empty($cart_item['id']) ? absint( $cart_item['id'] ) : '';
1027
                    $item_price = isset($cart_item["item_price"]) ? wpinv_round_amount( $cart_item["item_price"] ) : 0;
1028
                    $line_total = isset($cart_item["subtotal"]) ? wpinv_round_amount( $cart_item["subtotal"] ) : 0;
1029
                    $quantity   = !empty($cart_item['quantity']) && (int)$cart_item['quantity'] > 0 ? absint( $cart_item['quantity'] ) : 1;
1030
1031
                    $item       = $item_id ? new WPInv_Item( $item_id ) : NULL;
1032
                    $summary    = '';
1033
                    $cols       = 3;
1034
                    if ( !empty($item) ) {
1035
                        $item_name  = $item->get_name();
1036
                        $summary    = $item->get_summary();
1037
                    }
1038
                    $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...
1039
1040
                    $summary = apply_filters( 'wpinv_print_invoice_line_item_summary', $summary, $cart_item, $item, $invoice );
1041
1042
                    $item_tax       = '';
1043
                    $tax_rate       = '';
1044 View Code Duplication
                    if ( $use_taxes && $cart_item['tax'] > 0 && $cart_item['subtotal'] > 0 ) {
1045
                        $item_tax = wpinv_price( wpinv_format_amount( $cart_item['tax'] ), $invoice->get_currency() );
1046
                        $tax_rate = !empty( $cart_item['vat_rate'] ) ? $cart_item['vat_rate'] : ( $cart_item['tax'] / $cart_item['subtotal'] ) * 100;
1047
                        $tax_rate = $tax_rate > 0 ? (float)wpinv_round_amount( $tax_rate, 4 ) : '';
1048
                        $tax_rate = $tax_rate != '' ? ' <small class="tax-rate">(' . $tax_rate . '%)</small>' : '';
1049
                    }
1050
1051
                    $line_item_tax = $item_tax . $tax_rate;
1052
1053
                    if ( $line_item_tax === '' ) {
1054
                        $line_item_tax = 0; // Zero tax
1055
                    }
1056
1057
                    $action = apply_filters( 'wpinv_display_line_item_action', '', $cart_item, $invoice, $cols );
1058
1059
                    $line_item = '<tr class="row-' . ( ($count % 2 == 0) ? 'even' : 'odd' ) . ' wpinv-item">';
1060
                        $line_item .= '<td class="name">' . $action. esc_html__( $item_name, 'invoicing' ) . wpinv_get_item_suffix( $item );
1061
                        if ( $summary !== '' ) {
1062
                            $line_item .= '<br/><small class="meta">' . wpautop( wp_kses_post( $summary ) ) . '</small>';
1063
                        }
1064
                        $line_item .= '</td>';
1065
1066
                        $line_item .= '<td class="rate">' . esc_html__( wpinv_price( wpinv_format_amount( $item_price ), $invoice->get_currency() ) ) . '</td>';
1067
                        if ($quantities_enabled) {
1068
                            $cols++;
1069
                            $line_item .= '<td class="qty">' . $quantity . '</td>';
1070
                        }
1071
                        if ($use_taxes && !$zero_tax) {
1072
                            $cols++;
1073
                            $line_item .= '<td class="tax">' . $line_item_tax . '</td>';
1074
                        }
1075
                        $line_item .= '<td class="total">' . esc_html__( wpinv_price( wpinv_format_amount( $line_total ), $invoice->get_currency() ) ) . '</td>';
1076
                    $line_item .= '</tr>';
1077
1078
                    echo apply_filters( 'wpinv_display_line_item', $line_item, $cart_item, $invoice, $cols );
1079
1080
                    $count++;
1081
                }
1082
1083
                do_action( 'wpinv_display_before_subtotal', $invoice, $cols );
1084
                ?>
1085
                <tr class="row-sub-total row_odd">
1086
                    <td class="rate" colspan="<?php echo ( $cols - 1 ); ?>"><?php echo apply_filters( 'wpinv_print_cart_subtotal_label', '<strong>' . __( 'Sub Total', 'invoicing' ) . ':</strong>', $invoice ); ?></td>
1087
                    <td class="total"><strong><?php _e( wpinv_subtotal( $invoice_id, true ) ) ?></strong></td>
1088
                </tr>
1089
                <?php
1090
                do_action( 'wpinv_display_after_subtotal', $invoice, $cols );
1091
                
1092 View Code Duplication
                if ( wpinv_discount( $invoice_id, false ) > 0 ) {
1093
                    do_action( 'wpinv_display_before_discount', $invoice, $cols );
1094
                    ?>
1095
                        <tr class="row-discount">
1096
                            <td class="rate" colspan="<?php echo ( $cols - 1 ); ?>"><?php wpinv_get_discount_label( wpinv_discount_code( $invoice_id ) ); ?>:</td>
1097
                            <td class="total"><?php echo wpinv_discount( $invoice_id, true, true ); ?></td>
1098
                        </tr>
1099
                    <?php
1100
                    do_action( 'wpinv_display_after_discount', $invoice, $cols );
1101
                }
1102
1103
                if ( $use_taxes ) {
1104
                    do_action( 'wpinv_display_before_tax', $invoice, $cols );
1105
                    ?>
1106
                    <tr class="row-tax">
1107
                        <td class="rate" colspan="<?php echo ( $cols - 1 ); ?>"><?php echo apply_filters( 'wpinv_print_cart_tax_label', '<strong>' . $tax_label . ':</strong>', $invoice ); ?></td>
1108
                        <td class="total"><?php _e( wpinv_tax( $invoice_id, true ) ) ?></td>
1109
                    </tr>
1110
                    <?php
1111
                    do_action( 'wpinv_display_after_tax', $invoice, $cols );
1112
                }
1113
1114
                do_action( 'wpinv_display_before_total', $invoice, $cols );
1115
                ?>
1116
                <tr class="table-active row-total">
1117
                    <td class="rate" colspan="<?php echo ( $cols - 1 ); ?>"><?php echo apply_filters( 'wpinv_print_cart_total_label', '<strong>' . __( 'Total', 'invoicing' ) . ':</strong>', $invoice ); ?></td>
1118
                    <td class="total"><strong><?php _e( wpinv_payment_total( $invoice_id, true ) ) ?></strong></td>
1119
                </tr>
1120
                <?php
1121
                do_action( 'wpinv_display_after_total', $invoice, $cols );
1122
1123
                do_action( 'wpinv_display_line_end', $invoice, $cols );
1124
            }
1125
        ?>
1126
        </tbody>
1127
    </table>
1128
    <?php
1129
    echo ob_get_clean();
1130
}
1131
1132
function wpinv_display_invoice_totals( $invoice_id = 0 ) {
1133
    $use_taxes = wpinv_use_taxes();
1134
1135
    do_action( 'wpinv_before_display_totals_table', $invoice_id ); 
1136
    ?>
1137
    <table class="table table-sm table-bordered table-responsive">
1138
        <tbody>
1139
            <?php do_action( 'wpinv_before_display_totals' ); ?>
1140
            <tr class="row-sub-total">
1141
                <td class="rate"><strong><?php _e( 'Sub Total', 'invoicing' ); ?></strong></td>
1142
                <td class="total"><strong><?php _e( wpinv_subtotal( $invoice_id, true ) ) ?></strong></td>
1143
            </tr>
1144
            <?php do_action( 'wpinv_after_display_totals' ); ?>
1145
            <?php if ( wpinv_discount( $invoice_id, false ) > 0 ) { ?>
1146
                <tr class="row-discount">
1147
                    <td class="rate"><?php wpinv_get_discount_label( wpinv_discount_code( $invoice_id ) ); ?></td>
1148
                    <td class="total"><?php echo wpinv_discount( $invoice_id, true, true ); ?></td>
1149
                </tr>
1150
            <?php do_action( 'wpinv_after_display_discount' ); ?>
1151
            <?php } ?>
1152
            <?php if ( $use_taxes ) { ?>
1153
            <tr class="row-tax">
1154
                <td class="rate"><?php _e( 'Tax', 'invoicing' ); ?></td>
1155
                <td class="total"><?php _e( wpinv_tax( $invoice_id, true ) ) ?></td>
1156
            </tr>
1157
            <?php do_action( 'wpinv_after_display_tax' ); ?>
1158
            <?php } ?>
1159
            <?php if ( $fees = wpinv_get_fees( $invoice_id ) ) { ?>
1160
                <?php foreach ( $fees as $fee ) { ?>
1161
                    <tr class="row-fee">
1162
                        <td class="rate"><?php echo $fee['label']; ?></td>
1163
                        <td class="total"><?php echo $fee['amount_display']; ?></td>
1164
                    </tr>
1165
                <?php } ?>
1166
            <?php } ?>
1167
            <tr class="table-active row-total">
1168
                <td class="rate"><strong><?php _e( 'Total', 'invoicing' ) ?></strong></td>
1169
                <td class="total"><strong><?php _e( wpinv_payment_total( $invoice_id, true ) ) ?></strong></td>
1170
            </tr>
1171
            <?php do_action( 'wpinv_after_totals' ); ?>
1172
        </tbody>
1173
1174
    </table>
1175
1176
    <?php do_action( 'wpinv_after_totals_table' );
1177
}
1178
1179
function wpinv_display_payments_info( $invoice_id = 0, $echo = true ) {
1180
    $invoice = wpinv_get_invoice( $invoice_id );
1181
1182
    ob_start();
1183
    do_action( 'wpinv_before_display_payments_info', $invoice_id );
1184
    if ( ( $gateway_title = $invoice->get_gateway_title() ) || $invoice->is_paid() || $invoice->is_refunded() ) {
1185
        ?>
1186
        <div class="wpi-payment-info">
1187
            <p class="wpi-payment-gateway"><?php echo wp_sprintf( __( 'Payment via %s', 'invoicing' ), $gateway_title ? $gateway_title : __( 'Manually', 'invoicing' ) ); ?></p>
1188
            <?php if ( $gateway_title ) { ?>
1189
            <p class="wpi-payment-transid"><?php echo wp_sprintf( __( 'Transaction ID: %s', 'invoicing' ), $invoice->get_transaction_id() ); ?></p>
1190
            <?php } ?>
1191
        </div>
1192
        <?php
1193
    }
1194
    do_action( 'wpinv_after_display_payments_info', $invoice_id );
1195
    $outout = ob_get_clean();
1196
1197
    if ( $echo ) {
1198
        echo $outout;
1199
    } else {
1200
        return $outout;
1201
    }
1202
}
1203
1204
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...
1205
    wp_register_style( 'wpinv-single-style', WPINV_PLUGIN_URL . 'assets/css/invoice.css', array(), WPINV_VERSION );
1206
1207
    wp_print_styles( 'open-sans' );
1208
    wp_print_styles( 'wpinv-single-style' );
1209
1210
    $custom_css = wpinv_get_option('template_custom_css');
1211
    if(isset($custom_css) && !empty($custom_css)){
1212
        $custom_css     = wp_kses( $custom_css, array( '\'', '\"' ) );
1213
        $custom_css     = str_replace( '&gt;', '>', $custom_css );
1214
        echo '<style type="text/css">';
1215
        echo $custom_css;
1216
        echo '</style>';
1217
    }
1218
}
1219
add_action( 'wpinv_invoice_print_head', 'wpinv_display_style' );
1220
add_action( 'wpinv_invalid_invoice_head', 'wpinv_display_style' );
1221
1222
function wpinv_checkout_billing_details() {
1223
    $invoice_id = (int)wpinv_get_invoice_cart_id();
1224
    if (empty($invoice_id)) {
1225
        wpinv_error_log( 'Invoice id not found', 'ERROR', __FILE__, __LINE__ );
1226
        return null;
1227
    }
1228
1229
    $invoice = wpinv_get_invoice_cart( $invoice_id );
1230
    if (empty($invoice)) {
1231
        wpinv_error_log( 'Invoice not found', 'ERROR', __FILE__, __LINE__ );
1232
        return null;
1233
    }
1234
    $user_id        = $invoice->get_user_id();
1235
    $user_info      = $invoice->get_user_info();
1236
    $address_info   = wpinv_get_user_address( $user_id );
1237
1238 View Code Duplication
    if ( empty( $user_info['first_name'] ) && !empty( $user_info['first_name'] ) ) {
1239
        $user_info['first_name'] = $user_info['first_name'];
1240
        $user_info['last_name'] = $user_info['last_name'];
1241
    }
1242
1243
    if ( ( ( empty( $user_info['country'] ) && !empty( $address_info['country'] ) ) || ( empty( $user_info['state'] ) && !empty( $address_info['state'] ) && $user_info['country'] == $address_info['country'] ) ) ) {
1244
        $user_info['country']   = $address_info['country'];
1245
        $user_info['state']     = $address_info['state'];
1246
        $user_info['city']      = $address_info['city'];
1247
        $user_info['zip']       = $address_info['zip'];
1248
    }
1249
1250
    $address_fields = array(
1251
        'user_id',
1252
        'company',
1253
        'vat_number',
1254
        'email',
1255
        'phone',
1256
        'address'
1257
    );
1258
1259
    foreach ( $address_fields as $field ) {
1260
        if ( empty( $user_info[$field] ) ) {
1261
            $user_info[$field] = $address_info[$field];
1262
        }
1263
    }
1264
1265
    return apply_filters( 'wpinv_checkout_billing_details', $user_info, $invoice );
1266
}
1267
1268
function wpinv_admin_get_line_items($invoice = array()) {
1269
    $item_quantities    = wpinv_item_quantities_enabled();
1270
    $use_taxes          = wpinv_use_taxes();
1271
1272
    if ( empty( $invoice ) ) {
1273
        return NULL;
1274
    }
1275
1276
    $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...
1277
    if ( empty( $cart_items ) ) {
1278
        return NULL;
1279
    }
1280
    ob_start();
1281
1282
    do_action( 'wpinv_admin_before_line_items', $cart_items, $invoice );
1283
1284
    $count = 0;
1285
    foreach ( $cart_items as $key => $cart_item ) {
1286
        $item_id    = $cart_item['id'];
1287
        $wpi_item   = $item_id > 0 ? new WPInv_Item( $item_id ) : NULL;
1288
1289
        if (empty($wpi_item)) {
1290
            continue;
1291
        }
1292
1293
        $item_price     = wpinv_price( wpinv_format_amount( $cart_item['item_price'] ), $invoice->get_currency() );
0 ignored issues
show
Bug introduced by
The method get_currency 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...
1294
        $quantity       = !empty( $cart_item['quantity'] ) && $cart_item['quantity'] > 0 ? $cart_item['quantity'] : 1;
1295
        $item_subtotal  = wpinv_price( wpinv_format_amount( $cart_item['subtotal'] ), $invoice->get_currency() );
0 ignored issues
show
Bug introduced by
The method get_currency 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...
1296
        $can_remove     = true;
1297
1298
        $summary = apply_filters( 'wpinv_admin_invoice_line_item_summary', '', $cart_item, $wpi_item, $invoice );
1299
1300
        $item_tax       = '';
1301
        $tax_rate       = '';
1302
        if ( $cart_item['tax'] > 0 && $cart_item['subtotal'] > 0 ) {
1303
            $item_tax = wpinv_price( wpinv_format_amount( $cart_item['tax'] ), $invoice->get_currency() );
0 ignored issues
show
Bug introduced by
The method get_currency 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...
1304
            $tax_rate = !empty( $cart_item['vat_rate'] ) ? $cart_item['vat_rate'] : ( $cart_item['tax'] / $cart_item['subtotal'] ) * 100;
1305
            $tax_rate = $tax_rate > 0 ? (float)wpinv_round_amount( $tax_rate, 4 ) : '';
1306
            $tax_rate = $tax_rate != '' ? ' <span class="tax-rate">(' . $tax_rate . '%)</span>' : '';
1307
        }
1308
        $line_item_tax = $item_tax . $tax_rate;
1309
1310
        if ( $line_item_tax === '' ) {
1311
            $line_item_tax = 0; // Zero tax
1312
        }
1313
1314
        $line_item = '<tr class="item item-' . ( ($count % 2 == 0) ? 'even' : 'odd' ) . '" data-item-id="' . $item_id . '">';
1315
            $line_item .= '<td class="id">' . $item_id . '</td>';
1316
            $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 );
1317
            if ( $summary !== '' ) {
1318
                $line_item .= '<span class="meta">' . wpautop( wp_kses_post( $summary ) ) . '</span>';
1319
            }
1320
            $line_item .= '</td>';
1321
            $line_item .= '<td class="price">' . $item_price . '</td>';
1322
            
1323
            if ( $item_quantities ) {
1324
                if ( count( $cart_items ) == 1 && $quantity <= 1 ) {
1325
                    $can_remove = false;
1326
                }
1327
                $line_item .= '<td class="qty" data-quantity="' . $quantity . '">&nbsp;&times;&nbsp;' . $quantity . '</td>';
1328
            } else {
1329
                if ( count( $cart_items ) == 1 ) {
1330
                    $can_remove = false;
1331
                }
1332
            }
1333
            $line_item .= '<td class="total">' . $item_subtotal . '</td>';
1334
            
1335
            if ( $use_taxes ) {
1336
                $line_item .= '<td class="tax">' . $line_item_tax . '</td>';
1337
            }
1338
            $line_item .= '<td class="action">';
1339
            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...
1340
                $line_item .= '<i class="fa fa-remove wpinv-item-remove"></i>';
1341
            }
1342
            $line_item .= '</td>';
1343
        $line_item .= '</tr>';
1344
1345
        echo apply_filters( 'wpinv_admin_line_item', $line_item, $cart_item, $invoice );
1346
1347
        $count++;
1348
    } 
1349
1350
    do_action( 'wpinv_admin_after_line_items', $cart_items, $invoice );
1351
1352
    return ob_get_clean();
1353
}
1354
1355
function wpinv_checkout_form() {
1356
    global $wpi_checkout_id;
1357
1358
    // Set current invoice id.
1359
    $wpi_checkout_id = wpinv_get_invoice_cart_id();
1360
1361
    //Maybe update the prices
1362
    if(! empty( $_GET['wpi_dynamic_item'] ) && ! empty( $_GET['wpi_dynamic_price'] ) ) {
1363
1364
        //If the invoice exists, update it with new pricing details
1365
        if (! empty( $wpi_checkout_id ) ) {
1366
1367
            $_invoice       = wpinv_get_invoice_cart();
1368
            $_cart_details  = $_invoice->get_cart_details();
1369
            $_dynamic_item  = sanitize_text_field( $_GET['wpi_dynamic_item'] );
1370
1371
            //First, fetch the item
1372
            $item    = new WPInv_Item( $_dynamic_item );
1373
    
1374
            //Next, ensure it supports dynamic pricing...
1375
            if( $item->supports_dynamic_pricing() && $item->get_is_dynamic_pricing() ) {
1376
                
1377
                //... and that the new price is not lower than the minimum price
1378
                $_dynamic_price = (float) wpinv_sanitize_amount( sanitize_text_field( $_GET['wpi_dynamic_price'] ) );
1379
                if( $_dynamic_price < $item->get_minimum_price() ) {
1380
                    $_dynamic_price = $item->get_minimum_price();
1381
                }
1382
1383
                //Finally, update our invoice with the new price
1384
                if ( !empty( $_cart_details ) ) {
1385
1386
                    foreach ( $_cart_details as $key => $item ) {
1387
                        if ( !empty( $item['id'] ) && $_dynamic_item == $item['id'] ) {
1388
                            $_cart_details[$key]['custom_price'] = $_dynamic_price;
1389
                            $_cart_details[$key]['item_price']   = $_dynamic_price;
1390
                        }
1391
                    }
1392
1393
                    $_meta = $_invoice->get_meta();
1394
                    $_meta['cart_details'] = $_cart_details;
1395
                    $_invoice->set( 'payment_meta', $_meta );
1396
                    $_invoice->set( 'cart_details', $_cart_details );
1397
                    $_invoice->recalculate_totals();
1398
1399
                }
1400
1401
            }
1402
            
1403
        }
1404
1405
    }
1406
1407
    $form_action  = esc_url( wpinv_get_checkout_uri() );
1408
1409
    ob_start();
1410
        echo '<div id="wpinv_checkout_wrap">';
1411
1412
        if ( wpinv_get_cart_contents() || wpinv_cart_has_fees() ) {
1413
            ?>
1414
            <div id="wpinv_checkout_form_wrap" class="wpinv_clearfix table-responsive">
1415
                <?php do_action( 'wpinv_before_checkout_form' ); ?>
1416
                <form id="wpinv_checkout_form" class="wpi-form" action="<?php echo $form_action; ?>" method="POST">
1417
                    <?php
1418
                    do_action( 'wpinv_checkout_form_top' );
1419
                    do_action( 'wpinv_checkout_billing_info' );
1420
                    do_action( 'wpinv_checkout_cart' );
1421
                    do_action( 'wpinv_payment_mode_select'  );
1422
                    do_action( 'wpinv_checkout_form_bottom' )
1423
                    ?>
1424
                </form>
1425
                <?php do_action( 'wpinv_after_purchase_form' ); ?>
1426
            </div><!--end #wpinv_checkout_form_wrap-->
1427
        <?php
1428
        } else {
1429
            do_action( 'wpinv_cart_empty' );
1430
        }
1431
        echo '</div><!--end #wpinv_checkout_wrap-->';
1432
    return ob_get_clean();
1433
}
1434
1435
function wpinv_checkout_cart( $cart_details = array(), $echo = true ) {
1436
    global $ajax_cart_details;
1437
    $ajax_cart_details = $cart_details;
1438
    /*
1439
    // Check if the Update cart button should be shown
1440
    if( wpinv_item_quantities_enabled() ) {
1441
        add_action( 'wpinv_cart_footer_buttons', 'wpinv_update_cart_button' );
1442
    }
1443
    
1444
    // Check if the Save Cart button should be shown
1445
    if( !wpinv_is_cart_saving_disabled() ) {
1446
        add_action( 'wpinv_cart_footer_buttons', 'wpinv_save_cart_button' );
1447
    }
1448
    */
1449
    ob_start();
1450
    do_action( 'wpinv_before_checkout_cart' );
1451
    echo '<div id="wpinv_checkout_cart_form" method="post">';
1452
        echo '<div id="wpinv_checkout_cart_wrap">';
1453
            wpinv_get_template_part( 'wpinv-checkout-cart' );
1454
        echo '</div>';
1455
    echo '</div>';
1456
    do_action( 'wpinv_after_checkout_cart' );
1457
    $content = ob_get_clean();
1458
    
1459
    if ( $echo ) {
1460
        echo $content;
1461
    } else {
1462
        return $content;
1463
    }
1464
}
1465
add_action( 'wpinv_checkout_cart', 'wpinv_checkout_cart', 10 );
1466
1467
function wpinv_empty_cart_message() {
1468
	return apply_filters( 'wpinv_empty_cart_message', '<span class="wpinv_empty_cart">' . __( 'Your cart is empty.', 'invoicing' ) . '</span>' );
1469
}
1470
1471
/**
1472
 * Echoes the Empty Cart Message
1473
 *
1474
 * @since 1.0
1475
 * @return void
1476
 */
1477
function wpinv_empty_checkout_cart() {
1478
	echo wpinv_empty_cart_message();
1479
}
1480
add_action( 'wpinv_cart_empty', 'wpinv_empty_checkout_cart' );
1481
1482
function wpinv_save_cart_button() {
1483
    if ( wpinv_is_cart_saving_disabled() )
1484
        return;
1485
?>
1486
    <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>
1487
<?php
1488
}
1489
1490
function wpinv_update_cart_button() {
1491
    if ( !wpinv_item_quantities_enabled() )
1492
        return;
1493
?>
1494
    <input type="submit" name="wpinv_update_cart_submit" class="wpinv-submit wpinv-no-js button" value="<?php _e( 'Update Cart', 'invoicing' ); ?>"/>
1495
    <input type="hidden" name="wpi_action" value="update_cart"/>
1496
<?php
1497
}
1498
1499
function wpinv_checkout_cart_columns() {
1500
    $default = 3;
1501
    if ( wpinv_item_quantities_enabled() ) {
1502
        $default++;
1503
    }
1504
    
1505
    if ( wpinv_use_taxes() ) {
1506
        $default++;
1507
    }
1508
1509
    return apply_filters( 'wpinv_checkout_cart_columns', $default );
1510
}
1511
1512
function wpinv_display_cart_messages() {
1513
    global $wpi_session;
1514
1515
    $messages = $wpi_session->get( 'wpinv_cart_messages' );
1516
1517
    if ( $messages ) {
1518
        foreach ( $messages as $message_id => $message ) {
1519
            // Try and detect what type of message this is
1520
            if ( strpos( strtolower( $message ), 'error' ) ) {
1521
                $type = 'error';
1522
            } elseif ( strpos( strtolower( $message ), 'success' ) ) {
1523
                $type = 'success';
1524
            } else {
1525
                $type = 'info';
1526
            }
1527
1528
            $classes = apply_filters( 'wpinv_' . $type . '_class', array( 'wpinv_errors', 'wpinv-alert', 'wpinv-alert-' . $type ) );
1529
1530
            echo '<div class="' . implode( ' ', $classes ) . '">';
1531
                // Loop message codes and display messages
1532
                    echo '<p class="wpinv_error" id="wpinv_msg_' . $message_id . '">' . $message . '</p>';
1533
            echo '</div>';
1534
        }
1535
1536
        // Remove all of the cart saving messages
1537
        $wpi_session->set( 'wpinv_cart_messages', null );
1538
    }
1539
}
1540
add_action( 'wpinv_before_checkout_cart', 'wpinv_display_cart_messages' );
1541
1542
function wpinv_discount_field() {
1543
    if ( isset( $_GET['wpi-gateway'] ) && wpinv_is_ajax_disabled() ) {
1544
        return; // Only show before a payment method has been selected if ajax is disabled
1545
    }
1546
1547
    if ( !wpinv_is_checkout() ) {
1548
        return;
1549
    }
1550
1551
    if ( wpinv_has_active_discounts() && wpinv_get_cart_total() ) {
1552
    ?>
1553
    <div id="wpinv-discount-field" class="panel panel-default">
1554
        <div class="panel-body">
1555
            <p>
1556
                <label class="wpinv-label" for="wpinv_discount_code"><strong><?php _e( 'Discount', 'invoicing' ); ?></strong></label>
1557
                <span class="wpinv-description"><?php _e( 'Enter a discount code if you have one.', 'invoicing' ); ?></span>
1558
            </p>
1559
            <div class="form-group row">
1560
                <div class="col-sm-4">
1561
                    <input class="wpinv-input form-control" type="text" id="wpinv_discount_code" name="wpinv_discount_code" placeholder="<?php _e( 'Enter discount code', 'invoicing' ); ?>"/>
1562
                </div>
1563
                <div class="col-sm-3">
1564
                    <button id="wpi-apply-discount" type="button" class="btn btn-success btn-sm"><?php _e( 'Apply Discount', 'invoicing' ); ?></button>
1565
                </div>
1566
                <div style="clear:both"></div>
1567
                <div class="col-sm-12 wpinv-discount-msg">
1568
                    <div class="alert alert-success"><i class="fa fa-check-circle"></i><span class="wpi-msg"></span></div>
1569
                    <div class="alert alert-error"><i class="fa fa-warning"></i><span class="wpi-msg"></span></div>
1570
                </div>
1571
            </div>
1572
        </div>
1573
    </div>
1574
<?php
1575
    }
1576
}
1577
add_action( 'wpinv_after_checkout_cart', 'wpinv_discount_field', -10 );
1578
1579
function wpinv_agree_to_terms_js() {
1580
    if ( wpinv_get_option( 'show_agree_to_terms', false ) ) {
1581
?>
1582
<script type="text/javascript">
1583
    jQuery(document).ready(function($){
1584
        $( document.body ).on('click', '.wpinv_terms_links', function(e) {
1585
            //e.preventDefault();
1586
            $('#wpinv_terms').slideToggle();
1587
            $('.wpinv_terms_links').toggle();
1588
            return false;
1589
        });
1590
    });
1591
</script>
1592
<?php
1593
    }
1594
}
1595
add_action( 'wpinv_checkout_form_top', 'wpinv_agree_to_terms_js' );
1596
1597
function wpinv_payment_mode_select() {
1598
    $gateways = wpinv_get_enabled_payment_gateways( true );
1599
    $gateways = apply_filters( 'wpinv_payment_gateways_on_cart', $gateways );
1600
    $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...
1601
    $invoice = wpinv_get_invoice( 0, true );
1602
1603
    do_action('wpinv_payment_mode_top');
1604
    $invoice_id = (int)$invoice->ID;
1605
    $chosen_gateway = wpinv_get_chosen_gateway( $invoice_id );
1606
    ?>
1607
    <div id="wpinv_payment_mode_select" data-gateway="<?php echo $chosen_gateway; ?>" <?php echo ( $invoice->is_free() ? 'style="display:none;" data-free="1"' : '' ); ?>>
1608
            <?php do_action( 'wpinv_payment_mode_before_gateways_wrap' ); ?>
1609
            <div id="wpinv-payment-mode-wrap" class="panel panel-default">
1610
                <div class="panel-heading"><h3 class="panel-title"><?php _e( 'Select Payment Method', 'invoicing' ); ?></h3></div>
1611
                <div class="panel-body list-group wpi-payment_methods">
1612
                    <?php
1613
                    do_action( 'wpinv_payment_mode_before_gateways' );
1614
1615
                    if ( !empty( $gateways ) ) {
1616
                        foreach ( $gateways as $gateway_id => $gateway ) {
1617
                            $checked       = checked( $gateway_id, $chosen_gateway, false );
1618
                            $button_label  = wpinv_get_gateway_button_label( $gateway_id );
1619
                            $gateway_label = wpinv_get_gateway_checkout_label( $gateway_id );
1620
                            $description   = wpinv_get_gateway_description( $gateway_id );
1621
                            ?>
1622
                            <div class="list-group-item">
1623
                                <div class="radio">
1624
                                    <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_label ); ?></label>
1625
                                </div>
1626
                                <div style="display:none;" class="payment_box wpi_gateway_<?php echo esc_attr( $gateway_id );?>" role="alert">
1627
                                    <?php if ( !empty( $description ) ) { ?>
1628
                                        <div class="wpi-gateway-desc alert alert-info"><?php _e( $description, 'invoicing' ); ?></div>
1629
                                    <?php } ?>
1630
                                    <?php do_action( 'wpinv_' . $gateway_id . '_cc_form', $invoice_id ) ;?>
1631
                                </div>
1632
                            </div>
1633
                            <?php
1634
                        }
1635
                    } else {
1636
                        echo '<div class="alert alert-warning">'. __( 'No payment gateway active', 'invoicing' ) .'</div>';
1637
                    }
1638
1639
                    do_action( 'wpinv_payment_mode_after_gateways' );
1640
                    ?>
1641
                </div>
1642
            </div>
1643
            <?php do_action( 'wpinv_payment_mode_after_gateways_wrap' ); ?>
1644
    </div>
1645
    <?php
1646
    do_action('wpinv_payment_mode_bottom');
1647
}
1648
add_action( 'wpinv_payment_mode_select', 'wpinv_payment_mode_select' );
1649
1650
function wpinv_checkout_billing_info() {
1651
    if ( wpinv_is_checkout() ) {
1652
        $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...
1653
        $billing_details    = wpinv_checkout_billing_details();
1654
        $selected_country   = !empty( $billing_details['country'] ) ? $billing_details['country'] : wpinv_default_billing_country();
1655
        ?>
1656
        <div id="wpinv-fields" class="clearfix">
1657
            <div id="wpi-billing" class="wpi-billing clearfix panel panel-default">
1658
                <div class="panel-heading"><h3 class="panel-title"><?php _e( 'Billing Details', 'invoicing' );?></h3></div>
1659
                <div id="wpinv-fields-box" class="panel-body">
1660
                    <?php do_action( 'wpinv_checkout_billing_fields_first', $billing_details ); ?>
1661
                    <p class="wpi-cart-field wpi-col2 wpi-colf">
1662
                        <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>
1663
                        <?php
1664
                        echo wpinv_html_text( array(
1665
                                'id'            => 'wpinv_first_name',
1666
                                'name'          => 'wpinv_first_name',
1667
                                'value'         => $billing_details['first_name'],
1668
                                'class'         => 'wpi-input form-control',
1669
                                'placeholder'   => __( 'First name', 'invoicing' ),
1670
                                'required'      => (bool)wpinv_get_option( 'fname_mandatory' ),
1671
                            ) );
1672
                        ?>
1673
                    </p>
1674
                    <p class="wpi-cart-field wpi-col2 wpi-coll">
1675
                        <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>
1676
                        <?php
1677
                        echo wpinv_html_text( array(
1678
                                'id'            => 'wpinv_last_name',
1679
                                'name'          => 'wpinv_last_name',
1680
                                'value'         => $billing_details['last_name'],
1681
                                'class'         => 'wpi-input form-control',
1682
                                'placeholder'   => __( 'Last name', 'invoicing' ),
1683
                                'required'      => (bool)wpinv_get_option( 'lname_mandatory' ),
1684
                            ) );
1685
                        ?>
1686
                    </p>
1687
                    <p class="wpi-cart-field wpi-col2 wpi-colf">
1688
                        <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>
1689
                        <?php
1690
                        echo wpinv_html_text( array(
1691
                                'id'            => 'wpinv_address',
1692
                                'name'          => 'wpinv_address',
1693
                                'value'         => $billing_details['address'],
1694
                                'class'         => 'wpi-input form-control',
1695
                                'placeholder'   => __( 'Address', 'invoicing' ),
1696
                                'required'      => (bool)wpinv_get_option( 'address_mandatory' ),
1697
                            ) );
1698
                        ?>
1699
                    </p>
1700
                    <p class="wpi-cart-field wpi-col2 wpi-coll">
1701
                        <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>
1702
                        <?php
1703
                        echo wpinv_html_text( array(
1704
                                'id'            => 'wpinv_city',
1705
                                'name'          => 'wpinv_city',
1706
                                'value'         => $billing_details['city'],
1707
                                'class'         => 'wpi-input form-control',
1708
                                'placeholder'   => __( 'City', 'invoicing' ),
1709
                                'required'      => (bool)wpinv_get_option( 'city_mandatory' ),
1710
                            ) );
1711
                        ?>
1712
                    </p>
1713
                    <p id="wpinv_country_box" class="wpi-cart-field wpi-col2 wpi-colf">
1714
                        <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>
1715
                        <?php echo wpinv_html_select( array(
1716
                            'options'          => wpinv_get_country_list(),
1717
                            'name'             => 'wpinv_country',
1718
                            'id'               => 'wpinv_country',
1719
                            'selected'         => $selected_country,
1720
                            'show_option_all'  => false,
1721
                            'show_option_none' => false,
1722
                            'class'            => 'wpi-input form-control wpi_select2',
1723
                            'placeholder'      => __( 'Choose a country', 'invoicing' ),
1724
                            'required'         => (bool)wpinv_get_option( 'country_mandatory' ),
1725
                        ) ); ?>
1726
                    </p>
1727
                    <p id="wpinv_state_box" class="wpi-cart-field wpi-col2 wpi-coll">
1728
                        <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>
1729
                        <?php
1730
                        $states = wpinv_get_country_states( $selected_country );
1731
                        if( !empty( $states ) ) {
1732
                            echo wpinv_html_select( array(
1733
                                'options'          => $states,
1734
                                'name'             => 'wpinv_state',
1735
                                'id'               => 'wpinv_state',
1736
                                'selected'         => $billing_details['state'],
1737
                                'show_option_all'  => false,
1738
                                'show_option_none' => false,
1739
                                'class'            => 'wpi-input form-control wpi_select2',
1740
                                'placeholder'      => __( 'Choose a state', 'invoicing' ),
1741
                                'required'         => (bool)wpinv_get_option( 'state_mandatory' ),
1742
                            ) );
1743
                        } else {
1744
                            echo wpinv_html_text( array(
1745
                                'name'          => 'wpinv_state',
1746
                                'value'         => $billing_details['state'],
1747
                                'id'            => 'wpinv_state',
1748
                                'class'         => 'wpi-input form-control',
1749
                                'placeholder'   => __( 'State / Province', 'invoicing' ),
1750
                                'required'      => (bool)wpinv_get_option( 'state_mandatory' ),
1751
                            ) );
1752
                        }
1753
                        ?>
1754
                    </p>
1755
                    <p class="wpi-cart-field wpi-col2 wpi-colf">
1756
                        <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>
1757
                        <?php
1758
                        echo wpinv_html_text( array(
1759
                                'name'          => 'wpinv_zip',
1760
                                'value'         => $billing_details['zip'],
1761
                                'id'            => 'wpinv_zip',
1762
                                'class'         => 'wpi-input form-control',
1763
                                'placeholder'   => __( 'ZIP / Postcode', 'invoicing' ),
1764
                                'required'      => (bool)wpinv_get_option( 'zip_mandatory' ),
1765
                            ) );
1766
                        ?>
1767
                    </p>
1768
                    <p class="wpi-cart-field wpi-col2 wpi-coll">
1769
                        <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>
1770
                        <?php
1771
                        echo wpinv_html_text( array(
1772
                                'id'            => 'wpinv_phone',
1773
                                'name'          => 'wpinv_phone',
1774
                                'value'         => $billing_details['phone'],
1775
                                'class'         => 'wpi-input form-control',
1776
                                'placeholder'   => __( 'Phone', 'invoicing' ),
1777
                                'required'      => (bool)wpinv_get_option( 'phone_mandatory' ),
1778
                            ) );
1779
                        ?>
1780
                    </p>
1781
                    <?php do_action( 'wpinv_checkout_billing_fields_last', $billing_details ); ?>
1782
                    <div class="clearfix"></div>
1783
                </div>
1784
            </div>
1785
            <?php do_action( 'wpinv_after_billing_fields', $billing_details ); ?>
1786
        </div>
1787
        <?php
1788
    }
1789
}
1790
add_action( 'wpinv_checkout_billing_info', 'wpinv_checkout_billing_info' );
1791
1792
function wpinv_checkout_hidden_fields() {
1793
?>
1794
    <?php if ( is_user_logged_in() ) { ?>
1795
    <input type="hidden" name="wpinv_user_id" value="<?php echo get_current_user_id(); ?>"/>
1796
    <?php } ?>
1797
    <input type="hidden" name="wpi_action" value="payment" />
1798
<?php
1799
}
1800
1801
function wpinv_checkout_button_purchase() {
1802
    ob_start();
1803
?>
1804
    <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' ) ?>"/>
1805
<?php
1806
    return apply_filters( 'wpinv_checkout_button_purchase', ob_get_clean() );
1807
}
1808
1809
function wpinv_checkout_total() {
1810
    global $cart_total;
1811
?>
1812
<div id="wpinv_checkout_total" class="panel panel-info">
1813
    <div class="panel-body">
1814
    <?php
1815
    do_action( 'wpinv_purchase_form_before_checkout_total' );
1816
    ?>
1817
    <strong><?php _e( 'Invoice Total:', 'invoicing' ) ?></strong> <span class="wpinv-chdeckout-total"><?php echo $cart_total;?></span>
1818
    <?php
1819
    do_action( 'wpinv_purchase_form_after_checkout_total' );
1820
    ?>
1821
    </div>
1822
</div>
1823
<?php
1824
}
1825
add_action( 'wpinv_checkout_form_bottom', 'wpinv_checkout_total', 9998 );
1826
1827
function wpinv_checkout_accept_tandc() {
1828
    $page = wpinv_get_option( 'tandc_page' );
1829
    ?>
1830
    <div id="wpinv_checkout_tandc" class="panel panel-success">
1831
        <div class="panel-body">
1832
            <?php echo wpinv_get_policy_text(); ?>
1833
            <?php
1834
            if(isset($page) && (int)$page > 0 && apply_filters( 'wpinv_checkout_show_terms', true )){
1835
                $terms_link = esc_url( get_permalink( $page ) );
1836
                ?>
1837
                <label class="">
1838
                    <input type="checkbox" class="wpi-terms-checkbox" name="wpi_terms" id="wpi-terms" <?php checked( apply_filters( 'wpinv_terms_is_checked_default', isset( $_POST['wpi_terms'] ) ), true ); ?>> <span><?php printf( __( 'I&rsquo;ve read and accept the <a href="%s" target="_blank" class="wpi-terms-and-conditions-link">terms &amp; conditions</a>', 'invoicing' ), $terms_link ); ?></span> <span class="wpi-required">*</span>
1839
                </label>
1840
            <?php } ?>
1841
        </div>
1842
    </div>
1843
    <?php
1844
}
1845
add_action( 'wpinv_checkout_form_bottom', 'wpinv_checkout_accept_tandc', 9995 );
1846
1847
function wpinv_checkout_submit() {
1848
?>
1849
<div id="wpinv_purchase_submit" class="panel panel-success">
1850
    <div class="panel-body text-center">
1851
    <?php
1852
    do_action( 'wpinv_purchase_form_before_submit' );
1853
    wpinv_checkout_hidden_fields();
1854
    echo wpinv_checkout_button_purchase();
1855
    do_action( 'wpinv_purchase_form_after_submit' );
1856
    ?>
1857
    </div>
1858
</div>
1859
<?php
1860
}
1861
add_action( 'wpinv_checkout_form_bottom', 'wpinv_checkout_submit', 9999 );
1862
1863
function wpinv_receipt_billing_address( $invoice_id = 0 ) {
1864
    $invoice = wpinv_get_invoice( $invoice_id );
1865
1866
    if ( empty( $invoice ) ) {
1867
        return NULL;
1868
    }
1869
1870
    $billing_details = $invoice->get_user_info();
1871
    $address_row = '';
1872
    if ( $address = $billing_details['address'] ) {
1873
        $address_row .= wpautop( wp_kses_post( $address ) );
1874
    }
1875
1876
    $address_fields = array();
1877
    if ( !empty( $billing_details['city'] ) ) {
1878
        $address_fields[] = $billing_details['city'];
1879
    }
1880
1881
    $billing_country = !empty( $billing_details['country'] ) ? $billing_details['country'] : '';
1882
    if ( !empty( $billing_details['state'] ) ) {
1883
        $address_fields[] = wpinv_state_name( $billing_details['state'], $billing_country );
1884
    }
1885
1886
    if ( !empty( $billing_country ) ) {
1887
        $address_fields[] = wpinv_country_name( $billing_country );
1888
    }
1889
1890 View Code Duplication
    if ( !empty( $address_fields ) ) {
1891
        $address_fields = implode( ", ", $address_fields );
1892
1893
        if ( !empty( $billing_details['zip'] ) ) {
1894
            $address_fields .= ' ' . $billing_details['zip'];
1895
        }
1896
1897
        $address_row .= wpautop( wp_kses_post( $address_fields ) );
1898
    }
1899
    ob_start();
1900
    ?>
1901
    <table class="table table-bordered table-sm wpi-billing-details">
1902
        <tbody>
1903
            <tr class="wpi-receipt-name">
1904
                <th class="text-left"><?php _e( 'Name', 'invoicing' ); ?></th>
1905
                <td><?php echo esc_html( trim( $billing_details['first_name'] . ' ' . $billing_details['last_name'] ) ) ;?></td>
1906
            </tr>
1907
            <tr class="wpi-receipt-email">
1908
                <th class="text-left"><?php _e( 'Email', 'invoicing' ); ?></th>
1909
                <td><?php echo $billing_details['email'] ;?></td>
1910
            </tr>
1911 View Code Duplication
            <?php if ( $billing_details['company'] ) { ?>
1912
            <tr class="wpi-receipt-company">
1913
                <th class="text-left"><?php _e( 'Company', 'invoicing' ); ?></th>
1914
                <td><?php echo esc_html( $billing_details['company'] ) ;?></td>
1915
            </tr>
1916
            <?php } ?>
1917
            <tr class="wpi-receipt-address">
1918
                <th class="text-left"><?php _e( 'Address', 'invoicing' ); ?></th>
1919
                <td><?php echo $address_row ;?></td>
1920
            </tr>
1921 View Code Duplication
            <?php if ( $billing_details['phone'] ) { ?>
1922
            <tr class="wpi-receipt-phone">
1923
                <th class="text-left"><?php _e( 'Phone', 'invoicing' ); ?></th>
1924
                <td><?php echo esc_html( $billing_details['phone'] ) ;?></td>
1925
            </tr>
1926
            <?php } ?>
1927
        </tbody>
1928
    </table>
1929
    <?php
1930
    $output = ob_get_clean();
1931
    
1932
    $output = apply_filters( 'wpinv_receipt_billing_address', $output, $invoice_id );
1933
1934
    echo $output;
1935
}
1936
1937
function wpinv_filter_success_page_content( $content ) {
1938
    if ( isset( $_GET['payment-confirm'] ) && wpinv_is_success_page() ) {
1939
        if ( has_filter( 'wpinv_payment_confirm_' . sanitize_text_field( $_GET['payment-confirm'] ) ) ) {
1940
            $content = apply_filters( 'wpinv_payment_confirm_' . sanitize_text_field( $_GET['payment-confirm'] ), $content );
1941
        }
1942
    }
1943
1944
    return $content;
1945
}
1946
add_filter( 'the_content', 'wpinv_filter_success_page_content', 99999 );
1947
1948
function wpinv_receipt_actions( $invoice ) {
1949
    if ( !empty( $invoice ) ) {
1950
        $actions = array();
1951
1952
        if ( wpinv_user_can_view_invoice( $invoice->ID ) ) {
1953
            $actions['print']   = array(
1954
                'url'  => $invoice->get_view_url( true ),
1955
                'name' => __( 'Print Invoice', 'invoicing' ),
1956
                'class' => 'btn-primary',
1957
            );
1958
        }
1959
1960
        if ( is_user_logged_in() ) {
1961
            $actions['history'] = array(
1962
                'url'  => wpinv_get_history_page_uri(),
1963
                'name' => __( 'Invoice History', 'invoicing' ),
1964
                'class' => 'btn-warning',
1965
            );
1966
        }
1967
1968
        $actions = apply_filters( 'wpinv_invoice_receipt_actions', $actions, $invoice );
1969
1970
        if ( !empty( $actions ) ) {
1971
        ?>
1972
        <div class="wpinv-receipt-actions text-right">
1973
            <?php foreach ( $actions as $key => $action ) { $class = !empty($action['class']) ? sanitize_html_class( $action['class'] ) : ''; ?>
1974
            <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>
1975
            <?php } ?>
1976
        </div>
1977
        <?php
1978
        }
1979
    }
1980
}
1981
add_action( 'wpinv_receipt_start', 'wpinv_receipt_actions', -10, 1 );
1982
1983
function wpinv_invoice_link( $invoice_id ) {
1984
    $invoice = wpinv_get_invoice( $invoice_id );
1985
1986
    if ( empty( $invoice ) ) {
1987
        return NULL;
1988
    }
1989
1990
    $invoice_link = '<a href="' . esc_url( $invoice->get_view_url() ) . '">' . $invoice->get_number() . '</a>';
1991
1992
    return apply_filters( 'wpinv_get_invoice_link', $invoice_link, $invoice );
1993
}
1994
1995
function wpinv_invoice_subscription_details( $invoice ) {
1996
    if ( !empty( $invoice ) && $invoice->is_recurring() && ! wpinv_is_subscription_payment( $invoice ) ) {
1997
        $subscription = wpinv_get_subscription( $invoice, true );
1998
1999
        if ( empty( $subscription ) ) {
2000
            return;
2001
        }
2002
2003
        $frequency = WPInv_Subscriptions::wpinv_get_pretty_subscription_frequency($subscription->period, $subscription->frequency);
2004
        $billing = wpinv_price(wpinv_format_amount($subscription->recurring_amount), wpinv_get_invoice_currency_code($subscription->parent_payment_id)) . ' / ' . $frequency;
2005
        $initial = wpinv_price(wpinv_format_amount($subscription->initial_amount), wpinv_get_invoice_currency_code($subscription->parent_payment_id));
2006
2007
        $payments = $subscription->get_child_payments();
2008
        ?>
2009
        <div class="wpinv-subscriptions-details">
2010
            <h3 class="wpinv-subscriptions-t"><?php echo apply_filters( 'wpinv_subscription_details_title', __( 'Subscription Details', 'invoicing' ) ); ?></h3>
2011
            <table class="table">
2012
                <thead>
2013
                    <tr>
2014
                        <th><?php _e( 'Billing Cycle', 'invoicing' ) ;?></th>
2015
                        <th><?php _e( 'Start Date', 'invoicing' ) ;?></th>
2016
                        <th><?php _e( 'Expiration Date', 'invoicing' ) ;?></th>
2017
                        <th class="text-center"><?php _e( 'Times Billed', 'invoicing' ) ;?></th>
2018
                        <th class="text-center"><?php _e( 'Status', 'invoicing' ) ;?></th>
2019
                    </tr>
2020
                </thead>
2021
                <tbody>
2022
                    <tr>
2023
                        <td><?php printf(_x('%s then %s', 'Initial subscription amount then billing cycle and amount', 'invoicing'), $initial, $billing); ?></td>
2024
                        <td><?php echo date_i18n(get_option('date_format'), strtotime($subscription->created, current_time('timestamp'))); ?></td>
2025
                        <td><?php echo date_i18n(get_option('date_format'), strtotime($subscription->expiration, current_time('timestamp'))); ?></td>
2026
                        <td class="text-center"><?php echo $subscription->get_times_billed() . ' / ' . (($subscription->bill_times == 0) ? 'Until Cancelled' : $subscription->bill_times); ?></td>
2027
                        <td class="text-center wpi-sub-status"><?php echo $subscription->get_status_label(); ?></td>
2028
                    </tr>
2029
                </tbody>
2030
            </table>
2031
        </div>
2032
        <?php if ( !empty( $payments ) ) { ?>
2033
        <div class="wpinv-renewal-payments">
2034
            <h3 class="wpinv-renewals-t"><?php echo apply_filters( 'wpinv_renewal_payments_title', __( 'Renewal Payments', 'invoicing' ) ); ?></h3>
2035
            <table class="table">
2036
                <thead>
2037
                    <tr>
2038
                        <th>#</th>
2039
                        <th><?php _e( 'Invoice', 'invoicing' ) ;?></th>
2040
                        <th><?php _e( 'Date', 'invoicing' ) ;?></th>
2041
                        <th class="text-right"><?php _e( 'Amount', 'invoicing' ) ;?></th>
2042
                    </tr>
2043
                </thead>
2044
                <tbody>
2045
                    <?php
2046
                        $i = 1;
2047
                        foreach ( $payments as $payment ) {
2048
                            $invoice_id = $payment->ID;
2049
                    ?>
2050
                    <tr>
2051
                        <th scope="row"><?php echo $i;?></th>
2052
                        <td><?php echo wpinv_invoice_link( $invoice_id ) ;?></td>
2053
                        <td><?php echo wpinv_get_invoice_date( $invoice_id ); ?></td>
2054
                        <td class="text-right"><?php echo wpinv_payment_total( $invoice_id, true ); ?></td>
2055
                    </tr>
2056
                    <?php $i++; } ?>
2057
                </tbody>
2058
            </table>
2059
        </div>
2060
        <?php } ?>
2061
        <?php
2062
    }
2063
}
2064
2065
function wpinv_cart_total_label( $label, $invoice ) {
2066
    if ( empty( $invoice ) ) {
2067
        return $label;
2068
    }
2069
2070
    $prefix_label = '';
2071
    if ( $invoice->is_parent() && $item_id = $invoice->get_recurring() ) {
2072
        $prefix_label   = '<span class="label label-primary label-recurring">' . __( 'Recurring Payment', 'invoicing' ) . '</span> ' . wpinv_subscription_payment_desc( $invoice );
2073
    } else if ( $invoice->is_renewal() ) {
2074
        $prefix_label   = '<span class="label label-primary label-renewal">' . __( 'Renewal Payment', 'invoicing' ) . '</span> ';        
2075
    }
2076
2077
    if ( $prefix_label != '' ) {
2078
        $label  = '<span class="wpinv-cart-sub-desc">' . $prefix_label . '</span> ' . $label;
2079
    }
2080
2081
    return $label;
2082
}
2083
add_filter( 'wpinv_cart_total_label', 'wpinv_cart_total_label', 10, 2 );
2084
add_filter( 'wpinv_email_cart_total_label', 'wpinv_cart_total_label', 10, 2 );
2085
add_filter( 'wpinv_print_cart_total_label', 'wpinv_cart_total_label', 10, 2 );
2086
2087
add_action( 'wpinv_invoice_print_middle', 'wpinv_invoice_subscription_details', 10, 1 );
2088
2089
function wpinv_invoice_print_description( $invoice ) {
2090
    if ( empty( $invoice ) ) {
2091
        return NULL;
2092
    }
2093
    if ( $description = wpinv_get_invoice_description( $invoice->ID ) ) {
2094
        ?>
2095
        <div class="row wpinv-lower">
2096
            <div class="col-sm-12 wpinv-description">
2097
                <?php echo wpautop( $description ); ?>
2098
            </div>
2099
        </div>
2100
        <?php
2101
    }
2102
}
2103
add_action( 'wpinv_invoice_print_middle', 'wpinv_invoice_print_description', 10.1, 1 );
2104
2105
function wpinv_invoice_print_payment_info( $invoice ) {
2106
    if ( empty( $invoice ) ) {
2107
        return NULL;
2108
    }
2109
2110
    if ( $payments_info = wpinv_display_payments_info( $invoice->ID, false ) ) {
2111
        ?>
2112
        <div class="row wpinv-payments">
2113
            <div class="col-sm-12">
2114
                <?php echo $payments_info; ?>
2115
            </div>
2116
        </div>
2117
        <?php 
2118
    }
2119
}
2120
// add_action( 'wpinv_invoice_print_after_line_items', 'wpinv_invoice_print_payment_info', 10, 1 );
2121
2122
function wpinv_get_invoice_note_line_item( $note, $echo = true ) {
2123
    if ( empty( $note ) ) {
2124
        return NULL;
2125
    }
2126
2127
    if ( is_int( $note ) ) {
2128
        $note = get_comment( $note );
2129
    }
2130
2131
    if ( !( is_object( $note ) && is_a( $note, 'WP_Comment' ) ) ) {
2132
        return NULL;
2133
    }
2134
2135
    $note_classes   = array( 'note' );
2136
    $note_classes[] = get_comment_meta( $note->comment_ID, '_wpi_customer_note', true ) ? 'customer-note' : '';
2137
    $note_classes[] = $note->comment_author === 'System' ? 'system-note' : '';
2138
    $note_classes   = apply_filters( 'wpinv_invoice_note_class', array_filter( $note_classes ), $note );
2139
    $note_classes   = !empty( $note_classes ) ? implode( ' ', $note_classes ) : '';
2140
2141
    ob_start();
2142
    ?>
2143
    <li rel="<?php echo absint( $note->comment_ID ) ; ?>" class="<?php echo esc_attr( $note_classes ); ?>">
2144
        <div class="note_content">
2145
            <?php echo wpautop( wptexturize( wp_kses_post( $note->comment_content ) ) ); ?>
2146
        </div>
2147
        <p class="meta">
2148
            <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;
2149
            <?php if ( $note->comment_author !== 'System' || current_user_can( 'manage_options' ) ) { ?>
2150
                <a href="#" class="delete_note"><?php _e( 'Delete note', 'invoicing' ); ?></a>
2151
            <?php } ?>
2152
        </p>
2153
    </li>
2154
    <?php
2155
    $note_content = ob_get_clean();
2156
    $note_content = apply_filters( 'wpinv_get_invoice_note_line_item', $note_content, $note, $echo );
2157
2158
    if ( $echo ) {
2159
        echo $note_content;
2160
    } else {
2161
        return $note_content;
2162
    }
2163
}
2164
2165
function wpinv_invalid_invoice_content() {
2166
    global $post;
2167
2168
    $invoice = wpinv_get_invoice( $post->ID );
2169
2170
    $error = __( 'This invoice is only viewable by clicking on the invoice link that sent to you via email.', 'invoicing' );
2171
    if ( !empty( $invoice->ID ) && $invoice->has_status( array_keys( wpinv_get_invoice_statuses() ) ) ) {
2172
        if ( is_user_logged_in() ) {
2173 View Code Duplication
            if ( wpinv_require_login_to_checkout() ) {
2174
                if ( isset( $_GET['invoice_key'] ) && $_GET['invoice_key'] === $invoice->get_key() ) {
2175
                    $error = __( 'You are not allowed to view this invoice.', 'invoicing' );
2176
                }
2177
            }
2178 View Code Duplication
        } else {
2179
            if ( wpinv_require_login_to_checkout() ) {
2180
                if ( isset( $_GET['invoice_key'] ) && $_GET['invoice_key'] === $invoice->get_key() ) {
2181
                    $error = __( 'You must be logged in to view this invoice.', 'invoicing' );
2182
                }
2183
            }
2184
        }
2185
    } else {
2186
        $error = __( 'This invoice is deleted or does not exist.', 'invoicing' );
2187
    }
2188
    ?>
2189
    <div class="row wpinv-row-invalid">
2190
        <div class="col-md-6 col-md-offset-3 wpinv-message error">
2191
            <h3><?php _e( 'Access Denied', 'invoicing' ); ?></h3>
2192
            <p class="wpinv-msg-text"><?php echo $error; ?></p>
2193
        </div>
2194
    </div>
2195
    <?php
2196
}
2197
add_action( 'wpinv_invalid_invoice_content', 'wpinv_invalid_invoice_content' );
2198
2199
add_action( 'wpinv_checkout_billing_fields_last', 'wpinv_force_company_name_field');
2200
function wpinv_force_company_name_field(){
2201
    $invoice = wpinv_get_invoice_cart();
2202
    $user_id = wpinv_get_user_id( $invoice->ID );
2203
    $company = empty( $user_id ) ? "" : get_user_meta( $user_id, '_wpinv_company', true );
2204
    if ( 1 == wpinv_get_option( 'force_show_company' ) && !wpinv_use_taxes() ) {
2205
        ?>
2206
        <p class="wpi-cart-field wpi-col2 wpi-colf">
2207
            <label for="wpinv_company" class="wpi-label"><?php _e('Company Name', 'invoicing'); ?></label>
2208
            <?php
2209
            echo wpinv_html_text(array(
2210
                'id' => 'wpinv_company',
2211
                'name' => 'wpinv_company',
2212
                'value' => $company,
2213
                'class' => 'wpi-input form-control',
2214
                'placeholder' => __('Company name', 'invoicing'),
2215
            ));
2216
            ?>
2217
        </p>
2218
        <?php
2219
    }
2220
}
2221
2222
/**
2223
 * Function to get privacy policy text.
2224
 *
2225
 * @since 1.0.13
2226
 * @return string
2227
 */
2228
function wpinv_get_policy_text() {
2229
    $privacy_page_id = get_option( 'wp_page_for_privacy_policy', 0 );
2230
2231
    $text = wpinv_get_option('invoicing_privacy_checkout_message', sprintf( __( 'Your personal data will be used to process your invoice, payment and for other purposes described in our %s.', 'invoicing' ), '[wpinv_privacy_policy]' ));
0 ignored issues
show
Documentation introduced by
sprintf(__('Your persona...wpinv_privacy_policy]') is of type string, but the function expects a boolean.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2232
2233
    if(!$privacy_page_id){
2234
        $privacy_page_id = wpinv_get_option( 'privacy_page', 0 );
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2235
    }
2236
2237
    $privacy_link    = $privacy_page_id ? '<a href="' . esc_url( get_permalink( $privacy_page_id ) ) . '" class="wpinv-privacy-policy-link" target="_blank">' . __( 'privacy policy', 'invoicing' ) . '</a>' : __( 'privacy policy', 'invoicing' );
2238
2239
    $find_replace = array(
2240
        '[wpinv_privacy_policy]' => $privacy_link,
2241
    );
2242
2243
    $privacy_text = str_replace( array_keys( $find_replace ), array_values( $find_replace ), $text );
2244
2245
    return wp_kses_post(wpautop($privacy_text));
2246
}
2247
2248
2249
/**
2250
 * Allows the user to set their own price for an invoice item
2251
 */
2252
function wpinv_checkout_cart_item_name_your_price( $cart_item, $key ) {
0 ignored issues
show
Unused Code introduced by
The parameter $key 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...
2253
    
2254
    //Ensure we have an item id
2255
    if(! is_array( $cart_item ) || empty( $cart_item['id'] ) ) {
2256
        return;
2257
    }
2258
2259
    //Fetch the item
2260
    $item_id = $cart_item['id'];
2261
    $item    = new WPInv_Item( $item_id );
2262
    
2263
    if(! $item->supports_dynamic_pricing() || !$item->get_is_dynamic_pricing() ) {
2264
        return;
2265
    }
2266
2267
    //Fetch the dynamic pricing "strings"
2268
    $suggested_price_text = esc_html( wpinv_get_option( 'suggested_price_text', __( 'Suggested Price:', 'invoicing' ) ) );
2269
    $minimum_price_text   = esc_html( wpinv_get_option( 'minimum_price_text', __( 'Minimum Price:', 'invoicing' ) ) );
2270
    $name_your_price_text = esc_html( wpinv_get_option( 'name_your_price_text', __( 'Name Your Price', 'invoicing' ) ) );
2271
2272
    //Display a "name_your_price" button
2273
    echo " &mdash; <a href='#' class='wpinv-name-your-price-frontend small'>$name_your_price_text</a></div>";
2274
2275
    //Display a name_your_price form
2276
    echo '<div class="name-your-price-miniform">';
2277
    
2278
    //Maybe display the recommended price
2279
    if( $item->get_price() > 0 && !empty( $suggested_price_text ) ) {
2280
        $suggested_price = $item->get_the_price();
2281
        echo "<div>$suggested_price_text &mdash; $suggested_price</div>";
2282
    }
2283
2284
    //Display the update price form
2285
    $symbol         = wpinv_currency_symbol();
2286
    $position       = wpinv_currency_position();
2287
    $minimum        = esc_attr( $item->get_minimum_price() );
2288
    $price          = esc_attr( $cart_item['item_price'] );
2289
    $update         = esc_attr__( "Update", 'invoicing' );
2290
2291
    //Ensure it supports dynamic prici
2292
    if( $price < $minimum ) {
2293
        $price = $minimum;
2294
    }
2295
2296
    echo '<label>';
2297
    echo $position != 'right' ? $symbol . '&nbsp;' : '';
2298
    echo "<input type='number' min='$minimum' placeholder='$price' value='$price' class='wpi-field-price' />";
2299
    echo $position == 'right' ? '&nbsp;' . $symbol : '' ;
2300
    echo "</label>";
2301
    echo "<input type='hidden' value='$item_id' class='wpi-field-item' />";
2302
    echo "<a class='btn btn-success wpinv-submit wpinv-update-dynamic-price-frontend'>$update</a>";
2303
2304
    //Maybe display the minimum price
2305
    if( $item->get_minimum_price() > 0 && !empty( $minimum_price_text ) ) {
2306
        $minimum_price = wpinv_price( wpinv_format_amount( $item->get_minimum_price() ) );
2307
        echo "<div>$minimum_price_text &mdash; $minimum_price</div>";
2308
    }
2309
2310
    echo "</div>";
2311
2312
}
2313
add_action( 'wpinv_checkout_cart_item_price_after', 'wpinv_checkout_cart_item_name_your_price', 10, 2 );