Completed
Push — master-stable ( f5da56...c14258 )
by
unknown
09:30
created

utility-functions.php ➔ videopress_download_video()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 32
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 4
nop 2
dl 0
loc 32
rs 8.439
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B utility-functions.php ➔ create_local_media_library_for_videopress_guid() 0 29 4
1
<?php
2
3
/**
4
 * We won't have any videos less than sixty pixels wide. That would be silly.
5
 */
6
defined( 'VIDEOPRESS_MIN_WIDTH' ) or define( 'VIDEOPRESS_MIN_WIDTH', 60 );
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
7
8
/**
9
 * Validate user-supplied guid values against expected inputs
10
 *
11
 * @since 1.1
12
 * @param string $guid video identifier
13
 * @return bool true if passes validation test
14
 */
15
function videopress_is_valid_guid( $guid ) {
16
	if ( ! empty( $guid ) && is_string( $guid ) && strlen( $guid ) === 8 && ctype_alnum( $guid ) ) {
17
		return true;
18
	}
19
	return false;
20
}
21
22
/**
23
 * Get details about a specific video by GUID:
24
 *
25
 * @param $guid string
26
 * @return object
27
 */
28
function videopress_get_video_details( $guid ) {
29
	if ( ! videopress_is_valid_guid( $guid ) ) {
30
		return new WP_Error( 'bad-guid-format', __( 'Invalid Video GUID!', 'jetpack' ) );
31
	}
32
33
	$version  = '1.1';
34
	$endpoint = sprintf( '/videos/%1$s', $guid );
35
	$query_url = sprintf(
36
		'https://public-api.wordpress.com/rest/v%1$s%2$s',
37
		$version,
38
		$endpoint
39
	);
40
41
	// Look for data in our transient. If nothing, let's make a new query.
42
	$data_from_cache = get_transient( 'jetpack_videopress_' . $guid );
43
	if ( false === $data_from_cache ) {
44
		$response = wp_remote_get( esc_url_raw( $query_url ) );
45
		$data     = json_decode( wp_remote_retrieve_body( $response ) );
46
47
		// Cache the response for an hour.
48
		set_transient( 'jetpack_videopress_' . $guid, $data, HOUR_IN_SECONDS );
49
	} else {
50
		$data = $data_from_cache;
51
	}
52
53
	/**
54
	 * Allow functions to modify fetched video details.
55
	 *
56
	 * This filter allows third-party code to modify the return data
57
	 * about a given video.  It may involve swapping some data out or
58
	 * adding new parameters.
59
	 *
60
	 * @since 4.0.0
61
	 *
62
	 * @param object $data The data returned by the WPCOM API. See: https://developer.wordpress.com/docs/api/1.1/get/videos/%24guid/
63
	 * @param string $guid The GUID of the VideoPress video in question.
64
	 */
65
	return apply_filters( 'videopress_get_video_details', $data, $guid );
66
}
67
68
69
/**
70
 * Get an attachment ID given a URL.
71
 *
72
 * Modified from http://wpscholar.com/blog/get-attachment-id-from-wp-image-url/
73
 *
74
 * @todo: Add some caching in here.
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
75
 *
76
 * @param string $url
77
 *
78
 * @return int|bool Attachment ID on success, false on failure
79
 */
80
function videopress_get_attachment_id_by_url( $url ) {
81
	$wp_upload_dir = wp_upload_dir();
82
	// Strip out protocols, so it doesn't fail because searching for http: in https: dir.
83
	$dir = set_url_scheme( trailingslashit( $wp_upload_dir['baseurl'] ), 'relative' );
84
85
	// Is URL in uploads directory?
86
	if ( false !== strpos( $url, $dir ) ) {
87
88
		$file = basename( $url );
89
90
		$query_args = array(
91
			'post_type'   => 'attachment',
92
			'post_status' => 'inherit',
93
			'fields'      => 'ids',
94
			'meta_query'  => array(
95
				array(
96
					'key'     => '_wp_attachment_metadata',
97
					'compare' => 'LIKE',
98
					'value'   => $file,
99
				),
100
			)
101
		);
102
103
		$query = new WP_Query( $query_args );
104
105
		if ( $query->have_posts() ) {
106
			foreach ( $query->posts as $attachment_id ) {
107
				$meta          = wp_get_attachment_metadata( $attachment_id );
108
				$original_file = basename( $meta['file'] );
109
				$cropped_files = wp_list_pluck( $meta['sizes'], 'file' );
110
111
				if ( $original_file === $file || in_array( $file, $cropped_files ) ) {
112
					return (int) $attachment_id;
113
				}
114
			}
115
		}
116
117
	}
118
119
	return false;
120
}
121
122
/**
123
 * Similar to `media_sideload_image` -- but returns an ID.
124
 *
125
 * @param $url
126
 * @param $attachment_id
127
 *
128
 * @return int|mixed|object|WP_Error
129
 */
