-
-
Save ippeiukai/ee718addb65e9360b9cedac13fc224ea to your computer and use it in GitHub Desktop.
Wordpress: How to automatically attache youtube/vimeo thumbnail as a post feature image from a post meta key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// https://github.com/WebDevStudios/Automatic-Featured-Images-from-Videos/blob/1.2.0/automatic-featured-images-from-videos.php | |
/** | |
* If a YouTube or Vimeo video is added in the post content, grab its thumbnail and set it as the featured image. | |
* | |
* @since 1.0.0 | |
* | |
* @param int $post_id ID of the post being saved. | |
* @param string $video_thumbnail_url URL of the image thumbnail. | |
* @param string $video_id Video ID from embed. | |
*/ | |
function wds_set_video_thumbnail_as_featured_image( $post_id, $video_thumbnail_url, $video_id = '' ) { | |
// Bail if no valid video thumbnail URL. | |
if ( ! $video_thumbnail_url || is_wp_error( $video_thumbnail_url ) ) { | |
return; | |
} | |
$post_title = sanitize_title( preg_replace( '/[^a-zA-Z0-9\s]/', '-', get_the_title() ) ) . '-' . $video_id; | |
global $wpdb; | |
$stmt = "SELECT ID FROM {$wpdb->posts}"; | |
$stmt .= $wpdb->prepare( | |
' WHERE post_type = %s AND guid LIKE %s', | |
'attachment', | |
'%' . $wpdb->esc_like( $video_id ) . '%' | |
); | |
$attachment = $wpdb->get_col( $stmt ); | |
if ( !empty( $attachment[0] ) ) { | |
$attachment_id = $attachment[0]; | |
} else { | |
// Try to sideload the image. | |
$attachment_id = wds_ms_media_sideload_image_with_new_filename( $video_thumbnail_url, $post_id, $post_title, $video_id ); | |
} | |
// Bail if unable to sideload (happens if the URL or post ID is invalid, or if the URL 404s). | |
if ( is_wp_error( $attachment_id ) ) { | |
return; | |
} | |
// Woot! We got an image, so set it as the post thumbnail. | |
set_post_thumbnail( $post_id, $attachment_id ); | |
} | |
// https://github.com/WebDevStudios/Automatic-Featured-Images-from-Videos/blob/1.2.0/automatic-featured-images-from-videos.php | |
/** | |
* Handle the upload of a new image. | |
* | |
* @since 1.0.0 | |
* | |
* @param string $url URL to sideload. | |
* @param int $post_id Post ID to attach to. | |
* @param string|null $filename Filename to use. | |
* @param string $video_id Video ID. | |
* | |
* @return mixed | |
*/ | |
function wds_ms_media_sideload_image_with_new_filename( $url, $post_id, $filename = null, $video_id = null ) { | |
if ( ! $url || ! $post_id ) { | |
return new WP_Error( 'missing', esc_html__( 'Need a valid URL and post ID...', 'automatic-featured-images-from-videos' ) ); | |
} | |
require_once( ABSPATH . 'wp-admin/includes/file.php' ); | |
// Download file to temp location, returns full server path to temp file, ex; /home/user/public_html/mysite/wp-content/26192277_640.tmp. | |
$tmp = download_url( $url ); | |
// If error storing temporarily, unlink. | |
if ( is_wp_error( $tmp ) ) { | |
// And output wp_error. | |
return $tmp; | |
} | |
// Fix file filename for query strings. | |
preg_match( '/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $url, $matches ); | |
// Extract filename from url for title. | |
$url_filename = basename( $matches[0] ); | |
// Determine file type (ext and mime/type). | |
$url_type = wp_check_filetype( $url_filename ); | |
// Override filename if given, reconstruct server path. | |
if ( ! empty( $filename ) ) { | |
$filename = sanitize_file_name( $filename ); | |
// Extract path parts. | |
$tmppath = pathinfo( $tmp ); | |
// Build new path. | |
$new = $tmppath['dirname'] . '/' . $filename . '.' . $tmppath['extension']; | |
// Renames temp file on server. | |
rename( $tmp, $new ); | |
// Push new filename (in path) to be used in file array later. | |
$tmp = $new; | |
} | |
/* Assemble file data (should be built like $_FILES since wp_handle_sideload() will be using). */ | |
// Full server path to temp file. | |
$file_array['tmp_name'] = $tmp; | |
if ( ! empty( $filename ) ) { | |
// User given filename for title, add original URL extension. | |
$file_array['name'] = $filename . '.' . $url_type['ext']; | |
} else { | |
// Just use original URL filename. | |
$file_array['name'] = $url_filename; | |
} | |
$post_data = [ | |
// Just use the original filename (no extension). | |
'post_title' => get_the_title( $post_id ), | |
// Make sure gets tied to parent. | |
'post_parent' => $post_id, | |
]; | |
// Required libraries for media_handle_sideload. | |
require_once( ABSPATH . 'wp-admin/includes/file.php' ); | |
require_once( ABSPATH . 'wp-admin/includes/media.php' ); | |
require_once( ABSPATH . 'wp-admin/includes/image.php' ); | |
// Do the validation and storage stuff. | |
// $post_data can override the items saved to wp_posts table, like post_mime_type, guid, post_parent, post_title, post_content, post_status. | |
$att_id = media_handle_sideload( $file_array, $post_id, null, $post_data ); | |
// If error storing permanently, unlink. | |
if ( is_wp_error( $att_id ) ) { | |
// Clean up. | |
@unlink( $file_array['tmp_name'] ); | |
// And output wp_error. | |
return $att_id; | |
} | |
return $att_id; | |
} | |
// https://github.com/WebDevStudios/Automatic-Featured-Images-from-Videos/blob/1.2.0/automatic-featured-images-from-videos.php | |
/** | |
* Check if the content contains a vimeo url. | |
* | |
* Props to @rzen for lending his massive brain smarts to help with the regex. | |
* | |
* @author Gary Kovar | |
* | |
* @param $content | |
* | |
* @return string The value of the vimeo id. | |
* | |
*/ | |
function wds_check_for_vimeo( $content ) { | |
if ( preg_match( '#\/\/(.+\.)?(vimeo\.com)\/(\d*)#', $content, $vimeo_matches ) ) { | |
return $vimeo_matches[3]; | |
} | |
return false; | |
} | |
// https://github.com/WebDevStudios/Automatic-Featured-Images-from-Videos/blob/1.2.0/automatic-featured-images-from-videos.php | |
/** | |
* Get the image thumbnail and the video url from a vimeo id. | |
* | |
* @author Gary Kovar | |
* | |
* @since 1.0.5 | |
* | |
* @param string $vimeo_id Vimeo video ID. | |
* @return array Video information. | |
*/ | |
function wds_get_vimeo_details( $vimeo_id ) { | |
$video = []; | |
// @todo Get remote checking matching with wds_get_youtube_details. | |
$vimeo_data = wp_remote_get( 'https://www.vimeo.com/api/v2/video/' . intval( $vimeo_id ) . '.json' ); | |
if ( 200 === wp_remote_retrieve_response_code( $vimeo_data ) ) { | |
$response = json_decode( $vimeo_data['body'] ); | |
$large = isset( $response[0]->thumbnail_large ) ? $response[0]->thumbnail_large : ''; | |
if ( $large ) { | |
$larger_test = explode( '_', $large ); | |
$test_result = wp_remote_head( | |
$larger_test[0] | |
); | |
if ( 200 === wp_remote_retrieve_response_code( $test_result ) ) { | |
$large = $larger_test[0]; | |
} | |
} | |
// For the moment, we will force jpg since WebP is still iffy. | |
$video['video_thumbnail_url'] = isset( $large ) ? $large . '.jpg' : false; | |
$video['video_url'] = $response[0]->url; | |
$video['video_embed_url'] = 'https://player.vimeo.com/video/' . $vimeo_id; | |
} | |
return $video; | |
} | |
function set_featured_image_from_post_meta($post_id, $post, $update) { | |
$post_type = 'lecture'; // the custom post type | |
$meta_key = 'preview_vimeo_oembed'; // the custom meta key | |
if ($post_type !== get_post_type($post_id) || has_post_thumbnail($post_id)) { | |
return; | |
} | |
$video_url = get_post_meta($post_id, $meta_key, true); | |
if(!$video_url) { | |
return; | |
} | |
$vimeo_id = wds_check_for_vimeo($video_url); | |
if (!$vimeo_id) { | |
return; | |
} | |
$vimeo_details = wds_get_vimeo_details($vimeo_id); | |
if (empty($vimeo_details)) { | |
return; | |
} | |
$video_thumbnail_url = $vimeo_details['video_thumbnail_url']; | |
wds_set_video_thumbnail_as_featured_image($post_id, $video_thumbnail_url, $vimeo_id); | |
} | |
add_action('wp_after_insert_post', 'set_featured_image_from_post_meta', 10, 4); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment