Passed
Push — master ( 56b1f7...a15c21 )
by Brian
04:38 queued 10s
created

wpinv_tools_callback()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 104
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 58
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 104
rs 8.9163

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Contains 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 ( empty( $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 mixed
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 );
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
	$is_wizzard = is_admin() && isset( $_GET['page'] ) && 'gp-setup' == $_GET['page'];
199
200
	if ( isset( $option['desc'] ) && ( ! $is_wizzard && ! empty( $option['help-tip'] ) ) ) {
201
		$tip   = wpinv_clean( $option['desc'] );
202
		$name .= "<span class='dashicons dashicons-editor-help wpi-help-tip' title='$tip'></span>";
203
		unset( $option['desc'] );
204
	}
205
206
    // Loop through all tabs.
207
    add_settings_field(
208
        'wpinv_settings[' . $option['id'] . ']',
209
        $name,
210
        function_exists( $cb ) ? $cb : 'wpinv_missing_callback',
211
        $section,
212
        $section,
213
        array(
214
            'section'     => $section,
215
            'id'          => isset( $option['id'] )          ? $option['id']          : uniqid( 'wpinv-' ),
216
            'desc'        => isset( $option['desc'] )        ? $option['desc']        : '',
217
            'name'        => $name,
218
            'size'        => isset( $option['size'] )        ? $option['size']        : null,
219
            'options'     => isset( $option['options'] )     ? $option['options']     : '',
220
            'selected'    => isset( $option['selected'] )    ? $option['selected']    : null,
221
            'std'         => isset( $option['std'] )         ? $option['std']         : '',
222
            'min'         => isset( $option['min'] )         ? $option['min']         : 0,
223
            'max'         => isset( $option['max'] )         ? $option['max']         : 999999,
224
            'step'        => isset( $option['step'] )        ? $option['step']        : 1,
225
            'placeholder' => isset( $option['placeholder'] ) ? $option['placeholder'] : null,
226
            'allow_blank' => isset( $option['allow_blank'] ) ? $option['allow_blank'] : true,
227
            'readonly'    => isset( $option['readonly'] )    ? $option['readonly']    : false,
228
            'faux'        => isset( $option['faux'] )        ? $option['faux']        : false,
229
            'onchange'    => isset( $option['onchange'] )   ? $option['onchange']     : '',
230
            'custom'      => isset( $option['custom'] )     ? $option['custom']       : '',
231
			'default_content' => isset( $option['default_content'] )     ? $option['default_content']       : '',
232
			'class'       => isset( $option['class'] )     ? $option['class']         : '',
233
			'style'       => isset( $option['style'] )     ? $option['style']         : '',
234
            'cols'        => isset( $option['cols'] ) && (int) $option['cols'] > 0 ? (int) $option['cols'] : 50,
235
            'rows'        => isset( $option['rows'] ) && (int) $option['rows'] > 0 ? (int) $option['rows'] : 5,
236
        )
237
    );
238
239
}
240
241
/**
242
 * Returns an array of all registered settings.
243
 * 
244
 * @return array
245
 */
246
function wpinv_get_registered_settings() {
247
	return array_filter( apply_filters( 'wpinv_registered_settings', wpinv_get_data( 'admin-settings' ) ) );
248
}
249
250
/**
251
 * Returns an array of all integration settings.
252
 * 
253
 * @return array
254
 */
255
function getpaid_get_integration_settings() {
256
    return apply_filters( 'getpaid_integration_settings', array() );
257
}
258
259
/**
260
 * Sanitizes settings before they are saved.
261
 * 
262
 * @return array
263
 */
