PluginProbe
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News / 2.4.0
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News v2.4.0
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 4.0.2 4.0.1 2.3.5 2.3.6 2.4.0 2.4.1 2.4.10 2.4.11 2.4.12 2.4.13 2.4.14 2.4.15 2.4.16 2.4.17 2.4.18 2.4.19 2.4.2 2.4.20 2.4.21 All 88 releases
post-carousel / admin / views / sp-framework / classes / options.class.php

options.class.php in Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News 2.4.0, at admin/views/sp-framework/classes/options.class.php

864 lines 25.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if ( ! defined( 'ABSPATH' ) ) {
2 die; } // Cannot access directly.
3
4 if ( ! class_exists( 'SP_PC_Options' ) ) {
5 /**
6 * Options Class
7 *
8 * @since 1.0.0
9 * @version 1.0.0
10 */
11 class SP_PC_Options extends SP_PC_Abstract {
12
13 /**
14 * Unique ID/Name
15 *
16 * @var string
17 */
18 public $unique = '';
19 /**
20 * Notice.
21 *
22 * @var string
23 */
24 public $notice = '';
25 /**
26 * Abstract.
27 *
28 * @var string
29 */
30 public $abstract = 'options';
31 /**
32 * Setions.
33 *
34 * @var array
35 */
36 public $sections = array();
37 /**
38 * Options
39 *
40 * @var array
41 */
42 public $options = array();
43
44 /**
45 * Errors.
46 *
47 * @var array
48 */
49 public $errors = array();
50
51 /**
52 * Pre tabs.
53 *
54 * @var array
55 */
56 public $pre_tabs = array();
57
58 /**
59 * Pre fields.
60 *
61 * @var array
62 */
63 public $pre_fields = array();
64
65 /**
66 * Pre sections.
67 *
68 * @var array
69 */
70 public $pre_sections = array();
71
72 /**
73 * Default arguments.
74 *
75 * @var array
76 */
77 public $args = array(
78
79 // framework title.
80 'framework_title' => 'SPF Framework <small>by SP</small>',
81 'framework_class' => '',
82
83 // menu settings.
84 'menu_title' => '',
85 'menu_slug' => '',
86 'menu_type' => 'menu',
87 // 'menu_capability' => 'manage_options', It's implemented in add_admin_menu()
88 'menu_icon' => null,
89 'menu_position' => null,
90 'menu_hidden' => false,
91 'menu_parent' => '',
92
93 // menu extras.
94 'show_bar_menu' => true,
95 'show_sub_menu' => true,
96 'show_network_menu' => true,
97 'show_in_customizer' => false,
98
99 'show_search' => true,
100 'show_reset_all' => true,
101 'show_reset_section' => true,
102 'show_footer' => true,
103 'show_all_options' => true,
104 'sticky_header' => true,
105 'save_defaults' => true,
106 'ajax_save' => true,
107
108 // admin bar menu settings.
109 'admin_bar_menu_icon' => '',
110 'admin_bar_menu_priority' => 80,
111
112 // footer.
113 'footer_text' => '',
114 'footer_after' => '',
115 'footer_credit' => '',
116
117 // database model.
118 'database' => '', // options, transient, theme_mod, network.
119 'transient_time' => 0,
120
121 // contextual help.
122 'contextual_help' => array(),
123 'contextual_help_sidebar' => '',
124
125 // typography options.
126 'enqueue_webfont' => true,
127 'async_webfont' => false,
128
129 // others.
130 'output_css' => true,
131
132 // theme.
133 'theme' => 'dark',
134
135 'class' => '',
136
137 // external default values.
138 'defaults' => array(),
139
140 );
141
142 /**
143 * Run framework construct.
144 *
145 * @param string $key The filter unique key.
146 * @param array $params The parameters.
147 */
148 public function __construct( $key, $params = array() ) {
149
150 $this->unique = $key;
151 $this->args = apply_filters( "spf_{$this->unique}_args", wp_parse_args( $params['args'], $this->args ), $this );
152 $this->sections = apply_filters( "spf_{$this->unique}_sections", $params['sections'], $this );
153
154 // run only is admin panel options, avoid performance loss.
155 $this->pre_tabs = $this->pre_tabs( $this->sections );
156 $this->pre_fields = $this->pre_fields( $this->sections );
157 $this->pre_sections = $this->pre_sections( $this->sections );
158
159 $this->get_options();
160 $this->set_options();
161 $this->save_defaults();
162
163 add_action( 'admin_menu', array( &$this, 'add_admin_menu' ) );
164 add_action( 'admin_bar_menu', array( &$this, 'add_admin_bar_menu' ), $this->args['admin_bar_menu_priority'] );
165 add_action( 'wp_ajax_spf_' . $this->unique . '_ajax_save', array( &$this, 'ajax_save' ) );
166
167 if ( ! empty( $this->args['show_network_menu'] ) ) {
168 add_action( 'network_admin_menu', array( &$this, 'add_admin_menu' ) );
169 }
170
171 // wp enqeueu for typography and output css.
172 parent::__construct();
173
174 }
175
176 /**
177 * Instance.
178 *
179 * @param object $key The instance key.
180 * @param array $params All the parameters.
181 * @return mixed
182 */
183 public static function instance( $key, $params = array() ) {
184 return new self( $key, $params );
185 }
186 /**
187 * Pre tabs.
188 *
189 * @param array $sections All the sections.
190 * @return mixed
191 */
192 public function pre_tabs( $sections ) {
193
194 $result = array();
195 $parents = array();
196 $count = 100;
197
198 foreach ( $sections as $key => $section ) {
199 if ( ! empty( $section['parent'] ) ) {
200 $section['priority'] = ( isset( $section['priority'] ) ) ? $section['priority'] : $count;
201 $parents[ $section['parent'] ][] = $section;
202 unset( $sections[ $key ] );
203 }
204 $count++;
205 }
206
207 foreach ( $sections as $key => $section ) {
208 $section['priority'] = ( isset( $section['priority'] ) ) ? $section['priority'] : $count;
209 if ( ! empty( $section['id'] ) && ! empty( $parents[ $section['id'] ] ) ) {
210 $section['subs'] = wp_list_sort( $parents[ $section['id'] ], array( 'priority' => 'ASC' ), 'ASC', true );
211 }
212 $result[] = $section;
213 $count++;
214 }
215
216 return wp_list_sort( $result, array( 'priority' => 'ASC' ), 'ASC', true );
217 }
218
219 /**
220 * Pre fields method.
221 *
222 * @param array $sections The sections.
223 * @return $result
224 */
225 public function pre_fields( $sections ) {
226
227 $result = array();
228
229 foreach ( $sections as $key => $section ) {
230 if ( ! empty( $section['fields'] ) ) {
231 foreach ( $section['fields'] as $field ) {
232 $result[] = $field;
233 }
234 }
235 }
236
237 return $result;
238 }
239
240 /**
241 * The pre sections.
242 *
243 * @param array $sections The sections.
244 * @return mixed
245 */
246 public function pre_sections( $sections ) {
247
248 $result = array();
249
250 foreach ( $this->pre_tabs as $tab ) {
251 if ( ! empty( $tab['subs'] ) ) {
252 foreach ( $tab['subs'] as $sub ) {
253 $result[] = $sub;
254 }
255 }
256 if ( empty( $tab['subs'] ) ) {
257 $result[] = $tab;
258 }
259 }
260
261 return $result;
262 }
263
264 /**
265 * Add admin bar menu.
266 *
267 * @param object $wp_admin_bar The admin bar.
268 * @return void
269 */
270 public function add_admin_bar_menu( $wp_admin_bar ) {
271
272 if ( ! empty( $this->args['show_bar_menu'] ) && empty( $this->args['menu_hidden'] ) ) {
273
274 global $submenu;
275
276 $menu_slug = $this->args['menu_slug'];
277 $menu_icon = ( ! empty( $this->args['admin_bar_menu_icon'] ) ) ? '<span class="spf-ab-icon ab-icon ' . $this->args['admin_bar_menu_icon'] . '"></span>' : '';
278
279 $wp_admin_bar->add_node(
280 array(
281 'id' => $menu_slug,
282 'title' => $menu_icon . $this->args['menu_title'],
283 'href' => ( is_network_admin() ) ? network_admin_url( 'admin.php?page=' . $menu_slug ) : admin_url( 'admin.php?page=' . $menu_slug ),
284 )
285 );
286
287 if ( ! empty( $submenu[ $menu_slug ] ) ) {
288 foreach ( $submenu[ $menu_slug ] as $key => $menu ) {
289 $wp_admin_bar->add_node(
290 array(
291 'parent' => $menu_slug,
292 'id' => $menu_slug . '-' . $key,
293 'title' => $menu[0],
294 'href' => ( is_network_admin() ) ? network_admin_url( 'admin.php?page=' . $menu[2] ) : admin_url( 'admin.php?page=' . $menu[2] ),
295 )
296 );
297 }
298 }
299
300 if ( ! empty( $this->args['show_network_menu'] ) ) {
301 $wp_admin_bar->add_node(
302 array(
303 'parent' => 'network-admin',
304 'id' => $menu_slug . '-network-admin',
305 'title' => $menu_icon . $this->args['menu_title'],
306 'href' => network_admin_url( 'admin.php?page=' . $menu_slug ),
307 )
308 );
309 }
310 }
311
312 }
313
314 /**
315 * Ajax save method.
316 *
317 * @return void
318 */
319 public function ajax_save() {
320
321 $result = $this->set_options( true );
322 if ( ! $result ) {
323 wp_send_json_error(
324 array(
325 'success' => false,
326 'error' => esc_html__(
327 'Error while saving.',
328 'smart-post-show'
329 ),
330 )
331 );
332
333 } else {
334 wp_send_json_success(
335 array(
336 'success' => true,
337 'notice' => $this->notice,
338 'errors' => $this->errors,
339 )
340 );
341 }
342 }
343
344 /**
345 * Get default value.
346 *
347 * @param array $field The field array.
348 * @param array $options The options array.
349 * @return mixed
350 */
351 public function get_default( $field, $options = array() ) {
352
353 $default = ( isset( $this->args['defaults'][ $field['id'] ] ) ) ? $this->args['defaults'][ $field['id'] ] : '';
354 $default = ( isset( $field['default'] ) ) ? $field['default'] : $default;
355 $default = ( isset( $options[ $field['id'] ] ) ) ? $options[ $field['id'] ] : $default;
356
357 return $default;
358
359 }
360
361 /**
362 * Save defaults and set new fields value to main options.
363 *
364 * @return void
365 */
366 public function save_defaults() {
367
368 $tmp_options = $this->options;
369
370 foreach ( $this->pre_fields as $field ) {
371 if ( ! empty( $field['id'] ) ) {
372 $this->options[ $field['id'] ] = $this->get_default( $field, $this->options );
373 }
374 }
375
376 if ( $this->args['save_defaults'] && empty( $tmp_options ) ) {
377 $this->save_options( $this->options );
378 }
379
380 }
381
382 /**
383 * Set options.
384 *
385 * @param boolean $ajax The ajax save.
386 *
387 * @return mixed
388 */
389 public function set_options( $ajax = false ) {
390
391 // XSS ok.
392 // No worries, This "POST" requests is sanitizing in the below foreach. see #L380 - #L384.
393 $response = ( $ajax && ! empty( $_POST['data'] ) ) ? json_decode( wp_unslash( trim( $_POST['data'] ) ), true ) : $_POST; // phpcs:ignore
394
395 // Set variables.
396 $data = array();
397 $noncekey = 'spf_options_nonce' . $this->unique;
398 $nonce = ( ! empty( $response[ $noncekey ] ) ) ? $response[ $noncekey ] : '';
399 $options = ( ! empty( $response[ $this->unique ] ) ) ? $response[ $this->unique ] : array();
400 $transient = ( ! empty( $response['spf_transient'] ) ) ? $response['spf_transient'] : array();
401
402 if ( wp_verify_nonce( $nonce, 'spf_options_nonce' ) ) {
403
404 $importing = false;
405 $section_id = ( ! empty( $transient['section'] ) ) ? $transient['section'] : '';
406
407 // import data.
408 if ( ! $ajax && ! empty( $response['spf_import_data'] ) ) {
409
410 // XSS ok.
411 // No worries, This "POST" requests is sanitizing in the below foreach. see #L380 - #L384.
412 $import_data = json_decode( wp_unslash( trim( $response['spf_import_data'] ) ), true );
413 $options = ( is_array( $import_data ) && ! empty( $import_data ) ) ? $import_data : array();
414 $importing = true;
415 $this->notice = esc_html__( 'Settings successfully imported.', 'smart-post-show' );
416
417 }
418
419 if ( ! empty( $transient['reset'] ) ) {
420
421 foreach ( $this->pre_fields as $field ) {
422 if ( ! empty( $field['id'] ) ) {
423 $data[ $field['id'] ] = $this->get_default( $field );
424 }
425 }
426
427 $this->notice = esc_html__( 'Default options restored.', 'smart-post-show' );
428
429 } elseif ( ! empty( $transient['reset_section'] ) && ! empty( $section_id ) ) {
430
431 if ( ! empty( $this->pre_sections[ $section_id - 1 ]['fields'] ) ) {
432
433 foreach ( $this->pre_sections[ $section_id - 1 ]['fields'] as $field ) {
434 if ( ! empty( $field['id'] ) ) {
435 $data[ $field['id'] ] = $this->get_default( $field );
436 }
437 }
438 }
439
440 $data = wp_parse_args( $data, $this->options );
441 $this->notice = esc_html__( 'Default options restored for only this section.', 'smart-post-show' );
442
443 } else {
444
445 // sanitize and validate.
446 foreach ( $this->pre_fields as $field ) {
447
448 if ( ! empty( $field['id'] ) ) {
449
450 $field_id = $field['id'];
451 $field_value = isset( $options[ $field_id ] ) ? $options[ $field_id ] : '';
452
453 // Ajax and Importing doing wp_unslash already.
454 if ( ! $ajax && ! $importing ) {
455 $field_value = wp_unslash( $field_value );
456 }
457
458 // sanitize.
459 if ( ! isset( $field['sanitize'] ) ) {
460 if ( is_array( $field_value ) ) {
461
462 $data[ $field_id ] = wp_kses_post_deep( $field_value );
463
464 } else {
465
466 $data[ $field_id ] = wp_kses_post( $field_value );
467 }
468 } elseif ( isset( $field['sanitize'] ) && is_callable( $field['sanitize'] ) ) {
469
470 $data[ $field_id ] = call_user_func( $field['sanitize'], $field_value );
471
472 } else {
473 $data[ $field_id ] = $field_value;
474
475 }
476
477 // Validate "post" request of field.
478 if ( isset( $field['validate'] ) && is_callable( $field['validate'] ) ) {
479
480 $has_validated = call_user_func( $field['validate'], $field_value );
481
482 if ( ! empty( $has_validated ) ) {
483 $data[ $field_id ] = ( isset( $this->options[ $field_id ] ) ) ? $this->options[ $field_id ] : '';
484 $this->errors[ $field_id ] = $has_validated;
485 }
486 }
487 }
488 }
489 }
490
491 $data = apply_filters( "spf_{$this->unique}_save", $data, $this );
492
493 do_action( "spf_{$this->unique}_save_before", $data, $this );
494
495 $this->options = $data;
496
497 $this->save_options( $data );
498
499 do_action( "spf_{$this->unique}_save_after", $data, $this );
500
501 if ( empty( $this->notice ) ) {
502 $this->notice = esc_html__( 'Settings saved.', 'smart-post-show' );
503 }
504
505 return true;
506 }
507
508 return false;
509
510 }
511
512 /**
513 * Save options database.
514 *
515 * @param array $data The options values.
516 * @return void
517 */
518 public function save_options( $data ) {
519
520 if ( 'transient' === $this->args['database'] ) {
521 set_transient( $this->unique, $data, $this->args['transient_time'] );
522 } elseif ( 'theme_mod' === $this->args['database'] ) {
523 set_theme_mod( $this->unique, $data );
524 } elseif ( 'network' === $this->args['database'] ) {
525 update_site_option( $this->unique, $data );
526 } else {
527 update_option( $this->unique, $data );
528 }
529
530 do_action( "spf_{$this->unique}_saved", $data, $this );
531
532 }
533
534 /**
535 * Get options from database.
536 *
537 * @return mixed
538 */
539 public function get_options() {
540
541 if ( 'transient' === $this->args['database'] ) {
542 $this->options = get_transient( $this->unique );
543 } elseif ( 'theme_mod' === $this->args['database'] ) {
544 $this->options = get_theme_mod( $this->unique );
545 } elseif ( 'network' === $this->args['database'] ) {
546 $this->options = get_site_option( $this->unique );
547 } else {
548 $this->options = get_option( $this->unique );
549 }
550
551 if ( empty( $this->options ) ) {
552 $this->options = array();
553 }
554
555 return $this->options;
556
557 }
558
559 /**
560 * WP api – admin menu.
561 */
562 public function add_admin_menu() {
563 // Show plugin setting menu as per user role. – ShapedPlugin
564 // Use the hook 'sp_pc_dashboard_capability' to change user capability.
565 $menu_capability = apply_filters( 'sp_pc_dashboard_capability', 'manage_options' );
566 extract( $this->args );
567
568 if ( 'submenu' === $menu_type ) {
569
570 $menu_page = call_user_func( 'add_submenu_page', $menu_parent, $menu_title, $menu_title, $menu_capability, $menu_slug, array( &$this, 'add_options_html' ) );
571
572 } else {
573
574 $menu_page = call_user_func( 'add_menu_page', $menu_title, $menu_title, $menu_capability, $menu_slug, array( &$this, 'add_options_html' ), $menu_icon, $menu_position );
575
576 if ( ! empty( $this->args['show_sub_menu'] ) && count( $this->pre_tabs ) > 1 ) {
577
578 // create submenus.
579 $tab_key = 1;
580 foreach ( $this->pre_tabs as $section ) {
581
582 call_user_func( 'add_submenu_page', $menu_slug, $section['title'], $section['title'], $menu_capability, $menu_slug . '#tab=' . $tab_key, '__return_null' );
583
584 if ( ! empty( $section['subs'] ) ) {
585 $tab_key += ( count( $section['subs'] ) - 1 );
586 }
587
588 $tab_key++;
589
590 }
591
592 remove_submenu_page( $menu_slug, $menu_slug );
593
594 }
595
596 if ( ! empty( $menu_hidden ) ) {
597 remove_menu_page( $menu_slug );
598 }
599 }
600
601 add_action( 'load-' . $menu_page, array( &$this, 'add_page_on_load' ) );
602
603 }
604
605 /**
606 * Add page on load.
607 */
608 public function add_page_on_load() {
609
610 if ( ! empty( $this->args['contextual_help'] ) ) {
611
612 $screen = get_current_screen();
613
614 foreach ( $this->args['contextual_help'] as $tab ) {
615 $screen->add_help_tab( $tab );
616 }
617
618 if ( ! empty( $this->args['contextual_help_sidebar'] ) ) {
619 $screen->set_help_sidebar( $this->args['contextual_help_sidebar'] );
620 }
621 }
622
623 }
624
625 /**
626 * Error check function.
627 */
628 /**
629 * Error Check function
630 *
631 * @param mixed $sections The section.
632 * @param string $err The error.
633 * @return statement
634 */
635 public function error_check( $sections, $err = '' ) {
636
637 if ( ! $this->args['ajax_save'] ) {
638
639 if ( ! empty( $sections['fields'] ) ) {
640 foreach ( $sections['fields'] as $field ) {
641 if ( ! empty( $field['id'] ) ) {
642 if ( array_key_exists( $field['id'], $this->errors ) ) {
643 $err = '<span class="spf-label-error">!</span>';
644 }
645 }
646 }
647 }
648
649 if ( ! empty( $sections['subs'] ) ) {
650 foreach ( $sections['subs'] as $sub ) {
651 $err = $this->error_check( $sub, $err );
652 }
653 }
654
655 if ( ! empty( $sections['id'] ) && array_key_exists( $sections['id'], $this->errors ) ) {
656 $err = $this->errors[ $sections['id'] ];
657 }
658 }
659
660 return $err;
661 }
662
663 /**
664 * Option page html output.
665 *
666 * @return void
667 */
668 public function add_options_html() {
669
670 $has_nav = ( count( $this->pre_tabs ) > 1 ) ? true : false;
671 $show_all = ( ! $has_nav ) ? ' spf-show-all' : '';
672 $show_buttons = isset( $this->args['show_buttons'] ) ? $this->args['show_buttons'] : true;
673 $ajax_class = ( $this->args['ajax_save'] ) ? ' spf-save-ajax' : '';
674 $sticky_class = ( $this->args['sticky_header'] ) ? ' spf-sticky-header' : '';
675 $wrapper_class = ( $this->args['framework_class'] ) ? ' ' . $this->args['framework_class'] : '';
676 $theme = ( $this->args['theme'] ) ? ' spf-theme-' . $this->args['theme'] : '';
677 $class = ( $this->args['class'] ) ? ' ' . $this->args['class'] : '';
678
679 // echo '<div class="wrap"><h1>' . esc_html( $this->args['menu_title'] ) . '</h1></div>';.
680 echo '<div class="spf spf-options' . esc_attr( $theme ) . esc_attr( $class ) . esc_attr( $wrapper_class ) . '" data-slug="' . esc_attr( $this->args['menu_slug'] ) . '" data-unique="' . esc_attr( $this->unique ) . '">';
681
682 $notice_class = ( ! empty( $this->notice ) ) ? ' spf-form-show' : '';
683 $notice_text = ( ! empty( $this->notice ) ) ? $this->notice : '';
684
685 echo '<div class="spf-form-result spf-form-success' . esc_attr( $notice_class ) . '">' . esc_html( $notice_text ) . '</div>';
686
687 $error_class = ( ! empty( $this->errors ) ) ? ' spf-form-show' : '';
688
689 echo '<div class="spf-form-result spf-form-error' . esc_attr( $error_class ) . '">';
690 if ( ! empty( $this->errors ) ) {
691 foreach ( $this->errors as $error ) {
692 echo '<i class="spf-label-error">!</i> ' . esc_html( $error ) . '<br />';
693 }
694 }
695 echo '</div>';
696
697 echo '<div class="spf-container">';
698
699 echo '<form method="post" action="" enctype="multipart/form-data" id="spf-form" autocomplete="off">';
700
701 echo '<input type="hidden" class="spf-section-id" name="spf_transient[section]" value="1">';
702 wp_nonce_field( 'spf_options_nonce', 'spf_options_nonce' . $this->unique );
703
704 echo '<div class="spf-header' . esc_attr( $sticky_class ) . '">';
705 echo '<div class="spf-header-inner">';
706
707 echo '<div class="spf-header-left">';
708 if ( $show_buttons ) {
709 echo '<h1><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1.4em" fill="#e1624b" height="1.4em" viewBox="0 0 288 288" enable-background="new 0 0 288 288" xml:space="preserve"><path fill="#e1624b" d="M262.102,20.977H27.615c-3.195,0-6.638,2.401-6.638,5.63v234.359c0,3.229,3.443,6.057,6.638,6.057h234.487c3.187,0,4.921-2.828,4.921-6.057V26.607C267.023,23.378,265.289,20.977,262.102,20.977z M118.37,53.441h51.26v43.571h-51.26V53.441z M55.15,53.441h51.26v43.571H55.15V53.441z M135.457,235.413H55.15v-46.134h80.307V235.413z M135.457,173.047H55.15v-46.134h80.307V173.047z M235.413,235.413h-80.307v-46.134h80.307V235.413z M235.413,173.047h-80.307v-46.134h80.307V173.047z M235.413,97.012h-51.26V53.441h51.26V97.012z"></path><line fill="none" x1="-99" y1="-84" x2="-99" y2="-57"></line><line fill="none" x1="-170" y1="61" x2="-170" y2="101"></line></svg>' . esc_html__( 'Settings', 'smart-post-show-pro' ) . '</h1>';
710 } else {
711 echo '<h1 class="export-import"><img src="' . esc_url( SP_PC_URL ) . 'admin/assets/img/import-export.svg">' . esc_html( $this->args['framework_title'] ) . '</h1>';
712 }
713 echo '</div>';
714
715 echo '<div class="spf-header-right">';
716
717 echo ( $has_nav && $this->args['show_all_options'] ) ? '<div class="spf-expand-all" title="' . esc_html__( 'show all options', 'smart-post-show' ) . '"><i class="fa fa-outdent"></i></div>' : '';
718
719 echo ( $this->args['show_search'] ) ? '<div class="spf-search"><input type="text" name="spf-search" placeholder="' . esc_html__( 'Search option(s)', 'smart-post-show' ) . '" autocomplete="off" /></div>' : '';
720 if ( $show_buttons ) {
721 echo '<div class="spf-buttons">';
722 echo '<input type="submit" name="' . esc_attr( $this->unique ) . '[_nonce][save]" class="button button-primary spf-save' . esc_attr( $ajax_class ) . '" value="' . esc_html__( 'Save', 'smart-post-show' ) . '" data-save="' . esc_html__( 'Saving...', 'smart-post-show' ) . '">';
723 echo ( $this->args['show_reset_section'] ) ? '<input type="submit" name="spf_transient[reset_section]" class="button button-secondary spf-reset-section spf-confirm" value="' . esc_html__( 'Reset Section', 'smart-post-show' ) . '" data-confirm="' . esc_html__( 'Are you sure to reset this section options?', 'smart-post-show' ) . '">' : '';
724 echo ( $this->args['show_reset_all'] ) ? '<input type="submit" name="spf_transient[reset]" class="button spf-reset-all spf-confirm" value="' . esc_html__( 'Reset All', 'smart-post-show' ) . '" data-confirm="' . esc_html__( 'Are you sure to reset all options?', 'smart-post-show' ) . '">' : '';
725 echo '</div>';
726 }
727 echo '</div>';
728
729 echo '<div class="clear"></div>';
730 echo '</div>';
731 echo '</div>';
732
733 echo '<div class="spf-wrapper' . esc_attr( $show_all ) . '">';
734
735 if ( $has_nav ) {
736 echo '<div class="spf-nav spf-nav-options">';
737
738 echo '<ul>';
739
740 $tab_key = 1;
741
742 foreach ( $this->pre_tabs as $tab ) {
743
744 $tab_error = $this->error_check( $tab );
745 $tab_icon = ( ! empty( $tab['icon'] ) ) ? '<i class="' . $tab['icon'] . '"></i>' : '';
746
747 if ( ! empty( $tab['subs'] ) ) {
748
749 echo '<li class="spf-tab-depth-0">';
750
751 echo '<a href="#tab=' . esc_attr( $tab_key ) . '" class="spf-arrow">' . wp_kses_post( $tab_icon ) . esc_html( $tab['title'] ) . esc_html( $tab_error ) . '</a>';
752
753 echo '<ul>';
754
755 foreach ( $tab['subs'] as $sub ) {
756
757 $sub_error = $this->error_check( $sub );
758 $sub_icon = ( ! empty( $sub['icon'] ) ) ? '<i class="' . $sub['icon'] . '"></i>' : '';
759
760 echo '<li class="spf-tab-depth-1"><a id="spf-tab-link-' . esc_attr( $tab_key ) . '" href="#tab=' . esc_attr( $tab_key ) . '">' . wp_kses_post( $sub_icon ) . esc_html( $sub['title'] ) . esc_html( $sub_error ) . '</a></li>';
761
762 $tab_key++;
763 }
764
765 echo '</ul>';
766
767 echo '</li>';
768
769 } else {
770
771 echo '<li class="spf-tab-depth-0"><a id="spf-tab-link-' . esc_attr( $tab_key ) . '" href="#tab=' . esc_attr( $tab_key ) . '">' . wp_kses_post( $tab_icon ) . esc_html( $tab['title'] ) . esc_html( $tab_error ) . '</a></li>';
772
773 $tab_key++;
774 }
775 }
776
777 echo '</ul>';
778
779 echo '</div>';
780
781 }
782
783 echo '<div class="spf-content">';
784
785 echo '<div class="spf-sections">';
786
787 $section_key = 1;
788
789 foreach ( $this->pre_sections as $section ) {
790
791 $onload = ( ! $has_nav ) ? ' spf-onload' : '';
792 $section_icon = ( ! empty( $section['icon'] ) ) ? '<i class="spf-icon ' . $section['icon'] . '"></i>' : '';
793
794 echo '<div id="spf-section-' . esc_attr( $section_key ) . '" class="spf-section' . esc_attr( $onload ) . '">';
795 echo ( $has_nav ) ? '<div class="spf-section-title"><h3>' . wp_kses_post( $section_icon ) . esc_html( $section['title'] ) . '</h3></div>' : '';
796 echo ( ! empty( $section['description'] ) ) ? '<div class="spf-field spf-section-description">' . esc_html( $section['description'] ) . '</div>' : '';
797
798 if ( ! empty( $section['fields'] ) ) {
799
800 foreach ( $section['fields'] as $field ) {
801
802 $is_field_error = $this->error_check( $field );
803
804 if ( ! empty( $is_field_error ) ) {
805 $field['_error'] = $is_field_error;
806 }
807
808 $value = ( ! empty( $field['id'] ) && isset( $this->options[ $field['id'] ] ) ) ? $this->options[ $field['id'] ] : '';
809
810 SP_PC::field( $field, $value, $this->unique, 'options' );
811
812 }
813 } else {
814
815 echo '<div class="spf-no-option spf-text-muted">' . esc_html__( 'No option provided by developer.', 'smart-post-show' ) . '</div>';
816
817 }
818
819 echo '</div>';
820
821 $section_key++;
822 }
823
824 echo '</div>';
825
826 echo '<div class="clear"></div>';
827
828 echo '</div>';
829
830 echo '<div class="spf-nav-background"></div>';
831
832 echo '</div>';
833
834 if ( ! empty( $this->args['show_footer'] ) ) {
835
836 echo '<div class="spf-footer">';
837
838 echo '<div class="spf-buttons">';
839 echo '<input type="submit" name="spf_transient[save]" class="button button-primary spf-save' . esc_attr( $ajax_class ) . '" value="' . esc_html__( 'Save', 'smart-post-show' ) . '" data-save="' . esc_html__( 'Saving...', 'smart-post-show' ) . '">';
840 echo ( $this->args['show_reset_section'] ) ? '<input type="submit" name="spf_transient[reset_section]" class="button button-secondary spf-reset-section spf-confirm" value="' . esc_html__( 'Reset Section', 'smart-post-show' ) . '" data-confirm="' . esc_html__( 'Are you sure to reset this section options?', 'smart-post-show' ) . '">' : '';
841 echo ( $this->args['show_reset_all'] ) ? '<input type="submit" name="spf_transient[reset]" class="button spf-reset-all spf-confirm" value="' . esc_html__( 'Reset All', 'smart-post-show' ) . '" data-confirm="' . esc_html__( 'Are you sure to reset all options?', 'smart-post-show' ) . '">' : '';
842 echo '</div>';
843
844 echo ( ! empty( $this->args['footer_text'] ) ) ? '<div class="spf-copyright">' . esc_html( $this->args['footer_text'] ) . '</div>' : '';
845
846 echo '<div class="clear"></div>';
847 echo '</div>';
848
849 }
850
851 echo '</form>';
852
853 echo '</div>';
854
855 echo '<div class="clear"></div>';
856
857 echo ( ! empty( $this->args['footer_after'] ) ) ? wp_kses_post( $this->args['footer_after'] ) : '';
858
859 echo '</div>';
860
861 }
862 }
863 }
864