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

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