Passed
Push — master ( 258987...4a6585 )
by Brian
09:29 queued 04:10
created

wpinv_multicheck_callback()   B

Complexity

Conditions 7
Paths 26

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 18
c 0
b 0
f 0
dl 0
loc 24
rs 8.8333
cc 7
nc 26
nop 1
1
<?php
2
/**
3
 * Contains settings related functions
4
 *
5
 * @package Invoicing
6
 * @since   1.0.0
7
 */
8
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * Retrieves all default settings.
13
 * 
14
 * @return array
15
 */
16
function wpinv_get_settings() {
17
    $defaults = array();
18
19
    foreach ( array_values( wpinv_get_registered_settings() ) as $tab_settings ) {
20
21
        foreach ( array_values( $tab_settings ) as $section_settings ) {
22
23
            foreach ( $section_settings as $key => $setting ) {
24
                if ( isset( $setting['std'] ) ) {
25
                    $defaults[ $key ] = $setting['std'];
26
                }
27
            }
28
29
        }
30
31
    }
32
33
    return $defaults;
34
35
}
36
37
/**
38
 * Retrieves all settings.
39
 * 
40
 * @return array
41
 */
42
function wpinv_get_options() {
43
    global $wpinv_options;
44
45
    // Try fetching the saved options.
46
    if ( ! is_array( $wpinv_options ) ) {
47
        $wpinv_options = get_option( 'wpinv_settings' );
48
    }
49
50
    // If that fails, don't fetch the default settings to prevent a loop.
51
    if ( ! is_array( $wpinv_options ) ) {
52
        $wpinv_options = array();
53
    }
54
55
    return $wpinv_options;
56
}
57
58
/**
59
 * Retrieves a single setting.
60
 * 
61
 * @param string $key the setting key.
62
 * @param mixed $default The default value to use if the setting has not been set.
63
 * @return array
64
 */