130
function videopress_download_poster_image( $url, $attachment_id ) {
131
	// Set variables for storage, fix file filename for query strings.
132
	preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $url, $matches );
133
	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...
134
		return new WP_Error( 'image_sideload_failed', __( 'Invalid image URL', 'jetpack' ) );
135
	}
136
137
	$file_array = array();
138
	$file_array['name']     = basename( $matches[0] );
139
	$file_array['tmp_name'] = download_url( $url );
140
141
	// If error storing temporarily, return the error.
142
	if ( is_wp_error( $file_array['tmp_name'] ) ) {
143
		return $file_array['tmp_name'];
144
	}
145
146
	// Do the validation and storage stuff.
147
	$thumbnail_id = media_handle_sideload( $file_array, $attachment_id, null );
148
149
	// Flag it as poster image, so we can exclude it from display.
150
	update_post_meta( $thumbnail_id, 'videopress_poster_image', 1 );
151
152
	return $thumbnail_id;
153
}
154
155
/**
156
 * Creates a local media library item of a remote VideoPress video.
157
 *
158
 * @param $guid
159
 * @param int $parent_id
160
 *
161
 * @return int|object
162
 */
163
function create_local_media_library_for_videopress_guid( $guid, $parent_id = 0 ) {
164
	$vp_data = videopress_get_video_details( $guid );
165
	if ( ! $vp_data || is_wp_error( $vp_data ) ) {
166
		return $vp_data;
167
	}
168
169
	$args = array(
170
		'post_date'      => $vp_data->upload_date,
171
		'post_title'     => wp_kses( $vp_data->title, array() ),
172
		'post_content'   => wp_kses( $vp_data->description, array() ),
173
		'post_mime_type' => 'video/videopress',
174
		'guid'           => sprintf( 'https://videopress.com/v/%s', $guid ),
175
	);
176
177
	$attachment_id = wp_insert_attachment( $args, null, $parent_id );
178
179
	if ( ! is_wp_error( $attachment_id ) ) {
180
		update_post_meta( $attachment_id, 'videopress_guid', $guid );
181
		wp_update_attachment_metadata( $attachment_id, array(
182
			'width'  => $vp_data->width,
183
			'height' => $vp_data->height,
184
		) );
185
186
		$thumbnail_id = videopress_download_poster_image( $vp_data->poster, $attachment_id );
187
		update_post_meta( $attachment_id, '_thumbnail_id', $thumbnail_id );
188
	}
189
190
	return $attachment_id;
191
}
192
193
/**
194
 * Helper that will look for VideoPress media items that are more than 30 minutes old,
195
 * that have not had anything attached to them by a wpcom upload and deletes the ghost
196
 * attachment.
197
 *
198
 * These happen primarily because of failed upload attempts.
199
 *
200
 * @return int The number of items that were cleaned up.
201
 */
202
function videopress_cleanup_media_library() {
203
204
	// Disable this job for now.
205
	return 0;
206
	$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...
207
		'post_type'      => 'attachment',
208
		'post_status'    => 'inherit',
209
		'post_mime_type' => 'video/videopress',
210
		'meta_query'     => array(
211
			array(
212
				'key'   => 'videopress_status',
213
				'value' => 'new',
214
			),
215
		)
216
	);
217
218
	$query = new WP_Query( $query_args );
219
220
	$cleaned = 0;
221
222
	$now = current_time( 'timestamp' );
223
224
	if ( $query->have_posts() ) {
225
		foreach ( $query->posts as $post ) {
226
			$post_time = strtotime( $post->post_date_gmt );
227
228
			// If the post is older than 30 minutes, it is safe to delete it.
229
			if ( $now - $post_time > MINUTE_IN_SECONDS * 30 ) {
230
				// Force delete the attachment, because we don't want it appearing in the trash.
231
				wp_delete_attachment( $post->ID, true );
232
233
				$cleaned++;
234
			}
235
		}
236
	}
237
238
	return $cleaned;
239
}
240
241
/**
242
 * Return an absolute URI for a given filename and guid on the CDN.
243
 * No check is performed to ensure the guid exists or the file is present. Simple centralized string builder.
244
 *
245
 * @param string $guid     VideoPress identifier
246
 * @param string $filename name of file associated with the guid (video file name or thumbnail file name)
247
 *
248
 * @return string Absolute URL of VideoPress file for the given guid.
249
 */