264
function wpinv_settings_sanitize( $input = array() ) {
265
266
	$wpinv_options = wpinv_get_options();
267
	$raw_referrer  = wp_get_raw_referer();
268
269
    if ( empty( $raw_referrer ) ) {
270
		return array_merge( $wpinv_options, $input );
271
    }
272
273
    wp_parse_str( $raw_referrer, $referrer );
274
275
	if ( in_array( 'gp-setup', $referrer ) ) {
276
		return array_merge( $wpinv_options, $input );
277
	}
278
279
    $settings = wpinv_get_registered_settings();
280
    $tab      = isset( $referrer['tab'] ) ? $referrer['tab'] : 'general';
281
    $section  = isset( $referrer['section'] ) ? $referrer['section'] : 'main';
282
283
    $input = $input ? $input : array();
284
    $input = apply_filters( 'wpinv_settings_tab_' . $tab . '_sanitize', $input );
285
    $input = apply_filters( 'wpinv_settings_' . $tab . '-' . $section . '_sanitize', $input );
286
287
    // Loop through each setting being saved and pass it through a sanitization filter
288
    foreach ( $input as $key => $value ) {
289
290
        // Get the setting type (checkbox, select, etc)
291
        $type = isset( $settings[ $tab ][$section][ $key ]['type'] ) ? $settings[ $tab ][$section][ $key ]['type'] : false;
292
293
        if ( $type ) {
294
            // Field type specific filter
295
            $input[$key] = apply_filters( "wpinv_settings_sanitize_$type", $value, $key );
296
        }
297
298
        // General filter
299
		$input[ $key ] = apply_filters( 'wpinv_settings_sanitize', $input[ $key ], $key );
300
301
		// Key specific filter.
302
		$input[ $key ] = apply_filters( "wpinv_settings_sanitize_$key", $input[ $key ] );
303
    }
304
305
    // Loop through the whitelist and unset any that are empty for the tab being saved
306
    $main_settings    = isset( $settings[ $tab ] ) ? $settings[ $tab ] : array(); // Check for extensions that aren't using new sections
307
    $section_settings = ! empty( $settings[ $tab ][ $section ] ) ? $settings[ $tab ][ $section ] : array();
308
309
    $found_settings   = array_merge( $main_settings, $section_settings );
310
311
    if ( ! empty( $found_settings ) ) {
312
        foreach ( $found_settings as $key => $value ) {
313
314
            // settings used to have numeric keys, now they have keys that match the option ID. This ensures both methods work
315
            if ( is_numeric( $key ) ) {
316
                $key = $value['id'];
317
            }
318
319
            if ( ! isset( $input[ $key ] ) && isset( $wpinv_options[ $key ] ) ) {
320
                unset( $wpinv_options[ $key ] );
321
            }
322
        }
323
    }
324
325
    // Merge our new settings with the existing
326
    $output = array_merge( $wpinv_options, $input );
327
328
    add_settings_error( 'wpinv-notices', '', __( 'Settings updated.', 'invoicing' ), 'updated' );
329
330
    return $output;
331
}
332
add_filter( 'wpinv_settings_sanitize_text', 'trim', 10, 1 );
333
add_filter( 'wpinv_settings_sanitize_tax_rate', 'wpinv_sanitize_amount' );
334
335
function wpinv_settings_sanitize_tax_rates( $input ) {
336
    if( ! wpinv_current_user_can_manage_invoicing() ) {
337
        return $input;
338
    }
339
340
    $new_rates = ! empty( $_POST['tax_rates'] ) ? array_values( $_POST['tax_rates'] ) : array();
341
    $tax_rates = array();
342
343
    foreach ( $new_rates as $rate ) {
344
345
		$rate['rate']    = wpinv_sanitize_amount( $rate['rate'] );
346
		$rate['name']    = sanitize_text_field( $rate['name'] );
347
		$rate['state']   = sanitize_text_field( $rate['state'] );
348
		$rate['country'] = sanitize_text_field( $rate['country'] );
349
		$rate['global']  = empty( $rate['state'] );
350
		$tax_rates[]     = $rate;
351
352
	}
353
354
    update_option( 'wpinv_tax_rates', $tax_rates );
355
356
    return $input;
357
}
358
add_filter( 'wpinv_settings_taxes-rates_sanitize', 'wpinv_settings_sanitize_tax_rates' );
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
367
	if ( count( getpaid_get_integration_settings() ) > 0 ) {
368
		$tabs['integrations'] = __( 'Integrations', 'invoicing' );
369
	}
370
371
    $tabs['privacy']  = __( 'Privacy', 'invoicing' );
372
    $tabs['misc']     = __( 'Misc', 'invoicing' );
373
    $tabs['tools']    = __( 'Tools', 'invoicing' );
374
375
    return apply_filters( 'wpinv_settings_tabs', $tabs );
