PluginProbe
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News / 2.3.6
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News v2.3.6
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.3.6, at admin/views/sp-framework/classes/options.class.php

859 lines 25.5 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 $ajax_class = ( $this->args['ajax_save'] ) ? ' spf-save-ajax' : '';
673 $sticky_class = ( $this->args['sticky_header'] ) ? ' spf-sticky-header' : '';
674 $wrapper_class = ( $this->args['framework_class'] ) ? ' ' . $this->args['framework_class'] : '';
675 $theme = ( $this->args['theme'] ) ? ' spf-theme-' . $this->args['theme'] : '';
676 $class = ( $this->args['class'] ) ? ' ' . $this->args['class'] : '';
677
678 echo '<div class="wrap"><h1>' . esc_html( $this->args['menu_title'] ) . '</h1></div>';
679 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 ) . '">';
680
681 $notice_class = ( ! empty( $this->notice ) ) ? ' spf-form-show' : '';
682 $notice_text = ( ! empty( $this->notice ) ) ? $this->notice : '';
683
684 echo '<div class="spf-form-result spf-form-success' . esc_attr( $notice_class ) . '">' . esc_html( $notice_text ) . '</div>';
685
686 $error_class = ( ! empty( $this->errors ) ) ? ' spf-form-show' : '';
687
688 echo '<div class="spf-form-result spf-form-error' . esc_attr( $error_class ) . '">';
689 if ( ! empty( $this->errors ) ) {
690 foreach ( $this->errors as $error ) {
691 echo '<i class="spf-label-error">!</i> ' . esc_html( $error ) . '<br />';
692 }
693 }
694 echo '</div>';
695
696 echo '<div class="spf-container">';
697
698 echo '<form method="post" action="" enctype="multipart/form-data" id="spf-form" autocomplete="off">';
699
700 echo '<input type="hidden" class="spf-section-id" name="spf_transient[section]" value="1">';
701 wp_nonce_field( 'spf_options_nonce', 'spf_options_nonce' . $this->unique );
702
703 echo '<div class="spf-header' . esc_attr( $sticky_class ) . '">';
704 echo '<div class="spf-header-inner">';
705
706 echo '<div class="spf-header-left">';
707 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"/><line fill="none" x1="-99" y1="-84" x2="-99" y2="-57"/><line fill="none" x1="-170" y1="61" x2="-170" y2="101"/></svg>' . esc_html__( 'Settings', 'smart-post-show' ) . '</h1>';
708 echo '</div>';
709
710 echo '<div class="spf-header-right">';
711
712 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>' : '';
713
714 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>' : '';
715
716 echo '<div class="spf-buttons">';
717 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' ) . '">';
718 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' ) . '">' : '';
719 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' ) . '">' : '';
720 echo '</div>';
721
722 echo '</div>';
723
724 echo '<div class="clear"></div>';
725 echo '</div>';
726 echo '</div>';
727
728 echo '<div class="spf-wrapper' . esc_attr( $show_all ) . '">';
729
730 if ( $has_nav ) {
731 echo '<div class="spf-nav spf-nav-options">';
732
733 echo '<ul>';
734
735 $tab_key = 1;
736
737 foreach ( $this->pre_tabs as $tab ) {
738
739 $tab_error = $this->error_check( $tab );
740 $tab_icon = ( ! empty( $tab['icon'] ) ) ? '<i class="' . $tab['icon'] . '"></i>' : '';
741
742 if ( ! empty( $tab['subs'] ) ) {
743
744 echo '<li class="spf-tab-depth-0">';
745
746 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>';
747
748 echo '<ul>';
749
750 foreach ( $tab['subs'] as $sub ) {
751
752 $sub_error = $this->error_check( $sub );
753 $sub_icon = ( ! empty( $sub['icon'] ) ) ? '<i class="' . $sub['icon'] . '"></i>' : '';
754
755 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>';
756
757 $tab_key++;
758 }
759
760 echo '</ul>';
761
762 echo '</li>';
763
764 } else {
765
766 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>';
767
768 $tab_key++;
769 }
770 }
771
772 echo '</ul>';
773
774 echo '</div>';
775
776 }
777
778 echo '<div class="spf-content">';
779
780 echo '<div class="spf-sections">';
781
782 $section_key = 1;
783
784 foreach ( $this->pre_sections as $section ) {
785
786 $onload = ( ! $has_nav ) ? ' spf-onload' : '';
787 $section_icon = ( ! empty( $section['icon'] ) ) ? '<i class="spf-icon ' . $section['icon'] . '"></i>' : '';
788
789 echo '<div id="spf-section-' . esc_attr( $section_key ) . '" class="spf-section' . esc_attr( $onload ) . '">';
790 echo ( $has_nav ) ? '<div class="spf-section-title"><h3>' . wp_kses_post( $section_icon ) . esc_html( $section['title'] ) . '</h3></div>' : '';
791 echo ( ! empty( $section['description'] ) ) ? '<div class="spf-field spf-section-description">' . esc_html( $section['description'] ) . '</div>' : '';
792
793 if ( ! empty( $section['fields'] ) ) {
794
795 foreach ( $section['fields'] as $field ) {
796
797 $is_field_error = $this->error_check( $field );
798
799 if ( ! empty( $is_field_error ) ) {
800 $field['_error'] = $is_field_error;
801 }
802
803 $value = ( ! empty( $field['id'] ) && isset( $this->options[ $field['id'] ] ) ) ? $this->options[ $field['id'] ] : '';
804
805 SP_PC::field( $field, $value, $this->unique, 'options' );
806
807 }
808 } else {
809
810 echo '<div class="spf-no-option spf-text-muted">' . esc_html__( 'No option provided by developer.', 'smart-post-show' ) . '</div>';
811
812 }
813
814 echo '</div>';
815
816 $section_key++;
817 }
818
819 echo '</div>';
820
821 echo '<div class="clear"></div>';
822
823 echo '</div>';
824
825 echo '<div class="spf-nav-background"></div>';
826
827 echo '</div>';
828
829 if ( ! empty( $this->args['show_footer'] ) ) {
830
831 echo '<div class="spf-footer">';
832
833 echo '<div class="spf-buttons">';
834 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' ) . '">';
835 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' ) . '">' : '';
836 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' ) . '">' : '';
837 echo '</div>';
838
839 echo ( ! empty( $this->args['footer_text'] ) ) ? '<div class="spf-copyright">' . esc_html( $this->args['footer_text'] ) . '</div>' : '';
840
841 echo '<div class="clear"></div>';
842 echo '</div>';
843
844 }
845
846 echo '</form>';
847
848 echo '</div>';
849
850 echo '<div class="clear"></div>';
851
852 echo ( ! empty( $this->args['footer_after'] ) ) ? wp_kses_post( $this->args['footer_after'] ) : '';
853
854 echo '</div>';
855
856 }
857 }
858 }
859