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-average-shortcode.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-average-shortcode.php
424 lines
1 <?php
2 /**
3 * Class Strong_Testimonials_Average_Shortcode
4 *
5 * @since 2.31.0
6 */
7
8 class Strong_Testimonials_Average_Shortcode {
9
10 /**
11 * @var string
12 */
13 public $shortcode = 'testimonial_average_rating';
14
15 public function __construct() {
16 add_shortcode( $this->shortcode, array( $this, 'testimonial_average_rating_shortcode' ) );
17 }
18
19 /**
20 * Return average rating.
21 *
22 * @param $atts
23 * @param null $content
24 * @since 2.31.0
25 * @return string
26 */
27 public function testimonial_average_rating_shortcode( $atts, $content = null ) {
28 $pairs = array(
29 // parts
30 'average' => '',
31 'count' => '',
32 'stars' => '',
33 // style
34 'block' => '',
35 'centered' => '',
36 // HTML
37 'element' => 'div', // span
38 'class' => '', // on wrapper
39 // filters
40 'category' => '',
41 // rounded
42 'rounded' => '',
43 // field
44 'field' => '',
45 // decimals
46 'decimals' => 1,
47 );
48 $pairs = apply_filters( "wpmtst_shortcode_defaults__{$this->shortcode}", $pairs );
49
50 $atts = shortcode_atts( $pairs, normalize_empty_atts( $atts ), $this->shortcode );
51
52 // default parts
53 if ( ! $content ) {
54 $content = '{title} {stars} {summary}';
55 }
56
57 // set parts
58 preg_match_all( '#{(.*?)}#', $content, $parts );
59 /*
60 * Example:
61 *
62 * Array
63 * (
64 * [0] => Array
65 * (
66 * [0] => {title}
67 * [1] => {stars}
68 * [2] => {summary}
69 * )
70 *
71 * [1] => Array
72 * (
73 * [0] => title
74 * [1] => stars
75 * [2] => summary
76 * )
77 * )
78 */
79 $tag_list = $parts[0];
80 $tag_keys = $parts[1];
81 $parts = array_fill_keys( $tag_keys, '' );
82
83 // get posts
84 $args = array(
85 'posts_per_page' => -1,
86 'post_type' => 'wpm-testimonial',
87 'post_status' => 'publish',
88 'suppress_filters' => true,
89 );
90
91 // category
92 if ( $atts['category'] ) {
93 $args['tax_query'] = array(
94 array(
95 'taxonomy' => 'wpm-testimonial-category',
96 'field' => is_numeric( $atts['category'] ) ? 'id' : 'slug',
97 'terms' => $atts['category'],
98 ),
99 );
100 }
101
102 $args = apply_filters( 'wpmtst_query_args', $args, $atts );
103 $posts_array = get_posts( $args );
104
105 // get summary
106 $summary = $this->get_summary( $posts_array, $atts['field'], $atts['decimals'] );
107 /*
108 * Example:
109 *
110 * Array
111 * (
112 * [review_count] => 2
113 * [rating_count] => 2
114 * [rating_sum] => 10
115 * [rating_average] => 5
116 * [rating_detail] => Array
117 * (
118 * [5] => 2
119 * [4] => 0
120 * [3] => 0
121 * [2] => 0
122 * [1] => 0
123 * [0] => 0
124 * )
125 * )
126 */
127
128 // Want to build your own HTML? Return any truthy value to short-circuit this shortcode output.
129 $html = apply_filters( 'wpmtst_average_rating_pre_html', '', $atts, $summary );
130 if ( $html ) {
131 return $html;
132 }
133
134 // assemble classes
135 $class_list = array_filter( array_merge( array( 'strong-rating-wrapper', 'average' ), explode( ' ', $atts['class'] ) ) );
136 if ( $atts['block'] ) {
137 $class_list[] = 'block';
138 }
139 if ( $atts['centered'] ) {
140 $class_list[] = 'centered';
141 }
142
143 // round the rating if necessary
144 if ( ! empty( $atts['rounded'] ) ) {
145 $rating_average = number_format( $summary['rating_average'], 0 );
146 } else {
147 $rating_average = number_format( $summary['rating_average'], absint( $atts['decimals'] ) );
148 }
149
150 // title
151 if ( isset( $parts['title'] ) ) {
152 $parts['title'] = sprintf( '<span class="strong-rating-title">%s</span>', esc_html__( 'Average Rating:', 'strong-testimonials' ) );
153 }
154 if ( isset( $parts['title2'] ) ) {
155 /* translators: %s is a number */
156 $count = sprintf( _n( 'Average of %s Rating:', 'Average of %s Ratings:', $summary['rating_count'], 'strong-testimonials' ), $summary['rating_count'] );
157 $parts['title2'] = sprintf( '<span class="strong-rating-title">%s</span>', $count );
158 }
159
160 // stars
161 if ( isset( $parts['stars'] ) ) {
162 $parts['stars'] = $this->print_stars( $rating_average );
163 }
164
165 // average
166 if ( isset( $parts['average'] ) ) {
167 $parts['average'] = sprintf( '<span class="strong-rating-average">%s</span>', $rating_average );
168 }
169
170 // count
171 if ( isset( $parts['count'] ) ) {
172 $parts['count'] = sprintf( '<span class="strong-rating-count">%s</span>', $summary['rating_count'] );
173 }
174
175 // summary phrase
176 if ( isset( $parts['summary'] ) ) {
177
178 /* translators: %s is a number */
179 $average = sprintf( _n( '%s star', '%s stars', $rating_average, 'strong-testimonials' ), $rating_average );
180 /* translators: %s is a number */
181 $count = sprintf( _n( '(based on %s rating)', '(based on %s ratings)', $summary['rating_count'], 'strong-testimonials' ), $summary['rating_count'] );
182 $parts['summary'] = sprintf( '<span class="strong-rating-summary">%s</span>', $average . ' ' . $count );
183
184 } elseif ( isset( $parts['summary2'] ) ) {
185
186 /* translators: %s is a number */
187 $average = sprintf( _n( '%s star', '%s stars', $rating_average, 'strong-testimonials' ), $rating_average );
188 $parts['summary2'] = sprintf( '<span class="strong-rating-summary">%s</span>', $average );
189
190 }
191
192 // replace tags
193 foreach ( $tag_list as $key => $tag ) {
194 $content = str_replace( $tag, $parts[ $tag_keys[ $key ] ], $content );
195 }
196
197 $allowed_elements = array( 'span', 'p', 'i', 'div', 'li', 'ul', 'ol', 'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' );
198 $allowed_elements = apply_filters( 'wpmtst_allowed_shortcode_elements', $allowed_elements );
199 $element = in_array( $atts['element'], $allowed_elements, true ) ? esc_attr( $atts['element'] ) : 'div';
200
201 // assemble it.
202 $html = sprintf( '<%s class="%s">%s</%s>', esc_attr( $element ), esc_attr( implode( ' ', $class_list ) ), $content, esc_attr( $element ) );
203
204 wp_enqueue_style( 'wpmtst-rating-display' );
205
206 return apply_filters( 'wpmtst_average_rating_html', $html, $atts, $summary );
207 }
208
209 /**
210 * Calculate and return the average rating.
211 *
212 * @param $posts
213 * @since 1.1.0
214 * @return array|null
215 */
216 public function get_summary( $posts = null, $field = '', $decimals = 1 ) {
217 // Set a placeholder.
218 $average = array(
219 'review_count' => null,
220 'rating_count' => null,
221 'rating_sum' => null,
222 'rating_average' => null,
223 'rating_detail' => null,
224 );
225
226 if ( $posts ) {
227
228 // initialize totals
229 $review_count = count( $posts );
230 $rating_count = 0;
231 $rating_sum = 0;
232 // initial values for each rating
233 $rating_detail = array_fill_keys( array( 5, 4, 3, 2, 1, 0 ), 0 );
234
235 foreach ( $posts as $post ) {
236 // get rating value
237 $value = $this->get_rating_value( $post, $field );
238 // add to detail array
239 ++$rating_detail[ $value ];
240 // add to count and sum
241 if ( $value ) {
242 $rating_sum += $value;
243 ++$rating_count;
244 }
245 }
246
247 if ( $rating_count ) {
248
249 $rating_average = number_format( $rating_sum / $rating_count, absint( $decimals ) );
250 if ( 1 === absint( $decimals ) ) {
251 $rating_average = trim( $rating_average, '.0' );
252 }
253 $average = array(
254 'review_count' => number_format( $review_count ),
255 'rating_count' => number_format( $rating_count ),
256 'rating_sum' => number_format( $rating_sum ),
257 'rating_average' => $rating_average,
258 'rating_detail' => $rating_detail,
259 );
260 }
261 }
262
263 return $average;
264 }
265
266 /**
267 * Return the rating value for a single post.
268 *
269 * @param $post
270 * @since 1.1.0
271 * @return int|null
272 */
273 private function get_rating_value( $post, $field = '' ) {
274 if ( ! empty( $field ) ) {
275 if ( 'all' === $field ) {
276 $rating_fields = $this->find_all_rating_field();
277 } else {
278 $rating_fields = $this->find_rating_field( $field );
279 }
280 } else {
281 $rating_fields = $this->find_first_rating_field();
282 }
283 if ( $rating_fields ) {
284 $ratings = array();
285 foreach ( $rating_fields as $rating_field ) {
286 $rating = intval( get_post_meta( $post->ID, $rating_field['name'], true ) );
287 if ( ! $rating ) {
288 $rating = intval( $rating_field['default_display_value'] );
289 }
290 $ratings[] = $rating;
291 }
292 $rating = array_sum( $ratings ) / count( $ratings );
293 } else {
294 $rating = 5;
295 }
296 return $rating;
297 }
298
299 /**
300 * Find the first rating field.
301 *
302 * @since 1.1.0
303 * @return bool|int|string
304 */
305 private function find_first_rating_field() {
306 $fields = wpmtst_get_custom_fields();
307 foreach ( $fields as $key => $field ) {
308 if ( 'rating' === $field['input_type'] ) {
309 return array( $field );
310 }
311 }
312
313 return false;
314 }
315
316 /**
317 * Find specific rating field.
318 *
319 * @return bool|int|string
320 */
321 private function find_rating_field( $rating_field ) {
322 $fields = wpmtst_get_custom_fields();
323 foreach ( $fields as $key => $field ) {
324 if ( 'rating' === $field['input_type'] && $rating_field === $field['name'] ) {
325 return array( $field );
326 }
327 }
328
329 return false;
330 }
331
332 /**
333 * Find all rating field.
334 *
335 * @since 2.41.0
336 * @return bool|int|string
337 */
338 private function find_all_rating_field() {
339 $fields = wpmtst_get_custom_fields();
340 $rating = array();
341 foreach ( $fields as $key => $field ) {
342 if ( 'rating' === $field['input_type'] ) {
343 $rating[] = $field;
344 }
345 }
346
347 if ( ! empty( $rating ) ) {
348 return $rating;
349 }
350
351 return false;
352 }
353
354 /**
355 * Print the stars.
356 *
357 * @param float $rating Average rating.
358 * @param string $wrapper_class The container CSS class.
359 * @since 2.31.0
360 * @return string
361 */
362 public function print_stars( $rating = 0.0, $wrapper_class = 'strong-rating' ) {
363
364 $is_zero = ( 0.0 === (float) $rating ) ? ' current' : '';
365
366 $star_solid = wpmtst_get_star_svg( 'star_solid' );
367 $star_regular = wpmtst_get_star_svg( 'star_regular' );
368 $star_half = wpmtst_get_star_svg( 'star_half' );
369
370 $svg_args = array(
371 'svg' => array(
372 'class' => true,
373 'aria-hidden' => true,
374 'aria-labelledby' => true,
375 'role' => true,
376 'xmlns' => true,
377 'width' => true,
378 'height' => true,
379 'viewbox' => true, // <= Must be lower case!
380 'id' => true,
381 ),
382 'g' => array( 'fill' => true ),
383 'title' => array( 'title' => true ),
384 'path' => array(
385 'd' => true,
386 'fill' => true,
387 ),
388 'style' => array( 'type' => true ),
389 'span' => array(
390 'style' => array(),
391 'class' => array(),
392 ),
393 );
394
395 ob_start();
396 ?>
397 <span class="<?php echo esc_attr( $wrapper_class ); ?>">
398 <span class="star0 star<?php echo esc_attr( $is_zero ); ?>"></span>
399 <?php
400 if ( $is_zero ) {
401 echo str_repeat( '<span class="star" style="display: inline-block;" >' . $star_regular . '</span>', 5 );
402 } else {
403 for ( $i = 1; $i <= 5; $i++ ) {
404 if ( $i <= round( $rating ) ) {
405 $star_icon = $star_solid;
406 } else {
407 $star_icon = $star_regular;
408 }
409
410 if ( ( 0.9 >= $i - $rating ) && ( 0.1 <= $i - $rating ) ) {
411 $star_icon = $star_half;
412 }
413 echo wp_kses( sprintf( '<span class="star" style="display: inline-block;" >%s</span>', $star_icon ), $svg_args );
414 }
415 }
416 ?>
417 </span>
418 <?php
419 $html = apply_filters( 'wpmtst_average_rating_stars_html', ob_get_clean(), $rating );
420
421 return $html;
422 }
423 }
424