250
function videopress_cdn_file_url( $guid, $filename ) {
251
	return "https://videos.files.wordpress.com/{$guid}/{$filename}";
252
}
253
254
/**
255
 * Get an array of the transcoding status for the given video post.
256
 *
257
 * @since 4.4
258
 * @param int $post_id
259
 * @return array|bool Returns an array of statuses if this is a VideoPress post, otherwise it returns false.
260
 */
261
function videopress_get_transcoding_status( $post_id ) {
262
	$meta = wp_get_attachment_metadata( $post_id );
263
264
	// If this has not been processed by videopress, we can skip the rest.
265
	if ( ! $meta || ! isset( $meta['file_statuses'] ) ) {
266
		return false;
267
	}
268
269
	$info = (object) $meta['file_statuses'];
270
271
	$status = array(
272
		'std_mp4' => isset( $info->mp4 ) ? $info->mp4 : null,
273
		'std_ogg' => isset( $info->ogg ) ? $info->ogg : null,
274
		'dvd_mp4' => isset( $info->dvd ) ? $info->dvd : null,
275
		'hd_mp4'  => isset( $info->hd )  ? $info->hd : null,
276
	);
277
278
	return $status;
279
}
280
281
/**
282
 * Get the direct url to the video.
283
 *
284
 * @since 4.4
285
 * @param string $guid
286
 * @return string
287
 */
288
function videopress_build_url( $guid ) {
289
290
	// No guid, no videopress url.
291
	if ( ! $guid ) {
292
		return '';
293
	}
294
295
	return 'https://videopress.com/v/' . $guid;
296
}
297
298
/**
299
 * Create an empty videopress media item that will be filled out later by an xmlrpc
300
 * callback from the VideoPress servers.
301
 *
302
 * @since 4.4
303
 * @param string $title
304
 * @return int|WP_Error
305
 */
306
function videopress_create_new_media_item( $title, $guid = null ) {
307
	$post = array(
308
		'post_type'      => 'attachment',
309
		'post_mime_type' => 'video/videopress',
310
		'post_title'     => $title,
311
		'post_content'   => '',
312
		'guid'           => videopress_build_url( $guid ),
313
	);
314
315
	$media_id = wp_insert_post( $post );
316
317
	add_post_meta( $media_id, 'videopress_status', 'initiated' );
318
319
	add_post_meta( $media_id, 'videopress_guid', $guid );
320
321
	return $media_id;
322
}
323
324
325
/**
326
 * @param array $current_status
327
 * @param array $new_meta
328
 * @return array
329
 */
330
function videopress_merge_file_status( $current_status, $new_meta ) {
331
	$new_statuses = array();
332
333 View Code Duplication
	if ( isset( $new_meta['videopress']['files_status']['hd'] ) ) {
334
		$new_statuses['hd'] = $new_meta['videopress']['files_status']['hd'];
335
	}
336
337 View Code Duplication
	if ( isset( $new_meta['videopress']['files_status']['dvd'] ) ) {
338
		$new_statuses['dvd'] = $new_meta['videopress']['files_status']['dvd'];
339
	}
340
341 View Code Duplication
	if ( isset( $new_meta['videopress']['files_status']['std']['mp4'] ) ) {
342
		$new_statuses['mp4'] = $new_meta['videopress']['files_status']['std']['mp4'];
343
	}
344
345 View Code Duplication
	if ( isset( $new_meta['videopress']['files_status']['std']['ogg'] ) ) {
346
		$new_statuses['ogg'] = $new_meta['videopress']['files_status']['std']['ogg'];
347
	}
348
349
	foreach ( $new_statuses as $format => $status ) {
350
		if ( ! isset( $current_status[ $format ] ) ) {
351
			$current_status[ $format ] = $status;
352
			continue;
353
		}
354
355
		if ( $current_status[ $format ] !== 'DONE' ) {
356
			$current_status[ $format ] = $status;
357
		}
358
	}
359
360
	return $current_status;
361
}
362
363
/**
364
 * Check to see if a video has completed processing.
365
 *
366
 * @since 4.4
367
 * @param int $post_id
368
 * @return bool
369
 */