376
}
377
378
function wpinv_get_settings_tab_sections( $tab = false ) {
379
    $tabs     = false;
380
    $sections = wpinv_get_registered_settings_sections();
381
382
    if( $tab && ! empty( $sections[ $tab ] ) ) {
383
        $tabs = $sections[ $tab ];
384
    }
385
386
    return $tabs;
387
}
388
389
function wpinv_get_registered_settings_sections() {
390
    static $sections = false;
391
392
    if ( false !== $sections ) {
393
        return $sections;
394
    }
395
396
    $sections = array(
397
        'general' => apply_filters( 'wpinv_settings_sections_general', array(
398
            'main' => __( 'General Settings', 'invoicing' ),
399
            'page_section' => __( 'Page Settings', 'invoicing' ),
400
            'currency_section' => __( 'Currency Settings', 'invoicing' ),
401
            'labels' => __( 'Label Texts', 'invoicing' ),
402
        ) ),
403
        'gateways' => apply_filters( 'wpinv_settings_sections_gateways', array(
404
            'main' => __( 'Gateway Settings', 'invoicing' ),
405
        ) ),
406
        'taxes' => apply_filters( 'wpinv_settings_sections_taxes', array(
407
            'main'  => __( 'Tax Settings', 'invoicing' ),
408
			'rates' => __( 'Tax Rates', 'invoicing' ),
409
			'vat'   => __( 'EU VAT Settings', 'invoicing' )
410
        ) ),
411
        'emails' => apply_filters( 'wpinv_settings_sections_emails', array(
412
            'main' => __( 'Email Settings', 'invoicing' ),
413
		) ),
414
415
		'integrations' => wp_list_pluck( getpaid_get_integration_settings(), 'label', 'id' ),
416
417
        'privacy' => apply_filters( 'wpinv_settings_sections_privacy', array(
418
            'main' => __( 'Privacy policy', 'invoicing' ),
419
        ) ),
420
        'misc' => apply_filters( 'wpinv_settings_sections_misc', array(
421
            'main' => __( 'Miscellaneous', 'invoicing' ),
422
            'custom-css' => __( 'Custom CSS', 'invoicing' ),
423
        ) ),
424
        'tools' => apply_filters( 'wpinv_settings_sections_tools', array(
425
            'main' => __( 'Diagnostic Tools', 'invoicing' ),
426
        ) ),
427
    );
428
429
    $sections = apply_filters( 'wpinv_settings_sections', $sections );
430
431
    return $sections;
432
}
433
434
function wpinv_get_pages( $with_slug = false, $default_label = NULL ) {
435
	$pages_options = array();
436
437
	if( $default_label !== NULL && $default_label !== false ) {
438
		$pages_options = array( '' => $default_label ); // Blank option
439
	}
440
441
	$pages = get_pages();
442
	if ( $pages ) {
443
		foreach ( $pages as $page ) {
444
			$title = $with_slug ? $page->post_title . ' (' . $page->post_name . ')' : $page->post_title;
445
            $pages_options[ $page->ID ] = $title;
446
		}
447
	}
448
449
	return $pages_options;
450
}
451
452
function wpinv_header_callback( $args ) {
453
	if ( !empty( $args['desc'] ) ) {
454
        echo $args['desc'];
455
    }
456
}
457
458
function wpinv_hidden_callback( $args ) {
459
460
	$std     = isset( $args['std'] ) ? $args['std'] : '';
461
	$value   = wpinv_get_option( $args['id'], $std );
462
463
	if ( isset( $args['set_value'] ) ) {
464
		$value = $args['set_value'];
465
	}
466
467
	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
468
		$args['readonly'] = true;
469
		$name  = '';
470
	} else {
471
		$name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
472
	}
473
474
	$html = '<input type="hidden" id="wpinv_settings[' . wpinv_sanitize_key( $args['id'] ) . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '" />';
475
    
476
	echo $html;
477
}
478
479
/**
480
 * Displays a checkbox settings callback.
481
 */
