WP YouTube Lyte - Version 1.7.8

Version Description

  • misc. improvements to prevent structured data warnings from Google.
  • fix breaking locally cached thumbnails when mime_content_type function is not available.
  • tested with WordPress 5.3 (beta 3).
Download this release

Release Info

Developer futtta
Plugin Icon 128x128 WP YouTube Lyte
Version 1.7.8
Comparing to
See all releases

Code changes from version 1.7.7 to 1.7.8

Files changed (3) hide show
  1. lyteThumbs.php +10 -1
  2. readme.txt +12 -8
  3. wp-youtube-lyte.php +49 -18
lyteThumbs.php CHANGED
@@ -92,7 +92,7 @@ if ( !file_exists($localThumb) || $lyte_thumb_dontsave ) {
92
  * step 4: serve img
93
  */
94
 
95
- if ( $thumbContents == "" && !$lyte_thumb_dontsave && file_exists($localThumb) && mime_content_type($localThumb) === "image/jpeg" ) {
96
  $thumbContents = file_get_contents( $localThumb );
97
  } else {
98
  $lyte_thumb_error .= "not from cache/ ";
@@ -129,6 +129,15 @@ if ( $thumbContents != "") {
129
  /*
130
  * helper functions
131
  */
 
 
 
 
 
 
 
 
 
132
 
133
  function lyte_check_cache_dir( $dir ) {
134
  // Try creating the dir if it doesn't exist.
92
  * step 4: serve img
93
  */
94
 
95
+ if ( $thumbContents == "" && !$lyte_thumb_dontsave && file_exists($localThumb) && is_jpeg($localThumb) ) {
96
  $thumbContents = file_get_contents( $localThumb );
97
  } else {
98
  $lyte_thumb_error .= "not from cache/ ";
129
  /*
130
  * helper functions
131
  */
132
+ function is_jpeg( $in ) {
133
+ if ( function_exists( 'mime_content_type' ) && mime_content_type($in) === "image/jpeg" ) {
134
+ return true;
135
+ } elseif ( strpos( $in, '.jpg' ) === strlen( $in ) -4 ) {
136
+ return true;
137
+ } else {
138
+ return false;
139
+ }
140
+ }
141
 
142
  function lyte_check_cache_dir( $dir ) {
143
  // Try creating the dir if it doesn't exist.
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: futtta, optimizingmatters
3
  Tags: youtube, video, performance, gdpr, lazy load
4
  Donate link: http://blog.futtta.be/2013/10/21/do-not-donate-to-me/
5
  Requires at least: 4.0
6
- Tested up to: 5.2
7
- Stable tag: 1.7.7
8
 
9
  High performance YouTube video, playlist and audio-only embeds which don't slow down your blog and offer optimal accessibility.
10
 
@@ -53,14 +53,13 @@ An API is a way to have two pieces of software talk to each other to exchange in
53
  * Click on 'Create'
54
 
55
  3. On the next page (or when there is no next page, click on your Project's name):
56
- * Click on 'Enable an API'
57
  * Scroll down to YouTube Data API v3 and click on it
58
- * Click on 'OFF' at the top to enable the API
59
  * Optionally disable other API's
60
 
61
  4. In the sidebar on the left:
62
  * Click on 'Credentials'
63
- * Click on 'Create Credential'
64
  * Click on 'API key'
65
  * Set as little restrictions as possible, most problems with getting this working are caused by these settings.
66
  * Click on 'Create'
@@ -80,7 +79,7 @@ As opposed to some of the [most important](http://blog.futtta.be/2010/12/15/word
80
  LYTE by default uses WordPress' "the_content"-filter. Page builders don't apply that filter to their content and thus LYTE does not get triggered on those. As a workaround you can either add the LYTE widget or add the LYTE video using the shortcode in your page-builder Text-block, this works in most page-builders.
81
 
82
  = Can I use WP YouTube Lyte for a custom field? =
83
- Just pass the httpv url of such a field to lyte_preparse like this:
84
  `if(function_exists('lyte_preparse')) { echo lyte_preparse($video); }`
85
  and you're good to go!
86
 
@@ -94,7 +93,7 @@ Starting from version 1.1.0 it does; in [Infinite Scroll](http://wordpress.org/e
94
  * Google will not always display the thumbnail, this presumably depends of the relevance of the video to the rest of the page.
95
 
96
  = How does captions-support get added to the microdata? =
97
- In January 2014 [Benetech](http://benetech.org/), a U.S. nonprofit that develops and uses technology to create positive social change, offered a patch that adds the [accessibilityFeature property](http://schema.org/accessibilityFeature) to the microdata for videos that have captions. If you have microdata enabled, WP YouTube Lyte will automatically try to check (in a seperate, asynchronous call via a proxy-webservice, as YouTube only offers captions in their API v3 which requires authentication) if captions are available and if so, adds the accessibilityFeature property with value captions to the microdata. This can be disabled by either disabling microdata or, if you want microdata but not the accessibilityFeature-property by using the "lyte_docaptions"-filter to set captions to false (example-code is in lyte_helper.php_example).
98
 
99
  = Responsive LYTE embeds =
100
  * The video width in posts and pages will adapt to the width of the container (the div) in which your blogposts/ pages are shown. This means that if your theme is responsive, WP YouTube Lyte will follow.
@@ -136,8 +135,13 @@ Just tell me, I like the feedback! Use the [Contact-page on my blog](http://blog
136
 
137
  == Changelog ==
138
 
 
 
 
 
 
139
  = 1.7.7 =
140
- * bugfix: avoid having to click play twice in Chrome (due to autoplay not working)
141
 
142
  = 1.7.6 =
143
  * improvement: extra parameters for shortcode (start, showinfo, stepsize and hqthumb).
3
  Tags: youtube, video, performance, gdpr, lazy load
4
  Donate link: http://blog.futtta.be/2013/10/21/do-not-donate-to-me/
5
  Requires at least: 4.0
6
+ Tested up to: 5.3
7
+ Stable tag: 1.7.8
8
 
9
  High performance YouTube video, playlist and audio-only embeds which don't slow down your blog and offer optimal accessibility.
10
 
53
  * Click on 'Create'
54
 
55
  3. On the next page (or when there is no next page, click on your Project's name):
 
56
  * Scroll down to YouTube Data API v3 and click on it
57
+ * Click on 'ENABLE' at the top to enable the API
58
  * Optionally disable other API's
59
 
60
  4. In the sidebar on the left:
61
  * Click on 'Credentials'
62
+ * Click on 'Create Credential' at the top.
63
  * Click on 'API key'
64
  * Set as little restrictions as possible, most problems with getting this working are caused by these settings.
65
  * Click on 'Create'
79
  LYTE by default uses WordPress' "the_content"-filter. Page builders don't apply that filter to their content and thus LYTE does not get triggered on those. As a workaround you can either add the LYTE widget or add the LYTE video using the shortcode in your page-builder Text-block, this works in most page-builders.
80
 
81
  = Can I use WP YouTube Lyte for a custom field? =
82
+ Just pass the httpv url of such a field to lyte_preparse like this:
83
  `if(function_exists('lyte_preparse')) { echo lyte_preparse($video); }`
84
  and you're good to go!
85
 
93
  * Google will not always display the thumbnail, this presumably depends of the relevance of the video to the rest of the page.
94
 
95
  = How does captions-support get added to the microdata? =
96
+ In January 2014 [Benetech](http://benetech.org/), a U.S. nonprofit that develops and uses technology to create positive social change, offered a patch that adds the [accessibilityFeature property](http://schema.org/accessibilityFeature) to the microdata for videos that have captions. If you have microdata enabled, WP YouTube Lyte will automatically try to check (in a seperate, asynchronous call via a proxy-webservice, as YouTube only offers captions in their API v3 which requires authentication) if captions are available and if so, adds the accessibilityFeature property with value captions to the microdata. This can be disabled by either disabling microdata or, if you want microdata but not the accessibilityFeature-property by using the "lyte_docaptions"-filter to set captions to false (example-code is in lyte_helper.php_example).
97
 
98
  = Responsive LYTE embeds =
99
  * The video width in posts and pages will adapt to the width of the container (the div) in which your blogposts/ pages are shown. This means that if your theme is responsive, WP YouTube Lyte will follow.
135
 
136
  == Changelog ==
137
 
138
+ = 1.7.8 =
139
+ * misc. improvements to prevent structured data warnings from Google.
140
+ * fix breaking locally cached thumbnails when mime_content_type function is not available.
141
+ * tested with WordPress 5.3 (beta 3).
142
+
143
  = 1.7.7 =
144
+ * bugfix: avoid having to click play twice in Chrome (due to autoplay not working).
145
 
146
  = 1.7.6 =
147
  * improvement: extra parameters for shortcode (start, showinfo, stepsize and hqthumb).
wp-youtube-lyte.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: WP YouTube Lyte
4
  Plugin URI: http://blog.futtta.be/wp-youtube-lyte/
5
  Description: Lite and accessible YouTube audio and video embedding.
6
  Author: Frank Goossens (futtta)
7
- Version: 1.7.7
8
  Author URI: http://blog.futtta.be/
9
  Text Domain: wp-youtube-lyte
10
  Domain Path: /languages
@@ -13,7 +13,7 @@ Domain Path: /languages
13
  if ( ! defined( 'ABSPATH' ) ) exit;
14
 
15
  $debug=false;
16
- $lyte_version="1.7.7";
17
  $lyte_db_version=get_option('lyte_version','none');
18
 
19
  /** have we updated? */
@@ -83,7 +83,10 @@ add_action('after_setup_theme','lyte_settings_enforcer');
83
  function lyte_parse($the_content,$doExcerpt=false) {
84
  /** bail if amp */
85
  if ( is_amp()) { return str_replace( 'httpv://', 'https://', $the_content ); }
86
-
 
 
 
87
  /** main function to parse the content, searching and replacing httpv-links */
88
  global $lyteSettings, $toCache_index, $postID, $cachekey;
89
  $lyteSettings['path']=plugins_url() . "/" . dirname(plugin_basename(__FILE__)) . '/lyte/';
@@ -94,12 +97,12 @@ function lyte_parse($the_content,$doExcerpt=false) {
94
  $the_content = apply_filters( 'lyte_content_preparse',$the_content );
95
 
96
  if ( get_option('lyte_greedy','1')==="1" && strpos($the_content,"youtu") !== false ){
97
- // only preg_replace if "youtu" (as part of youtube.com or youtu.be) if found
98
  if (strpos($the_content,'/playlist?list=') !== false ) {
99
  // only preg_replace for playlists if there are playlists to be parsed
100
- $the_content=preg_replace('/^https?:\/\/(www.)?youtu(be.com|.be)\/playlist\?list=/m','httpv://www.youtube.com/playlist?list=',$the_content);
101
  }
102
- $the_content=preg_replace('/^https?:\/\/(www.)?youtu(be.com|.be)\/(watch\?v=)?/m','httpv://www.youtube.com/watch?v=',$the_content);
103
 
104
  // new: also replace original YT embed code (iframes)
105
  if ( apply_filters( 'lyte_eats_yframes', true ) && preg_match_all('#<iframe(?:[^<]*)?\ssrc=["|\']https:\/\/www\.youtube(?:-nocookie)?\.com\/embed\/(.*)["|\'](?:.*)><\/iframe>#Usm', $the_content, $matches, PREG_SET_ORDER)) {
@@ -323,14 +326,14 @@ function lyte_parse($the_content,$doExcerpt=false) {
323
  $thumbUrl="//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
324
  }
325
  }
 
 
 
 
326
  } else {
327
- // no useable result from youtube, fallback on video thumbnail (doesn't work on playlist)
328
  $thumbUrl = "//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
329
  }
330
- } else {
331
- // same fallback
332
- $thumbUrl = "//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
333
- }
334
 
335
  // do we have to serve the thumbnail from local cache?
336
  if (get_option('lyte_local_thumb','0') === '1') {
@@ -340,12 +343,34 @@ function lyte_parse($the_content,$doExcerpt=false) {
340
  /** API: filter hook to override thumbnail URL */
341
  $thumbUrl = apply_filters( 'lyte_match_thumburl', $thumbUrl, $vid );
342
 
 
 
 
 
 
 
 
 
343
  if ($audio===true) {
344
- $wrapper="<div class=\"lyte-wrapper-audio\" style=\"width:".$lyteSettings[2]."px;max-width:100%;overflow:hidden;height:38px;".$lyteSettings['pos']."\">";
345
  } else {
346
- $wrapper="<div class=\"lyte-wrapper".$lyteSettings['ratioClass']."\" style=\"width:".$lyteSettings[2]."px;max-width: 100%;".$lyteSettings['pos']."\">";
347
  }
348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  if ($doExcerpt) {
350
  $lytetemplate="";
351
  $templateType="excerpt";
@@ -354,14 +379,14 @@ function lyte_parse($the_content,$doExcerpt=false) {
354
  $textLink = ($lyteSettings['links']===0)? "" : "<br />".strip_tags($lytelinks_txt, '<a>')."<br />";
355
  $lytetemplate = "<a href=\"".$postURL."\"><img src=\"".$thumbUrl."\" alt=\"YouTube Video\"></a>".$textLink;
356
  $templateType="feed";
357
- } elseif (($audio !== true) && ( $plClass !== " playlist") && (($lyteSettings['microdata'] === "1")&&($noMicroData !== "1" ))) {
358
- $lytetemplate = $wrapper."<div class=\"lyMe".$audioClass.$hidefClass.$plClass.$qsaClass."\" id=\"WYL_".$vid."\" itemprop=\"video\" itemscope itemtype=\"https://schema.org/VideoObject\"><meta itemprop=\"thumbnailUrl\" content=\"".$thumbUrl."\" /><meta itemprop=\"embedURL\" content=\"https://www.youtube.com/embed/".$vid."\" /><meta itemprop=\"uploadDate\" content=\"".$yt_resp_array["dateField"]."\" />".$captionsMeta."<div id=\"lyte_".$vid."\" data-src=\"".$thumbUrl."\" class=\"pL\"><div class=\"tC".$titleClass."\"><div class=\"tT\" itemprop=\"name\">".$yt_resp_array["title"]."</div></div><div class=\"play\"></div><div class=\"ctrl\"><div class=\"Lctrl\"></div><div class=\"Rctrl\"></div></div></div>".$noscript."<meta itemprop=\"description\" content=\"".$yt_resp_array["description"]."\"></div></div>".$lytelinks_txt;
359
  $templateType="postMicrodata";
360
  } else {
361
  $lytetemplate = $wrapper."<div class=\"lyMe".$audioClass.$hidefClass.$plClass.$qsaClass."\" id=\"WYL_".$vid."\"><div id=\"lyte_".$vid."\" data-src=\"".$thumbUrl."\" class=\"pL\">";
362
 
363
- if (isset($yt_resp_array) && !empty($yt_resp_array) && !empty($yt_resp_array["title"])) {
364
- $lytetemplate .= "<div class=\"tC".$titleClass."\"><div class=\"tT\">".$yt_resp_array['title']."</div></div>";
365
  }
366
 
367
  $lytetemplate .= "<div class=\"play\"></div><div class=\"ctrl\"><div class=\"Lctrl\"></div><div class=\"Rctrl\"></div></div></div>".$noscript."</div></div>".$lytelinks_txt;
@@ -529,7 +554,13 @@ function lyte_get_YT_resp($vid,$playlist=false,$cachekey,$apiTestKey="",$isWidge
529
  $_thisLyte['captions_timestamp'] = strtotime("now");
530
  }
531
  }
532
-
 
 
 
 
 
 
533
  // try to cache the result
534
  if ( (($postID) || ($isWidget)) && !empty($_thisLyte) && empty($apiTestKey) ) {
535
  $_thisLyte['lyte_date_added']=time();
4
  Plugin URI: http://blog.futtta.be/wp-youtube-lyte/
5
  Description: Lite and accessible YouTube audio and video embedding.
6
  Author: Frank Goossens (futtta)
7
+ Version: 1.7.8
8
  Author URI: http://blog.futtta.be/
9
  Text Domain: wp-youtube-lyte
10
  Domain Path: /languages
13
  if ( ! defined( 'ABSPATH' ) ) exit;
14
 
15
  $debug=false;
16
+ $lyte_version="1.7.8";
17
  $lyte_db_version=get_option('lyte_version','none');
18
 
19
  /** have we updated? */
83
  function lyte_parse($the_content,$doExcerpt=false) {
84
  /** bail if amp */
85
  if ( is_amp()) { return str_replace( 'httpv://', 'https://', $the_content ); }
86
+
87
+ /** bail if LYTE feed disabled and is_feed */
88
+ if ( apply_filters( 'lyte_filter_dofeed', true ) === false && is_feed() ) { return str_replace( 'httpv://', 'https://', $the_content ); }
89
+
90
  /** main function to parse the content, searching and replacing httpv-links */
91
  global $lyteSettings, $toCache_index, $postID, $cachekey;
92
  $lyteSettings['path']=plugins_url() . "/" . dirname(plugin_basename(__FILE__)) . '/lyte/';
97
  $the_content = apply_filters( 'lyte_content_preparse',$the_content );
98
 
99
  if ( get_option('lyte_greedy','1')==="1" && strpos($the_content,"youtu") !== false ){
100
+ // only preg_replace if "youtu" (as part of youtube.com or youtu.be) is found
101
  if (strpos($the_content,'/playlist?list=') !== false ) {
102
  // only preg_replace for playlists if there are playlists to be parsed
103
+ $the_content=preg_replace('/^(?:<p>)?https?:\/\/(www.)?youtu(be.com|.be)\/playlist\?list=/m','httpv://www.youtube.com/playlist?list=',$the_content);
104
  }
105
+ $the_content=preg_replace('/^(?:<p>)?https?:\/\/(www.)?youtu(be.com|.be)\/(watch\?v=)?/m','httpv://www.youtube.com/watch?v=',$the_content);
106
 
107
  // new: also replace original YT embed code (iframes)
108
  if ( apply_filters( 'lyte_eats_yframes', true ) && preg_match_all('#<iframe(?:[^<]*)?\ssrc=["|\']https:\/\/www\.youtube(?:-nocookie)?\.com\/embed\/(.*)["|\'](?:.*)><\/iframe>#Usm', $the_content, $matches, PREG_SET_ORDER)) {
326
  $thumbUrl="//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
327
  }
328
  }
329
+ } else {
330
+ // no useable result from youtube, fallback on video thumbnail (doesn't work on playlist)
331
+ $thumbUrl = "//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
332
+ }
333
  } else {
334
+ // same fallback
335
  $thumbUrl = "//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
336
  }
 
 
 
 
337
 
338
  // do we have to serve the thumbnail from local cache?
339
  if (get_option('lyte_local_thumb','0') === '1') {
343
  /** API: filter hook to override thumbnail URL */
344
  $thumbUrl = apply_filters( 'lyte_match_thumburl', $thumbUrl, $vid );
345
 
346
+ if (isset($yt_resp_array) && !empty($yt_resp_array) && !empty($yt_resp_array["title"])) {
347
+ $_this_title = $yt_resp_array["title"];
348
+ $_this_title_tag = ' title="'.htmlentities( $_this_title ).'"';
349
+ } else {
350
+ $_this_title = false;
351
+ $_this_title_tag = '';
352
+ }
353
+
354
  if ($audio===true) {
355
+ $wrapper="<div class=\"lyte-wrapper-audio\"".$_this_title_tag." style=\"width:".$lyteSettings[2]."px;max-width:100%;overflow:hidden;height:38px;".$lyteSettings['pos']."\">";
356
  } else {
357
+ $wrapper="<div class=\"lyte-wrapper".$lyteSettings['ratioClass']."\"".$_this_title_tag." style=\"width:".$lyteSettings[2]."px;max-width: 100%;".$lyteSettings['pos']."\">";
358
  }
359
 
360
+ // do we have usable microdata fiels from the YT API, if not no microdata below.
361
+ foreach ( array( 'title', 'description','dateField' ) as $resp_key ) {
362
+ if ( empty( $yt_resp_array[$resp_key] ) ) {
363
+ $noMicroData = '1';
364
+ break;
365
+ }
366
+ }
367
+
368
+ // do we have a YT API key, if not; no microdata below.
369
+ $lyte_yt_api_key = apply_filters( 'lyte_filter_yt_api_key', get_option( 'lyte_yt_api_key', '' ) );
370
+ if ( $lyte_yt_api_key === "none" || empty( $lyte_yt_api_key ) ) {
371
+ $noMicroData = '1';
372
+ }
373
+
374
  if ($doExcerpt) {
375
  $lytetemplate="";
376
  $templateType="excerpt";
379
  $textLink = ($lyteSettings['links']===0)? "" : "<br />".strip_tags($lytelinks_txt, '<a>')."<br />";
380
  $lytetemplate = "<a href=\"".$postURL."\"><img src=\"".$thumbUrl."\" alt=\"YouTube Video\"></a>".$textLink;
381
  $templateType="feed";
382
+ } elseif ( $audio !== true && $plClass !== " playlist" && $lyteSettings['microdata'] === "1" && $noMicroData !== "1" ) {
383
+ $lytetemplate = $wrapper."<div class=\"lyMe".$audioClass.$hidefClass.$plClass.$qsaClass."\" id=\"WYL_".$vid."\" itemprop=\"video\" itemscope itemtype=\"https://schema.org/VideoObject\"><div><meta itemprop=\"thumbnailUrl\" content=\"".$thumbUrl."\" /><meta itemprop=\"embedURL\" content=\"https://www.youtube.com/embed/".$vid."\" /><meta itemprop=\"uploadDate\" content=\"".$yt_resp_array["dateField"]."\" /></div>".$captionsMeta."<div id=\"lyte_".$vid."\" data-src=\"".$thumbUrl."\" class=\"pL\"><div class=\"tC".$titleClass."\"><div class=\"tT\" itemprop=\"name\">".$yt_resp_array["title"]."</div></div><div class=\"play\"></div><div class=\"ctrl\"><div class=\"Lctrl\"></div><div class=\"Rctrl\"></div></div></div>".$noscript."<meta itemprop=\"description\" content=\"".$yt_resp_array["description"]."\"></div></div>".$lytelinks_txt;
384
  $templateType="postMicrodata";
385
  } else {
386
  $lytetemplate = $wrapper."<div class=\"lyMe".$audioClass.$hidefClass.$plClass.$qsaClass."\" id=\"WYL_".$vid."\"><div id=\"lyte_".$vid."\" data-src=\"".$thumbUrl."\" class=\"pL\">";
387
 
388
+ if ( isset( $_this_title ) ) {
389
+ $lytetemplate .= "<div class=\"tC".$titleClass."\"><div class=\"tT\">".$_this_title."</div></div>";
390
  }
391
 
392
  $lytetemplate .= "<div class=\"play\"></div><div class=\"ctrl\"><div class=\"Lctrl\"></div><div class=\"Rctrl\"></div></div></div>".$noscript."</div></div>".$lytelinks_txt;
554
  $_thisLyte['captions_timestamp'] = strtotime("now");
555
  }
556
  }
557
+
558
+ // try to ensure description is never empty to avoid Google structured data test tool complaining about it missing.
559
+ if ( ! array_key_exists( 'description', $_thisLyte ) || empty( $_thisLyte['description'] ) ) {
560
+ $_thisLyte['description'] = $_thisLyte['title'];
561
+ }
562
+ $_thisLyte['description'] = apply_filters( 'lyte_ytapi_description', $_thisLyte['description'] );
563
+
564
  // try to cache the result
565
  if ( (($postID) || ($isWidget)) && !empty($_thisLyte) && empty($apiTestKey) ) {
566
  $_thisLyte['lyte_date_added']=time();