Completed
Push — dependabot/npm_and_yarn/ini-1.... ( 6a445d...18502d )
by Yaroslav
08:59 queued 10s
created

utility-functions.php ➔ video_get_info_by_blogpostid()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 6
nop 2
dl 0
loc 32
rs 8.7857
c 0
b 0
f 0
1
<?php
2
3
use Automattic\Jetpack\Connection\Client;
4
5
/**
6
 * We won't have any videos less than sixty pixels wide. That would be silly.
7
 */
8
defined( 'VIDEOPRESS_MIN_WIDTH' ) or define( 'VIDEOPRESS_MIN_WIDTH', 60 );
9
10
/**
11
 * Validate user-supplied guid values against expected inputs
12
 *
13
 * @since 1.1
14
 * @param string $guid video identifier
15
 * @return bool true if passes validation test
16
 */
17
function videopress_is_valid_guid( $guid ) {
18
	if ( ! empty( $guid ) && is_string( $guid ) && strlen( $guid ) === 8 && ctype_alnum( $guid ) ) {
19
		return true;
20
	}
21
	return false;
22
}
23
24
/**
25
 * Get details about a specific video by GUID:
26
 *
27
 * @param $guid string
28
 * @return object
29
 */
30
function videopress_get_video_details( $guid ) {
31
	if ( ! videopress_is_valid_guid( $guid ) ) {
32
		return new WP_Error( 'bad-guid-format', __( 'Invalid Video GUID!', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'bad-guid-format'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
33
	}
34
35
	$version   = '1.1';
36
	$endpoint  = sprintf( '/videos/%1$s', $guid );
37
	$query_url = sprintf(
38
		'https://public-api.wordpress.com/rest/v%1$s%2$s',
39
		$version,
40
		$endpoint
41
	);
42
43
	// Look for data in our transient. If nothing, let's make a new query.
44
	$data_from_cache = get_transient( 'jetpack_videopress_' . $guid );
45
	if ( false === $data_from_cache ) {
46
		$response = wp_remote_get( esc_url_raw( $query_url ) );
47
		$data     = json_decode( wp_remote_retrieve_body( $response ) );
48
49
		// Cache the response for an hour.
50
		set_transient( 'jetpack_videopress_' . $guid, $data, HOUR_IN_SECONDS );
51
	} else {
52
		$data = $data_from_cache;
53
	}
54
55
	/**
56
	 * Allow functions to modify fetched video details.
57
	 *
58
	 * This filter allows third-party code to modify the return data
59
	 * about a given video.  It may involve swapping some data out or
60
	 * adding new parameters.
61
	 *
62
	 * @since 4.0.0
63
	 *
64
	 * @param object $data The data returned by the WPCOM API. See: https://developer.wordpress.com/docs/api/1.1/get/videos/%24guid/
65
	 * @param string $guid The GUID of the VideoPress video in question.
66
	 */
67
	return apply_filters( 'videopress_get_video_details', $data, $guid );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $guid.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
68
}
69
70
71
/**
72
 * Get an attachment ID given a URL.
73
 *
74
 * Modified from https://wpscholar.com/blog/get-attachment-id-from-wp-image-url/
75
 *
76
 * @deprecated since 8.4.0
77
 * @see videopress_get_post_id_by_guid()
78
 *
79
 * @param string $url
80
 *
81
 * @return int|bool Attachment ID on success, false on failure
82
 */
83
function videopress_get_attachment_id_by_url( $url ) {
84
	_deprecated_function( __FUNCTION__, 'jetpack-8.4' );
85
86
	$wp_upload_dir = wp_upload_dir();
87
	// Strip out protocols, so it doesn't fail because searching for http: in https: dir.
88
	$dir = set_url_scheme( trailingslashit( $wp_upload_dir['baseurl'] ), 'relative' );
89
90
	// Is URL in uploads directory?
91
	if ( false !== strpos( $url, $dir ) ) {
92
93
		$file = basename( $url );
94
95
		$query_args = array(
96
			'post_type'   => 'attachment',
97
			'post_status' => 'inherit',
98
			'fields'      => 'ids',
99
			'meta_query'  => array(
100
				array(
101
					'key'     => '_wp_attachment_metadata',
102
					'compare' => 'LIKE',
103
					'value'   => $file,
104
				),
105
			),
106
		);
107
108
		$query = new WP_Query( $query_args );
109
110
		if ( $query->have_posts() ) {
111
			foreach ( $query->posts as $attachment_id ) {
112
				$meta          = wp_get_attachment_metadata( $attachment_id );
113
				$original_file = basename( $meta['file'] );
114
				$cropped_files = wp_list_pluck( $meta['sizes'], 'file' );
115
116
				if ( $original_file === $file || in_array( $file, $cropped_files ) ) {
117
					return (int) $attachment_id;
118
				}
119
			}
120
		}
121
	}
122
123
	return false;
124
}
125
126
/**
127
 * Similar to `media_sideload_image` -- but returns an ID.
128
 *
129
 * @param $url
130
 * @param $attachment_id
131
 *
132
 * @return int|mixed|object|WP_Error
133
 */
134
function videopress_download_poster_image( $url, $attachment_id ) {
135
	// Set variables for storage, fix file filename for query strings.
136
	preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $url, $matches );
137
	if ( ! $matches ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $matches of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
138
		return new WP_Error( 'image_sideload_failed', __( 'Invalid image URL', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'image_sideload_failed'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
139
	}
140
141
	$file_array             = array();
142
	$file_array['name']     = basename( $matches[0] );
143
	$file_array['tmp_name'] = download_url( $url );
144
145
	// If error storing temporarily, return the error.
146
	if ( is_wp_error( $file_array['tmp_name'] ) ) {
147
		return $file_array['tmp_name'];
148
	}
149
150
	// Do the validation and storage stuff.
151
	$thumbnail_id = media_handle_sideload( $file_array, $attachment_id, null );
152
153
	// Flag it as poster image, so we can exclude it from display.
154
	update_post_meta( $thumbnail_id, 'videopress_poster_image', 1 );
155
156
	return $thumbnail_id;
157
}
158
159
/**
160
 * Creates a local media library item of a remote VideoPress video.
161
 *
162
 * @param $guid
163
 * @param int  $parent_id
164
 *
165
 * @return int|object
166
 */
167
function create_local_media_library_for_videopress_guid( $guid, $parent_id = 0 ) {
168
	$vp_data = videopress_get_video_details( $guid );
169
	if ( ! $vp_data || is_wp_error( $vp_data ) ) {
170
		return $vp_data;
171
	}
172
173
	$args = array(
174
		'post_date'      => $vp_data->upload_date,
175
		'post_title'     => wp_kses( $vp_data->title, array() ),
176
		'post_content'   => wp_kses( $vp_data->description, array() ),
177
		'post_mime_type' => 'video/videopress',
178
		'guid'           => sprintf( 'https://videopress.com/v/%s', $guid ),
179
	);
180
181
	$attachment_id = wp_insert_attachment( $args, null, $parent_id );
182
183
	if ( ! is_wp_error( $attachment_id ) ) {
184
		update_post_meta( $attachment_id, 'videopress_guid', $guid );
185
		wp_update_attachment_metadata(
186
			$attachment_id,
187
			array(
188
				'width'  => $vp_data->width,
189
				'height' => $vp_data->height,
190
			)
191
		);
192
193
		$thumbnail_id = videopress_download_poster_image( $vp_data->poster, $attachment_id );
194
		update_post_meta( $attachment_id, '_thumbnail_id', $thumbnail_id );
195
	}
196
197
	return $attachment_id;
198
}
199
200
/**
201
 * Helper that will look for VideoPress media items that are more than 30 minutes old,
202
 * that have not had anything attached to them by a wpcom upload and deletes the ghost
203
 * attachment.
204
 *
205
 * These happen primarily because of failed upload attempts.
206
 *
207
 * @return int The number of items that were cleaned up.
208
 */
209
function videopress_cleanup_media_library() {
210
211
	// Disable this job for now.
212
	return 0;
213
	$query_args = array(
0 ignored issues
show
Unused Code introduced by
$query_args = array('pos...', 'value' => 'new'))); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
214
		'post_type'      => 'attachment',
215
		'post_status'    => 'inherit',
216
		'post_mime_type' => 'video/videopress',
217
		'meta_query'     => array(
218
			array(
219
				'key'   => 'videopress_status',
220
				'value' => 'new',
221
			),
222
		),
223
	);
224
225
	$query = new WP_Query( $query_args );
226
227
	$cleaned = 0;
228
229
	$now = current_time( 'timestamp' );
230
231
	if ( $query->have_posts() ) {
232
		foreach ( $query->posts as $post ) {
233
			$post_time = strtotime( $post->post_date_gmt );
234
235
			// If the post is older than 30 minutes, it is safe to delete it.
236
			if ( $now - $post_time > MINUTE_IN_SECONDS * 30 ) {
237
				// Force delete the attachment, because we don't want it appearing in the trash.
238
				wp_delete_attachment( $post->ID, true );
239
240
				$cleaned++;
241
			}
242
		}
243
	}
244
245
	return $cleaned;
246
}
247
248
/**
249
 * Return an absolute URI for a given filename and guid on the CDN.
250
 * No check is performed to ensure the guid exists or the file is present. Simple centralized string builder.
251
 *
252
 * @param string $guid     VideoPress identifier
253
 * @param string $filename name of file associated with the guid (video file name or thumbnail file name)
254
 *
255
 * @return string Absolute URL of VideoPress file for the given guid.
256
 */
257
function videopress_cdn_file_url( $guid, $filename ) {
258
	return "https://videos.files.wordpress.com/{$guid}/{$filename}";
259
}
260
261
/**
262
 * Get an array of the transcoding status for the given video post.
263
 *
264
 * @since 4.4
265
 * @param int $post_id
266
 * @return array|bool Returns an array of statuses if this is a VideoPress post, otherwise it returns false.
267
 */
268
function videopress_get_transcoding_status( $post_id ) {
269
	$meta = wp_get_attachment_metadata( $post_id );
270
271
	// If this has not been processed by videopress, we can skip the rest.
272
	if ( ! $meta || ! isset( $meta['file_statuses'] ) ) {
273
		return false;
274
	}
275
276
	$info = (object) $meta['file_statuses'];
277
278
	$status = array(
279
		'std_mp4' => isset( $info->mp4 ) ? $info->mp4 : null,
280
		'std_ogg' => isset( $info->ogg ) ? $info->ogg : null,
281
		'dvd_mp4' => isset( $info->dvd ) ? $info->dvd : null,
282
		'hd_mp4'  => isset( $info->hd ) ? $info->hd : null,
283
	);
284
285
	return $status;
286
}
287
288
/**
289
 * Get the direct url to the video.
290
 *
291
 * @since 4.4
292
 * @param string $guid
293
 * @return string
294
 */
295
function videopress_build_url( $guid ) {
296
297
	// No guid, no videopress url.
298
	if ( ! $guid ) {
299
		return '';
300
	}
301
302
	return 'https://videopress.com/v/' . $guid;
303
}
304
305
/**
306
 * Create an empty videopress media item that will be filled out later by an xmlrpc
307
 * callback from the VideoPress servers.
308
 *
309
 * @since 4.4
310
 * @param string $title
311
 * @return int|WP_Error
312
 */
313
function videopress_create_new_media_item( $title, $guid = null ) {
314
	$post = array(
315
		'post_type'      => 'attachment',
316
		'post_mime_type' => 'video/videopress',
317
		'post_title'     => $title,
318
		'post_content'   => '',
319
		'guid'           => videopress_build_url( $guid ),
320
	);
321
322
	$media_id = wp_insert_post( $post );
323
324
	add_post_meta( $media_id, 'videopress_status', 'initiated' );
325
326
	add_post_meta( $media_id, 'videopress_guid', $guid );
327
328
	return $media_id;
329
}
330
331
332
/**
333
 * @param array $current_status
334
 * @param array $new_meta
335
 * @return array
336
 */
337
function videopress_merge_file_status( $current_status, $new_meta ) {
338
	$new_statuses = array();
339
340 View Code Duplication
	if ( isset( $new_meta['videopress']['files_status']['hd'] ) ) {
341
		$new_statuses['hd'] = $new_meta['videopress']['files_status']['hd'];
342
	}
343
344 View Code Duplication
	if ( isset( $new_meta['videopress']['files_status']['dvd'] ) ) {
345
		$new_statuses['dvd'] = $new_meta['videopress']['files_status']['dvd'];
346
	}
347
348 View Code Duplication
	if ( isset( $new_meta['videopress']['files_status']['std']['mp4'] ) ) {
349
		$new_statuses['mp4'] = $new_meta['videopress']['files_status']['std']['mp4'];
350
	}
351
352 View Code Duplication
	if ( isset( $new_meta['videopress']['files_status']['std']['ogg'] ) ) {
353
		$new_statuses['ogg'] = $new_meta['videopress']['files_status']['std']['ogg'];
354
	}
355
356
	foreach ( $new_statuses as $format => $status ) {
357
		if ( ! isset( $current_status[ $format ] ) ) {
358
			$current_status[ $format ] = $status;
359
			continue;
360
		}
361
362
		if ( $current_status[ $format ] !== 'DONE' ) {
363
			$current_status[ $format ] = $status;
364
		}
365
	}
366
367
	return $current_status;
368
}
369
370
/**
371
 * Check to see if a video has completed processing.
372
 *
373
 * @since 4.4
374
 * @param int $post_id
375
 * @return bool
376
 */
377
function videopress_is_finished_processing( $post_id ) {
378
	$post = get_post( $post_id );
379
380
	if ( is_wp_error( $post ) ) {
381
		return false;
382
	}
383
384
	$meta = wp_get_attachment_metadata( $post->ID );
385
386
	if ( ! isset( $meta['file_statuses'] ) || ! is_array( $meta['file_statuses'] ) ) {
387
		return false;
388
	}
389
390
	$check_statuses = array( 'hd', 'dvd', 'mp4', 'ogg' );
391
392
	foreach ( $check_statuses as $status ) {
393
		if ( ! isset( $meta['file_statuses'][ $status ] ) || $meta['file_statuses'][ $status ] != 'DONE' ) {
394
			return false;
395
		}
396
	}
397
398
	return true;
399
}
400
401
402
/**
403
 * Update the meta information  status for the given video post.
404
 *
405
 * @since 4.4
406
 * @param int $post_id
407
 * @return bool
408
 */
409
function videopress_update_meta_data( $post_id ) {
410
411
	$meta = wp_get_attachment_metadata( $post_id );
412
413
	// If this has not been processed by VideoPress, we can skip the rest.
414
	if ( ! $meta || ! isset( $meta['videopress'] ) ) {
415
		return false;
416
	}
417
418
	$info = (object) $meta['videopress'];
419
420
	$args = array(
421
		// 'sslverify' => false,
422
	);
423
424
	$result = wp_remote_get( videopress_make_video_get_path( $info->guid ), $args );
425
426
	if ( is_wp_error( $result ) ) {
427
		return false;
428
	}
429
430
	$response = json_decode( $result['body'], true );
431
432
	// Update the attachment metadata.
433
	$meta['videopress'] = $response;
434
435
	wp_update_attachment_metadata( $post_id, $meta );
436
437
	return true;
438
}
439
440
/**
441
 * Check to see if this is a VideoPress post that hasn't had a guid set yet.
442
 *
443
 * @param int $post_id
444
 * @return bool
445
 */
446
function videopress_is_attachment_without_guid( $post_id ) {
447
	$post = get_post( $post_id );
448
449
	if ( is_wp_error( $post ) ) {
450
		return false;
451
	}
452
453
	if ( $post->post_mime_type !== 'video/videopress' ) {
454
		return false;
455
	}
456
457
	$videopress_guid = get_post_meta( $post_id, 'videopress_guid', true );
458
459
	if ( $videopress_guid ) {
460
		return false;
461
	}
462
463
	return true;
464
}
465
466
/**
467
 * Check to see if this is a VideoPress attachment.
468
 *
469
 * @param int $post_id
470
 * @return bool
471
 */
472
function is_videopress_attachment( $post_id ) {
473
	$post = get_post( $post_id );
474
475
	if ( is_wp_error( $post ) ) {
476
		return false;
477
	}
478
479
	if ( $post->post_mime_type !== 'video/videopress' ) {
480
		return false;
481
	}
482
483
	return true;
484
}
485
486
/**
487
 * Get the video update path
488
 *
489
 * @since 4.4
490
 * @param string $guid
491
 * @return string
492
 */
493
function videopress_make_video_get_path( $guid ) {
494
	return sprintf(
495
		'%s/rest/v%s/videos/%s',
496
		JETPACK__WPCOM_JSON_API_BASE,
497
		Client::WPCOM_JSON_API_VERSION,
498
		$guid
499
	);
500
}
501
502
/**
503
 * Get the upload api path.
504
 *
505
 * @since 4.4
506
 * @param int $blog_id The id of the blog we're uploading to.
507
 * @return string
508
 */
509
function videopress_make_media_upload_path( $blog_id ) {
510
	return sprintf(
511
		'https://public-api.wordpress.com/rest/v1.1/sites/%s/media/new',
512
		$blog_id
513
	);
514
}
515
516
/**
517
 * This is a mock of the internal VideoPress method, which is meant to duplicate the functionality
518
 * of the WPCOM API, so that the Jetpack REST API returns the same data with no modifications.
519
 *
520
 * @param int $blog_id Blog ID.
521
 * @param int $post_id Post ID.
522
 * @return bool|stdClass
523
 */
524
function video_get_info_by_blogpostid( $blog_id, $post_id ) {
525
	$post = get_post( $post_id );
526
527
	$video_info                  = new stdClass();
528
	$video_info->post_id         = $post_id;
529
	$video_info->blog_id         = $blog_id;
530
	$video_info->guid            = null;
531
	$video_info->finish_date_gmt = '0000-00-00 00:00:00';
532
533
	if ( is_wp_error( $post ) ) {
534
		return $video_info;
535
	}
536
537
	if ( 'video/videopress' !== $post->post_mime_type ) {
538
		return $video_info;
539
	}
540
541
	// Since this is a VideoPress post, lt's fill out the rest of the object.
542
	$video_info->guid = get_post_meta( $post_id, 'videopress_guid', true );
543
	$meta             = wp_get_attachment_metadata( $post_id );
544
545
	if ( $meta && isset( $meta['videopress'] ) ) {
546
		$videopress_meta    = $meta['videopress'];
547
		$video_info->rating = $videopress_meta['rating'];
548
	}
549
550
	if ( videopress_is_finished_processing( $post_id ) ) {
551
		$video_info->finish_date_gmt = date( 'Y-m-d H:i:s' );
552
	}
553
554
	return $video_info;
555
}
556
557
558
/**
559
 * Check that a VideoPress video format has finished processing.
560
 *
561
 * This uses the info object, because that is what the WPCOM endpoint
562
 * uses, however we don't have a complete info object in the same way
563
 * WPCOM does, so we pull the meta information out of the post
564
 * options instead.
565
 *
566
 * Note: This mimics the WPCOM function of the same name and helps the media
567
 * API endpoint add all needed VideoPress data.
568
 *
569
 * @param stdClass $info
570
 * @param string   $format
571
 * @return bool
572
 */
573
function video_format_done( $info, $format ) {
574
575
	// Avoids notice when a non-videopress item is found.
576
	if ( ! is_object( $info ) ) {
577
		return false;
578
	}
579
580
	$post_id = $info->post_id;
581
582
	if ( get_post_mime_type( $post_id ) !== 'video/videopress' ) {
583
		return false;
584
	}
585
586
	$post = get_post( $post_id );
587
588
	if ( is_wp_error( $post ) ) {
589
		return false;
590
	}
591
592
	$meta = wp_get_attachment_metadata( $post->ID );
593
594
	switch ( $format ) {
595
		case 'fmt_hd':
596
			return isset( $meta['videopress']['files']['hd']['mp4'] );
597
			break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
598
599
		case 'fmt_dvd':
600
			return isset( $meta['videopress']['files']['dvd']['mp4'] );
601
			break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
602
603
		case 'fmt_std':
604
			return isset( $meta['videopress']['files']['std']['mp4'] );
605
			break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
606
607
		case 'fmt_ogg':
608
			return isset( $meta['videopress']['files']['std']['ogg'] );
609
			break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
610
	}
611
612
	return false;
613
}
614
615
/**
616
 * Get the image URL for the given VideoPress GUID
617
 *
618
 * We look up by GUID, because that is what WPCOM does and this needs to be
619
 * parameter compatible with that.
620
 *
621
 * Note: This mimics the WPCOM function of the same name and helps the media
622
 * API endpoint add all needed VideoPress data.
623
 *
624
 * @param string $guid
625
 * @param string $format
626
 * @return string
627
 */
628
function video_image_url_by_guid( $guid, $format ) {
629
630
	$post = videopress_get_post_by_guid( $guid );
631
632
	if ( is_wp_error( $post ) ) {
633
		return null;
634
	}
635
636
	$meta = wp_get_attachment_metadata( $post->ID );
637
638
	// We add ssl => 1 to make sure that the videos.files.wordpress.com domain is parsed as photon.
639
	$poster = apply_filters( 'jetpack_photon_url', $meta['videopress']['poster'], array( 'ssl' => 1 ), 'https' );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with array('ssl' => 1).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
640
641
	return $poster;
642
}
643
644
/**
645
 * Using a GUID, find a post.
646
 *
647
 * @param string $guid The post guid.
648
 * @return WP_Post|false The post for that guid, or false if none is found.
649
 */
650
function videopress_get_post_by_guid( $guid ) {
651
	$cache_key   = 'get_post_by_guid_' . $guid;
652
	$cache_group = 'videopress';
653
	$cached_post = wp_cache_get( $cache_key, $cache_group );
654
655
	if ( is_object( $cached_post ) && 'WP_Post' === get_class( $cached_post ) ) {
656
		return $cached_post;
657
	}
658
659
	$post_id = videopress_get_post_id_by_guid( $guid );
660
661
	if ( is_int( $post_id ) ) {
662
		$post = get_post( $post_id );
663
		wp_cache_set( $cache_key, $post, $cache_group, HOUR_IN_SECONDS );
664
665
		return $post;
666
	}
667
668
	return false;
669
}
670
671
/**
672
 * Using a GUID, find a post.
673
 *
674
 * Kept for backward compatibility. Use videopress_get_post_by_guid() instead.
675
 *
676
 * @deprecated since 8.4.0
677
 * @see videopress_get_post_by_guid()
678
 *
679
 * @param string $guid The post guid.
680
 * @return WP_Post|false The post for that guid, or false if none is found.
681
 */
682
function video_get_post_by_guid( $guid ) {
683
	_deprecated_function( __FUNCTION__, 'jetpack-8.4' );
684
	return videopress_get_post_by_guid( $guid );
685
}
686
687
/**
688
 * Using a GUID, find the associated post ID.
689
 *
690
 * @since 8.4.0
691
 * @param string $guid The guid to look for the post ID of.
692
 * @return int|false The post ID for that guid, or false if none is found.
693
 */
694
function videopress_get_post_id_by_guid( $guid ) {
695
	$cache_key = 'videopress_get_post_id_by_guid_' . $guid;
696
	$cached_id = get_transient( $cache_key );
697
698
	if ( is_int( $cached_id ) ) {
699
		return $cached_id;
700
	}
701
702
	$args = array(
703
		'post_type'      => 'attachment',
704
		'post_mime_type' => 'video/videopress',
705
		'post_status'    => 'inherit',
706
		'no_found_rows'  => true,
707
		'fields'         => 'ids',
708
		'meta_query'     => array(
709
			array(
710
				'key'     => 'videopress_guid',
711
				'value'   => $guid,
712
				'compare' => '=',
713
			),
714
		),
715
	);
716
717
	$query = new WP_Query( $args );
718
719
	if ( $query->have_posts() ) {
720
		$post_id = $query->next_post();
721
		set_transient( $cache_key, $post_id, HOUR_IN_SECONDS );
722
723
		return $post_id;
724
	}
725
726
	return false;
727
}
728
729
/**
730
 * From the given VideoPress post_id, return back the appropriate attachment URL.
731
 *
732
 * When the MP4 hasn't been processed yet or this is not a VideoPress video, this will return null.
733
 *
734
 * @param int $post_id Post ID of the attachment.
735
 * @return string|null
736
 */
737
function videopress_get_attachment_url( $post_id ) {
738
739
	// We only handle VideoPress attachments.
740
	if ( get_post_mime_type( $post_id ) !== 'video/videopress' ) {
741
		return null;
742
	}
743
744
	$meta = wp_get_attachment_metadata( $post_id );
745
746
	if ( ! isset( $meta['videopress']['files']['hd']['mp4'] ) ) {
747
		// Use the original file as the url if it isn't transcoded yet.
748
		if ( isset( $meta['original'] ) ) {
749
			$return = $meta['original'];
750
		} else {
751
			// Otherwise, there isn't much we can do.
752
			return null;
753
		}
754
	} else {
755
		$return = $meta['videopress']['file_url_base']['https'] . $meta['videopress']['files']['hd']['mp4'];
756
	}
757
758
	// If the URL is a string, return it. Otherwise, we shouldn't to avoid errors downstream, so null.
759
	return ( is_string( $return ) ) ? $return : null;
760
}
761
762
/**
763
 * Converts VideoPress flash embeds into oEmbed-able URLs.
764
 *
765
 * Older VideoPress embed depended on Flash, which no longer work,
766
 * so let us convert them to an URL that WordPress can oEmbed.
767
 *
768
 * Note that this file is always loaded via modules/module-extras.php and is not dependent on module status.
769
 *
770
 * @param string $content the content.
771
 * @return string filtered content
772
 */
773
function jetpack_videopress_flash_embed_filter( $content ) {
774
	$regex   = '%<embed[^>]*+>(?:\s*</embed>)?%i';
775
	$content = preg_replace_callback(
776
		$regex,
777
		function( $matches, $orig_html = null ) {
778
			$embed_code  = $matches[0];
779
			$url_matches = array();
780
781
			// get video ID from flash URL.
782
			$url_matched = preg_match( '/src="http:\/\/v.wordpress.com\/([^"]+)"/', $embed_code, $url_matches );
783
784
			if ( $url_matched ) {
785
				$video_id = $url_matches[1];
786
				return "https://videopress.com/v/$video_id";
787
			}
788
		},
789
		$content
790
	);
791
	return $content;
792
}
793
794
/**
795
 * Checks if the provided rating string is a valid VideoPress video rating value.
796
 *
797
 * @param mixed $rating The video rating to validate.
798
 * @return bool
799
 */
800
function videopress_is_valid_video_rating( $rating ) {
801
	return in_array( $rating, array( 'G', 'PG-13', 'R-17', 'X-18' ), true );
802
}
803
804
add_filter( 'the_content', 'jetpack_videopress_flash_embed_filter', 7 ); // Needs to be priority 7 to allow Core to oEmbed.
805