482
function wpinv_checkbox_callback( $args ) {
483
484
	$std = isset( $args['std'] ) ? $args['std'] : '';
485
	$std = wpinv_get_option( $args['id'], $std );
486
	$id  = esc_attr( $args['id'] );
487
488
	getpaid_hidden_field( "wpinv_settings[$id]", '0' );
489
	?>
490
		<fieldset>
491
			<label>
492
				<input id="wpinv-settings-<?php echo $id; ?>" name="wpinv_settings[<?php echo $id; ?>]" <?php checked( empty( $std ), false ); ?> value="1" type="checkbox">
493
				<?php echo wp_kses_post( $args['desc'] ); ?>
494
			</label>
495
		</fieldset>
496
	<?php
497
}
498
499
function wpinv_multicheck_callback( $args ) {
500
501
	$sanitize_id = wpinv_sanitize_key( $args['id'] );
502
	$class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
503
504
	if ( ! empty( $args['options'] ) ) {
505
506
		$std     = isset( $args['std'] ) ? $args['std'] : array();
507
		$value   = wpinv_get_option( $args['id'], $std );
508
509
		echo '<div class="wpi-mcheck-rows wpi-mcheck-' . $sanitize_id . $class . '">';
510
        foreach( $args['options'] as $key => $option ):
511
			$sanitize_key = wpinv_sanitize_key( $key );
512
			if ( in_array( $sanitize_key, $value ) ) { 
513
				$enabled = $sanitize_key;
514
			} else { 
515
				$enabled = NULL; 
516
			}
517
			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;';
518
			echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . wp_kses_post( $option ) . '</label></div>';
519
		endforeach;
520
		echo '</div>';
521
		echo '<p class="description">' . $args['desc'] . '</p>';
522
	}
523
}
524
525
function wpinv_payment_icons_callback( $args ) {
526
    
527
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
528
	$value   = wpinv_get_option( $args['id'], false);
529
530
	if ( ! empty( $args['options'] ) ) {
531
		foreach( $args['options'] as $key => $option ) {
532
            $sanitize_key = wpinv_sanitize_key( $key );
533
            
534
			if( empty( $value ) ) {
535
				$enabled = $option;
536
			} else {
537
				$enabled = NULL;
538
			}
539
540
			echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" style="margin-right:10px;line-height:16px;height:16px;display:inline-block;">';
541
542
				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;';
543
544
				if ( wpinv_string_is_image_url( $key ) ) {
545
					echo '<img class="payment-icon" src="' . esc_url( $key ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
546
				} else {
547
					$card = strtolower( str_replace( ' ', '', $option ) );
548
549
					if ( has_filter( 'wpinv_accepted_payment_' . $card . '_image' ) ) {
550
						$image = apply_filters( 'wpinv_accepted_payment_' . $card . '_image', '' );
551
					} else {
552
						$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

552
						$image       = wpinv_locate_template( 'images' . DIRECTORY_SEPARATOR . 'icons' . DIRECTORY_SEPARATOR . $card . '.gif', /** @scrutinizer ignore-type */ false );
Loading history...
553
						$content_dir = WP_CONTENT_DIR;
554
555
						if ( function_exists( 'wp_normalize_path' ) ) {
556
							// Replaces backslashes with forward slashes for Windows systems
557
							$image = wp_normalize_path( $image );
558
							$content_dir = wp_normalize_path( $content_dir );
559
						}
560
561
						$image = str_replace( $content_dir, content_url(), $image );
562
					}
563
564
					echo '<img class="payment-icon" src="' . esc_url( $image ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
565
				}
566
			echo $option . '</label>';
567
		}
568
		echo '<p class="description" style="margin-top:16px;">' . wp_kses_post( $args['desc'] ) . '</p>';
569
	}
570
}
571
572
/**
573
 * Displays a radio settings field.
574
 */
575
function wpinv_radio_callback( $args ) {
576
577
	$std = isset( $args['std'] ) ? $args['std'] : '';
578
	$std = wpinv_get_option( $args['id'], $std );
579
	?>
580
		<fieldset>
581
			<ul id="wpinv-settings-<?php echo esc_attr( $args['id'] ); ?>" style="margin-top: 0;">
582
				<?php foreach( $args['options'] as $key => $option ) : ?>
583
					<li>
584
						<label>
585
							<input name="wpinv_settings[<?php echo esc_attr( $args['id'] ); ?>]" <?php checked( $std, $key ); ?> value="<?php echo esc_attr( $key ); ?>" type="radio">
586
							<?php echo wp_kses_post( $option ); ?>
587
						</label>
588
					</li>
589
				<?php endforeach; ?>
590
			</ul>
591
		</fieldset>
592
	<?php
593
	getpaid_settings_description_callback( $args );
594
}
595
596
/**
597
 * Displays a description if available.
598
 */
599
function getpaid_settings_description_callback( $args ) {
600
601
	if ( ! empty( $args['desc'] ) ) {
602
		$description = wp_kses_post( $args['desc'] );
603
		echo "<p class='description'>$description</p>";
604
	}
605
606
}
607
608
/**
609
 * Displays a list of available gateways.
610
 */
611
function wpinv_gateways_callback() {
612
613
	?>
614
		</td>
615
	</tr>
616
	<tr class="bsui">
617
    	<td colspan="2" class="p-0">
618
			<?php include plugin_dir_path( __FILE__ ) . 'views/html-gateways-edit.php'; ?>
619
620
	<?php
621
}
622
623
function wpinv_gateway_select_callback($args) {
624
    
625
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
626
    $class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
627
	$std     = isset( $args['std'] ) ? $args['std'] : '';
628
	$value   = wpinv_get_option( $args['id'], $std );
629
630
	echo '<select name="wpinv_settings[' . $sanitize_id . ']"" id="wpinv_settings[' . $sanitize_id . ']" class="'.$class.'" >';
631
632
	foreach ( $args['options'] as $key => $option ) :
633
		if ( isset( $args['selected'] ) && $args['selected'] !== null && $args['selected'] !== false ) {
634
            $selected = selected( $key, $args['selected'], false );
635
        } else {
636
            $selected = selected( $key, $value, false );
637
        }
638
		echo '<option value="' . wpinv_sanitize_key( $key ) . '"' . $selected . '>' . esc_html( $option['admin_label'] ) . '</option>';
639
	endforeach;
640
641
	echo '</select>';
642
	echo '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
643
}
644
645
/**
646
 * Generates attributes.
647
 * 
648
 * @param array $args
649
 * @return string
650
 */
651
function wpinv_settings_attrs_helper( $args ) {
652
653
	$value        = isset( $args['std'] ) ? $args['std'] : '';
654
	$id           = esc_attr( $args['id'] );
655
	$placeholder  = esc_attr( $args['placeholder'] );
656
657
	if ( ! empty( $args['faux'] ) ) {
658
		$args['readonly'] = true;
659
		$name             = '';
660
	} else {
661
		$value  = wpinv_get_option( $args['id'], $value );
662
		$name   = "wpinv_settings[$id]";
663
	}
664
665
	$value    = is_scalar( $value ) ? esc_attr( $value ) : '';
666
	$class    = esc_attr( $args['class'] );
667
	$style    = esc_attr( $args['style'] );
668
	$readonly = empty( $args['readonly'] ) ? '' : 'readonly onclick="this.select()"';
669
670
	$onchange = '';
671
    if ( ! empty( $args['onchange'] ) ) {
672
        $onchange = ' onchange="' . esc_attr( $args['onchange'] ) . '"';
673
	}
674
675
	return "name='$name' id='wpinv-settings-$id' style='$style' value='$value' class='$class' placeholder='$placeholder' data-placeholder='$placeholder' $onchange $readonly";
676
}
677
678
/**
679
 * Displays a text input settings callback.
680
 */
681
function wpinv_text_callback( $args ) {
682
683
	$desc = wp_kses_post( $args['desc'] );
684
	$desc = empty( $desc ) ? '' : "<p class='description'>$desc</p>";
685
	$attr = wpinv_settings_attrs_helper( $args );
686
687
	?>
688
		<label style="width: 100%;">
689
			<input type="text" <?php echo $attr; ?>>
690
			<?php echo $desc; ?>
691
		</label>
692
	<?php
693
694
}
695
696
/**
697
 * Displays a number input settings callback.
698
 */
699
function wpinv_number_callback( $args ) {
700
701
	$desc = wp_kses_post( $args['desc'] );
702
	$desc = empty( $desc ) ? '' : "<p class='description'>$desc</p>";
703
	$attr = wpinv_settings_attrs_helper( $args );
704
	$max  = intval( $args['max'] );
705
	$min  = intval( $args['min'] );
706
	$step = floatval( $args['step'] );
707
708
	?>
709
		<label style="width: 100%;">
710
			<input type="number" step="<?php echo $step; ?>" max="<?php echo $max; ?>" min="<?php echo $min; ?>" <?php echo $attr; ?>>
711
			<?php echo $desc; ?>
712
		</label>
713
	<?php
714
715
}
716
717
function wpinv_textarea_callback( $args ) {
718
    
719
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
720
	$std     = isset( $args['std'] ) ? $args['std'] : '';
721
	$value   = wpinv_get_option( $args['id'], $std );
722
723
    $size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
724
    $class = ( isset( $args['class'] ) && ! is_null( $args['class'] ) ) ? $args['class'] : 'large-text';
725
726
	$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>';
727
	$html .= '<br /><label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
728
729
	echo $html;
730
}
731
732
function wpinv_password_callback( $args ) {
733
    
734
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
735
	$std     = isset( $args['std'] ) ? $args['std'] : '';
736
	$value   = wpinv_get_option( $args['id'], $std );
737
738
	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
739
	$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 ) . '"/>';
740
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
741
742
	echo $html;
743
}
744
745
function wpinv_missing_callback($args) {
746
	printf(
747
		__( 'The callback function used for the %s setting is missing.', 'invoicing' ),
748
		'<strong>' . $args['id'] . '</strong>'
749
	);
750
}
751
752
/**
753
 * Displays a number input settings callback.
754
 */
755
function wpinv_select_callback( $args ) {
756
757
	$desc   = wp_kses_post( $args['desc'] );
758
	$desc   = empty( $desc ) ? '' : "<p class='description'>$desc</p>";
759
	$attr   = wpinv_settings_attrs_helper( $args );
760
	$value  = isset( $args['std'] ) ? $args['std'] : '';
761
	$value  = wpinv_get_option( $args['id'], $value );
762
	$rand   = uniqid( 'random_id' );
763
764
	?>
765
		<label style="width: 100%;">
766
			<select <?php echo $attr; ?>>
767
				<?php foreach ( $args['options'] as $option => $name ) : ?>
768
					<option value="<?php echo esc_attr( $option ); ?>" <?php echo selected( $option, $value ); ?>><?php echo wpinv_clean( $name ); ?></option>
0 ignored issues
show
Bug introduced by
Are you sure wpinv_clean($name) of type array|string can be used in echo? ( Ignorable by Annotation )

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

768
					<option value="<?php echo esc_attr( $option ); ?>" <?php echo selected( $option, $value ); ?>><?php echo /** @scrutinizer ignore-type */ wpinv_clean( $name ); ?></option>
Loading history...
769
				<?php endforeach;?>
770
			</select>
771
772
			<?php if ( substr( $args['id'], -5 ) === '_page' && is_numeric( $value ) ) : ?>
773
				<a href="<?php echo get_edit_post_link( $value ); ?>" target="_blank" class="button getpaid-page-setting-edit"><?php _e( 'Edit Page', 'invoicing' ) ?></a>
0 ignored issues
show
Bug introduced by
$value of type string is incompatible with the type WP_Post|integer expected by parameter $id of get_edit_post_link(). ( Ignorable by Annotation )

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

773
				<a href="<?php echo get_edit_post_link( /** @scrutinizer ignore-type */ $value ); ?>" target="_blank" class="button getpaid-page-setting-edit"><?php _e( 'Edit Page', 'invoicing' ) ?></a>
Loading history...
774
			<?php endif; ?>
775
776
			<?php if ( substr( $args['id'], -5 ) === '_page' && ! empty( $args['default_content'] ) ) : ?>
777
				&nbsp;<a href="#TB_inline?&width=400&height=550&inlineId=<?php echo $rand; ?>" class="button thickbox getpaid-page-setting-view-default"><?php _e( 'View Default Content', 'invoicing' ) ?></a>
778
				<div id='<?php echo $rand; ?>' style='display:none;'>
779
					<div>
780
						<h3><?php _e( 'Original Content', 'invoicing' ) ?></h3>
781
						<textarea readonly onclick="this.select()" rows="8" style="width: 100%;"><?php echo gepaid_trim_lines( wp_kses_post( $args['default_content'] ) ); ?></textarea>
782
						<h3><?php _e( 'Current Content', 'invoicing' ) ?></h3>
783
						<textarea readonly onclick="this.select()" rows="8" style="width: 100%;"><?php $_post = get_post( $value ); echo empty( $_post ) ? '' : gepaid_trim_lines( wp_kses_post( $_post->post_content ) ); ?></textarea>
784
					</div>
785
				</div>
786
			<?php endif; ?>
787
788
			<?php echo $desc; ?>
789
		</label>
790
	<?php
791
792
}
793
794
function wpinv_color_select_callback( $args ) {
795
    
796
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
797
	$std     = isset( $args['std'] ) ? $args['std'] : '';
798
	$value   = wpinv_get_option( $args['id'], $std );
799
800
	$html = '<select id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"/>';
801
802
	foreach ( $args['options'] as $option => $color ) {
803
		$selected = selected( $option, $value, false );
804
		$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $color['label'] ) . '</option>';
805
	}
806
807
	$html .= '</select>';
808
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
809
810
	echo $html;
811
}
812
813
function wpinv_rich_editor_callback( $args ) {
814
	global $wp_version;
815
    
816
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
817
818
	$std     = isset( $args['std'] ) ? $args['std'] : '';
819
	$value   = wpinv_get_option( $args['id'], $std );
820
	
821
	if ( ! empty( $args['allow_blank'] ) && empty( $value ) ) {
822
		$value = $std;
823
	}
824
825
	$rows = isset( $args['size'] ) ? $args['size'] : 20;
826
827
	$html = '<div class="getpaid-settings-editor-input">';
828
	if ( $wp_version >= 3.3 && function_exists( 'wp_editor' ) ) {
829
		ob_start();
830
		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 ) );
