PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.2.2
Adminify – White Label, Admin Menu Editor, Login Customizer v4.2.2
4.3.1 4.3.0 4.2.26 4.2.25 4.2.24 4.2.23 4.2.22 4.2.21 4.2.20 4.2.19 4.2.18 4.2.17 4.2.16 4.2.15 4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.1.17 All 164 releases
adminify / Libs / adminify-framework / classes / admin-options.class.php

admin-options.class.php in Adminify – White Label, Admin Menu Editor, Login Customizer 4.2.2, at Libs/adminify-framework/classes/admin-options.class.php

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