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

947 lines 30.1 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 exit; // Exit if accessed directly.
11 }
12
13 if ( ! class_exists( 'SP_PC_Options' ) ) {
14 /**
15 * Options Class
16 *
17 * @since 1.0.0
18 * @version 1.0.0
19 */
20 class SP_PC_Options extends SP_PC_Abstract {
21
22 /**
23 * Unique ID/Name
24 *
25 * @var string
26 */
27 public $unique = '';
28 /**
29 * Notice.
30 *
31 * @var string
32 */
33 public $notice = '';
34 /**
35 * Abstract.
36 *
37 * @var string
38 */
39 public $abstract = 'options';
40 /**
41 * Setions.
42 *
43 * @var array
44 */
45 public $sections = array();
46 /**
47 * Options
48 *
49 * @var array
50 */
51 public $options = array();
52
53 /**
54 * Errors.
55 *
56 * @var array
57 */
58 public $errors = array();
59
60 /**
61 * Pre tabs.
62 *
63 * @var array
64 */
65 public $pre_tabs = array();
66
67 /**
68 * Pre fields.
69 *
70 * @var array
71 */
72 public $pre_fields = array();
73
74 /**
75 * Pre sections.
76 *
77 * @var array
78 */
79 public $pre_sections = array();
80
81 /**
82 * Default arguments.
83 *
84 * @var array
85 */
86 public $args = array(
87
88 // framework title.
89 'framework_title' => 'SPF Framework <small>by SP</small>',
90 'framework_class' => '',
91
92 // menu settings.
93 'menu_title' => '',
94 'menu_slug' => '',
95 'menu_type' => 'menu',
96 // 'menu_capability' => 'manage_options', It's implemented in add_admin_menu()
97 'menu_icon' => null,
98 'menu_position' => null,
99 'menu_hidden' => false,
100 'menu_parent' => '',
101
102 // menu extras.
103 'show_bar_menu' => true,
104 'show_sub_menu' => true,
105 'show_network_menu' => true,
106 'show_in_customizer' => false,
107
108 'show_search' => true,
109 'show_reset_all' => true,
110 'show_reset_section' => true,
111 'show_footer' => true,
112 'show_all_options' => true,
113 'sticky_header' => true,
114 'save_defaults' => true,
115 'ajax_save' => true,
116
117 // admin bar menu settings.
118 'admin_bar_menu_icon' => '',
119 'admin_bar_menu_priority' => 80,
120
121 // footer.
122 'footer_text' => '',
123 'footer_after' => '',
124 'footer_credit' => '',
125
126 // database model.
127 'database' => '', // options, transient, theme_mod, network.
128 'transient_time' => 0,
129
130 // contextual help.
131 'contextual_help' => array(),
132 'contextual_help_sidebar' => '',
133
134 // typography options.
135 'enqueue_webfont' => true,
136 'async_webfont' => false,
137
138 // others.
139 'output_css' => true,
140
141 // theme.
142 'theme' => 'dark',
143
144 'class' => '',
145
146 // external default values.
147 'defaults' => array(),
148
149 );
150
151 /**
152 * Run framework construct.
153 *
154 * @param string $key The filter unique key.
155 * @param array $params The parameters.
156 */
157 public function __construct( $key, $params = array() ) {
158
159 $this->unique = $key;
160 $this->args = apply_filters( "spf_{$this->unique}_args", wp_parse_args( $params['args'], $this->args ), $this );
161 $this->sections = apply_filters( "spf_{$this->unique}_sections", $params['sections'], $this );
162
163 // run only is admin panel options, avoid performance loss.
164 $this->pre_tabs = $this->pre_tabs( $this->sections );
165 $this->pre_fields = $this->pre_fields( $this->sections );
166 $this->pre_sections = $this->pre_sections( $this->sections );
167
168 $this->get_options();
169 $this->set_options();
170 $this->save_defaults();
171
172 add_action( 'admin_menu', array( &$this, 'add_admin_menu' ) );
173 add_action( 'admin_bar_menu', array( &$this, 'add_admin_bar_menu' ), $this->args['admin_bar_menu_priority'] );
174 add_action( 'wp_ajax_spf_' . $this->unique . '_ajax_save', array( &$this, 'ajax_save' ) );
175
176 if ( ! empty( $this->args['show_network_menu'] ) ) {
177 add_action( 'network_admin_menu', array( &$this, 'add_admin_menu' ) );
178 }
179
180 // wp enqeueu for typography and output css.
181 parent::__construct();
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 * Ajax save method.
323 *
324 * @return void
325 */
326 public function ajax_save() {
327
328 $result = $this->set_options( true );
329 if ( ! $result ) {
330 wp_send_json_error(
331 array(
332 'success' => false,
333 'error' => esc_html__(
334 'Error while saving.',
335 'post-carousel'
336 ),
337 )
338 );
339
340 } else {
341 wp_send_json_success(
342 array(
343 'success' => true,
344 'notice' => $this->notice,
345 'errors' => $this->errors,
346 )
347 );
348 }
349 }
350
351 /**
352 * Get default value.
353 *
354 * @param array $field The field array.
355 * @param array $options The options array.
356 * @return mixed
357 */
358 public function get_default( $field, $options = array() ) {
359
360 $default = ( isset( $this->args['defaults'][ $field['id'] ] ) ) ? $this->args['defaults'][ $field['id'] ] : '';
361 $default = ( isset( $field['default'] ) ) ? $field['default'] : $default;
362 $default = ( isset( $options[ $field['id'] ] ) ) ? $options[ $field['id'] ] : $default;
363
364 return $default;
365 }
366
367 /**
368 * Save defaults and set new fields value to main options.
369 *
370 * @return void
371 */
372 public function save_defaults() {
373
374 $tmp_options = $this->options;
375
376 foreach ( $this->pre_fields as $field ) {
377 if ( ! empty( $field['id'] ) ) {
378 $this->options[ $field['id'] ] = $this->get_default( $field, $this->options );
379 }
380 }
381
382 if ( $this->args['save_defaults'] && empty( $tmp_options ) ) {
383 $this->save_options( $this->options );
384 }
385 }
386
387 /**
388 * Sanitize Smart Post Show plugin options.
389 *
390 * @param array $options Raw options array.
391 * @return array Sanitized options array.
392 */
393 public function sanitize_options( $options ) {
394 if ( ! is_array( $options ) ) {
395 return array();
396 }
397
398 $sanitized = array();
399
400 foreach ( $options as $key => $value ) {
401 switch ( $key ) {
402 case 'spf_transient':
403 // Handle nested array.
404 $sanitized['spf_transient'] = array();
405 if ( is_array( $value ) ) {
406 foreach ( $value as $sub_key => $sub_val ) {
407 switch ( $sub_key ) {
408 case 'section':
409 $sanitized['spf_transient']['section'] = sanitize_text_field( $sub_val );
410 break;
411 default:
412 $sanitized['spf_transient'][ $sub_key ] = sanitize_text_field( $sub_val );
413 break;
414 }
415 }
416 }
417 break;
418 case 'spf_options_noncesp_post_carousel_settings':
419 case '_wp_http_referer':
420 $sanitized[ $key ] = sanitize_text_field( $value );
421 break;
422 case 'sp_post_carousel_settings':
423 $sanitized['sp_post_carousel_settings'] = array();
424 if ( is_array( $value ) ) {
425 foreach ( $value as $sub_key => $sub_val ) {
426 switch ( $sub_key ) {
427 case 'pcp_delete_all_data':
428 case 'pcp_swiper_js':
429 case 'pcp_swiper_css':
430 case 'pcp_fontawesome_css':
431 case 'accessibility':
432 // These should be boolean-like (0/1).
433 $sanitized['sp_post_carousel_settings'][ $sub_key ] = (int) $sub_val;
434 break;
435
436 case 'prev_slide_message':
437 case 'next_slide_message':
438 case 'first_slide_message':
439 case 'last_slide_message':
440 case 'pagination_bullet_message':
441 $sanitized['sp_post_carousel_settings'][ $sub_key ] = sanitize_text_field( $sub_val );
442 break;
443
444 case 'pcp_custom_css':
445 $sanitized['sp_post_carousel_settings'][ $sub_key ] = wp_strip_all_tags( $sub_val );
446 break;
447 case 'pcp_custom_js':
448 $sanitized['sp_post_carousel_settings'][ $sub_key ] = wp_kses_post( $sub_val );
449 break;
450 default:
451 $sanitized['sp_post_carousel_settings'][ $sub_key ] = sanitize_text_field( $sub_val );
452 break;
453 }
454 }
455 }
456 break;
457 default:
458 // Fallback sanitization.
459 $sanitized[ $key ] = is_scalar( $value ) ? wp_kses_post( $value ) : '';
460 break;
461 }
462 }
463
464 return $sanitized;
465 }
466
467
468
469
470 /**
471 * Set options.
472 *
473 * @param boolean $ajax The ajax save.
474 *
475 * @return mixed
476 */
477 public function set_options( $ajax = false ) {
478 // Check nonce.
479 $nonce = $ajax && ( ! empty( $_POST['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ( ( ! empty( $_POST[ 'spf_options_nonce' . $this->unique ] ) ) ? sanitize_text_field( wp_unslash( $_POST[ 'spf_options_nonce' . $this->unique ] ) ) : '' );
480 if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'spf_options_nonce' ) ) {
481 return false;
482 }
483 // XSS ok.
484 // No worries, This "POST" requests is sanitizing in the below.
485 $response = ( $ajax && ! empty( $_POST['data'] ) ) ? json_decode( wp_unslash( trim( $_POST['data'] ) ), true ) : wp_unslash( $_POST ); // phpcs:ignore -- Sanitized below.
486 $response = $this->sanitize_options( $response ); // Sanitize json response.
487 // Set variables.
488 $data = array();
489 $options = ( ! empty( $response[ $this->unique ] ) ) ? $response[ $this->unique ] : array();
490 $transient = ( ! empty( $response['spf_transient'] ) ) ? $response['spf_transient'] : array();
491 $importing = false;
492 $section_id = ( ! empty( $transient['section'] ) ) ? $transient['section'] : '';
493
494 if ( ! empty( $transient['reset'] ) ) {
495
496 foreach ( $this->pre_fields as $field ) {
497 if ( ! empty( $field['id'] ) ) {
498 $data[ $field['id'] ] = $this->get_default( $field );
499 }
500 }
501
502 $this->notice = esc_html__( 'Default options restored.', 'post-carousel' );
503
504 } elseif ( ! empty( $transient['reset_section'] ) && ! empty( $section_id ) ) {
505
506 if ( ! empty( $this->pre_sections[ $section_id - 1 ]['fields'] ) ) {
507
508 foreach ( $this->pre_sections[ $section_id - 1 ]['fields'] as $field ) {
509 if ( ! empty( $field['id'] ) ) {
510 $data[ $field['id'] ] = $this->get_default( $field );
511 }
512 }
513 }
514
515 $data = wp_parse_args( $data, $this->options );
516 $this->notice = esc_html__( 'Default options restored for only this section.', 'post-carousel' );
517
518 } else {
519 // Sanitize and validate.
520 foreach ( $this->pre_fields as $field ) {
521
522 if ( ! empty( $field['id'] ) ) {
523
524 $field_id = $field['id'];
525 $field_value = isset( $options[ $field_id ] ) ? $options[ $field_id ] : '';
526
527 // Ajax and Importing doing wp_unslash already.
528 if ( ! $ajax && ! $importing ) {
529 $field_value = wp_unslash( $field_value );
530 }
531
532 // sanitize.
533 if ( ! isset( $field['sanitize'] ) ) {
534 if ( is_array( $field_value ) ) {
535 $data[ $field_id ] = wp_kses_post_deep( $field_value );
536 } else {
537 $data[ $field_id ] = wp_kses_post( $field_value );
538 }
539 } elseif ( isset( $field['sanitize'] ) && is_callable( $field['sanitize'] ) ) {
540 $data[ $field_id ] = call_user_func( $field['sanitize'], $field_value );
541
542 } else {
543 $data[ $field_id ] = wp_kses_post( $field_value );
544
545 }
546
547 // Validate "post" request of field.
548 if ( isset( $field['validate'] ) && is_callable( $field['validate'] ) ) {
549
550 $has_validated = call_user_func( $field['validate'], $field_value );
551
552 if ( ! empty( $has_validated ) ) {
553 $data[ $field_id ] = ( isset( $this->options[ $field_id ] ) ) ? $this->options[ $field_id ] : '';
554 $this->errors[ $field_id ] = $has_validated;
555 }
556 }
557 }
558 }
559 }
560
561 $data = apply_filters( "spf_{$this->unique}_save", $data, $this );
562
563 do_action( "spf_{$this->unique}_save_before", $data, $this );
564
565 $this->options = $data;
566
567 $this->save_options( $data );
568
569 do_action( "spf_{$this->unique}_save_after", $data, $this );
570
571 if ( empty( $this->notice ) ) {
572 $this->notice = esc_html__( 'Settings saved.', 'post-carousel' );
573 }
574
575 return true;
576 }
577 /**
578 * Save options database.
579 *
580 * @param array $data The options values.
581 * @return void
582 */
583 public function save_options( $data ) {
584
585 if ( 'transient' === $this->args['database'] ) {
586 set_transient( $this->unique, $data, $this->args['transient_time'] );
587 } elseif ( 'theme_mod' === $this->args['database'] ) {
588 set_theme_mod( $this->unique, $data );
589 } elseif ( 'network' === $this->args['database'] ) {
590 update_site_option( $this->unique, $data );
591 } else {
592 update_option( $this->unique, $data );
593 }
594
595 do_action( "spf_{$this->unique}_saved", $data, $this );
596 }
597
598 /**
599 * Get options from database.
600 *
601 * @return mixed
602 */
603 public function get_options() {
604
605 if ( 'transient' === $this->args['database'] ) {
606 $this->options = get_transient( $this->unique );
607 } elseif ( 'theme_mod' === $this->args['database'] ) {
608 $this->options = get_theme_mod( $this->unique );
609 } elseif ( 'network' === $this->args['database'] ) {
610 $this->options = get_site_option( $this->unique );
611 } else {
612 $this->options = get_option( $this->unique );
613 }
614
615 if ( empty( $this->options ) ) {
616 $this->options = array();
617 }
618
619 return $this->options;
620 }
621
622 /**
623 * WP api – admin menu.
624 */
625 public function add_admin_menu() {
626 // Show plugin setting menu as per user role. – ShapedPlugin
627 // Use the hook 'sp_pc_dashboard_capability' to change user capability.
628 $menu_capability = apply_filters( 'sp_pc_dashboard_capability', 'manage_options' );
629 extract( $this->args ); // phpcs:ignore
630
631 if ( 'submenu' === $menu_type ) {
632
633 $menu_page = call_user_func( 'add_submenu_page', $menu_parent, $menu_title, $menu_title, $menu_capability, $menu_slug, array( &$this, 'add_options_html' ) );
634
635 } else {
636
637 $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 );
638
639 if ( ! empty( $this->args['show_sub_menu'] ) && count( $this->pre_tabs ) > 1 ) {
640
641 // create submenus.
642 $tab_key = 1;
643 foreach ( $this->pre_tabs as $section ) {
644
645 call_user_func( 'add_submenu_page', $menu_slug, $section['title'], $section['title'], $menu_capability, $menu_slug . '#tab=' . $tab_key, '__return_null' );
646
647 if ( ! empty( $section['subs'] ) ) {
648 $tab_key += ( count( $section['subs'] ) - 1 );
649 }
650
651 ++$tab_key;
652
653 }
654
655 remove_submenu_page( $menu_slug, $menu_slug );
656
657 }
658
659 if ( ! empty( $menu_hidden ) ) {
660 remove_menu_page( $menu_slug );
661 }
662 }
663
664 add_action( 'load-' . $menu_page, array( &$this, 'add_page_on_load' ) );
665 }
666
667 /**
668 * Add page on load.
669 */
670 public function add_page_on_load() {
671
672 if ( ! empty( $this->args['contextual_help'] ) ) {
673
674 $screen = get_current_screen();
675
676 foreach ( $this->args['contextual_help'] as $tab ) {
677 $screen->add_help_tab( $tab );
678 }
679
680 if ( ! empty( $this->args['contextual_help_sidebar'] ) ) {
681 $screen->set_help_sidebar( $this->args['contextual_help_sidebar'] );
682 }
683 }
684 }
685
686 /**
687 * Error check function.
688 */
689 /**
690 * Error Check function
691 *
692 * @param mixed $sections The section.
693 * @param string $err The error.
694 * @return statement
695 */
696 public function error_check( $sections, $err = '' ) {
697
698 if ( ! $this->args['ajax_save'] ) {
699
700 if ( ! empty( $sections['fields'] ) ) {
701 foreach ( $sections['fields'] as $field ) {
702 if ( ! empty( $field['id'] ) ) {
703 if ( array_key_exists( $field['id'], $this->errors ) ) {
704 $err = '<span class="spf-label-error">!</span>';
705 }
706 }
707 }
708 }
709
710 if ( ! empty( $sections['subs'] ) ) {
711 foreach ( $sections['subs'] as $sub ) {
712 $err = $this->error_check( $sub, $err );
713 }
714 }
715
716 if ( ! empty( $sections['id'] ) && array_key_exists( $sections['id'], $this->errors ) ) {
717 $err = $this->errors[ $sections['id'] ];
718 }
719 }
720
721 return $err;
722 }
723
724 /**
725 * Option page html output.
726 *
727 * @return void
728 */
729 public function add_options_html() {
730
731 $has_nav = ( count( $this->pre_tabs ) > 1 ) ? true : false;
732 $show_all = ( ! $has_nav ) ? ' spf-show-all' : '';
733 $show_buttons = isset( $this->args['show_buttons'] ) ? $this->args['show_buttons'] : true;
734 $menu_slug = isset( $this->args['menu_slug'] ) ? $this->args['menu_slug'] : '';
735 $ajax_class = ( $this->args['ajax_save'] ) ? ' spf-save-ajax' : '';
736 $sticky_class = ( $this->args['sticky_header'] ) ? ' spf-sticky-header' : '';
737 $wrapper_class = ( $this->args['framework_class'] ) ? ' ' . $this->args['framework_class'] : '';
738 $theme = ( $this->args['theme'] ) ? ' spf-theme-' . $this->args['theme'] : '';
739 $class = ( $this->args['class'] ) ? ' ' . $this->args['class'] : '';
740
741 if ( 'pcp_replace_layout' === $menu_slug ) {
742 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://wpsmartpost.com/pricing/?ref=1"><b>Upgrade To Pro</b></a></p></div>';
743 }
744
745 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 ) . '">';
746
747 if ( 'pcp_replace_layout' === $menu_slug ) {
748 echo '<div class="sp-smart-post-upgrade-to-pro-button">
749 <a href="https://wpsmartpost.com/pricing/?ref=1" target="_blank">Upgrade to Pro!</a>
750 </div>';
751 }
752 $notice_class = ( ! empty( $this->notice ) ) ? ' spf-form-show' : '';
753 $notice_text = ( ! empty( $this->notice ) ) ? $this->notice : '';
754
755 $error_class = ( ! empty( $this->errors ) ) ? ' spf-form-show' : '';
756
757 echo '<div class="spf-form-result spf-form-error' . esc_attr( $error_class ) . '">';
758 if ( ! empty( $this->errors ) ) {
759 foreach ( $this->errors as $error ) {
760 echo '<i class="spf-label-error">!</i> ' . esc_html( $error ) . '<br />';
761 }
762 }
763 echo '</div>';
764
765 echo '<div class="spf-container">';
766
767 echo '<form method="post" action="" enctype="multipart/form-data" id="spf-form" autocomplete="off">';
768
769 echo '<input type="hidden" class="spf-section-id" name="spf_transient[section]" value="1">';
770 wp_nonce_field( 'spf_options_nonce', 'spf_options_nonce' . $this->unique );
771
772 echo '<div class="spf-header' . esc_attr( $sticky_class ) . '">';
773 echo '<div class="spf-header-inner">';
774
775 echo '<div class="spf-header-left">';
776 if ( 'pcp_replace_layout' === $menu_slug ) {
777 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">
778 <style type="text/css">
779 .st0{fill:#D64224;}
780 </style>
781 <path class="st0" d="M0,69.3V0h69.4v18.6H18.6v50.7L0,69.3L0,69.3z M100,100H30.6V30.7H100V100z"/>
782 </svg>' . esc_html__( 'Replace Layout (Pro)', 'post-carousel' ) . '</h1>';
783 } elseif ( $show_buttons ) {
784 echo '<h1><svg width="30" height="30" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 100C0 44.772 44.772 0 100 0h600c55.229 0 100 44.772 100 100v600c0 55.229-44.771 100-100 100H100C44.772 800 0 755.229 0 700z" fill="url(#a)"/><path d="M115.997 471.75c0-24.162 19.587-43.75 43.749-43.75h164.498c24.162 0 43.75 19.588 43.75 43.75v164.5c0 24.163-19.588 43.75-43.75 43.75H159.746c-24.162 0-43.749-19.587-43.749-43.75zM423.993 246c0-69.588 56.411-126 125.998-126s125.998 56.412 125.998 126-56.411 126-125.998 126-125.998-56.412-125.998-126m-307.996-82.25c0-24.162 19.587-43.75 43.749-43.75h164.498c24.162 0 43.75 19.588 43.75 43.75v164.5c0 24.163-19.588 43.75-43.75 43.75H159.746c-24.162 0-43.749-19.587-43.749-43.75zm308.006 301.584c0-10.309 8.357-18.666 18.667-18.666h214.663c10.309 0 18.666 8.357 18.666 18.666s-8.357 18.667-18.666 18.667H442.67c-10.31 0-18.667-8.357-18.667-18.667m0 88.534c0-10.31 8.357-18.667 18.667-18.667h214.663c10.309 0 18.666 8.357 18.666 18.667 0 10.309-8.357 18.666-18.666 18.666H442.67c-10.31 0-18.667-8.357-18.667-18.666m0 88.533c0-10.309 8.357-18.667 18.667-18.667h214.663c10.309 0 18.666 8.358 18.666 18.667s-8.357 18.667-18.666 18.667H442.67c-10.31 0-18.667-8.358-18.667-18.667" fill="#fff"/><defs><linearGradient id="a" x1="400" y1="0" x2="400" y2="800" gradientUnits="userSpaceOnUse"><stop stop-color="#e1624b"/><stop offset="1" stop-color="#e1624b"/></linearGradient></defs></svg>' . esc_html__( 'Settings', 'post-carousel' ) . '</h1>';
785 } else {
786 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>';
787 }
788 echo '</div>';
789
790 echo '<div class="spf-header-right">';
791
792 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>' : '';
793
794 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>' : '';
795 if ( $show_buttons ) {
796 echo '<div class="spf-buttons">';
797 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' ) . '">';
798 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' ) . '">' : '';
799 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' ) . '">' : '';
800 echo '</div>';
801 }
802 echo '</div>';
803
804 echo '<div class="clear"></div>';
805 echo '</div>';
806 echo '</div>';
807
808 echo '<div class="spf-wrapper' . esc_attr( $show_all ) . '">';
809
810 if ( $has_nav ) {
811 echo '<div class="spf-nav spf-nav-options">';
812
813 echo '<ul>';
814
815 $tab_key = 1;
816
817 foreach ( $this->pre_tabs as $tab ) {
818
819 $tab_error = $this->error_check( $tab );
820 $tab_icon = ( ! empty( $tab['icon'] ) ) ? '<i class="' . $tab['icon'] . '"></i>' : '';
821
822 if ( ! empty( $tab['subs'] ) ) {
823
824 echo '<li class="spf-tab-depth-0">';
825
826 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>';
827
828 echo '<ul>';
829
830 foreach ( $tab['subs'] as $sub ) {
831
832 $sub_error = $this->error_check( $sub );
833 $sub_icon = ( ! empty( $sub['icon'] ) ) ? '<i class="' . $sub['icon'] . '"></i>' : '';
834
835 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>';
836
837 ++$tab_key;
838 }
839
840 echo '</ul>';
841
842 echo '</li>';
843
844 } else {
845
846 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>';
847
848 ++$tab_key;
849 }
850 }
851
852 echo '</ul>';
853
854 echo '</div>';
855
856 }
857
858 echo '<div class="spf-content">';
859
860 echo '<div class="spf-sections">';
861
862 $section_key = 1;
863
864 foreach ( $this->pre_sections as $section ) {
865
866 $onload = ( ! $has_nav ) ? ' spf-onload' : '';
867 $section_icon = ( ! empty( $section['icon'] ) ) ? '<i class="spf-icon ' . $section['icon'] . '"></i>' : '';
868
869 echo '<div id="spf-section-' . esc_attr( $section_key ) . '" class="spf-section' . esc_attr( $onload ) . '">';
870 echo ( $has_nav ) ? '<div class="spf-section-title"><h3>' . wp_kses_post( $section_icon ) . esc_html( $section['title'] ) . '</h3></div>' : '';
871 echo ( ! empty( $section['description'] ) ) ? '<div class="spf-field spf-section-description">' . esc_html( $section['description'] ) . '</div>' : '';
872
873 if ( ! empty( $section['fields'] ) ) {
874
875 foreach ( $section['fields'] as $field ) {
876
877 $is_field_error = $this->error_check( $field );
878
879 if ( ! empty( $is_field_error ) ) {
880 $field['_error'] = $is_field_error;
881 }
882
883 $value = ( ! empty( $field['id'] ) && isset( $this->options[ $field['id'] ] ) ) ? $this->options[ $field['id'] ] : '';
884
885 SP_PC::field( $field, $value, $this->unique, 'options' );
886
887 }
888 } else {
889
890 echo '<div class="spf-no-option spf-text-muted">' . esc_html__( 'No option provided by developer.', 'post-carousel' ) . '</div>';
891
892 }
893
894 echo '</div>';
895
896 ++$section_key;
897 }
898
899 echo '</div>';
900
901 echo '<div class="clear"></div>';
902
903 echo '</div>';
904
905 echo '<div class="spf-nav-background"></div>';
906
907 echo '</div>';
908
909 if ( ! empty( $this->args['show_footer'] ) ) {
910
911 echo '<div class="spf-footer">';
912
913 echo '<div class="spf-buttons">';
914 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' ) . '">';
915 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' ) . '">' : '';
916 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' ) . '">' : '';
917 echo '</div>';
918
919 echo ( ! empty( $this->args['footer_text'] ) ) ? '<div class="spf-copyright">' . esc_html( $this->args['footer_text'] ) . '</div>' : '';
920
921 echo '<div class="clear"></div>';
922 echo '</div>';
923
924 }
925
926 echo '</form>';
927
928 echo '</div>';
929
930 echo '<div class="clear"></div>';
931
932 echo ( ! empty( $this->args['footer_after'] ) ) ? wp_kses_post( $this->args['footer_after'] ) : '';
933
934 echo '</div>';
935
936 if ( 'pcp_settings' === $menu_slug ) {
937 echo '<a href="' . esc_url( admin_url( 'edit.php?post_type=sp_post_carousel&page=pcp_help#settings' ) ) . '" target="_blank" rel="noopener noreferrer" class="sp-pcp-classic-settings-page-link">
938 Back to Block Settings
939 <span class="sp-pcp-classic-settings-page-link-arrow">
940 <img src="' . esc_url( SP_PC_URL ) . 'admin/views/sp-framework/assets/img/block-settings-arrow.svg">
941 </span>
942 </a>';
943 }
944 }
945 }
946 }
947