831
		$html .= ob_get_clean();
832
	} else {
833
		$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>';
834
	}
835
836
	$html .= '</div><br/><label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
837
838
	echo $html;
839
}
840
841
function wpinv_upload_callback( $args ) {
842
    
843
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
844
845
	$std     = isset( $args['std'] ) ? $args['std'] : '';
846
	$value   = wpinv_get_option( $args['id'], $std );
847
848
	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
849
	$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 ) ) . '"/>';
850
	$html .= '<span>&nbsp;<input type="button" class="wpinv_settings_upload_button button-secondary" value="' . __( 'Upload File', 'invoicing' ) . '"/></span>';
851
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
852
853
	echo $html;
854
}
855
856
function wpinv_color_callback( $args ) {
857
858
	$std         = isset( $args['std'] ) ? $args['std'] : '';
859
	$value       = wpinv_get_option( $args['id'], $std );
860
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
861
862
	$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( $std ) . '" />';
863
	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
864
865
	echo $html;
866
}
867
868
function wpinv_country_states_callback($args) {
869
870
	$std     = isset( $args['std'] ) ? $args['std'] : '';
871
	$value   = wpinv_get_option( $args['id'], $std );
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 = selected( $option, $value, 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
/**
898
 * Displays the tax rates edit table.
899
 */
900
function wpinv_tax_rates_callback() {
901
	
902
	?>
903
		</td>
904
	</tr>
905
	<tr class="bsui">
906
    	<td colspan="2" class="p-0">
907
			<?php include plugin_dir_path( __FILE__ ) . 'views/html-tax-rates-edit.php'; ?>
908
909
	<?php
910
911
}
912
913
/**
914
 * Displays a tax rate' edit row.
915
 */
916
function wpinv_tax_rate_callback( $tax_rate, $key, $echo = true ) {
917
	ob_start();
918
919
	$key                      = sanitize_key( $key );
920
	$tax_rate['reduced_rate'] = empty( $tax_rate['reduced_rate'] ) ? 0 : $tax_rate['reduced_rate'];
921
	include plugin_dir_path( __FILE__ ) . 'views/html-tax-rate-edit.php';
922
923
	if ( $echo ) {
924
		echo ob_get_clean();
925
	} else {
926
		return ob_get_clean(); 
927
	}
928
929
}
930
931
932
function wpinv_tools_callback($args) {
933
    ob_start(); ?>
934
    </td><tr>
935
    <td colspan="2" class="wpinv_tools_tdbox">
936
    <?php if ( $args['desc'] ) { ?><p><?php echo $args['desc']; ?></p><?php } ?>
937
    <?php do_action( 'wpinv_tools_before' ); ?>
938
    <table id="wpinv_tools_table" class="wp-list-table widefat fixed posts">
939
        <thead>
940
            <tr>
941
                <th scope="col" class="wpinv-th-tool"><?php _e( 'Tool', 'invoicing' ); ?></th>
942
                <th scope="col" class="wpinv-th-desc"><?php _e( 'Description', 'invoicing' ); ?></th>
943
                <th scope="col" class="wpinv-th-action"><?php _e( 'Action', 'invoicing' ); ?></th>
944
            </tr>
945
        </thead>
946
947
        <tbody>
948
			<tr>
949
                <td><?php _e( 'Check Pages', 'invoicing' );?></td>
950
                <td>
951
                    <small><?php _e( 'Creates any missing GetPaid pages.', 'invoicing' ); ?></small>
952
                </td>
953
                <td>
954
					<a href="<?php
955
						echo esc_url(
956
							wp_nonce_url(
957
								add_query_arg( 'getpaid-admin-action', 'create_missing_pages' ),
958
								'getpaid-nonce',
959
								'getpaid-nonce'
960
							)
961
						);
962
					?>" class="button button-primary"><?php _e('Run', 'invoicing');?></a>
963
                </td>
964
            </tr>
965
			<tr>
966
                <td><?php _e( 'Create Database Tables', 'invoicing' );?></td>
967
                <td>
968
                    <small><?php _e( 'Run this tool to create any missing database tables.', 'invoicing' ); ?></small>
969
                </td>
970
                <td>
971
					<a href="<?php
972
						echo esc_url(
973
							wp_nonce_url(
974
								add_query_arg( 'getpaid-admin-action', 'create_missing_tables' ),
975
								'getpaid-nonce',
976
								'getpaid-nonce'
977
							)
978
						);
979
					?>" class="button button-primary"><?php _e('Run', 'invoicing');?></a>
980
                </td>
981
            </tr>
982
			<tr>
983
                <td><?php _e( 'Migrate old invoices', 'invoicing' );?></td>
984
                <td>
985
                    <small><?php _e( 'If your old invoices were not migrated after updating from Invoicing to GetPaid, you can use this tool to migrate them.', 'invoicing' ); ?></small>
986
                </td>
987
                <td>
988
					<a href="<?php
989
						echo esc_url(
990
							wp_nonce_url(
991
								add_query_arg( 'getpaid-admin-action', 'migrate_old_invoices' ),
992
								'getpaid-nonce',
993
								'getpaid-nonce'
994
							)
995
						);
996
					?>" class="button button-primary"><?php _e('Run', 'invoicing');?></a>
997
                </td>
998
            </tr>
999
1000
			<tr>
1001
                <td><?php _e( 'Recalculate Discounts', 'invoicing' );?></td>
1002
                <td>
1003
                    <small><?php _e( 'Recalculate discounts for existing invoices that have discount codes but are not discounted.', 'invoicing' ); ?></small>
1004
                </td>
1005
                <td>
1006
					<a href="<?php
1007
						echo esc_url(
1008
							wp_nonce_url(
1009
								add_query_arg( 'getpaid-admin-action', 'recalculate_discounts' ),
1010
								'getpaid-nonce',
1011
								'getpaid-nonce'
1012
							)
1013
						);
1014
					?>" class="button button-primary"><?php _e( 'Run', 'invoicing' );?></a>
1015
                </td>
1016
            </tr>
1017
1018
			<tr>
1019
                <td><?php _e( 'Set-up Wizard', 'invoicing' );?></td>
1020
                <td>
1021
                    <small><?php _e( 'Launch the quick set-up wizard.', 'invoicing' ); ?></small>
1022
                </td>
1023
                <td>
1024
					<a href="<?php
1025
						echo esc_url( admin_url( 'index.php?page=gp-setup' ) );
1026
					?>" class="button button-primary"><?php _e( 'Launch', 'invoicing' );?></a>
1027
                </td>
1028
            </tr>
1029
1030
			<?php do_action( 'wpinv_tools_row' ); ?>
1031
        </tbody>
1032
    </table>
1033
    <?php do_action( 'wpinv_tools_after' ); ?>
1034
    <?php
1035
    echo ob_get_clean();
1036
}
1037
1038
1039
function wpinv_descriptive_text_callback( $args ) {
1040
	echo wp_kses_post( $args['desc'] );
1041
}
1042
1043
function wpinv_raw_html_callback( $args ) {
1044
	echo $args['desc'];
1045
}
1046
1047
function wpinv_hook_callback( $args ) {
1048
	do_action( 'wpinv_' . $args['id'], $args );
1049
}
1050
1051
function wpinv_set_settings_cap() {
1052
	return wpinv_get_capability();
1053
}
1054
add_filter( 'option_page_capability_wpinv_settings', 'wpinv_set_settings_cap' );
1055
1056
1057
function wpinv_on_update_settings( $old_value, $value, $option ) {
1058
    $old = !empty( $old_value['remove_data_on_unistall'] ) ? 1 : '';
1059
    $new = !empty( $value['remove_data_on_unistall'] ) ? 1 : '';
1060
    
1061
    if ( $old != $new ) {
1062
        update_option( 'wpinv_remove_data_on_invoice_unistall', $new );
1063
    }
1064
}
1065
add_action( 'update_option_wpinv_settings', 'wpinv_on_update_settings', 10, 3 );
1066
1067
/**
1068
 * Returns the merge tags help text.
1069
 *
1070
 * @since    2.1.8
1071
 * 
1072
 * @return string
1073
 */
1074
function wpinv_get_merge_tags_help_text( $subscription = false ) {
1075
1076
	$url  = $subscription ? 'https://gist.github.com/picocodes/3d213982d57c34edf7a46fd3f0e8583e' : 'https://gist.github.com/picocodes/43bdc4d4bbba844534b2722e2af0b58f';
1077
	$link = sprintf(
1078
		'<strong><a href="%s" target="_blank">%s</a></strong>',
1079
		$url,
1080
		esc_html__( 'View available merge tags.', 'wpinv-quotes' )
1081
	);
1082
1083
	$description = esc_html__( 'The content of the email (Merge Tags and HTML are allowed).', 'invoicing' );
1084
1085
	return "$description $link";
1086
1087
}
1088