PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.1
16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 All 504 releases
← All changes | _inc/lib/class-jetpack-top-posts-helper.php +86 -21 13.3.316.3-a.1 View file →
@@ -13,11 +13,11 @@
13 13 class Jetpack_Top_Posts_Helper {
14 14 /**
15 15 * Returns user's top posts.
16 16 *
17 - * @param int $period Period of days to draw stats from.
18 - * @param int $items_count Optional. Number of items to display.
19 - * @param string $types Optional. Content types to include.
17 + * @param int|string $period Period of days to draw stats from, or 'all-time'.
18 + * @param int $items_count Optional. Number of items to display.
19 + * @param string $types Optional. Content types to include.
20 20 * @return array
21 21 */
22 22 public static function get_top_posts( $period, $items_count = null, $types = null ) {
23 23 $all_time_days = floor( ( time() - strtotime( get_option( 'site_created_date' ) ) ) / ( 60 * 60 * 24 * 365 ) );
@@ -37,16 +37,62 @@
37 37 'num' => $period !== 'all-time' ? $period : $all_time_days,
38 38 'period' => 'day',
39 39 );
40 40
41 - $data = ( new WPCOM_Stats() )->get_top_posts( $query_args, $override_cache );
41 + // Atomic or self-hosted sites via WPCOM public v1.1 endpoint.
42 + if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
43 + $data = ( new WPCOM_Stats() )->get_top_posts( $query_args, $override_cache );
44 + } else {
45 + // Directly access posts on WPCOM, as Simple sites run on the same environment.
46 + require_lib( 'jetpack-stats' );
47 + if ( class_exists( '\Jetpack\Stats\Top_Posts' ) ) {
48 + // @phan-suppress-next-line PhanUndeclaredClassMethod
49 + $data = ( new \Jetpack\Stats\Top_Posts() )->get_top_posts( get_current_blog_id(), $query_args );
50 + } else {
51 + $data = array( 'summary' => array( 'postviews' => array() ) );
52 + }
53 + }
42 54
43 55 if ( is_wp_error( $data ) ) {
44 56 $data = array( 'summary' => array( 'postviews' => array() ) );
45 57 }
46 58
47 - $posts_retrieved = is_countable( $data['summary']['postviews'] ) ? count( $data['summary']['postviews'] ) : 0;
59 + $acceptable_types = $is_rendering_block ? explode( ',', $types ) : array();
48 60
61 + // Remove posts that have subsequently been deleted. The endpoint can return more
62 + // entries than the `max` we asked for, so stop there, then keep only further ones
63 + // the block can render, so its type filter is never starved.
64 + $published = array();
65 + $renderable = 0;
66 +
67 + foreach ( (array) ( $data['summary']['postviews'] ?? array() ) as $item ) {
68 + $capped = $is_rendering_block && count( $published ) >= $posts_to_obtain_count;
69 +
70 + if ( $capped && $renderable >= $items_count ) {
71 + break;
72 + }
73 + if ( get_post_status( $item['id'] ) !== 'publish' ) {
74 + continue;
75 + }
76 +
77 + $can_render = $is_rendering_block
78 + && ! empty( $item['public'] )
79 + && in_array( $item['type'] ?? '', $acceptable_types, true );
80 +
81 + if ( $capped && ! $can_render ) {
82 + continue;
83 + }
84 +
85 + $published[] = $item;
86 +
87 + if ( $can_render ) {
88 + ++$renderable;
89 + }
90 + }
91 +
92 + $data['summary']['postviews'] = $published;
93 + $posts_retrieved = count( $published );
94 +
49 95 // Fallback to random posts if user does not have enough top content.
50 96 if ( $posts_retrieved < $posts_to_obtain_count ) {
51 97 $args = array(
52 98 'numberposts' => $posts_to_obtain_count - $posts_retrieved,
@@ -75,8 +121,13 @@
75 121
76 122 $top_posts = array();
77 123
78 124 foreach ( $data['summary']['postviews'] as $post ) {
125 + // Non-public entries are discarded, so skip their thumbnail lookups entirely.
126 + if ( empty( $post['public'] ) ) {
127 + continue;
128 + }
129 +
79 130 $post_id = $post['id'];
80 131 $thumbnail = get_the_post_thumbnail_url( $post_id );
81 132
82 133 if ( ! $thumbnail ) {
@@ -86,28 +137,42 @@
86 137 $thumbnail = wp_get_attachment_url( $post_image->ID );
87 138 }
88 139 }
89 140
90 - if ( $post['public'] ) {
91 - $top_posts[] = array(
92 - 'id' => $post_id,
93 - 'author' => get_the_author_meta( 'display_name', get_post_field( 'post_author', $post_id ) ),
94 - 'context' => get_the_category( $post_id ) ? get_the_category( $post_id ) : get_the_tags( $post_id ),
95 - 'href' => $post['href'],
96 - 'date' => get_the_date( '', $post_id ),
97 - 'title' => $post['title'],
98 - 'type' => $post['type'],
99 - 'public' => $post['public'],
100 - 'views' => isset( $post['views'] ) ? $post['views'] : 0,
101 - 'thumbnail' => $thumbnail,
102 - );
103 - }
141 + $top_post = array(
142 + 'id' => $post_id,
143 + 'author' => get_the_author_meta( 'display_name', get_post_field( 'post_author', $post_id ) ),
144 + 'context' => get_the_category( $post_id ) ? get_the_category( $post_id ) : get_the_tags( $post_id ),
145 + // Use the local permalink to avoid stale values from the Stats API.
146 + 'href' => get_permalink( $post_id ),
147 + 'date' => get_the_date( '', $post_id ),
148 + 'title' => $post['title'],
149 + 'type' => $post['type'] ?? '',
150 + 'public' => $post['public'],
151 + 'views' => $post['views'] ?? 0,
152 + 'thumbnail' => $thumbnail,
153 + );
154 +
155 + /**
156 + * Allows modifying the title of each individual post returned by the Top Posts helper.
157 + *
158 + * Applies to both the Top Posts block's front-end output and the REST
159 + * response used by the block editor preview.
160 + *
161 + * @module stats
162 + *
163 + * @since 15.8
164 + *
165 + * @param string $post_title Post title.
166 + * @param array $top_post Information about the post.
167 + */
168 + $top_post['title'] = apply_filters( 'jetpack_top_posts_item_title', $top_post['title'], $top_post );
169 +
170 + $top_posts[] = $top_post;
104 171 }
105 172
106 173 // This applies for rendering the block front-end, but not for editing it.
107 174 if ( $is_rendering_block ) {
108 - $acceptable_types = explode( ',', $types );
109 -
110 175 $top_posts = array_filter(
111 176 $top_posts,
112 177 function ( $item ) use ( $acceptable_types ) {
113 178 return in_array( $item['type'], $acceptable_types, true );