WP YouTube Lyte - Version 1.7.12

Version Description

  • fix for dash becoming double dash
  • move lyteThumbs.php to lyteCache.php because security solutions generally are traumatized by all things thumbs
  • add expiry for cached thumbnails (3 days) to ensure they are updated if the original image got changed
  • some other smaller changes, see https://github.com/futtta/wp-youtube-lyte/commits/main
Download this release

Release Info

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

Code changes from version 1.7.11 to 1.7.12

lyteThumbs.php → lyteCache.php RENAMED
@@ -19,7 +19,7 @@ error_reporting(0);
19
 
20
  if ( ! defined( 'LYTE_CACHE_DIR' ) ) {
21
  define( 'WP_CONTENT_DIR', dirname( dirname( __DIR__ ) ) );
22
- define( 'LYTE_CACHE_CHILD_DIR', 'cache/lyteThumbs' );
23
  define( 'LYTE_CACHE_DIR', WP_CONTENT_DIR .'/'. LYTE_CACHE_CHILD_DIR );
24
  }
25
 
@@ -79,12 +79,20 @@ if ( strpos($origThumbURL,'http') !== 0 && strpos($origThumbURL,'//') === 0 ) {
79
  }
80
 
81
  $localThumb = LYTE_CACHE_DIR . '/' . md5($origThumbURL) . ".jpg";
 
 
82
 
83
- if ( !file_exists($localThumb) || $lyte_thumb_dontsave ) {
84
  $thumbContents = lyte_get_thumb($origThumbURL);
85
 
86
- if ( $thumbContents != "" && !$lyte_thumb_dontsave ) {
87
- file_put_contents($localThumb, $thumbContents);
 
 
 
 
 
 
88
  }
89
  }
90
 