65
function wpinv_get_option( $key = '', $default = false ) {
66
67
    $options = wpinv_get_options();
68
    $value   = isset( $options[ $key ] ) ? $options[ $key ] : $default;
69
    $value   = apply_filters( 'wpinv_get_option', $value, $key, $default );
70
71
    return apply_filters( 'wpinv_get_option_' . $key, $value, $key, $default );
0 ignored issues
show
Bug Best Practice introduced by
The expression return apply_filters('wp...$value, $key, $default) could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
72
}
73
74
/**
75
 * Updates all settings.
76
 * 
77
 * @param array $options the new options.
78
 * @return bool
79
 */
80
function wpinv_update_options( $options ) {
81
    global $wpinv_options;
82
83
    // update the option.
84
    if ( is_array( $options ) && update_option( 'wpinv_settings', $options ) ) {
85
        $wpinv_options = $options;
86
        return true;
87
    }
88
89
    return false;
90
}
91
92
/**
93
 * Updates a single setting.
94
 * 
95
 * @param string $key the setting key.
96
 * @param mixed $value The setting value.
97
 * @return bool
98
 */
99
function wpinv_update_option( $key = '', $value = false ) {
100
101
    // If no key, exit.
102
    if ( empty( $key ) ) {
103
        return false;
104
    }
105
106
    // Maybe delete the option instead.
107
    if ( is_null( $value ) ) {
108
        return wpinv_delete_option( $key );
109
    }
110
111
    // Prepare the new options.
112
    $options         = wpinv_get_options();
113
    $options[ $key ] = apply_filters( 'wpinv_update_option', $value, $key );
114
115
    // Save the new options.
116
    return wpinv_update_options( $options );
117
118
}
119
120
/**
121
 * Deletes a single setting.
122
 * 
123
 * @param string $key the setting key.
124
 * @return bool
125
 */
126
function wpinv_delete_option( $key = '' ) {
127
128
    // If no key, exit
129
    if ( empty( $key ) ) {
130
        return false;
131
    }
132
133
    $options = wpinv_get_options();
134
135
    if ( isset( $options[ $key ] ) ) {
136
        unset( $options[ $key ] );
137
        return wpinv_update_options( $options );
138
    }
139
140
    return true;
141
142
}
143
144
/**
145
 * Register settings after admin inits.
146
 * 
147
 */
148
function wpinv_register_settings() {
149
150
    // Loop through all tabs.
151
    foreach ( wpinv_get_registered_settings() as $tab => $sections ) {
152
153
        // In each tab, loop through sections.
154
        foreach ( $sections as $section => $settings ) {
155
156
            // Check for backwards compatibility
157
            $section_tabs = wpinv_get_settings_tab_sections( $tab );
158
            if ( ! is_array( $section_tabs ) || ! array_key_exists( $section, $section_tabs ) ) {
159
                $section = 'main';
160
                $settings = $sections;
161
            }
162
163
            // Register the setting section.
164
            add_settings_section(
165
                'wpinv_settings_' . $tab . '_' . $section,
166
                __return_null(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of __return_null() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
167
                '__return_false',
168
                'wpinv_settings_' . $tab . '_' . $section
169
            );
170
171
            foreach ( $settings as $option ) {
172
                if ( ! empty( $option['id'] ) ) {
173
                    wpinv_register_settings_option( $tab, $section, $option );
174
                }
175
            }
176
177
        }
178
    }
179
180
    // Creates our settings in the options table.
181
    register_setting( 'wpinv_settings', 'wpinv_settings', 'wpinv_settings_sanitize' );
0 ignored issues
show
Bug introduced by
'wpinv_settings_sanitize' of type string is incompatible with the type array expected by parameter $args of register_setting(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

181
    register_setting( 'wpinv_settings', 'wpinv_settings', /** @scrutinizer ignore-type */ 'wpinv_settings_sanitize' );
Loading history...
182
}
183
add_action( 'admin_init', 'wpinv_register_settings' );
184
185
/**
186
 * Register a single settings option.
187
 * 
188
 * @param string $tab
189
 * @param string $section
190
 * @param string $option
191
 * 
192
 */
193
function wpinv_register_settings_option( $tab, $section, $option ) {
194
195
    $name    = isset( $option['name'] ) ? $option['name'] : '';
196
    $cb      = "wpinv_{$option['type']}_callback";
197
    $section = "wpinv_settings_{$tab}_$section";
198
199
	if ( isset( $option['desc'] ) && ! empty( $option['help-tip'] ) ) {
200
		$tip   = esc_attr( $option['desc'] );
201
		$name .= "<span class='dashicons dashicons-editor-help wpi-help-tip' title='$tip'></span>";
202
		unset( $option['desc'] );
203
	}
204
205
    // Loop through all tabs.
206
    add_settings_field(
207
        'wpinv_settings[' . $option['id'] . ']',
208
        $name,
209
        function_exists( $cb ) ? $cb : 'wpinv_missing_callback',
210
        $section,
211
        $section,
212
        array(
213
            'section'     => $section,
214
            'id'          => isset( $option['id'] )          ? $option['id']          : null,
215
            'desc'        => isset( $option['desc'] )        ? $option['desc']        : '',
216
            'name'        => $name,
217
            'size'        => isset( $option['size'] )        ? $option['size']        : null,
218
            'options'     => isset( $option['options'] )     ? $option['options']     : '',
219
            'selected'    => isset( $option['selected'] )    ? $option['selected']    : null,
220
            'std'         => isset( $option['std'] )         ? $option['std']         : '',
221
            'min'         => isset( $option['min'] )         ? $option['min']         : null,
222
            'max'         => isset( $option['max'] )         ? $option['max']         : null,
223
            'step'        => isset( $option['step'] )        ? $option['step']        : null,
224
            'placeholder' => isset( $option['placeholder'] ) ? $option['placeholder'] : null,
225
            'allow_blank' => isset( $option['allow_blank'] ) ? $option['allow_blank'] : true,
226
            'readonly'    => isset( $option['readonly'] )    ? $option['readonly']    : false,
227
            'faux'        => isset( $option['faux'] )        ? $option['faux']        : false,
228
            'onchange'    => isset( $option['onchange'] )   ? $option['onchange']     : '',
229
            'custom'      => isset( $option['custom'] )     ? $option['custom']       : '',
230
            'class'       => isset( $option['class'] )     ? $option['class']         : '',
231
            'cols'        => isset( $option['cols'] ) && (int) $option['cols'] > 0 ? (int) $option['cols'] : 50,
232
            'rows'        => isset( $option['rows'] ) && (int) $option['rows'] > 0 ? (int) $option['rows'] : 5,
233
        )
234
    );
235
236
}
237
238
/**
239
 * Returns an array of all registered settings.
240
 * 
241
 * @return array
242
 */
243
function wpinv_get_registered_settings() {
244
    return apply_filters( 'wpinv_registered_settings', wpinv_get_data( 'admin-settings' ) );
245
}
246
247
/**
248
 * Sanitizes settings before they are saved.
249
 * 
250
 * @return array
251
 */
252
function wpinv_settings_sanitize( $input = array() ) {
253
254
    $wpinv_options = wpinv_get_options();
255
256
    if ( empty( wp_get_raw_referer() ) ) {
257
        return $input;
258
    }
259
260
    wp_parse_str( wp_get_raw_referer(), $referrer );
0 ignored issues
show
Bug introduced by
It seems like wp_get_raw_referer() can also be of type false; however, parameter $string of wp_parse_str() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

260
    wp_parse_str( /** @scrutinizer ignore-type */ wp_get_raw_referer(), $referrer );
Loading history...
261
262
    $settings = wpinv_get_registered_settings();
263
    $tab      = isset( $referrer['tab'] ) ? $referrer['tab'] : 'general';
264
    $section  = isset( $referrer['section'] ) ? $referrer['section'] : 'main';
265
266
    $input = $input ? $input : array();
267
    $input = apply_filters( 'wpinv_settings_tab_' . $tab . '_sanitize', $input );
268
    $input = apply_filters( 'wpinv_settings_' . $tab . '-' . $section . '_sanitize', $input );
269
270
    // Loop through each setting being saved and pass it through a sanitization filter
271
    foreach ( $input as $key => $value ) {
272
273
        // Get the setting type (checkbox, select, etc)
274
        $type = isset( $settings[ $tab ][$section][ $key ]['type'] ) ? $settings[ $tab ][$section][ $key ]['type'] : false;
275
276
        if ( $type ) {
277
            // Field type specific filter
278
            $input[$key] = apply_filters( 'wpinv_settings_sanitize_' . $type, $value, $key );
279
        }
280
281
        // General filter
282
        $input[ $key ] = apply_filters( 'wpinv_settings_sanitize', $input[ $key ], $key );
283
    }
284
285
    // Loop through the whitelist and unset any that are empty for the tab being saved
286
    $main_settings    = $section == 'main' ? $settings[ $tab ] : array(); // Check for extensions that aren't using new sections
287
    $section_settings = ! empty( $settings[ $tab ][ $section ] ) ? $settings[ $tab ][ $section ] : array();
288
289
    $found_settings = array_merge( $main_settings, $section_settings );
290
291
    if ( ! empty( $found_settings ) ) {
292
        foreach ( $found_settings as $key => $value ) {
293
294
            // settings used to have numeric keys, now they have keys that match the option ID. This ensures both methods work
295
            if ( is_numeric( $key ) ) {
296
                $key = $value['id'];
297
            }
298
299
            if ( ! isset( $input[ $key ] ) && isset( $wpinv_options[ $key ] ) ) {
300
                unset( $wpinv_options[ $key ] );
301
            }
302
        }
303
    }
304
305
    // Merge our new settings with the existing
306
    $output = array_merge( $wpinv_options, $input );
307
308
    add_settings_error( 'wpinv-notices', '', __( 'Settings updated.', 'invoicing' ), 'updated' );
309
310
    return $output;
311
}
312
313
function wpinv_settings_sanitize_misc_accounting( $input ) {
314
315
    if ( ! wpinv_current_user_can_manage_invoicing() ) {
316
        return $input;
317
    }
318
319
    if( ! empty( $input['enable_sequential'] ) && !wpinv_get_option( 'enable_sequential' ) ) {
320
        // Shows an admin notice about upgrading previous order numbers
321
        getpaid_session()->set( 'upgrade_sequential', '1' );
322
    }
323
324
    return $input;
325
}
326
add_filter( 'wpinv_settings_misc-accounting_sanitize', 'wpinv_settings_sanitize_misc_accounting' );
327
328
function wpinv_settings_sanitize_tax_rates( $input ) {
329
    if( ! wpinv_current_user_can_manage_invoicing() ) {
330
        return $input;
331
    }
332
333
    $new_rates = !empty( $_POST['tax_rates'] ) ? array_values( $_POST['tax_rates'] ) : array();
334
335
    $tax_rates = array();
336
337
    if ( !empty( $new_rates ) ) {
338
        foreach ( $new_rates as $rate ) {
339
            if ( isset( $rate['country'] ) && empty( $rate['country'] ) && empty( $rate['state'] ) ) {
340
                continue;
341
            }
342
            
343
            $rate['rate'] = wpinv_sanitize_amount( $rate['rate'], 4 );
344
            
345
            $tax_rates[] = $rate;
346
        }
347
    }
348
349
    update_option( 'wpinv_tax_rates', $tax_rates );
350
351
    return $input;
352
}
353
add_filter( 'wpinv_settings_taxes-rates_sanitize', 'wpinv_settings_sanitize_tax_rates' );
354
355
function wpinv_sanitize_text_field( $input ) {
356
    return trim( $input );
357
}
358
add_filter( 'wpinv_settings_sanitize_text', 'wpinv_sanitize_text_field' );
359
360
function wpinv_get_settings_tabs() {
361
    $tabs             = array();
362
    $tabs['general']  = __( 'General', 'invoicing' );
363
    $tabs['gateways'] = __( 'Payment Gateways', 'invoicing' );
364
    $tabs['taxes']    = __( 'Taxes', 'invoicing' );
365
    $tabs['emails']   = __( 'Emails', 'invoicing' );
366
    $tabs['privacy']  = __( 'Privacy', 'invoicing' );
367
    $tabs['misc']     = __( 'Misc', 'invoicing' );
368
    $tabs['tools']    = __( 'Tools', 'invoicing' );
369
370
    return apply_filters( 'wpinv_settings_tabs', $tabs );
371
}
372
373
function wpinv_get_settings_tab_sections( $tab = false ) {
374
    $tabs     = false;
375
    $sections = wpinv_get_registered_settings_sections();
376
377
    if( $tab && ! empty( $sections[ $tab ] ) ) {
378
        $tabs = $sections[ $tab ];
379
    } else if ( $tab ) {
380
        $tabs = false;
381
    }
382
383
    return $tabs;
384
}
385
386
function wpinv_get_registered_settings_sections() {
387
    static $sections = false;
388
389
    if ( false !== $sections ) {
390
        return $sections;
391
    }
392
393
    $sections = array(
394
        'general' => apply_filters( 'wpinv_settings_sections_general', array(
395
            'main' => __( 'General Settings', 'invoicing' ),
396
            'currency_section' => __( 'Currency Settings', 'invoicing' ),
397
            'labels' => __( 'Label Texts', 'invoicing' ),
398
        ) ),
399
        'gateways' => apply_filters( 'wpinv_settings_sections_gateways', array(
400
            'main' => __( 'Gateway Settings', 'invoicing' ),
401
        ) ),
402
        'taxes' => apply_filters( 'wpinv_settings_sections_taxes', array(
403
            'main' => __( 'Tax Settings', 'invoicing' ),
404
            'rates' => __( 'Tax Rates', 'invoicing' ),
405
        ) ),
406
        'emails' => apply_filters( 'wpinv_settings_sections_emails', array(
407
            'main' => __( 'Email Settings', 'invoicing' ),
408
        ) ),
409
        'privacy' => apply_filters( 'wpinv_settings_sections_privacy', array(
410
            'main' => __( 'Privacy policy', 'invoicing' ),
411
        ) ),
412
        'misc' => apply_filters( 'wpinv_settings_sections_misc', array(
413
            'main' => __( 'Miscellaneous', 'invoicing' ),
414
            'fields' => __( 'Fields Settings', 'invoicing' ),
415
            'custom-css' => __( 'Custom CSS', 'invoicing' ),
416
        ) ),
417
        'tools' => apply_filters( 'wpinv_settings_sections_tools', array(
418
            'main' => __( 'Diagnostic Tools', 'invoicing' ),
419
        ) ),
420
    );
421
422
    $sections = apply_filters( 'wpinv_settings_sections', $sections );
423
424
    return $sections;
425
}
426
427
function wpinv_get_pages( $with_slug = false, $default_label = NULL ) {
428
	$pages_options = array();
429
430
	if( $default_label !== NULL && $default_label !== false ) {
431
		$pages_options = array( '' => $default_label ); // Blank option
432
	}
433
434
	$pages = get_pages();
435
	if ( $pages ) {
436
		foreach ( $pages as $page ) {
437
			$title = $with_slug ? $page->post_title . ' (' . $page->post_name . ')' : $page->post_title;
438
            $pages_options[ $page->ID ] = $title;
439
		}
440
	}
441
442
	return $pages_options;
443
}
444
445
function wpinv_header_callback( $args ) {
446
	if ( !empty( $args['desc'] ) ) {
447
        echo $args['desc'];
448
    }
449
}
450
451
function wpinv_hidden_callback( $args ) {
452
	global $wpinv_options;
453
454
	if ( isset( $args['set_value'] ) ) {
455
		$value = $args['set_value'];
456
	} elseif ( isset( $wpinv_options[ $args['id'] ] ) ) {
457
		$value = $wpinv_options[ $args['id'] ];
458
	} else {
459
		$value = isset( $args['std'] ) ? $args['std'] : '';
460
	}
461
462
	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
463
		$args['readonly'] = true;
464
		$value = isset( $args['std'] ) ? $args['std'] : '';
465
		$name  = '';
466
	} else {
467
		$name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
468
	}
469
470
	$html = '<input type="hidden" id="wpinv_settings[' . wpinv_sanitize_key( $args['id'] ) . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '" />';
471
    
472
	echo $html;
473
}
474
475
function wpinv_checkbox_callback( $args ) {
476
	global $wpinv_options;
477
    
478
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
479
480
	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
481
		$name = '';
482
	} else {
483
		$name = 'name="wpinv_settings[' . $sanitize_id . ']"';
484
	}
485
486
	$std     = isset( $args['std'] ) ? $args['std'] : 0;
487
	$value   = isset( $wpinv_options[ $args['id'] ] ) ? $wpinv_options[ $args['id'] ] : $std;
488
	$checked = checked( empty( $value ), false, false );
489
490
	$html = '<input type="checkbox" id="wpinv_settings[' . $sanitize_id . ']"' . $name . ' value="1" ' . $checked . '/>';
491
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
492
493
	echo $html;
494
}
495
496
function wpinv_multicheck_callback( $args ) {
497
	global $wpinv_options;
498
499
	$sanitize_id = wpinv_sanitize_key( $args['id'] );
500
	$class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
501
502
	if ( ! empty( $args['options'] ) ) {
503
504
		$std     = isset( $args['std'] ) ? $args['std'] : array();
505
		$value   = isset( $wpinv_options[ $args['id'] ] ) ? $wpinv_options[ $args['id'] ] : $std;
506
507
		echo '<div class="wpi-mcheck-rows wpi-mcheck-' . $sanitize_id . $class . '">';
508
        foreach( $args['options'] as $key => $option ):
509
			$sanitize_key = wpinv_sanitize_key( $key );
510
			if ( in_array( $sanitize_key, $value ) ) { 
511
				$enabled = $sanitize_key;
512
			} else { 
513
				$enabled = NULL; 
514
			}
515
			echo '<div class="wpi-mcheck-row"><input name="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="' . esc_attr( $sanitize_key ) . '" ' . checked( $sanitize_key, $enabled, false ) . '/>&nbsp;';
516
			echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . wp_kses_post( $option ) . '</label></div>';
517
		endforeach;
518
		echo '</div>';
519
		echo '<p class="description">' . $args['desc'] . '</p>';
520
	}
521
}
522
523
function wpinv_payment_icons_callback( $args ) {
524
	global $wpinv_options;
525
    
526
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
527
528
	if ( ! empty( $args['options'] ) ) {
529
		foreach( $args['options'] as $key => $option ) {
530
            $sanitize_key = wpinv_sanitize_key( $key );
531
            
532
			if( isset( $wpinv_options[$args['id']][$key] ) ) {
533
				$enabled = $option;
534
			} else {
535
				$enabled = NULL;
536
			}
537
538
			echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" style="margin-right:10px;line-height:16px;height:16px;display:inline-block;">';
539
540
				echo '<input name="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="' . esc_attr( $option ) . '" ' . checked( $option, $enabled, false ) . '/>&nbsp;';
541
542
				if ( wpinv_string_is_image_url( $key ) ) {
543
					echo '<img class="payment-icon" src="' . esc_url( $key ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
544
				} else {
545
					$card = strtolower( str_replace( ' ', '', $option ) );
546
547
					if ( has_filter( 'wpinv_accepted_payment_' . $card . '_image' ) ) {
548
						$image = apply_filters( 'wpinv_accepted_payment_' . $card . '_image', '' );
549
					} else {
550
						$image       = wpinv_locate_template( 'images' . DIRECTORY_SEPARATOR . 'icons' . DIRECTORY_SEPARATOR . $card . '.gif', false );
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $template_path of wpinv_locate_template(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

550
						$image       = wpinv_locate_template( 'images' . DIRECTORY_SEPARATOR . 'icons' . DIRECTORY_SEPARATOR . $card . '.gif', /** @scrutinizer ignore-type */ false );
Loading history...
551
						$content_dir = WP_CONTENT_DIR;
552
553
						if ( function_exists( 'wp_normalize_path' ) ) {
554
							// Replaces backslashes with forward slashes for Windows systems
555
							$image = wp_normalize_path( $image );
556
							$content_dir = wp_normalize_path( $content_dir );
557
						}
558
559
						$image = str_replace( $content_dir, content_url(), $image );
560
					}
561
562
					echo '<img class="payment-icon" src="' . esc_url( $image ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
563
				}
564
			echo $option . '</label>';
565
		}
566
		echo '<p class="description" style="margin-top:16px;">' . wp_kses_post( $args['desc'] ) . '</p>';
567
	}
568
}
569
570
function wpinv_radio_callback( $args ) {
571
	global $wpinv_options;
572
    
573
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
574
    
575
    foreach ( $args['options'] as $key => $option ) :
576
		$sanitize_key = wpinv_sanitize_key( $key );
577
        
578
        $checked = false;
579
580
		if ( isset( $wpinv_options[ $args['id'] ] ) && $wpinv_options[ $args['id'] ] == $key )
581
			$checked = true;
582
		elseif( isset( $args['std'] ) && $args['std'] == $key && ! isset( $wpinv_options[ $args['id'] ] ) )
583
			$checked = true;
584
585
		echo '<input name="wpinv_settings[' . $sanitize_id . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="radio" value="' . $sanitize_key . '" ' . checked(true, $checked, false) . '/>&nbsp;';
586
		echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . esc_html( $option ) . '</label><br/>';
587
	endforeach;
588
589
	echo '<p class="description">' . wp_kses_post( $args['desc'] ) . '</p>';
590
}
591
592
function wpinv_gateways_callback( $args ) {
593
	global $wpinv_options;
594
    
595
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
596
597
	foreach ( $args['options'] as $key => $option ) :
598
		$sanitize_key = wpinv_sanitize_key( $key );
599
        
600
        if ( isset( $wpinv_options['gateways'][ $key ] ) )
601
			$enabled = '1';
602
		else
603
			$enabled = null;
604
605
		echo '<input name="wpinv_settings[' . esc_attr( $args['id'] ) . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="1" ' . checked('1', $enabled, false) . '/>&nbsp;';
606
		echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . esc_html( $option['admin_label'] ) . '</label><br/>';
607
	endforeach;
608
}
609
610
function wpinv_gateway_select_callback($args) {
611
	global $wpinv_options;
612
    
613
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
614
    $class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
615
616
	echo '<select name="wpinv_settings[' . $sanitize_id . ']"" id="wpinv_settings[' . $sanitize_id . ']" class="'.$class.'" >';
617
618
	foreach ( $args['options'] as $key => $option ) :
619
		if ( isset( $args['selected'] ) && $args['selected'] !== null && $args['selected'] !== false ) {
620
            $selected = selected( $key, $args['selected'], false );
621
        } else {
622
            $selected = isset( $wpinv_options[ $args['id'] ] ) ? selected( $key, $wpinv_options[$args['id']], false ) : '';
623
        }
624
		echo '<option value="' . wpinv_sanitize_key( $key ) . '"' . $selected . '>' . esc_html( $option['admin_label'] ) . '</option>';
625
	endforeach;
626
627
	echo '</select>';
628
	echo '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
629
}
630
631
function wpinv_text_callback( $args ) {
632
	global $wpinv_options;
633
    
634
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
635
636
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
637
		$value = $wpinv_options[ $args['id'] ];
638
	} else {
639
		$value = isset( $args['std'] ) ? $args['std'] : '';
640
	}
641
642
	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
643
		$args['readonly'] = true;
644
		$value = isset( $args['std'] ) ? $args['std'] : '';
645
		$name  = '';
646
	} else {
647
		$name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
648
	}
649
	$class = !empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
650
651
	$readonly = $args['readonly'] === true ? ' readonly="readonly"' : '';
652
	$size     = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
653
	$html     = '<input type="text" class="' . sanitize_html_class( $size ) . '-text ' . $class . '" id="wpinv_settings[' . $sanitize_id . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"' . $readonly . '/>';
654
	$html    .= '<br /><label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
655
656
	echo $html;
657
}
658
659
function wpinv_number_callback( $args ) {
660
	global $wpinv_options;
661
    
662
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
663
664
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
665
		$value = $wpinv_options[ $args['id'] ];
666
	} else {
667
		$value = isset( $args['std'] ) ? $args['std'] : '';
668
	}
669
670
	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
671
		$args['readonly'] = true;
672
		$value = isset( $args['std'] ) ? $args['std'] : '';
673
		$name  = '';
674
	} else {
675
		$name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
676
	}
677
678
	$max  = isset( $args['max'] ) ? $args['max'] : 999999;
679
	$min  = isset( $args['min'] ) ? $args['min'] : 0;
680
	$step = isset( $args['step'] ) ? $args['step'] : 1;
681
	$class = !empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
682
683
	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
684
	$html = '<input type="number" step="' . esc_attr( $step ) . '" max="' . esc_attr( $max ) . '" min="' . esc_attr( $min ) . '" class="' . sanitize_html_class( $size ) . '-text ' . $class . '" id="wpinv_settings[' . $sanitize_id . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"/>';
685
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
686
687
	echo $html;
688
}
689
690
function wpinv_textarea_callback( $args ) {
691
	global $wpinv_options;
692
    
693
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
694
695
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
696
		$value = $wpinv_options[ $args['id'] ];
697
	} else {
698
		$value = isset( $args['std'] ) ? $args['std'] : '';
699
	}
