PluginProbe ʕ •ᴥ•ʔ
Strong Testimonials / 3.2.8
Strong Testimonials v3.2.8
3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.0.1 2.30.9 2.31.10 2.32 2.32.1 2.32.2 2.32.3 2.32.4 2.33 2.34 2.35 2.36 2.37 2.38 2.38.1 2.39 2.39.1 2.39.2 2.39.3 2.40.0 2.40.1 2.40.2 2.40.3 2.40.4 2.40.5 2.40.6 2.40.7 2.41.0 2.41.1 2.50.0 2.50.1 2.50.2 2.50.3 2.50.4 2.51.0 2.51.1 2.51.2 2.51.3 2.51.4 2.51.5 2.51.6 2.51.7 2.51.8 2.51.9 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.20 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.17 3.2.18 3.2.19 3.2.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0
strong-testimonials / includes / class-strong-testimonials-render.php
strong-testimonials / includes Last commit date
elementor 1 year ago logs 1 year ago strong-testimonials-beaver-block 1 year ago submodules 1 year ago class-strong-gutemberg.php 1 year ago class-strong-log.php 1 year ago class-strong-mail.php 1 year ago class-strong-testimonials-average-shortcode.php 1 year ago class-strong-testimonials-count-shortcode.php 1 year ago class-strong-testimonials-form.php 1 year ago class-strong-testimonials-order.php 1 year ago class-strong-testimonials-privacy.php 1 year ago class-strong-testimonials-render.php 1 year ago class-strong-testimonials-templates.php 1 year ago class-strong-testimonials-view-shortcode.php 1 year ago class-strong-testimonials-view-widget.php 1 year ago class-strong-view-display.php 1 year ago class-strong-view-form.php 1 year ago class-strong-view-slideshow.php 1 year ago class-strong-view.php 1 year ago class-walker-strong-category-checklist-front.php 1 year ago deprecated.php 1 year ago filters.php 1 year ago functions-activation.php 1 year ago functions-content.php 1 year ago functions-image.php 1 year ago functions-rating.php 1 year ago functions-template-form.php 1 year ago functions-template.php 1 year ago functions-views.php 1 year ago functions.php 1 year ago l10n-polylang.php 1 year ago l10n-wpml.php 1 year ago post-types.php 1 year ago retro.php 1 year ago scripts.php 1 year ago
class-strong-testimonials-render.php
723 lines
1 <?php
2 /**
3 * Class Strong_Testimonials_Render
4 *
5 * @since 2.28.0
6 */
7 class Strong_Testimonials_Render {
8
9 public $styles = array();
10
11 public $scripts = array();
12
13 public $script_vars = array();
14
15 public $css = array();
16
17 public $shortcode;
18
19 public $view_defaults = array();
20
21 public $view_atts = array();
22
23 public $query;
24
25 /**
26 * Strong_Testimonials_Render constructor.
27 */
28 public function __construct() {
29 $this->set_view_defaults();
30 $this->set_shortcodes();
31 $this->add_enqueue_actions();
32 }
33
34 /**
35 * Set the defaults for a view.
36 */
37 public function set_view_defaults() {
38 $this->view_defaults = wpmtst_get_view_default();
39 }
40
41 /**
42 * Get the shortcode defaults.
43 *
44 * @return array
45 */
46 public function get_view_defaults() {
47 return $this->view_defaults;
48 }
49
50 /**
51 * Set shortcode.
52 */
53 public function set_shortcodes() {
54 $this->shortcode = WPMST()->shortcode->get_shortcode();
55 }
56
57 /**
58 * Store view attributes.
59 *
60 * @param $atts
61 */
62 public function set_atts( $atts ) {
63 $this->view_atts = $atts;
64 }
65
66 /**
67 * Load scripts and styles.
68 *
69 * @since 2.28.0
70 */
71 private function add_enqueue_actions() {
72 $options = get_option( 'wpmtst_compat_options' );
73
74 /**
75 * Fallback.
76 * Provision each view when the shortcode is rendered.
77 * Enqueue both stylesheets and scripts in footer.
78 * _!_ Required for template function. _!_
79 */
80 add_action( 'wpmtst_view_rendered', array( $this, 'view_rendered' ) );
81 add_action( 'wpmtst_form_rendered', array( $this, 'view_rendered' ) );
82 add_action( 'wpmtst_form_success', array( $this, 'view_rendered' ) );
83
84 // We need to also check if page_loading is set to `advanced` in order for us to take into consideration the `prerender` option
85 if ( isset( $options['prerender'] ) && isset( $options['page_loading'] ) && 'advanced' === isset( $options['page_loading'] ) ) {
86 switch ( $options['prerender'] ) {
87 case 'none':
88 /**
89 * Use fallback.
90 */
91 break;
92
93 case 'all':
94 /**
95 * Provision all views.
96 * Enqueue stylesheets in head, scripts in footer.
97 */
98 add_action( 'wp_enqueue_scripts', array( $this, 'provision_all_views' ), 1 );
99 add_action( 'wp_enqueue_scripts', array( $this, 'view_rendered' ) );
100 break;
101
102 default:
103 /**
104 * Provision views in current page only.
105 * Enqueue stylesheets in head, scripts in footer.
106 */
107 $this->provision_current_page();
108 add_action( 'wp_enqueue_scripts', array( $this, 'view_rendered' ) );
109 }
110 }
111 }
112
113 /**
114 * Find shortcodes in content and prerender the view.
115 *
116 * In order to load stylesheets in normal sequence to prevent FOUC.
117 */
118 private function provision_current_page() {
119 // Look for our shortcodes in post content and widgets.
120 add_action( 'wp_enqueue_scripts', array( $this, 'find_views' ), 1 );
121 add_action( 'wp_enqueue_scripts', array( $this, 'find_views_in_postmeta' ), 1 );
122 add_action( 'wp_enqueue_scripts', array( $this, 'find_views_in_postexcerpt' ), 1 );
123 add_action( 'wp_enqueue_scripts', array( $this, 'find_widgets' ), 1 );
124
125 // Page Builder by Site Origin
126 if ( defined( 'SITEORIGIN_PANELS_VERSION' ) ) {
127 add_action( 'wp_enqueue_scripts', array( $this, 'find_pagebuilder_widgets' ), 1 );
128 }
129
130 // Beaver Builder
131 if ( defined( 'FL_BUILDER_VERSION' ) ) {
132 add_action( 'wp_enqueue_scripts', array( $this, 'find_beaverbuilder_widgets' ), 1 );
133 }
134
135 // Black Studio TinyMCE Widget
136 if ( class_exists( 'Black_Studio_TinyMCE_Plugin' ) ) {
137 add_action( 'wp_enqueue_scripts', array( $this, 'find_blackstudio_widgets' ), 1 );
138 }
139 }
140
141 /**
142 * Provision all views.
143 *
144 * @since 2.28.0
145 */
146 public function provision_all_views() {
147 $views = wpmtst_get_views();
148 foreach ( $views as $view ) {
149 // Array( [id] => 1, [name] => TEST, [value] => {serialized_array} )
150 $view_data = maybe_unserialize( $view['value'] );
151 if ( isset( $view_data['mode'] ) && 'single_template' !== $view_data['mode'] ) {
152 $atts = array(
153 'id' => $view['id'],
154 'view' => $view['id'],
155 );
156 $this->prerender( $atts );
157 }
158 }
159 }
160
161 /**
162 * Load stylesheet and scripts.
163 *
164 * Refer to add_enqueue_actions() for sequence.
165 *
166 * For compatibility with
167 * (1) page builders,
168 * (2) plugins like [Posts For Page] and [Custom Content Shortcode]
169 * that pull in other posts so this plugin cannot prerender them,
170 * (3) using the form in popup makers.
171 */
172 public function view_rendered() {
173 $this->load_styles();
174 $this->load_scripts();
175
176 /**
177 * Print script variables on footer hook.
178 * @since 2.25.2
179 */
180 add_action( 'wp_footer', array( $this, 'view_rendered_after' ) );
181 }
182
183 /**
184 * Add script variables only after view is rendered.
185 * To prevent duplicate variables.
186 *
187 * @since 2.24.1
188 */
189 public function view_rendered_after() {
190 $this->localize_scripts();
191 }
192
193 /**
194 * Add a stylesheet handle for enqueueing.
195 *
196 * @access private
197 *
198 * @param string $style_name The stylesheet handle.
199 *
200 *
201 */
202 public function add_style( $style_name ) {
203
204 if ( ! in_array( $style_name, $this->styles, true ) ) {
205 $this->styles[] = $style_name;
206 }
207 }
208
209 /**
210 * Add a script handle for enqueueing.
211 *
212 * @param string $script_name The script handle.
213 *
214 * @since 2.17.4 Using script handle as key.
215 */
216 public function add_script( $script_name ) {
217 $this->scripts[ $script_name ] = $script_name;
218 }
219
220 /**
221 * Add a script variable for localizing.
222 *
223 * @param string $script_name The script handle.
224 * @param string $var_name The script variable name.
225 * @param array $var The script variable.
226 *
227 * @since 2.17.5 Replace using variable name as key.
228 */
229 public function add_script_var( $script_name, $var_name, $var_val ) {
230 unset( $this->script_vars[ $var_name ] );
231 $this->script_vars[ $var_name ] = array(
232 'script_name' => $script_name,
233 'var_name' => $var_name,
234 'var' => $var_val,
235 );
236 }
237
238 /**
239 * Enqueue stylesheets for the view being processed.
240 *
241 * @since 2.22.3
242 */
243 public function load_styles() {
244 $styles = apply_filters( 'wpmtst_styles', $this->styles );
245 if ( $styles ) {
246 foreach ( $styles as $key => $style ) {
247 if ( ! wp_style_is( $style ) ) {
248 wp_enqueue_style( $style );
249 }
250 }
251 }
252 }
253
254 /**
255 * Enqueue scripts for the view being processed.
256 *
257 * @since 2.22.3
258 */
259 public function load_scripts() {
260 $scripts = apply_filters( 'wpmtst_scripts', $this->scripts );
261 if ( $scripts ) {
262 foreach ( $scripts as $key => $script ) {
263 if ( ! wp_script_is( $script ) ) {
264 wp_enqueue_script( $script );
265 }
266 }
267 }
268 }
269
270 /**
271 * Print script variables for the view being processed.
272 *
273 * @since 2.22.3
274 */
275 public function localize_scripts() {
276 $vars = apply_filters( 'wpmtst_script_vars', $this->script_vars );
277 if ( $vars ) {
278 foreach ( $vars as $key => $var ) {
279 wp_localize_script( $var['script_name'], $var['var_name'], $var['var'] );
280 }
281 }
282 }
283
284 /**
285 * Check the content for our shortcode.
286 *
287 * @param $content
288 *
289 * @return bool
290 */
291 private function check_content( $content ) {
292 if ( false === strpos( $content, '[' . $this->shortcode ) ) {
293 return false;
294 }
295
296 return true;
297 }
298
299 /**
300 * Check and process a widget.
301 *
302 * @since 2.28.0
303 *
304 * @param $widget
305 */
306 private function check_widget( $widget ) {
307 if ( isset( $widget['view'] ) && $widget['view'] ) {
308 $atts = array( 'view' => $widget['view'] );
309 $this->prerender( $atts );
310 }
311 }
312
313 /**
314 * Build list of all shortcode views on a page.
315 *
316 * @access public
317 */
318 public function find_views() {
319 global $post;
320 if ( empty( $post ) ) {
321 return;
322 }
323
324 $content = $post->post_content;
325 if ( ! $this->check_content( $content ) ) {
326 return;
327 }
328
329 $this->process_content( $content );
330 }
331
332 /**
333 * Build list of all shortcode views in a page's meta fields.
334 *
335 * To handle page builders that store shortcodes and widgets in post meta.
336 *
337 * @access public
338 * @since 1.15.11
339 */
340 public function find_views_in_postmeta() {
341 global $post;
342 if ( empty( $post ) ) {
343 return;
344 }
345
346 $meta_content = get_post_meta( $post->ID );
347 $meta_content_serialized = maybe_serialize( $meta_content );
348 if ( ! $this->check_content( $meta_content_serialized ) ) {
349 return;
350 }
351
352 $this->process_content( $meta_content_serialized );
353 }
354
355 /**
356 * Build list of all shortcode views in a page's excerpt.
357 *
358 * WooCommerce stores product short description in post_excerpt field.
359 *
360 * @access public
361 * @since 1.15.12
362 */
363 public function find_views_in_postexcerpt() {
364 global $post;
365 if ( empty( $post ) ) {
366 return;
367 }
368
369 if ( ! $this->check_content( $post->post_excerpt ) ) {
370 return;
371 }
372
373 $this->process_content( $post->post_excerpt );
374 }
375
376 /**
377 * Find widgets in a page to gather styles, scripts and script vars.
378 *
379 * For standard widgets NOT in [Page Builder by SiteOrigin] panels.
380 *
381 * Thanks to Matthew Harris for catching strict pass-by-reference error
382 * on $id = array_pop( explode( '-', $widget_name ) ).
383 * @link https://github.com/cdillon/strong-testimonials/issues/3
384 *
385 * @access public
386 */
387 public function find_widgets() {
388 // Get all widgets
389 $all_widgets = get_option( 'sidebars_widgets' );
390 if ( ! $all_widgets ) {
391 return;
392 }
393
394 // Get active strong widgets
395 $strong_widgets = get_option( 'widget_strong-testimonials-view-widget' );
396
397 foreach ( $all_widgets as $sidebar => $widgets ) {
398 // active widget areas only
399 if ( ! $widgets || empty( $widgets ) || 'wp_inactive_widgets' === $sidebar || 'array_version' === $sidebar ) {
400 continue;
401 }
402
403 foreach ( $widgets as $key => $widget_name ) {
404 if ( 0 === strpos( $widget_name, 'strong-testimonials-view-widget-' ) ) {
405 // Our plugin widget
406
407 if ( $strong_widgets ) {
408 $name_parts = explode( '-', $widget_name );
409 $id = array_pop( $name_parts );
410
411 if ( isset( $strong_widgets[ $id ] ) ) {
412 $widget = $strong_widgets[ $id ];
413 $this->check_widget( $widget );
414 }
415 }
416 } elseif ( 0 === strpos( $widget_name, 'text-' ) ) {
417 // Text widgets
418
419 // Get text widget content to scan for shortcodes.
420 $text_widgets = get_option( 'widget_text' );
421
422 if ( $text_widgets ) {
423 $name_parts = explode( '-', $widget_name );
424 $id = array_pop( $name_parts );
425
426 if ( isset( $text_widgets[ $id ] ) ) {
427 $widget = $text_widgets[ $id ];
428 if ( isset( $widget['text'] ) ) {
429 $this->process_content( $widget['text'] );
430 }
431 }
432 }
433 } elseif ( 0 === strpos( $widget_name, 'custom_html-' ) ) {
434 // Custom HTML widgets
435
436 // Get text widget content to scan for shortcodes.
437 $custom_html_widgets = get_option( 'widget_custom_html' );
438
439 if ( $custom_html_widgets ) {
440 $name_parts = explode( '-', $widget_name );
441 $id = array_pop( $name_parts );
442
443 if ( isset( $custom_html_widgets[ $id ] ) ) {
444 $widget = $custom_html_widgets[ $id ];
445 if ( isset( $widget['content'] ) ) {
446 $this->process_content( $widget['content'] );
447 }
448 }
449 }
450 }
451 } // foreach $widgets
452 } // foreach $all_widgets
453 }
454
455 /**
456 * Find widgets in a page to gather styles, scripts and script vars.
457 *
458 * For widgets in Page Builder by SiteOrigin.
459 */
460 public function find_pagebuilder_widgets() {
461 // Get all widgets
462 $panels_data = get_post_meta( get_the_ID(), 'panels_data', true );
463 if ( ! $panels_data ) {
464 return;
465 }
466
467 $all_widgets = $panels_data['widgets'];
468 if ( ! $all_widgets ) {
469 return;
470 }
471
472 // Need to group by cell to replicate Page Builder rendering order,
473 // whether these are Strong widgets or not.
474 $cells = array();
475 foreach ( $all_widgets as $key => $widget ) {
476 $cell_id = $widget['panels_info']['cell'];
477 $cells[ $cell_id ][] = $widget;
478 }
479
480 foreach ( $cells as $cell_widgets ) {
481 foreach ( $cell_widgets as $key => $widget ) {
482 if ( 'Strong_Testimonials_View_Widget' === $widget['panels_info']['class'] ) {
483 $this->check_widget( $widget );
484 } elseif ( 'WP_Widget_Text' === $widget['panels_info']['class'] ) {
485 // Is a Text widget?
486 $this->process_content( $widget['text'] );
487 }
488 }
489 }
490 }
491
492 /**
493 * Find widgets in a page to gather styles, scripts and script vars.
494 *
495 * For widgets in Beaver Builder.
496 */
497 public function find_beaverbuilder_widgets() {
498 $nodes = get_post_meta( get_the_ID(), '_fl_builder_data', true );
499 if ( ! $nodes ) {
500 return;
501 }
502
503 foreach ( $nodes as $key => $node ) {
504 if ( 'module' !== $node->type ) {
505 continue;
506 }
507
508 if ( 'widget' !== $node->settings->type ) {
509 continue;
510 }
511
512 if ( 'Strong_Testimonials_View_Widget' === $node->settings->widget ) {
513 $settings = (array) $node->settings;
514 $widget = (array) $settings['widget-strong-testimonials-view-widget'];
515 $this->check_widget( $widget );
516 }
517 }
518 }
519
520
521 /**
522 * Build list of all shortcode views in Black Studio TinyMCE Widget.
523 *
524 * @access public
525 * @since 1.16.14
526 */
527 public function find_blackstudio_widgets() {
528 global $post;
529 if ( empty( $post ) ) {
530 return;
531 }
532
533 $widget_content = get_option( 'widget_black-studio-tinymce' );
534 if ( ! $widget_content ) {
535 return;
536 }
537
538 $widget_content_serialized = maybe_serialize( $widget_content );
539 if ( ! $this->check_content( $widget_content_serialized ) ) {
540 return;
541 }
542
543 $this->process_content( $widget_content_serialized );
544 }
545
546 /**
547 * @param $atts
548 *
549 * @return bool
550 */
551 private function view_not_found( $atts ) {
552 return ( isset( $atts['view_not_found'] ) && $atts['view_not_found'] );
553 }
554
555 /**
556 * Process content for shortcodes.
557 *
558 * A combination of has_shortcode and shortcode_parse_atts.
559 * This seems to solve the unenclosed shortcode issue too.
560 *
561 * @access private
562 *
563 * @param string $content Post content or widget content.
564 */
565 private function process_content( $content ) {
566 preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER );
567 if ( empty( $matches ) ) {
568 return;
569 }
570
571 foreach ( $matches as $key => $shortcode ) {
572 if ( $this->shortcode === $shortcode[2] ) {
573 /**
574 * Retrieve all attributes from the shortcode.
575 *
576 * @since 1.16.13 Adding html_entity_decode.
577 */
578 $atts = shortcode_parse_atts( html_entity_decode( $shortcode[3] ) );
579 $this->prerender( $atts );
580 } else {
581 /**
582 * Recursively process nested shortcodes.
583 *
584 * Handles:
585 * Elegant Themes page builder.
586 *
587 * @since 1.15.5
588 */
589 $this->process_content( $shortcode[5] );
590 }
591 }
592 }
593
594 /**
595 * Prerender a view to gather styles, scripts, and script vars.
596 *
597 * Similar to Strong_Testimonials_View_Shortcode::render_view().
598 *
599 * @param $atts
600 *
601 * @since 1.25.0
602 * @since 2.16.0 Move all processing to Strong_View class.
603 */
604 public function prerender( $atts ) {
605 // Just like the shortcode function:
606 $atts = shortcode_atts(
607 array(),
608 $atts,
609 $this->shortcode
610 );
611 if ( $this->view_not_found( $atts ) ) {
612 return;
613 }
614
615 $this->set_atts( $atts );
616
617 switch ( $atts['mode'] ) {
618 case 'form':
619 $view = new Strong_View_Form( $atts );
620 break;
621 case 'slideshow':
622 $view = new Strong_View_Slideshow( $atts );
623 break;
624 default:
625 $view = new Strong_View_Display( $atts );
626 }
627 $view->process();
628
629 /**
630 * Allow themes and plugins to do stuff like add extra stylesheets.
631 *
632 * @since 2.22.0
633 */
634 do_action( 'wpmtst_view_found', $atts );
635 }
636
637 /**
638 * Parse view attributes.
639 *
640 * This is used by the shortcode filter and prerendering to assemble
641 * the view attributes.
642 *
643 * @param array $out The output array of shortcode attributes.
644 * @param array $pairs The supported attributes and their defaults.
645 * @param array $atts The user defined shortcode attributes.
646 *
647 * @return array
648 */
649 public function parse_view( $out, $pairs, $atts ) {
650 // Convert "id" to "view"
651 if ( isset( $atts['id'] ) && $atts['id'] ) {
652 $atts['view'] = $atts['id'];
653 unset( $atts['id'] );
654 } else {
655 return array_merge( array( 'view_not_found' => 1 ), $atts );
656 }
657
658 $atts['view'] = apply_filters( 'wpmtst_parse_view_id', $atts['view'] );
659
660 // Fetch the view
661 $view = wpmtst_get_view( $atts['view'] );
662
663 /**
664 * Add error attribute for shortcode handler.
665 *
666 * @since 1.21.0
667 */
668 if ( ! $view ) {
669 return array_merge( array( 'view_not_found' => 1 ), $atts );
670 }
671
672 $view_data = apply_filters( 'wpmtst_parse_view_data', unserialize( $view['value'] ), $atts['view'] );
673
674 /**
675 * Adjust for defaults.
676 *
677 * @since 2.30.0
678 */
679 if ( isset( $view_data['category'] ) && 'all' === $view_data['category'] ) {
680 $view_data['category'] = '';
681 }
682 if ( 'slideshow' === $view_data['mode'] ) {
683 unset( $view_data['id'] );
684 }
685
686 /**
687 * Saner approach.
688 *
689 * @since 2.30.0
690 */
691
692 // Post ID's override single ID, category, and count
693 if ( isset( $atts['post_ids'] ) ) {
694 $atts['id'] = $atts['post_ids'];
695 $atts['category'] = '';
696 $atts['count'] = -1;
697 }
698
699 // Override category slugs. This can handle a combination of slugs and ID's
700 if ( isset( $atts['category'] ) ) {
701 $cats = array();
702 $items = explode( ',', $atts['category'] );
703 foreach ( $items as $item ) {
704 if ( is_numeric( $item ) ) {
705 $cats[] = $item;
706 } else {
707 $term = get_term_by( 'slug', $item, 'wpm-testimonial-category' );
708 if ( $term ) {
709 $cats[] = $term->term_id;
710 }
711 }
712 }
713 if ( $cats ) {
714 $atts['category'] = implode( ',', $cats );
715 }
716 }
717
718 $out = array_merge( $this->get_view_defaults(), $view_data, $atts );
719
720 return $out;
721 }
722 }
723