Video Thumbnails - Version 1.8

Version Description

  • Added support for custom fields via a new setting
  • Added support for YouTube's privacy-enhanced domain (youtube-nocookie.com)
  • Fixed image duplication bug
  • Now more consistent with WordPress Coding Standards (thanks Daedalon)
Download this release

Release Info

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

Code changes from version 1.7.7 to 1.8

Files changed (2) hide show
  1. readme.txt +17 -15
  2. video-thumbnails.php +289 -277
readme.txt CHANGED
@@ -1,16 +1,16 @@
1
  === Video Thumbnails ===
2
  Contributors: sutherlandboswell
3
- Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=sutherland%2eboswell%40gmail%2ecom&lc=US&item_name=Sutherland%20Boswell&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted
4
  Tags: Video, Thumbnails, YouTube, Vimeo, Blip.tv, Justin.tv, Dailymotion, Metacafe, Image, Featured Image, Post Thumbnail
5
  Requires at least: 3.0
6
- Tested up to: 3.3
7
- Stable tag: 1.7.7
8
 
9
  Video Thumbnails simplifies the process of automatically displaying video thumbnails in your WordPress template.
10
 
11
  == Description ==
12
 
13
- Video Thumbnails makes it easy to automatically display video thumbnails in your template. When you publish a post, this plugin will find the first video embedded and locate the thumbnail for you. Thumbnails can be saved to your media library and set as a featured image automatically. There's even support for custom post types!
14
 
15
  Video Thumbnails currently supports these video services:
16
 
@@ -44,9 +44,9 @@ Some functions are available to advanced users who want to customize their theme
44
 
45
  The most likely problem is that your theme doesn't support post thumbnails. If thumbnails are supported, you should see a box titled "Featured Image" on the edit post page. If thumbnails aren't supported, your theme will have to be modified to support Featured Images or to support one of our custom functions.
46
 
47
- = I'm using a custom field to store the video and it isn't working, is there a solution? =
48
 
