WP YouTube Lyte - Version 1.7.14

Version Description

  • fix WordPress core blocks "recent posts block" breaking when summary or full article were shown.
  • remove old language-files (translations are now entirely handled via https://translate.wordpress.org/projects/wp-plugins/wp-youtube-lyte/
  • add logic to lyteCache.php to prevent (ab)use like e.g. hotlinking (needs to be enabled with lyte_filter_local_thumb_doublecheck filter) or lyteCache caching even if local thumbnail caching is off.
  • some smaller fixes.
Download this release

Release Info

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

Code changes from version 1.7.13 to 1.7.14

Files changed (3) hide show
  1. lyteCache.php +84 -88
  2. readme.txt +21 -10
  3. wp-youtube-lyte.php +54 -23
lyteCache.php CHANGED
@@ -23,67 +23,55 @@ if ( ! defined( 'LYTE_CACHE_DIR' ) ) {
23
  define( 'LYTE_CACHE_DIR', WP_CONTENT_DIR .'/'. LYTE_CACHE_CHILD_DIR );
24
  }
25
 
26
- $lyte_thumb_error = "";
27
- $lyte_thumb_dontsave = "";
28
- $thumbContents = "";
29
  $lyte_thumb_report_err = false;
30
 
31
  /*
32
  * step 1: get vid ID (or full thumbnail URL) from request and validate
33
  */
34
 
 
 
35
  // should we output debug info in a header?
36
- if ( array_key_exists("reportErr", $_GET) ) {
37
  $lyte_thumb_report_err = true;
38
  }
39
 
40
- // get thumbnail-url from request
41
- if ( array_key_exists("origThumbUrl", $_GET) && $_GET["origThumbUrl"] !== "" ) {
42
- $origThumbURL = urldecode($_GET["origThumbUrl"]);
43
- } else {
44
- // faulty request, force a grey background
45
- $origThumbURL = "https://i.ytimg.com/vi/thisisnotavalidvid/hqdefault.jpg";
46
- }
47
-
48
- // make sure the thumbnail-url is for youtube
49
- $origThumbDomain = parse_url($origThumbURL, PHP_URL_HOST);
50
- if ( str_replace( array("ytimg.com","youtube.com","youtu.be"), "", $origThumbDomain ) === $origThumbDomain ) {
51
- // faulty request, force a grey background
52
- $origThumbURL = "https://i.ytimg.com/vi/thisisnotavalidvid/hqdefault.jpg";
53
- }
54
 
55
- // make sure the thumbnail-url is for an image (.jpg)
56
- $origThumbPath = parse_url($origThumbURL, PHP_URL_PATH);
57
- if ( lyte_str_ends_in( $origThumbPath, ".jpg" ) !== true ) {
58
- // faulty request, force a grey background
59
- $origThumbURL = "https://i.ytimg.com/vi/thisisnotavalidvid/hqdefault.jpg";
60
  }
61
 
62
- // TODO: extra checks to prevent automated hotlinking abuse?
63
-
64
  /*
65
- * step 2: check for and if need be create wp-content/cache/lyte_thumbs
66
  */
67
 
68
- if ( lyte_check_cache_dir(LYTE_CACHE_DIR) === false ) {
69
  $lyte_thumb_dontsave = true;
70
- $lyte_thumb_error .= "checkcache fail/ ";
71
  }
72
 
73
  /*
74
- * step 3: if not in cache: fetch from YT and store in cache
75
  */
76
 
77
  if ( strpos($origThumbURL,'http') !== 0 && strpos($origThumbURL,'//') === 0 ) {
78
  $origThumbURL = 'https:'.$origThumbURL;
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.
@@ -97,40 +85,40 @@ if ( !file_exists( $localThumb ) || $lyte_thumb_dontsave || ( file_exists( $loca
97
  }
98
 
99
  /*
100
- * step 4: serve img
101
  */
102
 
103
- if ( $thumbContents == "" && !$lyte_thumb_dontsave && file_exists($localThumb) && is_jpeg($localThumb) ) {
104
  $thumbContents = file_get_contents( $localThumb );
105
  } else {
106
- $lyte_thumb_error .= "not from cache/ ";
107
  }
108
 
109
- if ( $thumbContents != "") {
110
- if ( $lyte_thumb_error !== "" && $lyte_thumb_report_err ) {
111
  header('X-lyte-error: '.$lyte_thumb_error);
112
  }
113
 
114
- $modTime=filemtime($localThumb);
115
 
116
- date_default_timezone_set("UTC");
117
- $modTimeMatch = (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $modTime);
118
 
119
  if ( $modTimeMatch ) {
120
  header('HTTP/1.1 304 Not Modified');
121
  header('Connection: close');
122
  } else {
123
  // send all sorts of headers
124
- $expireTime=60*60*24*7; // 1w
125
- header('Content-Length: '.strlen($thumbContents));
126
- header('Cache-Control: max-age='.$expireTime.', public, immutable');
127
- header('Expires: '.gmdate('D, d M Y H:i:s', time() + $expireTime).' GMT');
128
- header('Last-Modified: '.gmdate('D, d M Y H:i:s', $modTime).' GMT');
129
- header('Content-type:image/jpeg');
130
  echo $thumbContents;
131
  }
132
  } else {
133
- $lyte_thumb_error .= "no thumbContent/ ";
134
  lyte_thumb_fallback();
135
  }
136
 
@@ -155,68 +143,76 @@ function is_jpeg( $in ) {
155
 
156
  function lyte_check_cache_dir( $dir ) {
157
  // Try creating the dir if it doesn't exist.
158
- if ( ! file_exists( $dir ) ) {
159
- @mkdir( $dir, 0775, true );
160
- if ( ! file_exists( $dir ) ) {
161
- return false;
162
- }
163
- }
164
-
165
- // If we still cannot write, bail.
166
- if ( ! is_writable( $dir ) ) {
167
  return false;
168
  }
169
 
170
- // Create an index.html in there to avoid prying eyes!
171
- $idx_file = rtrim( $dir, '/\\' ) . '/index.html';
172
- if ( ! is_file( $idx_file ) ) {
173
- @file_put_contents( $idx_file, '<html><head><meta name="robots" content="noindex, nofollow"></head><body>Generated by <a href="http://wordpress.org/extend/plugins/wp-youtube-lyte/" rel="nofollow">WP YouTube Lyte</a></body></html>' );
174
- }
175
-
176
  return true;
177
  }
178
 
179
- function lyte_str_ends_in($haystack,$needle) {
180
- $needleLength = strlen($needle);
181
- $haystackLength = strlen($haystack);
182
- $lastPos=strrpos($haystack,$needle);
183
- if ($lastPos === $haystackLength - $needleLength) {
184
- return true;
185
- } else {
186
- return false;
187
- }
188
- }
189
-
190
- function lyte_get_thumb($thumbUrl) {
191
  global $lyte_thumb_error;
192
- if (function_exists("curl_init")) {
193
  $curl = curl_init();
194
- curl_setopt($curl, CURLOPT_URL, $thumbUrl);
195
- curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");
196
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
197
- curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
198
- $str = curl_exec($curl);
199
- $err = curl_error($curl);
200
- curl_close($curl);
201
- if ( !$err && $str != "" ) {
202
  return $str;
203
  } else {
204
- $lyte_thumb_error .= "curl err: ".$err."/ ";
205
  }
206
  } else {
207
- $lyte_thumb_error .= "no curl/ ";
208
  }
209
 
210
- // if no curl or if curl error
211
- $resp = file_get_contents($thumbUrl);
212
  return $resp;
213
  }
214
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  function lyte_thumb_fallback() {
216
  global $origThumbURL, $lyte_thumb_error, $lyte_thumb_report_err;
217
  // if for any reason we can't show a local thumbnail, we redirect to the original one
218
- if ( strpos( $origThumbURL, "http" ) !== 0) {
219
- $origThumbURL = "https:".$origThumbURL;
220
  }
221
  if ( $lyte_thumb_report_err ) {
222
  header('X-lyte-error: '.$lyte_thumb_error);
23
  define( 'LYTE_CACHE_DIR', WP_CONTENT_DIR .'/'. LYTE_CACHE_CHILD_DIR );
24
  }
25
 
26
+ $lyte_thumb_error = '';
27
+ $lyte_thumb_dontsave = '';
28
+ $thumbContents = '';
29
  $lyte_thumb_report_err = false;
30
 
31
  /*
32
  * step 1: get vid ID (or full thumbnail URL) from request and validate
33
  */
34
 
35
+ $origThumbURL = get_origThumbUrl();
36
+
37
  // should we output debug info in a header?
38
+ if ( array_key_exists( 'reportErr', $_GET ) ) {
39
  $lyte_thumb_report_err = true;
40
  }
41
 
42
+ /*
43
+ * step 2: check if it is safe to serve from cache and redirect if not.
44
+ */
 
 
 
 
 
 
 
 
 
 
 
45
 
46
+ if ( ! file_exists( LYTE_CACHE_DIR ) || ( file_exists( LYTE_CACHE_DIR . '/doubleCheckLyteThumbnailCache.txt' ) && ! array_key_exists( 'lyteCookie', $_COOKIE ) ) ) {
47
+ // local thumbnail caching not on or no cookie found, redirect to original at youtube.
48
+ $lyte_thumb_error = 'possible hotlinker/';
49
+ lyte_thumb_fallback();
 
50
  }
51
 
 
 
52
  /*
53
+ * step 3: check for and if need be create wp-content/cache/lyte_thumbs
54
  */
55
 
56
+ if ( lyte_check_cache_dir( LYTE_CACHE_DIR ) === false ) {
57
  $lyte_thumb_dontsave = true;
58
+ $lyte_thumb_error .= 'checkcache fail/ ';
59
  }
60
 
61
  /*
62
+ * step 4: if not in cache: fetch from YT and store in cache
63
  */
64
 
65
  if ( strpos($origThumbURL,'http') !== 0 && strpos($origThumbURL,'//') === 0 ) {
66
  $origThumbURL = 'https:'.$origThumbURL;
67
  }
68
 
69
+ $localThumb = LYTE_CACHE_DIR . '/' . md5($origThumbURL) . '.jpg';
70
  $expiryTime = filemtime( $localThumb ) + 3*24*60*60; // images can be cached for 3 days.
71
  $now = time();
72
 
73
  if ( !file_exists( $localThumb ) || $lyte_thumb_dontsave || ( file_exists( $localThumb ) && $expiryTime < $now ) ) {
74
+ $thumbContents = lyte_get_thumb( $origThumbURL );
75
 
76
  if ( $thumbContents != '' && ! $lyte_thumb_dontsave ) {
77
  // save file but immediately check if it is a jpeg and delete if not.
85
  }
86
 
87
  /*
88
+ * step 5: serve img
89
  */
90
 
91
+ if ( $thumbContents == '' && ! $lyte_thumb_dontsave && file_exists( $localThumb ) && is_jpeg( $localThumb ) ) {
92
  $thumbContents = file_get_contents( $localThumb );
93
  } else {
94
+ $lyte_thumb_error .= 'not from cache/ ';
95
  }
96
 
97
+ if ( $thumbContents != '') {
98
+ if ( $lyte_thumb_error !== '' && $lyte_thumb_report_err ) {
99
  header('X-lyte-error: '.$lyte_thumb_error);
100
  }
101
 
102
+ $modTime = filemtime($localThumb);
103
 
104
+ date_default_timezone_set('UTC');
105
+ $modTimeMatch = ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) && strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) === $modTime );
106
 
107
  if ( $modTimeMatch ) {
108
  header('HTTP/1.1 304 Not Modified');
109
  header('Connection: close');
110
  } else {
111
  // send all sorts of headers
112
+ $expireTime = 60 * 60 * 24 * 7; // 1w
113
+ header( 'Content-Length: '. strlen( $thumbContents) );
114
+ header( 'Cache-Control: max-age=' . $expireTime . ', public, immutable' );
115
+ header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expireTime).' GMT' );
116
+ header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', $modTime) . ' GMT' );
117
+ header( 'Content-type:image/jpeg' );
118
  echo $thumbContents;
119
  }
120
  } else {
121
+ $lyte_thumb_error .= 'no thumbContent/ ';
122
  lyte_thumb_fallback();
123
  }
124
 
143
 
144
  function lyte_check_cache_dir( $dir ) {
145
  // Try creating the dir if it doesn't exist.
146
+ if ( ! file_exists( $dir ) || ! is_writable( $dir ) ) {
 
 
 
 
 
 
 
 
147
  return false;
148
  }
149
 
 
 
 
 
 
 
150
  return true;
151
  }
152
 
153
+ function lyte_get_thumb( $thumbUrl ) {
 
 
 
 
 
 
 
 
 
 
 
154
  global $lyte_thumb_error;
155
+ if ( function_exists( 'curl_init' ) ) {
156
  $curl = curl_init();
157
+ curl_setopt( $curl, CURLOPT_URL, $thumbUrl );
158
+ curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)');
159
+ curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );
160
+ curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 5 );
161
+ $str = curl_exec( $curl );
162
+ $err = curl_error( $curl );
163
+ curl_close( $curl );
164
+ if ( ! $err && $str != '' ) {
165
  return $str;
166
  } else {
167
+ $lyte_thumb_error .= 'curl err: ' . $err . '/ ';
168
  }
169
  } else {
170
+ $lyte_thumb_error .= 'no curl/ ';
171
  }