@@ -130,9 +138,15 @@ if ( $thumbContents != "") {
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;
@@ -174,6 +188,7 @@ function lyte_str_ends_in($haystack,$needle) {
174
  }
175
 
176
  function lyte_get_thumb($thumbUrl) {
 
177
  global $lyte_thumb_error;
178
  if (function_exists("curl_init")) {
179
  $curl = curl_init();
19
 
20
  if ( ! defined( 'LYTE_CACHE_DIR' ) ) {
21
  define( 'WP_CONTENT_DIR', dirname( dirname( __DIR__ ) ) );
22
+ define( 'LYTE_CACHE_CHILD_DIR', 'cache/lyteCache' );
23
  define( 'LYTE_CACHE_DIR', WP_CONTENT_DIR .'/'. LYTE_CACHE_CHILD_DIR );
24
  }
25
 
79
  }
80
 
81
  $localThumb = LYTE_CACHE_DIR . '/' . md5($origThumbURL) . ".jpg";
82
+ $expiryTime = filemtime( $localThumb ) + 3*24*60*60; // images can be cached for 3 days.
83
+ $now = time();
84
 
85
+ if ( !file_exists( $localThumb ) || $lyte_thumb_dontsave || ( file_exists( $localThumb ) && $expiryTime < $now ) ) {
86
  $thumbContents = lyte_get_thumb($origThumbURL);
87
 
88
+ if ( $thumbContents != '' && ! $lyte_thumb_dontsave ) {
89
+ // save file but immediately check if it is a jpeg and delete if not.
90
+ file_put_contents( $localThumb, $thumbContents );
91
+ if ( ! is_jpeg( $localThumb ) ) {
92
+ unlink( $localThumb );
93
+ $thumbContents = '';
94
+ $lyte_thumb_error .= 'deleted as not jpeg/ ';
95
+ }
96
  }
97
  }
98
 
138
  * helper functions
139
  */
140
  function is_jpeg( $in ) {
141
+ // reliable checks based on exif/ mime type.
142
+ if ( function_exists( 'exif_imagetype' ) && exif_imagetype( $in ) === IMAGETYPE_JPEG ) {
143
+ return true;
144
+ } else if ( function_exists( 'mime_content_type' ) && mime_content_type( $in ) === 'image/jpeg' ) {
145
  return true;
146
+ }
147
+
148
+ // only rely on file extension if exif/mime functions are not available.
149
+ if ( ! function_exists( 'exif_imagetype' ) && ! function_exists( 'mime_content_type' ) && ( strpos( $in, '.jpg' ) === strlen( $in ) -4 ) ) {
150
  return true;
151
  } else {
152
  return false;
188
  }
189
 
190
  function lyte_get_thumb($thumbUrl) {
191
+ error_log('getting '.$thumbUrl);
192
  global $lyte_thumb_error;
193
  if (function_exists("curl_init")) {
194
  $curl = curl_init();
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.3
7
- Stable tag: 1.7.11
8
 
9
  High performance YouTube video, playlist and audio-only embeds which don't slow down your blog and offer optimal accessibility.
10
 
@@ -135,6 +135,12 @@ Just tell me, I like the feedback! Use the [Contact-page on my blog](http://blog
135
 
136
  == Changelog ==
137
 
 
 
 
 
 
 
138
  = 1.7.11 =
139
  * fix playlist that got broken due to the priority change (from 4 to 10)
140
  * add is_amp (and is_feed) checks to the new lyte_prepare function (which runs at priority 4)
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.5
7
+ Stable tag: 1.7.12
8
 
9
  High performance YouTube video, playlist and audio-only embeds which don't slow down your blog and offer optimal accessibility.
10
 
135
 
136
  == Changelog ==
137
 
138
+ = 1.7.12 =
139
+ * fix for dash becoming double dash
140
+ * move lyteThumbs.php to lyteCache.php because security solutions generally are traumatized by all things thumbs
141
+ * add expiry for cached thumbnails (3 days) to ensure they are updated if the original image got changed
142
+ * some other smaller changes, see https://github.com/futtta/wp-youtube-lyte/commits/main
143
+
144
  = 1.7.11 =
145
  * fix playlist that got broken due to the priority change (from 4 to 10)
146
  * add is_amp (and is_feed) checks to the new lyte_prepare function (which runs at priority 4)
widget.php CHANGED
@@ -47,7 +47,7 @@ class WYLWidget extends WP_Widget {
47
 
48
  // do we have to serve the thumbnail from local cache?
49
  if (get_option('lyte_local_thumb','0') === '1') {
50
- $WYLthumb = plugins_url( 'lyteThumbs.php?origThumbUrl=' . urlencode($WYLthumb) , __FILE__ );
51
  }
52
 
53
  // filter to alter the thumbnail
@@ -79,7 +79,7 @@ class WYLWidget extends WP_Widget {
79
  lyte_initer();
80
  }
81
 
82
- function update($new_instance, $old_instance) {
83
  $instance = $old_instance;
84
  $instance['WYLtitle'] = strip_tags($new_instance['WYLtitle']);
85
  $instance['WYLurl'] = strip_tags($new_instance['WYLurl']);
@@ -141,7 +141,7 @@ class WYLWidget extends WP_Widget {
141
  } else {
142
  $selected="";
143
  }
144
-
145
  if ($wSize[$x]['depr']!==true) {
146
  echo "<option value=\"".$x."\"".$selected.">".$wSize[$x]['w']."X".$wSize[$x]['h']."</option>";
147
  }
@@ -167,9 +167,9 @@ class WYLWidget extends WP_Widget {
167
  </label></p>
168
  <p><label for="<?php echo $this->get_field_id('WYLurl'); ?>"><?php _e("Youtube-URL:","wp-youtube-lyte") ?> <input class="widefat" id="<?php echo $this->get_field_id('WYLurl'); ?>" name="<?php echo $this->get_field_name('WYLurl'); ?>" type="text" value="<?php echo $WYLurl; ?>" /></label></p>
169
  <p><label for="<?php echo $this->get_field_id('WYLtext'); ?>"><?php _e("Text:","wp-youtube-lyte") ?> <textarea class="widefat" id="<?php echo $this->get_field_id('WYLtext'); ?>" name="<?php echo $this->get_field_name('WYLtext'); ?>" rows="16" cols="20"><?php echo $WYLtext; ?></textarea></label></p>
170
- <?php
171
  }
172
- }
173
 
174
  function lyte_register_widget() {
175
  register_widget('WYLWidget');
47
 
48
  // do we have to serve the thumbnail from local cache?
49
  if (get_option('lyte_local_thumb','0') === '1') {
50
+ $WYLthumb = plugins_url( 'lyteCache.php?origThumbUrl=' . urlencode($WYLthumb) , __FILE__ );
51
  }
52
 
53
  // filter to alter the thumbnail
79
  lyte_initer();
80
  }
81
 
82
+ function update($new_instance, $old_instance) {
83
  $instance = $old_instance;
84
  $instance['WYLtitle'] = strip_tags($new_instance['WYLtitle']);
85
  $instance['WYLurl'] = strip_tags($new_instance['WYLurl']);
141
  } else {
142
  $selected="";
143
  }
144
+
145
  if ($wSize[$x]['depr']!==true) {
146
  echo "<option value=\"".$x."\"".$selected.">".$wSize[$x]['w']."X".$wSize[$x]['h']."</option>";
147
  }
167
  </label></p>
168
  <p><label for="<?php echo $this->get_field_id('WYLurl'); ?>"><?php _e("Youtube-URL:","wp-youtube-lyte") ?> <input class="widefat" id="<?php echo $this->get_field_id('WYLurl'); ?>" name="<?php echo $this->get_field_name('WYLurl'); ?>" type="text" value="<?php echo $WYLurl; ?>" /></label></p>
169
  <p><label for="<?php echo $this->get_field_id('WYLtext'); ?>"><?php _e("Text:","wp-youtube-lyte") ?> <textarea class="widefat" id="<?php echo $this->get_field_id('WYLtext'); ?>" name="<?php echo $this->get_field_name('WYLtext'); ?>" rows="16" cols="20"><?php echo $WYLtext; ?></textarea></label></p>
170
+ <?php
171
  }
172
+ }
173
 
174
  function lyte_register_widget() {
175
  register_widget('WYLWidget');
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.11
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.11";
17
  $lyte_db_version=get_option('lyte_version','none');
18
 
19
  /** have we updated? */
@@ -28,6 +28,20 @@ if ($lyte_db_version !== $lyte_version) {
28
  lyte_rm_cache();
29
  lyte_not_greedy();
30
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
  update_option('lyte_version',$lyte_version);
33
  $lyte_db_version=$lyte_version;
@@ -97,7 +111,11 @@ function lyte_parse($the_content,$doExcerpt=false) {
97
  // new: also replace original YT embed code (iframes)
98
  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 ) ) {
99
  foreach ( $matches as $match ) {
100
- $the_content = str_replace( $match[0], 'httpv://youtu.be/'.$match[1], $the_content );
 
 
 
 
101
  }
102
  }
103
  }
@@ -106,11 +124,11 @@ function lyte_parse($the_content,$doExcerpt=false) {
106
  if (apply_filters('lyte_remove_wpautop',false)) {
107
  remove_filter('the_content','wpautop');
108
  }
109
- $char_codes = array('&#215;','&#8211;');
110
- $replacements = array("x", "--");
111
  $the_content=str_replace($char_codes, $replacements, $the_content);
112
  $lyte_feed=is_feed();
113
-
114
  $hidefClass = ($lyteSettings['hidef']==="1") ? " hidef" : "";
115
 
116
  $postID = get_the_ID();
@@ -118,7 +136,7 @@ function lyte_parse($the_content,$doExcerpt=false) {
118
 
119
  $lytes_regexp="/(?:<p>)?http(v|a):\/\/([a-zA-Z0-9\-\_]+\.|)(youtube|youtu)(\.com|\.be)\/(((watch(\?v\=|\/v\/)|.+?v\=|)([a-zA-Z0-9\-\_]{11}))|(playlist\?list\=([a-zA-Z0-9\-\_]*)))([^\s<]*)(<?:\/p>)?/";
120
 
121
- preg_match_all($lytes_regexp, $the_content, $matches, PREG_SET_ORDER);
122
 
123
  foreach($matches as $match) {
124
  /** API: filter hook to preparse fragment in a httpv-url, e.g. to force hqThumb=1 or showinfo=0 */
@@ -146,7 +164,7 @@ function lyte_parse($the_content,$doExcerpt=false) {
146
  $noMicroData="1";
147
  }
148
  }
149
-
150
  $qsa="";
151
  if (!empty($showinfo[0])) {
152
  $qsa="&amp;".$showinfo[0];
@@ -218,24 +236,24 @@ function lyte_parse($the_content,$doExcerpt=false) {
218
  }
219
  $thumbUrl = $lyteSettings['scheme']."://i.ytimg.com/vi/".$vid."/0.jpg";
220
  if (get_option('lyte_local_thumb','0') === '1') {
221
- $thumbUrl = plugins_url( 'lyteThumbs.php?origThumbUrl=' . urlencode($thumbUrl) , __FILE__ );
222
  }
223
  $thumbUrl = apply_filters( 'lyte_match_thumburl', $thumbUrl, $vid );
224
  $noscript="<noscript><a href=\"".$lyteSettings['scheme']."://youtu.be/".$vid."\"><img src=\"" . $thumbUrl . "\" alt=\"\" width=\"".$lyteSettings[2]."\" height=\"".$NSimgHeight."\" />".$noscript_post."</a></noscript>";
225
  }
226
-
227
  // add disclaimer to lytelinks
228
  $disclaimer = wp_kses_data( get_option( 'lyte_disclaimer', '') );
229
  if ( !empty( $disclaimer ) ) {
230
  $disclaimer = '<span class="lyte_disclaimer">' . $disclaimer . '</span>';
231
  }
232
-
233
  if ( $disclaimer && empty( $lytelinks_txt ) ) {
234
  $lytelinks_txt = "<div class=\"lL\" style=\"max-width:100%;width:".$lyteSettings[2]."px;".$lyteSettings['pos']."\">".$diclaimer."</div>";
235
  } else if ( $disclaimer ) {
236
  $lytelinks_txt = str_replace('</div>','<br/>'.$disclaimer.'</div>',$lytelinks_txt);
237
  }
238
-
239
  // fetch data from YT api (v2 or v3)
240
  $isPlaylist=false;
241
  if ($plClass===" playlist") {
@@ -251,12 +269,12 @@ function lyte_parse($the_content,$doExcerpt=false) {
251
  // captions, thanks to Benetech
252
  $captionsMeta="";
253
  $doCaptions=true;
254
-
255
  /** API: filter hook to disable captions */
256
  $doCaptions = apply_filters( 'lyte_docaptions', $doCaptions );
257
-
258
  if(($lyteSettings['microdata'] === "1")&&($noMicroData !== "1" )&&($doCaptions === true)) {
259
- if (array_key_exists('captions_data',$yt_resp_array)) {
260
  if ($yt_resp_array["captions_data"]=="true") {
261
  $captionsMeta="<meta itemprop=\"accessibilityFeature\" content=\"captions\" />";
262
  $forceCaptionsUpdate=false;
@@ -267,7 +285,7 @@ function lyte_parse($the_content,$doExcerpt=false) {
267
  $forceCaptionsUpdate=true;
268
  $yt_resp_array["captions_data"]=false;
269
  }
270
-
271
  if ($forceCaptionsUpdate===true) {
272
  $captionsMeta="";
273
  $threshold = 30;
@@ -278,13 +296,13 @@ function lyte_parse($the_content,$doExcerpt=false) {
278
  $cache_timestamp = false;
279
  $interval = $threshold+1;
280
  }
281
-
282
  if(!is_int($cache_timestamp) || ($interval > $threshold && !is_null( $yt_resp_array["captions_data"]))) {
283
  $yt_resp_array['captions_timestamp'] = strtotime("now");
284
  wp_schedule_single_event(strtotime("now") + 60*60, 'schedule_captions_lookup', array($postID, $cachekey, $vid));
285
  $yt_resp_precache=json_encode($yt_resp_array);
286
  $toCache=base64_encode(gzcompress($yt_resp_precache));
287
- update_post_meta($postID, $cachekey, $toCache);
288
  }
289
  }
290
  }
@@ -297,7 +315,10 @@ function lyte_parse($the_content,$doExcerpt=false) {
297
  $thumbUrl=$yt_resp_array["thumbUrl"];
298
  } else {
299
  $thumbUrl="//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
300
- }
 
 
 
301
  }
302
  } else {
303
  // no useable result from youtube, fallback on video thumbnail (doesn't work on playlist)
@@ -310,7 +331,7 @@ function lyte_parse($the_content,$doExcerpt=false) {
310
 
311
  // do we have to serve the thumbnail from local cache?
312
  if (get_option('lyte_local_thumb','0') === '1') {
313
- $thumbUrl = plugins_url( 'lyteThumbs.php?origThumbUrl=' . urlencode($thumbUrl) , __FILE__ );
314
  }
315
 
316
  /** API: filter hook to override thumbnail URL */
@@ -343,17 +364,17 @@ function lyte_parse($the_content,$doExcerpt=false) {
343
  if ( $lyte_yt_api_key === "none" || empty( $lyte_yt_api_key ) ) {
344
  $noMicroData = '1';
345
  }
346
-
347
  if ($doExcerpt) {
348
  $lytetemplate="";
349
  $templateType="excerpt";
350
  } elseif ($lyte_feed) {
351
- $postURL = get_permalink( $postID );
352
  $textLink = ($lyteSettings['links']===0)? "" : "<br />".strip_tags($lytelinks_txt, '<a>')."<br />";
353
  $lytetemplate = "<a href=\"".$postURL."\"><img src=\"".$thumbUrl."\" alt=\"YouTube Video\"></a>".$textLink;
354
  $templateType="feed";
355
  } elseif ( $audio !== true && $plClass !== " playlist" && $lyteSettings['microdata'] === "1" && $noMicroData !== "1" ) {
356
- $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;
357
  $templateType="postMicrodata";
358
  } else {
359
  $lytetemplate = $wrapper."<div class=\"lyMe".$audioClass.$hidefClass.$plClass.$qsaClass."\" id=\"WYL_".$vid."\"><div id=\"lyte_".$vid."\" data-src=\"".$thumbUrl."\" class=\"pL\">";
@@ -361,7 +382,7 @@ function lyte_parse($the_content,$doExcerpt=false) {
361
  if ( isset( $_this_title ) ) {
362
  $lytetemplate .= "<div class=\"tC".$titleClass."\"><div class=\"tT\">".$_this_title."</div></div>";
363
  }
364
-
365
  $lytetemplate .= "<div class=\"play\"></div><div class=\"ctrl\"><div class=\"Lctrl\"></div><div class=\"Rctrl\"></div></div></div>".$noscript."</div></div>".$lytelinks_txt;
366
  $templateType="post";
367
  }
@@ -384,6 +405,9 @@ function lyte_parse($the_content,$doExcerpt=false) {
384
  }
385
  }
386
 
 
 
 
387
  /** API: filter hook to postparse the_content before returning */
388
  $the_content = apply_filters( 'lyte_content_postparse',$the_content );
389
 
@@ -393,8 +417,8 @@ function lyte_parse($the_content,$doExcerpt=false) {
393
  function captions_lookup($postID, $cachekey, $vid) {
394
  // captions lookup at YouTube via a11ymetadata.org
395
  $response = wp_remote_request("http://api.a11ymetadata.org/captions/youtubeid=".$vid."/youtube");
396
-
397
- if(!is_wp_error($response)) {
398
  $rawJson = wp_remote_retrieve_body($response);
399
  $decodeJson = json_decode($rawJson, true);
400
 
@@ -405,16 +429,16 @@ function captions_lookup($postID, $cachekey, $vid) {
405
  if($yt_resp) {
406
  $yt_resp_array=json_decode($yt_resp,true);
407
 
408
- if ($decodeJson['status'] == 'success' && $decodeJson['data']['captions'] == '1') {
409
  $yt_resp_array['captions_data'] = true;
410
- } else {
411
  $yt_resp_array['captions_data'] = false;
412
  }
413
 
414
- $yt_resp_array['captions_timestamp'] = strtotime("now");
415
  $yt_resp_precache=json_encode($yt_resp_array);
416
  $toCache=base64_encode(gzcompress($yt_resp_precache));
417
- update_post_meta($postID, $cachekey, $toCache);
418
  }
419
  }
420
  }
@@ -423,9 +447,9 @@ function captions_lookup($postID, $cachekey, $vid) {
423
  function lyte_get_YT_resp($vid,$playlist=false,$cachekey,$apiTestKey="",$isWidget=false) {
424
  /** logic to get video info from cache or get it from YouTube and set it */
425
  global $postID, $cachekey, $toCache_index;
426
-
427
  $_thisLyte = array();
428
- $yt_error = array();
429
 
430
  if ( $postID && empty($apiTestKey) && !$isWidget ) {
431
  $cache_resp = get_post_meta( $postID, $cachekey, true );
@@ -473,7 +497,7 @@ function lyte_get_YT_resp($vid,$playlist=false,$cachekey,$apiTestKey="",$isWidge
473
  } else {
474
  // v3, feeling somewhat lonely now v2 has gently been put to sleep
475
  $yt_api_base = "https://www.googleapis.com/youtube/v3/";
476
-
477
  if ($playlist) {
478
  $yt_api_target = "playlists?part=snippet%2C+id&id=".$vid."&key=".$lyte_yt_api_key;
479
  } else {
@@ -493,7 +517,7 @@ function lyte_get_YT_resp($vid,$playlist=false,$cachekey,$apiTestKey="",$isWidge
493
  return $yt_error;
494
  }
495
  } else {
496
- $yt_resp_array = (array) json_decode(wp_remote_retrieve_body($yt_resp),true);
497
  if(is_array($yt_resp_array)) {
498
  // extract relevant data
499
  // v3
@@ -589,11 +613,11 @@ function lyte_init() {
589
  } else {
590
  $mobJS = "var mOs=navigator.userAgent.match(/(iphone|ipad|ipod|android)/i);";
591
  }
592
-
593
  /** API: filter hook to change css */
594
  $lyte_css = apply_filters( 'lyte_css', $lyte_css);
595
-
596
- echo "<script type=\"text/javascript\">var bU='".$lyteSettings['path']."';".$mobJS."style = document.createElement('style');style.type = 'text/css';rules = document.createTextNode(\"".$lyte_css."\" );if(style.styleSheet) { style.styleSheet.cssText = rules.nodeValue;} else {style.appendChild(rules);}document.getElementsByTagName('head')[0].appendChild(style);</script>";
597
  echo "<script type=\"text/javascript\" async src=\"".$lyteSettings['path'].$lyteSettings['file']."\"></script>";
598
  }
599
 
@@ -655,7 +679,7 @@ function lyte_rm_cache() {
655
  // remove thumbnail cache
656
  if (get_option('lyte_local_thumb','0') === '1') {
657
  if ( ! defined( 'LYTE_CACHE_DIR' ) ) {
658
- define( 'LYTE_CACHE_CHILD_DIR', 'cache/lyteThumbs' );
659
  define( 'LYTE_CACHE_DIR', WP_CONTENT_DIR .'/'. LYTE_CACHE_CHILD_DIR );
660
  }
661
  array_map('unlink', glob(LYTE_CACHE_DIR . "/*"));
@@ -664,7 +688,7 @@ function lyte_rm_cache() {
664
  // and remove cached YT data from postmeta
665
  try {
666
  ini_set('max_execution_time',90); // give PHP some more time for this, post-meta can be sloooooow
667
-
668
  // cache in post_meta, for posts
669
  $lyte_posts = json_decode(get_option("lyte_cache_index"),true);
670
  $lyteCacheIterator = 0;
@@ -684,16 +708,35 @@ function lyte_rm_cache() {
684
  }
685
  update_option("lyte_cache_index",json_encode($lyte_posts));
686
  }
687
-
688
  // and the widget cache which isn't in post_meta
689
  update_option('lyte_widget_cache','');
690
-
691
  return $returnCode;
692
  } catch(Exception $e) {
693
  return $e->getMessage();
694
  }
695
  }
696
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
697
  /** function to call from within themes */
698
  /* use with e.g. : <?php if(function_exists('lyte_preparse')) { echo lyte_preparse($videoId); } ?> */
699
  function lyte_preparse($videoId) {
@@ -708,7 +751,7 @@ function lyte_add_action_link($links) {
708
  /** is_amp, but I shouldn't have to do this, should I? */
709
  if (!function_exists("is_amp")) {
710
  function is_amp() {
711
- if ( function_exists('is_amp_endpoint') ) {
712
  return is_amp_endpoint();
713
  } else if ( function_exists('ampforwp_is_amp_endpoint') ) {
714
  return ampforwp_is_amp_endpoint();
@@ -728,18 +771,18 @@ function lyte_prepare( $the_content ) {
728
  if ( apply_filters( 'lyte_filter_do_gutenberg', true ) && strpos( $the_content, "<!-- wp:" ) !== false && strpos( $the_content, "youtu" ) !== false ) {
729
  /*
730
  * do Gutenberg stuff here, playlists if needed first and then single videos
731
- *
732
  * having Gutenberg markup in HTML comments is ugly as hell
733
  * esp. for 3rd parties such as Lyte who have to parse info out of that
734
- *
735
  * Luke Cavanagh; thanks for the Gutenbeard reference and for the funny animated gif :)
736
  * https://media1.giphy.com/media/l2QZTNMFTQ2Z00zHG/giphy.gif
737
  */
738
  if ( strpos( $the_content, '/playlist?list=' ) !== false ) {
739
- $gutenbeard_playlist_regex = '%<\!--\s?wp:(?:core[-|/])?embed(?:/youtube)?\s?{"url":"https://www.youtube.com/playlist\?list=(.*)"(?:.*)?}\s?-->.*(?:<figcaption>(.*)</figcaption>)?<\!--\s?/wp:(?:core[-|/])?embed(?:/youtube)?\s?-->%Us';
740
  $the_content = preg_replace($gutenbeard_playlist_regex, '<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube">httpv://www.youtube.com/playlist?list=\1<figcaption>\2</figcaption></figure>',$the_content);
741
  }
742
- $gutenbeard_single_regex = '%<\!--\s?wp:(?:core[-|/])?embed(?:/youtube)?\s?{"url":"https?://(?:www\.)?youtu(?:be\.com/watch\?v=|.be/)(.*)"(?:.*)?}\s?-->.*(?:<figcaption>(.*)</figcaption>)?<\!--\s?/wp:(?:core[-|/])?embed(?:/youtube)?\s?-->%Us';
743
  $the_content = preg_replace($gutenbeard_single_regex, '<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube">httpv://www.youtube.com/watch?v=\1<figcaption>\2</figcaption></figure>',$the_content);
744
  }
745
 
@@ -752,7 +795,7 @@ function lyte_prepare( $the_content ) {
752
  }
753
  // and lastly normal single embeds.
754
  $the_content = preg_replace( '/^(?:<p>)?https?:\/\/(www.)?youtu(be.com|.be)\/(watch\?v=)?/m', 'httpv://www.youtube.com/watch?v=', $the_content );
755
- }
756
  return $the_content;
757
  }
758
 
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.12
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.12";
17
  $lyte_db_version=get_option('lyte_version','none');
18
 
19
  /** have we updated? */
28
  lyte_rm_cache();
29
  lyte_not_greedy();
30
  break;
31
+ case "1.7.0":
32
+ case "1.7.1":
33
+ case "1.7.2":
34
+ case "1.7.3":
35
+ case "1.7.4":
36
+ case "1.7.5":
37
+ case "1.7.6":
38
+ case "1.7.7":
39
+ case "1.7.8":
40
+ case "1.7.9":
41
+ case "1.7.10":
42
+ case "1.7.11":
43
+ lyte_mv_cache();
44
+ break;
45
  }
46
  update_option('lyte_version',$lyte_version);
47
  $lyte_db_version=$lyte_version;
111
  // new: also replace original YT embed code (iframes)
112
  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 ) ) {
113
  foreach ( $matches as $match ) {
114
+ if ( strpos( $match[1], 'videoseries' ) === false) {
115
+ $the_content = str_replace( $match[0], 'httpv://youtu.be/'.$match[1], $the_content );
116
+ } else {
117
+ $the_content = str_replace( $match[0], 'httpv://youtube.com/playlist?list=' . str_replace( 'videoseries?list=', '', $match[1] ), $the_content );
118
+ }
119
  }
120
  }
121
  }
124
  if (apply_filters('lyte_remove_wpautop',false)) {
125
  remove_filter('the_content','wpautop');
126
  }
127
+ $char_codes = array('&#215;','&#8211;','\u002d');
128
+ $replacements = array("x", "--", "-");
129
  $the_content=str_replace($char_codes, $replacements, $the_content);
130
  $lyte_feed=is_feed();
131
+
132
  $hidefClass = ($lyteSettings['hidef']==="1") ? " hidef" : "";
133
 
134
  $postID = get_the_ID();
136
 
137
  $lytes_regexp="/(?:<p>)?http(v|a):\/\/([a-zA-Z0-9\-\_]+\.|)(youtube|youtu)(\.com|\.be)\/(((watch(\?v\=|\/v\/)|.+?v\=|)([a-zA-Z0-9\-\_]{11}))|(playlist\?list\=([a-zA-Z0-9\-\_]*)))([^\s<]*)(<?:\/p>)?/";
138
 
139
+ preg_match_all($lytes_regexp, $the_content, $matches, PREG_SET_ORDER);
140
 
141
  foreach($matches as $match) {
142
  /** API: filter hook to preparse fragment in a httpv-url, e.g. to force hqThumb=1 or showinfo=0 */
164
  $noMicroData="1";
165
  }
166
  }
167
+
168
  $qsa="";
169
  if (!empty($showinfo[0])) {
170
  $qsa="&amp;".$showinfo[0];
236
  }
237
  $thumbUrl = $lyteSettings['scheme']."://i.ytimg.com/vi/".$vid."/0.jpg";
238
  if (get_option('lyte_local_thumb','0') === '1') {
239
+ $thumbUrl = plugins_url( 'lyteCache.php?origThumbUrl=' . urlencode($thumbUrl) , __FILE__ );
240
  }
241
  $thumbUrl = apply_filters( 'lyte_match_thumburl', $thumbUrl, $vid );
242
  $noscript="<noscript><a href=\"".$lyteSettings['scheme']."://youtu.be/".$vid."\"><img src=\"" . $thumbUrl . "\" alt=\"\" width=\"".$lyteSettings[2]."\" height=\"".$NSimgHeight."\" />".$noscript_post."</a></noscript>";
243
  }
244
+
245
  // add disclaimer to lytelinks
246
  $disclaimer = wp_kses_data( get_option( 'lyte_disclaimer', '') );
247
  if ( !empty( $disclaimer ) ) {
248
  $disclaimer = '<span class="lyte_disclaimer">' . $disclaimer . '</span>';
249
  }
250
+
251
  if ( $disclaimer && empty( $lytelinks_txt ) ) {
252
  $lytelinks_txt = "<div class=\"lL\" style=\"max-width:100%;width:".$lyteSettings[2]."px;".$lyteSettings['pos']."\">".$diclaimer."</div>";
253
  } else if ( $disclaimer ) {
254
  $lytelinks_txt = str_replace('</div>','<br/>'.$disclaimer.'</div>',$lytelinks_txt);
255
  }
256
+
257
  // fetch data from YT api (v2 or v3)
258
  $isPlaylist=false;
259
  if ($plClass===" playlist") {
269
  // captions, thanks to Benetech
270
  $captionsMeta="";
271
  $doCaptions=true;
272
+
273
  /** API: filter hook to disable captions */
274
  $doCaptions = apply_filters( 'lyte_docaptions', $doCaptions );
275
+
276
  if(($lyteSettings['microdata'] === "1")&&($noMicroData !== "1" )&&($doCaptions === true)) {
277
+ if ( array_key_exists( 'captions_data', $yt_resp_array ) && is_int( $yt_resp_array["captions_timestamp"] ) ) {
278
  if ($yt_resp_array["captions_data"]=="true") {
279
  $captionsMeta="<meta itemprop=\"accessibilityFeature\" content=\"captions\" />";
280
  $forceCaptionsUpdate=false;
285
  $forceCaptionsUpdate=true;
286
  $yt_resp_array["captions_data"]=false;
287
  }
288
+
289
  if ($forceCaptionsUpdate===true) {
290
  $captionsMeta="";
291
  $threshold = 30;
296
  $cache_timestamp = false;
297
  $interval = $threshold+1;
298
  }
299
+
300
  if(!is_int($cache_timestamp) || ($interval > $threshold && !is_null( $yt_resp_array["captions_data"]))) {
301
  $yt_resp_array['captions_timestamp'] = strtotime("now");
302
  wp_schedule_single_event(strtotime("now") + 60*60, 'schedule_captions_lookup', array($postID, $cachekey, $vid));
303
  $yt_resp_precache=json_encode($yt_resp_array);
304
  $toCache=base64_encode(gzcompress($yt_resp_precache));
305
+ update_post_meta($postID, $cachekey, $toCache);
306
  }
307
  }
308
  }
315
  $thumbUrl=$yt_resp_array["thumbUrl"];
316
  } else {
317
  $thumbUrl="//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
318
+ }
319
+ }
320
+ if ( strpos( $noscript, 'alt=""' ) !== false && array_key_exists( 'title', $yt_resp_array ) ) {
321
+ $noscript = str_replace( 'alt=""', 'alt="' . htmlentities( $yt_resp_array["title"] ). '"', $noscript );
322
  }
323
  } else {
324
  // no useable result from youtube, fallback on video thumbnail (doesn't work on playlist)
331
 
332
  // do we have to serve the thumbnail from local cache?
333
  if (get_option('lyte_local_thumb','0') === '1') {
334
+ $thumbUrl = plugins_url( 'lyteCache.php?origThumbUrl=' . urlencode($thumbUrl) , __FILE__ );
335
  }
336
 
337
  /** API: filter hook to override thumbnail URL */
364
  if ( $lyte_yt_api_key === "none" || empty( $lyte_yt_api_key ) ) {
365
  $noMicroData = '1';
366
  }
367
+
368
  if ($doExcerpt) {
369
  $lytetemplate="";
370
  $templateType="excerpt";
371
  } elseif ($lyte_feed) {
372
+ $postURL = get_permalink( $postID );
373
  $textLink = ($lyteSettings['links']===0)? "" : "<br />".strip_tags($lytelinks_txt, '<a>')."<br />";
374
  $lytetemplate = "<a href=\"".$postURL."\"><img src=\"".$thumbUrl."\" alt=\"YouTube Video\"></a>".$textLink;
375
  $templateType="feed";
376
  } elseif ( $audio !== true && $plClass !== " playlist" && $lyteSettings['microdata'] === "1" && $noMicroData !== "1" ) {
377
+ $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=\"duration\" content=\"" . $yt_resp_array['duration'] . "\" /><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;
378
  $templateType="postMicrodata";
379
  } else {
380
  $lytetemplate = $wrapper."<div class=\"lyMe".$audioClass.$hidefClass.$plClass.$qsaClass."\" id=\"WYL_".$vid."\"><div id=\"lyte_".$vid."\" data-src=\"".$thumbUrl."\" class=\"pL\">";
382
  if ( isset( $_this_title ) ) {
383
  $lytetemplate .= "<div class=\"tC".$titleClass."\"><div class=\"tT\">".$_this_title."</div></div>";
384
  }
385
+
386
  $lytetemplate .= "<div class=\"play\"></div><div class=\"ctrl\"><div class=\"Lctrl\"></div><div class=\"Rctrl\"></div></div></div>".$noscript."</div></div>".$lytelinks_txt;
387
  $templateType="post";
388
  }
405
  }
406
  }
407
 
408
+ // replace remaining double dash
409
+ $the_content = str_replace( array( ' -- ', '-- ', ' --' ), ' &#8211 ', $the_content );
410
+
411
  /** API: filter hook to postparse the_content before returning */
412
  $the_content = apply_filters( 'lyte_content_postparse',$the_content );
413
 
417
  function captions_lookup($postID, $cachekey, $vid) {
418
  // captions lookup at YouTube via a11ymetadata.org
419
  $response = wp_remote_request("http://api.a11ymetadata.org/captions/youtubeid=".$vid."/youtube");
420
+
421
+ if(!is_wp_error($response)) {
422
  $rawJson = wp_remote_retrieve_body($response);
423
  $decodeJson = json_decode($rawJson, true);
424
 
429
  if($yt_resp) {
430
  $yt_resp_array=json_decode($yt_resp,true);
431
 
432
+ if ($decodeJson['status'] == 'success' && $decodeJson['data']['captions'] == '1') {
433
  $yt_resp_array['captions_data'] = true;
434
+ } else {
435
  $yt_resp_array['captions_data'] = false;
436
  }
437
 
438
+ $yt_resp_array['captions_timestamp'] = strtotime("now");
439
  $yt_resp_precache=json_encode($yt_resp_array);
440
  $toCache=base64_encode(gzcompress($yt_resp_precache));
441
+ update_post_meta($postID, $cachekey, $toCache);
442
  }
443
  }
444
  }
447
  function lyte_get_YT_resp($vid,$playlist=false,$cachekey,$apiTestKey="",$isWidget=false) {
448
  /** logic to get video info from cache or get it from YouTube and set it */
449
  global $postID, $cachekey, $toCache_index;
450
+
451
  $_thisLyte = array();
452
+ $yt_error = array();
453
 
454
  if ( $postID && empty($apiTestKey) && !$isWidget ) {
455
  $cache_resp = get_post_meta( $postID, $cachekey, true );
497
  } else {
498
  // v3, feeling somewhat lonely now v2 has gently been put to sleep
499
  $yt_api_base = "https://www.googleapis.com/youtube/v3/";
500
+
501
  if ($playlist) {
502
  $yt_api_target = "playlists?part=snippet%2C+id&id=".$vid."&key=".$lyte_yt_api_key;
503
  } else {
517
  return $yt_error;
518
  }
519
  } else {
520
+ $yt_resp_array = (array) json_decode(wp_remote_retrieve_body($yt_resp),true);
521
  if(is_array($yt_resp_array)) {
522
  // extract relevant data
523
  // v3
613
  } else {
614
  $mobJS = "var mOs=navigator.userAgent.match(/(iphone|ipad|ipod|android)/i);";
615
  }
616
+
617
  /** API: filter hook to change css */
618
  $lyte_css = apply_filters( 'lyte_css', $lyte_css);
619
+
620
+ echo "<script type=\"text/javascript\">var bU='".$lyteSettings['path']."';".$mobJS."style = document.createElement('style');style.type = 'text/css';rules = document.createTextNode(\"".$lyte_css."\" );if(style.styleSheet) { style.styleSheet.cssText = rules.nodeValue;} else {style.appendChild(rules);}document.getElementsByTagName('head')[0].appendChild(style);</script>";
621
  echo "<script type=\"text/javascript\" async src=\"".$lyteSettings['path'].$lyteSettings['file']."\"></script>";
622
  }
623
 
679
  // remove thumbnail cache
680
  if (get_option('lyte_local_thumb','0') === '1') {
681
  if ( ! defined( 'LYTE_CACHE_DIR' ) ) {
682
+ define( 'LYTE_CACHE_CHILD_DIR', 'cache/lyteCache' );
683
  define( 'LYTE_CACHE_DIR', WP_CONTENT_DIR .'/'. LYTE_CACHE_CHILD_DIR );
684
  }
685
  array_map('unlink', glob(LYTE_CACHE_DIR . "/*"));
688
  // and remove cached YT data from postmeta
689
  try {
690
  ini_set('max_execution_time',90); // give PHP some more time for this, post-meta can be sloooooow
691
+
692
  // cache in post_meta, for posts
693
  $lyte_posts = json_decode(get_option("lyte_cache_index"),true);
694
  $lyteCacheIterator = 0;
708
  }
709
  update_option("lyte_cache_index",json_encode($lyte_posts));
710
  }
711
+
712
  // and the widget cache which isn't in post_meta
713
  update_option('lyte_widget_cache','');
714
+
715
  return $returnCode;
716
  } catch(Exception $e) {
717
  return $e->getMessage();
718
  }
719
  }
720
 
721
+ // updating LYTE thumbnail cache directory to avoid blocking by firewalls.
722
+ function lyte_mv_cache() {
723
+ if ( get_option( 'lyte_local_thumb', '0' ) === '1' ) {
724
+ $old_cache_dir = WP_CONTENT_DIR . '/cache/lyteThumbs';
725
+ $new_cache_dir = WP_CONTENT_DIR . '/cache/lyteCache';
726
+ if ( file_exists( $old_cache_dir ) ) {
727
+ rename( $old_cache_dir, $new_cache_dir );
728
+ }
729
+ add_action( 'admin_notices', 'lyte_thumbcache_moved' );
730
+ }
731
+ }
732
+
733
+ // notice to ask people to purge page caches.
734
+ function lyte_thumbcache_moved() {
735
+ echo '<div class="notice notice-warning"><p>';
736
+ _e( 'WP YouTube Lyte: the name of the thumbnail cache script has changed, clear any page cache(s) you might have.', 'wp-youtube-lyte' );
737
+ echo '</p></div>';
738
+ }
739
+
740
  /** function to call from within themes */
741
  /* use with e.g. : <?php if(function_exists('lyte_preparse')) { echo lyte_preparse($videoId); } ?> */
742
  function lyte_preparse($videoId) {
751
  /** is_amp, but I shouldn't have to do this, should I? */
752
  if (!function_exists("is_amp")) {
753
  function is_amp() {
754
+ if ( function_exists('is_amp_endpoint') ) {
755
  return is_amp_endpoint();
756
  } else if ( function_exists('ampforwp_is_amp_endpoint') ) {
757
  return ampforwp_is_amp_endpoint();
771
  if ( apply_filters( 'lyte_filter_do_gutenberg', true ) && strpos( $the_content, "<!-- wp:" ) !== false && strpos( $the_content, "youtu" ) !== false ) {
772
  /*
773
  * do Gutenberg stuff here, playlists if needed first and then single videos
774
+ *
775
  * having Gutenberg markup in HTML comments is ugly as hell
776
  * esp. for 3rd parties such as Lyte who have to parse info out of that
777
+ *
778
  * Luke Cavanagh; thanks for the Gutenbeard reference and for the funny animated gif :)
779
  * https://media1.giphy.com/media/l2QZTNMFTQ2Z00zHG/giphy.gif
780
  */
781
  if ( strpos( $the_content, '/playlist?list=' ) !== false ) {
782
+ $gutenbeard_playlist_regex = '%<\!--\s?wp:(?:core[-|/])?embed(?:/youtube)?\s?{"url":"https://www.youtube.com/playlist\?list=(.*)"(?:.*)?}\s?-->.*(?:(?:<figcaption>(.*)</figcaption>).*)?<\!--\s?/wp:(?:core[-|/])?embed(?:/youtube)?\s?-->%Us';
783
  $the_content = preg_replace($gutenbeard_playlist_regex, '<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube">httpv://www.youtube.com/playlist?list=\1<figcaption>\2</figcaption></figure>',$the_content);
784
  }
785
+ $gutenbeard_single_regex = '%<\!--\s?wp:(?:core[-|/])?embed(?:/youtube)?\s?{"url":"https?://(?:www\.)?youtu(?:be\.com/watch\?v=|.be/)(.*)"(?:.*)?}\s?-->.*(?:(?:<figcaption>(.*)</figcaption>).*)?<\!--\s?/wp:(?:core[-|/])?embed(?:/youtube)?\s?-->%Us';
786
  $the_content = preg_replace($gutenbeard_single_regex, '<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube">httpv://www.youtube.com/watch?v=\1<figcaption>\2</figcaption></figure>',$the_content);
787
  }
788
 
795
  }
796
  // and lastly normal single embeds.
797
  $the_content = preg_replace( '/^(?:<p>)?https?:\/\/(www.)?youtu(be.com|.be)\/(watch\?v=)?/m', 'httpv://www.youtube.com/watch?v=', $the_content );
798
+ }
799
  return $the_content;
800
  }
801