Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

major refactoring to use video provider #54

Closed
153 changes: 23 additions & 130 deletions automatic-featured-images-from-videos.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ function wds_load_afi() {
if ( defined( 'WP_CLI' ) && WP_CLI ) {
require_once( plugin_dir_path( __FILE__ ) . 'includes/cli.php' );
}
require_once( plugin_dir_path( __FILE__ ) . 'includes/Provider_Bootstrap.php' );
require_once( plugin_dir_path( __FILE__ ) . 'includes/providers/Video_Provider.php' );
require_once( plugin_dir_path( __FILE__ ) . 'includes/providers/Youtube.php' );
require_once( plugin_dir_path( __FILE__ ) . 'includes/providers/Vimeo.php' );
}

/**
Expand Down Expand Up @@ -112,45 +116,40 @@ function wds_check_if_content_contains_video( $post_id, $post ) {
// Allow developers to filter the content to allow for searching in postmeta or other places.
$content = apply_filters( 'wds_featured_images_from_video_filter_content', $content, $post_id );

// Set the video id.
$youtube_id = wds_check_for_youtube( $content );
$vimeo_id = wds_check_for_vimeo( $content );
$video_thumbnail_url = '';
$providers = new Provider_Bootstrap();
$providers->add_provider( new Youtube() );
$providers->add_provider( new Vimeo() );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have a WP_Error return possible for this method, but don't do anything with that potential return value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah...not sure what to do with that. We don't usually raise exceptions in WP? Do you have thoughts, preferences?


if ( $youtube_id ) {
$youtube_details = wds_get_youtube_details( $youtube_id );
$video_thumbnail_url = $youtube_details['video_thumbnail_url'];
$video_url = $youtube_details['video_url'];
$video_embed_url = $youtube_details['video_embed_url'];
}
$has_video = false;
foreach ( $providers->video_providers() as $video_provider ) {
if ( ! is_a( $video_provider, Video_Provider::class ) ) {
return new WP_Error( __( 'The passed provider is not a Provider Object', 'automatic-featured-images-from-videos' ) );
}

if ( $vimeo_id ) {
$vimeo_details = wds_get_vimeo_details( $vimeo_id );
$video_thumbnail_url = $vimeo_details['video_thumbnail_url'];
$video_url = $vimeo_details['video_url'];
$video_embed_url = $vimeo_details['video_embed_url'];
if ( $video_provider->match_content( $content ) ) {
$has_video = true;
$video_thumbnail_url = $video_provider->get_video_thumbnail_url();
$video_url = $video_provider->get_video_url();
$video_embed_url = $video_provider->get_video_embed_url();
$video_id = $video_provider->get_video_id();

break;
}
}

if ( $post_id
&& ! has_post_thumbnail( $post_id )
&& $content
&& ( $youtube_details || $vimeo_details )
&& $has_video
) {
$video_id = '';
if ( $youtube_id ) {
$video_id = $youtube_id;
}
if ( $vimeo_id ) {
$video_id = $vimeo_id;
}
if ( ! wp_is_post_revision( $post_id ) ) {
wds_set_video_thumbnail_as_featured_image( $post_id, $video_thumbnail_url, $video_id );
}
}

if ( $post_id
&& $content
&& ( $youtube_id || $vimeo_id )
&& $has_video
) {
update_post_meta( $post_id, '_is_video', true );
update_post_meta( $post_id, '_video_url', $video_url );
Expand Down Expand Up @@ -208,46 +207,6 @@ function wds_set_video_thumbnail_as_featured_image( $post_id, $video_thumbnail_u
set_post_thumbnail( $post_id, $attachment_id );
}

/**
* Check if the content contains a youtube 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 youtube id.
*
*/
function wds_check_for_youtube( $content ) {
if ( preg_match( '#\/\/(www\.)?(youtu|youtube|youtube-nocookie)\.(com|be)\/(watch|embed)?\/?(\?v=)?([a-zA-Z0-9\-\_]+)#', $content, $youtube_matches ) ) {
return $youtube_matches[6];
}

return false;
}

/**
* 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;
}

/**
* Handle the upload of a new image.
*
Expand Down Expand Up @@ -338,72 +297,6 @@ function wds_ms_media_sideload_image_with_new_filename( $url, $post_id, $filenam
return $att_id;
}

/**
* Get the image thumbnail and the video url from a youtube id.
*
* @author Gary Kovar
*
* @since 1.0.5
*
* @param string $youtube_id Youtube video ID.
* @return array Video data.
*/
function wds_get_youtube_details( $youtube_id ) {
$video = array();
$video_thumbnail_url_string = 'http://img.youtube.com/vi/%s/%s';

$video_check = wp_remote_head( 'https://www.youtube.com/oembed?format=json&url=http://www.youtube.com/watch?v=' . $youtube_id );
if ( 200 === wp_remote_retrieve_response_code( $video_check ) ) {
$remote_headers = wp_remote_head(
sprintf(
$video_thumbnail_url_string,
$youtube_id,
'maxresdefault.jpg'
)
);
$video['video_thumbnail_url'] = ( 404 === wp_remote_retrieve_response_code( $remote_headers ) ) ?
sprintf(
$video_thumbnail_url_string,
$youtube_id,
'hqdefault.jpg'
) :
sprintf(
$video_thumbnail_url_string,
$youtube_id,
'maxresdefault.jpg'
);
$video['video_url'] = 'https://www.youtube.com/watch?v=' . $youtube_id;
$video['video_embed_url'] = 'https://www.youtube.com/embed/' . $youtube_id;
}

return $video;
}