700
    
701
    $size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
702
    $class = ( isset( $args['class'] ) && ! is_null( $args['class'] ) ) ? $args['class'] : 'large-text';
703
704
	$html = '<textarea class="' . sanitize_html_class( $class ) . ' txtarea-' . sanitize_html_class( $size ) . ' wpi-' . esc_attr( sanitize_html_class( $sanitize_id ) ) . ' " cols="' . $args['cols'] . '" rows="' . $args['rows'] . '" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
705
	$html .= '<br /><label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
706
707
	echo $html;
708
}
709
710
function wpinv_password_callback( $args ) {
711
	global $wpinv_options;
712
    
713
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
714
715
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
716
		$value = $wpinv_options[ $args['id'] ];
717
	} else {
718
		$value = isset( $args['std'] ) ? $args['std'] : '';
719
	}
720
721
	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
722
	$html = '<input type="password" class="' . sanitize_html_class( $size ) . '-text" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( $value ) . '"/>';
723
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
724
725
	echo $html;
726
}
727
728
function wpinv_missing_callback($args) {
729
	printf(
730
		__( 'The callback function used for the %s setting is missing.', 'invoicing' ),
731
		'<strong>' . $args['id'] . '</strong>'
732
	);
733
}
734
735
function wpinv_select_callback($args) {
736
	global $wpinv_options;
737
    
738
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
739
740
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
741
		$value = $wpinv_options[ $args['id'] ];
742
	} else {
743
		$value = isset( $args['std'] ) ? $args['std'] : '';
744
	}
