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

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