WP YouTube Lyte - Version 1.7.1

Version Description

  • Finally fixed a nasty bug that caused API key validation to fail on PHP 7.1 and higher. A big thank you to @emilyatal, @mkalina, @nicolaottomano, @aminech, @partounian, @nicksws who all provided valuable input in the WordPress LYTE support forum and tested multiple debug-versions to help fix this.
Download this release

Release Info

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

Code changes from version 1.7.0 to 1.7.1

Files changed (4) hide show
  1. options.php +144 -139
  2. readme.txt +7 -15
  3. widget.php +122 -126
  4. wp-youtube-lyte.php +557 -553
options.php CHANGED
@@ -9,34 +9,34 @@ load_plugin_textdomain( 'wp-youtube-lyte', false, $plugin_dir );
9
  add_action('admin_menu', 'lyte_create_menu');
10
 
11
  if (get_option('lyte_emptycache','0')==="1") {
12
- $emptycache=lyte_rm_cache();
13
- update_option('lyte_emptycache','0');
14
- if ($emptycache==="OK") {
15
- add_action('admin_notices', 'lyte_cacheclear_ok_notice');
16
- } elseif ($emptycache==="PART") {
17
- add_action('admin_notices', 'lyte_cacheclear_part_notice');
18
- update_option('lyte_emptycache','1'); // to ensure cache-purging continues
19
- } else {
20
- add_action('admin_notices', 'lyte_cacheclear_fail_notice');
21
- }
22
  }
23
 
24
  function lyte_cacheclear_ok_notice() {
25
- echo '<div class="updated"><p>';
26
- _e('Your WP YouTube Lyte cache has been succesfully cleared.', 'wp-youtube-lyte' );
27
- echo '</p></div>';
28
  }
29
 
30
  function lyte_cacheclear_part_notice() {
31
- echo '<div class="error"><p>';
32
- _e('WP YouTube Lyte cache was partially cleared, refresh this page to continue purging.', 'wp-youtube-lyte' );
33
- echo '</p></div>';
34
  }
35
 
36
  function lyte_cacheclear_fail_notice() {
37
- echo '<div class="error"><p>';
38
- _e('There was a problem, the WP YouTube Lyte cache could not be cleared.', 'wp-youtube-lyte' );
39
- echo '</p></div>';
40
  }
41
 