745
    
746
    if ( isset( $args['selected'] ) && $args['selected'] !== null && $args['selected'] !== false ) {
747
        $value = $args['selected'];
748
    }
749
750
	if ( isset( $args['placeholder'] ) ) {
751
		$placeholder = $args['placeholder'];
752
	} else {
753
		$placeholder = '';
754
	}
755
    
756
    if( !empty( $args['onchange'] ) ) {
757
        $onchange = ' onchange="' . esc_attr( $args['onchange'] ) . '"';
758
    } else {
759
        $onchange = '';
760
    }
761
762
    $class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
763
764
	$html = '<select id="wpinv_settings[' . $sanitize_id . ']" class="'.$class.'"  name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" data-placeholder="' . esc_html( $placeholder ) . '"' . $onchange . ' />';
765
766
	foreach ( $args['options'] as $option => $name ) {
767
		$selected = selected( $option, $value, false );
768
		$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $name ) . '</option>';
769
	}
770
771
	$html .= '</select>';
772
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
773
774
	echo $html;
775
}
776
777
function wpinv_color_select_callback( $args ) {
778
	global $wpinv_options;
779
    
780
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
781
782
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
783
		$value = $wpinv_options[ $args['id'] ];
784
	} else {
785
		$value = isset( $args['std'] ) ? $args['std'] : '';
786
	}