49
- Yes, [this thread](http://wordpress.org/support/topic/plugin-video-thumbnails-cant-find-youtube-thumbnails) has a solution for searching a custom field instead of the post's main content.
50
 
51
  = Can I use the functions outside of a loop? =
52
 
@@ -62,13 +62,13 @@ The settings page includes a checklist of all your post types so you can pick an
62
 
63
  = I am editing my theme and only want to display a thumbnail if one is found. How do I do this? =
64
 
65
- `<?php if( ( $video_thumbnail = get_video_thumbnail() ) != null ) { echo "<img src='" . $video_thumbnail . "' />"; } ?>` will only display a thumbnail when one exists.
66
 
67
  = I edited my theme and now I'm getting huge thumbnails, how can I resize them? =
68
 
69
- Adding a width attribute to the image element should scale the image in most modern browsers. Ex: `<?php if( ( $video_thumbnail = get_video_thumbnail() ) != null ) { echo "<img src='" . $video_thumbnail . "' width='300' />"; } ?>`
70
 
71
- You can also assign a class to the element and style it with CSS, or even use a library like [TimThumb](http://code.google.com/p/timthumb/) to resize your images.
72
 
73
  = I edited my theme and now I'm seeing the thumbnail and the video, how do I only display the thumbnail? =
74
 
@@ -88,6 +88,12 @@ The Vimeo API has a rate limit, so in rare cases you may exceed this limit. Try
88
 
89
  == Changelog ==
90
 
 
 
 
 
 
 
91
  = 1.7.7 =
92
  * Better cURL error handling
93
  * Better regex matching
@@ -223,12 +229,8 @@ This version adds the thumbnail URL to the post's meta data, meaning any outside
223
 
224
  == Known Issues ==
225
 
226
- * Because the plugin politely removes its settings when being deactivated, settings may revert back to the defaults when upgrading the plugin automatically. I believe this is an issue that will be fixed in WordPress 3.1.
227
 
228
  == Roadmap ==
229
 
230
- This plugin is still very young, and has a future planned as the ultimate plugin for video thumbnails. Here's some of the planned additions:
231
-
232
- * Better Blip.tv support
233
- * More services
234
- * Option to display video thumbnails on the admin post list page
1
  === Video Thumbnails ===
2
  Contributors: sutherlandboswell
3
+ Donate link: http://wie.ly/u/donate
4
  Tags: Video, Thumbnails, YouTube, Vimeo, Blip.tv, Justin.tv, Dailymotion, Metacafe, Image, Featured Image, Post Thumbnail
5
  Requires at least: 3.0
6
+ Tested up to: 3.3.1
7
+ Stable tag: 1.8
8
 
9
  Video Thumbnails simplifies the process of automatically displaying video thumbnails in your WordPress template.
10
 
11
  == Description ==
12
 
13
+ Video Thumbnails makes it easy to automatically display video thumbnails in your template. When you publish a post, this plugin will find the first video embedded and locate the thumbnail for you. Thumbnails can be saved to your media library and set as a featured image automatically. There's even support for custom post types and custom fields!
14
 
15
  Video Thumbnails currently supports these video services:
16
 
44
 
45
  The most likely problem is that your theme doesn't support post thumbnails. If thumbnails are supported, you should see a box titled "Featured Image" on the edit post page. If thumbnails aren't supported, your theme will have to be modified to support Featured Images or to support one of our custom functions.
46
 
47
+ = How can I use Video Thumbnails if I use a custom field to store the video? =
48
 
49
+ On the Video Thumbnails settings page just enter the name of the custom field and the plugin will scan it.
50
 
51
  = Can I use the functions outside of a loop? =
52
 
62
 
63
  = I am editing my theme and only want to display a thumbnail if one is found. How do I do this? =
64
 
65
+ `<?php if( ( $video_thumbnail = get_video_thumbnail() ) != null ) { echo "<img src='" . $video_thumbnail . "' />"; } ?>` will only display a thumbnail when one exists, but I recommend using the Featured Image setting and [the_post_thumbnail](http://codex.wordpress.org/Function_Reference/the_post_thumbnail) template tag.
66
 
67
  = I edited my theme and now I'm getting huge thumbnails, how can I resize them? =
68
 
69
+ The best solution is to use the Featured Image setting and [the_post_thumbnail](http://codex.wordpress.org/Function_Reference/the_post_thumbnail) template tag.
70
 
71
+ As an alternative you could assign a class to the element and style it with CSS, or even use a library like [TimThumb](http://code.google.com/p/timthumb/) to resize your images.
72
 
73
  = I edited my theme and now I'm seeing the thumbnail and the video, how do I only display the thumbnail? =
74
 
88
 
89
  == Changelog ==
90
 
91
+ = 1.8 =
92
+ * Added support for custom fields via a new setting
93
+ * Added support for YouTube's privacy-enhanced domain (youtube-nocookie.com)
94
+ * Fixed image duplication bug
95
+ * Now more consistent with [WordPress Coding Standards](http://codex.wordpress.org/WordPress_Coding_Standards) (thanks [Daedalon](http://wordpress.org/support/profile/daedalon))
96
+
97
  = 1.7.7 =
98
  * Better cURL error handling
99
  * Better regex matching
229
 
230
  == Known Issues ==
231
 
232
+ * In some cases you may have to manually search for thumbnails on the post editor
233
 
234
  == Roadmap ==
235
 
236
+ Version 2.0 is in the works and will mainly include code reorganization and optimizations, but suggestions for new features are always welcome.
 
 
 
 
video-thumbnails.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://sutherlandboswell.com/projects/wordpress-video-thumbnails/
5
  Description: Automatically retrieve video thumbnails for your posts and display them in your theme. Currently supports YouTube, Vimeo, Blip.tv, Justin.tv, Dailymotion and Metacafe.
6
  Author: Sutherland Boswell
7
  Author URI: http://sutherlandboswell.com
8
- Version: 1.7.7
9
  License: GPL2
10
  */
11
  /* Copyright 2010 Sutherland Boswell (email : sutherland.boswell@gmail.com)
@@ -25,78 +25,78 @@ License: GPL2
25
  */
26
 
27
  // Get Vimeo Thumbnail
28
- function getVimeoInfo($id, $info = 'thumbnail_large') {
29
- if (!function_exists('curl_init')) {
30
  return null;
31
  } else {
32
  $ch = curl_init();
33
  $videoinfo_url = "http://vimeo.com/api/v2/video/$id.php";
34
- curl_setopt($ch, CURLOPT_URL, $videoinfo_url);
35
- curl_setopt($ch, CURLOPT_HEADER, 0);
36
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
37
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
38
- curl_setopt($ch, CURLOPT_FAILONERROR, true); // Return an error for curl_error() processing if HTTP response code >= 400
39
- $output = unserialize(curl_exec($ch));
40
  $output = $output[0][$info];
41
- if (curl_error($ch) != null) {
42
- $output = new WP_Error('vimeo_info_retrieval', __("Error retrieving video information from the URL <a href=\"" . $videoinfo_url . "\">" . $videoinfo_url . "</a>: <code>" . curl_error($ch) . "</code>. 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."));
43
  }
44
- curl_close($ch);
45
  return $output;
46
  }
47
  };
48
 
49
  // Blip.tv Functions
50
- function getBliptvInfo($id) {
51
  $videoinfo_url = "http://blip.tv/players/episode/$id?skin=rss";
52
- $xml = simplexml_load_file($videoinfo_url);
53
- if ($xml == false) {
54
- return new WP_Error('dailymotion_info_retrieval', __("Error retrieving video information from the URL <a href=\"" . $videoinfo_url . "\">" . $videoinfo_url . "</a>. 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."));
55
  } else {
56
- $result = $xml->xpath("/rss/channel/item/media:thumbnail/@url");
57
  $thumbnail = (string) $result[0]['url'];
58
  return $thumbnail;
59
  }
60
  }
61
 
62
  // Justin.tv Functions
63
- function getJustintvInfo($id) {
64
- $xml = simplexml_load_file("http://api.justin.tv/api/clip/show/$id.xml");
65
  return (string) $xml->clip->image_url_large;
66
  }
67
 
68
  // Get DailyMotion Thumbnail
69
- function getDailyMotionThumbnail($id) {
70
- if (!function_exists('curl_init')) {
71
  return null;
72
  } else {
73
  $ch = curl_init();
74
  $videoinfo_url = "https://api.dailymotion.com/video/$id?fields=thumbnail_url";
75
- curl_setopt($ch, CURLOPT_URL, $videoinfo_url);
76
- curl_setopt($ch, CURLOPT_HEADER, 0);
77
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
78
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
79
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
80
- curl_setopt($ch, CURLOPT_FAILONERROR, true); // Return an error for curl_error() processing if HTTP response code >= 400
81
- $output = curl_exec($ch);
82
- $output = json_decode($output);
83
  $output = $output->thumbnail_url;
84
- if (curl_error($ch) != null) {
85
- $output = new WP_Error('dailymotion_info_retrieval', __("Error retrieving video information from the URL <a href=\"" . $videoinfo_url . "\">" . $videoinfo_url . "</a>: <code>" . curl_error($ch) . "</code>. 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."));
86
- }
87
- curl_close($ch); // Moved here to allow curl_error() operation above. Was previously below curl_exec() call.
88
  return $output;
89
  }
90
  };
91
 
92
  // Metacafe
93
- function getMetacafeThumbnail($id) {
94
  $videoinfo_url = "http://www.metacafe.com/api/item/$id/";
95
- $xml = simplexml_load_file($videoinfo_url);
96
- if ($xml == false) {
97
- return new WP_Error('dailymotion_info_retrieval', __("Error retrieving video information from the URL <a href=\"" . $videoinfo_url . "\">" . $videoinfo_url . "</a>. 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."));
98
  } else {
99
- $result = $xml->xpath("/rss/channel/item/media:thumbnail/@url");
100
  $thumbnail = (string) $result[0]['url'];
101
  return $thumbnail;
102
  }
@@ -105,249 +105,253 @@ function getMetacafeThumbnail($id) {
105
  //
106
  // The Main Event
107
  //
108
- function get_video_thumbnail($post_id=null) {
109
-
110
  // Get the post ID if none is provided
111
- if($post_id==null OR $post_id=='') $post_id = get_the_ID();
112
-
113
- // Check to see if thumbnail has already been found and still exists as a file
114
- if( ( ($thumbnail_meta = get_post_meta($post_id, '_video_thumbnail', true)) != '' ) && wp_remote_retrieve_response_code(wp_remote_head($thumbnail_meta)) === '200' ) {
115
  return $thumbnail_meta;
116
  }
117
  // If the thumbnail isn't stored in custom meta, fetch a thumbnail
118
  else {
119
 
120
- // Gets the post's content
121
- $post_array = get_post($post_id);
122
- $markup = $post_array->post_content;
123
- $markup = apply_filters('the_content',$markup);
 
 
 
 
124
  $new_thumbnail = null;
125
-
126
  // Simple Video Embedder Compatibility
127
- if(function_exists('p75HasVideo')) {
128
- if ( p75HasVideo($post_id) ) {
129
- $markup = p75GetVideo($post_id);
130
  }
131
  }
132
-
133
  // Checks for the old standard YouTube embed
134
- preg_match('#<object[^>]+>.+?https?://www.youtube.com/[ve]/([A-Za-z0-9\-_]+).+?</object>#s', $markup, $matches);
135
-
136
  // More comprehensive search for YouTube embed, redundant but necessary until more testing is completed
137
- if(!isset($matches[1])) {
138
- preg_match('#https?://www.youtube.com/[ve]/([A-Za-z0-9\-_]+)#s', $markup, $matches);
139
  }
140
 
141
  // Checks for YouTube iframe, the new standard since at least 2011
142
- if(!isset($matches[1])) {
143
- preg_match('#https?://www.youtube.com/embed/([A-Za-z0-9\-_]+)#s', $markup, $matches);
144
  }
145
-
146
  // Checks for any YouTube URL. After http(s) support a or v for Youtube Lyte and v or vh for Smart Youtube plugin
147
- if(!isset($matches[1])) {
148
- preg_match('#(?:https?(?:a|vh?)?://)?(?:www\.)?youtube.com/watch\?v=([A-Za-z0-9\-_]+)#s', $markup, $matches);
149
  }
150
-
151
  // Checks for any shortened youtu.be URL. After http(s) a or v for Youtube Lyte and v or vh for Smart Youtube plugin
152
- if(!isset($matches[1])) {
153
- preg_match('#(?:https?(?:a|vh?)?://)?youtu.be/([A-Za-z0-9\-_]+)#s', $markup, $matches);
154
  }
155
-
156
  // Checks for YouTube Lyte
157
- if(!isset($matches[1]) && function_exists('lyte_parse')) {
158
- preg_match('#<div class="lyte" id="([A-Za-z0-9\-_]+)"#s', $markup, $matches);
159
  }
160
-
161
  // If we've found a YouTube video ID, create the thumbnail URL
162
- if(isset($matches[1])) {
163
  $youtube_thumbnail = 'http://img.youtube.com/vi/' . $matches[1] . '/0.jpg';
164
-
165
  // Check to make sure it's an actual thumbnail
166
- if (!function_exists('curl_init')) {
167
  $new_thumbnail = $youtube_thumbnail;
168
  } else {
169
- $ch = curl_init($youtube_thumbnail);
170
- curl_setopt($ch, CURLOPT_NOBODY, true);
171
- curl_exec($ch);
172
- $retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
173
  // $retcode > 400 -> not found, $retcode = 200, found.
174
- curl_close($ch);
175
- if($retcode==200) {
176
  $new_thumbnail = $youtube_thumbnail;
177
  }
178
  }
179
  }
180
-
181
  // Vimeo
182
- if($new_thumbnail==null) {
183
-
184
  // Standard embed code
185
- preg_match('#<object[^>]+>.+?http://vimeo.com/moogaloop.swf\?clip_id=([A-Za-z0-9\-_]+)&.+?</object>#s', $markup, $matches);
186
-
187
  // Find Vimeo embedded with iframe code
188
- if(!isset($matches[1])) {
189
- preg_match('#http://player.vimeo.com/video/([0-9]+)#s', $markup, $matches);
190
  }
191
-
192
  // If we still haven't found anything, check for Vimeo embedded with JR_embed
193
- if(!isset($matches[1])) {
194
- preg_match('#\[vimeo id=([A-Za-z0-9\-_]+)]#s', $markup, $matches);
195
  }
196
-
197
  // If we still haven't found anything, check for Vimeo URL
198
- if(!isset($matches[1])) {
199
- preg_match('#(?:http://)?(?:www\.)?vimeo.com/([A-Za-z0-9\-_]+)#s', $markup, $matches);
200
  }
201
-
202
  // If we still haven't found anything, check for Vimeo shortcode
203
- if(!isset($matches[1])) {
204
- preg_match('#\[vimeo clip_id="([A-Za-z0-9\-_]+)"[^>]*]#s', $markup, $matches);
205
  }
206
- if(!isset($matches[1])) {
207
- preg_match('#\[vimeo video_id="([A-Za-z0-9\-_]+)"[^>]*]#s', $markup, $matches);
208
  }
209
-
210
  // Now if we've found a Vimeo ID, let's set the thumbnail URL
211
- if(isset($matches[1])) {
212
- $vimeo_thumbnail = getVimeoInfo($matches[1], $info = 'thumbnail_large');
213
- if (is_wp_error($vimeo_thumbnail)) {
214
  return $vimeo_thumbnail;
215
- } else if (isset($vimeo_thumbnail)) {
216
  $new_thumbnail = $vimeo_thumbnail;
217
  }
218
  }
219
  }
220
-
221
  // Blip.tv
222
- if($new_thumbnail==null) {
223
-
224
  // Blip.tv embed URL
225
- preg_match('#http://blip.tv/play/([A-Za-z0-9]+)#s', $markup, $matches);
226
 
227
  // Now if we've found a Blip.tv embed URL, let's set the thumbnail URL
228
- if(isset($matches[1])) {
229
- $blip_thumbnail = getBliptvInfo($matches[1]);
230
- if (is_wp_error($blip_thumbnail)) {
231
  return $blip_thumbnail;
232
- } else if (isset($blip_thumbnail)) {
233
- $new_thumbnail = $blip_thumbnail;
234
  }
235
  }
236
  }
237
-
238
  // Justin.tv
239
- if($new_thumbnail==null) {
240
-
241
  // Justin.tv archive ID
242
- preg_match('#archive_id=([0-9]+)#s', $markup, $matches);
243
 
244
  // Now if we've found a Justin.tv archive ID, let's set the thumbnail URL
245
- if(isset($matches[1])) {
246
- $justin_thumbnail = getJustintvInfo($matches[1]);
247
  $new_thumbnail = $justin_thumbnail;
248
  }
249
  }
250
-
251
  // Dailymotion
252
- if($new_thumbnail==null) {
253
-
254
  // Dailymotion flash
255
- preg_match('#<object[^>]+>.+?http://www.dailymotion.com/swf/video/([A-Za-z0-9]+).+?</object>#s', $markup, $matches);
256
-
257
  // Dailymotion url
258
- if(!isset($matches[1])) {
259
- preg_match('#(?:https?://)?(?:www\.)?dailymotion.com/video/([A-Za-z0-9]+)#s', $markup, $matches);
260
  }
261
-
262
  // Dailymotion iframe
263
- if(!isset($matches[1])) {
264
- preg_match('#https?://www.dailymotion.com/embed/video/([A-Za-z0-9]+)#s', $markup, $matches);
265
  }
266
 
267
  // Now if we've found a Dailymotion video ID, let's set the thumbnail URL
268
- if(isset($matches[1])) {
269
- $dailymotion_thumbnail = getDailyMotionThumbnail($matches[1]);
270
- if (is_wp_error($dailymotion_thumbnail)) {
271
  return $dailymotion_thumbnail;
272
- } else if (isset($dailymotion_thumbnail)) {
273
- $new_thumbnail = strtok($dailymotion_thumbnail, '?');
274
  }
275
  }
276
  }
277
-
278
  // Metacafe
279
- if($new_thumbnail==null) {
280
-
281
  // Find ID from Metacafe embed url
282
- preg_match('#http://www.metacafe.com/fplayer/([A-Za-z0-9\-_]+)/#s', $markup, $matches);
283
 
284
  // Now if we've found a Metacafe video ID, let's set the thumbnail URL
285
- if(isset($matches[1])) {
286
- $metacafe_thumbnail = getMetacafeThumbnail($matches[1]);
287
- if (is_wp_error($metacafe_thumbnail)) {
288
  return $metacafe_thumbnail;
289
- } else if (isset($metacafe_thumbnail)) {
290
- $new_thumbnail = strtok($metacafe_thumbnail, '?');
291
  }
292
  }
293
  }
294
-
295
  // Return the new thumbnail variable and update meta if one is found
296
- if($new_thumbnail!=null) {
297
-
298
  // Save as Attachment if enabled
299
- if(get_option('video_thumbnails_save_media')==1) {
300
  $error = '';
301
- $ch = curl_init();
302
- $timeout = 0;
303
- curl_setopt ($ch, CURLOPT_URL, $new_thumbnail);
304
- curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
305
- curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
306
- curl_setopt($ch, CURLOPT_FAILONERROR, true); // Return an error for curl_error() processing if HTTP response code >= 400
307
- $image_contents = curl_exec($ch);
308
- if (curl_error($ch) != null || $image_contents == null) {
309
  $curl_error = '';
310
- if (curl_error($ch) != null) {
311
- $curl_error = ": <code>" . curl_error($ch) . "</code>";
312
  }
313
- $error = new WP_Error('thumbnail_retrieval', __("Error retrieving a thumbnail from the URL <a href=\"" . $new_thumbnail . "\">" . $new_thumbnail . "</a>" . $curl_error . ". If opening that URL in your web browser shows an image, the problem may be related to your web server and might be something your server administrator can solve."));
314
  }
315
- curl_close($ch);
316
 
317
- if ($error != null) {
318
  return $error;
319
  } else {
320
 
321
- $upload = wp_upload_bits(basename($new_thumbnail), null, $image_contents);
322
 
323
  $new_thumbnail = $upload['url'];
324
 
325
  $filename = $upload['file'];
326
 
327
- $wp_filetype = wp_check_filetype(basename($filename), null );
328
  $attachment = array(
329
- 'post_mime_type' => $wp_filetype['type'],
330
- 'post_title' => get_the_title($post_id),
331
- 'post_content' => '',
332
- 'post_status' => 'inherit'
333
  );
334
  $attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
335
  // you must first include the image.php file
336
  // for the function wp_generate_attachment_metadata() to work
337
- require_once(ABSPATH . "wp-admin" . '/includes/image.php');
338
  $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
339
  wp_update_attachment_metadata( $attach_id, $attach_data );
340
 
341
  }
342
 
343
  }
344
-
345
  // Add hidden custom field with thumbnail URL
346
- if(!update_post_meta($post_id, '_video_thumbnail', $new_thumbnail)) add_post_meta($post_id, '_video_thumbnail', $new_thumbnail, true);
347
-
348
  // Set attachment as featured image if enabled
349
- if(get_option('video_thumbnails_set_featured')==1 && get_option('video_thumbnails_save_media')==1 && get_post_meta($post_id, '_thumbnail_id', true) == '' ) {
350
- if(!update_post_meta($post_id, '_thumbnail_id', $attach_id)) add_post_meta($post_id, '_thumbnail_id', $attach_id, true);
351
  }
352
  }
353
  return $new_thumbnail;
@@ -356,43 +360,42 @@ function get_video_thumbnail($post_id=null) {
356
  };
357
 
358
  // Echo thumbnail
359
- function video_thumbnail($post_id=null) {
360
- if( ( $video_thumbnail = get_video_thumbnail($post_id) ) == null ) { echo plugins_url() . "/video-thumbnails/default.jpg"; }
361
  else { echo $video_thumbnail; }
362
  };
363
 
364
  // Create Meta Fields on Edit Page
365
 
366
- add_action("admin_init", "video_thumbnail_admin_init");
367
 
368
- function video_thumbnail_admin_init(){
369
- $video_thumbnails_post_types = get_option('video_thumbnails_post_types');
370
- if(is_array($video_thumbnails_post_types)) {
371
- foreach ($video_thumbnails_post_types as $type) {
372
- add_meta_box("video_thumbnail", "Video Thumbnail", "video_thumbnail_admin", $type, "side", "low");
373
  }
374
  }
375
  }
376
-
377
- function video_thumbnail_admin(){
378
  global $post;
379
- $custom = get_post_custom($post->ID);
380
  $video_thumbnail = $custom["_video_thumbnail"][0];
381
-
382
- if(isset($video_thumbnail) && $video_thumbnail!='') {
383
- echo '<p id="video-thumbnails-preview"><img src="' . $video_thumbnail . '" width="100%" /></p>';
384
- }
385
-
386
  if ( get_post_status() == 'publish' || get_post_status() == 'private' ) {
387
- if(isset($video_thumbnail) && $video_thumbnail!='') {
388
- echo '<p><a href="#" id="video-thumbnails-reset" onclick="video_thumbnails_reset(\'' . $post->ID . '\');return false;">Reset Video Thumbnail</a></p>';
389
  } else {
390
  echo '<p id="video-thumbnails-preview">We didn\'t find a video thumbnail for this post.</p>';
391
- echo '<p><a href="#" id="video-thumbnails-reset" onclick="video_thumbnails_reset(\'' . $post->ID . '\');return false;">Search Again</a></p>';
392
  }
393
  } else {
394
- if(isset($video_thumbnail) && $video_thumbnail!='') {
395
- echo '<p><a href="#" id="video-thumbnails-reset" onclick="video_thumbnails_reset(\'' . $post->ID . '\');return false;">Reset Video Thumbnail</a></p>';
396
  } else {
397
  echo '<p>A video thumbnail will be found for this post when it is published.</p>';
398
  }
@@ -401,48 +404,48 @@ function video_thumbnail_admin(){
401
 
402
  // AJAX Searching
403
 
404
- if ( in_array( basename($_SERVER['PHP_SELF']), apply_filters( 'video_thumbnails_editor_pages', array('post-new.php', 'page-new.php', 'post.php', 'page.php') ) ) ) {
405
- add_action('admin_head', 'video_thumbnails_ajax');
406
  }
407
 
408
  function video_thumbnails_ajax() {
409
  ?>
410
 
411
  <!-- Video Thumbnails Researching Ajax -->
412
- <script type="text/javascript" >
413
  function video_thumbnails_reset(id) {
414
 
415
  var data = {
416
  action: 'video_thumbnails',
417
  post_id: id
418
  };
419
-
420
- document.getElementById('video-thumbnails-preview').innerHTML = 'Working... <img src="<?php echo home_url('wp-admin/images/loading.gif'); ?>"/>';
421
 
422
  // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
423
- jQuery.post(ajaxurl, data, function(response) {
424
- document.getElementById('video-thumbnails-preview').innerHTML = response;
425
  });
426
  };
427
  </script>
428
  <?php
429
  }
430
 
431
- add_action('wp_ajax_video_thumbnails', 'video_thumbnails_callback');
432
 
433
  function video_thumbnails_callback() {
434
  global $wpdb; // this is how you get access to the database
435
 
436
  $post_id = $_POST['post_id'];
437
 
438
- delete_post_meta($post_id, '_video_thumbnail');
439
 
440
- $video_thumbnail = get_video_thumbnail($post_id);
441
 
442
- if ( is_wp_error($video_thumbnail) ) {
443
  echo $video_thumbnail->get_error_message();
444
- } else if ( $video_thumbnail != null ){
445
- echo '<img src="' . $video_thumbnail . '" width="100%" />';
446
  } else {
447
  echo 'We didn\'t find a video thumbnail for this post. (be sure you have saved changes first)';
448
  }
@@ -452,20 +455,20 @@ function video_thumbnails_callback() {
452
 
453
  // Find video thumbnail when saving a post, but not on autosave
454
 
455
- add_action('new_to_publish', 'save_video_thumbnail', 10, 1);
456
- add_action('draft_to_publish', 'save_video_thumbnail', 10, 1);
457
- add_action('pending_to_publish', 'save_video_thumbnail', 10, 1);
458
- add_action('future_to_publish', 'save_video_thumbnail', 10, 1);
459
 
460
- function save_video_thumbnail( $post ){
461
  $post_type = get_post_type( $post->ID );
462
- $video_thumbnails_post_types = get_option('video_thumbnails_post_types');
463
- if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
464
  return null;
465
  } else {
466
  // Check that Video Thumbnails are enabled for current post type
467
- if (in_array($post_type, (array) $video_thumbnails_post_types) || $post_type == $video_thumbnails_post_types) {
468
- get_video_thumbnail($post->ID);
469
  } else {
470
  return null;
471
  }
@@ -474,43 +477,45 @@ function save_video_thumbnail( $post ){
474
 
475
  // Set Default Options
476
 
477
- register_activation_hook(__FILE__,'video_thumbnails_activate');
478
- register_deactivation_hook(__FILE__,'video_thumbnails_deactivate');
479
 
480
  function video_thumbnails_activate() {
481
- add_option('video_thumbnails_save_media','1');
482
- add_option('video_thumbnails_set_featured','1');
483
- add_option('video_thumbnails_post_types',array('post'));
 
484
  }
485
 
486
  function video_thumbnails_deactivate() {
487
- delete_option('video_thumbnails_save_media');
488
- delete_option('video_thumbnails_set_featured');
489
- delete_option('video_thumbnails_post_types');
 
490
  }
491
 
492
  // Check for cURL
493
 
494
- register_activation_hook(__FILE__,'video_thumbnails_curl_check');
495
 
496
- function video_thumbnails_curl_check(){
497
- if (!function_exists('curl_init')) {
498
- deactivate_plugins(basename(__FILE__)); // Deactivate ourself
499
- wp_die("Sorry, but this plugin requires cURL to be activated on your server.<BR><BR>Google should be able to help you.");
500
  }
501
  }
502
 
503
  // AJAX for Past Posts
504
 
505
  if ( isset ( $_GET['page'] ) && ( $_GET['page'] == 'video-thumbnail-options' ) ) {
506
- add_action('admin_head', 'video_thumbnails_past_ajax');
507
  }
508
 
509
  function video_thumbnails_past_ajax() {
510
  ?>
511
 
512
  <!-- Video Thumbnails Past Post Ajax -->
513
- <script type="text/javascript" >
514
  function video_thumbnails_past(id) {
515
 
516
  var data = {
@@ -519,8 +524,7 @@ function video_thumbnails_past(id) {
519
  };
520
 
521
  // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
522
- jQuery.post(ajaxurl, data, function(response) {
523
-
524
 
525
  document.getElementById(id+'_result').innerHTML = response;
526
 
@@ -529,14 +533,17 @@ function video_thumbnails_past(id) {
529
  };
530
 
531
  <?php
532
- $video_thumbnails_post_types = get_option('video_thumbnails_post_types');
533
- $posts = get_posts(array('showposts'=>-1,'post_type'=>$video_thumbnails_post_types));
534
-
535
- if ($posts) {
536
- foreach($posts as $post) {
 
 
 
537
  $post_ids[] = $post->ID;
538
  }
539
- $ids = implode(',',$post_ids);
540
  }
541
  ?>
542
 
@@ -568,20 +575,20 @@ function scan_video_thumbnails(){
568
  <?php
569
  }
570
 
571
- add_action('wp_ajax_video_thumbnails_past', 'video_thumbnails_past_callback');
572
 
573
  function video_thumbnails_past_callback() {
574
  global $wpdb; // this is how you get access to the database
575
 
576
  $post_id = $_POST['post_id'];
577
 
578
- echo get_the_title($post_id) . ' - ';
579
 
580
- $video_thumbnail = get_video_thumbnail($post_id);
581
 
582
- if ( is_wp_error($video_thumbnail) ) {
583
  echo $video_thumbnail->get_error_message();
584
- } else if ( $video_thumbnail != null ){
585
  echo '<span style="color:green">&#10004;</span> Success!';
586
  } else {
587
  echo '<span style="color:red">&#10006;</span> Couldn\'t find a video thumbnail for this post.';
@@ -592,82 +599,87 @@ function video_thumbnails_past_callback() {
592
 
593
  // Administration
594
 
595
- add_action('admin_menu', 'video_thumbnails_menu');
596
 
597
  function video_thumbnails_menu() {
598
-
599
- add_options_page('Video Thumbnail Options', 'Video Thumbnails', 'manage_options', 'video-thumbnail-options', 'video_thumbnail_options');
600
-
601
  }
602
 
603
- function video_thumbnails_checkbox_option($option_name, $option_description) { ?>
604
- <fieldset><legend class="screen-reader-text"><span><?php echo $option_description; ?></span></legend>
605
- <label for="<?php echo $option_name; ?>"><input name="<?php echo $option_name; ?>" type="checkbox" id="<?php echo $option_name; ?>" value="1" <?php if(get_option($option_name)==1) echo "checked='checked'"; ?>/> <?php echo $option_description; ?></label>
606
  </fieldset> <?php
607
  }
608
 
609
  function video_thumbnail_options() {
610
 
611
- if (!current_user_can('manage_options')) {
612
- wp_die( __('You do not have sufficient permissions to access this page.') );
613
  }
614
 
615
  ?>
616
 
617
  <div class="wrap">
618
-
619
  <div id="icon-options-general" class="icon32"></div><h2>Video Thumbnails Options</h2>
620
-
621
  <p>Say thanks by donating, any amount is appreciated!<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_s-xclick"><input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"><img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"></form></p>
622
 
623
  <form method="post" action="options.php">
624
- <?php wp_nonce_field('update-options'); ?>
625
-
626
  <table class="form-table">
627
-
628
- <tr valign="top">
629
- <th scope="row">Save Thumbnail to Media</th>
630
- <td><?php video_thumbnails_checkbox_option('video_thumbnails_save_media', 'Save local copies of thumbnails using the media library'); ?></td>
631
  </tr>
632
 
633
- <tr valign="top">
634
- <th scope="row">Set as Featured Image</th>
635
- <td><?php video_thumbnails_checkbox_option('video_thumbnails_set_featured', 'Automatically set thumbnail as featured image ("Save Thumbnail to Media" must be enabled)'); ?></td>
636
  </tr>
637
-
638
- <tr valign="top">
639
- <th scope="row">Post Types</th>
640
  <td>
641
- <?php $video_thumbnails_post_types = get_option('video_thumbnails_post_types'); ?>
642
- <?php foreach(get_post_types() as $type): if($type == 'attachment' OR $type == 'revision' OR $type == 'nav_menu_item') continue; ?>
643
  <label for="video_thumbnails_post_types_<?php echo $type; ?>">
644
- <input id="video_thumbnails_post_types_<?php echo $type; ?>" name="video_thumbnails_post_types[]" type="checkbox" value="<?php echo $type; ?>" <?php if(is_array($video_thumbnails_post_types)) checked(in_array($type, $video_thumbnails_post_types)); ?> />
645
- <?php echo $type; ?>
646
  </label>
647
  <br />
648
  <?php endforeach; ?>
649
  </td>
650
  </tr>
651
-
652
- </table>
653
 
 
 
 
 
 
 
 
 
 
654
  <p class="submit">
655
- <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
656
  </p>
657
-
658
  <h3>How to use</h3>
659
-
660
  <p>For themes that use featured images, simply leave the two settings above enabled.</p>
661
-
662
  <p>For more detailed instructions, check out the page for <a href="http://wordpress.org/extend/plugins/video-thumbnails/">Video Thumbnails on the official plugin directory</a>.</p>
663
-
664
  <input type="hidden" name="action" value="update" />
665
- <input type="hidden" name="page_options" value="video_thumbnails_save_media,video_thumbnails_set_featured,video_thumbnails_post_types" />
666
 
667
  </form>
668
-
669
  <h3>Scan All Posts</h3>
670
-
671
  <p>Scan all of your past posts for video thumbnails. Be sure to save any settings before running the scan.</p>
672
 
673
  <p><input type="submit" class="button-primary" onclick="scan_video_thumbnails();" value="Scan Past Posts" /></p>
5
  Description: Automatically retrieve video thumbnails for your posts and display them in your theme. Currently supports YouTube, Vimeo, Blip.tv, Justin.tv, Dailymotion and Metacafe.
6
  Author: Sutherland Boswell
7
  Author URI: http://sutherlandboswell.com
8
+ Version: 1.8
9
  License: GPL2
10
  */
11
  /* Copyright 2010 Sutherland Boswell (email : sutherland.boswell@gmail.com)
25
  */
26
 
27
  // Get Vimeo Thumbnail
28
+ function getVimeoInfo( $id, $info = 'thumbnail_large' ) {
29
+ if ( ! function_exists( 'curl_init' ) ) {
30
  return null;
31
  } else {
32
  $ch = curl_init();
33
  $videoinfo_url = "http://vimeo.com/api/v2/video/$id.php";
34
+ curl_setopt( $ch, CURLOPT_URL, $videoinfo_url );
35
+ curl_setopt( $ch, CURLOPT_HEADER, 0 );
36
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
37
+ curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );
38
+ curl_setopt( $ch, CURLOPT_FAILONERROR, true ); // Return an error for curl_error() processing if HTTP response code >= 400
39
+ $output = unserialize( curl_exec( $ch ) );
40
  $output = $output[0][$info];
41
+ if ( curl_error( $ch ) != null ) {
42
+ $output = new WP_Error( 'vimeo_info_retrieval', __( 'Error retrieving video information from the URL <a href="' . $videoinfo_url . '">' . $videoinfo_url . '</a>.<br /><a href="http://curl.haxx.se/libcurl/c/libcurl-errors.html">Libcurl error</a> ' . curl_errno( $ch ) . ': <code>' . curl_error( $ch ) . '</code>. 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.' ) );
43
  }
44
+ curl_close( $ch );
45
  return $output;
46
  }
47
  };
48
 
49
  // Blip.tv Functions
50
+ function getBliptvInfo( $id ) {
51
  $videoinfo_url = "http://blip.tv/players/episode/$id?skin=rss";
52
+ $xml = simplexml_load_file( $videoinfo_url );
53
+ if ( $xml == false ) {
54
+ return new WP_Error( 'bliptv_info_retrieval', __( 'Error retrieving video information from the URL <a href="' . $videoinfo_url . '">' . $videoinfo_url . '</a>. 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.' ) );
55
  } else {
56
+ $result = $xml->xpath( "/rss/channel/item/media:thumbnail/@url" );
57
  $thumbnail = (string) $result[0]['url'];
58
  return $thumbnail;
59
  }
60
  }
61
 
62
  // Justin.tv Functions
63
+ function getJustintvInfo( $id ) {
64
+ $xml = simplexml_load_file( "http://api.justin.tv/api/clip/show/$id.xml" );
65
  return (string) $xml->clip->image_url_large;
66
  }
67
 
68
  // Get DailyMotion Thumbnail
69
+ function getDailyMotionThumbnail( $id ) {
70
+ if ( ! function_exists( 'curl_init' ) ) {
71
  return null;
72
  } else {
73
  $ch = curl_init();
74
  $videoinfo_url = "https://api.dailymotion.com/video/$id?fields=thumbnail_url";
75
+ curl_setopt( $ch, CURLOPT_URL, $videoinfo_url );
76
+ curl_setopt( $ch, CURLOPT_HEADER, 0 );
77
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
78
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
79
+ curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );
80
+ curl_setopt( $ch, CURLOPT_FAILONERROR, true ); // Return an error for curl_error() processing if HTTP response code >= 400
81
+ $output = curl_exec( $ch );
82
+ $output = json_decode( $output );
83
  $output = $output->thumbnail_url;
84
+ if ( curl_error( $ch ) != null ) {
85
+ $output = new WP_Error( 'dailymotion_info_retrieval', __( 'Error retrieving video information from the URL <a href="' . $videoinfo_url . '">' . $videoinfo_url . '</a>.<br /><a href="http://curl.haxx.se/libcurl/c/libcurl-errors.html">Libcurl error</a> ' . curl_errno( $ch ) . ': <code>' . curl_error( $ch ) . '</code>. 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.' ) );
86
+ }
87
+ curl_close( $ch ); // Moved here to allow curl_error() operation above. Was previously below curl_exec() call.
88
  return $output;
89
  }
90
  };
91
 
92
  // Metacafe
93
+ function getMetacafeThumbnail( $id ) {
94
  $videoinfo_url = "http://www.metacafe.com/api/item/$id/";
95
+ $xml = simplexml_load_file( $videoinfo_url );
96
+ if ( $xml == false ) {
97
+ return new WP_Error( 'metacafe_info_retrieval', __( 'Error retrieving video information from the URL <a href="' . $videoinfo_url . '">' . $videoinfo_url . '</a>.<br /><a href="http://curl.haxx.se/libcurl/c/libcurl-errors.html">Libcurl error</a> ' . curl_errno( $ch ) . ': <code>' . curl_error( $ch ) . '</code>. 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.' ) );
98
  } else {
99
+ $result = $xml->xpath( "/rss/channel/item/media:thumbnail/@url" );
100
  $thumbnail = (string) $result[0]['url'];
101
  return $thumbnail;
102
  }
105
  //
106
  // The Main Event
107
  //
108
+ function get_video_thumbnail( $post_id = null ) {
109
+
110
  // Get the post ID if none is provided
111
+ if ( $post_id == null OR $post_id == '' ) $post_id = get_the_ID();
112
+
113
+ // Check to see if thumbnail has already been found
114
+ if( ( $thumbnail_meta = get_post_meta( $post_id, '_video_thumbnail', true ) ) != '' ) {
115
  return $thumbnail_meta;
116
  }
117
  // If the thumbnail isn't stored in custom meta, fetch a thumbnail
118
  else {
119
 
120
+ // Get the post or custom field to search
121
+ if ( $video_key = get_option( 'video_thumbnails_custom_field' ) ) {
122
+ $markup = get_post_meta( $post_id, $video_key, true );
123
+ } else {
124
+ $post_array = get_post( $post_id );
125
+ $markup = $post_array->post_content;
126
+ $markup = apply_filters( 'the_content', $markup );
127
+ }
128
  $new_thumbnail = null;
129
+
130
  // Simple Video Embedder Compatibility
131
+ if ( function_exists( 'p75HasVideo' ) ) {
132
+ if ( p75HasVideo( $post_id ) ) {
133
+ $markup = p75GetVideo( $post_id );
134
  }
135
  }
136
+
137
  // Checks for the old standard YouTube embed
138
+ preg_match( '#<object[^>]+>.+?https?://www\.youtube(?:\-nocookie)?\.com/[ve]/([A-Za-z0-9\-_]+).+?</object>#s', $markup, $matches );
139
+
140
  // More comprehensive search for YouTube embed, redundant but necessary until more testing is completed
141
+ if ( !isset( $matches[1] ) ) {
142
+ preg_match( '#https?://www\.youtube(?:\-nocookie)?\.com/[ve]/([A-Za-z0-9\-_]+)#', $markup, $matches );
143
  }
144
 
145
  // Checks for YouTube iframe, the new standard since at least 2011
146
+ if ( !isset( $matches[1] ) ) {
147
+ preg_match( '#https?://www\.youtube(?:\-nocookie)?\.com/embed/([A-Za-z0-9\-_]+)#', $markup, $matches );
148
  }
149
+
150
  // Checks for any YouTube URL. After http(s) support a or v for Youtube Lyte and v or vh for Smart Youtube plugin
151
+ if ( !isset( $matches[1] ) ) {
152
+ preg_match( '#(?:https?(?:a|vh?)?://)?(?:www\.)?youtube(?:\-nocookie)?\.com/watch\?.*v=([A-Za-z0-9\-_]+)#', $markup, $matches );
153
  }
154
+
155
  // Checks for any shortened youtu.be URL. After http(s) a or v for Youtube Lyte and v or vh for Smart Youtube plugin
156
+ if ( !isset( $matches[1] ) ) {
157
+ preg_match( '#(?:https?(?:a|vh?)?://)?youtu\.be/([A-Za-z0-9\-_]+)#', $markup, $matches );
158
  }
159
+
160
  // Checks for YouTube Lyte
161
+ if ( !isset( $matches[1] ) && function_exists( 'lyte_parse' ) ) {
162
+ preg_match( '#<div class="lyte" id="([A-Za-z0-9\-_]+)"#', $markup, $matches );
163
  }
164
+
165
  // If we've found a YouTube video ID, create the thumbnail URL
166
+ if ( isset( $matches[1] ) ) {
167
  $youtube_thumbnail = 'http://img.youtube.com/vi/' . $matches[1] . '/0.jpg';
168
+
169
  // Check to make sure it's an actual thumbnail
170
+ if ( ! function_exists( 'curl_init' ) ) {
171
  $new_thumbnail = $youtube_thumbnail;
172
  } else {
173
+ $ch = curl_init( $youtube_thumbnail );
174
+ curl_setopt( $ch, CURLOPT_NOBODY, true );
175
+ curl_exec( $ch );
176
+ $retcode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
177
  // $retcode > 400 -> not found, $retcode = 200, found.
178
+ curl_close( $ch );
179
+ if ( $retcode == 200 ) {
180
  $new_thumbnail = $youtube_thumbnail;
181
  }
182
  }
183
  }
184
+
185
  // Vimeo
186
+ if ( $new_thumbnail == null ) {
187
+
188
  // Standard embed code
189
+ preg_match( '#<object[^>]+>.+?http://vimeo\.com/moogaloop.swf\?clip_id=([A-Za-z0-9\-_]+)&.+?</object>#s', $markup, $matches );
190
+
191
  // Find Vimeo embedded with iframe code
192
+ if ( !isset( $matches[1] ) ) {
193
+ preg_match( '#http://player\.vimeo\.com/video/([0-9]+)#', $markup, $matches );
194
  }
195
+
196
  // If we still haven't found anything, check for Vimeo embedded with JR_embed
197
+ if ( !isset( $matches[1] ) ) {
198
+ preg_match( '#\[vimeo id=([A-Za-z0-9\-_]+)]#', $markup, $matches );
199
  }
200
+
201
  // If we still haven't found anything, check for Vimeo URL
202
+ if ( !isset( $matches[1] ) ) {
203
+ preg_match( '#(?:http://)?(?:www\.)?vimeo\.com/([A-Za-z0-9\-_]+)#', $markup, $matches );
204
  }
205
+
206
  // If we still haven't found anything, check for Vimeo shortcode
207
+ if ( !isset( $matches[1] ) ) {
208
+ preg_match( '#\[vimeo clip_id="([A-Za-z0-9\-_]+)"[^>]*]#', $markup, $matches );
209
  }
210
+ if ( !isset( $matches[1] ) ) {
211
+ preg_match( '#\[vimeo video_id="([A-Za-z0-9\-_]+)"[^>]*]#', $markup, $matches );
212
  }
213
+
214
  // Now if we've found a Vimeo ID, let's set the thumbnail URL
215
+ if ( isset( $matches[1] ) ) {
216
+ $vimeo_thumbnail = getVimeoInfo( $matches[1], $info = 'thumbnail_large' );
217
+ if ( is_wp_error( $vimeo_thumbnail ) ) {
218
  return $vimeo_thumbnail;
219
+ } else if ( isset( $vimeo_thumbnail ) ) {
220
  $new_thumbnail = $vimeo_thumbnail;
221
  }
222
  }
223
  }
224
+
225
  // Blip.tv
226
+ if ( $new_thumbnail == null ) {
227
+
228
  // Blip.tv embed URL
229
+ preg_match( '#http://blip\.tv/play/([A-Za-z0-9]+)#', $markup, $matches );
230
 
231
  // Now if we've found a Blip.tv embed URL, let's set the thumbnail URL
232
+ if ( isset( $matches[1] ) ) {
233
+ $blip_thumbnail = getBliptvInfo( $matches[1] );
234
+ if ( is_wp_error( $blip_thumbnail ) ) {
235
  return $blip_thumbnail;
236
+ } else if ( isset( $blip_thumbnail ) ) {
237
+ $new_thumbnail = $blip_thumbnail;
238
  }
239
  }
240
  }
241
+
242
  // Justin.tv
243
+ if ( $new_thumbnail == null ) {
244
+
245
  // Justin.tv archive ID
246
+ preg_match( '#archive_id=([0-9]+)#', $markup, $matches );
247
 
248
  // Now if we've found a Justin.tv archive ID, let's set the thumbnail URL
249
+ if ( isset( $matches[1] ) ) {
250
+ $justin_thumbnail = getJustintvInfo( $matches[1] );
251
  $new_thumbnail = $justin_thumbnail;
252
  }
253
  }
254
+
255
  // Dailymotion
256
+ if ( $new_thumbnail == null ) {
257
+
258
  // Dailymotion flash
259
+ preg_match( '#<object[^>]+>.+?http://www\.dailymotion\.com/swf/video/([A-Za-z0-9]+).+?</object>#s', $markup, $matches );
260
+
261
  // Dailymotion url
262
+ if ( !isset( $matches[1] ) ) {
263
+ preg_match( '#(?:https?://)?(?:www\.)?dailymotion\.com/video/([A-Za-z0-9]+)#', $markup, $matches );
264
  }
265
+
266
  // Dailymotion iframe
267
+ if ( !isset( $matches[1] ) ) {
268
+ preg_match( '#https?://www\.dailymotion\.com/embed/video/([A-Za-z0-9]+)#', $markup, $matches );
269
  }
270
 
271
  // Now if we've found a Dailymotion video ID, let's set the thumbnail URL
272
+ if ( isset( $matches[1] ) ) {
273
+ $dailymotion_thumbnail = getDailyMotionThumbnail( $matches[1] );
274
+ if ( is_wp_error( $dailymotion_thumbnail ) ) {
275
  return $dailymotion_thumbnail;
276
+ } else if ( isset( $dailymotion_thumbnail ) ) {
277
+ $new_thumbnail = strtok( $dailymotion_thumbnail, '?' );
278
  }
279
  }
280
  }
281
+
282
  // Metacafe
283
+ if ( $new_thumbnail == null ) {
284
+
285
  // Find ID from Metacafe embed url
286
+ preg_match( '#http://www\.metacafe\.com/fplayer/([A-Za-z0-9\-_]+)/#', $markup, $matches );
287
 
288
  // Now if we've found a Metacafe video ID, let's set the thumbnail URL
289
+ if ( isset( $matches[1] ) ) {
290
+ $metacafe_thumbnail = getMetacafeThumbnail( $matches[1] );
291
+ if ( is_wp_error( $metacafe_thumbnail ) ) {
292
  return $metacafe_thumbnail;
293
+ } else if ( isset( $metacafe_thumbnail ) ) {
294
+ $new_thumbnail = strtok( $metacafe_thumbnail, '?' );
295
  }
296
  }
297
  }
298
+
299
  // Return the new thumbnail variable and update meta if one is found
300
+ if ( $new_thumbnail != null ) {
301
+
302
  // Save as Attachment if enabled
303
+ if ( get_option( 'video_thumbnails_save_media' ) == 1 ) {
304
  $error = '';
305
+ $ch = curl_init();
306
+ $timeout = 0;
307
+ curl_setopt ( $ch, CURLOPT_URL, $new_thumbnail );
308
+ curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
309
+ curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
310
+ curl_setopt( $ch, CURLOPT_FAILONERROR, true ); // Return an error for curl_error() processing if HTTP response code >= 400
311
+ $image_contents = curl_exec( $ch );
312
+ if ( curl_error( $ch ) != null || $image_contents == null ) {
313
  $curl_error = '';
314
+ if ( curl_error( $ch ) != null ) {
315
+ $curl_error = '<br /><a href="http://curl.haxx.se/libcurl/c/libcurl-errors.html">Libcurl error</a> ' . curl_errno( $ch ) . ': <code>' . curl_error( $ch ) . '</code>';
316
  }
317
+ $error = new WP_Error( 'thumbnail_retrieval', __( 'Error retrieving a thumbnail from the URL <a href="' . $new_thumbnail . '">' . $new_thumbnail . '</a>' . $curl_error . '. If opening that URL in your web browser shows an image, the problem may be related to your web server and might be something your server administrator can solve.' ) );
318
  }
319
+ curl_close( $ch );
320
 
321
+ if ( $error != null ) {
322
  return $error;
323
  } else {
324
 
325
+ $upload = wp_upload_bits( basename( $new_thumbnail ), null, $image_contents );
326
 
327
  $new_thumbnail = $upload['url'];
328
 
329
  $filename = $upload['file'];
330
 
331
+ $wp_filetype = wp_check_filetype( basename( $filename ), null );
332
  $attachment = array(
333
+ 'post_mime_type' => $wp_filetype['type'],
334
+ 'post_title' => get_the_title($post_id),
335
+ 'post_content' => '',
336
+ 'post_status' => 'inherit'
337
  );
338
  $attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
339
  // you must first include the image.php file
340
  // for the function wp_generate_attachment_metadata() to work
341
+ require_once( ABSPATH . 'wp-admin/includes/image.php' );
342
  $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
343
  wp_update_attachment_metadata( $attach_id, $attach_data );
344
 
345
  }
346
 
347
  }
348
+
349
  // Add hidden custom field with thumbnail URL
350
+ if ( !update_post_meta( $post_id, '_video_thumbnail', $new_thumbnail ) ) add_post_meta( $post_id, '_video_thumbnail', $new_thumbnail, true );
351
+
352
  // Set attachment as featured image if enabled
353
+ if ( get_option( 'video_thumbnails_set_featured' ) == 1 && get_option( 'video_thumbnails_save_media' ) == 1 && get_post_meta( $post_id, '_thumbnail_id', true ) == '' ) {
354
+ if ( !update_post_meta( $post_id, '_thumbnail_id', $attach_id ) ) add_post_meta( $post_id, '_thumbnail_id', $attach_id, true );
355
  }
356
  }
357
  return $new_thumbnail;
360
  };
361
 
362
  // Echo thumbnail
363
+ function video_thumbnail( $post_id = null ) {
364
+ if ( ( $video_thumbnail = get_video_thumbnail( $post_id ) ) == null ) { echo plugins_url() . '/video-thumbnails/default.jpg'; }
365
  else { echo $video_thumbnail; }
366
  };
367
 
368
  // Create Meta Fields on Edit Page
369
 
370
+ add_action( 'admin_init', 'video_thumbnail_admin_init' );
371
 
372
+ function video_thumbnail_admin_init() {
373
+ $video_thumbnails_post_types = get_option( 'video_thumbnails_post_types' );
374
+ if ( is_array( $video_thumbnails_post_types ) ) {
375
+ foreach ( $video_thumbnails_post_types as $type ) {
376
+ add_meta_box( 'video_thumbnail', 'Video Thumbnail', 'video_thumbnail_admin', $type, 'side', 'low' );
377
  }
378
  }
379
  }
380
+
381
+ function video_thumbnail_admin() {
382
  global $post;
383
+ $custom = get_post_custom( $post->ID );
384
  $video_thumbnail = $custom["_video_thumbnail"][0];
385
+
386
+ if ( isset( $video_thumbnail ) && $video_thumbnail != '' ) {
387
+ echo '<p id="video-thumbnails-preview"><img src="' . $video_thumbnail . '" style="max-width:100%;" /></p>'; }
388
+
 
389
  if ( get_post_status() == 'publish' || get_post_status() == 'private' ) {
390
+ if ( isset( $video_thumbnail ) && $video_thumbnail != '' ) {
391
+ echo '<p><a href="#" id="video-thumbnails-reset" onclick="video_thumbnails_reset(\'' . $post->ID . '\' );return false;">Reset Video Thumbnail</a></p>';
392
  } else {
393
  echo '<p id="video-thumbnails-preview">We didn\'t find a video thumbnail for this post.</p>';
394
+ echo '<p><a href="#" id="video-thumbnails-reset" onclick="video_thumbnails_reset(\'' . $post->ID . '\' );return false;">Search Again</a></p>';
395
  }
396
  } else {
397
+ if ( isset( $video_thumbnail ) && $video_thumbnail != '' ) {
398
+ echo '<p><a href="#" id="video-thumbnails-reset" onclick="video_thumbnails_reset(\'' . $post->ID . '\' );return false;">Reset Video Thumbnail</a></p>';
399
  } else {
400
  echo '<p>A video thumbnail will be found for this post when it is published.</p>';
401
  }
404
 
405
  // AJAX Searching
406
 
407
+ if ( in_array( basename( $_SERVER['PHP_SELF'] ), apply_filters( 'video_thumbnails_editor_pages', array( 'post-new.php', 'page-new.php', 'post.php', 'page.php' ) ) ) ) {
408
+ add_action( 'admin_head', 'video_thumbnails_ajax' );
409
  }
410
 
411
  function video_thumbnails_ajax() {
412
  ?>
413
 
414
  <!-- Video Thumbnails Researching Ajax -->
415
+ <script type="text/javascript">
416
  function video_thumbnails_reset(id) {
417
 
418
  var data = {
419
  action: 'video_thumbnails',
420
  post_id: id
421
  };
422
+
423
+ document.getElementById('video-thumbnails-preview').innerHTML='Working... <img src="<?php echo home_url( 'wp-admin/images/loading.gif' ); ?>"/>';
424
 
425
  // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
426
+ jQuery.post(ajaxurl, data, function(response){
427
+ document.getElementById('video-thumbnails-preview').innerHTML=response;
428
  });
429
  };
430
  </script>
431
  <?php
432
  }
433
 
434
+ add_action( 'wp_ajax_video_thumbnails', 'video_thumbnails_callback' );
435
 
436
  function video_thumbnails_callback() {
437
  global $wpdb; // this is how you get access to the database
438
 
439
  $post_id = $_POST['post_id'];
440
 
441
+ delete_post_meta( $post_id, '_video_thumbnail' );
442
 
443
+ $video_thumbnail = get_video_thumbnail( $post_id );
444
 
445
+ if ( is_wp_error( $video_thumbnail ) ) {
446
  echo $video_thumbnail->get_error_message();
447
+ } else if ( $video_thumbnail != null ) {
448
+ echo '<img src="' . $video_thumbnail . '" style="max-width:100%;" />';
449
  } else {
450
  echo 'We didn\'t find a video thumbnail for this post. (be sure you have saved changes first)';
451
  }
455
 
456
  // Find video thumbnail when saving a post, but not on autosave
457
 
458
+ add_action( 'new_to_publish', 'save_video_thumbnail', 10, 1 );
459
+ add_action( 'draft_to_publish', 'save_video_thumbnail', 10, 1 );
460
+ add_action( 'pending_to_publish', 'save_video_thumbnail', 10, 1 );
461
+ add_action( 'future_to_publish', 'save_video_thumbnail', 10, 1 );
462
 
463
+ function save_video_thumbnail( $post ) {
464
  $post_type = get_post_type( $post->ID );
465
+ $video_thumbnails_post_types = get_option( 'video_thumbnails_post_types' );
466
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
467
  return null;
468
  } else {
469
  // Check that Video Thumbnails are enabled for current post type
470
+ if ( in_array( $post_type, (array) $video_thumbnails_post_types ) || $post_type == $video_thumbnails_post_types ) {
471
+ get_video_thumbnail( $post->ID );
472
  } else {
473
  return null;
474
  }
477
 
478
  // Set Default Options
479
 
480
+ register_activation_hook( __FILE__, 'video_thumbnails_activate' );
481
+ register_deactivation_hook( __FILE__, 'video_thumbnails_deactivate' );
482
 
483
  function video_thumbnails_activate() {
484
+ add_option( 'video_thumbnails_save_media', '1' );
485
+ add_option( 'video_thumbnails_set_featured', '1' );
486
+ add_option( 'video_thumbnails_custom_field', '' );
487
+ add_option( 'video_thumbnails_post_types', array( 'post' ) );
488
  }
489
 
490
  function video_thumbnails_deactivate() {
491
+ delete_option( 'video_thumbnails_save_media' );
492
+ delete_option( 'video_thumbnails_set_featured' );
493
+ delete_option( 'video_thumbnails_custom_field' );
494
+ delete_option( 'video_thumbnails_post_types' );
495
  }
496
 
497
  // Check for cURL
498
 
499
+ register_activation_hook( __FILE__, 'video_thumbnails_curl_check' );
500
 
501
+ function video_thumbnails_curl_check() {
502
+ if ( ! function_exists( 'curl_init' ) ) {
503
+ deactivate_plugins( basename( __FILE__ ) ); // Deactivate ourself
504
+ wp_die( 'Sorry, but this plugin requires <a href="http://curl.haxx.se/libcurl/">libcurl</a> to be activated on your server.' );
505
  }
506
  }
507
 
508
  // AJAX for Past Posts
509
 
510
  if ( isset ( $_GET['page'] ) && ( $_GET['page'] == 'video-thumbnail-options' ) ) {
511
+ add_action( 'admin_head', 'video_thumbnails_past_ajax' );
512
  }
513
 
514
  function video_thumbnails_past_ajax() {
515
  ?>
516
 
517
  <!-- Video Thumbnails Past Post Ajax -->
518
+ <script type="text/javascript">
519
  function video_thumbnails_past(id) {
520
 
521
  var data = {
524
  };
525
 
526
  // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
527
+ jQuery.post(ajaxurl, data, function(response){
 
528
 
529
  document.getElementById(id+'_result').innerHTML = response;
530
 
533
  };
534
 
535
  <?php
536
+ $video_thumbnails_post_types = get_option( 'video_thumbnails_post_types' );
537
+ $posts = get_posts( array(
538
+ 'showposts' => -1,
539
+ 'post_type' => $video_thumbnails_post_types
540
+ ) );
541
+
542
+ if ( $posts ) {
543
+ foreach ( $posts as $post ) {
544
  $post_ids[] = $post->ID;
545
  }
546
+ $ids = implode( ', ', $post_ids );
547
  }
548
  ?>
549
 
575
  <?php
576
  }
577
 
578
+ add_action( 'wp_ajax_video_thumbnails_past', 'video_thumbnails_past_callback' );
579
 
580
  function video_thumbnails_past_callback() {
581
  global $wpdb; // this is how you get access to the database
582
 
583
  $post_id = $_POST['post_id'];
584
 
585
+ echo get_the_title( $post_id ) . ' - ';
586
 
587
+ $video_thumbnail = get_video_thumbnail( $post_id );
588
 
589
+ if ( is_wp_error( $video_thumbnail ) ) {
590
  echo $video_thumbnail->get_error_message();
591
+ } else if ( $video_thumbnail != null ) {
592
  echo '<span style="color:green">&#10004;</span> Success!';
593
  } else {
594
  echo '<span style="color:red">&#10006;</span> Couldn\'t find a video thumbnail for this post.';
599
 
600
  // Administration
601
 
602
+ add_action( 'admin_menu', 'video_thumbnails_menu' );
603
 
604
  function video_thumbnails_menu() {
605
+ add_options_page( 'Video Thumbnail Options', 'Video Thumbnails', 'manage_options', 'video-thumbnail-options', 'video_thumbnail_options' );
 
 
606
  }
607
 
608
+ function video_thumbnails_checkbox_option( $option_name, $option_description ) { ?>
609
+ <fieldset><legend class="screen-reader-text"><span><?php echo $option_description; ?></span></legend>
610
+ <label for="<?php echo $option_name; ?>"><input name="<?php echo $option_name; ?>" type="checkbox" id="<?php echo $option_name; ?>" value="1" <?php if ( get_option( $option_name ) == 1 ) echo 'checked="checked"'; ?>/> <?php echo $option_description; ?></label>
611
  </fieldset> <?php
612
  }
613
 
614
  function video_thumbnail_options() {
615
 
616
+ if ( ! current_user_can( 'manage_options' ) ) {
617
+ wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
618
  }
619
 
620
  ?>
621
 
622
  <div class="wrap">
623
+
624
  <div id="icon-options-general" class="icon32"></div><h2>Video Thumbnails Options</h2>
625
+
626
  <p>Say thanks by donating, any amount is appreciated!<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_s-xclick"><input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"><img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"></form></p>
627
 
628
  <form method="post" action="options.php">
629
+ <?php wp_nonce_field( 'update-options' ); ?>
630
+
631
  <table class="form-table">
632
+
633
+ <tr valign="top">
634
+ <th scope="row">Save Thumbnail to Media</th>
635
+ <td><?php video_thumbnails_checkbox_option( 'video_thumbnails_save_media', 'Save local copies of thumbnails using the media library' ); ?></td>
636
  </tr>
637
 
638
+ <tr valign="top">
639
+ <th scope="row">Set as Featured Image</th>
640
+ <td><?php video_thumbnails_checkbox_option( 'video_thumbnails_set_featured', 'Automatically set thumbnail as featured image ("Save Thumbnail to Media" must be enabled)' ); ?></td>
641
  </tr>
642
+
643
+ <tr valign="top">
644
+ <th scope="row">Post Types</th>
645
  <td>
646
+ <?php $video_thumbnails_post_types = get_option( 'video_thumbnails_post_types' ); ?>
647
+ <?php foreach ( get_post_types() as $type ) : if ( $type == 'attachment' OR $type == 'revision' OR $type == 'nav_menu_item' ) continue; ?>
648
  <label for="video_thumbnails_post_types_<?php echo $type; ?>">
649
+ <input id="video_thumbnails_post_types_<?php echo $type; ?>" name="video_thumbnails_post_types[]" type="checkbox" value="<?php echo $type; ?>" <?php if ( is_array( $video_thumbnails_post_types ) ) checked( in_array( $type, $video_thumbnails_post_types ) ); ?> />
650
+ <?php echo $type; ?>
651
  </label>
652
  <br />
653
  <?php endforeach; ?>
654
  </td>
655
  </tr>
 
 
656
 
657
+ <tr valign="top">
658
+ <th scope="row">Custom Field (Optional: If your video is stored in a custom field, enter the name of that field here. Otherwise, leave this field blank.)</th>
659
+ <td><fieldset><legend class="screen-reader-text"><span>Custom Field (Optional: If your video is stored in a custom field, enter the name of that field here. Otherwise, leave this field blank.)</span></legend>
660
+ <input name="video_thumbnails_custom_field" type="text" id="video_thumbnails_custom_field" value="<?php echo get_option( 'video_thumbnails_custom_field' ); ?>" />
661
+ </fieldset></td>
662
+ </tr>
663
+
664
+ </table>
665
+
666
  <p class="submit">
667
+ <input type="submit" class="button-primary" value="<?php _e( 'Save Changes' ) ?>" />
668
  </p>
669
+
670
  <h3>How to use</h3>
671
+
672
  <p>For themes that use featured images, simply leave the two settings above enabled.</p>
673
+
674
  <p>For more detailed instructions, check out the page for <a href="http://wordpress.org/extend/plugins/video-thumbnails/">Video Thumbnails on the official plugin directory</a>.</p>
675
+
676
  <input type="hidden" name="action" value="update" />
677
+ <input type="hidden" name="page_options" value="video_thumbnails_save_media,video_thumbnails_set_featured,video_thumbnails_post_types,video_thumbnails_custom_field" />
678
 
679
  </form>
680
+
681
  <h3>Scan All Posts</h3>
682
+
683
  <p>Scan all of your past posts for video thumbnails. Be sure to save any settings before running the scan.</p>
684
 
685
  <p><input type="submit" class="button-primary" onclick="scan_video_thumbnails();" value="Scan Past Posts" /></p>