Video Thumbnails - Version 2.1

Version Description

  • Changes under the hood to ensure the first video is found
  • Improved YouTube regex
Download this release

Release Info

Developer sutherlandboswell
Plugin Icon 128x128 Video Thumbnails
Version 2.1
Comparing to
See all releases

Code changes from version 2.0.10 to 2.1

php/class-video-thumbnails-settings.php CHANGED
@@ -262,7 +262,7 @@ function scan_video_thumbnails(){
262
  foreach ( $provider->test_cases as $test_case ) {
263
  echo '<tr>';
264
  echo '<td><strong>' . $provider->service_name . '</strong> - ' . $test_case['name'] . '</td>';
265
- $result = $provider->scan_for_thumbnail( $test_case['markup'] );
266
  if ( is_wp_error( $result ) ) {
267
  $error_string = $result->get_error_message();
268
  echo '<td style="color:red;">&#10007; Failed</td>';
@@ -318,10 +318,7 @@ function scan_video_thumbnails(){
318
 
319
  global $video_thumbnails;
320
 
321
- foreach ( $video_thumbnails->providers as $provider ) {
322
- $new_thumbnail = $provider->scan_for_thumbnail( stripslashes( $_POST['markup'] ) );
323
- if ( $new_thumbnail != null ) break;
324
- }
325
 
326
  if ( $new_thumbnail == null ) {
327
  echo '<p><span style="color:red;">&#10006;</span> No thumbnail found</p>';
262
  foreach ( $provider->test_cases as $test_case ) {
263
  echo '<tr>';
264
  echo '<td><strong>' . $provider->service_name . '</strong> - ' . $test_case['name'] . '</td>';
265
+ $result = $video_thumbnails->get_first_thumbnail_url( $test_case['markup'] );
266
  if ( is_wp_error( $result ) ) {
267
  $error_string = $result->get_error_message();
268
  echo '<td style="color:red;">&#10007; Failed</td>';
318
 
319
  global $video_thumbnails;
320
 
321
+ $new_thumbnail = $video_thumbnails->get_first_thumbnail_url( stripslashes( $_POST['markup'] ) );
 
 
 
322
 
323
  if ( $new_thumbnail == null ) {
324
  echo '<p><span style="color:red;">&#10006;</span> No thumbnail found</p>';
php/providers/class-video-thumbnails-providers.php CHANGED
@@ -71,6 +71,16 @@ class Video_Thumbnails_Providers {
71
  }
72
  }
73
 
 
 
 
 
 
 
 
 
 
 
74
  // // Requires PHP 5.3.0+
75
  // public static function register_provider( $providers ) {
76
  // $providers[] = new static;
71
  }
72
  }
73
 
74
+ public function scan_for_videos( $markup ) {
75
+ $videos = array();
76
+ foreach ( $this->regexes as $regex ) {
77
+ if ( preg_match_all( $regex, $markup, $matches, PREG_OFFSET_CAPTURE ) ) {
78
+ $videos = array_merge( $videos, $matches[1] );
79
+ }
80
+ }
81
+ return $videos;
82
+ }
83
+
84
  // // Requires PHP 5.3.0+
85
  // public static function register_provider( $providers ) {
86
  // $providers[] = new static;
php/providers/class-wistia-thumbnails.php CHANGED
@@ -44,33 +44,25 @@ class Wistia_Thumbnails extends Video_Thumbnails_Providers {
44
  return $providers;
45
  }
46
 
47
- public function scan_for_thumbnail( $markup ) {
48
- // Find thumbnail URL if embedded in player
49
- $thumb_regex = '#https://wistia\.sslcs\.cdngc\.net/deliveries/[0-9a-zA-Z]+\.jpg#';
50
- if ( preg_match( $thumb_regex, urldecode( $markup ), $matches ) ) {
51
- return $matches[0];
52
- }
53
- $oembed_regex = '#https?://(.+)?(wistia\.com|wistia\.net|wi\.st)/(medias|embed)/(?:[\+~%\/\.\w\-]*)#';
54
- if ( preg_match( $oembed_regex, urldecode( $markup ), $matches ) ) {
55
- return $this->get_thumbnail_url( $matches[0] );
56
- }
57
- // Run regex for oEmbed API
58
- foreach ( $this->regexes as $regex ) {
59
- if ( preg_match( $regex, $markup, $matches ) ) {
60
- return $this->get_thumbnail_url( 'http://fast.wistia.net/embed/iframe/' . $matches[1] );
61
- }
62
- }
63
- }
64
-
65
  // Regex strings
66
  public $regexes = array(
67
  '#Wistia\.embed\("([0-9a-zA-Z]+)"#', // JavaScript API embedding
 
 
68
  );
69
 
70
  // Thumbnail URL
71
- public function get_thumbnail_url( $url ) {
72
- $url = urlencode( $url );
73
- $request = "http://fast.wistia.com/oembed?url=$url";
 
 
 
 
 
 
 
 
74
  $response = wp_remote_get( $request, array( 'sslverify' => false ) );
75
  if( is_wp_error( $response ) ) {
76
  $result = new WP_Error( 'wistia_info_retrieval', __( 'Error retrieving video information from the URL <a href="' . $request . '">' . $request . '</a> using <code>wp_remote_get()</code><br />If opening that URL in your web browser returns anything else than an error page, the problem may be related to your web server and might be something your host administrator can solve.<br />Details: ' . $response->get_error_message() ) );
@@ -78,7 +70,9 @@ class Wistia_Thumbnails extends Video_Thumbnails_Providers {
78
  $result = json_decode( $response['body'] );
79
  $result = $result->thumbnail_url;
80
  }
 
81
  return $result;
 
82
  }
83
 
84
  // Test cases
44
  return $providers;
45
  }
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  // Regex strings
48
  public $regexes = array(
49
  '#Wistia\.embed\("([0-9a-zA-Z]+)"#', // JavaScript API embedding
50
+ '#(https?://(?:.+)?(?:wistia\.com|wistia\.net|wi\.st)/(?:medias|embed)/(?:[\+~%\/\.\w\-]*))#', // Embed URL
51
+ '#(https://wistia\.sslcs\.cdngc\.net/deliveries/[0-9a-zA-Z]+\.jpg)#' // Thumbnail image
52
  );
53
 
54
  // Thumbnail URL
55
+ public function get_thumbnail_url( $id ) {
56
+
57
+ // ID is an image URL, return it
58
+ if ( substr( $id, -4 ) == '.jpg' ) return $id;
59
+
60
+ // ID is actually an ID, convert it to a URL
61
+ if ( substr( $id, 0, 4 ) != 'http' ) $id = 'http://fast.wistia.net/embed/iframe/' . $id;
62
+
63
+ // ID should now be an embed URL, use oEmbed to find thumbnail URL
64
+ $id = urlencode( $id );
65
+ $request = "http://fast.wistia.com/oembed?url=$id";
66
  $response = wp_remote_get( $request, array( 'sslverify' => false ) );
67
  if( is_wp_error( $response ) ) {
68
  $result = new WP_Error( 'wistia_info_retrieval', __( 'Error retrieving video information from the URL <a href="' . $request . '">' . $request . '</a> using <code>wp_remote_get()</code><br />If opening that URL in your web browser returns anything else than an error page, the problem may be related to your web server and might be something your host administrator can solve.<br />Details: ' . $response->get_error_message() ) );
70
  $result = json_decode( $response['body'] );
71
  $result = $result->thumbnail_url;
72
  }
73
+
74
  return $result;
75
+
76
  }
77
 
78
  // Test cases
php/providers/class-youtube-thumbnails.php CHANGED
@@ -35,12 +35,10 @@ class YouTube_Thumbnails extends Video_Thumbnails_Providers {
35
 
36
  // Regex strings
37
  public $regexes = array(
38
- '#<object[^>]+>.+?(?:https?:)?//www\.youtube(?:\-nocookie)?\.com/[ve]/([A-Za-z0-9\-_]+).+?</object>#s', // Old standard YouTube embed
39
- '#(?:https?:)?//www\.youtube(?:\-nocookie)?\.com/[ve]/([A-Za-z0-9\-_]+)#', // More comprehensive search for old YouTube embed (probably can be removed)
40
- '#(?:https?:)?//www\.youtube(?:\-nocookie)?\.com/embed/([A-Za-z0-9\-_]+)#', // YouTube iframe, the new standard since at least 2011
41
- '#(?:https?(?:a|vh?)?://)?(?:www\.)?youtube(?:\-nocookie)?\.com/watch\?.*v=([A-Za-z0-9\-_]+)#', // Any YouTube URL. After http(s) support a or v for Youtube Lyte and v or vh for Smart Youtube plugin
42
- '#(?:https?(?:a|vh?)?://)?youtu\.be/([A-Za-z0-9\-_]+)#', // Any shortened youtu.be URL. After http(s) a or v for Youtube Lyte and v or vh for Smart Youtube plugin
43
- '#<div class="lyte" id="([A-Za-z0-9\-_]+)"#' // YouTube Lyte
44
  );
45
 
46
  // Thumbnail URL
35
 
36
  // Regex strings
37
  public $regexes = array(
38
+ '#(?:https?:)?//www\.youtube(?:\-nocookie)?\.com/(?:v|e|embed)/([A-Za-z0-9\-_]+)#', // Comprehensive search for both iFrame and old school embeds
39
+ '#(?:https?(?:a|vh?)?://)?(?:www\.)?youtube(?:\-nocookie)?\.com/watch\?.*v=([A-Za-z0-9\-_]+)#', // Any YouTube URL. After http(s) support a or v for Youtube Lyte and v or vh for Smart Youtube plugin
40
+ '#(?:https?(?:a|vh?)?://)?youtu\.be/([A-Za-z0-9\-_]+)#', // Any shortened youtu.be URL. After http(s) a or v for Youtube Lyte and v or vh for Smart Youtube plugin
41
+ '#<div class="lyte" id="([A-Za-z0-9\-_]+)"#' // YouTube Lyte
 
 
42
  );
43
 
44
  // Thumbnail URL
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: sutherlandboswell
3
  Donate link: http://wie.ly/u/donate
4
  Tags: Video, Thumbnails, YouTube, Vimeo, Blip, Justin.tv, Dailymotion, Metacafe, Image, Featured Image, Post Thumbnail
5
  Requires at least: 3.1
6
- Tested up to: 3.6
7
- Stable tag: 2.0.10
8
 
9
  Video Thumbnails simplifies the process of automatically displaying video thumbnails in your WordPress template.
10
 
@@ -97,6 +97,10 @@ The Vimeo API has a rate limit, so in rare cases you may exceed this limit. Try
97
 
98
  == Changelog ==
99
 
 
 
 
 
100
  = 2.0.10 =
101
  * Reduced overhead on settings pages
102
 
@@ -295,6 +299,9 @@ The Vimeo API has a rate limit, so in rare cases you may exceed this limit. Try
295
 
296
  == Upgrade Notice ==
297
 
 
 
 
298
  = 2.0 =
299
  Despite being a major upgrade, your settings should remain intact. Please report any problems so they can be fixed quickly!
300
 
3
  Donate link: http://wie.ly/u/donate
4
  Tags: Video, Thumbnails, YouTube, Vimeo, Blip, Justin.tv, Dailymotion, Metacafe, Image, Featured Image, Post Thumbnail
5
  Requires at least: 3.1
6
+ Tested up to: 3.7
7
+ Stable tag: 2.1
8
 
9
  Video Thumbnails simplifies the process of automatically displaying video thumbnails in your WordPress template.
10
 
97
 
98
  == Changelog ==
99
 
100
+ = 2.1 =
101
+ * Changes under the hood to ensure the first video is found
102
+ * Improved YouTube regex
103
+
104
  = 2.0.10 =
105
  * Reduced overhead on settings pages
106
 
299
 
300
  == Upgrade Notice ==
301
 
302
+ = 2.1 =
303
+ Changes to the scanning process may affect any custom code you've developed for Video Thumbnails
304
+
305
  = 2.0 =
306
  Despite being a major upgrade, your settings should remain intact. Please report any problems so they can be fixed quickly!
307
 
video-thumbnails.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://refactored.co/plugins/video-thumbnails
5
  Description: Automatically retrieve video thumbnails for your posts and display them in your theme. Currently supports YouTube, Vimeo, Facebook, Blip.tv, Justin.tv, Dailymotion, Metacafe, Wistia, Youku, Funny or Die, and MPORA.
6
  Author: Sutherland Boswell
7
  Author URI: http://sutherlandboswell.com
8
- Version: 2.0.10
9
  License: GPL2
10
  */
11
  /* Copyright 2013 Sutherland Boswell (email : sutherland.boswell@gmail.com)
@@ -28,7 +28,7 @@ License: GPL2
28
 
29
  define( 'VIDEO_THUMBNAILS_PATH', dirname(__FILE__) );
30
  define( 'VIDEO_THUMBNAILS_FIELD', '_video_thumbnail' );
31
- define( 'VIDEO_THUMBNAILS_VERSION', '2.0.10' );
32
 
33
  // Providers
34
  require_once( VIDEO_THUMBNAILS_PATH . '/php/providers/class-video-thumbnails-providers.php' );
@@ -107,6 +107,62 @@ class Video_Thumbnails {
107
  }
108
  }
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  // The main event
111
  function get_video_thumbnail( $post_id = null ) {
112
 
@@ -137,13 +193,7 @@ class Video_Thumbnails {
137
  // Filter for extensions to modify what markup is scanned
138
  $markup = apply_filters( 'video_thumbnail_markup', $markup, $post_id );
139
 
140
- // Filter to modify providers immediately before scanning
141
- $providers = apply_filters( 'video_thumbnail_providers_pre_scan', $this->providers );
142
-
143
- foreach ( $providers as $key => $provider ) {
144
- $new_thumbnail = $provider->scan_for_thumbnail( $markup );
145
- if ( $new_thumbnail != null ) break;
146
- }
147
  }
148
 
149
  // Return the new thumbnail variable and update meta if one is found
5
  Description: Automatically retrieve video thumbnails for your posts and display them in your theme. Currently supports YouTube, Vimeo, Facebook, Blip.tv, Justin.tv, Dailymotion, Metacafe, Wistia, Youku, Funny or Die, and MPORA.
6
  Author: Sutherland Boswell
7
  Author URI: http://sutherlandboswell.com
8
+ Version: 2.1
9
  License: GPL2
10
  */
11
  /* Copyright 2013 Sutherland Boswell (email : sutherland.boswell@gmail.com)
28
 
29
  define( 'VIDEO_THUMBNAILS_PATH', dirname(__FILE__) );
30
  define( 'VIDEO_THUMBNAILS_FIELD', '_video_thumbnail' );
31
+ define( 'VIDEO_THUMBNAILS_VERSION', '2.1' );
32
 
33
  // Providers
34
  require_once( VIDEO_THUMBNAILS_PATH . '/php/providers/class-video-thumbnails-providers.php' );
107
  }
108
  }
109
 
110
+ /**
111
+ * A usort() callback that sorts videos by offset
112
+ */
113
+ function compare_by_offset( $a, $b ) {
114
+ return $a['offset'] - $b['offset'];
115
+ }
116
+
117
+ /**
118
+ * Find all the videos in a post
119
+ * @param string $markup Markup to scan for videos
120
+ * @return array An array of video information
121
+ */
122
+ function find_videos( $markup ) {
123
+
124
+ $videos = array();
125
+
126
+ // Filter to modify providers immediately before scanning
127
+ $providers = apply_filters( 'video_thumbnail_providers_pre_scan', $this->providers );
128
+
129
+ foreach ( $providers as $key => $provider ) {
130
+
131
+ $provider_videos = $provider->scan_for_videos( $markup );
132
+
133
+ if ( empty( $provider_videos ) ) continue;
134
+
135
+ foreach ( $provider_videos as $video ) {
136
+ $videos[] = array(
137
+ 'id' => $video[0],
138
+ 'provider' => $key,
139
+ 'offset' => $video[1]
140
+ );
141
+ }
142
+
143
+ }
144
+
145
+ usort( $videos, array( &$this, 'compare_by_offset' ) );
146
+
147
+ return $videos;
148
+
149
+ }
150
+
151
+ /**
152
+ * Finds the first video in markup and retrieves a thumbnail
153
+ * @param string $markup Post markup to scan
154
+ * @return mixed Null if no thumbnail or a string with a remote URL
155
+ */
156
+ function get_first_thumbnail_url( $markup ) {
157
+ $thumbnail = null;
158
+ $videos = $this->find_videos( $markup );
159
+ foreach ( $videos as $video ) {
160
+ $thumbnail = $this->providers[$video['provider']]->get_thumbnail_url( $video['id'] );
161
+ if ( $thumbnail != null ) break;
162
+ }
163
+ return $thumbnail;
164
+ }
165
+
166
  // The main event
167
  function get_video_thumbnail( $post_id = null ) {
168
 
193
  // Filter for extensions to modify what markup is scanned
194
  $markup = apply_filters( 'video_thumbnail_markup', $markup, $post_id );
195
 
196
+ $new_thumbnail = $this->get_first_thumbnail_url( $markup );
 
 
 
 
 
 
197
  }
198
 
199
  // Return the new thumbnail variable and update meta if one is found