787
788
	$html = '<select id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"/>';
789
790
	foreach ( $args['options'] as $option => $color ) {
791
		$selected = selected( $option, $value, false );
792
		$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $color['label'] ) . '</option>';
793
	}
794
795
	$html .= '</select>';
796
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
797
798
	echo $html;
799
}
800
801
function wpinv_rich_editor_callback( $args ) {
802
	global $wpinv_options, $wp_version;
803
    
804
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
805
806
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
807
		$value = $wpinv_options[ $args['id'] ];
808
809
		if( empty( $args['allow_blank'] ) && empty( $value ) ) {
810
			$value = isset( $args['std'] ) ? $args['std'] : '';
811
		}
812
	} else {
813
		$value = isset( $args['std'] ) ? $args['std'] : '';
814
	}
815
816
	$rows = isset( $args['size'] ) ? $args['size'] : 20;
817
818
	$html = '<div class="getpaid-settings-editor-input">';
819
	if ( $wp_version >= 3.3 && function_exists( 'wp_editor' ) ) {
820
		ob_start();
821
		wp_editor( stripslashes( $value ), 'wpinv_settings_' . esc_attr( $args['id'] ), array( 'textarea_name' => 'wpinv_settings[' . esc_attr( $args['id'] ) . ']', 'textarea_rows' => absint( $rows ), 'media_buttons' => false ) );
822
		$html .= ob_get_clean();
823
	} else {
824
		$html .= '<textarea class="large-text" rows="10" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" class="wpi-' . esc_attr( sanitize_html_class( $args['id'] ) ) . '">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
825
	}
