PluginProbe
Easy Hotel – Powerful Hotel Booking / trunk
Easy Hotel – Powerful Hotel Booking vtrunk
2.0.8 2.0.7 2.0.6 2.0.5 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 1.9.9 1.9.8 1.9.7 1.9.6 1.9.5 1.9.4 1.9.3 1.9.2 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 All 110 releases
easy-hotel / admin / includes / framework / classes / admin-options.class.php

admin-options.class.php in Easy Hotel – Powerful Hotel Booking trunk, at admin/includes/framework/classes/admin-options.class.php

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