/**
* 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 = array();

// @todo Get remote checking matching with wds_get_youtube_details.
$vimeo_data = wp_remote_get( 'http://www.vimeo.com/api/v2/video/' . intval( $vimeo_id ) . '.php' );
if ( 200 === wp_remote_retrieve_response_code( $vimeo_data ) ) {
$response = unserialize( $vimeo_data['body'] );
$video['video_thumbnail_url'] = isset( $response[0]['thumbnail_large'] ) ? $response[0]['thumbnail_large'] : false;
$video['video_url'] = $response[0]['url'];
$video['video_embed_url'] = 'https://player.vimeo.com/video/' . $vimeo_id;
}

return $video;
}

/**
* Check if the post is a video.
*
Expand Down
27 changes: 27 additions & 0 deletions includes/Provider_Bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

class Provider_Bootstrap {

protected $providers = [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely willing to drop 5.2, but this array shorthand would necessitate dropping 5.3 as well. Also tempting, especially with this plugin not being one of our more popular ones, even with useful utility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a habit...let me know where you want to go with versioning and I'll adjust accordingly.


public function add_provider( $provider ) {
if ( ! is_a( $provider, Video_Provider::class ) ) {
return new WP_Error( __( 'The passed provider is not a Provider Object', 'automatic-featured-images-from-videos' ) );
}

$this->providers[] = $provider;
}

public function video_providers() {
/**
* Allow developers to pass in custom video providers.
* Video providers should extend the Video_Provider class.
*
* @since 1.1.1
*
* @param Video_Provider $value An object that is of a class that extends Video_Provider.
*/
return apply_filters( 'wds_video_providers', $this->providers );
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like we have a slight disconnect with how to add providers. We get to do so with the add_provider method, everyone else would need to use the filter. Is there a way we could work things to be the same routine for everyone? Perhaps everyone uses the filter version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally fair point. I've refactored based on this note.
Given we have an add_provider method, I've added a remove_provider method. I've also updated the provider classes as appropriate.


}
17 changes: 17 additions & 0 deletions includes/providers/Video_Provider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

abstract class Video_Provider {

protected $id;

abstract public function match_content( $content );

abstract public function get_video_id();

abstract public function get_video_thumbnail_url();

abstract public function get_video_url();

abstract public function get_video_embed_url();

}
47 changes: 47 additions & 0 deletions includes/providers/Vimeo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

class Vimeo extends Video_Provider {

private $thumbnail_url;
private $url;
private $embed_url;


public function match_content( $content ) {
if ( preg_match( '#\/\/(.+\.)?(vimeo\.com)\/(\d*)#', $content, $vimeo_matches ) ) {
$this->id = $vimeo_matches[3];
$this->get_vimeo();

return true;
}

return false;
}

private function get_vimeo() {
$vimeo_data = wp_remote_get( 'http://www.vimeo.com/api/v2/video/' . (int) $this->id . '.php' );
if ( 200 === wp_remote_retrieve_response_code( $vimeo_data ) ) {
$response = unserialize( $vimeo_data['body'] );
$this->thumbnail_url = isset( $response[0]['thumbnail_large'] ) ? $response[0]['thumbnail_large'] : false;
$this->url = $response[0]['url'];
$this->embed_url = 'https://player.vimeo.com/video/' . $this->id;
}
}

public function get_video_thumbnail_url() {
return $this->thumbnail_url;
}

public function get_video_url() {
return $this->url;
}

public function get_video_embed_url() {
return $this->embed_url;
}

public function get_video_id() {
return $this->id;
}

}
56 changes: 56 additions & 0 deletions includes/providers/Youtube.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

class Youtube extends Video_Provider {

public function match_content( $content ) {
if ( preg_match( '#\/\/(www\.)?(youtu|youtube|youtube-nocookie)\.(com|be)\/(watch|embed)?\/?(\?v=)?([a-zA-Z0-9\-\_]+)#', $content, $youtube_matches ) ) {
$this->id = $youtube_matches[6];

return true;
}

return false;
}

public function get_video_thumbnail_url() {
$video_thumbnail_url_string = 'http://img.youtube.com/vi/%s/%s';

$video_check = wp_remote_head( 'https://www.youtube.com/oembed?format=json&url=http://www.youtube.com/watch?v=' . $this->id );
if ( 200 === wp_remote_retrieve_response_code( $video_check ) ) {
$remote_headers = wp_remote_head(
sprintf(
$video_thumbnail_url_string,
$this->id,
'maxresdefault.jpg'
)
);
$video_thumbnail_url = ( 404 === wp_remote_retrieve_response_code( $remote_headers ) ) ?
sprintf(
$video_thumbnail_url_string,
$this->id,
'hqdefault.jpg'
) :
sprintf(
$video_thumbnail_url_string,
$this->id,
'maxresdefault.jpg'
);
return $video_thumbnail_url;
}

return '';
}

public function get_video_url() {
return 'https://www.youtube.com/watch?v=' . $this->id;
}

public function get_video_embed_url() {
return 'https://www.youtube.com/embed/' . $this->id;
}

public function get_video_id() {
return $this->id;
}

}