172
 
173
+ // if no curl or if curl error.
174
+ $resp = file_get_contents( $thumbUrl );
175
  return $resp;
176
  }
177
 
178
+ function get_origThumbURL() {
179
+ $invalid = false;
180
+
181
+ // get thumbnail-url from request
182
+ if ( array_key_exists( 'origThumbUrl', $_GET ) && $_GET['origThumbUrl'] !== '' ) {
183
+ $origThumbURL = urldecode( $_GET['origThumbUrl'] );
184
+ } else {
185
+ $invalid = true;
186
+ }
187
+
188
+ // break URL in parts to investigate.
189
+ $origThumbURL_parts = parse_url( $origThumbURL );
190
+
191
+ // make sure the thumbnail-domain is for youtube.
192
+ $origThumbDomain = $origThumbURL_parts['host'];
193
+ if ( ! $invalid && str_replace( array( 'ytimg.com','youtube.com','youtu.be' ), '', $origThumbDomain ) === $origThumbDomain ) {
194
+ $invalid = true;
195
+ }
196
+
197
+ // and make sure the thumbnail-url is for an image (.jpg)
198
+ $origThumbPath = $origThumbURL_parts['path'];
199
+ if ( ! $invalid && strpos( $origThumbPath, '.jpg' ) !== strlen( $origThumbPath ) - 4 ) {
200
+ $invalid = true;
201
+ }
202
+
203
+ // one of the above checks was not OK, so replace with fallback thumb URL (grey background).
204
+ if ( $invalid ) {
205
+ $origThumbURL = 'https://i.ytimg.com/vi/thisisnotavalidvid/hqdefault.jpg';
206
+ }
207
+
208
+ return $origThumbURL;
209
+ }
210
+
211
  function lyte_thumb_fallback() {
212
  global $origThumbURL, $lyte_thumb_error, $lyte_thumb_report_err;
213
  // if for any reason we can't show a local thumbnail, we redirect to the original one
214
+ if ( strpos( $origThumbURL, 'http' ) !== 0) {
215
+ $origThumbURL = 'https:' . $origThumbURL;
216
  }
217
  if ( $lyte_thumb_report_err ) {
218
  header('X-lyte-error: '.$lyte_thumb_error);
readme.txt CHANGED
@@ -4,7 +4,7 @@ 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.13
8
 
9
  High performance YouTube video, playlist and audio-only embeds which don't slow down your blog and offer optimal accessibility.
10
 
@@ -22,9 +22,10 @@ The plugin picks up on normal YouTube links, taking over from WordPress core's o
22
  * httpv://www.youtube.com/watch?v=_SQkWbRublY?start=20&showinfo=0 (video player, start playing at 20 seconds and don't show title)
23
 
24
  Or using shortcodes:
25
- [lyte id='_SQkWbRublY' /]
26
- [lyte id='_SQkWbRublY' audio='true' /]
27
- [lyte id='A486E741B25F8E00' playlist='true' /]
 
28
 
29
  WP YouTube Lyte has been written with optimal performance as primary goal, but has been tested for maximum browser-compatibility (iPad included) while keeping an eye on accessibility. Starting with version 1.2.0 lyte embeds are fully responsive and can automatically embed [videoObject microdata](http://support.google.com/webmasters/bin/answer.py?hl=en&answer=2413309) as well. The plugin is fully multi-language, with support for Catalan, Dutch, English, French, German, Hebrew, Romanian, Spanish and Slovene.
30
 
@@ -115,12 +116,16 @@ You probably added a link around the httpv-url. No link is needed, just the http
115
  = My video's seem to load slower on mobile devices? =
116
  By default (unless "cache thumbnail locally" is active) WP YouTube Lyte will indeed load slower normal YouTube video's instead of Lyte ones, as Lyte video's require would require two clicks from the user to play a video (once to load the YouTube video and once to start it) because there is no autoplay-support on mobile. If you want to, you can force WP YouTube Lyte to make video's Lyte on mobile with this code (add it in your child theme's functions.php, in a seperate helper plugin or using the [code snippets plugin](https://wordpress.org/plugins/code-snippets/);
117
 
118
- `
119
- add_filter('lyte_do_mobile','lyte_on_mobile',10,0);
120
- function lyte_on_mobile(){
121
- return true;
122
- }
123
- `
 
 
 
 
124
 
125
  = Any other issues should I know about? =
126
  * Having the same YouTube-video on one page can cause WP YouTube Lyte to malfunction (as the YouTube id is used as the div's id in the DOM, and DOM id's are supposed to be unique)
@@ -135,6 +140,12 @@ Just tell me, I like the feedback! Use the [Contact-page on my blog](http://blog
135
 
136
  == Changelog ==
137
 
 
 
 
 
 
 
138
  = 1.7.13 =
139
  * fix regression causing HTML comments to break
140
 
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.14
8
 
9
  High performance YouTube video, playlist and audio-only embeds which don't slow down your blog and offer optimal accessibility.
10
 
22
  * httpv://www.youtube.com/watch?v=_SQkWbRublY?start=20&showinfo=0 (video player, start playing at 20 seconds and don't show title)
23
 
24
  Or using shortcodes:
25
+
26
+ `[lyte id='_SQkWbRublY' /]`
27
+ `[lyte id='_SQkWbRublY' audio='true' /]`
28
+ `[lyte id='A486E741B25F8E00' playlist='true' /]`
29
 
30
  WP YouTube Lyte has been written with optimal performance as primary goal, but has been tested for maximum browser-compatibility (iPad included) while keeping an eye on accessibility. Starting with version 1.2.0 lyte embeds are fully responsive and can automatically embed [videoObject microdata](http://support.google.com/webmasters/bin/answer.py?hl=en&answer=2413309) as well. The plugin is fully multi-language, with support for Catalan, Dutch, English, French, German, Hebrew, Romanian, Spanish and Slovene.
31
 
116
  = My video's seem to load slower on mobile devices? =
117
  By default (unless "cache thumbnail locally" is active) WP YouTube Lyte will indeed load slower normal YouTube video's instead of Lyte ones, as Lyte video's require would require two clicks from the user to play a video (once to load the YouTube video and once to start it) because there is no autoplay-support on mobile. If you want to, you can force WP YouTube Lyte to make video's Lyte on mobile with this code (add it in your child theme's functions.php, in a seperate helper plugin or using the [code snippets plugin](https://wordpress.org/plugins/code-snippets/);
118
 
119
+ `add_filter( 'lyte_do_mobile', '__return_true' );`
120
+
121
+ = lyteCache.php is using a lot of resources =
122
+ lyteCache.php is a standalone file (it does not rely on WordPress) that is used when local thumbnail caching is active, which means requests for those thumbnails are handled by PHP. In WP YouTube Lyte 1.7.14 logic was added to prevent lyteCache.php doing thumbnail caching when being called directy without "local thumbnail caching" being active.
123
+
124
+ Moreover if you want to ensure the thumbnails can only be used on your own site (and not hotlinked) you can use this code snippet:
125
+
126
+ `add_filter( 'lyte_filter_local_thumb_doublecheck', '__return_true' );`
127
+
128
+ This will have WP YouTube Lyte set (in JavaScript in the HTML) and check (in the request for the thumbnail) a cookie. If the cookie is not set, the image request will be redirected to the YouTube origin URL.
129
 
130
  = Any other issues should I know about? =
131
  * Having the same YouTube-video on one page can cause WP YouTube Lyte to malfunction (as the YouTube id is used as the div's id in the DOM, and DOM id's are supposed to be unique)
140
 
141
  == Changelog ==
142
 
143
+ = 1.7.14 =
144
+ * fix WordPress core blocks "recent posts block" breaking when summary or full article were shown.
145
+ * remove old language-files (translations are now entirely handled via https://translate.wordpress.org/projects/wp-plugins/wp-youtube-lyte/
146
+ * add logic to lyteCache.php to prevent (ab)use like e.g. hotlinking (needs to be enabled with `lyte_filter_local_thumb_doublecheck` filter) or lyteCache caching even if local thumbnail caching is off.
147
+ * some smaller fixes.
148
+
149
  = 1.7.13 =
150
  * fix regression causing HTML comments to break
151
 
wp-youtube-lyte.php CHANGED
@@ -4,16 +4,15 @@ 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.13
8
  Author URI: http://blog.futtta.be/
9
  Text Domain: wp-youtube-lyte
10
- Domain Path: /languages
11
  */
12
 
13
  if ( ! defined( 'ABSPATH' ) ) exit;
14
 
15
  $debug=false;
16
- $lyte_version="1.7.13";
17
  $lyte_db_version=get_option('lyte_version','none');
18
 
19
  /** have we updated? */
@@ -290,7 +289,7 @@ function lyte_parse($the_content,$doExcerpt=false) {
290
  $captionsMeta="";
291
  $threshold = 30;
292
  if (array_key_exists('captions_timestamp',$yt_resp_array)) {
293
- $cache_timestamp = $yt_resp_array["captions_timestamp"];
294
  $interval = (strtotime("now") - $cache_timestamp)/60/60/24;
295
  } else {
296
  $cache_timestamp = false;
@@ -616,34 +615,39 @@ function lyte_init() {
616
  $mobJS = "var mOs=navigator.userAgent.match(/(iphone|ipad|ipod|android)/i);";
617
  }
618
 
 
 
 
 
 
 
 
619
  /** API: filter hook to change css */
620
  $lyte_css = apply_filters( 'lyte_css', $lyte_css);
621
 
622
- 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>";
623
  echo "<script type=\"text/javascript\" async src=\"".$lyteSettings['path'].$lyteSettings['file']."\"></script>";
624
  }
625
 
626
  /** override default wp_trim_excerpt to have lyte_parse remove the httpv-links */
627
- function lyte_trim_excerpt($text) {
628
- global $post;
629
- $raw_excerpt = $text;
630
- if ( '' == $text ) {
631
- $text = get_the_content('');
 
632
  $text = lyte_parse($text, true);
633
  $text = strip_shortcodes( $text );
634
- $text = apply_filters('the_content', $text);
635
- $text = str_replace(']]>', ']]&gt;', $text);
636
- $excerpt_length = apply_filters('excerpt_length', 55);
637
- $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
638
- if (function_exists('wp_trim_words')) {
639
- $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
640
- } else {
641
- $length = $excerpt_length*6;
642
- $text = substr( strip_tags(trim(preg_replace('/\s+/', ' ', $text))), 0, $length );
643
- $text .= $excerpt_more;
644
- }
645
- }
646
- return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
647
  }
648
 
649
  /** Lyte shortcode */
@@ -801,10 +805,36 @@ function lyte_prepare( $the_content ) {
801
  return $the_content;
802
  }
803
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  /** hooking it all up to wordpress */
805
  if ( is_admin() ) {
806
  require_once(dirname(__FILE__).'/options.php');
807
  add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'lyte_add_action_link' );
 
808
  } else {
809
  add_filter('the_content', 'lyte_prepare', 4);
810
  add_filter('the_content', 'lyte_parse', 10);
@@ -812,6 +842,7 @@ if ( is_admin() ) {
812
  remove_filter('get_the_excerpt', 'wp_trim_excerpt');
813
  add_filter('get_the_excerpt', 'lyte_trim_excerpt');
814
  add_action('schedule_captions_lookup', 'captions_lookup', 1, 3);
 
815
 
816
  /** API: action hook to allow extra actions or filters to be added */
817
  do_action("lyte_actionsfilters");
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.14
8
  Author URI: http://blog.futtta.be/
9
  Text Domain: wp-youtube-lyte
 
10
  */
11
 
12
  if ( ! defined( 'ABSPATH' ) ) exit;
13
 
14
  $debug=false;
15
+ $lyte_version="1.7.14";
16
  $lyte_db_version=get_option('lyte_version','none');
17
 
18
  /** have we updated? */
289
  $captionsMeta="";
290
  $threshold = 30;
291
  if (array_key_exists('captions_timestamp',$yt_resp_array)) {
292
+ $cache_timestamp = (int) $yt_resp_array["captions_timestamp"];
293
  $interval = (strtotime("now") - $cache_timestamp)/60/60/24;
294
  } else {
295
  $cache_timestamp = false;
615
  $mobJS = "var mOs=navigator.userAgent.match(/(iphone|ipad|ipod|android)/i);";
616
  }
617
 
618
+ // if we're caching local thumbnails and filter says so, create lyteCookie cookie to prevent image hotlinking.
619
+ if ( get_option( 'lyte_local_thumb', '0' ) === '1' && apply_filters( 'lyte_filter_local_thumb_doublecheck', false ) ) {
620
+ $doublecheck_thumb_cookie = 'document.cookie="lyteCookie=1;path=/;samesite=strict";';
621
+ } else {
622
+ $doublecheck_thumb_cookie = '';
623
+ }
624
+
625
  /** API: filter hook to change css */
626
  $lyte_css = apply_filters( 'lyte_css', $lyte_css);
627
 
628
+ echo "<script type=\"text/javascript\">var bU='" . $lyteSettings['path'] . "';" . $mobJS . $doublecheck_thumb_cookie . "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>";
629
  echo "<script type=\"text/javascript\" async src=\"".$lyteSettings['path'].$lyteSettings['file']."\"></script>";
630
  }
631
 
632
  /** override default wp_trim_excerpt to have lyte_parse remove the httpv-links */
633
+ function lyte_trim_excerpt($text = '', $post = null) {
634
+ $raw_excerpt = $text;
635
+
636
+ if ( '' === trim( $text ) ) {
637
+ $post = get_post( $post );
638
+ $text = get_the_content( '', false, $post );
639
  $text = lyte_parse($text, true);
640
  $text = strip_shortcodes( $text );
641
+ $text = excerpt_remove_blocks( $text );
642
+ $text = apply_filters( 'the_content', $text );
643
+ $text = str_replace( ']]>', ']]&gt;', $text );
644
+ $excerpt_length = intval( _x( '55', 'excerpt_length' ) );
645
+ $excerpt_length = (int) apply_filters( 'excerpt_length', $excerpt_length );
646
+ $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[&hellip;]' );
647
+ $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
648
+ }
649
+
650
+ return apply_filters( 'wp_trim_excerpt', $text, $raw_excerpt );
 
 
 
651
  }
652
 
653
  /** Lyte shortcode */
805
  return $the_content;
806
  }
807
 
808
+ function lytecache_doublecheck_activator() {
809
+ // image hotlinking protection: conditionally (by filter, off by default)
810
+ // create a file telling lyteCache to check for a cookie before serving thumbnail.
811
+ // file is also set if local thumbnail caching is not active, rendering lyteCache harmless.
812
+ if ( ! defined( 'LYTE_CACHE_DIR' ) ) {
813
+ define( 'LYTE_CACHE_DIR', WP_CONTENT_DIR .'/cache/lyteCache' );
814
+ }
815
+ $_doublecheck_activator_file = LYTE_CACHE_DIR . '/doubleCheckLyteThumbnailCache.txt';
816
+
817
+ if ( ( get_option( 'lyte_local_thumb', '0' ) === '1' && apply_filters( 'lyte_filter_local_thumb_doublecheck', false ) ) || get_option( 'lyte_local_thumb', '0' ) !== '1' ) {
818
+ if ( ! file_exists( $_doublecheck_activator_file ) ) {
819
+ if ( ! file_exists( LYTE_CACHE_DIR ) ) {
820
+ // create LYTE cache dir (and index.html) if it doesn't exist yet.
821
+ @mkdir( LYTE_CACHE_DIR, 0775, true );
822
+ @file_put_contents( LYTE_CACHE_DIR . '/index.html', '<html><head><meta name="robots" content="noindex, nofollow"></head><body>Generated by <a href="http://wordpress.org/extend/plugins/wp-youtube-lyte/" rel="nofollow">WP YouTube Lyte</a></body></html>' );
823
+ }
824
+ // file needed but not found, create it.
825
+ @file_put_contents( $_doublecheck_activator_file, 'This file is used to ensure lyteCache.php is not abused (prevent hotlinking of cached YouTube thumbnails or lyteCache.php being accessed when local thumbnail caching is not active).' );
826
+ }
827
+ } elseif ( file_exists( $_doublecheck_activator_file ) ) {
828
+ // file exists but not needed (any more), delete it.
829
+ @unlink( $_doublecheck_activator_file );
830
+ }
831
+ }
832
+
833
  /** hooking it all up to wordpress */
834
  if ( is_admin() ) {
835
  require_once(dirname(__FILE__).'/options.php');
836
  add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'lyte_add_action_link' );
837
+ add_action( 'admin_init', 'lytecache_doublecheck_activator' );
838
  } else {
839
  add_filter('the_content', 'lyte_prepare', 4);
840
  add_filter('the_content', 'lyte_parse', 10);
842
  remove_filter('get_the_excerpt', 'wp_trim_excerpt');
843
  add_filter('get_the_excerpt', 'lyte_trim_excerpt');
844
  add_action('schedule_captions_lookup', 'captions_lookup', 1, 3);
845
+ add_action( 'init', 'lytecache_doublecheck_activator' );
846
 
847
  /** API: action hook to allow extra actions or filters to be added */
848
  do_action("lyte_actionsfilters");