PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / trunk
Forumax – AI Powered Advanced Community Forum Plugin vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 2.0.0 2.1.0 All 29 releases
bbp-core / lib / csf / classes / admin-options.class.php

admin-options.class.php in Forumax – AI Powered Advanced Community Forum Plugin trunk, at lib/csf/classes/admin-options.class.php

669 lines 24.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if ( ! defined( 'ABSPATH' ) ) { die; } // Cannot access directly.
2 /**
3 *
4 * Options Class
5 *
6 * @since 1.0.0
7 * @version 1.0.0
8 *
9 */
10 if ( ! class_exists( 'CSF_Options' ) ) {
11 class CSF_Options extends CSF_Abstract {
12
13 // constans
14 public $unique = '';
15 public $notice = '';
16 public $abstract = 'options';
17 public $sections = array();
18 public $options = array();
19 public $errors = array();
20 public $pre_tabs = array();
21 public $pre_fields = array();
22 public $pre_sections = array();
23 public $args = array(
24
25 // framework title
26 'framework_title' => 'Codestar Framework <small>by Codestar</small>',
27 'framework_class' => '',
28
29 // menu settings
30 'menu_title' => '',
31 'menu_slug' => '',
32 'menu_type' => 'menu',
33 'menu_capability' => 'manage_options',
34 'menu_icon' => null,
35 'menu_position' => null,
36 'menu_hidden' => false,
37 'register_menu' => true,
38 'menu_parent' => '',
39 'sub_menu_title' => '',
40
41 // menu extras
42 'show_bar_menu' => true,
43 'show_sub_menu' => true,
44 'show_in_network' => true,
45 'show_in_customizer' => false,
46
47 'show_search' => true,
48 'show_reset_all' => true,
49 'show_reset_section' => true,
50 'show_footer' => true,
51 'show_all_options' => true,
52 'show_form_warning' => true,
53 'sticky_header' => true,
54 'save_defaults' => true,
55 'ajax_save' => true,
56 'form_action' => '',
57
58 // admin bar menu settings
59 'admin_bar_menu_icon' => '',
60 'admin_bar_menu_priority' => 50,
61
62 // footer
63 'footer_text' => 'Thank you for creating Knowledge base with EazyDocs',
64 'footer_after' => '',
65 'footer_credit' => '',
66
67 // database model
68 'database' => '', // options, transient, theme_mod, network
69 'transient_time' => 0,
70
71 // contextual help
72 'contextual_help' => array(),
73 'contextual_help_sidebar' => '',
74
75 // typography options
76 'enqueue_webfont' => true,
77 'async_webfont' => false,
78
79 // others
80 'output_css' => true,
81
82 // theme
83 'nav' => 'normal',
84 'theme' => 'dark',
85 'class' => '',
86
87 // external default values
88 'defaults' => array(),
89
90 );
91
92 // run framework construct
93 public function __construct( $key, $params = array() ) {
94
95 $this->unique = $key;
96 $this->args = apply_filters( "csf_{$this->unique}_args", wp_parse_args( $params['args'], $this->args ), $this );
97 $this->sections = apply_filters( "csf_{$this->unique}_sections", $params['sections'], $this );
98
99 // run only is admin panel options, avoid performance loss
100 $this->pre_tabs = $this->pre_tabs( $this->sections );
101 $this->pre_fields = $this->pre_fields( $this->sections );
102 $this->pre_sections = $this->pre_sections( $this->sections );
103
104 $this->get_options();
105 $this->set_options();
106 $this->save_defaults();
107
108 if ( ! empty( $this->args['register_menu'] ) ) {
109 add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
110 add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu' ), $this->args['admin_bar_menu_priority'] );
111 }
112 add_action( 'wp_ajax_csf_'. $this->unique .'_ajax_save', array( $this, 'ajax_save' ) );
113
114 if ( ! empty( $this->args['register_menu'] ) && $this->args['database'] === 'network' && ! empty( $this->args['show_in_network'] ) ) {
115 add_action( 'network_admin_menu', array( $this, 'add_admin_menu' ) );
116 }
117
118 // wp enqeueu for typography and output css
119 parent::__construct();
120
121 }
122
123 // instance
124 public static function instance( $key, $params = array() ) {
125 return new self( $key, $params );
126 }
127
128 // add admin bar menu
129 public function add_admin_bar_menu( $wp_admin_bar ) {
130
131 if ( ! current_user_can( $this->args['menu_capability'] ) ) {
132 return;
133 }
134
135 if ( is_network_admin() && ( $this->args['database'] !== 'network' || $this->args['show_in_network'] !== true ) ) {
136 return;
137 }
138
139 if ( ! empty( $this->args['show_bar_menu'] ) && empty( $this->args['menu_hidden'] ) ) {
140
141 global $submenu;
142
143 $menu_slug = $this->args['menu_slug'];
144 $menu_icon = ( ! empty( $this->args['admin_bar_menu_icon'] ) ) ? '<span class="csf-ab-icon ab-icon '. esc_attr( $this->args['admin_bar_menu_icon'] ) .'"></span>' : '';
145
146 $wp_admin_bar->add_node( array(
147 'id' => $menu_slug,
148 'title' => $menu_icon . esc_attr( $this->args['menu_title'] ),
149 'href' => esc_url( ( is_network_admin() ) ? network_admin_url( 'admin.php?page='. $menu_slug ) : admin_url( 'admin.php?page='. $menu_slug ) ),
150 ) );
151
152 if ( ! empty( $submenu[$menu_slug] ) ) {
153 foreach ( $submenu[$menu_slug] as $menu_key => $menu_value ) {
154 $wp_admin_bar->add_node( array(
155 'parent' => $menu_slug,
156 'id' => $menu_slug .'-'. $menu_key,
157 'title' => $menu_value[0],
158 'href' => esc_url( ( is_network_admin() ) ? network_admin_url( 'admin.php?page='. $menu_value[2] ) : admin_url( 'admin.php?page='. $menu_value[2] ) ),
159 ) );
160 }
161 }
162
163 }
164
165 }
166
167 public function ajax_save() {
168
169 $result = $this->set_options( true );
170
171 if ( ! $result ) {
172 wp_send_json_error( array( 'error' => esc_html__( 'Error while saving the changes.', 'forumax' ) ) );
173 } else {
174 wp_send_json_success( array( 'notice' => $this->notice, 'errors' => $this->errors ) );
175 }
176
177 }
178
179 // get default value
180 public function get_default( $field ) {
181
182 $default = ( isset( $field['default'] ) ) ? $field['default'] : '';
183 $default = ( isset( $this->args['defaults'][$field['id']] ) ) ? $this->args['defaults'][$field['id']] : $default;
184
185 return $default;
186
187 }
188
189 // save defaults and set new fields value to main options
190 public function save_defaults() {
191
192 $tmp_options = $this->options;
193
194 foreach ( $this->pre_fields as $field ) {
195 if ( ! empty( $field['id'] ) ) {
196 $this->options[$field['id']] = ( isset( $this->options[$field['id']] ) ) ? $this->options[$field['id']] : $this->get_default( $field );
197 }
198 }
199
200 if ( $this->args['save_defaults'] && empty( $tmp_options ) ) {
201 $this->save_options( $this->options );
202 }
203
204 }
205
206 // set options
207 public function set_options( $ajax = false ) {
208
209 // XSS ok.
210 // No worries, This "POST" requests is sanitizing in the below foreach. see #L337 - #L341
211 $response = ( $ajax && ! empty( $_POST['data'] ) ) ? json_decode( wp_unslash( trim( $_POST['data'] ) ), true ) : $_POST;
212
213 // Set variables.
214 $data = array();
215 $noncekey = 'csf_options_nonce'. $this->unique;
216 $nonce = ( ! empty( $response[$noncekey] ) ) ? $response[$noncekey] : '';
217 $options = ( ! empty( $response[$this->unique] ) ) ? $response[$this->unique] : array();
218 $transient = ( ! empty( $response['csf_transient'] ) ) ? $response['csf_transient'] : array();
219
220 if ( wp_verify_nonce( $nonce, 'csf_options_nonce' ) ) {
221
222 $importing = false;
223 $section_id = ( ! empty( $transient['section'] ) ) ? $transient['section'] : '';
224
225 if ( ! $ajax && ! empty( $response[ 'csf_import_data' ] ) ) {
226
227 // XSS ok.
228 // No worries, This "POST" requests is sanitizing in the below foreach. see #L337 - #L341
229 $import_data = json_decode( wp_unslash( trim( $response[ 'csf_import_data' ] ) ), true );
230 $options = ( is_array( $import_data ) && ! empty( $import_data ) ) ? $import_data : array();
231 $importing = true;
232 $this->notice = esc_html__( 'Settings successfully imported.', 'forumax' );
233
234 }
235
236 if ( ! empty( $transient['reset'] ) ) {
237
238 foreach ( $this->pre_fields as $field ) {
239 if ( ! empty( $field['id'] ) ) {
240 $data[$field['id']] = $this->get_default( $field );
241 }
242 }
243
244 $this->notice = esc_html__( 'Default settings restored.', 'forumax' );
245
246 } else if ( ! empty( $transient['reset_section'] ) && ! empty( $section_id ) ) {
247
248 if ( ! empty( $this->pre_sections[$section_id-1]['fields'] ) ) {
249
250 foreach ( $this->pre_sections[$section_id-1]['fields'] as $field ) {
251 if ( ! empty( $field['id'] ) ) {
252 $data[$field['id']] = $this->get_default( $field );
253 }
254 }
255
256 }
257
258 $data = wp_parse_args( $data, $this->options );
259
260 $this->notice = esc_html__( 'Default settings restored.', 'forumax' );
261
262 } else {
263
264 // sanitize and validate
265 foreach ( $this->pre_fields as $field ) {
266
267 if ( ! empty( $field['id'] ) ) {
268
269 $field_id = $field['id'];
270 $field_value = isset( $options[$field_id] ) ? $options[$field_id] : '';
271
272 // Ajax and Importing doing wp_unslash already.
273 if ( ! $ajax && ! $importing ) {
274 $field_value = wp_unslash( $field_value );
275 }
276
277 // Sanitize "post" request of field.
278 if ( ! isset( $field['sanitize'] ) ) {
279
280 if( is_array( $field_value ) ) {
281
282 $data[$field_id] = wp_kses_post_deep( $field_value );
283
284 } else {
285
286 $data[$field_id] = wp_kses_post( $field_value );
287
288 }
289
290 } else if( isset( $field['sanitize'] ) && is_callable( $field['sanitize'] ) ) {
291
292 $data[$field_id] = call_user_func( $field['sanitize'], $field_value );
293
294 } else {
295
296 $data[$field_id] = $field_value;
297
298 }
299
300 // Validate "post" request of field.
301 if ( isset( $field['validate'] ) && is_callable( $field['validate'] ) ) {
302
303 $has_validated = call_user_func( $field['validate'], $field_value );
304
305 if ( ! empty( $has_validated ) ) {
306
307 $data[$field_id] = ( isset( $this->options[$field_id] ) ) ? $this->options[$field_id] : '';
308 $this->errors[$field_id] = $has_validated;
309
310 }
311
312 }
313
314 }
315
316 }
317
318 }
319
320 $data = apply_filters( "csf_{$this->unique}_save", $data, $this );
321
322 do_action( "csf_{$this->unique}_save_before", $data, $this );
323
324 $this->options = $data;
325
326 $this->save_options( $data );
327
328 do_action( "csf_{$this->unique}_save_after", $data, $this );
329
330 if ( empty( $this->notice ) ) {
331 $this->notice = esc_html__( 'Settings saved.', 'forumax' );
332 }
333
334 return true;
335
336 }
337
338 return false;
339
340 }
341
342 // save options database
343 public function save_options( $data ) {
344
345 if ( $this->args['database'] === 'transient' ) {
346 set_transient( $this->unique, $data, $this->args['transient_time'] );
347 } else if ( $this->args['database'] === 'theme_mod' ) {
348 set_theme_mod( $this->unique, $data );
349 } else if ( $this->args['database'] === 'network' ) {
350 update_site_option( $this->unique, $data );
351 } else {
352 update_option( $this->unique, $data );
353 }
354
355 do_action( "csf_{$this->unique}_saved", $data, $this );
356
357 }
358
359 // get options from database
360 public function get_options() {
361
362 if ( $this->args['database'] === 'transient' ) {
363 $this->options = get_transient( $this->unique );
364 } else if ( $this->args['database'] === 'theme_mod' ) {
365 $this->options = get_theme_mod( $this->unique );
366 } else if ( $this->args['database'] === 'network' ) {
367 $this->options = get_site_option( $this->unique );
368 } else {
369 $this->options = get_option( $this->unique );
370 }
371
372 if ( empty( $this->options ) ) {
373 $this->options = array();
374 }
375
376 return $this->options;
377
378 }
379
380 // admin menu
381 public function add_admin_menu() {
382
383 extract( $this->args );
384
385 if ( $menu_type === 'submenu' ) {
386
387 $menu_page = call_user_func( 'add_submenu_page', $menu_parent, esc_attr( $menu_title ), esc_attr( $menu_title ), $menu_capability, $menu_slug, array( $this, 'add_options_html' ) );
388
389 } else {
390
391 $menu_page = call_user_func( 'add_menu_page', esc_attr( $menu_title ), esc_attr( $menu_title ), $menu_capability, $menu_slug, array( $this, 'add_options_html' ), $menu_icon, $menu_position );
392
393 if ( ! empty( $sub_menu_title ) ) {
394 call_user_func( 'add_submenu_page', $menu_slug, esc_attr( $sub_menu_title ), esc_attr( $sub_menu_title ), $menu_capability, $menu_slug, array( $this, 'add_options_html' ) );
395 }
396
397 if ( ! empty( $this->args['show_sub_menu'] ) && count( $this->pre_tabs ) > 1 ) {
398
399 // create submenus
400 foreach ( $this->pre_tabs as $section ) {
401 call_user_func( 'add_submenu_page', $menu_slug, esc_attr( $section['title'] ), esc_attr( $section['title'] ), $menu_capability, $menu_slug .'#tab='. sanitize_title( $section['title'] ), '__return_null' );
402 }
403
404 remove_submenu_page( $menu_slug, $menu_slug );
405
406 }
407
408 if ( ! empty( $menu_hidden ) ) {
409 remove_menu_page( $menu_slug );
410 }
411
412 }
413
414 add_action( 'load-'. $menu_page, array( $this, 'add_page_on_load' ) );
415
416 }
417
418 public function add_page_on_load() {
419
420 if ( ! empty( $this->args['contextual_help'] ) ) {
421
422 $screen = get_current_screen();
423
424 foreach ( $this->args['contextual_help'] as $tab ) {
425 $screen->add_help_tab( $tab );
426 }
427
428 if ( ! empty( $this->args['contextual_help_sidebar'] ) ) {
429 $screen->set_help_sidebar( $this->args['contextual_help_sidebar'] );
430 }
431
432 }
433
434 if ( ! empty( $this->args['footer_credit'] ) ) {
435 add_filter( 'admin_footer_text', array( $this, 'add_admin_footer_text' ) );
436 }
437
438 }
439
440 public function add_admin_footer_text() {
441 echo wp_kses_post( $this->args['footer_credit'] );
442 }
443
444 public function error_check( $sections, $err = '' ) {
445
446 if ( ! $this->args['ajax_save'] ) {
447
448 if ( ! empty( $sections['fields'] ) ) {
449 foreach ( $sections['fields'] as $field ) {
450 if ( ! empty( $field['id'] ) ) {
451 if ( array_key_exists( $field['id'], $this->errors ) ) {
452 $err = '<span class="csf-label-error">!</span>';
453 }
454 }
455 }
456 }
457
458 if ( ! empty( $sections['subs'] ) ) {
459 foreach ( $sections['subs'] as $sub ) {
460 $err = $this->error_check( $sub, $err );
461 }
462 }
463
464 if ( ! empty( $sections['id'] ) && array_key_exists( $sections['id'], $this->errors ) ) {
465 $err = $this->errors[$sections['id']];
466 }
467
468 }
469
470 return $err;
471 }
472
473 // option page html output
474 public function add_options_html() {
475
476 $has_nav = ( count( $this->pre_tabs ) > 1 ) ? true : false;
477 $show_all = ( ! $has_nav ) ? ' csf-show-all' : '';
478 $ajax_class = ( $this->args['ajax_save'] ) ? ' csf-save-ajax' : '';
479 $sticky_class = ( $this->args['sticky_header'] ) ? ' csf-sticky-header' : '';
480 $wrapper_class = ( $this->args['framework_class'] ) ? ' '. $this->args['framework_class'] : '';
481 $theme = ( $this->args['theme'] ) ? ' csf-theme-'. $this->args['theme'] : '';
482 $class = ( $this->args['class'] ) ? ' '. $this->args['class'] : '';
483 $nav_type = ( $this->args['nav'] === 'inline' ) ? 'inline' : 'normal';
484 $form_action = ( $this->args['form_action'] ) ? $this->args['form_action'] : '';
485
486 do_action( 'csf_options_before' );
487
488 echo '<div class="csf csf-options'. esc_attr( $theme . $class . $wrapper_class ) .'" data-slug="'. esc_attr( $this->args['menu_slug'] ) .'" data-unique="'. esc_attr( $this->unique ) .'">';
489
490 echo '<div class="csf-container">';
491
492 echo '<form method="post" action="'. esc_attr( $form_action ) .'" enctype="multipart/form-data" id="csf-form" autocomplete="off" novalidate="novalidate">';
493
494 echo '<input type="hidden" class="csf-section-id" name="csf_transient[section]" value="1">';
495
496 wp_nonce_field( 'csf_options_nonce', 'csf_options_nonce'. $this->unique );
497
498 echo '<div class="csf-header'. esc_attr( $sticky_class ) .'">';
499 echo '<div class="csf-header-inner">';
500
501 echo '<div class="csf-header-left">';
502 echo '<h1>'. $this->args['framework_title'] .'</h1>';
503 echo '</div>';
504
505 echo '<div class="csf-header-right">';
506
507 $notice_class = ( ! empty( $this->notice ) ) ? 'csf-form-show' : '';
508 $notice_text = ( ! empty( $this->notice ) ) ? $this->notice : '';
509
510 echo '<div class="csf-form-result csf-form-success '. esc_attr( $notice_class ) .'">'. $notice_text .'</div>';
511
512 echo ( $this->args['show_form_warning'] ) ? '<div class="csf-form-result csf-form-warning">'. esc_html__( 'You have unsaved changes, save your changes!', 'forumax' ) .'</div>' : '';
513
514 echo ( $has_nav && $this->args['show_all_options'] ) ? '<div class="csf-expand-all" title="'. esc_html__( 'show all settings', 'forumax' ) .'"><i class="fas fa-outdent"></i></div>' : '';
515
516 echo ( $this->args['show_search'] ) ? '<div class="csf-search"><input type="text" name="csf-search" placeholder="'. esc_html__( 'Search...', 'forumax' ) .'" autocomplete="off" /></div>' : '';
517
518 echo '<div class="csf-buttons">';
519 echo '<input type="submit" name="'. esc_attr( $this->unique ) .'[_nonce][save]" class="button button-primary csf-top-save csf-save'. esc_attr( $ajax_class ) .'" value="'. esc_html__( 'Save', 'forumax' ) .'" data-save="'. esc_html__( 'Saving...', 'forumax' ) .'">';
520 echo ( $this->args['show_reset_section'] ) ? '<input type="submit" name="csf_transient[reset_section]" class="button button-secondary csf-reset-section csf-confirm" value="'. esc_html__( 'Reset Section', 'forumax' ) .'" data-confirm="'. esc_html__( 'Are you sure to reset this section options?', 'forumax' ) .'">' : '';
521 echo ( $this->args['show_reset_all'] ) ? '<input type="submit" name="csf_transient[reset]" class="button csf-warning-primary csf-reset-all csf-confirm" value="'. ( ( $this->args['show_reset_section'] ) ? esc_html__( 'Reset All', 'forumax' ) : esc_html__( 'Reset', 'forumax' ) ) .'" data-confirm="'. esc_html__( 'Are you sure you want to reset all settings to default values?', 'forumax' ) .'">' : '';
522 echo '</div>';
523
524 echo '</div>';
525
526 echo '<div class="clear"></div>';
527 echo '</div>';
528 echo '</div>';
529
530 echo '<div class="csf-wrapper'. esc_attr( $show_all ) .'">';
531
532 if ( $has_nav ) {
533
534 echo '<div class="csf-nav csf-nav-'. esc_attr( $nav_type ) .' csf-nav-options">';
535
536 echo '<ul>';
537
538 foreach ( $this->pre_tabs as $tab ) {
539
540 $tab_id = sanitize_title( $tab['title'] );
541 $tab_error = $this->error_check( $tab );
542 $tab_icon = ( ! empty( $tab['icon'] ) ) ? '<i class="csf-tab-icon '. esc_attr( $tab['icon'] ) .'"></i>' : '';
543
544 if ( ! empty( $tab['subs'] ) ) {
545
546 echo '<li class="csf-tab-item">';
547
548 echo '<a href="#tab='. esc_attr( $tab_id ) .'" data-tab-id="'. esc_attr( $tab_id ) .'" class="csf-arrow">'. $tab_icon . $tab['title'] . $tab_error .'</a>';
549
550 echo '<ul>';
551
552 foreach ( $tab['subs'] as $sub ) {
553
554 $sub_id = $tab_id .'/'. sanitize_title( $sub['title'] );
555 $sub_error = $this->error_check( $sub );
556 $sub_icon = ( ! empty( $sub['icon'] ) ) ? '<i class="csf-tab-icon '. esc_attr( $sub['icon'] ) .'"></i>' : '';
557
558 echo '<li><a href="#tab='. esc_attr( $sub_id ) .'" data-tab-id="'. esc_attr( $sub_id ) .'">'. $sub_icon . $sub['title'] . $sub_error .'</a></li>';
559
560 }
561
562 echo '</ul>';
563
564 echo '</li>';
565
566 } else {
567
568 echo '<li class="csf-tab-item"><a href="#tab='. esc_attr( $tab_id ) .'" data-tab-id="'. esc_attr( $tab_id ) .'">'. $tab_icon . $tab['title'] . $tab_error .'</a></li>';
569
570 }
571
572 }
573
574 echo '</ul>';
575
576 echo '</div>';
577
578 }
579
580 echo '<div class="csf-content">';
581
582 echo '<div class="csf-sections">';
583
584 foreach ( $this->pre_sections as $section ) {
585
586 $section_onload = ( ! $has_nav ) ? ' csf-onload' : '';
587 $section_class = ( ! empty( $section['class'] ) ) ? ' '. $section['class'] : '';
588 $section_icon = ( ! empty( $section['icon'] ) ) ? '<i class="csf-section-icon '. esc_attr( $section['icon'] ) .'"></i>' : '';
589 $section_title = ( ! empty( $section['title'] ) ) ? $section['title'] : '';
590 $section_parent = ( ! empty( $section['ptitle'] ) ) ? sanitize_title( $section['ptitle'] ) .'/' : '';
591 $section_slug = ( ! empty( $section['title'] ) ) ? sanitize_title( $section_title ) : '';
592
593 echo '<div class="csf-section hidden'. esc_attr( $section_onload . $section_class ) .'" data-section-id="'. esc_attr( $section_parent . $section_slug ) .'">';
594 echo ( $has_nav ) ? '<div class="csf-section-title"><h3>'. $section_icon . $section_title .'</h3></div>' : '';
595 echo ( ! empty( $section['description'] ) ) ? '<div class="csf-field csf-section-description">'. $section['description'] .'</div>' : '';
596
597 if ( ! empty( $section['fields'] ) ) {
598
599 foreach ( $section['fields'] as $field ) {
600
601 $is_field_error = $this->error_check( $field );
602
603 if ( ! empty( $is_field_error ) ) {
604 $field['_error'] = $is_field_error;
605 }
606
607 if ( ! empty( $field['id'] ) ) {
608 $field['default'] = $this->get_default( $field );
609 }
610
611 $value = ( ! empty( $field['id'] ) && isset( $this->options[$field['id']] ) ) ? $this->options[$field['id']] : '';
612
613 CSF::field( $field, $value, $this->unique, 'options' );
614
615 }
616
617 } else {
618
619 echo '<div class="csf-no-option">'. esc_html__( 'No data available.', 'forumax' ) .'</div>';
620
621 }
622
623 echo '</div>';
624
625 }
626
627 echo '</div>';
628
629 echo '<div class="clear"></div>';
630
631 echo '</div>';
632
633 echo ( $has_nav && $nav_type === 'normal' ) ? '<div class="csf-nav-background"></div>' : '';
634
635 echo '</div>';
636
637 if ( ! empty( $this->args['show_footer'] ) ) {
638
639 echo '<div class="csf-footer">';
640
641 echo '<div class="csf-buttons">';
642 echo '<input type="submit" name="csf_transient[save]" class="button button-primary csf-save'. esc_attr( $ajax_class ) .'" value="'. esc_html__( 'Save', 'forumax' ) .'" data-save="'. esc_html__( 'Saving...', 'forumax' ) .'">';
643 echo ( $this->args['show_reset_section'] ) ? '<input type="submit" name="csf_transient[reset_section]" class="button button-secondary csf-reset-section csf-confirm" value="'. esc_html__( 'Reset Section', 'forumax' ) .'" data-confirm="'. esc_html__( 'Are you sure to reset this section options?', 'forumax' ) .'">' : '';
644 echo ( $this->args['show_reset_all'] ) ? '<input type="submit" name="csf_transient[reset]" class="button csf-warning-primary csf-reset-all csf-confirm" value="'. ( ( $this->args['show_reset_section'] ) ? esc_html__( 'Reset All', 'forumax' ) : esc_html__( 'Reset', 'forumax' ) ) .'" data-confirm="'. esc_html__( 'Are you sure you want to reset all settings to default values?', 'forumax' ) .'">' : '';
645 echo '</div>';
646
647 echo ( ! empty( $this->args['footer_text'] ) ) ? '<div class="csf-copyright">'. $this->args['footer_text'] .'</div>' : '';
648
649 echo '<div class="clear"></div>';
650 echo '</div>';
651
652 }
653
654 echo '</form>';
655
656 echo '</div>';
657
658 echo '<div class="clear"></div>';
659
660 echo ( ! empty( $this->args['footer_after'] ) ) ? $this->args['footer_after'] : '';
661
662 echo '</div>';
663
664 do_action( 'csf_options_after' );
665
666 }
667 }
668 }
669