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

wpinv-template-functions.php ➔ wpinv_display_to_address()   B

Complexity

Conditions 6
Paths 17

Size

Total Lines 42

Duplication

Lines 6
Ratio 14.29 %

Importance

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