826
827
	$html .= '</div><br/><label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
828
829
	echo $html;
830
}
831
832
function wpinv_upload_callback( $args ) {
833
	global $wpinv_options;
834
    
835
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
836
837
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
838
		$value = $wpinv_options[$args['id']];
839
	} else {
840
		$value = isset($args['std']) ? $args['std'] : '';
841
	}
842
843
	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
844
	$html = '<input type="text" class="' . sanitize_html_class( $size ) . '-text" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
845
	$html .= '<span>&nbsp;<input type="button" class="wpinv_settings_upload_button button-secondary" value="' . __( 'Upload File', 'invoicing' ) . '"/></span>';
846
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
847
848
	echo $html;
849
}
850
851
function wpinv_color_callback( $args ) {
852
	global $wpinv_options;
853
    
854
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
855
856
	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
857
		$value = $wpinv_options[ $args['id'] ];
858
	} else {
859
		$value = isset( $args['std'] ) ? $args['std'] : '';
860
	}
861
862
	$default = isset( $args['std'] ) ? $args['std'] : '';
863
864
	$html = '<input type="text" class="wpinv-color-picker" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( $value ) . '" data-default-color="' . esc_attr( $default ) . '" />';
865
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
866
867
	echo $html;
868
}
869
870
function wpinv_country_states_callback($args) {
871
	global $wpinv_options;
872
    
873
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
874
875
	if ( isset( $args['placeholder'] ) ) {
876
		$placeholder = $args['placeholder'];
877
	} else {
878
		$placeholder = '';
879
	}
880
881
	$states = wpinv_get_country_states();
882
883
	$class = empty( $states ) ? ' class="wpinv-no-states"' : ' class="wpi_select2"';
884
	$html = '<select id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"' . $class . 'data-placeholder="' . esc_html( $placeholder ) . '"/>';
885
886
	foreach ( $states as $option => $name ) {
887
		$selected = isset( $wpinv_options[ $args['id'] ] ) ? selected( $option, $wpinv_options[$args['id']], false ) : '';
888
		$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $name ) . '</option>';
889
	}
890
891
	$html .= '</select>';
892
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
893
894
	echo $html;