370
function videopress_is_finished_processing( $post_id ) {
371
	$post = get_post( $post_id );
372
373
	if ( is_wp_error( $post ) ) {
374
		return false;
375
	}
376
377
	$meta = wp_get_attachment_metadata( $post->ID );
378
379
	if ( ! isset( $meta['file_statuses'] ) || ! is_array( $meta['file_statuses'] ) ) {
380
		return false;
381
	}
382
383
	$check_statuses = array( 'hd', 'dvd', 'mp4', 'ogg' );
384
385
	foreach ( $check_statuses as $status ) {
386
		if ( ! isset( $meta['file_statuses'][ $status ] ) || $meta['file_statuses'][ $status ] != 'DONE' ) {
387
			return false;
388
		}
389
	}
390
391
	return true;
392
}
393
394
395
/**
396
 * Update the meta information  status for the given video post.
397
 *
398
 * @since 4.4
399
 * @param int $post_id
400
 * @return bool
401
 */
402
function videopress_update_meta_data( $post_id ) {
403
404
	$meta = wp_get_attachment_metadata( $post_id );
405
406
	// If this has not been processed by VideoPress, we can skip the rest.
407
	if ( ! $meta || ! isset( $meta['videopress'] ) ) {
408
		return false;
409
	}
410
411
	$info = (object) $meta['videopress'];
412
413
	$args = array(
414
		// 'sslverify' => false,
415
	);
416
417
	$result = wp_remote_get( videopress_make_video_get_path( $info->guid ), $args );
418
419
	if ( is_wp_error( $result ) ) {
420
		return false;
421
	}
422
423
	$response = json_decode( $result['body'], true );
424
425
	// Update the attachment metadata.
426
	$meta['videopress'] = $response;
427
428
	wp_update_attachment_metadata( $post_id, $meta );
429
430
	return true;
431
}
432
433
/**
434
 * Check to see if this is a VideoPress post that hasn't had a guid set yet.
435
 *
436
 * @param int $post_id
437
 * @return bool
438
 */
439
function videopress_is_attachment_without_guid( $post_id ) {
440
	$post = get_post( $post_id );
441
442
	if ( is_wp_error( $post ) ) {
443
		return false;
444
	}
445
446
	if ( $post->post_mime_type !== 'video/videopress' ) {
447
		return false;
448
	}
449
450
	$videopress_guid = get_post_meta( $post_id, 'videopress_guid', true );
451
452
	if ( $videopress_guid ) {
453
		return false;
454
	}
455
456
	return true;
457
}
458
459
/**
460
 * Check to see if this is a VideoPress attachment.
461
 *
462
 * @param int $post_id
463
 * @return bool
464
 */
465
function is_videopress_attachment( $post_id ) {
466
	$post = get_post( $post_id );
467
468
	if ( is_wp_error( $post ) ) {
469
		return false;
470
	}
471
472
	if ( $post->post_mime_type !== 'video/videopress' ) {
473
		return false;
474
	}
475
476
	return true;
477
}
478
479
/**
480
 * Get the video update path
481
 *
482
 * @since 4.4
483
 * @param string $guid
484
 * @return string
485
 */
486
function videopress_make_video_get_path( $guid ) {
487
	return sprintf(
488
		'%s://%s/rest/v%s/videos/%s',
489
		'https',
490
		JETPACK__WPCOM_JSON_API_HOST,
491
		Jetpack_Client::WPCOM_JSON_API_VERSION,
492
		$guid
493
	);
494
}
495
496
/**
497
 * Get the upload api path.
498
 *
499
 * @since 4.4
500
 * @param int $blog_id The id of the blog we're uploading to.
501
 * @return string
502
 */
503
function videopress_make_media_upload_path( $blog_id ) {
504
	return sprintf(
505
		'https://public-api.wordpress.com/rest/v1.1/sites/%s/media/new',
506
		$blog_id
507
	);
508
}
509
510
/**
511
 * This is a mock of the internal VideoPress method, which is meant to duplicate the functionality
512
 * of the WPCOM API, so that the Jetpack REST API returns the same data with no modifications.
513
 *
514
 * @param int $blog_id Blog ID.
515
 * @param int $post_id Post ID.
516
 * @return bool|stdClass
517
 */
518
function video_get_info_by_blogpostid( $blog_id, $post_id ) {
519
	$post = get_post( $post_id );
520
521
	$video_info = new stdClass();
522
	$video_info->post_id = $post_id;
523
	$video_info->blog_id = $blog_id;
524
	$video_info->guid = null;
525
	$video_info->finish_date_gmt = '0000-00-00 00:00:00';
526
527
	if ( is_wp_error( $post ) ) {
528
		return $video_info;
529
	}
530
531
	if ( 'video/videopress' !== $post->post_mime_type ) {
532
		return $video_info;
533
	}
534
535
	// Since this is a VideoPress post, lt's fill out the rest of the object.
536
	$video_info->guid = get_post_meta( $post_id, 'videopress_guid', true );
537
538
	if ( videopress_is_finished_processing( $post_id ) ) {
539
		$video_info->finish_date_gmt = date( 'Y-m-d H:i:s' );
540
	}
541
542
	return $video_info;
543
}
544
545
546
/**
547
 * Check that a VideoPress video format has finished processing.
548
 *
549
 * This uses the info object, because that is what the WPCOM endpoint
550
 * uses, however we don't have a complete info object in the same way
551
 * WPCOM does, so we pull the meta information out of the post
552
 * options instead.
553
 *
554
 * Note: This mimics the WPCOM function of the same name and helps the media
555
 * API endpoint add all needed VideoPress data.
556
 *
557
 * @param stdClass $info
558
 * @param string $format
559
 * @return bool
560
 */
