PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / 5.0.2
WP Popular Posts v5.0.2
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 6 years ago Admin 6 years ago Container 6 years ago Front 6 years ago Moment 6 years ago Rest 6 years ago Widget 6 years ago Bootstrap.php 6 years ago Cache.php 6 years ago Helper.php 6 years ago I18N.php 6 years ago Image.php 6 years ago Output.php 6 years ago Query.php 6 years ago Settings.php 6 years ago Themer.php 6 years ago Translate.php 6 years ago WordPressPopularPosts.php 6 years ago deprecated.php 6 years ago template-tags.php 6 years ago
Output.php
888 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 * Constructor.
80 *
81 * @since 4.0.0
82 * @param array $public_options
83 * @param array $admin_options
84 * @param WordPressPopularPosts\Image $thumbnail
85 * @param WordPressPopularPosts\Translate $translate
86 * @param \WordPressPopularPosts\Themer $themer
87 */
88 public function __construct(array $public_options = [], array $admin_options = [], Image $thumbnail, Translate $translate, \WordPressPopularPosts\Themer $themer)
89 {
90 $this->public_options = $public_options;
91 $this->admin_options = $admin_options;
92 $this->thumbnail = $thumbnail;
93 $this->translate = $translate;
94 $this->themer = $themer;
95
96 $this->more = '...';
97
98 // Allow customization of the more (...) string
99 if ( has_filter('wpp_excerpt_more') )
100 $this->more = apply_filters('wpp_excerpt_more', $this->more);
101 }
102
103 /**
104 * Sets data.
105 *
106 * @since 5.0.0
107 * @param array
108 */
109 public function set_data(array $data = [])
110 {
111 $this->data = $data;
112 }
113
114 /**
115 * Sets public options.
116 *
117 * @since 5.0.0
118 * @param array
119 */
120 public function set_public_options(array $public_options = [])
121 {
122 $this->public_options = Helper::merge_array_r(
123 $this->public_options,
124 $public_options
125 );
126 }
127
128 /**
129 * Output the HTML.
130 *
131 * @since 4.0.0
132 */
133 public function output()
134 {
135 echo $this->output;
136 }
137
138 /**
139 * Return the HTML.
140 *
141 * @since 4.0.0
142 * @return string
143 */
144 public function get_output()
145 {
146 return $this->output;
147 }
148
149 /**
150 * Build the HTML output.
151 *
152 * @since 4.0.0
153 */
154 public function build_output()
155 {
156 // Got some posts, format 'em!
157 if ( ! empty($this->data) ) {
158
159 $this->output = "\n" . "<!-- WordPress Popular Posts" . ( WP_DEBUG ? ' v' . WPP_VERSION : '' ) . " -->" . "\n";
160
161 // Allow WP themers / coders access to raw data
162 // so they can build their own output
163 if ( has_filter('wpp_custom_html') ) {
164 $this->output .= apply_filters('wpp_custom_html', $this->data, $this->public_options);
165 return;
166 }
167
168 if ( $this->public_options['theme']['name'] ) {
169 $this->output .= '<div class="popular-posts-sr">';
170
171 $theme_stylesheet = $this->themer->get_theme($this->public_options['theme']['name'])['path'] . '/style.css';
172 $theme_css_rules = wp_strip_all_tags(file_get_contents($theme_stylesheet), true);
173 $additional_styles = '';
174
175 if ( has_filter('wpp_additional_theme_styles') ) {
176 $additional_styles = wp_strip_all_tags(apply_filters('wpp_additional_theme_styles', '', $this->public_options['theme']['name']), true);
177
178 if ( $additional_styles )
179 $additional_styles = ' /* additional rules */ ' . $additional_styles;
180 }
181
182 $this->output .= '<style>' . $theme_css_rules . $additional_styles . '</style>';
183 }
184
185 /* Open HTML wrapper */
186 // Output a custom wrapper
187 if (
188 isset($this->public_options['markup']['custom_html'])
189 && $this->public_options['markup']['custom_html']
190 && isset($this->public_options['markup']['wpp-start'])
191 && isset($this->public_options['markup']['wpp-end'])
192 ){
193 $this->output .= "\n" . htmlspecialchars_decode($this->public_options['markup']['wpp-start'], ENT_QUOTES) ."\n";
194 }
195 // Output the default wrapper
196 else {
197
198 $classes = "wpp-list";
199
200 if ( $this->public_options['thumbnail']['active'] )
201 $classes .= " wpp-list-with-thumbnails";
202
203 $this->output .= "\n" . "<ul class=\"{$classes}\">" . "\n";
204
205 }
206
207 $position = 0;
208
209 // Format each post
210 foreach( $this->data as $post_object ) {
211 $position++;
212 $this->output .= $this->render_post($post_object, $position);
213 }
214
215 /* Close HTML wrapper */
216 // Output a custom wrapper
217 if (
218 isset($this->public_options['markup']['custom_html'])
219 && $this->public_options['markup']['custom_html']
220 && isset($this->public_options['markup']['wpp-start'])
221 && isset($this->public_options['markup']['wpp-end'])
222 ){
223 $this->output .= "\n" . htmlspecialchars_decode($this->public_options['markup']['wpp-end'], ENT_QUOTES) ."\n";
224 }
225 // Output default wrapper
226 else {
227 $this->output .= "</ul>" . "\n";
228 }
229
230 if ( $this->public_options['theme']['name'] ) {
231 $this->output .= "</div>";
232 }
233
234 }
235 // Got nothing to show, give 'em the old "Sorry. No data so far." message!
236 else {
237 $this->output = apply_filters('wpp_no_data', "<p class=\"wpp-no-data\">" . __('Sorry. No data so far.', 'wordpress-popular-posts') . "</p>");
238 }
239 }
240
241 /**
242 * Build the HTML markup for a single post.
243 *
244 * @since 4.0.0
245 * @access private
246 * @param object $post_object
247 * @param integer $position
248 * @return string
249 */
250 private function render_post(\stdClass $post_object, $position = 1)
251 {
252 $is_single = $this->is_single();
253 $post = '';
254 $post_id = $post_object->id;
255 $trid = $this->translate->get_object_id(
256 $post_object->id,
257 get_post_type($post_object->id)
258 );
259
260 if ( $post_id != $trid ) {
261 $post_id = $trid;
262 }
263
264 $is_current_post = ( $is_single && ($is_single == $post_id || $is_single == $post_object->id) ) ? true : false;
265
266 // Permalink
267 $permalink = $this->get_permalink($post_object, $post_id);
268
269 // Post title (and title attribute)
270 $post_title_attr = esc_attr(wp_strip_all_tags($this->get_title($post_object, $post_id)));
271 $post_title = $this->get_title($post_object, $post_id);
272
273 if ( $this->public_options['shorten_title']['active'] ) {
274 $length = ( filter_var($this->public_options['shorten_title']['length'], FILTER_VALIDATE_INT) && $this->public_options['shorten_title']['length'] > 0 )
275 ? $this->public_options['shorten_title']['length']
276 : 25;
277
278 $post_title = Helper::truncate($post_title, $length, $this->public_options['shorten_title']['words'], $this->more);
279 }
280
281 // Thumbnail
282 $post_thumbnail = $this->get_thumbnail($post_object);
283
284 // Post excerpt
285 $post_excerpt = $this->get_excerpt($post_object, $post_id);
286
287 // Post rating
288 $post_rating = $this->get_rating($post_object);
289
290 /**
291 * Post meta
292 */
293
294 // Post date
295 $post_date = $this->get_date($post_object);
296
297 // Post taxonomies
298 $post_taxonomies = $this->get_taxonomies($post_id);
299
300 // Post author
301 $post_author = $this->get_author($post_object, $post_id);
302
303 // Post views count
304 $post_views = $this->get_pageviews($post_object);
305
306 // Post comments count
307 $post_comments = $this->get_comments($post_object);
308
309 // Post meta
310 $post_meta = join(' | ', $this->get_metadata($post_object, $post_id));
311
312 // Build custom HTML output
313 if ( $this->public_options['markup']['custom_html'] ) {
314 $data = [
315 'id' => $post_id,
316 '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>',
317 'summary' => $post_excerpt,
318 'stats' => $post_meta,
319 '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>' : '',
320 'img_no_link' => $post_thumbnail,
321 'url' => $permalink,
322 'text_title' => $post_title,
323 'taxonomy' => $post_taxonomies,
324 '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>' : '',
325 'views' => ( $this->public_options['order_by'] == "views" || $this->public_options['order_by'] == "comments" ) ? number_format_i18n($post_views) : number_format_i18n($post_views, 2),
326 'comments' => number_format_i18n($post_comments),
327 'date' => $post_date,
328 'total_items' => count($this->data),
329 'item_position' => $position
330 ];
331 $post = $this->format_content(htmlspecialchars_decode($this->public_options['markup']['post-html'], ENT_QUOTES), $data, $this->public_options['rating']). "\n";
332 } // Use the "stock" HTML output
333 else {
334 $wpp_post_class = [];
335
336 if ( $is_current_post ) {
337 $wpp_post_class[] = "current";
338 }
339
340 // Allow themers / plugin developer
341 // to add custom classes to each post
342 $wpp_post_class = apply_filters("wpp_post_class", $wpp_post_class, $post_id);
343
344 $post_thumbnail = ( ! empty($post_thumbnail) )
345 ? "<a href=\"{$permalink}\" " . ($post_title_attr !== $post_title ? "title=\"{$post_title_attr}\" " : "") . "target=\"{$this->admin_options['tools']['link']['target']}\">{$post_thumbnail}</a>\n"
346 : "";
347
348 $post_excerpt = ( ! empty($post_excerpt) )
349 ? " <span class=\"wpp-excerpt\">{$post_excerpt}</span>\n"
350 : "";
351
352 $post_meta = ( ! empty($post_meta) )
353 ? " <span class=\"wpp-meta post-stats\">{$post_meta}</span>\n"
354 : '';
355
356 $post_rating = ( ! empty($post_rating) )
357 ? " <span class=\"wpp-rating\">{$post_rating}</span>\n"
358 : "";
359
360 $post =
361 "<li" . ( ( is_array($wpp_post_class) && ! empty($wpp_post_class) ) ? ' class="' . esc_attr(implode(" ", $wpp_post_class)) . '"' : '') . ">\n"
362 . $post_thumbnail
363 . "<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"
364 . $post_excerpt
365 . $post_meta
366 . $post_rating
367 . "</li>\n";
368 }
369
370 return apply_filters('wpp_post', $post, $post_object, $this->public_options);
371 }
372
373 /**
374 * Return the processed post/page title.
375 *
376 * @since 3.0.0
377 * @access private
378 * @param object $post_object
379 * @param integer $post_id
380 * @return string
381 */
382 private function get_title(\stdClass $post_object, $post_id)
383 {
384 if ( $post_object->id != $post_id ) {
385 $title = get_the_title($post_id);
386 } else {
387 $title = $post_object->title;
388 }
389
390 // Run the_title filter so core/plugin title hooks can
391 // be applied to the post title
392 $title = apply_filters('the_title', $title, $post_object->id);
393
394 return apply_filters('wpp_the_title', $title, $post_object->id, $post_id);
395 }
396
397 /**
398 * Return the permalink.
399 *
400 * @since 4.0.12
401 * @access private
402 * @param object $post_object
403 * @param integer $post_id
404 * @return string
405 */
406 private function get_permalink(\stdClass $post_object, $post_id) {
407 $permalink = get_permalink($post_object->id);
408
409 return $post_object->id != $post_id
410 ? $this->translate->url($permalink, $this->translate->get_current_language())
411 : $permalink;
412 }
413
414 /**
415 * Return the processed thumbnail.
416 *
417 * @since 3.0.0
418 * @access private
419 * @param object $post_object
420 * @return string
421 */
422 private function get_thumbnail(\stdClass $post_object)
423 {
424 $thumbnail = '';
425
426 if ( $this->public_options['thumbnail']['active'] ) {
427 $thumbnail = $this->thumbnail->get(
428 $post_object,
429 [
430 $this->public_options['thumbnail']['width'],
431 $this->public_options['thumbnail']['height']
432 ],
433 $this->admin_options['tools']['thumbnail']['source'],
434 $this->public_options['thumbnail']['crop'],
435 $this->public_options['thumbnail']['build']
436 );
437 }
438
439 return $thumbnail;
440 }
441
442 /**
443 * Return post excerpt.
444 *
445 * @since 3.0.0
446 * @access private
447 * @param object $post_object
448 * @param integer $post_id
449 * @return string
450 */
451 private function get_excerpt(\stdClass $post_object, $post_id)
452 {
453 $excerpt = '';
454
455 if ( $this->public_options['post-excerpt']['active'] ) {
456
457 if ( $post_object->id != $post_id ) {
458 $the_post = get_post($post_id);
459
460 $excerpt = ( empty($the_post->post_excerpt) )
461 ? $the_post->post_content
462 : $the_post->post_excerpt;
463 }
464 else {
465 $excerpt = ( empty($post_object->post_excerpt) )
466 ? $post_object->post_content
467 : $post_object->post_excerpt;
468 }
469
470 // remove caption tags
471 $excerpt = preg_replace("/\[caption.*\[\/caption\]/", "", $excerpt);
472
473 // remove Flash objects
474 $excerpt = preg_replace("/<object[0-9 a-z_?*=\":\-\/\.#\,\\n\\r\\t]+/smi", "", $excerpt);
475
476 // remove iframes
477 $excerpt = preg_replace("/<iframe.*?\/iframe>/i", "", $excerpt);
478
479 // remove WP shortcodes
480 $excerpt = strip_shortcodes($excerpt);
481
482 // remove style/script tags
483 $excerpt = preg_replace('@<(script|style)[^>]*?>.*?</\\1>@si', '', $excerpt);
484
485 // remove HTML tags if requested
486 if ( $this->public_options['post-excerpt']['keep_format'] ) {
487 $excerpt = strip_tags($excerpt, '<a><b><i><em><strong>');
488 } else {
489 $excerpt = strip_tags($excerpt);
490
491 // remove URLs, too
492 $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);
493 }
494
495 }
496
497 // Balance tags, if needed
498 if ( '' !== $excerpt ) {
499
500 $excerpt = Helper::truncate($excerpt, $this->public_options['post-excerpt']['length'], $this->public_options['post-excerpt']['words'], $this->more);
501
502 if ( $this->public_options['post-excerpt']['keep_format'] )
503 $excerpt = force_balance_tags($excerpt);
504 }
505
506 return $excerpt;
507 }
508
509 /**
510 * Return post rating.
511 *
512 * @since 3.0.0
513 * @access private
514 * @param object $post_object
515 * @return string
516 */
517 private function get_rating(\stdClass $post_object)
518 {
519 $rating = '';
520
521 if ( function_exists('the_ratings_results') && $this->public_options['rating'] ) {
522 $rating = the_ratings_results($post_object->id);
523 }
524
525 return $rating;
526 }
527
528 /**
529 * Get post date.
530 *
531 * @since 3.0.0
532 * @access private
533 * @param object $post_object
534 * @return string
535 */
536 private function get_date(\stdClass $post_object)
537 {
538 $date = '';
539
540 if ( $this->public_options['stats_tag']['date']['active'] ) {
541 // Check locale
542 if ( ! $current_language_locale = $this->translate->get_locale($this->translate->get_current_language()) ) {
543 $current_language_locale = get_locale();
544 }
545
546 try {
547 Moment\Moment::setLocale($current_language_locale);
548 } // Locale not found, fallback to English (US)
549 catch( \Exception $e ) {
550 Moment\Moment::setLocale('en_US');
551 }
552
553 $m = new Moment\Moment('@' . strtotime($post_object->date));
554
555 $date = ( 'relative' == $this->public_options['stats_tag']['date']['format'] )
556 ? $m->fromNow()->getRelative()
557 : $m->format($this->public_options['stats_tag']['date']['format']);
558 }
559
560 return $date;
561 }
562
563 /**
564 * Get post taxonomies.
565 *
566 * @since 3.0.0
567 * @access private
568 * @param integer $post_id
569 * @return string
570 */
571 private function get_taxonomies($post_id)
572 {
573 $post_tax = '';
574
575 if ( (isset($this->public_options['stats_tag']['category']) && $this->public_options['stats_tag']['category']) || $this->public_options['stats_tag']['taxonomy'] ) {
576
577 $taxonomy = 'category';
578
579 if (
580 $this->public_options['stats_tag']['taxonomy']['active']
581 && ! empty($this->public_options['stats_tag']['taxonomy']['name'])
582 ) {
583 $taxonomy = $this->public_options['stats_tag']['taxonomy']['name'];
584 }
585
586 $terms = wp_get_post_terms($post_id, $taxonomy);
587
588 if ( ! is_wp_error($terms) ) {
589 // Usage: https://wordpress.stackexchange.com/a/46824
590 if ( has_filter('wpp_post_exclude_terms') ) {
591 $args = apply_filters('wpp_post_exclude_terms', []);
592 $terms = wp_list_filter($terms, $args, 'NOT');
593 }
594
595 if (
596 is_array($terms)
597 && ! empty($terms)
598 ) {
599 $taxonomy_separator = apply_filters('wpp_taxonomy_separator', ', ');
600
601 foreach ($terms as $term) {
602 $term_link = get_term_link($term);
603
604 if ( is_wp_error($term_link) )
605 continue;
606
607 $term_link = $this->translate->url($term_link, $this->translate->get_current_language());
608 $post_tax .= "<a href=\"{$term_link}\" class=\"{$taxonomy} {$taxonomy}-{$term->term_id}\">{$term->name}</a>" . $taxonomy_separator;
609 }
610 }
611 }
612
613 if ( '' != $post_tax )
614 $post_tax = rtrim($post_tax, $taxonomy_separator);
615
616 }
617
618 return $post_tax;
619 }
620
621 /**
622 * Get post author.
623 *
624 * @since 3.0.0
625 * @access private
626 * @param object $post_object
627 * @param integer $post_id
628 * @return string
629 */
630 private function get_author(\stdClass $post_object, $post_id)
631 {
632 $author = ( $this->public_options['stats_tag']['author'] )
633 ? get_the_author_meta('display_name', $post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid)
634 : "";
635
636 return $author;
637 }
638
639 /**
640 * Return post views count.
641 *
642 * @since 3.0.0
643 * @access private
644 * @param object $post_object
645 * @return int|float
646 */
647 private function get_pageviews(\stdClass $post_object)
648 {
649 $pageviews = 0;
650
651 if (
652 (
653 $this->public_options['order_by'] == "views"
654 || $this->public_options['order_by'] == "avg"
655 || $this->public_options['stats_tag']['views']
656 )
657 && ( isset($post_object->pageviews) || isset($post_object->avg_views) )
658 ) {
659 $pageviews = ( $this->public_options['order_by'] == "views" || $this->public_options['order_by'] == "comments" )
660 ? $post_object->pageviews
661 : $post_object->avg_views;
662 }
663
664 return $pageviews;
665 }
666
667 /**
668 * Return post comment count.
669 *
670 * @since 3.0.0
671 * @access private
672 * @param object $post_object
673 * @return int
674 */
675 private function get_comments(\stdClass $post_object)
676 {
677 $comments = ( ( $this->public_options['order_by'] == "comments" || $this->public_options['stats_tag']['comment_count'] ) && isset($post_object->comment_count) )
678 ? $post_object->comment_count
679 : 0;
680
681 return $comments;
682 }
683
684 /**
685 * Return post metadata.
686 *
687 * @since 3.0.0
688 * @access private
689 * @param object $post_object
690 * @param integer $post_id
691 * @return array
692 */
693 private function get_metadata(\stdClass $post_object, $post_id)
694 {
695 $stats = [];
696
697 // comments
698 if ( $this->public_options['stats_tag']['comment_count'] ) {
699 $comments = $this->get_comments($post_object);
700
701 $comments_text = sprintf(
702 _n('%s comment', '%s comments', $comments, 'wordpress-popular-posts'),
703 number_format_i18n($comments)
704 );
705 }
706
707 // views
708 if ( $this->public_options['stats_tag']['views'] ) {
709 $pageviews = $this->get_pageviews($post_object);
710
711 if ( $this->public_options['order_by'] == 'avg' ) {
712 $views_text = sprintf(
713 _n('%s view per day', '%s views per day', $pageviews, 'wordpress-popular-posts'),
714 number_format_i18n($pageviews, (fmod($pageviews, 1) !== 0.0 ? 2 : 0))
715 );
716 }
717 else {
718 $views_text = sprintf(
719 _n('%s view', '%s views', $pageviews, 'wordpress-popular-posts'),
720 number_format_i18n($pageviews)
721 );
722 }
723 }
724
725 if ( "comments" == $this->public_options['order_by'] ) {
726 if ( $this->public_options['stats_tag']['comment_count'] )
727 $stats[] = '<span class="wpp-comments">' . $comments_text . '</span>'; // First comments count
728 if ( $this->public_options['stats_tag']['views'] )
729 $stats[] = '<span class="wpp-views">' . $views_text . "</span>"; // ... then views
730 } else {
731 if ( $this->public_options['stats_tag']['views'] )
732 $stats[] = '<span class="wpp-views">' . $views_text . "</span>"; // First views count
733 if ( $this->public_options['stats_tag']['comment_count'] )
734 $stats[] = '<span class="wpp-comments">' . $comments_text . '</span>'; // ... then comments
735 }
736
737 // author
738 if ( $this->public_options['stats_tag']['author'] ) {
739 $author = $this->get_author($post_object, $post_id);
740 $author_url = get_author_posts_url($post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid);
741 $display_name = '<a href="' . $this->translate->url($author_url, $this->translate->get_current_language()) . '">' . $author . '</a>';
742 $stats[] = '<span class="wpp-author">' . sprintf(__('by %s', 'wordpress-popular-posts'), $display_name) . '</span>';
743 }
744
745 // date
746 if ( $this->public_options['stats_tag']['date']['active'] ) {
747 $date = $this->get_date($post_object);
748 $stats[] = '<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>';
749 }
750
751 // taxonomy
752 if ( $this->public_options['stats_tag']['category'] ) {
753 $post_tax = $this->get_taxonomies($post_id);
754
755 if ( $post_tax != '' ) {
756 $stats[] = '<span class="wpp-category">' . sprintf(__('under %s', 'wordpress-popular-posts'), $post_tax) . '</span>';
757 }
758 }
759
760 return $stats;
761 }
762
763 /**
764 * Parse content tags.
765 *
766 * @since 1.4.6
767 * @access private
768 * @param string HTML string with content tags
769 * @param array Post data
770 * @param bool Used to display post rating (if functionality is available)
771 * @return string
772 */
773 private function format_content($string, $data = [], $rating) {
774
775 if ( empty($string) || ( empty($data) || ! is_array($data) ) )
776 return false;
777
778 $params = [];
779 $pattern = '/\{(pid|excerpt|summary|meta|stats|title|image|thumb|thumb_img|thumb_url|rating|score|url|text_title|author|taxonomy|category|views|comments|date|total_items|item_position)\}/i';
780 preg_match_all($pattern, $string, $matches);
781
782 array_map('strtolower', $matches[0]);
783
784 if ( in_array("{pid}", $matches[0]) ) {
785 $string = str_replace("{pid}", $data['id'], $string);
786 }
787
788 if ( in_array("{title}", $matches[0]) ) {
789 $string = str_replace("{title}", $data['title'], $string);
790 }
791
792 if ( in_array("{meta}", $matches[0]) || in_array("{stats}", $matches[0]) ) {
793 $string = str_replace(["{meta}", "{stats}"], $data['stats'], $string);
794 }
795
796 if ( in_array("{excerpt}", $matches[0]) || in_array("{summary}", $matches[0]) ) {
797 $string = str_replace(["{excerpt}", "{summary}"], $data['summary'], $string);
798 }
799
800 if ( in_array("{image}", $matches[0]) || in_array("{thumb}", $matches[0]) ) {
801 $string = str_replace(["{image}", "{thumb}"], $data['img'], $string);
802 }
803
804 if ( in_array("{thumb_img}", $matches[0]) ) {
805 $string = str_replace("{thumb_img}", $data['img_no_link'], $string);
806 }
807
808 if ( in_array("{thumb_url}", $matches[0]) && ! empty($data['img_no_link']) ) {
809 $dom = new \DOMDocument;
810
811 if ( $dom->loadHTML($data['img_no_link']) ) {
812 $img_tag = $dom->getElementsByTagName('img');
813
814 if ( $img_tag->length ) {
815 foreach( $img_tag as $node ) {
816 if ( $node->hasAttribute('src') || $node->hasAttribute('data-img-src') ) {
817 $src = $node->hasAttribute('src') ? $node->getAttribute('src') : $node->getAttribute('data-img-src');
818 $string = str_replace("{thumb_url}", $src, $string);
819 }
820 }
821 }
822 }
823 }
824
825 // WP-PostRatings check
826 if ( $rating ) {
827 if ( function_exists('the_ratings_results') && in_array("{rating}", $matches[0]) ) {
828 $string = str_replace("{rating}", the_ratings_results($data['id']), $string);
829 }
830
831 if ( function_exists('expand_ratings_template') && in_array("{score}", $matches[0]) ) {
832 $string = str_replace("{score}", expand_ratings_template('%RATINGS_SCORE%', $data['id']), $string);
833 // removing the redundant plus sign
834 $string = str_replace('+', '', $string);
835 }
836 }
837
838 if ( in_array("{url}", $matches[0]) ) {
839 $string = str_replace("{url}", $data['url'], $string);
840 }
841
842 if ( in_array("{text_title}", $matches[0]) ) {
843 $string = str_replace("{text_title}", $data['text_title'], $string);
844 }
845
846 if ( in_array("{author}", $matches[0]) ) {
847 $string = str_replace("{author}", $data['author'], $string);
848 }
849
850 if ( in_array("{taxonomy}", $matches[0]) || in_array("{category}", $matches[0]) ) {
851 $string = str_replace(["{taxonomy}", "{category}"], $data['taxonomy'], $string);
852 }
853
854 if ( in_array("{views}", $matches[0]) ) {
855 $string = str_replace("{views}", $data['views'], $string);
856 }
857
858 if ( in_array("{comments}", $matches[0]) ) {
859 $string = str_replace("{comments}", $data['comments'], $string);
860 }
861
862 if ( in_array("{date}", $matches[0]) ) {
863 $string = str_replace("{date}", $data['date'], $string);
864 }
865
866 if ( in_array("{total_items}", $matches[0]) ) {
867 $string = str_replace("{total_items}", $data['total_items'], $string);
868 }
869
870 if ( in_array("{item_position}", $matches[0]) ) {
871 $string = str_replace("{item_position}", $data['item_position'], $string);
872 }
873
874 return apply_filters("wpp_parse_custom_content_tags", $string, $data['id']);
875 }
876
877 /**
878 * Checks whether we're currently seeing a single post/page/CPT.
879 *
880 * @since 5.0.0
881 * @return int
882 */
883 public function is_single()
884 {
885 return apply_filters('wpp_is_single', Helper::is_single());
886 }
887 }
888