42
  function lyte_create_menu() {
@@ -47,20 +47,20 @@ function lyte_create_menu() {
47
  }
48
 
49
  function register_lyte_settings() {
50
- register_setting( 'lyte-settings-group', 'lyte_show_links' );
51
- register_setting( 'lyte-settings-group', 'lyte_size' );
52
- register_setting( 'lyte-settings-group', 'lyte_hidef' );
53
- register_setting( 'lyte-settings-group', 'lyte_position' );
54
- register_setting( 'lyte-settings-group', 'lyte_notification' );
55
- register_setting( 'lyte-settings-group', 'lyte_microdata' );
56
- register_setting( 'lyte-settings-group', 'lyte_emptycache' );
57
- register_setting( 'lyte-settings-group', 'lyte_greedy' );
58
- register_setting( 'lyte-settings-group', 'lyte_yt_api_key' );
59
- register_setting( 'lyte-settings-group', 'lyte_local_thumb' );
60
  }
61
 
62
  function lyte_admin_scripts() {
63
- wp_enqueue_script('jqcookie', plugins_url('/external/jquery.cookie.min.js', __FILE__), array('jquery'),null,true);
64
  wp_enqueue_script('unslider', plugins_url('/external/unslider-min.js', __FILE__), array('jquery'),null,true);
65
  }
66
 
@@ -70,35 +70,35 @@ function lyte_admin_styles() {
70
  }
71
 
72
  function lyte_admin_nag_apikey() {
73
- echo "<div class=\"update-nag\">";
74
- _e('For WP YouTube Lyte to function optimally, you should enter an YouTube API key ', 'wp-youtube-lyte');
75
- echo " <a href=\"options-general.php?page=lyte_settings_page\">";
76
- _e('in the settings screen.','wp-youtube-lyte');
77
- echo "</a>.</div>";
78
  }
79
 
80
  $lyte_yt_api_key=get_option('lyte_yt_api_key','');
81
  $lyte_yt_api_key=apply_filters('lyte_filter_yt_api_key', $lyte_yt_api_key);
82
  if (empty($lyte_yt_api_key)) {
83
- add_action('admin_notices', 'lyte_admin_nag_apikey');
84
- }
85
 
86
  function lyte_admin_api_error(){
87
- $yt_error=json_decode(get_option('lyte_api_error'),1);
88
- echo '<div class="error"><p>';
89
- _e('WP YouTube Lyte got the following error back from the YouTube API: ','wp-youtube-lyte');
90
- echo "<strong>".$yt_error["reason"]."</strong>";
91
- echo " (".date("r",$yt_error["timestamp"]).").";
92
- echo '</a>.</p></div>';
93
- update_option('lyte_api_error','');
94
  }
95
 
96
  if (get_option('lyte_api_error','')!=='') {
97
- add_action('admin_notices', 'lyte_admin_api_error');
98
- }
99
 
100
  function lyte_settings_page() {
101
- global $pSize, $pSizeOrder;
102
  ?>
103
  <style>
104
  /* rss block */
@@ -172,54 +172,54 @@ function lyte_settings_page() {
172
  <form method="post" action="options.php">
173
  <?php settings_fields( 'lyte-settings-group' ); ?>
174
  <table class="form-table">
175
- <input type="hidden" name="lyte_notification" value="<?php echo get_option('lyte_notification','0'); ?>" />
176
- <tr valign="top">
177
- <th scope="row"><?php _e("Your YouTube API key.","wp-youtube-lyte") ?></th>
178
- <td>
179
- <?php // only show api key input field if there's no result from filter
180
- $filter_key=apply_filters('lyte_filter_yt_api_key','');
181
- if (empty($filter_key)) { ?>
182
- <fieldset>
183
- <legend class="screen-reader-text"><span><?php _e("Please enter your YouTube API key.","wp-youtube-lyte") ?></span></legend>
184
- <label title="<?php _e('API key','wp-youtube-lyte'); ?>"><input type="text" size="28" name="lyte_yt_api_key" id="lyte_yt_api_key" value="<?php echo get_option('lyte_yt_api_key',''); ?>"><span id="check_api_key" class="submit button-secondary" style="margin:0px 5px;"><?php _e("Test Key"); ?></span></label><br />
185
- <div id="lyte_key_check_output" style="display:none;margin-bottom:5px;background-color:white;border-left:solid;border-width:4px;border-color:#2ea2cc;padding:5px 5px 5px 15px;"></div>
186
- <?php _e("WP YouTube Lyte uses YouTube's API to fetch information on each video. For your site to use that API, you will have to <a href=\"https://console.developers.google.com/project/\" target=\"_blank\">register your site as a new application</a>, enable the YouTube API for it and get a server key and fill it out here.","wp-youtube-lyte"); ?>
187
- </fieldset>
188
- <?php } else { ?>
189
- <?php _e("Great, your YouTube API key has been taken care of!","wp-youtube-lyte"); ?>
190
- <?php } ?>
191
- </td>
192
- </tr>
193
  <tr valign="top">
194
  <th scope="row"><?php _e("Player size","wp-youtube-lyte") ?>:</th>
195
  <td>
196
  <fieldset><legend class="screen-reader-text"><span><?php _e("Player size","wp-youtube-lyte") ?></span></legend>
197
- <?php
198
- $sel = !is_bool(get_option('lyte_size')) ? (int) get_option('lyte_size') : 0;
199
- foreach (array("169","43") as $f) {
200
- foreach ($pSizeOrder[$f] as $i) {
201
- $pS=$pSize[$i];
202
- if ($pS['a']===true) {
203
- ?>
204
- <label title="<?php echo $pS['w']."X".$pS['h']; ?>"><input type="radio" name="lyte_size" class="l_size" value="<?php echo $i."\"";if($i===$sel) echo " checked";echo " /> ".$pS['w']."X".$pS['h']." (".$pS['t'];?>)</label><br />
205
- <?php
206
- }
207
- }
208
- ?><br /><?php
209
- }
210
- ?>
211
  </fieldset>
212
  </td>
213
  </tr>
214
  <tr valign="top">
215
- <th scope="row"><?php _e("Add links below the embedded videos?","wp-youtube-lyte") ?></th>
216
- <td>
217
- <fieldset>
218
- <legend class="screen-reader-text"><span><?php _e("Show links?","wp-youtube-lyte") ?></span></legend>
219
- <label title="<?php _e('Show YouTube-link','wp-youtube-lyte');?>"><input type="radio" name="lyte_show_links" value="1" <?php if (get_option('lyte_show_links')==="1" || get_option('lyte_show_links')==="2") echo "checked" ?> /><?php _e(" Add YouTube-link.","wp-youtube-lyte") ?></label><br />
220
- <label title="<?php _e('Don\'t include links.','wp-youtube-lyte');?>"><input type="radio" name="lyte_show_links" value="0" <?php if ((get_option('lyte_show_links')!=="1") && (get_option('lyte_show_links')!=="2")) echo "checked" ?> /><?php _e(" Don't add any links.","wp-youtube-lyte") ?></label>
221
- </fieldset>
222
- </td>
223
  </tr>
224
  <tr valign="top">
225
  <th scope="row"><?php _e("Player position:","wp-youtube-lyte") ?></th>
@@ -227,7 +227,7 @@ function lyte_settings_page() {
227
  <fieldset>
228
  <legend class="screen-reader-text"><span><?php _e("Left, center or right?","wp-youtube-lyte"); ?></span></legend>
229
  <label title="<?php _e('Left','wp-youtube-lyte');?>"><input type="radio" name="lyte_position" value="0" <?php if (get_option('lyte_position','0')==="0") echo "checked" ?> /><?php _e("Left","wp-youtube-lyte") ?></label><br />
230
- <label title="<?php _e('Center','wp-youtube-lyte');?>"><input type="radio" name="lyte_position" value="1" <?php if (get_option('lyte_position','0')==="1") echo "checked" ?> /><?php _e("Center","wp-youtube-lyte") ?></label>
231
  </fieldset>
232
  </td>
233
  </tr>
@@ -240,7 +240,7 @@ function lyte_settings_page() {
240
  <label title="<?php _e('Don\'t enable HD playback','wp-youtube-lyte');?>"><input type="radio" name="lyte_hidef" value="0" <?php if (get_option('lyte_hidef','0')!=="1") echo "checked" ?> /><?php _e("No HD (default)","wp-youtube-lyte") ?></label>
241
  </fieldset>
242
  </td>
243
- </tr>
244
  <tr valign="top">
245
  <th scope="row"><?php _e("Add microdata?","wp-youtube-lyte") ?></th>
246
  <td>
@@ -267,13 +267,13 @@ function lyte_settings_page() {
267
  <fieldset>
268
  <legend class="screen-reader-text"><span><?php _e("Cache thumbnails locally?","wp-youtube-lyte") ?></span></legend>
269
  <label title="<?php _e('That would be great!','wp-youtube-lyte');?>"><input type="radio" name="lyte_local_thumb" value="1" <?php if (get_option('lyte_local_thumb','0')==="1") echo "checked" ?> /><?php _e("Yes.","wp-youtube-lyte") ?></label><br />
270
- <label title="<?php _e('No, I\'ll stick to httpv or shortcodes.','wp-youtube-lyte');?>"><input type="radio" name="lyte_local_thumb" value="0" <?php if (get_option('lyte_local_thumb','0')!=="1") echo "checked" ?> /><?php _e("No (default).","wp-youtube-lyte") ?></label>
271
  <br />
272
  <?php _e("Having the thumbnails cached locally can improve performance and will enhance visitor privacy as by default no requests will be sent to YouTube unless the video is played.","wp-youtube-lyte"); ?>
273
  </fieldset>
274
  </td>
275
  </tr>
276
- <tr valign="top">
277
  <th scope="row"><?php _e("Empty WP YouTube Lyte's cache","wp-youtube-lyte") ?></th>
278
  <td>
279
  <fieldset>
@@ -347,7 +347,7 @@ function lyte_settings_page() {
347
  jQuery( "#check_api_key" ).click(function() {
348
  jQuery("#lyte_key_check_output").show();
349
  jQuery("#lyte_key_check_output").append('<p><?php _e("Checking your key ..."); ?></p>');
350
- lyte_yt_api_key=jQuery("input#lyte_yt_api_key").val();
351
  if ((lyte_yt_api_key.length>9) &&(lyte_yt_api_key.length<99)) {
352
  var data = {
353
  'action': 'lyte_check_yt_api_key',
@@ -359,7 +359,7 @@ function lyte_settings_page() {
359
  });
360
  } else {
361
  jQuery("#lyte_key_check_output").append('<p><?php _e("That does not seem to be a correct API key!"); ?></p>');
362
- }
363
  })
364
  jQuery('#lyte_admin_feed').fadeTo("slow",1).show();
365
  jQuery('.lyte_banner').unslider({autoplay:true, delay:3500, infinite: false, arrows:{prev:'<a class="unslider-arrow prev"></a>', next:'<a class="unslider-arrow next"></a>'}}).fadeTo("slow",1).show();
@@ -389,53 +389,58 @@ function lyte_settings_page() {
389
  // ajax receiver for YT API key check
390
  add_action( 'wp_ajax_lyte_check_yt_api_key', 'lyte_check_yt_api_key_callback' );
391
  function lyte_check_yt_api_key_callback() {
392
- check_ajax_referer( "lyte_check_api_key", 'lyte_nonce' );
393
- $api_key = strip_tags($_POST['lyte_yt_api_key']);
394
 
395
- // use random video to make sure a cache is not spoiling things
396
- $vidToCheck=array("jLOnUWJTCG0","ZmnZHudtzXg","2_7oQcAkyl8","nOvv80wkSgI","pBCt5nfsZ30","KHw7gdJ14uQ","qJ_PMvjmC6M","DVwHCGAr_OE","LtOGa5M8AuU","VHO9uZX9FNU");
397
- $randVidIndex=array_rand($vidToCheck);
398
-
399
- $api_response = lyte_get_YT_resp($vidToCheck[$randVidIndex],false,"",$api_key);
400
-
401
- if (is_array($api_response)) {
402
- if (!empty($api_response["title"])) {
403
- _e("API seems OK, you can Save Changes below now.");
404
- } else if (!empty($api_response["reason"])) {
405
- _e("API key not OK, your key seems to ");
406
- switch ($api_response["reason"]) {
407
- case "keyInvalid":
408
- _e("be invalid.",'wp-youtube-lyte');
409
- break;
410
- case "ipRefererBlocked":
411
- _e("be valid, but restricted to an IP-address which is not your server's.",'wp-youtube-lyte');
412
- _e("Try changing the allowed IP for your API key to include this one: ",'wp-youtube-lyte');
413
- echo $_SERVER["SERVER_ADDR"];
414
- break;
415
- case "keyExpired":
416
- _e("have expired, please check in the Google Developer Console.",'wp-youtube-lyte');
417
- break;
418
- case "limitExceeded":
419
- case "quotaExceeded":
420
- case "rateLimitExceeded":
421
- case "userRateLimitExceeded":
422
- _e("be correct, but seems to have exceeded the number of requests that can be made with it.",'wp-youtube-lyte');
423
- break;
424
- case "videoNotFound":
425
- _e("probably work, but as the video with id ",'wp-youtube-lyte');
426
- echo $vidToCheck[$randVidIndex];
427
- _e(" was not found we cannot be sure, please try again.",'wp-youtube-lyte');
428
- break;
429
- default:
430
- _e("be faulty, with YouTube API returning reason: ",'wp-youtube-lyte');
431
- echo $api_response["reason"];
432
- }
433
- }
434
- } else {
435
- _e("Something went wrong, WP YouTube Lyte might not have been able to retrieve information from the YouTube API, got error: ",'wp-youtube-lyte');
436
- print_r($api_response);
437
- }
438
- wp_die();
 
 
 
 
 
439
  }
440
 
441
  function getFutttaFeeds($url) {
9
  add_action('admin_menu', 'lyte_create_menu');
10
 
11
  if (get_option('lyte_emptycache','0')==="1") {
12
+ $emptycache=lyte_rm_cache();
13
+ update_option('lyte_emptycache','0');
14
+ if ($emptycache==="OK") {
15
+ add_action('admin_notices', 'lyte_cacheclear_ok_notice');
16
+ } elseif ($emptycache==="PART") {
17
+ add_action('admin_notices', 'lyte_cacheclear_part_notice');
18
+ update_option('lyte_emptycache','1'); // to ensure cache-purging continues
19
+ } else {
20
+ add_action('admin_notices', 'lyte_cacheclear_fail_notice');
21
+ }
22
  }
23
 
24
  function lyte_cacheclear_ok_notice() {
25
+ echo '<div class="updated"><p>';
26
+ _e('Your WP YouTube Lyte cache has been succesfully cleared.', 'wp-youtube-lyte' );
27
+ echo '</p></div>';
28
  }
29
 
30
  function lyte_cacheclear_part_notice() {
31
+ echo '<div class="error"><p>';
32
+ _e('WP YouTube Lyte cache was partially cleared, refresh this page to continue purging.', 'wp-youtube-lyte' );
33
+ echo '</p></div>';
34
  }
35
 
36
  function lyte_cacheclear_fail_notice() {
37
+ echo '<div class="error"><p>';
38
+ _e('There was a problem, the WP YouTube Lyte cache could not be cleared.', 'wp-youtube-lyte' );
39
+ echo '</p></div>';
40
  }
41
 
42
  function lyte_create_menu() {
47
  }
48
 
49
  function register_lyte_settings() {
50
+ register_setting( 'lyte-settings-group', 'lyte_show_links' );
51
+ register_setting( 'lyte-settings-group', 'lyte_size' );
52
+ register_setting( 'lyte-settings-group', 'lyte_hidef' );
53
+ register_setting( 'lyte-settings-group', 'lyte_position' );
54
+ register_setting( 'lyte-settings-group', 'lyte_notification' );
55
+ register_setting( 'lyte-settings-group', 'lyte_microdata' );
56
+ register_setting( 'lyte-settings-group', 'lyte_emptycache' );
57
+ register_setting( 'lyte-settings-group', 'lyte_greedy' );
58
+ register_setting( 'lyte-settings-group', 'lyte_yt_api_key' );
59
+ register_setting( 'lyte-settings-group', 'lyte_local_thumb' );
60
  }
61
 
62
  function lyte_admin_scripts() {
63
+ wp_enqueue_script('jqcookie', plugins_url('/external/jquery.cookie.min.js', __FILE__), array('jquery'),null,true);
64
  wp_enqueue_script('unslider', plugins_url('/external/unslider-min.js', __FILE__), array('jquery'),null,true);
65
  }
66
 
70
  }
71
 
72
  function lyte_admin_nag_apikey() {
73
+ echo "<div class=\"update-nag\">";
74
+ _e('For WP YouTube Lyte to function optimally, you should enter an YouTube API key ', 'wp-youtube-lyte');
75
+ echo " <a href=\"options-general.php?page=lyte_settings_page\">";
76
+ _e('in the settings screen.','wp-youtube-lyte');
77
+ echo "</a>.</div>";
78
  }
79
 
80
  $lyte_yt_api_key=get_option('lyte_yt_api_key','');
81
  $lyte_yt_api_key=apply_filters('lyte_filter_yt_api_key', $lyte_yt_api_key);
82
  if (empty($lyte_yt_api_key)) {
83
+ add_action('admin_notices', 'lyte_admin_nag_apikey');
84
+ }
85
 
86
  function lyte_admin_api_error(){
87
+ $yt_error=json_decode(get_option('lyte_api_error'),1);
88
+ echo '<div class="error"><p>';
89
+ _e('WP YouTube Lyte got the following error back from the YouTube API: ','wp-youtube-lyte');
90
+ echo "<strong>".$yt_error["reason"]."</strong>";
91
+ echo " (".date("r",$yt_error["timestamp"]).").";
92
+ echo '</a>.</p></div>';
93
+ update_option('lyte_api_error','');
94
  }
95
 
96
  if (get_option('lyte_api_error','')!=='') {
97
+ add_action('admin_notices', 'lyte_admin_api_error');
98
+ }
99
 
100
  function lyte_settings_page() {
101
+ global $pSize, $pSizeOrder;
102
  ?>
103
  <style>
104
  /* rss block */
172
  <form method="post" action="options.php">
173
  <?php settings_fields( 'lyte-settings-group' ); ?>
174
  <table class="form-table">
175
+ <input type="hidden" name="lyte_notification" value="<?php echo get_option('lyte_notification','0'); ?>" />
176
+ <tr valign="top">
177
+ <th scope="row"><?php _e("Your YouTube API key.","wp-youtube-lyte") ?></th>
178
+ <td>
179
+ <?php // only show api key input field if there's no result from filter
180
+ $filter_key=apply_filters('lyte_filter_yt_api_key','');
181
+ if (empty($filter_key)) { ?>
182
+ <fieldset>
183
+ <legend class="screen-reader-text"><span><?php _e("Please enter your YouTube API key.","wp-youtube-lyte") ?></span></legend>
184
+ <label title="<?php _e('API key','wp-youtube-lyte'); ?>"><input type="text" size="28" name="lyte_yt_api_key" id="lyte_yt_api_key" value="<?php echo get_option('lyte_yt_api_key',''); ?>"><span id="check_api_key" class="submit button-secondary" style="margin:0px 5px;"><?php _e("Test Key"); ?></span></label><br />
185
+ <div id="lyte_key_check_output" style="display:none;margin-bottom:5px;background-color:white;border-left:solid;border-width:4px;border-color:#2ea2cc;padding:5px 5px 5px 15px;"></div>
186
+ <?php _e("WP YouTube Lyte uses YouTube's API to fetch information on each video. For your site to use that API, you will have to <a href=\"https://console.developers.google.com/project/\" target=\"_blank\">register your site as a new application</a>, enable the YouTube API for it and get a server key and fill it out here.","wp-youtube-lyte"); ?>
187
+ </fieldset>
188
+ <?php } else { ?>
189
+ <?php _e("Great, your YouTube API key has been taken care of!","wp-youtube-lyte"); ?>
190
+ <?php } ?>
191
+ </td>
192
+ </tr>
193
  <tr valign="top">
194
  <th scope="row"><?php _e("Player size","wp-youtube-lyte") ?>:</th>
195
  <td>
196
  <fieldset><legend class="screen-reader-text"><span><?php _e("Player size","wp-youtube-lyte") ?></span></legend>
197
+ <?php
198
+ $sel = !is_bool(get_option('lyte_size')) ? (int) get_option('lyte_size') : 0;
199
+ foreach (array("169","43") as $f) {
200
+ foreach ($pSizeOrder[$f] as $i) {
201
+ $pS=$pSize[$i];
202
+ if ($pS['a']===true) {
203
+ ?>
204
+ <label title="<?php echo $pS['w']."X".$pS['h']; ?>"><input type="radio" name="lyte_size" class="l_size" value="<?php echo $i."\"";if($i===$sel) echo " checked";echo " /> ".$pS['w']."X".$pS['h']." (".$pS['t'];?>)</label><br />
205
+ <?php
206
+ }
207
+ }
208
+ ?><br /><?php
209
+ }
210
+ ?>
211
  </fieldset>
212
  </td>
213
  </tr>
214
  <tr valign="top">
215
+ <th scope="row"><?php _e("Add links below the embedded videos?","wp-youtube-lyte") ?></th>
216
+ <td>
217
+ <fieldset>
218
+ <legend class="screen-reader-text"><span><?php _e("Show links?","wp-youtube-lyte") ?></span></legend>
219
+ <label title="<?php _e('Show YouTube-link','wp-youtube-lyte');?>"><input type="radio" name="lyte_show_links" value="1" <?php if (get_option('lyte_show_links')==="1" || get_option('lyte_show_links')==="2") echo "checked" ?> /><?php _e(" Add YouTube-link.","wp-youtube-lyte") ?></label><br />
220
+ <label title="<?php _e('Don\'t include links.','wp-youtube-lyte');?>"><input type="radio" name="lyte_show_links" value="0" <?php if ((get_option('lyte_show_links')!=="1") && (get_option('lyte_show_links')!=="2")) echo "checked" ?> /><?php _e(" Don't add any links.","wp-youtube-lyte") ?></label>
221
+ </fieldset>
222
+ </td>
223
  </tr>
224
  <tr valign="top">
225
  <th scope="row"><?php _e("Player position:","wp-youtube-lyte") ?></th>
227
  <fieldset>
228
  <legend class="screen-reader-text"><span><?php _e("Left, center or right?","wp-youtube-lyte"); ?></span></legend>
229
  <label title="<?php _e('Left','wp-youtube-lyte');?>"><input type="radio" name="lyte_position" value="0" <?php if (get_option('lyte_position','0')==="0") echo "checked" ?> /><?php _e("Left","wp-youtube-lyte") ?></label><br />
230
+ <label title="<?php _e('Center','wp-youtube-lyte');?>"><input type="radio" name="lyte_position" value="1" <?php if (get_option('lyte_position','0')==="1") echo "checked" ?> /><?php _e("Center","wp-youtube-lyte") ?></label>
231
  </fieldset>
232
  </td>
233
  </tr>
240
  <label title="<?php _e('Don\'t enable HD playback','wp-youtube-lyte');?>"><input type="radio" name="lyte_hidef" value="0" <?php if (get_option('lyte_hidef','0')!=="1") echo "checked" ?> /><?php _e("No HD (default)","wp-youtube-lyte") ?></label>
241
  </fieldset>
242
  </td>
243
+ </tr>
244
  <tr valign="top">
245
  <th scope="row"><?php _e("Add microdata?","wp-youtube-lyte") ?></th>
246
  <td>
267
  <fieldset>
268
  <legend class="screen-reader-text"><span><?php _e("Cache thumbnails locally?","wp-youtube-lyte") ?></span></legend>
269
  <label title="<?php _e('That would be great!','wp-youtube-lyte');?>"><input type="radio" name="lyte_local_thumb" value="1" <?php if (get_option('lyte_local_thumb','0')==="1") echo "checked" ?> /><?php _e("Yes.","wp-youtube-lyte") ?></label><br />
270
+ <label title="<?php _e('No, keep on using YouTube hosted thumbnails.','wp-youtube-lyte');?>"><input type="radio" name="lyte_local_thumb" value="0" <?php if (get_option('lyte_local_thumb','0')!=="1") echo "checked" ?> /><?php _e("No (default).","wp-youtube-lyte") ?></label>
271
  <br />
272
  <?php _e("Having the thumbnails cached locally can improve performance and will enhance visitor privacy as by default no requests will be sent to YouTube unless the video is played.","wp-youtube-lyte"); ?>
273
  </fieldset>
274
  </td>
275
  </tr>
276
+ <tr valign="top">
277
  <th scope="row"><?php _e("Empty WP YouTube Lyte's cache","wp-youtube-lyte") ?></th>
278
  <td>
279
  <fieldset>
347
  jQuery( "#check_api_key" ).click(function() {
348
  jQuery("#lyte_key_check_output").show();
349
  jQuery("#lyte_key_check_output").append('<p><?php _e("Checking your key ..."); ?></p>');
350
+ lyte_yt_api_key=jQuery("input#lyte_yt_api_key").val();
351
  if ((lyte_yt_api_key.length>9) &&(lyte_yt_api_key.length<99)) {
352
  var data = {
353
  'action': 'lyte_check_yt_api_key',
359
  });
360
  } else {
361
  jQuery("#lyte_key_check_output").append('<p><?php _e("That does not seem to be a correct API key!"); ?></p>');
362
+ }
363
  })
364
  jQuery('#lyte_admin_feed').fadeTo("slow",1).show();
365
  jQuery('.lyte_banner').unslider({autoplay:true, delay:3500, infinite: false, arrows:{prev:'<a class="unslider-arrow prev"></a>', next:'<a class="unslider-arrow next"></a>'}}).fadeTo("slow",1).show();
389
  // ajax receiver for YT API key check
390
  add_action( 'wp_ajax_lyte_check_yt_api_key', 'lyte_check_yt_api_key_callback' );
391
  function lyte_check_yt_api_key_callback() {
392
+ check_ajax_referer( "lyte_check_api_key", 'lyte_nonce' );
393
+ $api_key = strip_tags($_POST['lyte_yt_api_key']);
394
 
395
+ // use random video to make sure a cache is not spoiling things
396
+ $vidToCheck=array("ZmnZHudtzXg","2_7oQcAkyl8","nOvv80wkSgI","pBCt5nfsZ30","KHw7gdJ14uQ","qJ_PMvjmC6M","DVwHCGAr_OE","LtOGa5M8AuU","VHO9uZX9FNU");
397
+ $randVidIndex=array_rand($vidToCheck);
398
+
399
+ $api_response = lyte_get_YT_resp($vidToCheck[$randVidIndex],false,"",$api_key);
400
+
401
+ if (is_array($api_response)) {
402
+ if (!empty($api_response["title"])) {
403
+ _e("API seems OK, you can Save Changes below now.");
404
+ } else if (!empty($api_response["reason"])) {
405
+ $all_but_one = __("API key not OK, your key seems to ");
406
+ switch ($api_response["reason"]) {
407
+ case "keyInvalid":
408
+ echo $all_but_one;
409
+ _e("be invalid.",'wp-youtube-lyte');
410
+ break;
411
+ case "ipRefererBlocked":
412
+ echo $all_but_one;
413
+ _e("be valid, but restricted to an IP-address which is not your server's.",'wp-youtube-lyte');
414
+ _e("Try changing the allowed IP for your API key to include this one: ",'wp-youtube-lyte');
415
+ echo $_SERVER["SERVER_ADDR"];
416
+ break;
417
+ case "keyExpired":
418
+ echo $all_but_one;
419
+ _e("have expired, please check in the Google Developer Console.",'wp-youtube-lyte');
420
+ break;
421
+ case "limitExceeded":
422
+ case "quotaExceeded":
423
+ case "rateLimitExceeded":
424
+ case "userRateLimitExceeded":
425
+ echo $all_but_one;
426
+ _e("be correct, but seems to have exceeded the number of requests that can be made with it.",'wp-youtube-lyte');
427
+ break;
428
+ case "videoNotFound":
429
+ echo $all_but_one;
430
+ _e("probably work, but as the video with id ",'wp-youtube-lyte');
431
+ echo $vidToCheck[$randVidIndex];
432
+ _e(" was not found we cannot be sure, please try again.",'wp-youtube-lyte');
433
+ break;
434
+ default:
435
+ _e("Your API key might be OK, but the API call did not succeed or the response was not entirely expected. Technical error: ",'wp-youtube-lyte');
436
+ echo $api_response["reason"];
437
+ }
438
+ }
439
+ } else {
440
+ _e("Something went wrong, WP YouTube Lyte might not have been able to retrieve information from the YouTube API, got error: ",'wp-youtube-lyte');
441
+ print_r($api_response);
442
+ }
443
+ wp_die();
444
  }
445
 
446
  function getFutttaFeeds($url) {
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: 4.9
7
- Stable tag: 1.7.0
8
 
9
  High performance YouTube video, playlist and audio-only embeds which don't slow down your blog and offer optimal accessibility.
10
 
@@ -43,9 +43,6 @@ Just install form your Wordpress "Plugins|Add New" screen and all will be well.
43
  = Why does WP YouTube Lyte need to access the YouTube API? What is an API anyway? =
44
  An API is a way to have two pieces of software talk to each other to exchange information. In this case WP YouTube Lyte contacts YouTube to ask it for the thumbnail, the title and the description of the video you added. The thumbnail and title are visible on the webpage (in the Lyte player) while the description is in the HTML as microdata for search engines optimization reasons (see below).
45
 
46
- = What is an API key and why does WP YouTube Lyte need one all of a sudden? =
47
- Up until WP YouTube Lyte 1.5.0 the v2 YouTube API was used, but [in September 2014 Google announced it was going to decommission that version, forcing the switch to v3](http://youtube-eng.blogspot.be/2014/09/have-you-migrated-to-data-api-v3-yet.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+YouTubeEngDevBlog+%28YouTube+Engineering+and+Developers+Blog%29). A big difference between v2 and v3 is that, whereas v2 allowed "anonymous" requests, this is not the case for v3 any more. This means any request to the YouTube API v3 has to be identified with a key (a string with seamingly random letters & numbers). You can get such a key from Google for free (see below) and you have to enter that in WP YouTube Lyte's settings page.
48
-
49
  = OK, now how can get that API key? =
50
 
51
  1. Go to [Google Developer Console](https://console.developers.google.com/projectselector/apis/library) and log in with your Google account.
@@ -76,17 +73,12 @@ Yes, with some exceptions; WP YouTube Lyte will continue to work, rendering Lyte
76
  = I don't want an API key, how can I get rid of the "API key"-notice? =
77
  Just enter "none" (without the quotes) in the API key field and Lyte will stop nagging you.
78
 
79
- = What does "html5 video support" mean? =
80
- When playing, HTML5 video will not be visible for everyone (see requirements). Indeed some visitors will see the fallback Flash video instead.
81
-
82
- = What are the requirements to see embedded YouTube HTML5 video? =
83
- * Beginning 2015 YouTube announced it would switch to HTML5 video by default.
84
- * This will work in browsers that support the h264 or WebM video codecs, most modern browser should work.
85
- * Browsers that don't support those codecs will, upon playing, fall back to Flash.
86
-
87
  = Does WP YouTube Lyte protect my visitor's privacy? =
88
  As opposed to some of the [most important](http://blog.futtta.be/2010/12/15/wordpress-com-stats-trojan-horse-for-quantcast-tracking/) [plugins](http://blog.futtta.be/2010/01/22/add-to-any-removed-from-here/) there is no 3rd party tracking code in WP YouTube Lyte, but YouTube off course does see visitor requests coming in for the thumbnails unless the option to cache thumbnails locally is enabled. If thumbnails are cached locally, no request will be sent to YouTube by your visitor's browser until/ unless the video is played.
89
 
 
 
 
90
  = Can I use WP YouTube Lyte for a custom field? =
91
  Just pass the httpv url of such a field to lyte_preparse like this:
92
  `if(function_exists('lyte_preparse')) { echo lyte_preparse($video); }`
@@ -95,9 +87,6 @@ and you're good to go!
95
  = Does WP YouTube Lyte work with Infinite Scroll? =
96
  Starting from version 1.1.0 it does; in [Infinite Scroll](http://wordpress.org/extend/plugins/infinite-scroll/)'s configuration you just have to add "ly.te()" in the "Javascript to be called after the next posts are fetched"-box.
97
 
98
- = Can I still integrate with YouTube's JS API? =
99
- This was added as a beta feature in version 1.1.0; add ?enablejsapi=1 to the httpv URL. WP YouTube Lyte will pick this up, and add ?enablejsapi=1&origin=<hostname-of-blog> to the URL of the iFrame with the iFrame id being set to iF_<youtube-video-id>. As soon as your visitors plays the video, you should be able to hook up with the video.
100
-
101
  = How does WP YouTube Lyte support microdata? =
102
  * There is a [specific microdata scheme for "videoObject"](http://support.google.com/webmasters/bin/answer.py?hl=en&answer=2413309) which WP YouTube Lyte can add to your page, which Google can use to display the video thumbnail next to the search-result
103
  * This is optional and can be disabled in the options page
@@ -148,6 +137,9 @@ Just tell me, I like the feedback! Use the [Contact-page on my blog](http://blog
148
 
149
  == Changelog ==
150
 
 
 
 
151
  = 1.7.0 =
152
  * new: option to have thumbnail hosted locally to improve performance and privacy (I am not a lawyer, but this could make embedded YouTube GDPR compliant as not requests are sent to YouTube unless/ until the video is played).
153
  * removed option to add "easy youtube"-links (defunct)
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: 4.9
7
+ Stable tag: 1.7.1
8
 
9
  High performance YouTube video, playlist and audio-only embeds which don't slow down your blog and offer optimal accessibility.
10
 
43
  = Why does WP YouTube Lyte need to access the YouTube API? What is an API anyway? =
44
  An API is a way to have two pieces of software talk to each other to exchange information. In this case WP YouTube Lyte contacts YouTube to ask it for the thumbnail, the title and the description of the video you added. The thumbnail and title are visible on the webpage (in the Lyte player) while the description is in the HTML as microdata for search engines optimization reasons (see below).
45
 
 
 
 
46
  = OK, now how can get that API key? =
47
 
48
  1. Go to [Google Developer Console](https://console.developers.google.com/projectselector/apis/library) and log in with your Google account.
73
  = I don't want an API key, how can I get rid of the "API key"-notice? =
74
  Just enter "none" (without the quotes) in the API key field and Lyte will stop nagging you.
75
 
 
 
 
 
 
 
 
 
76
  = Does WP YouTube Lyte protect my visitor's privacy? =
77
  As opposed to some of the [most important](http://blog.futtta.be/2010/12/15/wordpress-com-stats-trojan-horse-for-quantcast-tracking/) [plugins](http://blog.futtta.be/2010/01/22/add-to-any-removed-from-here/) there is no 3rd party tracking code in WP YouTube Lyte, but YouTube off course does see visitor requests coming in for the thumbnails unless the option to cache thumbnails locally is enabled. If thumbnails are cached locally, no request will be sent to YouTube by your visitor's browser until/ unless the video is played.
78
 
79
+ = I use a page builder and LYTE does not seem active on the YouTube video's I add there? =
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 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); }`
87
  = Does WP YouTube Lyte work with Infinite Scroll? =
88
  Starting from version 1.1.0 it does; in [Infinite Scroll](http://wordpress.org/extend/plugins/infinite-scroll/)'s configuration you just have to add "ly.te()" in the "Javascript to be called after the next posts are fetched"-box.
89
 
 
 
 
90
  = How does WP YouTube Lyte support microdata? =
91
  * There is a [specific microdata scheme for "videoObject"](http://support.google.com/webmasters/bin/answer.py?hl=en&answer=2413309) which WP YouTube Lyte can add to your page, which Google can use to display the video thumbnail next to the search-result
92
  * This is optional and can be disabled in the options page
137
 
138
  == Changelog ==
139
 
140
+ = 1.7.1 =
141
+ * Finally fixed a nasty bug that caused API key validation to fail on PHP 7.1 and higher. A big thank you to @emilyatal, @mkalina, @nicolaottomano, @aminech, @partounian, @nicksws who all provided valuable input in [the WordPress LYTE support forum](https://wordpress.org/support/topic/youtube-api-got-error-1-2/) and tested multiple debug-versions to help fix this.
142
+
143
  = 1.7.0 =
144
  * new: option to have thumbnail hosted locally to improve performance and privacy (I am not a lawyer, but this could make embedded YouTube GDPR compliant as not requests are sent to YouTube unless/ until the video is played).
145
  * removed option to add "easy youtube"-links (defunct)
widget.php CHANGED
@@ -1,51 +1,48 @@
1
  <?php
2
  class WYLWidget extends WP_Widget {
3
  public function __construct() {
4
- parent::__construct(false, $name = 'WP YouTube Lyte');
5
  }
6
 
7
  function widget($args, $instance) {
8
  extract( $args );
9
- global $wSize, $wyl_version, $wp_lyte_plugin_url, $lyteSettings;
10
- $lyteSettings['path']= plugins_url() . "/" . dirname(plugin_basename(__FILE__)) . '/lyte/';
11
- $qsa="";
12
-
13
- $WYLtitle = apply_filters('widget_title', $instance['WYLtitle']);
14
- $WYLtext = apply_filters( 'widget_text', $instance['WYLtext'], $instance );
15
-
16
- $WYLsize = apply_filters( 'widget_text', $instance['WYLsize'], $instance );
17
- if ($WYLsize=="") $WYLsize=$wDefault;
18
-
19
- $WYLaudio = apply_filters( 'widget_text', $instance['WYLaudio'], $instance );
20
- if ($WYLaudio!=="audio") {
21
- $wrapperClass = " lidget";
22
- $audioClass = "";
23
- $wHeight = $wSize[$WYLsize]['h'];
24
- } else {
25
- $wrapperClass = "-audio lidget";
26
- $audioClass = " lyte-audio";
27
- $wHeight = "38";
28
- }
29
-
30
- $WYLurl=str_replace("httpv://","https://",trim($instance['WYLurl']));
31
- $WYLqs=substr(strstr($WYLurl,'?'),1);
32
- parse_str($WYLqs,$WYLarr);
33
 
34
  if (strpos($WYLurl,'youtu.be')) {
35
- $WYLid=substr(parse_url($WYLurl,PHP_URL_PATH),1,11);
 
 
 
 
 
36
  $PLClass="";
37
  $WYLthumb="https://img.youtube.com/vi/".$WYLid."/mqdefault.jpg";
38
- } else {
39
- if (isset($WYLarr['v'])) {
40
- $WYLid=$WYLarr['v'];
41
- $PLClass="";
42
- $WYLthumb="https://img.youtube.com/vi/".$WYLid."/mqdefault.jpg";
43
- } else if (isset($WYLarr['list'])) {
44
- $WYLid=$WYLarr['list'];
45
- $yt_resp=lyte_get_YT_resp($WYLid,true,"","",true);
46
- $WYLthumb=$yt_resp["thumbUrl"];
47
- $PLClass=" playlist";
48
- }
49
  }
50
 
51
  // do we have to serve the thumbnail from local cache?
@@ -54,129 +51,128 @@ class WYLWidget extends WP_Widget {
54
  }
55
 
56
  // filter to alter the thumbnail
57
- $WYLthumb = apply_filters( "lyte_filter_widget_thumb", $WYLthumb, $WYLid );
58
-
59
- if (isset($WYLarr['start'])) $qsa="&amp;start=".$WYLarr['start'];
60
- if (isset($WYLarr['enablejsapi'])) {
61
- $urlArr=parse_url($lyteSettings['path']);
62
- $origin=$urlArr[scheme]."://".$urlArr[host]."/";
63
- $qsa.="&amp;enablejsapi=".$WYLarr['enablejsapi']."&amp;origin=".$origin;
64
- }
65
-
66
- if (!empty($qsa)) {
67
- $esc_arr=array("&" => "\&", "?" => "\?", "=" => "\=");
68
- $qsaClass=" qsa_".strtr($qsa,$esc_arr);
69
- } else {
70
- $qsaClass="";
71
- }
72
-
73
- $WYL_dom_id="YLW_".$WYLid;
74
-
75
- ?>
76
- <?php echo $before_widget; ?>
77
  <?php if ( $WYLtitle ) echo $before_title . $WYLtitle . $after_title; ?>
78
- <div class="lyte-wrapper<?php echo $wrapperClass; ?>" style="width:<?php echo $wSize[$WYLsize]['w']; ?>px; height:<?php echo $wHeight; ?>px; min-width:200px; max-width:100%;"><div class="lyMe<?php echo $PLClass; echo $audioClass; echo $qsaClass; ?>" id="<?php echo $WYL_dom_id; ?>"><div id="lyte_<?php echo $WYLid; ?>" data-src="<?php echo $WYLthumb;?>" class="pL"><div class="play"></div><div class="ctrl"><div class="Lctrl"></div></div></div></div><noscript><a href="https://youtu.be/<?php echo $WYLid;?>"><img src="<?php echo $WYLthumb; ?>" alt="" /></a></noscript></div>
79
- <div><?php echo $WYLtext ?></div>
80
  <?php echo $after_widget; ?>
81
  <?php
82
- lyte_initer();
83
  }
84
 
85
- function update($new_instance, $old_instance) {
86
- $instance = $old_instance;
87
- $instance['WYLtitle'] = strip_tags($new_instance['WYLtitle']);
88
- $instance['WYLurl'] = strip_tags($new_instance['WYLurl']);
89
- $instance['WYLsize'] = strip_tags($new_instance['WYLsize']);
90
- $instance['WYLaudio'] = strip_tags($new_instance['WYLaudio']);
91
 
92
  if ( current_user_can('unfiltered_html') ) {
93
- $instance['WYLtext'] = $new_instance['WYLtext'];
94
- } else {
95
- $instance['WYLtext'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['WYLtext']) ) );
96
- }
97
 
98
- return $instance;
99
  }
100
 
101
  function form($instance) {
102
  global $wSize, $wDefault;
103
 
104
  if (isset($instance['WYLtitle'])) {
105
- $WYLtitle = esc_attr($instance['WYLtitle']);
106
- } else {
107
- $WYLtitle = "";
108
- }
109
-
110
- if (isset($instance['WYLurl'])) {
111
- $WYLurl = esc_attr($instance['WYLurl']);
112
- } else {
113
- $WYLurl = "";
114
- }
115
-
116
- if (isset($instance['WYLtext'])) {
117
- $WYLtext = format_to_edit($instance['WYLtext']);
118
  } else {
119
- $WYLtext = "";
120
  }
121
 
122
- if (isset($instance['WYLaudio'])) {
123
- $WYLaudio = esc_attr($instance['WYLaudio']);
124
  } else {
125
- $WYLaudio = "";
126
  }
127
- if ($WYLaudio!=="audio") $WYLaudio="";
128
 
129
- if (isset($instance['WYLsize'])) {
130
- $WYLsize = esc_attr($instance['WYLsize']);
131
  } else {
132
- $WYLsize = "";
133
  }
134
 
135
- if ($WYLsize=="") $WYLsize=$wDefault;
 
 
 
 
 
 
 
 
 
 
 
136
 
 
137
  ?>
138
- <p><label for="<?php echo $this->get_field_id('WYLtitle'); ?>"><?php _e("Title:","wp-youtube-lyte") ?> <input class="widefat" id="<?php echo $this->get_field_id('WYLtitle'); ?>" name="<?php echo $this->get_field_name('WYLtitle'); ?>" type="text" value="<?php echo $WYLtitle; ?>" /></label></p>
139
- <p><label for="<?php echo $this->get_field_id('WYLsize'); ?>"><?php _e("Size:","wp-youtube-lyte") ?>
140
- <select class="widefat" id="<?php echo $this->get_field_id('WYLsize'); ?>" name="<?php echo $this->get_field_name('WYLsize'); ?>">
141
- <?php
142
- foreach ($wSize as $x => $size) {
143
- if ($x==$WYLsize) {
144
- $selected=" selected=\"true\"";
145
- } else {
146
- $selected="";
147
- }
148
-
149
- if ($wSize[$x]['depr']!==true) {
150
- echo "<option value=\"".$x."\"".$selected.">".$wSize[$x]['w']."X".$wSize[$x]['h']."</option>";
151
- }
152
- $x++;
153
- }
154
- ?>
155
- </select>
156
- </label></p>
157
- <p><label for="<?php echo $this->get_field_id('WYLaudio'); ?>"><?php _e("Type:","wp-youtube-lyte") ?>
158
  <select class="widefat" id="<?php echo $this->get_field_id('WYLaudio'); ?>" name="<?php echo $this->get_field_name('WYLaudio'); ?>">
159
- <?php
160
- if($WYLaudio==="audio") {
161
- $aselected=" selected=\"true\"";
162
- $vselected="";
163
- } else {
164
- $vselected=" selected=\"true\"";
165
- $aselected="";
166
- }
167
  echo "<option value=\"audio\"".$aselected.">".__("audio","wp-youtube-lyte")."</option>";
168
- echo "<option value=\"video\"".$vselected.">".__("video","wp-youtube-lyte")."</option>";
169
- ?>
170
  </select>
171
  </label></p>
172
- <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>
173
- <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>
174
  <?php
175
  }
176
  }
177
 
178
  function lyte_register_widget() {
179
- register_widget('WYLWidget');
180
  }
181
 
182
  add_action('widgets_init', 'lyte_register_widget');
1
  <?php
2
  class WYLWidget extends WP_Widget {
3
  public function __construct() {
4
+ parent::__construct(false, $name = 'WP YouTube Lyte');
5
  }
6
 
7
  function widget($args, $instance) {
8
  extract( $args );
9
+ global $wSize, $wyl_version, $wp_lyte_plugin_url, $lyteSettings;
10
+ $lyteSettings['path']= plugins_url() . "/" . dirname(plugin_basename(__FILE__)) . '/lyte/';
11
+ $qsa="";
12
+
13
+ $WYLtitle = apply_filters('widget_title', $instance['WYLtitle']);
14
+ $WYLtext = apply_filters( 'widget_text', $instance['WYLtext'], $instance );
15
+ $WYLsize = apply_filters( 'widget_text', $instance['WYLsize'], $instance );
16
+ if ($WYLsize=="") $WYLsize=$wDefault;
17
+ $WYLaudio = apply_filters( 'widget_text', $instance['WYLaudio'], $instance );
18
+ if ($WYLaudio!=="audio") {
19
+ $wrapperClass = " lidget";
20
+ $audioClass = "";
21
+ $wHeight = $wSize[$WYLsize]['h'];
22
+ } else {
23
+ $wrapperClass = "-audio lidget";
24
+ $audioClass = " lyte-audio";
25
+ $wHeight = "38";
26
+ }
27
+ $WYLurl=str_replace("httpv://","https://",trim($instance['WYLurl']));
28
+ $WYLqs=substr(strstr($WYLurl,'?'),1);
29
+ parse_str($WYLqs,$WYLarr);
 
 
 
30
 
31
  if (strpos($WYLurl,'youtu.be')) {
32
+ $WYLid=substr(parse_url($WYLurl,PHP_URL_PATH),1,11);
33
+ $PLClass="";
34
+ $WYLthumb="https://img.youtube.com/vi/".$WYLid."/mqdefault.jpg";
35
+ } else {
36
+ if (isset($WYLarr['v'])) {
37
+ $WYLid=$WYLarr['v'];
38
  $PLClass="";
39
  $WYLthumb="https://img.youtube.com/vi/".$WYLid."/mqdefault.jpg";
40
+ } else if (isset($WYLarr['list'])) {
41
+ $WYLid=$WYLarr['list'];
42
+ $yt_resp=lyte_get_YT_resp($WYLid,true,"","",true);
43
+ $WYLthumb=$yt_resp["thumbUrl"];
44
+ $PLClass=" playlist";
45
+ }
 
 
 
 
 
46
  }
47
 
48
  // do we have to serve the thumbnail from local cache?
51
  }
52
 
53
  // filter to alter the thumbnail
54
+ $WYLthumb = apply_filters( "lyte_filter_widget_thumb", $WYLthumb, $WYLid );
55
+
56
+ if (isset($WYLarr['start'])) $qsa="&amp;start=".$WYLarr['start'];
57
+ if (isset($WYLarr['enablejsapi'])) {
58
+ $urlArr=parse_url($lyteSettings['path']);
59
+ $origin=$urlArr[scheme]."://".$urlArr[host]."/";
60
+ $qsa.="&amp;enablejsapi=".$WYLarr['enablejsapi']."&amp;origin=".$origin;
61
+ }
62
+
63
+ if (!empty($qsa)) {
64
+ $esc_arr=array("&" => "\&", "?" => "\?", "=" => "\=");
65
+ $qsaClass=" qsa_".strtr($qsa,$esc_arr);
66
+ } else {
67
+ $qsaClass="";
68
+ }
69
+
70
+ $WYL_dom_id="YLW_".$WYLid;
71
+
72
+ ?>
73
+ <?php echo $before_widget; ?>
74
  <?php if ( $WYLtitle ) echo $before_title . $WYLtitle . $after_title; ?>
75
+ <div class="lyte-wrapper<?php echo $wrapperClass; ?>" style="width:<?php echo $wSize[$WYLsize]['w']; ?>px; height:<?php echo $wHeight; ?>px; min-width:200px; max-width:100%;"><div class="lyMe<?php echo $PLClass; echo $audioClass; echo $qsaClass; ?>" id="<?php echo $WYL_dom_id; ?>"><div id="lyte_<?php echo $WYLid; ?>" data-src="<?php echo $WYLthumb;?>" class="pL"><div class="play"></div><div class="ctrl"><div class="Lctrl"></div></div></div></div><noscript><a href="https://youtu.be/<?php echo $WYLid;?>"><img src="<?php echo $WYLthumb; ?>" alt="" /></a></noscript></div>
76
+ <div><?php echo $WYLtext ?></div>
77
  <?php echo $after_widget; ?>
78
  <?php
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']);
86
+ $instance['WYLsize'] = strip_tags($new_instance['WYLsize']);
87
+ $instance['WYLaudio'] = strip_tags($new_instance['WYLaudio']);
88
 
89
  if ( current_user_can('unfiltered_html') ) {
90
+ $instance['WYLtext'] = $new_instance['WYLtext'];
91
+ } else {
92
+ $instance['WYLtext'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['WYLtext']) ) );
93
+ }
94
 
95
+ return $instance;
96
  }
97
 
98
  function form($instance) {
99
  global $wSize, $wDefault;
100
 
101
  if (isset($instance['WYLtitle'])) {
102
+ $WYLtitle = esc_attr($instance['WYLtitle']);
 
 
 
 
 
 
 
 
 
 
 
 
103
  } else {
104
+ $WYLtitle = "";
105
  }
106
 
107
+ if (isset($instance['WYLurl'])) {
108
+ $WYLurl = esc_attr($instance['WYLurl']);
109
  } else {
110
+ $WYLurl = "";
111
  }
 
112
 
113
+ if (isset($instance['WYLtext'])) {
114
+ $WYLtext = format_to_edit($instance['WYLtext']);
115
  } else {
116
+ $WYLtext = "";
117
  }
118
 
119
+ if (isset($instance['WYLaudio'])) {
120
+ $WYLaudio = esc_attr($instance['WYLaudio']);
121
+ } else {
122
+ $WYLaudio = "";
123
+ }
124
+ if ($WYLaudio!=="audio") $WYLaudio="";
125
+
126
+ if (isset($instance['WYLsize'])) {
127
+ $WYLsize = esc_attr($instance['WYLsize']);
128
+ } else {
129
+ $WYLsize = "";
130
+ }
131
 
132
+ if ($WYLsize=="") $WYLsize=$wDefault;
133
  ?>
134
+ <p><label for="<?php echo $this->get_field_id('WYLtitle'); ?>"><?php _e("Title:","wp-youtube-lyte") ?> <input class="widefat" id="<?php echo $this->get_field_id('WYLtitle'); ?>" name="<?php echo $this->get_field_name('WYLtitle'); ?>" type="text" value="<?php echo $WYLtitle; ?>" /></label></p>
135
+ <p><label for="<?php echo $this->get_field_id('WYLsize'); ?>"><?php _e("Size:","wp-youtube-lyte") ?>
136
+ <select class="widefat" id="<?php echo $this->get_field_id('WYLsize'); ?>" name="<?php echo $this->get_field_name('WYLsize'); ?>">
137
+ <?php
138
+ foreach ($wSize as $x => $size) {
139
+ if ($x==$WYLsize) {
140
+ $selected=" selected=\"true\"";
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
+ }
148
+ $x++;
149
+ }
150
+ ?>
151
+ </select>
152
+ </label></p>
153
+ <p><label for="<?php echo $this->get_field_id('WYLaudio'); ?>"><?php _e("Type:","wp-youtube-lyte") ?>
154
  <select class="widefat" id="<?php echo $this->get_field_id('WYLaudio'); ?>" name="<?php echo $this->get_field_name('WYLaudio'); ?>">
155
+ <?php
156
+ if($WYLaudio==="audio") {
157
+ $aselected=" selected=\"true\"";
158
+ $vselected="";
159
+ } else {
160
+ $vselected=" selected=\"true\"";
161
+ $aselected="";
162
+ }
163
  echo "<option value=\"audio\"".$aselected.">".__("audio","wp-youtube-lyte")."</option>";
164
+ echo "<option value=\"video\"".$vselected.">".__("video","wp-youtube-lyte")."</option>";
165
+ ?>
166
  </select>
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');
176
  }
177
 
178
  add_action('widgets_init', 'lyte_register_widget');
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.0
8
  Author URI: http://blog.futtta.be/
9
  Text Domain: wp-youtube-lyte
10
  Domain Path: /languages
@@ -18,29 +18,29 @@ $lyte_db_version=get_option('lyte_version','none');
18
 
19
  /** have we updated? */
20
  if ($lyte_db_version !== $lyte_version) {
21
- switch($lyte_db_version) {
22
- case "1.5.0":
23
- lyte_rm_cache();
24
- break;
25
- case "1.4.2":
26
- case "1.4.1":
27
- case "1.4.0":
28
- lyte_rm_cache();
29
- lyte_not_greedy();
30
- break;
31
- }
32
- update_option('lyte_version',$lyte_version);
33
- $lyte_db_version=$lyte_version;
34
  }
35
 
36
  /** are we in debug-mode */
37
  if (!$debug) {
38
- $wyl_version=$lyte_version;
39
- $wyl_file="lyte-min.js";
40
  } else {
41
- $wyl_version=rand()/1000;
42
- $wyl_file="lyte.js";
43
- lyte_rm_cache();
44
  }
45
 
46
  /** get paths, language and includes */
@@ -56,10 +56,10 @@ if ((is_bool($oSize)) || ($pSize[$oSize]['a']===false)) { $sel = (int) $pDefault
56
  $pSizeFormat=$pSize[$sel]['f'];
57
  $j=0;
58
  foreach ($pSizeOrder[$pSizeFormat] as $sizeId) {
59
- $sArray[$j]['w']=(int) $pSize[$sizeId]['w'];
60
- $sArray[$j]['h']=(int) $pSize[$sizeId]['h'];
61
- if ($sizeId===$sel) $selSize=$j;
62
- $j++;
63
  }
64
 
65
  /** get other options and push in array*/
@@ -75,571 +75,575 @@ $lyteSettings['scheme'] = ( is_ssl() ) ? "https" : "http";
75
 
76
  /** API: filter hook to alter $lyteSettings */
77
  function lyte_settings_enforcer() {
78
- global $lyteSettings;
79
- $lyteSettings = apply_filters( 'lyte_settings', $lyteSettings );
80
- }
81
  add_action('after_setup_theme','lyte_settings_enforcer');
82
 
83
  function lyte_parse($the_content,$doExcerpt=false) {
84
- /** bail if amp */
85
- if ( is_amp()) { return $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/';
90
- $urlArr=parse_url($lyteSettings['path']);
91
- $origin=$urlArr['scheme']."://".$urlArr['host']."/";
92
-
93
- /** API: filter hook to preparse the_content, e.g. to force normal youtube links to be parsed */
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
-
105
- if ( strpos($the_content,"<!-- wp:") !== false && strpos($the_content,"youtu") !== false ) {
106
- /*
107
- * do Gutenberg stuff here, playlists if needed first and then single videos
108
- *
109
- * having Gutenberg markup in HTML comments is ugly as hell
110
- * esp. for 3rd parties such as Lyte who have to parse info out of that
111
- *
112
- * Luke Cavanagh; thanks for the Gutenbeard reference and for the funny animated gif :)
113
- * https://media1.giphy.com/media/l2QZTNMFTQ2Z00zHG/giphy.gif
114
- */
115
- if (strpos($the_content,'/playlist?list=') !== false ) {
116
- $gutenbeard_playlist_regex = '%<\!--\s?wp:(?:core[-|/])?embed(?:/youtube)?\s?{"url":"https://www.youtube.com/playlist\?list=(.*)"}\s?-->.*<\!--\s?/wp:(?:core[-|/])?embed(?:/youtube)?\s?-->%Us';
117
- $the_content = preg_replace($gutenbeard_playlist_regex, 'httpv://www.youtube.com/playlist?list=\1',$the_content);
118
- }
119
- $gutenbeard_single_regex = '%<\!--\s?wp:(?:core[-|/])?embed(?:/youtube)?\s?{"url":"https?://(?:www\.)?youtu(?:be\.com|.be)/(?:watch\?v=)?(.*)"}\s?-->.*<\!--\s?/wp:(?:core[-|/])?embed(?:/youtube)?\s?-->%Us';
120
- $the_content = preg_replace($gutenbeard_single_regex, 'httpv://www.youtube.com/watch?v=\1',$the_content);
121
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
- if((strpos($the_content, "httpv")!==FALSE)||(strpos($the_content, "httpa")!==FALSE)) {
124
- if (apply_filters('lyte_remove_wpautop',false)) {
125
- remove_filter('the_content','wpautop');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
- $char_codes = array('&#215;','&#8211;');
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();
135
- $toCache_index=array();
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 */
143
- $match[12] = apply_filters( 'lyte_match_preparse_fragment',$match[12] );
144
-
145
- preg_match("/stepSize\=([\+\-0-9]{2})/",$match[12],$sMatch);
146
- preg_match("/showinfo\=([0-1]{1})/",$match[12],$showinfo);
147
- preg_match("/start\=([0-9]*)/",$match[12],$start);
148
- preg_match("/enablejsapi\=([0-1]{1})/",$match[12],$jsapi);
149
- preg_match("/hqThumb\=([0-1]{1})/",$match[12],$hqThumb);
150
- preg_match("/noMicroData\=([0-1]{1})/",$match[12],$microData);
151
-
152
- $thumb="normal";
153
- if ($lyteSettings['hidef']==="1") {
154
- $thumb="highres";
155
- } else if (!empty($hqThumb)) {
156
- if ($hqThumb[0]==="hqThumb=1") {
157
- $thumb="highres";
158
- }
159
- }
160
-
161
- $noMicroData="0";
162
- if (!empty($microData)) {
163
- if ($microData[0]==="noMicroData=1") {
164
- $noMicroData="1";
165
- }
166
- }
167
 
168
- $qsa="";
169
- if (!empty($showinfo[0])) {
170
- $qsa="&amp;".$showinfo[0];
171
- $titleClass=" hidden";
172
- } else {
173
- $titleClass="";
174
- }
175
- if (!empty($start[0])) $qsa.="&amp;".$start[0];
176
- if (!empty($jsapi[0])) $qsa.="&amp;".$jsapi[0]."&amp;origin=".$origin;
177
-
178
- if (!empty($qsa)) {
179
- $esc_arr=array("&" => "\&", "?" => "\?", "=" => "\=");
180
- $qsaClass=" qsa_".strtr($qsa,$esc_arr);
181
- } else {
182
- $qsaClass="";
183
- }
184
-
185
- if (!empty($sMatch)) {
186
- $newSize=(int) $sMatch[1];
187
- $newPos=(int) $lyteSettings['selSize']+$newSize;
188
- if ($newPos<0) {
189
- $newPos=0;
190
- } else if ($newPos > count($lyteSettings['sizeArray'])-1) {
191
- $newPos=count($lyteSettings['sizeArray'])-1;
192
- }
193
- $lyteSettings[2]=$lyteSettings['sizeArray'][$newPos]['w'];
194
- $lyteSettings[3]=$lyteSettings['sizeArray'][$newPos]['h'];
195
- } else {
196
- $lyteSettings[2]=$lyteSettings['sizeArray'][$lyteSettings['selSize']]['w'];
197
- $lyteSettings[3]=$lyteSettings['sizeArray'][$lyteSettings['selSize']]['h'];
198
- }
199
-
200
- if ($match[1]!=="a") {
201
- $divHeight=$lyteSettings[3];
202
- $audioClass="";
203
- $audio=false;
204
- } else {
205
- $audio=true;
206
- $audioClass=" lyte-audio";
207
- $divHeight=38;
208
- }
209
-
210
- $NSimgHeight=$divHeight-20;
211
-
212
- if ($match[11]!="") {
213
- $plClass=" playlist";
214
- $vid=$match[11];
215
- switch ($lyteSettings['links']) {
216
- case "0":
217
- $noscript_post="<br />".__("Watch this playlist on YouTube","wp-youtube-lyte");
218
- $noscript="<noscript><a href=\"".$lyteSettings['scheme']."://youtube.com/playlist?list=".$vid."\">".$noscript_post."</a></noscript>";
219
- $lytelinks_txt="";
220
- break;
221
- default:
222
- $noscript="";
223
- $lytelinks_txt="<div class=\"lL\" style=\"max-width:100%;width:".$lyteSettings[2]."px;".$lyteSettings['pos']."\">".__("Watch this playlist","wp-youtube-lyte")." <a href=\"".$lyteSettings['scheme']."://www.youtube.com/playlist?list=".$vid."\">".__("on YouTube","wp-youtube-lyte")."</a></div>";
224
- }
225
- } else if ($match[9]!="") {
226
- $plClass="";
227
- $vid=$match[9];
228
- switch ($lyteSettings['links']) {
229
- case "0":
230
- $noscript_post="<br />".__("Watch this video on YouTube","wp-youtube-lyte");
231
- $lytelinks_txt="<div class=\"lL\" style=\"max-width:100%;width:".$lyteSettings[2]."px;".$lyteSettings['pos']."\"></div>";
232
- break;
233
- default:
234
- $noscript_post="";
235
- $lytelinks_txt="<div class=\"lL\" style=\"max-width:100%;width:".$lyteSettings[2]."px;".$lyteSettings['pos']."\">".__("Watch this video","wp-youtube-lyte")." <a href=\"".$lyteSettings['scheme']."://youtu.be/".$vid."\">".__("on YouTube","wp-youtube-lyte")."</a>.</div>";
236
- }
237
-
238
- $noscript="<noscript><a href=\"".$lyteSettings['scheme']."://youtu.be/".$vid."\"><img src=\"".$lyteSettings['scheme']."://i.ytimg.com/vi/".$vid."/0.jpg\" alt=\"\" width=\"".$lyteSettings[2]."\" height=\"".$NSimgHeight."\" />".$noscript_post."</a></noscript>";
239
- }
240
-
241
- // fetch data from YT api (v2 or v3)
242
- $isPlaylist=false;
243
- if ($plClass===" playlist") {
244
- $isPlaylist=true;
245
- }
246
- $cachekey = '_lyte_' . $vid;
247
- $yt_resp_array=lyte_get_YT_resp($vid,$isPlaylist,$cachekey);
248
 
249
  // If there was a result from youtube or from cache, use it
250
  if ( $yt_resp_array ) {
251
- if (is_array($yt_resp_array)) {
252
- if ($isPlaylist!==true) {
253
- // captions, thanks to Benetech
254
- $captionsMeta="";
255
- $doCaptions=true;
256
-
257
- /** API: filter hook to disable captions */
258
- $doCaptions = apply_filters( 'lyte_docaptions', $doCaptions );
259
-
260
- if(($lyteSettings['microdata'] === "1")&&($noMicroData !== "1" )&&($doCaptions === true)) {
261
- if (array_key_exists('captions_data',$yt_resp_array)) {
262
- if ($yt_resp_array["captions_data"]=="true") {
263
- $captionsMeta="<meta itemprop=\"accessibilityFeature\" content=\"captions\" />";
264
- $forceCaptionsUpdate=false;
265
- } else {
266
- $forceCaptionsUpdate=true;
267
- }
268
- } else {
269
- $forceCaptionsUpdate=true;
270
- $yt_resp_array["captions_data"]=false;
271
- }
272
-
273
- if ($forceCaptionsUpdate===true) {
274
- $captionsMeta="";
275
- $threshold = 30;
276
- if (array_key_exists('captions_timestamp',$yt_resp_array)) {
277
- $cache_timestamp = $yt_resp_array["captions_timestamp"];
278
- $interval = (strtotime("now") - $cache_timestamp)/60/60/24;
279
- } else {
280
- $cache_timestamp = false;
281
- $interval = $threshold+1;
282
- }
283
-
284
- if(!is_int($cache_timestamp) || ($interval > $threshold && !is_null( $yt_resp_array["captions_data"]))) {
285
- $yt_resp_array['captions_timestamp'] = strtotime("now");
286
- wp_schedule_single_event(strtotime("now") + 60*60, 'schedule_captions_lookup', array($postID, $cachekey, $vid));
287
- $yt_resp_precache=json_encode($yt_resp_array);
288
- $toCache=base64_encode(gzcompress($yt_resp_precache));
289
- update_post_meta($postID, $cachekey, $toCache);
290
- }
291
- }
292
- }
293
- }
294
- $thumbUrl="";
295
- if (($thumb==="highres") && (!empty($yt_resp_array["HQthumbUrl"]))){
296
- $thumbUrl=$yt_resp_array["HQthumbUrl"];
297
- } else {
298
- if (!empty($yt_resp_array["thumbUrl"])) {
299
- $thumbUrl=$yt_resp_array["thumbUrl"];
300
- } else {
301
- $thumbUrl="//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
302
- }
303
- }
304
- } else {
305
- // no useable result from youtube, fallback on video thumbnail (doesn't work on playlist)
306
- $thumbUrl = "//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
307
- }
308
- } else {
309
- // same fallback
310
- $thumbUrl = "//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
311
- }
312
-
313
- // do we have to serve the thumbnail from local cache?
314
- if (get_option('lyte_local_thumb','0') === '1') {
315
- $thumbUrl = plugins_url( 'lyteThumbs.php?origThumbUrl=' . urlencode($thumbUrl) , __FILE__ );
316
- }
317
 
318
- /** API: filter hook to override thumbnail URL */
319
- $thumbUrl = apply_filters( 'lyte_match_thumburl', $thumbUrl );
320
-
321
-
322
- if ($audio===true) {
323
- $wrapper="<div class=\"lyte-wrapper-audio\" style=\"width:".$lyteSettings[2]."px;max-width:100%;overflow:hidden;height:38px;".$lyteSettings['pos']."\">";
324
- } else {
325
- $wrapper="<div class=\"lyte-wrapper".$lyteSettings['ratioClass']."\" style=\"width:".$lyteSettings[2]."px;max-width: 100%;".$lyteSettings['pos']."\">";
326
- }
327
-
328
- if ($doExcerpt) {
329
- $lytetemplate="";
330
- $templateType="excerpt";
331
- } elseif ($lyte_feed) {
332
- $postURL = get_permalink( $postID );
333
- $textLink = ($lyteSettings['links']===0)? "" : "<br />".strip_tags($lytelinks_txt, '<a>')."<br />";
334
- $lytetemplate = "<a href=\"".$postURL."\"><img src=\"".$thumbUrl."\" alt=\"YouTube Video\"></a>".$textLink;
335
- $templateType="feed";
336
- } elseif (($audio !== true) && ( $plClass !== " playlist") && (($lyteSettings['microdata'] === "1")&&($noMicroData !== "1" ))) {
337
- $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;
338
- $templateType="postMicrodata";
339
- } else {
340
- $lytetemplate = $wrapper."<div class=\"lyMe".$audioClass.$hidefClass.$plClass.$qsaClass."\" id=\"WYL_".$vid."\"><div id=\"lyte_".$vid."\" data-src=\"".$thumbUrl."\" class=\"pL\">";
341
-
342
- if (isset($yt_resp_array) && !empty($yt_resp_array) && !empty($yt_resp_array["title"])) {
 
 
 
 
343
  $lytetemplate .= "<div class=\"tC".$titleClass."\"><div class=\"tT\">".$yt_resp_array['title']."</div></div>";
344
  }
345
-
346
- $lytetemplate .= "<div class=\"play\"></div><div class=\"ctrl\"><div class=\"Lctrl\"></div><div class=\"Rctrl\"></div></div></div>".$noscript."</div></div>".$lytelinks_txt;
347
- $templateType="post";
348
- }
349
-
350
- /** API: filter hook to parse template before being applied */
351
- $lytetemplate = apply_filters( 'lyte_match_postparse_template',$lytetemplate,$templateType );
352
- $the_content = preg_replace($lytes_regexp, $lytetemplate, $the_content, 1);
353
  }
354
 
355
- // update lyte_cache_index
356
- if ((is_array($toCache_index))&&(!empty($toCache_index))) {
357
- $lyte_cache=json_decode(get_option('lyte_cache_index'),true);
358
- $lyte_cache[$postID]=$toCache_index;
359
- update_option('lyte_cache_index',json_encode($lyte_cache));
360
- }
361
 
362
- if (!$lyte_feed) {
363
- lyte_initer();
364
- }
365
- }
366
 
367
- /** API: filter hook to postparse the_content before returning */
368
- $the_content = apply_filters( 'lyte_content_postparse',$the_content );
369
 
370
- return $the_content;
371
  }
372
 
373
  function captions_lookup($postID, $cachekey, $vid) {
374
- // captions lookup at YouTube via a11ymetadata.org
375
- $response = wp_remote_request("http://api.a11ymetadata.org/captions/youtubeid=".$vid."/youtube");
376
-
377
- if(!is_wp_error($response)) {
378
- $rawJson = wp_remote_retrieve_body($response);
379
- $decodeJson = json_decode($rawJson, true);
380
-
381
- $yt_resp = get_post_meta($postID, $cachekey, true);
382
-
383
- if (!empty($yt_resp)) {
384
- $yt_resp = gzuncompress(base64_decode($yt_resp));
385
- if($yt_resp) {
386
- $yt_resp_array=json_decode($yt_resp,true);
387
-
388
- if ($decodeJson['status'] == 'success' && $decodeJson['data']['captions'] == '1') {
389
- $yt_resp_array['captions_data'] = true;
390
- } else {
391
- $yt_resp_array['captions_data'] = false;
392
- }
393
-
394
- $yt_resp_array['captions_timestamp'] = strtotime("now");
395
- $yt_resp_precache=json_encode($yt_resp_array);
396
- $toCache=base64_encode(gzcompress($yt_resp_precache));
397
- update_post_meta($postID, $cachekey, $toCache);
398
- }
399
- }
400
- }
401
  }
402
 
403
  function lyte_get_YT_resp($vid,$playlist=false,$cachekey,$apiTestKey="",$isWidget=false) {
404
- /** logic to get video info from cache or get it from YouTube and set it */
405
- global $postID, $cachekey, $toCache_index;
406
- if ( $postID && empty($apiTestKey) && !$isWidget ) {
407
- $cache_resp = get_post_meta( $postID, $cachekey, true );
408
- if (!empty($cache_resp)) {
409
- $_thisLyte = json_decode(gzuncompress(base64_decode($cache_resp)),1);
410
- // make sure there are not old APIv2 full responses in cache
411
- if (array_key_exists('entry', $_thisLyte)) {
412
- if ($_thisLyte['entry']['xmlns$yt']==="http://gdata.youtube.com/schemas/2007") {
413
- $_thisLyte = "";
414
- }
415
- }
416
- }
417
- } else if ($isWidget) {
418
- $cache_resp = get_option("lyte_widget_cache");
419
- if (!empty($cache_resp)) {
420
- $widget_cache = json_decode(gzuncompress(base64_decode($cache_resp)),1);
421
- $_thisLyte = $widget_cache[$vid];
422
- }
423
- } else {
424
- $_thisLyte = "";
425
- }
426
-
427
- if ( empty( $_thisLyte ) ) {
428
- // get info from youtube
429
- // first get yt api key
430
- $lyte_yt_api_key = get_option('lyte_yt_api_key','');
431
- $lyte_yt_api_key = apply_filters('lyte_filter_yt_api_key', $lyte_yt_api_key);
432
- if (!empty($apiTestKey)) {
433
- $lyte_yt_api_key=$apiTestKey;
434
- }
435
-
436
- if (($lyte_yt_api_key==="none") || (empty($lyte_yt_api_key))) {
437
- $_thisLyte['title']="";
438
- if ($playlist) {
439
- $_thisLyte['thumbUrl']="";
440
- $_thisLyte['HQthumbUrl']="";
441
- } else {
442
- $_thisLyte['thumbUrl']="//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
443
- $_thisLyte['HQthumbUrl']="//i.ytimg.com/vi/".$vid."/maxresdefault.jpg";
444
- }
445
- $_thisLyte['dateField']="";
446
- $_thisLyte['duration']="";
447
- $_thisLyte['description']="";
448
- $_thisLyte['captions_data']="false";
449
- $_thisLyte['captions_timestamp']=strtotime("now");
450
- return $_thisLyte;
451
- } else {
452
- // v3, feeling somewhat lonely now v2 has gently been put to sleep
453
- $yt_api_base = "https://www.googleapis.com/youtube/v3/";
454
-
455
- if ($playlist) {
456
- $yt_api_target = "playlists?part=snippet%2C+id&id=".$vid."&key=".$lyte_yt_api_key;
457
- } else {
458
- $yt_api_target = "videos?part=id%2C+snippet%2C+contentDetails&id=".$vid."&key=".$lyte_yt_api_key;
459
- }
460
- }
461
-
462
- $yt_api_url = $yt_api_base.$yt_api_target;
463
- $yt_resp = wp_remote_get($yt_api_url);
464
-
465
- // check if we got through
466
- if (is_wp_error($yt_resp)) {
467
- $_thisLyte = "";
468
- } else {
469
- $yt_resp_array=json_decode(wp_remote_retrieve_body($yt_resp),true);
470
- if(is_array($yt_resp_array)) {
471
- // extract relevant data
472
- // v3
473
- if (in_array(wp_remote_retrieve_response_code($yt_resp),array(400,403,404))) {
474
- $yt_error['code']=wp_remote_retrieve_response_code($yt_resp);
475
- $yt_error['reason']=$yt_resp_array['error']['errors'][0]['reason'];
476
- $yt_error['timestamp']=strtotime("now");
477
- if (empty($apiTestKey)) {
478
- update_option("lyte_api_error",json_encode($yt_error));
479
- } else {
480
- return $yt_error;
481
- }
482
- $_thisLyte = "";
483
- } else {
484
- if ($playlist) {
485
- $_thisLyte['title']="Playlist: ".esc_attr(sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['title']));
486
- $_thisLyte['thumbUrl']=esc_url(@$yt_resp_array['items'][0]['snippet']['thumbnails']['high']['url']);
487
- $_thisLyte['HQthumbUrl']=esc_url(@$yt_resp_array['items'][0]['snippet']['thumbnails']['maxres']['url']);
488
- $_thisLyte['dateField']=sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['publishedAt']);
489
- $_thisLyte['duration']="";
490
- $_thisLyte['description']=esc_attr(sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['description']));
491
- $_thisLyte['captions_data']="false";
492
- $_thisLyte['captions_timestamp'] = "";
493
- } else {
494
- $_thisLyte['title']=esc_attr(sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['title']));
495
- $_thisLyte['thumbUrl']=esc_url(@$yt_resp_array['items'][0]['snippet']['thumbnails']['high']['url']);
496
- $_thisLyte['HQthumbUrl']=esc_url(@$yt_resp_array['items'][0]['snippet']['thumbnails']['maxres']['url']);
497
- $_thisLyte['dateField']=sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['publishedAt']);
498
- $_thisLyte['duration']=sanitize_text_field(@$yt_resp_array['items'][0]['contentDetails']['duration']);
499
- $_thisLyte['description']=esc_attr(sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['description']));
500
- $_thisLyte['captions_data']=sanitize_text_field(@$yt_resp_array['items'][0]['contentDetails']['caption']);
501
- $_thisLyte['captions_timestamp'] = strtotime("now");
502
- }
503
- }
504
-
505
- // try to cache the result
506
- if ( (($postID) || ($isWidget)) && !empty($_thisLyte) && empty($apiTestKey) ) {
507
- $_thisLyte['lyte_date_added']=time();
508
-
509
- if ( $postID && !$isWidget ) {
510
- $yt_resp_precache=json_encode($_thisLyte);
511
-
512
- // then gzip + base64 (to limit amount of data + solve problems with wordpress removing slashes)
513
- $yt_resp_precache=base64_encode(gzcompress($yt_resp_precache));
514
-
515
- // and do the actual caching
516
- $toCache = ( $yt_resp_precache ) ? $yt_resp_precache : '{{unknown}}';
517
-
518
- update_post_meta( $postID, $cachekey, $toCache );
519
- // and finally add new cache-entry to toCache_index which will be added to lyte_cache_index pref
520
- $toCache_index[]=$cachekey;
521
- } else if ($isWidget) {
522
- $widget_cache[$vid]=$_thisLyte;
523
- update_option("lyte_widget_cache",base64_encode(gzcompress(json_encode($widget_cache))));
524
- }
525
- }
526
- }
527
- }
528
- }
529
- foreach (array("title","thumbUrl","HQthumbUrl","dateField","duration","description","captions_data","captions_timestamp") as $key) {
530
- if (!array_key_exists($key,$_thisLyte)) {
531
- $_thisLyte[$key]="";
532
  }
 
533
  }
534
- return $_thisLyte;
 
 
 
 
 
 
535
  }
536
 
537
  /* only add js/css once and only if needed */
538
  function lyte_initer() {
539
- global $lynited;
540
- if (!$lynited) {
541
- $lynited=true;
542
- add_action('wp_footer', 'lyte_init');
543
- }
544
  }
545
 
546
  /* actual initialization */
547
  function lyte_init() {
548
- global $lyteSettings;
549
- $lyte_css = ".lyte-wrapper-audio div, .lyte-wrapper div {margin:0px; overflow:hidden;} .lyte,.lyMe{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;background-color:#777;} .fourthree .lyMe, .fourthree .lyte {padding-bottom:75%;} .lidget{margin-bottom:5px;} .lidget .lyte, .widget .lyMe {padding-bottom:0!important;height:100%!important;} .lyte-wrapper-audio .lyte{height:38px!important;overflow:hidden;padding:0!important} .lyMe iframe, .lyte iframe,.lyte .pL{position:absolute !important;top:0;left:0;width:100%;height:100%!important;background:no-repeat scroll center #000;background-size:cover;cursor:pointer} .tC{left:0;position:absolute;top:0;width:100%} .tC{background-image:linear-gradient(to bottom,rgba(0,0,0,0.6),rgba(0,0,0,0))} .tT{color:#FFF;font-family:Roboto,sans-serif;font-size:16px;height:auto;text-align:left;padding:5px 10px 50px 10px} .play{background:no-repeat scroll 0 0 transparent;width:88px;height:63px;position:absolute;left:43%;left:calc(50% - 44px);left:-webkit-calc(50% - 44px);top:38%;top:calc(50% - 31px);top:-webkit-calc(50% - 31px);} .widget .play {top:30%;top:calc(45% - 31px);top:-webkit-calc(45% - 31px);transform:scale(0.6);-webkit-transform:scale(0.6);-ms-transform:scale(0.6);} .lyte:hover .play{background-position:0 -65px;} .lyte-audio .pL{max-height:38px!important} .lyte-audio iframe{height:438px!important} .ctrl{background:repeat scroll 0 -220px rgba(0,0,0,0.3);width:100%;height:40px;bottom:0px;left:0;position:absolute;} .lyte-wrapper .ctrl{display:none}.Lctrl{background:no-repeat scroll 0 -137px transparent;width:158px;height:40px;bottom:0;left:0;position:absolute} .Rctrl{background:no-repeat scroll -42px -179px transparent;width:117px;height:40px;bottom:0;right:0;position:absolute;padding-right:10px;}.lyte-audio .play{display:none}.lyte-audio .ctrl{background-color:rgba(0,0,0,1)}.hidden{display:none}";
550
-
551
- // by default show lyte vid on mobile (requiring user clicking play two times)
552
- // but can be overruled by this filter
553
- // also "do lyte mobile" when option to cache thumbnails is on to ensure privacy (gdpr)
554
- $mobLyte = apply_filters( 'lyte_do_mobile', false );
555
- if ( $mobLyte || get_option( 'lyte_local_thumb', 0 ) ) {
556
- $mobJS = "var mOs=null;";
557
- } else {
558
- $mobJS = "var mOs=navigator.userAgent.match(/(iphone|ipad|ipod|android)/i);";
559
- }
560
-
561
- /** API: filter hook to change css */
562
- $lyte_css = apply_filters( 'lyte_css', $lyte_css);
563
-
564
- 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>";
565
- echo "<script type=\"text/javascript\" async src=\"".$lyteSettings['path'].$lyteSettings['file']."\"></script>";
566
  }
567
 
568
  /** override default wp_trim_excerpt to have lyte_parse remove the httpv-links */
569
  function lyte_trim_excerpt($text) {
570
- global $post;
571
- $raw_excerpt = $text;
572
- if ( '' == $text ) {
573
- $text = get_the_content('');
574
- $text = lyte_parse($text, true);
575
- $text = strip_shortcodes( $text );
576
- $text = apply_filters('the_content', $text);
577
- $text = str_replace(']]>', ']]&gt;', $text);
578
- $excerpt_length = apply_filters('excerpt_length', 55);
579
- $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
580
- if (function_exists('wp_trim_words')) {
581
- $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
582
- } else {
583
- $length = $excerpt_length*6;
584
- $text = substr( strip_tags(trim(preg_replace('/\s+/', ' ', $text))), 0, $length );
585
- $text .= $excerpt_more;
586
- }
587
  }
588
- return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
 
589
  }
590
 
591
  /** Lyte shortcode */
592
  function shortcode_lyte($atts) {
593
- extract(shortcode_atts(array(
594
- "id" => '',
595
- "audio" => '',
596
- "playlist" => '',
597
- ), $atts));
598
 
599
- if ($audio) {$proto="httpa";} else {$proto="httpv";}
600
- if ($playlist) {$action="playlist?list=";} else {$action="watch?v=";}
601
-
602
  return lyte_parse($proto.'://www.youtube.com/'.$action.$id);
603
  }
604
 
605
  /** update functions */
606
  /** upgrade, so lyte should not be greedy */
607
  function lyte_not_greedy() {
608
- update_option( "lyte_greedy", "0" );
609
  }
610
 
611
  /** function to flush YT responses from cache */
612
  function lyte_rm_cache() {
613
- try {
614
- ini_set('max_execution_time',90); // give PHP some more time for this, post-meta can be sloooooow
615
-
616
- // cache in post_meta, for posts
617
- $lyte_posts = json_decode(get_option("lyte_cache_index"),true);
618
- $lyteCacheIterator = 0;
619
- $lytePurgeThreshold = 500;
620
- $returnCode = "OK";
621
- if (is_array($lyte_posts)){
622
- foreach ($lyte_posts as $postID => $lyte_post) {
623
- foreach ($lyte_post as $cachekey) {
624
- delete_post_meta($postID, $cachekey);
625
- }
626
- unset ($lyte_posts[$postID]);
627
- $lyteCacheIterator++;
628
- if ($lyteCacheIterator > ($lytePurgeThreshold-1)) {
629
- $returnCode = "PART";
630
- break;
631
- }
632
- }
633
- update_option("lyte_cache_index",json_encode($lyte_posts));
634
- }
635
-
636
- // and the widget cache which isn't in post_meta
637
- update_option('lyte_widget_cache','');
638
-
639
- return $returnCode;
640
- } catch(Exception $e) {
641
- return $e->getMessage();
642
- }
643
  }
644
 
645
  /** function to call from within themes */
@@ -649,33 +653,33 @@ function lyte_preparse($videoId) {
649
  }
650
 
651
  function lyte_add_action_link($links) {
652
- $links[]='<a href="' . admin_url( 'options-general.php?page=lyte_settings_page' ) . '">' . __('Settings') . '</a>';
653
- return $links;
654
  }
655
 
656
  /** is_amp, but I shouldn't have to do this, should I? */
657
  if (!function_exists("is_amp")) {
658
- function is_amp() {
659
- if ((strpos($_SERVER['REQUEST_URI'],'?amp')!==false) || (strpos($_SERVER['REQUEST_URI'],'/amp/')!==false)) {
660
- return true;
661
- } else {
662
- return false;
663
- }
664
- }
665
  }
666
 
667
  /** hooking it all up to wordpress */
668
  if ( is_admin() ) {
669
- require_once(dirname(__FILE__).'/options.php');
670
- add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'lyte_add_action_link' );
671
  } else {
672
- add_filter('the_content', 'lyte_parse', 4);
673
- add_shortcode("lyte", "shortcode_lyte");
674
- remove_filter('get_the_excerpt', 'wp_trim_excerpt');
675
- add_filter('get_the_excerpt', 'lyte_trim_excerpt');
676
- add_action('schedule_captions_lookup', 'captions_lookup', 1, 3);
677
-
678
- /** API: action hook to allow extra actions or filters to be added */
679
- do_action("lyte_actionsfilters");
680
  }
681
  ?>
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.1
8
  Author URI: http://blog.futtta.be/
9
  Text Domain: wp-youtube-lyte
10
  Domain Path: /languages
18
 
19
  /** have we updated? */
20
  if ($lyte_db_version !== $lyte_version) {
21
+ switch($lyte_db_version) {
22
+ case "1.5.0":
23
+ lyte_rm_cache();
24
+ break;
25
+ case "1.4.2":
26
+ case "1.4.1":
27
+ case "1.4.0":
28
+ lyte_rm_cache();
29
+ lyte_not_greedy();
30
+ break;
31
+ }
32
+ update_option('lyte_version',$lyte_version);
33
+ $lyte_db_version=$lyte_version;
34
  }
35
 
36
  /** are we in debug-mode */
37
  if (!$debug) {
38
+ $wyl_version=$lyte_version;
39
+ $wyl_file="lyte-min.js";
40
  } else {
41
+ $wyl_version=rand()/1000;
42
+ $wyl_file="lyte.js";
43
+ lyte_rm_cache();
44
  }
45
 
46
  /** get paths, language and includes */
56
  $pSizeFormat=$pSize[$sel]['f'];
57
  $j=0;
58
  foreach ($pSizeOrder[$pSizeFormat] as $sizeId) {
59
+ $sArray[$j]['w']=(int) $pSize[$sizeId]['w'];
60
+ $sArray[$j]['h']=(int) $pSize[$sizeId]['h'];
61
+ if ($sizeId===$sel) $selSize=$j;
62
+ $j++;
63
  }
64
 
65
  /** get other options and push in array*/
75
 
76
  /** API: filter hook to alter $lyteSettings */
77
  function lyte_settings_enforcer() {
78
+ global $lyteSettings;
79
+ $lyteSettings = apply_filters( 'lyte_settings', $lyteSettings );
80
+ }
81
  add_action('after_setup_theme','lyte_settings_enforcer');
82
 
83
  function lyte_parse($the_content,$doExcerpt=false) {
84
+ /** bail if amp */
85
+ if ( is_amp()) { return $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/';
90
+ $urlArr=parse_url($lyteSettings['path']);
91
+ $origin=$urlArr['scheme']."://".$urlArr['host']."/";
92
+
93
+ /** API: filter hook to preparse the_content, e.g. to force normal youtube links to be parsed */
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
+
105
+ if ( strpos($the_content,"<!-- wp:") !== false && strpos($the_content,"youtu") !== false ) {
106
+ /*
107
+ * do Gutenberg stuff here, playlists if needed first and then single videos
108
+ *
109
+ * having Gutenberg markup in HTML comments is ugly as hell
110
+ * esp. for 3rd parties such as Lyte who have to parse info out of that
111
+ *
112
+ * Luke Cavanagh; thanks for the Gutenbeard reference and for the funny animated gif :)
113
+ * https://media1.giphy.com/media/l2QZTNMFTQ2Z00zHG/giphy.gif
114
+ */
115
+ if (strpos($the_content,'/playlist?list=') !== false ) {
116
+ $gutenbeard_playlist_regex = '%<\!--\s?wp:(?:core[-|/])?embed(?:/youtube)?\s?{"url":"https://www.youtube.com/playlist\?list=(.*)"}\s?-->.*<\!--\s?/wp:(?:core[-|/])?embed(?:/youtube)?\s?-->%Us';
117
+ $the_content = preg_replace($gutenbeard_playlist_regex, 'httpv://www.youtube.com/playlist?list=\1',$the_content);
118
+ }
119
+ $gutenbeard_single_regex = '%<\!--\s?wp:(?:core[-|/])?embed(?:/youtube)?\s?{"url":"https?://(?:www\.)?youtu(?:be\.com|.be)/(?:watch\?v=)?(.*)"}\s?-->.*<\!--\s?/wp:(?:core[-|/])?embed(?:/youtube)?\s?-->%Us';
120
+ $the_content = preg_replace($gutenbeard_single_regex, 'httpv://www.youtube.com/watch?v=\1',$the_content);
121
+ }
122
+
123
+ if((strpos($the_content, "httpv")!==FALSE)||(strpos($the_content, "httpa")!==FALSE)) {
124
+ if (apply_filters('lyte_remove_wpautop',false)) {
125
+ remove_filter('the_content','wpautop');
126
+ }
127
+ $char_codes = array('&#215;','&#8211;');
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();
135
+ $toCache_index=array();
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 */
143
+ $match[12] = apply_filters( 'lyte_match_preparse_fragment',$match[12] );
144
 
145
+ preg_match("/stepSize\=([\+\-0-9]{2})/",$match[12],$sMatch);
146
+ preg_match("/showinfo\=([0-1]{1})/",$match[12],$showinfo);
147
+ preg_match("/start\=([0-9]*)/",$match[12],$start);
148
+ preg_match("/enablejsapi\=([0-1]{1})/",$match[12],$jsapi);
149
+ preg_match("/hqThumb\=([0-1]{1})/",$match[12],$hqThumb);
150
+ preg_match("/noMicroData\=([0-1]{1})/",$match[12],$microData);
151
+
152
+ $thumb="normal";
153
+ if ($lyteSettings['hidef']==="1") {
154
+ $thumb="highres";
155
+ } else if (!empty($hqThumb)) {
156
+ if ($hqThumb[0]==="hqThumb=1") {
157
+ $thumb="highres";
158
+ }
159
+ }
160
+
161
+ $noMicroData="0";
162
+ if (!empty($microData)) {
163
+ if ($microData[0]==="noMicroData=1") {
164
+ $noMicroData="1";
165
  }
166
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
 
168
+ $qsa="";
169
+ if (!empty($showinfo[0])) {
170
+ $qsa="&amp;".$showinfo[0];
171
+ $titleClass=" hidden";
172
+ } else {
173
+ $titleClass="";
174
+ }
175
+ if (!empty($start[0])) $qsa.="&amp;".$start[0];
176
+ if (!empty($jsapi[0])) $qsa.="&amp;".$jsapi[0]."&amp;origin=".$origin;
177
+
178
+ if (!empty($qsa)) {
179
+ $esc_arr=array("&" => "\&", "?" => "\?", "=" => "\=");
180
+ $qsaClass=" qsa_".strtr($qsa,$esc_arr);
181
+ } else {
182
+ $qsaClass="";
183
+ }
184
+
185
+ if (!empty($sMatch)) {
186
+ $newSize=(int) $sMatch[1];
187
+ $newPos=(int) $lyteSettings['selSize']+$newSize;
188
+ if ($newPos<0) {
189
+ $newPos=0;
190
+ } else if ($newPos > count($lyteSettings['sizeArray'])-1) {
191
+ $newPos=count($lyteSettings['sizeArray'])-1;
192
+ }
193
+ $lyteSettings[2]=$lyteSettings['sizeArray'][$newPos]['w'];
194
+ $lyteSettings[3]=$lyteSettings['sizeArray'][$newPos]['h'];
195
+ } else {
196
+ $lyteSettings[2]=$lyteSettings['sizeArray'][$lyteSettings['selSize']]['w'];
197
+ $lyteSettings[3]=$lyteSettings['sizeArray'][$lyteSettings['selSize']]['h'];
198
+ }
199
+
200
+ if ($match[1]!=="a") {
201
+ $divHeight=$lyteSettings[3];
202
+ $audioClass="";
203
+ $audio=false;
204
+ } else {
205
+ $audio=true;
206
+ $audioClass=" lyte-audio";
207
+ $divHeight=38;
208
+ }
209
+
210
+ $NSimgHeight=$divHeight-20;
211
+
212
+ if ($match[11]!="") {
213
+ $plClass=" playlist";
214
+ $vid=$match[11];
215
+ switch ($lyteSettings['links']) {
216
+ case "0":
217
+ $noscript_post="<br />".__("Watch this playlist on YouTube","wp-youtube-lyte");
218
+ $noscript="<noscript><a href=\"".$lyteSettings['scheme']."://youtube.com/playlist?list=".$vid."\">".$noscript_post."</a></noscript>";
219
+ $lytelinks_txt="";
220
+ break;
221
+ default:
222
+ $noscript="";
223
+ $lytelinks_txt="<div class=\"lL\" style=\"max-width:100%;width:".$lyteSettings[2]."px;".$lyteSettings['pos']."\">".__("Watch this playlist","wp-youtube-lyte")." <a href=\"".$lyteSettings['scheme']."://www.youtube.com/playlist?list=".$vid."\">".__("on YouTube","wp-youtube-lyte")."</a></div>";
224
+ }
225
+ } else if ($match[9]!="") {
226
+ $plClass="";
227
+ $vid=$match[9];
228
+ switch ($lyteSettings['links']) {
229
+ case "0":
230
+ $noscript_post="<br />".__("Watch this video on YouTube","wp-youtube-lyte");
231
+ $lytelinks_txt="<div class=\"lL\" style=\"max-width:100%;width:".$lyteSettings[2]."px;".$lyteSettings['pos']."\"></div>";
232
+ break;
233
+ default:
234
+ $noscript_post="";
235
+ $lytelinks_txt="<div class=\"lL\" style=\"max-width:100%;width:".$lyteSettings[2]."px;".$lyteSettings['pos']."\">".__("Watch this video","wp-youtube-lyte")." <a href=\"".$lyteSettings['scheme']."://youtu.be/".$vid."\">".__("on YouTube","wp-youtube-lyte")."</a>.</div>";
236
+ }
237
+
238
+ $noscript="<noscript><a href=\"".$lyteSettings['scheme']."://youtu.be/".$vid."\"><img src=\"".$lyteSettings['scheme']."://i.ytimg.com/vi/".$vid."/0.jpg\" alt=\"\" width=\"".$lyteSettings[2]."\" height=\"".$NSimgHeight."\" />".$noscript_post."</a></noscript>";
239
+ }
240
+
241
+ // fetch data from YT api (v2 or v3)
242
+ $isPlaylist=false;
243
+ if ($plClass===" playlist") {
244
+ $isPlaylist=true;
245
+ }
246
+ $cachekey = '_lyte_' . $vid;
247
+ $yt_resp_array=lyte_get_YT_resp($vid,$isPlaylist,$cachekey);
248
 
249
  // If there was a result from youtube or from cache, use it
250
  if ( $yt_resp_array ) {
251
+ if (is_array($yt_resp_array)) {
252
+ if ($isPlaylist!==true) {
253
+ // captions, thanks to Benetech
254
+ $captionsMeta="";
255
+ $doCaptions=true;
256
+
257
+ /** API: filter hook to disable captions */
258
+ $doCaptions = apply_filters( 'lyte_docaptions', $doCaptions );
259
+
260
+ if(($lyteSettings['microdata'] === "1")&&($noMicroData !== "1" )&&($doCaptions === true)) {
261
+ if (array_key_exists('captions_data',$yt_resp_array)) {
262
+ if ($yt_resp_array["captions_data"]=="true") {
263
+ $captionsMeta="<meta itemprop=\"accessibilityFeature\" content=\"captions\" />";
264
+ $forceCaptionsUpdate=false;
265
+ } else {
266
+ $forceCaptionsUpdate=true;
267
+ }
268
+ } else {
269
+ $forceCaptionsUpdate=true;
270
+ $yt_resp_array["captions_data"]=false;
271
+ }
272
+
273
+ if ($forceCaptionsUpdate===true) {
274
+ $captionsMeta="";
275
+ $threshold = 30;
276
+ if (array_key_exists('captions_timestamp',$yt_resp_array)) {
277
+ $cache_timestamp = $yt_resp_array["captions_timestamp"];
278
+ $interval = (strtotime("now") - $cache_timestamp)/60/60/24;
279
+ } else {
280
+ $cache_timestamp = false;
281
+ $interval = $threshold+1;
282
+ }
283
+
284
+ if(!is_int($cache_timestamp) || ($interval > $threshold && !is_null( $yt_resp_array["captions_data"]))) {
285
+ $yt_resp_array['captions_timestamp'] = strtotime("now");
286
+ wp_schedule_single_event(strtotime("now") + 60*60, 'schedule_captions_lookup', array($postID, $cachekey, $vid));
287
+ $yt_resp_precache=json_encode($yt_resp_array);
288
+ $toCache=base64_encode(gzcompress($yt_resp_precache));
289
+ update_post_meta($postID, $cachekey, $toCache);
290
+ }
291
+ }
292
+ }
293
+ }
294
+ $thumbUrl="";
295
+ if (($thumb==="highres") && (!empty($yt_resp_array["HQthumbUrl"]))){
296
+ $thumbUrl=$yt_resp_array["HQthumbUrl"];
297
+ } else {
298
+ if (!empty($yt_resp_array["thumbUrl"])) {
299
+ $thumbUrl=$yt_resp_array["thumbUrl"];
300
+ } else {
301
+ $thumbUrl="//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
302
+ }
303
+ }
304
+ } else {
305
+ // no useable result from youtube, fallback on video thumbnail (doesn't work on playlist)
306
+ $thumbUrl = "//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
307
+ }
308
+ } else {
309
+ // same fallback
310
+ $thumbUrl = "//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
311
+ }
 
 
 
 
 
312
 
313
+ // do we have to serve the thumbnail from local cache?
314
+ if (get_option('lyte_local_thumb','0') === '1') {
315
+ $thumbUrl = plugins_url( 'lyteThumbs.php?origThumbUrl=' . urlencode($thumbUrl) , __FILE__ );
316
+ }
317
+
318
+ /** API: filter hook to override thumbnail URL */
319
+ $thumbUrl = apply_filters( 'lyte_match_thumburl', $thumbUrl, $vid );
320
+
321
+ if ($audio===true) {
322
+ $wrapper="<div class=\"lyte-wrapper-audio\" style=\"width:".$lyteSettings[2]."px;max-width:100%;overflow:hidden;height:38px;".$lyteSettings['pos']."\">";
323
+ } else {
324
+ $wrapper="<div class=\"lyte-wrapper".$lyteSettings['ratioClass']."\" style=\"width:".$lyteSettings[2]."px;max-width: 100%;".$lyteSettings['pos']."\">";
325
+ }
326
+
327
+ if ($doExcerpt) {
328
+ $lytetemplate="";
329
+ $templateType="excerpt";
330
+ } elseif ($lyte_feed) {
331
+ $postURL = get_permalink( $postID );
332
+ $textLink = ($lyteSettings['links']===0)? "" : "<br />".strip_tags($lytelinks_txt, '<a>')."<br />";
333
+ $lytetemplate = "<a href=\"".$postURL."\"><img src=\"".$thumbUrl."\" alt=\"YouTube Video\"></a>".$textLink;
334
+ $templateType="feed";
335
+ } elseif (($audio !== true) && ( $plClass !== " playlist") && (($lyteSettings['microdata'] === "1")&&($noMicroData !== "1" ))) {
336
+ $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;
337
+ $templateType="postMicrodata";
338
+ } else {
339
+ $lytetemplate = $wrapper."<div class=\"lyMe".$audioClass.$hidefClass.$plClass.$qsaClass."\" id=\"WYL_".$vid."\"><div id=\"lyte_".$vid."\" data-src=\"".$thumbUrl."\" class=\"pL\">";
340
+
341
+ if (isset($yt_resp_array) && !empty($yt_resp_array) && !empty($yt_resp_array["title"])) {
342
  $lytetemplate .= "<div class=\"tC".$titleClass."\"><div class=\"tT\">".$yt_resp_array['title']."</div></div>";
343
  }
344
+
345
+ $lytetemplate .= "<div class=\"play\"></div><div class=\"ctrl\"><div class=\"Lctrl\"></div><div class=\"Rctrl\"></div></div></div>".$noscript."</div></div>".$lytelinks_txt;
346
+ $templateType="post";
347
+ }
348
+
349
+ /** API: filter hook to parse template before being applied */
350
+ $lytetemplate = apply_filters( 'lyte_match_postparse_template',$lytetemplate,$templateType );
351
+ $the_content = preg_replace($lytes_regexp, $lytetemplate, $the_content, 1);
352
  }
353
 
354
+ // update lyte_cache_index
355
+ if ((is_array($toCache_index))&&(!empty($toCache_index))) {
356
+ $lyte_cache=json_decode(get_option('lyte_cache_index'),true);
357
+ $lyte_cache[$postID]=$toCache_index;
358
+ update_option('lyte_cache_index',json_encode($lyte_cache));
359
+ }
360
 
361
+ if (!$lyte_feed) {
362
+ lyte_initer();
363
+ }
364
+ }
365
 
366
+ /** API: filter hook to postparse the_content before returning */
367
+ $the_content = apply_filters( 'lyte_content_postparse',$the_content );
368
 
369
+ return $the_content;
370
  }
371
 
372
  function captions_lookup($postID, $cachekey, $vid) {
373
+ // captions lookup at YouTube via a11ymetadata.org
374
+ $response = wp_remote_request("http://api.a11ymetadata.org/captions/youtubeid=".$vid."/youtube");
375
+
376
+ if(!is_wp_error($response)) {
377
+ $rawJson = wp_remote_retrieve_body($response);
378
+ $decodeJson = json_decode($rawJson, true);
379
+
380
+ $yt_resp = get_post_meta($postID, $cachekey, true);
381
+
382
+ if (!empty($yt_resp)) {
383
+ $yt_resp = gzuncompress(base64_decode($yt_resp));
384
+ if($yt_resp) {
385
+ $yt_resp_array=json_decode($yt_resp,true);
386
+
387
+ if ($decodeJson['status'] == 'success' && $decodeJson['data']['captions'] == '1') {
388
+ $yt_resp_array['captions_data'] = true;
389
+ } else {
390
+ $yt_resp_array['captions_data'] = false;
391
+ }
392
+
393
+ $yt_resp_array['captions_timestamp'] = strtotime("now");
394
+ $yt_resp_precache=json_encode($yt_resp_array);
395
+ $toCache=base64_encode(gzcompress($yt_resp_precache));
396
+ update_post_meta($postID, $cachekey, $toCache);
397
+ }
398
+ }
399
+ }
400
  }
401
 
402
  function lyte_get_YT_resp($vid,$playlist=false,$cachekey,$apiTestKey="",$isWidget=false) {
403
+ /** logic to get video info from cache or get it from YouTube and set it */
404
+ global $postID, $cachekey, $toCache_index;
405
+
406
+ $_thisLyte = array();
407
+ $yt_error = array();
408
+
409
+ if ( $postID && empty($apiTestKey) && !$isWidget ) {
410
+ $cache_resp = get_post_meta( $postID, $cachekey, true );
411
+ if (!empty($cache_resp)) {
412
+ $_thisLyte = json_decode(gzuncompress(base64_decode($cache_resp)),1);
413
+ // make sure there are not old APIv2 full responses in cache
414
+ if (array_key_exists('entry', $_thisLyte)) {
415
+ if ($_thisLyte['entry']['xmlns$yt']==="http://gdata.youtube.com/schemas/2007") {
416
+ $_thisLyte = array();
417
+ }
418
+ }
419
+ }
420
+ } else if ($isWidget) {
421
+ $cache_resp = get_option("lyte_widget_cache");
422
+ if (!empty($cache_resp)) {
423
+ $widget_cache = json_decode(gzuncompress(base64_decode($cache_resp)),1);
424
+ $_thisLyte = $widget_cache[$vid];
425
+ }
426
+ }
427
+
428
+ if ( empty( $_thisLyte ) ) {
429
+ // get info from youtube
430
+ // first get yt api key
431
+ $lyte_yt_api_key = get_option('lyte_yt_api_key','');
432
+ $lyte_yt_api_key = apply_filters('lyte_filter_yt_api_key', $lyte_yt_api_key);
433
+ if (!empty($apiTestKey)) {
434
+ $lyte_yt_api_key=$apiTestKey;
435
+ }
436
+
437
+ if (($lyte_yt_api_key==="none") || (empty($lyte_yt_api_key))) {
438
+ $_thisLyte['title']="";
439
+ if ($playlist) {
440
+ $_thisLyte['thumbUrl']="";
441
+ $_thisLyte['HQthumbUrl']="";
442
+ } else {
443
+ $_thisLyte['thumbUrl']="//i.ytimg.com/vi/".$vid."/hqdefault.jpg";
444
+ $_thisLyte['HQthumbUrl']="//i.ytimg.com/vi/".$vid."/maxresdefault.jpg";
445
+ }
446
+ $_thisLyte['dateField']="";
447
+ $_thisLyte['duration']="";
448
+ $_thisLyte['description']="";
449
+ $_thisLyte['captions_data']="false";
450
+ $_thisLyte['captions_timestamp']=strtotime("now");
451
+ return $_thisLyte;
452
+ } else {
453
+ // v3, feeling somewhat lonely now v2 has gently been put to sleep
454
+ $yt_api_base = "https://www.googleapis.com/youtube/v3/";
455
+
456
+ if ($playlist) {
457
+ $yt_api_target = "playlists?part=snippet%2C+id&id=".$vid."&key=".$lyte_yt_api_key;
458
+ } else {
459
+ $yt_api_target = "videos?part=id%2C+snippet%2C+contentDetails&id=".$vid."&key=".$lyte_yt_api_key;
460
+ }
461
+ }
462
+
463
+ $yt_api_url = $yt_api_base.$yt_api_target;
464
+ $yt_resp = wp_remote_get($yt_api_url);
465
+
466
+ // check if we got through
467
+ if ( is_wp_error($yt_resp) ) {
468
+ $yt_error['code']=408;
469
+ $yt_error['reason']=$yt_resp->get_error_message();
470
+ $yt_error['timestamp']=strtotime("now");
471
+ if (!empty($apiTestKey)) {
472
+ return $yt_error;
473
+ }
474
+ } else {
475
+ $yt_resp_array = (array) json_decode(wp_remote_retrieve_body($yt_resp),true);
476
+ if(is_array($yt_resp_array)) {
477
+ // extract relevant data
478
+ // v3
479
+ if (in_array(wp_remote_retrieve_response_code($yt_resp),array(400,403,404))) {
480
+ $yt_error['code']=wp_remote_retrieve_response_code($yt_resp);
481
+ $yt_error['reason']=$yt_resp_array['error']['errors'][0]['reason'];
482
+ $yt_error['timestamp']=strtotime("now");
483
+ if (empty($apiTestKey)) {
484
+ update_option("lyte_api_error",json_encode($yt_error));
485
+ } else {
486
+ return $yt_error;
487
+ }
488
+ } else {
489
+ if ($playlist) {
490
+ $_thisLyte['title']="Playlist: ".esc_attr(sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['title']));
491
+ $_thisLyte['thumbUrl']=esc_url(@$yt_resp_array['items'][0]['snippet']['thumbnails']['high']['url']);
492
+ $_thisLyte['HQthumbUrl']=esc_url(@$yt_resp_array['items'][0]['snippet']['thumbnails']['maxres']['url']);
493
+ $_thisLyte['dateField']=sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['publishedAt']);
494
+ $_thisLyte['duration']="";
495
+ $_thisLyte['description']=esc_attr(sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['description']));
496
+ $_thisLyte['captions_data']="false";
497
+ $_thisLyte['captions_timestamp'] = "";
498
+ } else {
499
+ $_thisLyte['title']=esc_attr(sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['title']));
500
+ $_thisLyte['thumbUrl']=esc_url(@$yt_resp_array['items'][0]['snippet']['thumbnails']['high']['url']);
501
+ $_thisLyte['HQthumbUrl']=esc_url(@$yt_resp_array['items'][0]['snippet']['thumbnails']['maxres']['url']);
502
+ $_thisLyte['dateField']=sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['publishedAt']);
503
+ $_thisLyte['duration']=sanitize_text_field(@$yt_resp_array['items'][0]['contentDetails']['duration']);
504
+ $_thisLyte['description']=esc_attr(sanitize_text_field(@$yt_resp_array['items'][0]['snippet']['description']));
505
+ $_thisLyte['captions_data']=sanitize_text_field(@$yt_resp_array['items'][0]['contentDetails']['caption']);
506
+ $_thisLyte['captions_timestamp'] = strtotime("now");
507
+ }
508
+ }
509
+
510
+ // try to cache the result
511
+ if ( (($postID) || ($isWidget)) && !empty($_thisLyte) && empty($apiTestKey) ) {
512
+ $_thisLyte['lyte_date_added']=time();
513
+
514
+ if ( $postID && !$isWidget ) {
515
+ $yt_resp_precache=json_encode($_thisLyte);
516
+
517
+ // then gzip + base64 (to limit amount of data + solve problems with wordpress removing slashes)
518
+ $yt_resp_precache=base64_encode(gzcompress($yt_resp_precache));
519
+
520
+ // and do the actual caching
521
+ $toCache = ( $yt_resp_precache ) ? $yt_resp_precache : '{{unknown}}';
522
+
523
+ update_post_meta( $postID, $cachekey, $toCache );
524
+ // and finally add new cache-entry to toCache_index which will be added to lyte_cache_index pref
525
+ $toCache_index[]=$cachekey;
526
+ } else if ($isWidget) {
527
+ $widget_cache[$vid]=$_thisLyte;
528
+ update_option("lyte_widget_cache",base64_encode(gzcompress(json_encode($widget_cache))));
529
+ }
 
530
  }
531
+ }
532
  }
533
+ }
534
+ foreach (array("title","thumbUrl","HQthumbUrl","dateField","duration","description","captions_data","captions_timestamp") as $key) {
535
+ if (!array_key_exists($key,$_thisLyte)) {
536
+ $_thisLyte[$key]="";
537
+ }
538
+ }
539
+ return $_thisLyte;
540
  }
541
 
542
  /* only add js/css once and only if needed */
543
  function lyte_initer() {
544
+ global $lynited;
545
+ if (!$lynited) {
546
+ $lynited=true;
547
+ add_action('wp_footer', 'lyte_init');
548
+ }
549
  }
550
 
551
  /* actual initialization */
552
  function lyte_init() {
553
+ global $lyteSettings;
554
+ $lyte_css = ".lyte-wrapper-audio div, .lyte-wrapper div {margin:0px; overflow:hidden;} .lyte,.lyMe{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;background-color:#777;} .fourthree .lyMe, .fourthree .lyte {padding-bottom:75%;} .lidget{margin-bottom:5px;} .lidget .lyte, .widget .lyMe {padding-bottom:0!important;height:100%!important;} .lyte-wrapper-audio .lyte{height:38px!important;overflow:hidden;padding:0!important} .lyMe iframe, .lyte iframe,.lyte .pL{position:absolute !important;top:0;left:0;width:100%;height:100%!important;background:no-repeat scroll center #000;background-size:cover;cursor:pointer} .tC{left:0;position:absolute;top:0;width:100%} .tC{background-image:linear-gradient(to bottom,rgba(0,0,0,0.6),rgba(0,0,0,0))} .tT{color:#FFF;font-family:Roboto,sans-serif;font-size:16px;height:auto;text-align:left;padding:5px 10px 50px 10px} .play{background:no-repeat scroll 0 0 transparent;width:88px;height:63px;position:absolute;left:43%;left:calc(50% - 44px);left:-webkit-calc(50% - 44px);top:38%;top:calc(50% - 31px);top:-webkit-calc(50% - 31px);} .widget .play {top:30%;top:calc(45% - 31px);top:-webkit-calc(45% - 31px);transform:scale(0.6);-webkit-transform:scale(0.6);-ms-transform:scale(0.6);} .lyte:hover .play{background-position:0 -65px;} .lyte-audio .pL{max-height:38px!important} .lyte-audio iframe{height:438px!important} .ctrl{background:repeat scroll 0 -220px rgba(0,0,0,0.3);width:100%;height:40px;bottom:0px;left:0;position:absolute;} .lyte-wrapper .ctrl{display:none}.Lctrl{background:no-repeat scroll 0 -137px transparent;width:158px;height:40px;bottom:0;left:0;position:absolute} .Rctrl{background:no-repeat scroll -42px -179px transparent;width:117px;height:40px;bottom:0;right:0;position:absolute;padding-right:10px;}.lyte-audio .play{display:none}.lyte-audio .ctrl{background-color:rgba(0,0,0,1)}.hidden{display:none}";
555
+
556
+ // by default show lyte vid on mobile (requiring user clicking play two times)
557
+ // but can be overruled by this filter
558
+ // also "do lyte mobile" when option to cache thumbnails is on to ensure privacy (gdpr)
559
+ $mobLyte = apply_filters( 'lyte_do_mobile', false );
560
+ if ( $mobLyte || get_option( 'lyte_local_thumb', 0 ) ) {
561
+ $mobJS = "var mOs=null;";
562
+ } else {
563
+ $mobJS = "var mOs=navigator.userAgent.match(/(iphone|ipad|ipod|android)/i);";
564
+ }
565
+
566
+ /** API: filter hook to change css */
567
+ $lyte_css = apply_filters( 'lyte_css', $lyte_css);
568
+
569
+ 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>";
570
+ echo "<script type=\"text/javascript\" async src=\"".$lyteSettings['path'].$lyteSettings['file']."\"></script>";
571
  }
572
 
573
  /** override default wp_trim_excerpt to have lyte_parse remove the httpv-links */
574
  function lyte_trim_excerpt($text) {
575
+ global $post;
576
+ $raw_excerpt = $text;
577
+ if ( '' == $text ) {
578
+ $text = get_the_content('');
579
+ $text = lyte_parse($text, true);
580
+ $text = strip_shortcodes( $text );
581
+ $text = apply_filters('the_content', $text);
582
+ $text = str_replace(']]>', ']]&gt;', $text);
583
+ $excerpt_length = apply_filters('excerpt_length', 55);
584
+ $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
585
+ if (function_exists('wp_trim_words')) {
586
+ $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
587
+ } else {
588
+ $length = $excerpt_length*6;
589
+ $text = substr( strip_tags(trim(preg_replace('/\s+/', ' ', $text))), 0, $length );
590
+ $text .= $excerpt_more;
 
591
  }
592
+ }
593
+ return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
594
  }
595
 
596
  /** Lyte shortcode */
597
  function shortcode_lyte($atts) {
598
+ extract(shortcode_atts(array(
599
+ "id" => '',
600
+ "audio" => '',
601
+ "playlist" => '',
602
+ ), $atts));
603
 
604
+ if ($audio) {$proto="httpa";} else {$proto="httpv";}
605
+ if ($playlist) {$action="playlist?list=";} else {$action="watch?v=";}
 
606
  return lyte_parse($proto.'://www.youtube.com/'.$action.$id);
607
  }
608
 
609
  /** update functions */
610
  /** upgrade, so lyte should not be greedy */
611
  function lyte_not_greedy() {
612
+ update_option( "lyte_greedy", "0" );
613
  }
614
 
615
  /** function to flush YT responses from cache */
616
  function lyte_rm_cache() {
617
+ try {
618
+ ini_set('max_execution_time',90); // give PHP some more time for this, post-meta can be sloooooow
619
+
620
+ // cache in post_meta, for posts
621
+ $lyte_posts = json_decode(get_option("lyte_cache_index"),true);
622
+ $lyteCacheIterator = 0;
623
+ $lytePurgeThreshold = 500;
624
+ $returnCode = "OK";
625
+ if (is_array($lyte_posts)){
626
+ foreach ($lyte_posts as $postID => $lyte_post) {
627
+ foreach ($lyte_post as $cachekey) {
628
+ delete_post_meta($postID, $cachekey);
629
+ }
630
+ unset ($lyte_posts[$postID]);
631
+ $lyteCacheIterator++;
632
+ if ($lyteCacheIterator > ($lytePurgeThreshold-1)) {
633
+ $returnCode = "PART";
634
+ break;
635
+ }
636
+ }
637
+ update_option("lyte_cache_index",json_encode($lyte_posts));
638
+ }
639
+
640
+ // and the widget cache which isn't in post_meta
641
+ update_option('lyte_widget_cache','');
642
+
643
+ return $returnCode;
644
+ } catch(Exception $e) {
645
+ return $e->getMessage();
646
+ }
647
  }
648
 
649
  /** function to call from within themes */
653
  }
654
 
655
  function lyte_add_action_link($links) {
656
+ $links[]='<a href="' . admin_url( 'options-general.php?page=lyte_settings_page' ) . '">' . __('Settings') . '</a>';
657
+ return $links;
658
  }
659
 
660
  /** is_amp, but I shouldn't have to do this, should I? */
661
  if (!function_exists("is_amp")) {
662
+ function is_amp() {
663
+ if ((strpos($_SERVER['REQUEST_URI'],'?amp')!==false) || (strpos($_SERVER['REQUEST_URI'],'/amp/')!==false)) {
664
+ return true;
665
+ } else {
666
+ return false;
667
+ }
668
+ }
669
  }
670
 
671
  /** hooking it all up to wordpress */
672
  if ( is_admin() ) {
673
+ require_once(dirname(__FILE__).'/options.php');
674
+ add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'lyte_add_action_link' );
675
  } else {
676
+ add_filter('the_content', 'lyte_parse', 4);
677
+ add_shortcode("lyte", "shortcode_lyte");
678
+ remove_filter('get_the_excerpt', 'wp_trim_excerpt');
679
+ add_filter('get_the_excerpt', 'lyte_trim_excerpt');
680
+ add_action('schedule_captions_lookup', 'captions_lookup', 1, 3);
681
+
682
+ /** API: action hook to allow extra actions or filters to be added */
683
+ do_action("lyte_actionsfilters");
684
  }
685
  ?>