561
function video_format_done( $info, $format ) {
562
563
	// Avoids notice when a non-videopress item is found.
564
	if ( ! is_object( $info ) ) {
565
		return false;
566
	}
567
568
	$post_id = $info->post_id;
569
570
	if ( get_post_mime_type( $post_id ) !== 'video/videopress' ) {
571
		return false;
572
	}
573
574
	$post = get_post( $post_id );
575
576
	if ( is_wp_error( $post ) ) {
577
		return false;
578
	}
579
580
	$meta = wp_get_attachment_metadata( $post->ID );
581
582
	switch ( $format ) {
583
		case 'fmt_hd':
584
			return isset( $meta['videopress']['files']['hd']['mp4'] );
585
			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...
586
587
		case 'fmt_dvd':
588
			return isset( $meta['videopress']['files']['dvd']['mp4'] );
589
			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...
590
591
		case 'fmt_std':
592
			return isset( $meta['videopress']['files']['std']['mp4'] );
593
			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...
594
595
		case 'fmt_ogg':
596
			return isset( $meta['videopress']['files']['std']['ogg'] );
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
600
	return false;
601
}
602
603
/**
604
 * Get the image URL for the given VideoPress GUID
605
 *
606
 * We look up by GUID, because that is what WPCOM does and this needs to be
607
 * parameter compatible with that.
608
 *
609
 * Note: This mimics the WPCOM function of the same name and helps the media
610
 * API endpoint add all needed VideoPress data.
611
 *
612
 * @param string $guid
613
 * @param string $format
614
 * @return string
615
 */
616
function video_image_url_by_guid( $guid, $format ) {
0 ignored issues
show
Unused Code introduced by
The parameter $format is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
617
618
	$post = video_get_post_by_guid( $guid );
619
620
	if ( is_wp_error( $post ) ) {
621
		return null;
622
	}
623
624
	$meta = wp_get_attachment_metadata( $post->ID );
625
626
	// We add ssl => 1 to make sure that the videos.files.wordpress.com domain is parsed as photon.
627
	$poster = apply_filters( 'jetpack_photon_url', $meta['videopress']['poster'], array( 'ssl' => 1 ), 'https' );
628
629
	return $poster;
630
}
631
632
/**
633
 * Using a GUID, find a post.
634
 *
635
 * @param string $guid
636
 * @return WP_Post
637
 */
638
function video_get_post_by_guid( $guid ) {
639
	$args = array(
640
		'post_type' 	 => 'attachment',
641
		'post_mime_type' => 'video/videopress',
642
		'post_status' 	 => 'inherit',
643
		'meta_query' 	 => array(
644
			array(
645
				'key' 	  => 'videopress_guid',
646
				'value'   => $guid,
647
				'compare' => '=',
648
			)
649
		)
650
	);
651
652
	$query = new WP_Query( $args );
653
654
	$post = $query->next_post();
655
656
	return $post;
657
}
658
659
/**
660
 * From the given VideoPress post_id, return back the appropriate attachment URL.
661
 *
662
 * When the MP4 hasn't been processed yet or this is not a VideoPress video, this will return null.
663
 *
664
 * @param int $post_id
665
 * @return string|null
666
 */
667
function videopress_get_attachment_url( $post_id ) {
668
669
	// We only handle VideoPress attachments.
670
	if ( get_post_mime_type( $post_id ) !== 'video/videopress' ) {
671
		return null;
672
	}
673
674
	$meta = wp_get_attachment_metadata( $post_id );
675
676
	if ( ! isset( $meta['videopress']['files']['hd']['mp4'] ) ) {
677
		// Use the original file as the url if it isn't transcoded yet.
678
		if ( isset( $meta['original'] ) ) {
679
			return $meta['original'];
680
		}
681
682
		// Otherwise, there isn't much we can do.
683
		return null;
684
	}
685
686
	return $meta['videopress']['file_url_base']['https'] . $meta['videopress']['files']['hd']['mp4'];
687
}
688