PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 1.0.8
Forumax – AI Powered Advanced Community Forum Plugin v1.0.8
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 / includes / admin / settings / codestar-framework / classes / admin-options.class.php

admin-options.class.php in Forumax – AI Powered Advanced Community Forum Plugin 1.0.8, at includes/admin/settings/codestar-framework/classes/admin-options.class.php

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