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.media-summary.php +65 -48 12.0.3 → 16.3-a.1 View file →
@@ -4,8 +4,10 @@
4 4 *
5 5 * @package automattic/jetpack
6 6 */
7 7
8 +use Automattic\Jetpack\Image_CDN\Image_CDN_Core;
9 +
8 10 /**
9 11 * Class Jetpack_Media_Summary
10 12 *
11 13 * Priority: embed [video] > gallery > image > text
@@ -21,26 +23,28 @@
21 23
22 24 /**
23 25 * Get media summary for a post.
24 26 *
25 - * @param int $post_id Post ID.
27 + * @param ?int $post_id Post ID.
26 28 * @param int $blog_id Blog ID, if applicable.
27 29 * @param array $args {
28 30 * Optional. An array of arguments.
29 31 * @type int $max_words Maximum number of words.
30 32 * @type int $max_chars Maximum number of characters.
33 + * @type bool $include_excerpt Whether to compute the excerpt and return it. Default true.
34 + * @type bool $include_counts Whether to compute word/link counts. Default true.
31 35 * }
32 36 *
33 37 * @return array|mixed|void
34 38 */
35 - public static function get( $post_id, $blog_id = 0, $args = array() ) {
36 - // @todo: Use type hinting in the line above when at PHP 7.0+.
39 + public static function get( ?int $post_id, int $blog_id = 0, array $args = array() ) {
37 40 $post_id = (int) $post_id;
38 - $blog_id = (int) $blog_id;
39 41
40 42 $defaults = array(
41 - 'max_words' => 16,
42 - 'max_chars' => 256,
43 + 'max_words' => 16,
44 + 'max_chars' => 256,
45 + 'include_excerpt' => true,
46 + 'include_counts' => true,
43 47 );
44 48 $args = wp_parse_args( $args, $defaults );
45 49
46 50 $switched = false;
@@ -50,9 +54,10 @@
50 54 } else {
51 55 $blog_id = get_current_blog_id();
52 56 }
53 57
54 - $cache_key = "{$blog_id}_{$post_id}_{$args['max_words']}_{$args['max_chars']}";
58 + $cache_key = "{$blog_id}_{$post_id}_{$args['max_words']}_{$args['max_chars']}_"
59 + . (int) $args['include_excerpt'] . '_' . (int) $args['include_counts'];
55 60 if ( isset( self::$cache[ $cache_key ] ) ) {
56 61 if ( $switched ) {
57 62 restore_current_blog();
58 63 }
@@ -75,20 +80,28 @@
75 80 'secure' => array(
76 81 'image' => '',
77 82 ),
78 83 'count' => array(
79 - 'image' => 0,
80 - 'video' => 0,
81 - 'word' => 0,
82 - 'link' => 0,
84 + 'image' => 0,
85 + 'video' => 0,
86 + 'word' => 0,
87 + 'word_remaining' => 0,
88 + 'link' => 0,
83 89 ),
84 90 );
85 91
86 92 if ( $post instanceof WP_Post && empty( $post->post_password ) ) {
87 - $return['excerpt'] = self::get_excerpt( $post->post_content, $post->post_excerpt, $args['max_words'], $args['max_chars'], $post );
88 - $return['count']['word'] = self::get_word_count( $post->post_content );
89 - $return['count']['word_remaining'] = self::get_word_remaining_count( $post->post_content, $return['excerpt'] );
90 - $return['count']['link'] = self::get_link_count( $post->post_content );
93 + if ( $args['include_excerpt'] ) {
94 + $return['excerpt'] = self::get_excerpt( $post->post_content, $post->post_excerpt, $args['max_words'], $args['max_chars'], $post );
95 + }
96 + if ( $args['include_counts'] ) {
97 + $return['count']['word'] = self::get_word_count( $post->post_content );
98 + $return['count']['link'] = self::get_link_count( $post->post_content );
99 + // Only compute word_remaining if we have an excerpt. If not, leave the default of 0.
100 + if ( $args['include_excerpt'] && '' !== $return['excerpt'] ) {
101 + $return['count']['word_remaining'] = self::get_word_remaining_count( $post->post_content, $return['excerpt'] );
102 + }
103 + }
91 104 }
92 105
93 106 $extract = Jetpack_Media_Meta_Extractor::extract( $blog_id, $post_id, Jetpack_Media_Meta_Extractor::ALL );
94 107
@@ -143,8 +156,11 @@
143 156 ++$return['count']['video'];
144 157 break;
145 158 case 'youtube':
146 159 if ( 0 === $return['count']['video'] ) {
160 + if ( ! isset( $extract['shortcode']['youtube']['id'][0] ) ) {
161 + break;
162 + }
147 163 $return['type'] = 'video';
148 164 $return['video'] = esc_url_raw( 'http://www.youtube.com/watch?feature=player_embedded&v=' . $extract['shortcode']['youtube']['id'][0] );
149 165 $return['image'] = self::get_video_poster( 'youtube', $extract['shortcode']['youtube']['id'][0] );
150 166 $return['secure']['video'] = self::https( $return['video'] );
@@ -153,8 +169,11 @@
153 169 ++$return['count']['video'];
154 170 break;
155 171 case 'vimeo':
156 172 if ( 0 === $return['count']['video'] ) {
173 + if ( ! isset( $extract['shortcode']['vimeo']['id'][0] ) ) {
174 + break;
175 + }
157 176 $return['type'] = 'video';
158 177 $return['video'] = esc_url_raw( 'http://vimeo.com/' . $extract['shortcode']['vimeo']['id'][0] );
159 178 $return['secure']['video'] = self::https( $return['video'] );
160 179
@@ -177,18 +196,18 @@
177 196 if ( 0 === $return['count']['video'] ) {
178 197 $return['type'] = 'video';
179 198 $return['video'] = 'http://' . $embed;
180 199 $return['secure']['video'] = self::https( $return['video'] );
181 - if ( false !== strpos( $embed, 'youtube' ) ) {
200 + if ( str_contains( $embed, 'youtube' ) ) {
182 201 $return['image'] = self::get_video_poster( 'youtube', jetpack_get_youtube_id( $return['video'] ) );
183 202 $return['secure']['image'] = self::https( $return['image'] );
184 - } elseif ( false !== strpos( $embed, 'youtu.be' ) ) {
203 + } elseif ( str_contains( $embed, 'youtu.be' ) ) {
185 204 $youtube_id = jetpack_get_youtube_id( $return['video'] );
186 205 $return['video'] = 'http://youtube.com/watch?v=' . $youtube_id . '&feature=youtu.be';
187 206 $return['secure']['video'] = self::https( $return['video'] );
188 207 $return['image'] = self::get_video_poster( 'youtube', jetpack_get_youtube_id( $return['video'] ) );
189 208 $return['secure']['image'] = self::https( $return['image'] );
190 - } elseif ( false !== strpos( $embed, 'vimeo' ) ) {
209 + } elseif ( str_contains( $embed, 'vimeo' ) ) {
191 210 $poster_image = get_post_meta( $post_id, 'vimeo_poster_image', true );
192 211 if ( ! empty( $poster_image ) ) {
193 212 $return['image'] = $poster_image;
194 213 $poster_url_parts = wp_parse_url( $poster_image );
@@ -193,9 +212,9 @@
193 212 $return['image'] = $poster_image;
194 213 $poster_url_parts = wp_parse_url( $poster_image );
195 214 $return['secure']['image'] = 'https://secure-a.vimeocdn.com' . $poster_url_parts['path'];
196 215 }
197 - } elseif ( false !== strpos( $embed, 'dailymotion' ) ) {
216 + } elseif ( str_contains( $embed, 'dailymotion' ) ) {
198 217 $return['image'] = str_replace( 'dailymotion.com/video/', 'dailymotion.com/thumbnail/video/', $embed );
199 218 $return['image'] = wp_parse_url( $return['image'], PHP_URL_SCHEME ) === null ? 'http://' . $return['image'] : $return['image'];
200 219 $return['secure']['image'] = self::https( $return['image'] );
201 220 }
@@ -219,9 +238,9 @@
219 238 }
220 239 ++$number_of_paragraphs;
221 240 }
222 241
223 - $number_of_paragraphs = $number_of_paragraphs - $return['count']['video']; // subtract amount for videos.
242 + $number_of_paragraphs -= $return['count']['video']; // subtract amount for videos.
224 243
225 244 // More than 2 paragraph? The video is not the primary focus so we can do some more analysis.
226 245 if ( $number_of_paragraphs > 2 ) {
227 246 $return['type'] = 'standard';
@@ -245,9 +264,9 @@
245 264 $number_of_paragraphs = 0;
246 265
247 266 foreach ( $paragraphs as $i => $paragraph ) {
248 267 // Don't include 'actual' captions as a paragraph.
249 - if ( false !== strpos( $paragraph, '[caption' ) ) {
268 + if ( str_contains( $paragraph, '[caption' ) ) {
250 269 unset( $paragraphs[ $i ] );
251 270 continue;
252 271 }
253 272 // Don't include blank lines as a paragraph.
@@ -257,13 +276,16 @@
257 276 }
258 277 ++$number_of_paragraphs;
259 278 }
260 279
261 - $return['image'] = $extract['image'][0]['url'];
262 - $return['secure']['image'] = self::ssl_img( $return['image'] );
263 - ++$return['count']['image'];
280 + // @phan-suppress-next-line PhanTypeMismatchDimFetch -- Phan is understandably confused, as $extract has many forms, including this one.
281 + if ( ! empty( $extract['image'][0]['url'] ) ) {
282 + $return['image'] = $extract['image'][0]['url'];
283 + $return['secure']['image'] = self::ssl_img( $return['image'] );
284 + ++$return['count']['image'];
285 + }
264 286
265 - if ( $number_of_paragraphs <= 2 && 1 === count( $extract['image'] ) ) {
287 + if ( $number_of_paragraphs <= 2 && is_countable( $extract['image'] ) && 1 === count( $extract['image'] ) ) {
266 288 // If we have lots of text or images, let's not treat it as an image post, but return its first image.
267 289 $return['type'] = 'image';
268 290 }
269 291 }
@@ -306,12 +328,12 @@
306 328 *
307 329 * @return string URL.
308 330 */
309 331 public static function ssl_img( $url ) {
310 - if ( false !== strpos( $url, 'files.wordpress.com' ) ) {
332 + if ( str_contains( $url, 'files.wordpress.com' ) ) {
311 333 return self::https( $url );
312 334 } else {
313 - return self::https( jetpack_photon_url( $url ) );
335 + return self::https( Image_CDN_Core::cdn_url( $url ) );
314 336 }
315 337 }
316 338
317 339 /**
@@ -338,27 +360,20 @@
338 360 /**
339 361 * Clean text of shortcodes and tags.
340 362 *
341 363 * @param string $text Dirty text.
364 + * @param bool $preserve_urls When true, keep http(s) URLs in the text instead of stripping them. Default false.
342 365 *
343 366 * @return string Clean text.
344 367 */
345 - public static function clean_text( $text ) {
346 - return trim(
347 - preg_replace(
348 - '/[\s]+/',
349 - ' ',
350 - preg_replace(
351 - '@https?://[\S]+@',
352 - '',
353 - strip_shortcodes(
354 - wp_strip_all_tags(
355 - $text
356 - )
357 - )
358 - )
359 - )
360 - );
368 + public static function clean_text( $text, $preserve_urls = false ) {
369 + $text = strip_shortcodes( wp_strip_all_tags( $text ) );
370 +
371 + if ( ! $preserve_urls ) {
372 + $text = preg_replace( '@https?://[\S]+@', '', $text );
373 + }
374 +
375 + return trim( preg_replace( '/[\s]+/', ' ', $text ) );
361 376 }
362 377
363 378 /**
364 379 * Retrieve an excerpt for the post summary.
@@ -372,11 +387,12 @@
372 387 * @param string $post_excerpt The post's excerpt. Empty if none was explicitly set.
373 388 * @param int $max_words Maximum number of words for the excerpt. Used on wp.com. Default 16.
374 389 * @param int $max_chars Maximum characters in the excerpt. Used on wp.com. Default 256.
375 390 * @param WP_Post $requested_post The post object.
391 + * @param bool $preserve_urls When true, keep http(s) URLs in the excerpt instead of stripping them. Default false.
376 392 * @return string Post excerpt.
377 393 **/
378 - public static function get_excerpt( $post_content, $post_excerpt, $max_words = 16, $max_chars = 256, $requested_post = null ) {
394 + public static function get_excerpt( $post_content, $post_excerpt, $max_words = 16, $max_chars = 256, $requested_post = null, $preserve_urls = false ) {
379 395 global $post;
380 396 $original_post = $post; // Saving the global for later use.
381 397 if ( empty( $post_excerpt ) && function_exists( 'wpcom_enhanced_excerpt_extract_excerpt' ) ) {
382 398 return self::clean_text(
@@ -388,9 +404,10 @@
388 404 'max_words' => $max_words,
389 405 'max_chars' => $max_chars,
390 406 'read_more_threshold' => 25,
391 407 )
392 - )
408 + ),
409 + $preserve_urls
393 410 );
394 411 } elseif ( $requested_post instanceof WP_Post ) {
395 412 // @todo Refactor to not need to override the global.
396 413 // phpcs:ignore: WordPress.WP.GlobalVariablesOverride.Prohibited
@@ -400,9 +417,9 @@
400 417 $post_excerpt = apply_filters( 'get_the_excerpt', $post_excerpt, $post );
401 418 // phpcs:ignore: WordPress.WP.GlobalVariablesOverride.Prohibited
402 419 $post = $original_post; // wp_reset_postdata uses the $post global.
403 420 wp_reset_postdata();
404 - return self::clean_text( $post_excerpt );
421 + return self::clean_text( $post_excerpt, $preserve_urls );
405 422 }
406 423 return '';
407 424 }
408 425
@@ -427,9 +444,9 @@
427 444 *
428 445 * @return int Word count.
429 446 */
430 447 public static function get_word_count( $post_content ) {
431 - return (int) count( self::split_content_in_words( self::clean_text( $post_content ) ) );
448 + return count( self::split_content_in_words( self::clean_text( $post_content ) ) );
432 449 }
433 450
434 451 /**
435 452 * Get remainder word count (after the excerpt).
@@ -442,9 +459,9 @@
442 459 public static function get_word_remaining_count( $post_content, $excerpt_content ) {
443 460 $content_word_count = count( self::split_content_in_words( self::clean_text( $post_content ) ) );
444 461 $excerpt_word_count = count( self::split_content_in_words( self::clean_text( $excerpt_content ) ) );
445 462
446 - return (int) $content_word_count - $excerpt_word_count;
463 + return $content_word_count - $excerpt_word_count;
447 464 }
448 465
449 466 /**
450 467 * Counts the number of links in a post.