Passed
Push — master ( e67cdc...5aad15 )
by Stiofan
10:57
created

wpinv_get_pages()   B

Complexity

Conditions 11
Paths 65

Size

Total Lines 61
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 26
nop 2
dl 0
loc 61
rs 7.3166
c 0
b 0
f 0
nc 65

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Contains 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
    return $defaults;
32
33
}
34
35
/**
36
 * Retrieves all settings.
37
 *
38
 * @return array
39
 */
40
function wpinv_get_options() {
41
    global $wpinv_options;
42
43
    // Try fetching the saved options.
44
    if ( empty( $wpinv_options ) ) {
45
        $wpinv_options = get_option( 'wpinv_settings' );
46
    }
47
48
    // If that fails, don't fetch the default settings to prevent a loop.
49
    if ( ! is_array( $wpinv_options ) ) {
50
        $wpinv_options = array();
51
    }
52
53
    return $wpinv_options;
54
}
55
56
/**
57
 * Retrieves a single setting.
58
 *
59
 * @param string $key the setting key.
60
 * @param mixed $default The default value to use if the setting has not been set.
61
 * @return mixed
62
 */
63
function wpinv_get_option( $key = '', $default = false ) {
64
65
    $options = wpinv_get_options();
66
    $value   = isset( $options[ $key ] ) ? $options[ $key ] : $default;
67
    $value   = apply_filters( 'wpinv_get_option', $value, $key, $default );
68
69
    return apply_filters( 'wpinv_get_option_' . $key, $value, $key, $default );
70
}
71
72
/**
73
 * Updates all settings.
74
 *
75
 * @param array $options the new options.
76
 * @return bool
77
 */
78
function wpinv_update_options( $options ) {
79
    global $wpinv_options;
80
81
    // update the option.
82
    if ( is_array( $options ) && update_option( 'wpinv_settings', $options ) ) {
83
        $wpinv_options = $options;
84
        return true;
85
    }
86
87
    return false;
88
}
89
90
/**
91
 * Updates a single setting.
92
 *
93
 * @param string $key the setting key.
94
 * @param mixed $value The setting value.
95
 * @return bool
96
 */
97
function wpinv_update_option( $key = '', $value = false ) {
98
99
    // If no key, exit.
100
    if ( empty( $key ) ) {
101
        return false;
102
    }
103
104
    // Maybe delete the option instead.
105
    if ( is_null( $value ) ) {
106
        return wpinv_delete_option( $key );
107
    }
108
109
    // Prepare the new options.
110
    $options         = wpinv_get_options();
111
    $options[ $key ] = apply_filters( 'wpinv_update_option', $value, $key );
112
113
    // Save the new options.
114
    return wpinv_update_options( $options );
115
116
}
117
118
/**
119
 * Deletes a single setting.
120
 *
121
 * @param string $key the setting key.
122
 * @return bool
123
 */
124
function wpinv_delete_option( $key = '' ) {
125
126
    // If no key, exit
127
    if ( empty( $key ) ) {
128
        return false;
129
    }
130
131
    $options = wpinv_get_options();
132
133
    if ( isset( $options[ $key ] ) ) {
134
        unset( $options[ $key ] );
135
        return wpinv_update_options( $options );
136
    }
137
138
    return true;
139
140
}
141
142
/**
143
 * Register settings after admin inits.
144
 *
145
 */
