Wordpress - Custom Video Post Type with PHP
In my work at KVCR/FNX, I was asked to create a "Video Portal" where users could watch our licensed and original content. The equipment we had to do this was a WordPress host and a Vimeo pro account.
To get started, I created a WordPress installation from scratch, and built around a custom post type I created programatically via PHP. This custom post type was "Video", and allowed for several pick and choose options. These options included Geoblocking, series selection, automatic thumbnail selection via the vimeo/youtube thumbnail, and more.
In this post, we'll go over the YouTube/Vimeo thumbnail selection and generation.
Declare Support your Theme Needs
/* functions.php */
add_theme_support('post-thumbnails');
add_theme_support('title-tag');
new Videos;
Create the Custom Post Type
/*
class.videos.php
*/
class Videos {
/*
Videos Class
` Provides the wordpress functionality to add videos.
VITAL to theme.
*/
public function __construct() {
register_post_type('video', $this->create_video());
add_action( 'post_updated', array($this, 'save_video'));
}
public function create_video() {
/*
Defines the "Video" Content Type in wordpress.
*/
$args = array (
'labels' => array(
'name' => __( 'Videos' ),
'singular_name' => __( 'Videos' ),
'add_new' => __( 'Add Video' ),
'add_new_item' => __( 'Add New Video' ),
'edit_item' => __( 'Edit Video' ),
'new_item' => __( 'Add New Video' ),
'view_item' => __( 'View Video' ),
'search_items' => __( 'Search Videos' ),
'not_found' => __( 'No Videos Found' ),
'not_found_in_trash' => __( 'No Videos found in trash. ' )
),
'has_archive' => true,
'menu_icon' => 'dashicons-format-video',
'public' => true,
'show_ui' => true,
'capability_type' => 'post',
'hierarchical' => false,
'rewrite' => true,
'menu_position' => 20,
'supports' => array('title', 'thumbnail', 'editor'),
);
return $args;
}
}
This is very simple code, and should add a "Video" custom post type. No support for the above mentioned features has been added yet.
Custom Featured Image - Frontend
In order to allow for a custom featured image, the user needs to input a youtube or a vimeo ID. This is the frontend code that allows you to input that Vimeo/YouTube ID so that the system can automatically pick that thumbnail.
The user selects whether it is a Vimeo or YouTube video through a radio selection box.
/*
class.videos.php
*/
add_action( 'add_meta_boxes', array($this, 'video_meta_boxes'));
public function video_meta_boxes() {
/*
Defines three meta boxes for the left side.
youtube Information
And a notice about the thumbnail (UI)
*/
add_meta_box(
'metainfo',
'Meta Information',
array($this, 'video_meta_information'),
'video',
'normal',
'high'
);
add_meta_box(
'featured_image_help',
'Note',
array($this, 'video_featured_image_help'),
'video',
'side',
'low'
);
public function video_meta_information( $post ) {
/*
Call back for the video ID metabox
*/
wp_nonce_field( 'video_meta_save', 'video_meta_box' );
$provider = get_post_meta($post->ID, 'provider', true);
$videoid = get_post_meta($post->ID, 'videoid', true);
$season = get_post_meta($post->ID, 'season', true);
$episode = get_post_meta($post->ID, 'episode', true);
require_once(THEME_ROOT. 'includes/tpl/video-meta.tpl.php');
/*
<table class="admin">
<tr>
<td colspan=2><p><i>Please enter JUST the youtube OR Vimeo ID. E.G TimW1s36NCI/112212232</i></p></td>
</tr>
<tr>
<th>Video ID</th>
<td><input type="text" name="videoid" value="<?php print $videoid; ?>"/></td>
</tr>
<tr>
<th>Provider</th>
<td>
<table>
<tr>
<td>
<input type="radio" name="provider" value="youtube" <?php if($provider == 'youtube') {print 'checked'; } ?>>Youtube
</td>
</tr>
<tr>
<td>
<input type="radio" name="provider" value="vimeo" <?php if($provider == 'vimeo') {print 'checked'; } ?>>Vimeo
</td>
</tr>
</table>
</td>
</tr>
</table>
*/
}
public function video_featured_image_help( $post ) {
/*
Call back for the featured image metabox
*/
require_once(THEME_ROOT.'includes/tpl/video-featured-image-help.tpl.php');
/*
<p>Upon uploading of this video, the server will make the featured image a thumbnail from the Vimeo ID provided.<br /><br />To override this feature, simply replace the image once it has added in.</p>
*/
}
Custom Featured Image - Backend
We needed support for a "Featured Image". This image was what shows in the frontend when a user clicks on an episode. This should be pulled from Youtube/Vimeo to make everyones lives easier.
Here is some code to accomplish that. Note that you need a Youtube API key in order to grab a thumbnail from Youtube.
public function save_video( $post_id ) {
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
/*
If autosaving, do nothing
*/
return;
}
/*
Update video ID
*/
$videoid = wp_kses( $_POST['videoid'], '');
update_post_meta( $post_id, 'videoid', $videoid, '' );
/*
Update video provider
*/
$provider = wp_kses ($_POST['provider'], '');
update_post_meta( $post_id, 'provider', $provider, '');
if( !isset( $_POST['videoid'] ) || !isset ( $_POST['provider']) || !wp_verify_nonce( $_REQUEST['video_meta_box'], 'video_meta_save' ) ) {
/*
If the video ID and provider isn't selected, or the wp_kses is faked, get out
*/
return;
}
if( !has_post_thumbnail($post_id)) {
if($provider == 'youtube') {
$this->Generate_Featured_Image( $this->fetch_youtube_thumbnail($videoid), $post_id );
}
if($provider == 'vimeo') {
$this->Generate_Featured_Image( $this->fetch_vimeo_thumbnail($videoid), $post_id );
}
}
}
public function fetch_vimeo_thumbnail($vimeoid) {
/*
Used to get the thumbnail URL from a vimeo ID.
*/
$jsonurl = 'https://vimeo.com/api/oembed.json?url=http://vimeo.com/'.$vimeoid;
$jsondownload = file_get_contents($jsonurl);
$jsondecoded = json_decode($jsondownload, true);
$thumbnailurl = $jsondecoded['thumbnail_url'];
return $thumbnailurl;
}
public function fetch_youtube_thumbnail($youtubeid) {
/*
Used to get the thumbnail URL from a video ID.
*/
$jsonurl = 'https://www.googleapis.com/youtube/v3/videos?part=id,snippet&id='.$youtubeid.'&key=YOUTUBEAPIKEY';
$jsondownload = file_get_contents($jsonurl);
$jsondecoded = json_decode($jsondownload);
$thumbnailurl = $jsondecoded->items[0]->snippet->thumbnails->high->url;
return $thumbnailurl;
}
private function Generate_Featured_Image( $image_url, $post_id ){
/*
Given an Image URL, downloads the image to the WP media gallery
And sets it to the featured image.
*/
$upload_dir = wp_upload_dir();
$image_data = file_get_contents($image_url);
$filename = date('mdyHisu').basename($image_url);
if(wp_mkdir_p($upload_dir['path']))
$file = $upload_dir['path'] . '/' . $filename;
else
$file = $upload_dir['basedir'] . '/' . $filename;
file_put_contents($file, $image_data);
$wp_filetype = wp_check_filetype($filename, null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => sanitize_file_name($filename),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $file, $post_id );
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata( $attach_id, $file );
$res1 = wp_update_attachment_metadata( $attach_id, $attach_data );
$res2 = set_post_thumbnail( $post_id, $attach_id );
}
At this point, the user should have a custom post type called "Video" and be able to assign a featured image. This featured image is automatically pulled from Youtube or Vimeo (depending on what the user selected) once the user clicks "Publish".