895
}
896
897
function wpinv_tax_rates_callback($args) {
898
	global $wpinv_options;
899
	$rates = wpinv_get_tax_rates();
900
	ob_start(); ?>
901
    </td><tr>
902
    <td colspan="2" class="wpinv_tax_tdbox">
903
	<p><?php echo $args['desc']; ?></p>
904
	<table id="wpinv_tax_rates" class="wp-list-table widefat fixed posts">
905
		<thead>
906
			<tr>
907
				<th scope="col" class="wpinv_tax_country"><?php _e( 'Country', 'invoicing' ); ?></th>
908
				<th scope="col" class="wpinv_tax_state"><?php _e( 'State / Province', 'invoicing' ); ?></th>
909
                <th scope="col" class="wpinv_tax_global" title="<?php esc_attr_e( 'Apply rate to whole country, regardless of state / province', 'invoicing' ); ?>"><?php _e( 'Country Wide', 'invoicing' ); ?></th>
910
                <th scope="col" class="wpinv_tax_rate"><?php _e( 'Rate %', 'invoicing' ); ?></th> 
911
                <th scope="col" class="wpinv_tax_name"><?php _e( 'Tax Name', 'invoicing' ); ?></th>
912
				<th scope="col" class="wpinv_tax_action"><?php _e( 'Remove', 'invoicing' ); ?></th>
913
			</tr>
914
		</thead>
915
        <tbody>
916
		<?php if( !empty( $rates ) ) : ?>
917
			<?php foreach( $rates as $key => $rate ) : ?>
918
            <?php 
919
            $sanitized_key = wpinv_sanitize_key( $key );
920
            ?>
921
			<tr>
922
				<td class="wpinv_tax_country">
923
					<?php
924
					echo wpinv_html_select( array(
925
						'options'          => wpinv_get_country_list( true ),
926
						'name'             => 'tax_rates[' . $sanitized_key . '][country]',
927
                        'id'               => 'tax_rates[' . $sanitized_key . '][country]',
928
						'selected'         => $rate['country'],
929
						'show_option_all'  => false,
930
						'show_option_none' => false,
931
						'class'            => 'wpinv-tax-country wpi_select2',
932
						'placeholder'      => __( 'Choose a country', 'invoicing' )
933
					) );
934
					?>
935
				</td>
936
				<td class="wpinv_tax_state">
937
					<?php
938
					$states = wpinv_get_country_states( $rate['country'] );
939
					if( !empty( $states ) ) {
940
						echo wpinv_html_select( array(
941
							'options'          => array_merge( array( '' => '' ), $states ),
942
							'name'             => 'tax_rates[' . $sanitized_key . '][state]',
943
                            'id'               => 'tax_rates[' . $sanitized_key . '][state]',
944
							'selected'         => $rate['state'],
945
							'show_option_all'  => false,
946
							'show_option_none' => false,
947
                            'class'            => 'wpi_select2',
948
							'placeholder'      => __( 'Choose a state', 'invoicing' )
949
						) );
950
					} else {
951
						echo wpinv_html_text( array(
952
							'name'  => 'tax_rates[' . $sanitized_key . '][state]', $rate['state'],
953
							'value' => ! empty( $rate['state'] ) ? $rate['state'] : '',
954
                            'id'    => 'tax_rates[' . $sanitized_key . '][state]',
955
						) );
956
					}
957
					?>
958
				</td>
959
				<td class="wpinv_tax_global">
960
					<input type="checkbox" name="tax_rates[<?php echo $sanitized_key; ?>][global]" id="tax_rates[<?php echo $sanitized_key; ?>][global]" value="1"<?php checked( true, ! empty( $rate['global'] ) ); ?>/>
961
					<label for="tax_rates[<?php echo $sanitized_key; ?>][global]"><?php _e( 'Apply to whole country', 'invoicing' ); ?></label>
962
				</td>
963
				<td class="wpinv_tax_rate"><input type="number" class="small-text" step="any" min="0" max="99" name="tax_rates[<?php echo $sanitized_key; ?>][rate]" value="<?php echo esc_html( $rate['rate'] ); ?>"/></td>
964
                <td class="wpinv_tax_name"><input type="text" class="regular-text" name="tax_rates[<?php echo $sanitized_key; ?>][name]" value="<?php echo esc_html( $rate['name'] ); ?>"/></td>
965
				<td class="wpinv_tax_action"><span class="wpinv_remove_tax_rate button-secondary"><?php _e( 'Remove Rate', 'invoicing' ); ?></span></td>
966
			</tr>
967
			<?php endforeach; ?>
968
		<?php else : ?>
969
			<tr>
970
				<td class="wpinv_tax_country">
971
					<?php
972
					echo wpinv_html_select( array(
973
						'options'          => wpinv_get_country_list( true ),
974
						'name'             => 'tax_rates[0][country]',
975
						'show_option_all'  => false,
976
						'show_option_none' => false,
977
						'class'            => 'wpinv-tax-country wpi_select2',
978
						'placeholder'      => __( 'Choose a country', 'invoicing' )
979
					) ); ?>
980
				</td>
981
				<td class="wpinv_tax_state">
982
					<?php echo wpinv_html_text( array(
983
						'name' => 'tax_rates[0][state]'
984
					) ); ?>
985
				</td>
986
				<td class="wpinv_tax_global">
987
					<input type="checkbox" name="tax_rates[0][global]" id="tax_rates[0][global]" value="1"/>
988
					<label for="tax_rates[0][global]"><?php _e( 'Apply to whole country', 'invoicing' ); ?></label>
989
				</td>
990
				<td class="wpinv_tax_rate"><input type="number" class="small-text" step="any" min="0" max="99" name="tax_rates[0][rate]" placeholder="<?php echo (float)wpinv_get_option( 'tax_rate', 0 ) ;?>" value="<?php echo (float)wpinv_get_option( 'tax_rate', 0 ) ;?>"/></td>
991
                <td class="wpinv_tax_name"><input type="text" class="regular-text" name="tax_rates[0][name]" /></td>
992
				<td><span class="wpinv_remove_tax_rate button-secondary"><?php _e( 'Remove Rate', 'invoicing' ); ?></span></td>
993
			</tr>
994
		<?php endif; ?>
995
        </tbody>
996
        <tfoot><tr><td colspan="5"></td><td class="wpinv_tax_action"><span class="button-secondary" id="wpinv_add_tax_rate"><?php _e( 'Add Tax Rate', 'invoicing' ); ?></span></td></tr></tfoot>
997
	</table>
998
	<?php
999
	echo ob_get_clean();
1000
}
1001
1002
function wpinv_tools_callback($args) {
1003
    global $wpinv_options;
1004
    ob_start(); ?>
1005
    </td><tr>
1006
    <td colspan="2" class="wpinv_tools_tdbox">
1007
    <?php if ( $args['desc'] ) { ?><p><?php echo $args['desc']; ?></p><?php } ?>
1008
    <?php do_action( 'wpinv_tools_before' ); ?>
1009
    <table id="wpinv_tools_table" class="wp-list-table widefat fixed posts">
1010
        <thead>
1011
            <tr>
1012
                <th scope="col" class="wpinv-th-tool"><?php _e( 'Tool', 'invoicing' ); ?></th>
1013
                <th scope="col" class="wpinv-th-desc"><?php _e( 'Description', 'invoicing' ); ?></th>
1014
                <th scope="col" class="wpinv-th-action"><?php _e( 'Action', 'invoicing' ); ?></th>
1015
            </tr>
1016
        </thead>
1017
            <?php do_action( 'wpinv_tools_row' ); ?>
1018
        <tbody>
1019
        </tbody>
1020
    </table>
1021
    <?php do_action( 'wpinv_tools_after' ); ?>
1022
    <?php
1023
    echo ob_get_clean();
1024
}
1025
1026
function wpinv_descriptive_text_callback( $args ) {
1027
	echo wp_kses_post( $args['desc'] );
1028
}
1029
1030
function wpinv_hook_callback( $args ) {
1031
	do_action( 'wpinv_' . $args['id'], $args );
1032
}
1033
1034
function wpinv_set_settings_cap() {
1035
	return wpinv_get_capability();
1036
}
1037
add_filter( 'option_page_capability_wpinv_settings', 'wpinv_set_settings_cap' );
1038
1039
function wpinv_settings_sanitize_input( $value, $key ) {
1040
    if ( $key == 'tax_rate' || $key == 'eu_fallback_rate' ) {
1041
        $value = wpinv_sanitize_amount( $value, 4 );
1042
        $value = $value >= 100 ? 99 : $value;
1043
    }
1044
        
1045
    return $value;
1046
}
1047
add_filter( 'wpinv_settings_sanitize', 'wpinv_settings_sanitize_input', 10, 2 );
1048
1049
function wpinv_on_update_settings( $old_value, $value, $option ) {
1050
    $old = !empty( $old_value['remove_data_on_unistall'] ) ? 1 : '';
1051
    $new = !empty( $value['remove_data_on_unistall'] ) ? 1 : '';
1052
    
1053
    if ( $old != $new ) {
1054
        update_option( 'wpinv_remove_data_on_invoice_unistall', $new );
1055
    }
1056
}
1057
add_action( 'update_option_wpinv_settings', 'wpinv_on_update_settings', 10, 3 );
1058
add_action( 'wpinv_settings_tab_bottom_emails_new_invoice', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1059
add_action( 'wpinv_settings_tab_bottom_emails_cancelled_invoice', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1060
add_action( 'wpinv_settings_tab_bottom_emails_failed_invoice', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1061
add_action( 'wpinv_settings_tab_bottom_emails_onhold_invoice', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1062
add_action( 'wpinv_settings_tab_bottom_emails_processing_invoice', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1063
add_action( 'wpinv_settings_tab_bottom_emails_completed_invoice', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1064
add_action( 'wpinv_settings_tab_bottom_emails_refunded_invoice', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1065
add_action( 'wpinv_settings_tab_bottom_emails_user_invoice', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1066
add_action( 'wpinv_settings_tab_bottom_emails_user_note', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1067
add_action( 'wpinv_settings_tab_bottom_emails_overdue', 'wpinv_settings_tab_bottom_emails', 10, 2 );
1068
1069
function wpinv_settings_tab_bottom_emails( $active_tab, $section ) {
1070
    ?>
1071
    <div class="wpinv-email-wc-row ">
1072
        <div class="wpinv-email-wc-td">
1073
            <h3 class="wpinv-email-wc-title"><?php echo apply_filters( 'wpinv_settings_email_wildcards_title', __( 'Wildcards For Emails', 'invoicing' ) ); ?></h3>
1074
            <p class="wpinv-email-wc-description">
1075
                <?php
1076
                $description = __( 'The following wildcards can be used in email subjects, heading and content:<br>
1077
                    <strong>{site_title} :</strong> Site Title<br>
1078
                    <strong>{name} :</strong> Customer\'s full name<br>
1079
                    <strong>{first_name} :</strong> Customer\'s first name<br>
1080
                    <strong>{last_name} :</strong> Customer\'s last name<br>
1081
                    <strong>{email} :</strong> Customer\'s email address<br>
1082
                    <strong>{invoice_number} :</strong> The invoice number<br>
1083
                    <strong>{invoice_total} :</strong> The invoice total<br>
1084
                    <strong>{invoice_link} :</strong> The invoice link<br>
1085
                    <strong>{invoice_pay_link} :</strong> The payment link<br>
1086
                    <strong>{invoice_date} :</strong> The date the invoice was created<br>
1087
                    <strong>{invoice_due_date} :</strong> The date the invoice is due<br>
1088
                    <strong>{date} :</strong> Today\'s date.<br>
1089
                    <strong>{is_was} :</strong> If due date of invoice is past, displays "was" otherwise displays "is"<br>
1090
                    <strong>{invoice_label} :</strong> Invoices/quotes singular name. Ex: Invoice/Quote<br>', 'invoicing' );
1091
                echo apply_filters('wpinv_settings_email_wildcards_description', $description, $active_tab, $section);
1092
                ?>
1093
            </p>
1094
        </div>
1095
    </div>
1096
    <?php
1097
}