146
function wpinv_register_settings() {
147
	do_action( 'getpaid_before_register_settings' );
148
149
    // Loop through all tabs.
150
    foreach ( wpinv_get_registered_settings() as $tab => $sections ) {
151
152
        // In each tab, loop through sections.
153
        foreach ( $sections as $section => $settings ) {
154
155
            // Check for backwards compatibility
156
            $section_tabs = wpinv_get_settings_tab_sections( $tab );
157
            if ( ! is_array( $section_tabs ) || ! array_key_exists( $section, $section_tabs ) ) {
158
                $section = 'main';
159
                $settings = $sections;
160
            }
161
162
			do_action( "getpaid_register_{$tab}_{$section}" );
163
164
            // Register the setting section.
165
            add_settings_section(
166
                'wpinv_settings_' . $tab . '_' . $section,
167
                __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...
168
                '__return_false',
169
                'wpinv_settings_' . $tab . '_' . $section
170
            );
171
172
            foreach ( $settings as $option ) {
173
                if ( ! empty( $option['id'] ) ) {
174
                    wpinv_register_settings_option( $tab, $section, $option );
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
	do_action( 'getpaid_after_register_settings' );
184
}
185
add_action( 'admin_init', 'wpinv_register_settings' );
186
187
/**
188
 * Register a single settings option.
189
 *
190
 * @param string $tab
191
 * @param string $section
192
 * @param string $option
193
 *
194
 */
195
function wpinv_register_settings_option( $tab, $section, $option ) {
196
197
    $name       = isset( $option['name'] ) ? $option['name'] : '';
198
    $cb         = "wpinv_{$option['type']}_callback";
199
    $section    = "wpinv_settings_{$tab}_$section";
200
	$is_wizzard = is_admin() && isset( $_GET['page'] ) && 'gp-setup' == $_GET['page'];
201
202
	if ( isset( $option['desc'] ) && ( ! $is_wizzard && ! empty( $option['help-tip'] ) ) ) {
203
		$tip   = wpinv_clean( $option['desc'] );
204
		$name .= "<span class='dashicons dashicons-editor-help wpi-help-tip' title='$tip'></span>";
205
		unset( $option['desc'] );
206
	}
207
208
    // Loop through all tabs.
209
    add_settings_field(
210
        'wpinv_settings[' . $option['id'] . ']',
211
        $name,
212
        function_exists( $cb ) ? $cb : 'wpinv_missing_callback',
213
        $section,
214
        $section,
215
        array(
216
            'section'         => $section,
217
            'id'              => isset( $option['id'] ) ? $option['id'] : uniqid( 'wpinv-' ),
218
            'desc'            => isset( $option['desc'] ) ? $option['desc'] : '',
219
            'name'            => $name,
220
            'size'            => isset( $option['size'] ) ? $option['size'] : null,
221
            'options'         => isset( $option['options'] ) ? $option['options'] : '',
222
            'selected'        => isset( $option['selected'] ) ? $option['selected'] : null,
223
            'std'             => isset( $option['std'] ) ? $option['std'] : '',
224
            'min'             => isset( $option['min'] ) ? $option['min'] : 0,
225
            'max'             => isset( $option['max'] ) ? $option['max'] : 999999,
226
            'step'            => isset( $option['step'] ) ? $option['step'] : 1,
227
            'placeholder'     => isset( $option['placeholder'] ) ? $option['placeholder'] : null,
228
            'allow_blank'     => isset( $option['allow_blank'] ) ? $option['allow_blank'] : true,
229
            'readonly'        => isset( $option['readonly'] ) ? $option['readonly'] : false,
230
            'faux'            => isset( $option['faux'] ) ? $option['faux'] : false,
231
            'onchange'        => isset( $option['onchange'] ) ? $option['onchange'] : '',
232
            'custom'          => isset( $option['custom'] ) ? $option['custom'] : '',
233
			'default_content' => isset( $option['default_content'] ) ? $option['default_content'] : '',
234
			'class'           => isset( $option['class'] ) ? $option['class'] : '',
235
			'style'           => isset( $option['style'] ) ? $option['style'] : '',
236
            'cols'            => isset( $option['cols'] ) && (int) $option['cols'] > 0 ? (int) $option['cols'] : 50,
237
            'rows'            => isset( $option['rows'] ) && (int) $option['rows'] > 0 ? (int) $option['rows'] : 5,
238
        )
239
    );
240
241
}
242
243
/**
244
 * Returns an array of all registered settings.
245
 *
246
 * @return array
247
 */
248
function wpinv_get_registered_settings() {
249
	return array_filter( apply_filters( 'wpinv_registered_settings', wpinv_get_data( 'admin-settings' ) ) );
250
}
251
252
/**
253
 * Returns an array of all integration settings.
254
 *
255
 * @return array
256
 */
257
function getpaid_get_integration_settings() {
258
    return apply_filters( 'getpaid_integration_settings', array() );
259
}
260
261
/**
262
 * Sanitizes settings before they are saved.
263
 *
264
 * @return array
265
 */
266
function wpinv_settings_sanitize( $input = array() ) {
267
268
	$wpinv_options = wpinv_get_options();
269
	$raw_referrer  = wp_get_raw_referer();
270
271
    if ( empty( $raw_referrer ) ) {
272
		return array_merge( $wpinv_options, $input );
273
    }
274
275
    wp_parse_str( $raw_referrer, $referrer );
276
277
	if ( in_array( 'gp-setup', $referrer ) ) {
278
		return array_merge( $wpinv_options, $input );
279
	}
280
281
    $settings = wpinv_get_registered_settings();
282
    $tab      = isset( $referrer['tab'] ) ? $referrer['tab'] : 'general';
283
    $section  = isset( $referrer['section'] ) ? $referrer['section'] : 'main';
284
285
    $input = $input ? $input : array();
286
    $input = apply_filters( 'wpinv_settings_tab_' . $tab . '_sanitize', $input );
287
    $input = apply_filters( 'wpinv_settings_' . $tab . '-' . $section . '_sanitize', $input );
288
289
    // Loop through each setting being saved and pass it through a sanitization filter
290
    foreach ( $input as $key => $value ) {
291
292
        // Get the setting type (checkbox, select, etc)
293
        $type = isset( $settings[ $tab ][ $section ][ $key ]['type'] ) ? $settings[ $tab ][ $section ][ $key ]['type'] : false;
294
295
        if ( $type ) {
296
            // Field type specific filter
297
            $input[ $key ] = apply_filters( "wpinv_settings_sanitize_$type", $value, $key );
298
        }
299
300
        // General filter
301
		$input[ $key ] = apply_filters( 'wpinv_settings_sanitize', $input[ $key ], $key );
302
303
		// Key specific filter.
304
		$input[ $key ] = apply_filters( "wpinv_settings_sanitize_$key", $input[ $key ] );
305
    }
306
307
    // Loop through the whitelist and unset any that are empty for the tab being saved
308
    $main_settings    = isset( $settings[ $tab ] ) ? $settings[ $tab ] : array(); // Check for extensions that aren't using new sections
309
    $section_settings = ! empty( $settings[ $tab ][ $section ] ) ? $settings[ $tab ][ $section ] : array();
310
311
    $found_settings   = array_merge( $main_settings, $section_settings );
312
313
    if ( ! empty( $found_settings ) ) {
314
        foreach ( $found_settings as $key => $value ) {
315
316
            // settings used to have numeric keys, now they have keys that match the option ID. This ensures both methods work
317
            if ( is_numeric( $key ) ) {
318
                $key = $value['id'];
319
            }
320
321
            if ( ! isset( $input[ $key ] ) && isset( $wpinv_options[ $key ] ) ) {
322
                unset( $wpinv_options[ $key ] );
323
            }
324
        }
325
    }
326
327
    // Merge our new settings with the existing
328
    $output = array_merge( $wpinv_options, $input );
329
330
    add_settings_error( 'wpinv-notices', '', __( 'Settings updated.', 'invoicing' ), 'updated' );
331
332
    return $output;
333
}
334
add_filter( 'wpinv_settings_sanitize_text', 'trim', 10, 1 );
335
add_filter( 'wpinv_settings_sanitize_tax_rate', 'wpinv_sanitize_amount' );
336
337
function wpinv_settings_sanitize_tax_rates( $input ) {
338
    if ( ! wpinv_current_user_can_manage_invoicing() ) {
339
        return $input;
340
    }
341
342
    $new_rates = ! empty( $_POST['tax_rates'] ) ? wp_kses_post_deep( array_values( $_POST['tax_rates'] ) ) : array();
343
    $tax_rates = array();
344
345
    foreach ( $new_rates as $rate ) {
346
347
		$rate['rate']    = wpinv_sanitize_amount( $rate['rate'] );
348
		$rate['name']    = sanitize_text_field( $rate['name'] );
349
		$rate['state']   = sanitize_text_field( $rate['state'] );
350
		$rate['country'] = sanitize_text_field( $rate['country'] );
351
		$rate['global']  = empty( $rate['state'] );
352
		$tax_rates[]     = $rate;
353
354
	}
355
356
    update_option( 'wpinv_tax_rates', $tax_rates );
357
358
    return $input;
359
}
360
add_filter( 'wpinv_settings_taxes-rates_sanitize', 'wpinv_settings_sanitize_tax_rates' );
361
362
function wpinv_settings_sanitize_tax_rules( $input ) {
363
    if ( ! wpinv_current_user_can_manage_invoicing() ) {
364
        return $input;
365
    }
366
367
	if ( empty( $_POST['wpinv_tax_rules_nonce'] ) || ! wp_verify_nonce( $_POST['wpinv_tax_rules_nonce'], 'wpinv_tax_rules' ) ) {
368
		return $input;
369
	}
370
371
    $new_rules = ! empty( $_POST['tax_rules'] ) ? wp_kses_post_deep( array_values( $_POST['tax_rules'] ) ) : array();
372
    $tax_rules = array();
373
374
    foreach ( $new_rules as $rule ) {
375
376
		$rule['key']      = sanitize_title_with_dashes( $rule['key'] );
377
		$rule['label']    = sanitize_text_field( $rule['label'] );
378
		$rule['tax_base'] = sanitize_text_field( $rule['tax_base'] );
379
		$tax_rules[]      = $rule;
380
381
	}
382
383
    update_option( 'wpinv_tax_rules', $tax_rules );
384
385
    return $input;
386
}
387
add_filter( 'wpinv_settings_taxes-rules_sanitize', 'wpinv_settings_sanitize_tax_rules' );
388
389
function wpinv_get_settings_tabs() {
390
    $tabs             = array();
391
    $tabs['general']  = __( 'General', 'invoicing' );
392
    $tabs['gateways'] = __( 'Payment Gateways', 'invoicing' );
393
    $tabs['taxes']    = __( 'Taxes', 'invoicing' );
394
	$tabs['emails']   = __( 'Emails', 'invoicing' );
395
396
	if ( count( getpaid_get_integration_settings() ) > 0 ) {
397
		$tabs['integrations'] = __( 'Integrations', 'invoicing' );
398
	}
399
400
    $tabs['privacy']  = __( 'Privacy', 'invoicing' );
401
    $tabs['misc']     = __( 'Misc', 'invoicing' );
402
    $tabs['tools']    = __( 'Tools', 'invoicing' );
403
404
    return apply_filters( 'wpinv_settings_tabs', $tabs );
405
}
406
407
function wpinv_get_settings_tab_sections( $tab = false ) {
408
    $tabs     = false;
409
    $sections = wpinv_get_registered_settings_sections();
410
411
    if ( $tab && ! empty( $sections[ $tab ] ) ) {
412
        $tabs = $sections[ $tab ];
413
    }
414
415
    return $tabs;
416
}
417
418
function wpinv_get_registered_settings_sections() {
419
    static $sections = false;
420
421
    if ( false !== $sections ) {
422
        return $sections;
423
    }
424
425
    $sections = array(
426
        'general'      => apply_filters(
427
            'wpinv_settings_sections_general',
428
            array(
429
				'main'             => __( 'General Settings', 'invoicing' ),
430
				'page_section'     => __( 'Page Settings', 'invoicing' ),
431
				'currency_section' => __( 'Currency Settings', 'invoicing' ),
432
				'labels'           => __( 'Label Texts', 'invoicing' ),
433
            )
434
        ),
435
        'gateways'     => apply_filters(
436
            'wpinv_settings_sections_gateways',
437
            array(
438
				'main' => __( 'Gateway Settings', 'invoicing' ),
439
            )
440
        ),
441
        'taxes'        => apply_filters(
442
            'wpinv_settings_sections_taxes',
443
            array(
444
				'main'  => __( 'Tax Settings', 'invoicing' ),
445
				'rules' => __( 'Tax Rules', 'invoicing' ),
446
				'rates' => __( 'Tax Rates', 'invoicing' ),
447
				'vat'   => __( 'EU VAT Settings', 'invoicing' ),
448
            )
449
        ),
450
        'emails'       => apply_filters(
451
            'wpinv_settings_sections_emails',
452
            array(
453
				'main' => __( 'Email Settings', 'invoicing' ),
454
            )
455
        ),
456
457
		'integrations' => wp_list_pluck( getpaid_get_integration_settings(), 'label', 'id' ),
458
459
        'privacy'      => apply_filters(
460
            'wpinv_settings_sections_privacy',
461
            array(
462
				'main' => __( 'Privacy policy', 'invoicing' ),
463
            )
464
        ),
465
        'misc'         => apply_filters(
466
            'wpinv_settings_sections_misc',
467
            array(
468
				'main'       => __( 'Miscellaneous', 'invoicing' ),
469
				'custom-css' => __( 'Custom CSS', 'invoicing' ),
470
            )
471
        ),
472
        'tools'        => apply_filters(
473
            'wpinv_settings_sections_tools',
474
            array(
475
				'main' => __( 'Diagnostic Tools', 'invoicing' ),
476
            )
477
        ),
478
    );
479
480
    $sections = apply_filters( 'wpinv_settings_sections', $sections );
481
482
    return $sections;
483
}
484
485
function wpinv_get_pages( $with_slug = false, $default_label = null ) {
486
487
    global $gp_tmpl_page_options,$wpdb;
488
489
    if ( ! empty( $gp_tmpl_page_options ) ) {
490
        return $gp_tmpl_page_options;
491
    }
492
493
    $exclude_pages = array();
494
    if ( $page_on_front = get_option( 'page_on_front' ) ) {
495
        $exclude_pages[] = $page_on_front;
496
    }
497
498
    if ( $page_for_posts = get_option( 'page_for_posts' ) ) {
499
        $exclude_pages[] = $page_for_posts;
500
    }
501
502
    $exclude_pages_placeholders = '';
503
    if ( ! empty( $exclude_pages ) ) {
504
        // Sanitize the array of excluded pages and implode it for the SQL query
505
        $exclude_pages_placeholders = implode(',', array_fill(0, count($exclude_pages), '%d'));
506
    }
507
508
    // Prepare the base SQL query, including child_of = 0 (only root-level pages)
509
    $sql = "
510
		SELECT ID, post_title, post_name
511
		FROM $wpdb->posts
512
		WHERE post_type = 'page'
513
		AND post_status = 'publish'
514
		AND post_parent = 0 
515
	";
516
517
    // Add the exclusion if there are pages to exclude
518
    if ( ! empty( $exclude_pages ) ) {
519
        $sql .= " AND ID NOT IN ($exclude_pages_placeholders)";
520
    }
521
522
    // Add sorting
523
    $sql .= " ORDER BY post_title ASC";
524
525
    // Prepare the SQL query to include the excluded pages
526
    $pages = $wpdb->get_results( $wpdb->prepare( $sql, ...$exclude_pages ) );
527
528
	$pages_options = array();
529
530
    if ( $pages ) {
531
        foreach ( $pages as $page ) {
532
            $title = $with_slug ? $page->post_title . ' (' . $page->post_name . ')' : $page->post_title;
533
            $pages_options[ $page->ID ] = $title;
534
        }
535
    }
536
537
538
539
    $gp_tmpl_page_options = $pages_options;
540
541
    if ( $default_label !== null && $default_label !== false ) {
542
        $pages_options = array( '' => $default_label ) + $pages_options; // Blank option
543
    }
544
545
	return $pages_options;
546
}
547
548
function wpinv_header_callback( $args ) {
549
	if ( ! empty( $args['desc'] ) ) {
550
        echo wp_kses_post( $args['desc'] );
551
    }
552
}
553
554
function wpinv_hidden_callback( $args ) {
555
556
	$std     = isset( $args['std'] ) ? $args['std'] : '';
557
	$value   = wpinv_get_option( $args['id'], $std );
558
559
	if ( isset( $args['set_value'] ) ) {
560
		$value = $args['set_value'];
561
	}
562
563
	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
564
		$args['readonly'] = true;
565
		$name  = '';
566
	} else {
567
		$name = 'wpinv_settings[' . esc_attr( $args['id'] ) . ']';
568
	}
569
570
	echo '<input type="hidden" id="wpinv_settings[' . esc_attr( $args['id'] ) . ']" name="' . esc_attr( $name ) . '" value="' . esc_attr( stripslashes( $value ) ) . '" />';
571
572
}
573
574
/**
575
 * Displays a checkbox settings callback.
576
 */
577
function wpinv_checkbox_callback( $args ) {
578
579
	$std = isset( $args['std'] ) ? $args['std'] : '';
580
	$std = wpinv_get_option( $args['id'], $std );
581
	$id  = esc_attr( $args['id'] );
582
583
	getpaid_hidden_field( "wpinv_settings[$id]", '0' );
584
	?>
585
		<label>
586
			<input id="wpinv-settings-<?php echo esc_attr( $id ); ?>" name="wpinv_settings[<?php echo esc_attr( $id ); ?>]" <?php checked( empty( $std ), false ); ?> value="1" type="checkbox" />
587
			<?php echo wp_kses_post( $args['desc'] ); ?>
588
		</label>
589
	<?php
590
}
591
592
function wpinv_multicheck_callback( $args ) {
593
594
	$sanitize_id = wpinv_sanitize_key( $args['id'] );
595
	$class = ! empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
596
597
	if ( ! empty( $args['options'] ) ) {
598
599
		$std     = isset( $args['std'] ) ? $args['std'] : array();
600
		$value   = wpinv_get_option( $args['id'], $std );
601
602
		echo '<div class="wpi-mcheck-rows wpi-mcheck-' . esc_attr( $sanitize_id . $class ) . '">';
603
        foreach ( $args['options'] as $key => $option ) :
604
			$sanitize_key = esc_attr( wpinv_sanitize_key( $key ) );
605
			if ( in_array( $sanitize_key, $value ) ) {
606
				$enabled = $sanitize_key;
607
			} else {
608
				$enabled = null;
609
			}
610
			echo '<div class="wpi-mcheck-row"><input name="wpinv_settings[' . esc_attr( $sanitize_id ) . '][' . esc_attr( $sanitize_key ) . ']" id="wpinv_settings[' . esc_attr( $sanitize_id ) . '][' . esc_attr( $sanitize_key ) . ']" type="checkbox" value="' . esc_attr( $sanitize_key ) . '" ' . checked( $sanitize_key, $enabled, false ) . '/>&nbsp;';
611
			echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . '][' . esc_attr( $sanitize_key ) . ']">' . wp_kses_post( $option ) . '</label></div>';
612
		endforeach;
613
		echo '</div>';
614
		echo '<p class="description">' . wp_kses_post( $args['desc'] ) . '</p>';
615
	}
616
}
617
618
function wpinv_payment_icons_callback( $args ) {
619
620
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
621
	$value   = wpinv_get_option( $args['id'], false );
622
623
	if ( ! empty( $args['options'] ) ) {
624
		foreach ( $args['options'] as $key => $option ) {
625
            $sanitize_key = wpinv_sanitize_key( $key );
626
627
			if ( empty( $value ) ) {
628
				$enabled = $option;
629
			} else {
630
				$enabled = null;
631
			}
632
633
			echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . '][' . esc_attr( $sanitize_key ) . ']" style="margin-right:10px;line-height:16px;height:16px;display:inline-block;">';
634
635
				echo '<input name="wpinv_settings[' . esc_attr( $sanitize_id ) . '][' . esc_attr( $sanitize_key ) . ']" id="wpinv_settings[' . esc_attr( $sanitize_id ) . '][' . esc_attr( $sanitize_key ) . ']" type="checkbox" value="' . esc_attr( $option ) . '" ' . checked( $option, $enabled, false ) . '/>&nbsp;';
636
637
				if ( wpinv_string_is_image_url( $key ) ) {
638
				echo '<img class="payment-icon" src="' . esc_url( $key ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
639
				} else {
640
				$card = strtolower( str_replace( ' ', '', $option ) );
641
642
				if ( has_filter( 'wpinv_accepted_payment_' . $card . '_image' ) ) {
643
					$image = apply_filters( 'wpinv_accepted_payment_' . $card . '_image', '' );
644
					} else {
645
					$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

645
					$image       = wpinv_locate_template( 'images' . DIRECTORY_SEPARATOR . 'icons' . DIRECTORY_SEPARATOR . $card . '.gif', /** @scrutinizer ignore-type */ false );
Loading history...
646
					$content_dir = WP_CONTENT_DIR;
647
648
					if ( function_exists( 'wp_normalize_path' ) ) {
649
						// Replaces backslashes with forward slashes for Windows systems
650
						$image = wp_normalize_path( $image );
651
						$content_dir = wp_normalize_path( $content_dir );
652
						}
653
654
					$image = str_replace( $content_dir, content_url(), $image );
655
					}
656
657
				echo '<img class="payment-icon" src="' . esc_url( $image ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
658
				}
659
			echo wp_kses_post( $option ) . '</label>';
660
		}
661
		echo '<p class="description" style="margin-top:16px;">' . wp_kses_post( $args['desc'] ) . '</p>';
662
	}
663
}
664
665
/**
666
 * Displays a radio settings field.
667
 */
668
function wpinv_radio_callback( $args ) {
669
670
	$std = isset( $args['std'] ) ? $args['std'] : '';
671
	$std = wpinv_get_option( $args['id'], $std );
672
	?>
673
		<fieldset>
674
			<ul id="wpinv-settings-<?php echo esc_attr( $args['id'] ); ?>" style="margin-top: 0;">
675
				<?php foreach ( $args['options'] as $key => $option ) : ?>
676
					<li>
677
						<label>
678
							<input name="wpinv_settings[<?php echo esc_attr( $args['id'] ); ?>]" <?php checked( $std, $key ); ?> value="<?php echo esc_attr( $key ); ?>" type="radio">
679
							<?php echo wp_kses_post( $option ); ?>
680
						</label>
681
					</li>
682
				<?php endforeach; ?>
683
			</ul>
684
		</fieldset>
685
	<?php
686
	getpaid_settings_description_callback( $args );
687
}
688
689
/**
690
 * Displays a description if available.
691
 */
692
function getpaid_settings_description_callback( $args ) {
693
694
	if ( ! empty( $args['desc'] ) ) {
695
		$description = $args['desc'];
696
		echo wp_kses_post( "<p class='description'>$description</p>" );
697
	}
698
699
}
700
701
/**
702
 * Displays a list of available gateways.
703
 */
704
function wpinv_gateways_callback() {
705
706
	?>
707
		</td>
708
	</tr>
709
	<tr class="bsui">
710
    	<td colspan="2" class="p-0">
711
			<?php include plugin_dir_path( __FILE__ ) . 'views/html-gateways-edit.php'; ?>
712
713
	<?php
714
}
715
716
function wpinv_gateway_select_callback( $args ) {
717
718
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
719
    $class = ! empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
720
	$std     = isset( $args['std'] ) ? $args['std'] : '';
721
	$value   = wpinv_get_option( $args['id'], $std );
722
723
	echo '<select name="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"" id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" class="' . esc_attr( $class ) . '" >';
724
725
	foreach ( $args['options'] as $key => $option ) :
726
727
		echo '<option value="' . esc_attr( $key ) . '" ';
728
729
		if ( isset( $args['selected'] ) && $args['selected'] !== null && $args['selected'] !== false ) {
730
            selected( $key, $args['selected'] );
731
        } else {
732
            selected( $key, $value );
733
        }
734
735
		echo '>' . esc_html( $option['admin_label'] ) . '</option>';
736
	endforeach;
737
738
	echo '</select>';
739
	echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
740
}
741
742
/**
743
 * Generates attributes.
744
 *
745
 * @param array $args
746
 * @return string
747
 */
748
function wpinv_settings_attrs_helper( $args ) {
749
750
	$value = isset( $args['std'] ) ? $args['std'] : '';
751
	$id    = esc_attr( $args['id'] );
752
	$value = is_scalar( $value ) ? $value : '';
753
754
	$attrs = array(
755
		'name'     => ! empty( $args['faux'] ) ? false : "wpinv_settings[$id]",
756
		'readonly' => ! empty( $args['faux'] ),
757
		'value'    => ! empty( $args['faux'] ) ? $value : wpinv_get_option( $args['id'], $value ),
758
		'id'       => 'wpinv-settings-' . $args['id'],
759
		'style'    => $args['style'],
760
		'class'    => $args['class'],
761
		'placeholder' => $args['placeholder'],
762
		'data-placeholder' => $args['placeholder'],
763
	);
764
765
	if ( ! empty( $args['onchange'] ) ) {
766
		$attrs['onchange'] = $args['onchange'];
767
	}
768
769
	foreach ( $attrs as $key => $value ) {
770
771
		if ( false === $value ) {
772
			continue;
773
		}
774
775
		if ( true === $value ) {
776
			echo ' ' . esc_attr( $key );
777
		} else {
778
			echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
779
		}
780
781
	}
782
783
}
784
785
/**
786
 * Displays a text input settings callback.
787
 */
788
function wpinv_text_callback( $args ) {
789
790
	?>
791
		<label style="width: 100%;">
792
			<input type="text" <?php wpinv_settings_attrs_helper( $args ); ?>>
793
			<?php getpaid_settings_description_callback( $args ); ?>
794
		</label>
795
	<?php
796
797
}
798
799
/**
800
 * Displays a number input settings callback.
801
 */
802
function wpinv_number_callback( $args ) {
803
804
	?>
805
		<label style="width: 100%;">
806
			<input type="number" step="<?php echo esc_attr( $args['step'] ); ?>" max="<?php echo intval( $args['max'] ); ?>" min="<?php echo intval( $args['min'] ); ?>" <?php wpinv_settings_attrs_helper( $args ); ?>>
807
			<?php getpaid_settings_description_callback( $args ); ?>
808
		</label>
809
	<?php
810
811
}
812
813
function wpinv_textarea_callback( $args ) {
814
815
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
816
	$std     = isset( $args['std'] ) ? $args['std'] : '';
817
	$value   = wpinv_get_option( $args['id'], $std );
818
819
    $size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
820
    $class = ( isset( $args['class'] ) && ! is_null( $args['class'] ) ) ? $args['class'] : 'large-text';
821
822
	echo '<textarea class="' . esc_attr( $class ) . ' txtarea-' . esc_attr( $size ) . ' wpi-' . esc_attr( sanitize_html_class( $sanitize_id ) ) . ' " cols="' . esc_attr( $args['cols'] ) . '" rows="' . esc_attr( $args['rows'] ) . '" id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
823
	echo '<br /><label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
824
825
}
826
827
function wpinv_password_callback( $args ) {
828
829
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
830
	$std     = isset( $args['std'] ) ? $args['std'] : '';
831
	$value   = wpinv_get_option( $args['id'], $std );
832
833
	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
834
	echo '<input type="password" class="' . esc_attr( $size ) . '-text" id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( $value ) . '"/>';
835
	echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
836
837
}
838
839
function wpinv_missing_callback( $args ) {
840
	printf(
841
		esc_html__( 'The callback function used for the %s setting is missing.', 'invoicing' ),
842
		'<strong>' . esc_html( $args['id'] ) . '</strong>'
843
	);
844
}
845
846
/**
847
 * Displays a number input settings callback.
848
 */
849
function wpinv_select_callback( $args ) {
850
851
	$desc   = wp_kses_post( $args['desc'] );
852
	$desc   = empty( $desc ) ? '' : "<p class='description'>$desc</p>";
853
	$value  = isset( $args['std'] ) ? $args['std'] : '';
854
	$value  = wpinv_get_option( $args['id'], $value );
855
	$rand   = uniqid( 'random_id' );
856
857
	?>
858
		<label style="width: 100%;">
859
			<select <?php wpinv_settings_attrs_helper( $args ); ?> data-allow-clear="true">
860
				<?php foreach ( $args['options'] as $option => $name ) : ?>
861
					<option value="<?php echo esc_attr( $option ); ?>" <?php echo selected( $option, $value ); ?>><?php echo esc_html( $name ); ?></option>
862
				<?php endforeach; ?>
863
			</select>
864
865
			<?php if ( substr( $args['id'], -5 ) === '_page' && is_numeric( $value ) ) : ?>
866
				<a href="<?php echo esc_url( get_edit_post_link( $value ) ); ?>" target="_blank" class="button getpaid-page-setting-edit"><?php esc_html_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 $post 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

866
				<a href="<?php echo esc_url( get_edit_post_link( /** @scrutinizer ignore-type */ $value ) ); ?>" target="_blank" class="button getpaid-page-setting-edit"><?php esc_html_e( 'Edit Page', 'invoicing' ); ?></a>
Loading history...
867
			<?php endif; ?>
868
869
			<?php if ( substr( $args['id'], -5 ) === '_page' && ! empty( $args['default_content'] ) ) : ?>
870
				&nbsp;<a href="#TB_inline?&width=400&height=550&inlineId=<?php echo esc_attr( $rand ); ?>" class="button thickbox getpaid-page-setting-view-default"><?php esc_html_e( 'View Default Content', 'invoicing' ); ?></a>
871
				<div id='<?php echo esc_attr( $rand ); ?>' style='display:none;'>
872
					<div>
873
						<h3><?php esc_html_e( 'Original Content', 'invoicing' ); ?></h3>
874
						<textarea readonly onclick="this.select()" rows="8" style="width: 100%;"><?php echo wp_kses_post( gepaid_trim_lines( $args['default_content'] ) ); ?></textarea>
875
						<h3><?php esc_html_e( 'Current Content', 'invoicing' ); ?></h3>
876
						<textarea readonly onclick="this.select()" rows="8" style="width: 100%;"><?php $_post = get_post( $value ); echo empty( $_post ) ? '' : wp_kses_post( gepaid_trim_lines( $_post->post_content ) ); ?></textarea>
877
					</div>
878
				</div>
879
			<?php endif; ?>
880
881
			<?php echo wp_kses_post( $desc ); ?>
882
		</label>
883
	<?php
884
885
}
886
887
function wpinv_color_select_callback( $args ) {
888
889
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
890
	$std     = isset( $args['std'] ) ? $args['std'] : '';
891
	$value   = wpinv_get_option( $args['id'], $std );
892
893
	echo '<select id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"/>';
894
895
	foreach ( $args['options'] as $option => $color ) {
896
		echo '<option value="' . esc_attr( $option ) . '" ' . selected( $option, $value ) . '>' . esc_html( $color['label'] ) . '</option>';
897
	}
898
899
	echo '</select>';
900
	echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
901
902
}
903
904
function wpinv_rich_editor_callback( $args ) {
905
	global $wp_version;
906
907
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
908
909
	$std     = isset( $args['std'] ) ? $args['std'] : '';
910
	$value   = wpinv_get_option( $args['id'], $std );
911
912
	if ( ! empty( $args['allow_blank'] ) && empty( $value ) ) {
913
		$value = $std;
914
	}
915
916
	$rows = isset( $args['size'] ) ? $args['size'] : 20;
917
918
	echo '<div class="getpaid-settings-editor-input">';
919
	if ( $wp_version >= 3.3 && function_exists( 'wp_editor' ) ) {
920
		wp_editor(
921
            stripslashes( $value ),
922
            'wpinv_settings_' . esc_attr( $args['id'] ),
923
            array(
924
				'textarea_name' => 'wpinv_settings[' . esc_attr( $args['id'] ) . ']',
925
				'textarea_rows' => absint( $rows ),
926
				'media_buttons' => false,
927
            )
928
        );
929
	} else {
930
		echo '<textarea class="large-text" rows="10" id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" class="wpi-' . esc_attr( sanitize_html_class( $args['id'] ) ) . '">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
931
	}
932
933
	echo '</div><br/><label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
934
935
}
936
937
function wpinv_upload_callback( $args ) {
938
939
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
940
941
	$std     = isset( $args['std'] ) ? $args['std'] : '';
942
	$value   = wpinv_get_option( $args['id'], $std );
943
944
	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
945
	echo '<input type="text" class="' . sanitize_html_class( $size ) . '-text" id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
946
	echo '<span>&nbsp;<input type="button" class="wpinv_settings_upload_button button-secondary" value="' . esc_attr__( 'Upload File', 'invoicing' ) . '"/></span>';
947
	echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
948
949
}
950
951
function wpinv_color_callback( $args ) {
952
953
	$std         = isset( $args['std'] ) ? $args['std'] : '';
954
	$value       = wpinv_get_option( $args['id'], $std );
955
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
956
957
	echo '<input type="text" class="wpinv-color-picker" id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( $value ) . '" data-default-color="' . esc_attr( $std ) . '" />';
958
	echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
959
960
}
961
962
function wpinv_country_states_callback( $args ) {
963
964
	$std     = isset( $args['std'] ) ? $args['std'] : '';
965
	$value   = wpinv_get_option( $args['id'], $std );
966
967
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
968
969
	if ( isset( $args['placeholder'] ) ) {
970
		$placeholder = $args['placeholder'];
971
	} else {
972
		$placeholder = '';
973
	}
974
975
	$states = wpinv_get_country_states();
976
977
	$class = empty( $states ) ? 'wpinv-no-states' : 'wpi_select2';
978
	echo '<select id="wpinv_settings[' . esc_attr( $sanitize_id ) . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" class="' . esc_attr( $class ) . '" data-placeholder="' . esc_html( $placeholder ) . '"/>';
979
980
	foreach ( $states as $option => $name ) {
981
		echo '<option value="' . esc_attr( $option ) . '" ' . selected( $option, $value ) . '>' . esc_html( $name ) . '</option>';
982
	}
983
984
	echo '</select>';
985
	echo '<label for="wpinv_settings[' . esc_attr( $sanitize_id ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
986
987
}
988
989
/**
990
 * Displays the tax rates edit table.
991
 */
992
function wpinv_tax_rates_callback() {
993
994
	?>
995
		</td>
996
	</tr>
997
	<tr class="bsui">
998
    	<td colspan="2" class="p-0">
999
			<?php include plugin_dir_path( __FILE__ ) . 'views/html-tax-rates-edit.php'; ?>
1000
1001
	<?php
1002
1003
}
1004
1005
/**
1006
 * Displays a tax rate' edit row.
1007
 */
1008
function wpinv_tax_rate_callback( $tax_rate, $key ) {
1009
1010
	$key                      = sanitize_key( $key );
1011
	$tax_rate['reduced_rate'] = empty( $tax_rate['reduced_rate'] ) ? 0 : $tax_rate['reduced_rate'];
1012
	include plugin_dir_path( __FILE__ ) . 'views/html-tax-rate-edit.php';
1013
1014
}
1015
1016
/**
1017
 * Displays the tax rules edit table.
1018
 */
1019
function wpinv_tax_rules_callback() {
1020
1021
	?>
1022
		</td>
1023
	</tr>
1024
	<tr class="bsui">
1025
    	<td colspan="2" class="p-0">
1026
			<?php include plugin_dir_path( __FILE__ ) . 'views/html-tax-rules-edit.php'; ?>
1027
1028
	<?php
1029
1030
}
1031
1032
function wpinv_tools_callback( $args ) {
1033
    ?>
1034
    </td><tr>
1035
    <td colspan="2" class="wpinv_tools_tdbox">
1036
    <?php
1037
    if ( $args['desc'] ) {
1038
?>
1039
<p><?php echo wp_kses_post( $args['desc'] ); ?></p><?php } ?>
1040
    <?php do_action( 'wpinv_tools_before' ); ?>
1041
    <table id="wpinv_tools_table" class="wp-list-table widefat fixed posts">
1042
        <thead>
1043
            <tr>
1044
                <th scope="col" class="wpinv-th-tool"><?php esc_html_e( 'Tool', 'invoicing' ); ?></th>
1045
                <th scope="col" class="wpinv-th-desc"><?php esc_html_e( 'Description', 'invoicing' ); ?></th>
1046
                <th scope="col" class="wpinv-th-action"><?php esc_html_e( 'Action', 'invoicing' ); ?></th>
1047
            </tr>
1048
        </thead>
1049
1050
        <tbody>
1051
			<tr>
1052
                <td><?php esc_html_e( 'Check Pages', 'invoicing' ); ?></td>
1053
                <td>
1054
                    <small><?php esc_html_e( 'Creates any missing GetPaid pages.', 'invoicing' ); ?></small>
1055
                </td>
1056
                <td>
1057
					<a href="
1058
                    <?php
1059
						echo esc_url(
1060
							wp_nonce_url(
1061
								add_query_arg( 'getpaid-admin-action', 'create_missing_pages' ),
1062
								'getpaid-nonce',
1063
								'getpaid-nonce'
1064
							)
1065
						);
1066
					?>
1067
                    " class="button button-primary"><?php esc_html_e( 'Run', 'invoicing' ); ?></a>
1068
                </td>
1069
            </tr>
1070
			<tr>
1071
                <td><?php esc_html_e( 'Refresh Permalinks', 'invoicing' ); ?></td>
1072
                <td>
1073
                    <small><?php esc_html_e( 'Might fix the page not found error when viewing an invoice.', 'invoicing' ); ?></small>
1074
                </td>
1075
                <td>
1076
					<a href="
1077
                    <?php
1078
						echo esc_url(
1079
							wp_nonce_url(
1080
								add_query_arg( 'getpaid-admin-action', 'refresh_permalinks' ),
1081
								'getpaid-nonce',
1082
								'getpaid-nonce'
1083
							)
1084
						);
1085
					?>
1086
                    " class="button button-primary"><?php esc_html_e( 'Run', 'invoicing' ); ?></a>
1087
                </td>
1088
            </tr>
1089
			<tr>
1090
                <td><?php esc_html_e( 'Repair Database Tables', 'invoicing' ); ?></td>
1091
                <td>
1092
                    <small><?php esc_html_e( 'Run this tool to create any missing database tables.', 'invoicing' ); ?></small>
1093
                </td>
1094
                <td>
1095
					<a href="
1096
                    <?php
1097
						echo esc_url(
1098
							wp_nonce_url(
1099
								add_query_arg( 'getpaid-admin-action', 'create_missing_tables' ),
1100
								'getpaid-nonce',
1101
								'getpaid-nonce'
1102
							)
1103
						);
1104
					?>
1105
                    " class="button button-primary"><?php esc_html_e( 'Run', 'invoicing' ); ?></a>
1106
                </td>
1107
            </tr>
1108
			<tr>
1109
                <td><?php esc_html_e( 'Migrate old invoices', 'invoicing' ); ?></td>
1110
                <td>
1111
                    <small><?php esc_html_e( 'If your old invoices were not migrated after updating from Invoicing to GetPaid, you can use this tool to migrate them.', 'invoicing' ); ?></small>
1112
                </td>
1113
                <td>
1114
					<a href="
1115
                    <?php
1116
						echo esc_url(
1117
							wp_nonce_url(
1118
								add_query_arg( 'getpaid-admin-action', 'migrate_old_invoices' ),
1119
								'getpaid-nonce',
1120
								'getpaid-nonce'
1121
							)
1122
						);
1123
					?>
1124
                    " class="button button-primary"><?php esc_html_e( 'Run', 'invoicing' ); ?></a>
1125
                </td>
1126
            </tr>
1127
1128
			<tr>
1129
                <td><?php esc_html_e( 'Recalculate Discounts', 'invoicing' ); ?></td>
1130
                <td>
1131
                    <small><?php esc_html_e( 'Recalculate discounts for existing invoices that have discount codes but are not discounted.', 'invoicing' ); ?></small>
1132
                </td>
1133
                <td>
1134
					<a href="
1135
                    <?php
1136
						echo esc_url(
1137
							wp_nonce_url(
1138
								add_query_arg( 'getpaid-admin-action', 'recalculate_discounts' ),
1139
								'getpaid-nonce',
1140
								'getpaid-nonce'
1141
							)
1142
						);
1143
					?>
1144
                    " class="button button-primary"><?php esc_html_e( 'Run', 'invoicing' ); ?></a>
1145
                </td>
1146
            </tr>
1147
1148
			<tr>
1149
                <td><?php esc_html_e( 'Set-up Wizard', 'invoicing' ); ?></td>
1150
                <td>
1151
                    <small><?php esc_html_e( 'Launch the quick set-up wizard.', 'invoicing' ); ?></small>
1152
                </td>
1153
                <td>
1154
					<a href="
1155
                    <?php
1156
						echo esc_url( admin_url( 'index.php?page=gp-setup' ) );
1157
					?>
1158
                    " class="button button-primary"><?php esc_html_e( 'Launch', 'invoicing' ); ?></a>
1159
                </td>
1160
            </tr>
1161
1162
			<?php do_action( 'wpinv_tools_row' ); ?>
1163
        </tbody>
1164
    </table>
1165
    <?php do_action( 'wpinv_tools_after' ); ?>
1166
    <?php
1167
}
1168
1169
1170
function wpinv_descriptive_text_callback( $args ) {
1171
	echo wp_kses_post( $args['desc'] );
1172
}
1173
1174
function wpinv_raw_html_callback( $args ) {
1175
	echo wp_kses( $args['desc'], getpaid_allowed_html() );
1176
}
1177
1178
function wpinv_hook_callback( $args ) {
1179
	do_action( 'wpinv_' . $args['id'], $args );
1180
}
1181
1182
function wpinv_set_settings_cap() {
1183
	return wpinv_get_capability();
1184
}
1185
add_filter( 'option_page_capability_wpinv_settings', 'wpinv_set_settings_cap' );
1186
1187
1188
function wpinv_on_update_settings( $old_value, $value, $option ) {
1189
    $old = ! empty( $old_value['remove_data_on_unistall'] ) ? 1 : '';
1190
    $new = ! empty( $value['remove_data_on_unistall'] ) ? 1 : '';
1191
1192
    if ( $old != $new ) {
1193
        update_option( 'wpinv_remove_data_on_invoice_unistall', $new );
1194
    }
1195
}
1196
add_action( 'update_option_wpinv_settings', 'wpinv_on_update_settings', 10, 3 );
1197
1198
1199
/**
1200
 * Retrieve merge tags for email templates.
1201
 * 
1202
 * Returns an array of merge tags that can be used in email templates for invoices & subscriptions.
1203
 * 
1204
 * @since    2.1.8
1205
 *
1206
 * @return array
1207
 */
1208
function wpinv_get_email_merge_tags( $subscription = false ) {
1209
	$merge_tags = array(
1210
		'{site_title}'           => __( 'Site Title', 'invoicing' ),
1211
		'{name}'                 => __( "Customer's full name", 'invoicing' ),
1212
		'{first_name}'           => __( "Customer's first name", 'invoicing' ),
1213
		'{last_name}'            => __( "Customer's last name", 'invoicing' ),
1214
		'{email}'                => __( "Customer's email address", 'invoicing' ),
1215
		'{invoice_number}'       => __( 'The invoice number', 'invoicing' ),
1216
		'{invoice_currency}'     => __( 'The invoice currency', 'invoicing' ),
1217
		'{invoice_total}'        => __( 'The invoice total', 'invoicing' ),
1218
		'{invoice_link}'         => __( 'The invoice link', 'invoicing' ),
1219
		'{invoice_pay_link}'     => __( 'The payment link', 'invoicing' ),
1220
		'{invoice_receipt_link}' => __( 'The receipt link', 'invoicing' ),
1221
		'{invoice_date}'         => __( 'The date the invoice was created', 'invoicing' ),
1222
		'{invoice_due_date}'     => __( 'The date the invoice is due', 'invoicing' ),
1223
		'{date}'                 => __( "Today's date", 'invoicing' ),
1224
		'{is_was}'               => __( 'If due date of invoice is past, displays "was" otherwise displays "is"', 'invoicing' ),
1225
		'{invoice_label}'        => __( 'Invoices/quotes singular name. Ex: Invoice/Quote', 'invoicing' ),
1226
		'{invoice_quote}'        => __( 'Invoices/quotes singular name in small letters. Ex: invoice/quote', 'invoicing' ),
1227
		'{invoice_description}'  => __( 'The description of the invoice', 'invoicing' ),
1228
	);
1229
1230
	if ( $subscription ) {
1231
		$merge_tags = array_merge(
1232
			$merge_tags,
1233
			array(
1234
				'{subscription_renewal_date}'     => __( 'The next renewal date of the subscription', 'invoicing' ),
1235
				'{subscription_created}'          => __( "The subscription's creation date", 'invoicing' ),
1236
				'{subscription_status}'           => __( "The subscription's status", 'invoicing' ),
1237
				'{subscription_profile_id}'       => __( "The subscription's remote profile id", 'invoicing' ),
1238
				'{subscription_id}'               => __( "The subscription's id", 'invoicing' ),
1239
				'{subscription_recurring_amount}' => __( 'The renewal amount of the subscription', 'invoicing' ),
1240
				'{subscription_initial_amount}'   => __( 'The initial amount of the subscription', 'invoicing' ),
1241
				'{subscription_recurring_period}' => __( 'The recurring period of the subscription (e.g 1 year)', 'invoicing' ),
1242
				'{subscription_bill_times}'       => __( 'The maximum number of times the subscription can be renewed', 'invoicing' ),
1243
				'{subscription_url}'              => __( 'The URL to manage a subscription', 'invoicing' ),
1244
				'{subscription_name}'             => __( 'The name of the recurring item', 'invoicing' ),
1245
			)
1246
		);
1247
	}
1248
1249
	return $merge_tags;
1250
}
1251
1252
1253
/**
1254
 * Returns the merge tags help text.
1255
 *
1256
 * @since    2.1.8
1257
 *
1258
 * @return string
1259
 */
1260
function wpinv_get_merge_tags_help_text( $subscription = false ) {
1261
	$merge_tags = wpinv_get_email_merge_tags( $subscription );
1262
1263
	$output = '<div class="bsui">';
1264
1265
	$link = sprintf(
1266
		'<strong class="getpaid-merge-tags text-primary" role="button">%s</strong>',
1267
		esc_html__( 'View available merge tags.', 'invoicing' )
1268
	);
1269
1270
	$description = esc_html__( 'The content of the email (Merge Tags and HTML are allowed).', 'invoicing' );
1271
	
1272
	$output .= "$description $link";
1273
1274
	$output .= '<div class="getpaid-merge-tags-content mt-2 p-1 d-none">';
1275
	$output .= '<p class="mb-2">' . esc_html__( 'The following wildcards can be used in email subjects, heading and content:', 'invoicing' ) . '</p>';
1276
1277
	$output .= '<ul class="p-0 m-0">';
1278
	foreach($merge_tags as $tag => $tag_description) {
1279
		$output .= "<li class='mb-2'><strong class='text-dark'>$tag</strong> &mdash; $tag_description</li>";
1280
	}
1281
1282
	$output .= '</ul></div></div>';
1283
1284
	return $output;
1285
}
1286