PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / 6.0.0
WP Popular Posts v6.0.0
4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 5.0.0 5.0.1 5.0.2 5.1.0 5.2.0 5.2.1 5.2.2 5.2.3 5.2.4 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.2.0 6.2.1 6.3.0 6.3.1 6.3.2 6.3.3 6.3.4 6.4.0 6.4.1 6.4.2 7.0.0 7.0.1 7.1.0 7.2.0 7.3.0 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.3.7 7.3.8 7.4.0 trunk 2.3.7 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.2 4.0.3 4.0.5 4.0.6
wordpress-popular-posts / src / Output.php
wordpress-popular-posts / src Last commit date
Activation 4 years ago Admin 4 years ago Block 4 years ago Container 4 years ago Front 4 years ago Rest 4 years ago Traits 4 years ago Widget 4 years ago Bootstrap.php 4 years ago Cache.php 4 years ago Helper.php 4 years ago I18N.php 4 years ago Image.php 4 years ago Output.php 4 years ago Query.php 4 years ago Settings.php 4 years ago Themer.php 4 years ago Translate.php 4 years ago WordPressPopularPosts.php 4 years ago deprecated.php 4 years ago template-tags.php 4 years ago
Output.php
977 lines
1 <?php
2 /**
3 * This class formats the HTML output of every popular posts listing.
4 *
5 *
6 * @package WordPressPopularPosts
7 * @author Hector Cabrera <me@cabrerahector.com>
8 */
9
10 namespace WordPressPopularPosts;
11
12 class Output {
13
14 /**
15 * Popular posts data.
16 *
17 * @since 4.0.0
18 * @var string
19 */
20 private $data;
21
22 /**
23 * HTML output.
24 *
25 * @since 4.0.0
26 * @var string
27 */
28 private $output;
29
30 /**
31 * Widget / shortcode settings.
32 *
33 * @since 4.0.0
34 * @var array
35 */
36 private $public_options = [];
37
38 /**
39 * Administrative settings.
40 *
41 * @since 2.3.3
42 * @var array
43 */
44 private $admin_options = [];
45
46 /**
47 * Default excerpt 'more' string.
48 *
49 * @since 4.2.1
50 * @var string
51 */
52 private $more;
53
54 /**
55 * Image object
56 *
57 * @since 4.0.2
58 * @var WordPressPopularPosts\Image
59 */
60 private $thumbnail;
61
62 /**
63 * Translate object.
64 *
65 * @var \WordPressPopularPosts\Translate $translate
66 * @access private
67 */
68 private $translate;
69
70 /**
71 * Themer object.
72 *
73 * @var \WordPressPopularPosts\Themer $themer
74 * @access private
75 */
76 private $themer;
77
78 /**
79 * WordPress Date format.
80 *
81 * @var string
82 * @access private
83 */
84 private $wp_date_format;
85
86 /**
87 * Constructor.
88 *
89 * @since 4.0.0
90 * @param array $public_options
91 * @param array $admin_options
92 * @param WordPressPopularPosts\Image $thumbnail
93 * @param WordPressPopularPosts\Translate $translate
94 * @param WordPressPopularPosts\Themer $themer
95 */
96 public function __construct(array $public_options, array $admin_options, Image $thumbnail, Translate $translate, Themer $themer)
97 {
98 $this->public_options = $public_options;
99 $this->admin_options = $admin_options;
100 $this->thumbnail = $thumbnail;
101 $this->translate = $translate;
102 $this->themer = $themer;
103
104 $this->more = '...';
105
106 $this->wp_date_format = get_option('date_format');
107
108 if ( ! $this->wp_date_format )
109 $this->wp_date_format = 'F j, Y';
110 }
111
112 /**
113 * Sets data.
114 *
115 * @since 5.0.0
116 * @param array
117 */
118 public function set_data(array $data = [])
119 {
120 $this->data = $data;
121 }
122
123 /**
124 * Sets public options.
125 *
126 * @since 5.0.0
127 * @param array
128 */
129 public function set_public_options(array $public_options = [])
130 {
131 $this->public_options = Helper::merge_array_r(
132 Settings::get('widget_options'),
133 $public_options
134 );
135 }
136
137 /**
138 * Output the HTML.
139 *
140 * @since 4.0.0
141 */
142 public function output()
143 {
144 echo $this->get_output();
145 }
146
147 /**
148 * Return the HTML.
149 *
150 * @since 4.0.0
151 * @return string
152 */
153 public function get_output()
154 {
155 $this->output = "\n" . ( WP_DEBUG ? '<!-- WordPress Popular Posts v' . WPP_VERSION . ( $this->admin_options['tools']['cache']['active'] ? ' - cached' : '' ) . ' -->' : '' ) . "\n" . $this->output;
156 return $this->output;
157 }
158
159 /**
160 * Build the HTML output.
161 *
162 * @since 4.0.0
163 */
164 public function build_output()
165 {
166 // Got some posts, format 'em!
167 if ( ! empty($this->data) ) {
168
169 $this->output = '';
170
171 // Allow WP themers / coders access to raw data
172 // so they can build their own output
173 if ( has_filter('wpp_custom_html') ) {
174 $this->output .= apply_filters('wpp_custom_html', $this->data, $this->public_options);
175 return;
176 }
177
178 if (
179 isset($this->public_options['theme']['name'])
180 && $this->public_options['theme']['name']
181 ) {
182 $this->output .= '<div class="popular-posts-sr">';
183
184 if ( @file_exists(get_stylesheet_directory() . '/wordpress-popular-posts/themes/' . $this->public_options['theme']['name'] . '/style.css') ) {
185 $theme_stylesheet = get_stylesheet_directory() . '/wordpress-popular-posts/themes/' . $this->public_options['theme']['name'] . '/style.css';
186 } else {
187 $theme_stylesheet = $this->themer->get_theme($this->public_options['theme']['name'])['path'] . '/style.css';
188 }
189
190 $theme_css_rules = wp_strip_all_tags(file_get_contents($theme_stylesheet), true);
191 $additional_styles = '';
192
193 if ( has_filter('wpp_additional_theme_styles') ) {
194 $additional_styles = wp_strip_all_tags(apply_filters('wpp_additional_theme_styles', '', $this->public_options['theme']['name']), true);
195
196 if ( $additional_styles )
197 $additional_styles = ' /* additional rules */ ' . $additional_styles;
198 }
199
200 $this->output .= '<style>' . $theme_css_rules . $additional_styles . '</style>';
201 }
202
203 /* Open HTML wrapper */
204 // Output a custom wrapper
205 if (
206 isset($this->public_options['markup']['custom_html'])
207 && $this->public_options['markup']['custom_html']
208 && isset($this->public_options['markup']['wpp-start'])
209 && isset($this->public_options['markup']['wpp-end'])
210 ){
211 $this->output .= "\n" . htmlspecialchars_decode($this->public_options['markup']['wpp-start'], ENT_QUOTES) ."\n";
212 }
213 // Output the default wrapper
214 else {
215
216 $classes = "wpp-list";
217
218 if ( $this->public_options['thumbnail']['active'] )
219 $classes .= " wpp-list-with-thumbnails";
220
221 $this->output .= "\n" . "<ul class=\"{$classes}\">" . "\n";
222
223 }
224
225 $position = 0;
226
227 // Format each post
228 foreach( $this->data as $post_object ) {
229 $position++;
230 $this->output .= $this->render_post($post_object, $position);
231 }
232
233 /* Close HTML wrapper */
234 // Output a custom wrapper
235 if (
236 isset($this->public_options['markup']['custom_html'])
237 && $this->public_options['markup']['custom_html']
238 && isset($this->public_options['markup']['wpp-start'])
239 && isset($this->public_options['markup']['wpp-end'])
240 ){
241 $this->output .= "\n" . htmlspecialchars_decode($this->public_options['markup']['wpp-end'], ENT_QUOTES) ."\n";
242 }
243 // Output default wrapper
244 else {
245 $this->output .= "</ul>" . "\n";
246 }
247
248 if (
249 isset($this->public_options['theme']['name'])
250 && $this->public_options['theme']['name']
251 ) {
252 $this->output .= "</div>";
253 }
254
255 }
256 // Got nothing to show, give 'em the old "Sorry. No data so far." message!
257 else {
258 $this->output = apply_filters('wpp_no_data', "<p class=\"wpp-no-data\">" . __('Sorry. No data so far.', 'wordpress-popular-posts') . "</p>");
259 }
260 }
261
262 /**
263 * Build the HTML markup for a single post.
264 *
265 * @since 4.0.0
266 * @access private
267 * @param object $post_object
268 * @param integer $position
269 * @return string
270 */
271 private function render_post(\stdClass $post_object, int $position = 1)
272 {
273 $is_single = $this->is_single();
274 $post = '';
275 $post_id = $post_object->id;
276 $trid = $this->translate->get_object_id(
277 $post_object->id,
278 get_post_type($post_object->id)
279 );
280
281 if ( $post_id != $trid ) {
282 $post_id = $trid;
283 }
284
285 $is_current_post = ( $is_single && ($is_single == $post_id || $is_single == $post_object->id) ) ? true : false;
286
287 // Permalink
288 $permalink = $this->get_permalink($post_object, $post_id);
289
290 // Post title (and title attribute)
291 $post_title_attr = esc_attr(wp_strip_all_tags($this->get_title($post_object, $post_id)));
292 $post_title = $this->get_title($post_object, $post_id);
293
294 if ( $this->public_options['shorten_title']['active'] ) {
295 $length = ( filter_var($this->public_options['shorten_title']['length'], FILTER_VALIDATE_INT) && $this->public_options['shorten_title']['length'] > 0 )
296 ? $this->public_options['shorten_title']['length']
297 : 25;
298
299 $more = $this->public_options['shorten_title']['words'] ? ' ' . $this->more : $this->more;
300 $more = apply_filters('wpp_title_more', $more);
301 $post_title = Helper::truncate($post_title, $length, $this->public_options['shorten_title']['words'], $more);
302 }
303
304 // Thumbnail
305 $post_thumbnail = $this->get_thumbnail($post_id);
306
307 // Post excerpt
308 $post_excerpt = $this->get_excerpt($post_object, $post_id);
309
310 // Post rating
311 $post_rating = $this->get_rating($post_object);
312
313 /**
314 * Post meta
315 */
316
317 // Post date
318 $post_date = $this->get_date($post_object);
319
320 // Post taxonomies
321 $post_taxonomies = $this->get_taxonomies($post_id);
322
323 // Post author
324 $post_author = $this->get_author($post_object, $post_id);
325
326 // Post views count
327 $post_views = $this->get_pageviews($post_object);
328
329 // Post comments count
330 $post_comments = $this->get_comments($post_object);
331
332 // Post meta
333 $meta_arr = $this->get_metadata(
334 $post_object,
335 $post_id,
336 $post_date,
337 $post_taxonomies,
338 $post_author,
339 $post_views,
340 $post_comments
341 );
342
343 if (
344 is_array($meta_arr)
345 && ! empty($meta_arr)
346 && "views" == $this->public_options['order_by']
347 ) {
348 $keys = ['views', 'comments', 'author', 'date', 'taxonomy'];
349 $new_meta_arr = [];
350
351 foreach($keys as $key) {
352 if ( isset($meta_arr[$key]))
353 $new_meta_arr[$key] = $meta_arr[$key];
354 }
355
356 if ( ! empty($new_meta_arr) )
357 $meta_arr = $new_meta_arr;
358 }
359
360 $post_meta_separator = apply_filters('wpp_post_meta_separator', ' | ');
361 $post_meta = join($post_meta_separator, $meta_arr);
362
363 $prettify_numbers = apply_filters('wpp_pretiffy_numbers', true);
364
365 // Build custom HTML output
366 if ( $this->public_options['markup']['custom_html'] ) {
367 $data = [
368 'id' => $post_id,
369 'is_current_post' => $is_current_post,
370 'title' => '<a href="' . $permalink . '" ' . ($post_title_attr !== $post_title ? 'title="' . $post_title_attr . '" ' : '' ) . 'class="wpp-post-title" target="' . $this->admin_options['tools']['link']['target'] . '">' . $post_title . '</a>',
371 'title_attr' => $post_title_attr,
372 'summary' => $post_excerpt,
373 'stats' => $post_meta,
374 'img' => ( ! empty($post_thumbnail) ) ? '<a href="' . $permalink . '" ' . ($post_title_attr !== $post_title ? 'title="' . $post_title_attr . '" ' : '' ) . 'target="' . $this->admin_options['tools']['link']['target'] . '">' . $post_thumbnail . '</a>' : '',
375 'img_no_link' => $post_thumbnail,
376 'url' => $permalink,
377 'text_title' => $post_title,
378 'taxonomy' => $post_taxonomies,
379 'taxonomy_copy' => isset($meta_arr['taxonomy']) ? $meta_arr['taxonomy'] : null,
380 'author' => ( ! empty($post_author) ) ? '<a href="' . get_author_posts_url($post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid ) . '">' . $post_author . '</a>' : '',
381 'author_copy' => isset($meta_arr['author']) ? $meta_arr['author'] : null,
382 'author_name' => $post_author,
383 'author_url' => ( ! empty($post_author) ) ? get_author_posts_url($post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid ) : '',
384 'views' => ( $this->public_options['order_by'] == "views" || $this->public_options['order_by'] == "comments" ) ? ($prettify_numbers ? Helper::prettify_number($post_views) : number_format_i18n($post_views)) : ($prettify_numbers ? Helper::prettify_number($post_views, 2) : number_format_i18n($post_views, 2)),
385 'views_copy' => isset($meta_arr['views']) ? $meta_arr['views'] : null,
386 'comments' => $prettify_numbers ? Helper::prettify_number($post_comments) : number_format_i18n($post_comments),
387 'comments_copy' => isset($meta_arr['comments']) ? $meta_arr['comments'] : null,
388 'date' => $post_date,
389 'date_copy' => isset($meta_arr['date']) ? $meta_arr['date'] : null,
390 'total_items' => count($this->data),
391 'item_position' => $position
392 ];
393 $post = $this->format_content(htmlspecialchars_decode($this->public_options['markup']['post-html'], ENT_QUOTES), $data, $this->public_options['rating']). "\n";
394 } // Use the "stock" HTML output
395 else {
396 $wpp_post_class = [];
397
398 if ( $is_current_post ) {
399 $wpp_post_class[] = "current";
400 }
401
402 // Allow themers / plugin developer
403 // to add custom classes to each post
404 $wpp_post_class = apply_filters("wpp_post_class", $wpp_post_class, $post_id);
405
406 $post_thumbnail = ( ! empty($post_thumbnail) )
407 ? "<a href=\"{$permalink}\" " . ($post_title_attr !== $post_title ? "title=\"{$post_title_attr}\" " : "") . "target=\"{$this->admin_options['tools']['link']['target']}\">{$post_thumbnail}</a>\n"
408 : "";
409
410 $post_excerpt = ( ! empty($post_excerpt) )
411 ? " <span class=\"wpp-excerpt\">{$post_excerpt}</span>\n"
412 : "";
413
414 $post_meta = ( ! empty($post_meta) )
415 ? " <span class=\"wpp-meta post-stats\">{$post_meta}</span>\n"
416 : '';
417
418 $post_rating = ( ! empty($post_rating) )
419 ? " <span class=\"wpp-rating\">{$post_rating}</span>\n"
420 : "";
421
422 $post =
423 "<li" . ( ( is_array($wpp_post_class) && ! empty($wpp_post_class) ) ? ' class="' . esc_attr(implode(" ", $wpp_post_class)) . '"' : '') . ">\n"
424 . $post_thumbnail
425 . "<a href=\"{$permalink}\" " . ($post_title_attr !== $post_title ? "title=\"{$post_title_attr}\" " : "") . "class=\"wpp-post-title\" target=\"{$this->admin_options['tools']['link']['target']}\">{$post_title}</a>\n"
426 . $post_excerpt
427 . $post_meta
428 . $post_rating
429 . "</li>\n";
430 }
431
432 return apply_filters('wpp_post', $post, $post_object, $this->public_options);
433 }
434
435 /**
436 * Return the processed post/page title.
437 *
438 * @since 3.0.0
439 * @access private
440 * @param object $post_object
441 * @param integer $post_id
442 * @return string
443 */
444 private function get_title(\stdClass $post_object, int $post_id)
445 {
446 if ( $post_object->id != $post_id ) {
447 $title = get_the_title($post_id);
448 } else {
449 $title = $post_object->title;
450 }
451
452 // Run the_title filter so core/plugin title hooks can
453 // be applied to the post title
454 $title = apply_filters('the_title', $title, $post_object->id);
455
456 return apply_filters('wpp_the_title', $title, $post_object->id, $post_id);
457 }
458
459 /**
460 * Return the permalink.
461 *
462 * @since 4.0.12
463 * @access private
464 * @param object $post_object
465 * @param integer $post_id
466 * @return string
467 */
468 private function get_permalink(\stdClass $post_object, int $post_id) {
469 if ( $post_object->id != $post_id ) {
470 return get_permalink($post_id);
471 }
472
473 return get_permalink($post_object->id);
474 }
475
476 /**
477 * Return the processed thumbnail.
478 *
479 * @since 3.0.0
480 * @access private
481 * @param int $post_id
482 * @return string
483 */
484 private function get_thumbnail(int $post_id)
485 {
486 $thumbnail = '';
487
488 if ( $this->public_options['thumbnail']['active'] ) {
489 $thumbnail = $this->thumbnail->get(
490 $post_id,
491 [
492 $this->public_options['thumbnail']['width'],
493 $this->public_options['thumbnail']['height']
494 ],
495 $this->admin_options['tools']['thumbnail']['source'],
496 $this->public_options['thumbnail']['crop'],
497 $this->public_options['thumbnail']['build']
498 );
499 }
500
501 return $thumbnail;
502 }
503
504 /**
505 * Return post excerpt.
506 *
507 * @since 3.0.0
508 * @access private
509 * @param object $post_object
510 * @param integer $post_id
511 * @return string
512 */
513 private function get_excerpt(\stdClass $post_object, int $post_id)
514 {
515 $excerpt = '';
516
517 if ( $this->public_options['post-excerpt']['active'] ) {
518
519 if ( $post_object->id != $post_id ) {
520 $the_post = get_post($post_id);
521
522 $excerpt = ( empty($the_post->post_excerpt) )
523 ? $the_post->post_content
524 : $the_post->post_excerpt;
525 }
526 else {
527 $excerpt = ( empty($post_object->post_excerpt) )
528 ? $post_object->post_content
529 : $post_object->post_excerpt;
530 }
531
532 // remove caption tags
533 $excerpt = preg_replace("/\[caption.*\[\/caption\]/", "", $excerpt);
534
535 // remove Flash objects
536 $excerpt = preg_replace("/<object[0-9 a-z_?*=\":\-\/\.#\,\\n\\r\\t]+/smi", "", $excerpt);
537
538 // remove iframes
539 $excerpt = preg_replace("/<iframe.*?\/iframe>/i", "", $excerpt);
540
541 // remove WP shortcodes
542 $excerpt = strip_shortcodes($excerpt);
543
544 // remove style/script tags
545 $excerpt = preg_replace('@<(script|style)[^>]*?>.*?</\\1>@si', '', $excerpt);
546
547 // remove HTML tags if requested
548 if ( $this->public_options['post-excerpt']['keep_format'] ) {
549 $excerpt = strip_tags($excerpt, '<a><b><i><em><strong>');
550 } else {
551 $excerpt = strip_tags($excerpt);
552
553 // remove URLs, too
554 $excerpt = preg_replace('_^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS', '', $excerpt);
555 }
556
557 $excerpt = trim($excerpt);
558
559 }
560
561 // Balance tags, if needed
562 if ( '' !== $excerpt ) {
563
564 $more = $this->public_options['post-excerpt']['words'] ? ' ' . $this->more : $this->more;
565 $more = apply_filters('wpp_excerpt_more', $more);
566 $excerpt = Helper::truncate($excerpt, $this->public_options['post-excerpt']['length'], $this->public_options['post-excerpt']['words'], $more);
567
568 if ( $this->public_options['post-excerpt']['keep_format'] )
569 $excerpt = force_balance_tags($excerpt);
570 }
571
572 return $excerpt;
573 }
574
575 /**
576 * Return post rating.
577 *
578 * @since 3.0.0
579 * @access private
580 * @param object $post_object
581 * @return string
582 */
583 private function get_rating(\stdClass $post_object)
584 {
585 $rating = '';
586
587 if ( function_exists('the_ratings_results') && $this->public_options['rating'] ) {
588 $rating = the_ratings_results($post_object->id);
589 }
590
591 return $rating;
592 }
593
594 /**
595 * Get post date.
596 *
597 * @since 3.0.0
598 * @access private
599 * @param object $post_object
600 * @return string
601 */
602 private function get_date(\stdClass $post_object)
603 {
604 $date = '';
605
606 if ( $this->public_options['stats_tag']['date']['active'] ) {
607 if ( 'relative' == $this->public_options['stats_tag']['date']['format'] ) {
608 $date = sprintf(
609 __('%s ago', 'wordpress-popular-posts'),
610 human_time_diff(
611 strtotime($post_object->date),
612 current_time('timestamp')
613 )
614 );
615 } else {
616 $date = date_i18n(
617 ( 'wp_date_format' == $this->public_options['stats_tag']['date']['format'] ? $this->wp_date_format : $this->public_options['stats_tag']['date']['format'] ),
618 strtotime($post_object->date)
619 );
620 }
621 }
622
623 return $date;
624 }
625
626 /**
627 * Get post taxonomies.
628 *
629 * @since 3.0.0
630 * @access private
631 * @param integer $post_id
632 * @return string
633 */
634 private function get_taxonomies(int $post_id)
635 {
636 $post_tax = '';
637
638 if (
639 (isset($this->public_options['stats_tag']['category']) && $this->public_options['stats_tag']['category'])
640 || $this->public_options['stats_tag']['taxonomy']['active']
641 ) {
642
643 $taxonomy = 'category';
644
645 if (
646 $this->public_options['stats_tag']['taxonomy']['active']
647 && ! empty($this->public_options['stats_tag']['taxonomy']['name'])
648 ) {
649 $taxonomy = $this->public_options['stats_tag']['taxonomy']['name'];
650 }
651
652 $terms = wp_get_post_terms($post_id, $taxonomy);
653
654 if ( ! is_wp_error($terms) ) {
655 // Usage: https://wordpress.stackexchange.com/a/46824
656 if ( has_filter('wpp_post_exclude_terms') ) {
657 $args = apply_filters('wpp_post_exclude_terms', []);
658 $terms = wp_list_filter($terms, $args, 'NOT');
659 }
660
661 $terms = apply_filters('wpp_post_terms', $terms);
662
663 if (
664 is_array($terms)
665 && ! empty($terms)
666 ) {
667 $taxonomy_separator = apply_filters('wpp_taxonomy_separator', ', ');
668
669 foreach ($terms as $term) {
670 $term_link = get_term_link($term);
671
672 if ( is_wp_error($term_link) )
673 continue;
674
675 $term_link = $this->translate->url($term_link, $this->translate->get_current_language());
676 $post_tax .= "<a href=\"{$term_link}\" class=\"wpp-taxonomy {$taxonomy} {$taxonomy}-{$term->term_id}\">{$term->name}</a>" . $taxonomy_separator;
677 }
678 }
679 }
680
681 if ( '' != $post_tax )
682 $post_tax = rtrim($post_tax, $taxonomy_separator);
683
684 }
685
686 return $post_tax;
687 }
688
689 /**
690 * Get post author.
691 *
692 * @since 3.0.0
693 * @access private
694 * @param object $post_object
695 * @param integer $post_id
696 * @return string
697 */
698 private function get_author(\stdClass $post_object, int $post_id)
699 {
700 $author = ( $this->public_options['stats_tag']['author'] )
701 ? get_the_author_meta('display_name', $post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid)
702 : "";
703
704 return $author;
705 }
706
707 /**
708 * Return post views count.
709 *
710 * @since 3.0.0
711 * @access private
712 * @param object $post_object
713 * @return int|float
714 */
715 private function get_pageviews(\stdClass $post_object)
716 {
717 $pageviews = 0;
718
719 if (
720 (
721 $this->public_options['order_by'] == "views"
722 || $this->public_options['order_by'] == "avg"
723 || $this->public_options['stats_tag']['views']
724 )
725 && ( isset($post_object->pageviews) || isset($post_object->avg_views) )
726 ) {
727 $pageviews = ( $this->public_options['order_by'] == "views" || $this->public_options['order_by'] == "comments" )
728 ? $post_object->pageviews
729 : $post_object->avg_views;
730 }
731
732 return $pageviews;
733 }
734
735 /**
736 * Return post comment count.
737 *
738 * @since 3.0.0
739 * @access private
740 * @param object $post_object
741 * @return int
742 */
743 private function get_comments(\stdClass $post_object)
744 {
745 $comments = ( ( $this->public_options['order_by'] == "comments" || $this->public_options['stats_tag']['comment_count'] ) && isset($post_object->comment_count) )
746 ? $post_object->comment_count
747 : 0;
748
749 return $comments;
750 }
751
752 /**
753 * Return post metadata.
754 *
755 * @since 3.0.0
756 * @access private
757 * @param object $post_object
758 * @param integer $post_id
759 * @return array
760 */
761 //private function get_metadata(\stdClass $post_object, $post_id)
762 private function get_metadata(\stdClass $post_object, int $post_id, string $date, string $post_tax, string $author, $pageviews, int $comments) /** @TODO: starting PHP 8.0 $pageviews can be declared as mixed $pageviews */
763 {
764 $stats = [];
765
766 $prettify_numbers = apply_filters('wpp_pretiffy_numbers', true);
767
768 // comments
769 if ( $this->public_options['stats_tag']['comment_count'] ) {
770 $comments_text = sprintf(
771 _n('%s comment', '%s comments', $comments, 'wordpress-popular-posts'),
772 $prettify_numbers ? Helper::prettify_number($comments) : number_format_i18n($comments)
773 );
774
775 $stats['comments'] = '<span class="wpp-comments">' . $comments_text . '</span>';
776 }
777
778 // views
779 if ( $this->public_options['stats_tag']['views'] ) {
780 if ( $this->public_options['order_by'] == 'avg' ) {
781 $views_text = sprintf(
782 _n('%s view per day', '%s views per day', $pageviews, 'wordpress-popular-posts'),
783 $prettify_numbers ? Helper::prettify_number($pageviews, 2) : number_format_i18n($pageviews, (fmod($pageviews, 1) !== 0.0 ? 2 : 0))
784 );
785 }
786 else {
787 $views_text = sprintf(
788 _n('%s view', '%s views', $pageviews, 'wordpress-popular-posts'),
789 $prettify_numbers ? Helper::prettify_number($pageviews) : number_format_i18n($pageviews)
790 );
791 }
792
793 $stats['views'] = '<span class="wpp-views">' . $views_text . "</span>";
794 }
795
796 // author
797 if ( $this->public_options['stats_tag']['author'] ) {
798 $author_url = get_author_posts_url($post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid);
799 $display_name = '<a href="' . $this->translate->url($author_url, $this->translate->get_current_language()) . '">' . $author . '</a>';
800 $stats['author'] = '<span class="wpp-author">' . sprintf(__('by %s', 'wordpress-popular-posts'), $display_name) . '</span>';
801 }
802
803 // date
804 if ( $this->public_options['stats_tag']['date']['active'] ) {
805 $stats['date'] = '<span class="wpp-date">' . ( 'relative' == $this->public_options['stats_tag']['date']['format'] ? sprintf(__('posted %s', 'wordpress-popular-posts'), $date) : sprintf(__('posted on %s', 'wordpress-popular-posts'), $date) ) . '</span>';
806 }
807
808 // taxonomy
809 if ( ($this->public_options['stats_tag']['category'] || $this->public_options['stats_tag']['taxonomy']['active']) && $post_tax != '' ) {
810 $stats['taxonomy'] = '<span class="wpp-category">' . sprintf(__('under %s', 'wordpress-popular-posts'), $post_tax) . '</span>';
811 }
812
813 return $stats;
814 }
815
816 /**
817 * Parse content tags.
818 *
819 * @since 1.4.6
820 * @access private
821 * @param string HTML string with content tags
822 * @param array Post data
823 * @param bool Used to display post rating (if functionality is available)
824 * @return string
825 */
826 private function format_content(string $string, array $data, bool $rating) {
827
828 if ( empty($string) || ( empty($data) || ! is_array($data) ) )
829 return false;
830
831 $params = [];
832 $pattern = '/\{(pid|current_class|excerpt|summary|meta|stats|title|title_attr|image|thumb|thumb_img|thumb_url|rating|score|url|text_title|author|author_copy|author_name|author_url|taxonomy|taxonomy_copy|category|category_copy|views|views_copy|comments|comments_copy|date|date_copy|total_items|item_position)\}/i';
833 preg_match_all($pattern, $string, $matches);
834
835 array_map('strtolower', $matches[0]);
836
837 if ( in_array("{pid}", $matches[0]) ) {
838 $string = str_replace("{pid}", $data['id'], $string);
839 }
840
841 if ( in_array("{current_class}", $matches[0]) ) {
842 $string = str_replace("{current_class}", ( $data['is_current_post'] ? 'current' : '' ), $string);
843 }
844
845 if ( in_array("{title}", $matches[0]) ) {
846 $string = str_replace("{title}", $data['title'], $string);
847 }
848
849 if ( in_array("{title_attr}", $matches[0]) ) {
850 $string = str_replace("{title_attr}", $data['title_attr'], $string);
851 }
852
853 if ( in_array("{meta}", $matches[0]) || in_array("{stats}", $matches[0]) ) {
854 $string = str_replace(["{meta}", "{stats}"], $data['stats'], $string);
855 }
856
857 if ( in_array("{excerpt}", $matches[0]) || in_array("{summary}", $matches[0]) ) {
858 $string = str_replace(["{excerpt}", "{summary}"], $data['summary'], $string);
859 }
860
861 if ( in_array("{image}", $matches[0]) || in_array("{thumb}", $matches[0]) ) {
862 $string = str_replace(["{image}", "{thumb}"], $data['img'], $string);
863 }
864
865 if ( in_array("{thumb_img}", $matches[0]) ) {
866 $string = str_replace("{thumb_img}", $data['img_no_link'], $string);
867 }
868
869 if ( in_array("{thumb_url}", $matches[0]) && ! empty($data['img_no_link']) ) {
870 $dom = new \DOMDocument;
871
872 if ( $dom->loadHTML($data['img_no_link']) ) {
873 $img_tag = $dom->getElementsByTagName('img');
874
875 if ( $img_tag->length ) {
876 foreach( $img_tag as $node ) {
877 if ( $node->hasAttribute('src') ) {
878 $src = $node->getAttribute('src');
879 $string = str_replace("{thumb_url}", $src, $string);
880 }
881 }
882 }
883 }
884 }
885
886 // WP-PostRatings check
887 if ( $rating ) {
888 if ( function_exists('the_ratings_results') && in_array("{rating}", $matches[0]) ) {
889 $string = str_replace("{rating}", the_ratings_results($data['id']), $string);
890 }
891
892 if ( function_exists('expand_ratings_template') && in_array("{score}", $matches[0]) ) {
893 $string = str_replace("{score}", expand_ratings_template('%RATINGS_SCORE%', $data['id']), $string);
894 // removing the redundant plus sign
895 $string = str_replace('+', '', $string);
896 }
897 }
898
899 if ( in_array("{url}", $matches[0]) ) {
900 $string = str_replace("{url}", $data['url'], $string);
901 }
902
903 if ( in_array("{text_title}", $matches[0]) ) {
904 $string = str_replace("{text_title}", $data['text_title'], $string);
905 }
906
907 if ( in_array("{author}", $matches[0]) ) {
908 $string = str_replace("{author}", $data['author'], $string);
909 }
910
911 if ( in_array("{author_copy}", $matches[0]) ) {
912 $string = str_replace("{author_copy}", $data['author_copy'], $string);
913 }
914
915 if ( in_array("{author_name}", $matches[0]) ) {
916 $string = str_replace("{author_name}", $data['author_name'], $string);
917 }
918
919 if ( in_array("{author_url}", $matches[0]) ) {
920 $string = str_replace("{author_url}", $data['author_url'], $string);
921 }
922
923 if ( in_array("{taxonomy}", $matches[0]) || in_array("{category}", $matches[0]) ) {
924 $string = str_replace(["{taxonomy}", "{category}"], $data['taxonomy'], $string);
925 }
926
927 if ( in_array("{taxonomy_copy}", $matches[0]) || in_array("{category_copy}", $matches[0]) ) {
928 $string = str_replace(["{taxonomy_copy}", "{category_copy}"], $data['taxonomy_copy'], $string);
929 }
930
931 if ( in_array("{views}", $matches[0]) ) {
932 $string = str_replace("{views}", $data['views'], $string);
933 }
934
935 if ( in_array("{views_copy}", $matches[0]) ) {
936 $string = str_replace("{views_copy}", $data['views_copy'], $string);
937 }
938
939 if ( in_array("{comments}", $matches[0]) ) {
940 $string = str_replace("{comments}", $data['comments'], $string);
941 }
942
943 if ( in_array("{comments_copy}", $matches[0]) ) {
944 $string = str_replace("{comments_copy}", $data['comments_copy'], $string);
945 }
946
947 if ( in_array("{date}", $matches[0]) ) {
948 $string = str_replace("{date}", $data['date'], $string);
949 }
950
951 if ( in_array("{date_copy}", $matches[0]) ) {
952 $string = str_replace("{date_copy}", $data['date_copy'], $string);
953 }
954
955 if ( in_array("{total_items}", $matches[0]) ) {
956 $string = str_replace("{total_items}", $data['total_items'], $string);
957 }
958
959 if ( in_array("{item_position}", $matches[0]) ) {
960 $string = str_replace("{item_position}", $data['item_position'], $string);
961 }
962
963 return apply_filters("wpp_parse_custom_content_tags", $string, $data['id']);
964 }
965
966 /**
967 * Checks whether we're currently seeing a single post/page/CPT.
968 *
969 * @since 5.0.0
970 * @return int
971 */
972 public function is_single()
973 {
974 return apply_filters('wpp_is_single', Helper::is_single());
975 }
976 }
977