PluginProbe
Embed Plus for YouTube Gallery, Livestream and Lazy Loading with Facades / trunk
Embed Plus for YouTube Gallery, Livestream and Lazy Loading with Facades vtrunk
trunk 1.0 1.1 10.0 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 11.0 11.0.1 11.1 11.2 11.3 11.3.1 11.4 11.5 11.6 11.7 11.7.1 11.8 All 143 releases
youtube-embed-plus / youtube.php

youtube.php in Embed Plus for YouTube Gallery, Livestream and Lazy Loading with Facades trunk, at youtube.php

6,131 lines 366.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Embed Plus for YouTube Gallery, Livestream and Lazy Loading with Facades
4 Plugin URI: https://www.embedplus.com/dashboard/pro-easy-video-analytics.aspx?ref=plugin
5 Description: A multi-featured plugin to embed YouTube in WordPress. Embed a video, YouTube channel gallery, playlist, or YouTube livestream. Defer JavaScript too!
6 Version: 14.2.6.1
7 Author: Embed Plus for YouTube Plugin Team
8 Author URI: https://www.embedplus.com
9 Requires at least: 4.5
10 */
11
12 /*
13 Embed Plus for YouTube Gallery, Livestream and Lazy Loading with Facades
14 Copyright (C) 2026 EmbedPlus.com
15
16 This program is free software: you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28
29 */
30
31 //define('WP_DEBUG', true);
32
33 class YouTubePrefs
34 {
35
36 public static $folder_name = 'youtube-embed-plus';
37 public static $curltimeout = 30;
38 public static $version = '14.2.6.1';
39 public static $opt_version = 'version';
40 public static $optembedwidth = null;
41 public static $optembedheight = null;
42 public static $defaultheight = null;
43 public static $defaultwidth = null;
44 public static $oembeddata = null;
45 public static $opt_center = 'centervid';
46 public static $opt_glance = 'glance';
47 public static $opt_autoplay = 'autoplay';
48 public static $opt_debugmode = 'debugmode';
49 public static $opt_uninstall_data = 'uninstall_data';
50 public static $opt_old_script_method = 'old_script_method';
51 public static $opt_cc_load_policy = 'cc_load_policy';
52 public static $opt_cc_lang_pref = 'cc_lang_pref';
53 public static $opt_iv_load_policy = 'iv_load_policy';
54 public static $opt_loop = 'loop';
55 public static $opt_rel = 'rel';
56 public static $opt_fs = 'fs';
57 public static $opt_playsinline = 'playsinline';
58 public static $opt_autohide = 'autohide';
59 public static $opt_controls = 'controls';
60 public static $opt_disablekb = 'disablekb';
61 public static $opt_theme = 'theme';
62 public static $opt_color = 'color';
63 public static $opt_listType = 'listType';
64 public static $opt_dohl = 'dohl';
65 public static $opt_hl = 'hl';
66 public static $opt_nocookie = 'nocookie';
67 public static $opt_gb_compat = 'gb_compat';
68 public static $opt_facade_mode = 'facade_mode';
69 public static $opt_facade_autoplay = 'facade_autoplay';
70 public static $opt_gdpr_consent = 'gdpr_consent';
71 public static $opt_gdpr_consent_message = 'gdpr_consent_message';
72 public static $opt_gdpr_consent_button = 'gdpr_consent_button';
73 public static $gdpr_cookie_name = 'ytprefs_gdpr_consent';
74 public static $opt_playlistorder = 'playlistorder';
75 public static $opt_acctitle = 'acctitle';
76 public static $opt_pro = 'pro';
77 public static $opt_oldspacing = 'oldspacing';
78 public static $opt_frontend_only = 'frontend_only';
79 public static $opt_responsive = 'responsive';
80 public static $opt_responsive_all = 'responsive_all';
81 public static $opt_origin = 'origin';
82 public static $opt_widgetfit = 'widgetfit';
83 public static $opt_evselector_light = 'evselector_light';
84 public static $opt_stop_mobile_buffer = 'stop_mobile_buffer';
85 public static $opt_restrict_wizard = 'restrict_wizard';
86 public static $opt_restrict_wizard_roles = 'restrict_wizard_roles';
87 public static $opt_ajax_compat = 'ajax_compat';
88 public static $opt_maxres_facade = 'maxres_facade';
89 public static $opt_ytapi_load = 'ytapi_load';
90 public static $opt_defaultdims = 'defaultdims';
91 public static $opt_defaultwidth = 'width';
92 public static $opt_defaultheight = 'height';
93 public static $opt_pause_others = 'pause_others';
94 public static $opt_defaultvol = 'defaultvol';
95 public static $opt_vol = 'vol';
96 public static $opt_apikey = 'apikey';
97 public static $opt_migrate = 'migrate';
98 public static $opt_migrate_youtube = 'migrate_youtube';
99 public static $opt_migrate_embedplusvideo = 'migrate_embedplusvideo';
100 public static $opt_gallery_pagesize = 'gallery_pagesize';
101 public static $opt_gallery_columns = 'gallery_columns';
102 public static $opt_gallery_collapse_grid = 'gallery_collapse_grid';
103 public static $opt_gallery_collapse_grid_breaks = 'gallery_collapse_grid_breaks';
104 public static $opt_gallery_scrolloffset = 'gallery_scrolloffset';
105 public static $opt_gallery_hideprivate = 'gallery_hideprivate';
106 public static $opt_gallery_showtitle = 'gallery_showtitle';
107 public static $opt_gallery_showpaging = 'gallery_showpaging';
108 public static $opt_gallery_thumbplay = 'gallery_thumbplay';
109 public static $opt_gallery_autonext = 'gallery_autonext';
110 public static $opt_gallery_channelsub = 'gallery_channelsub';
111 public static $opt_gallery_channelsublink = 'gallery_channelsublink';
112 public static $opt_gallery_channelsubtext = 'gallery_channelsubtext';
113 public static $opt_gallery_customarrows = 'gallery_customarrows';
114 public static $opt_gallery_customprev = 'gallery_customprev';
115 public static $opt_gallery_customnext = 'gallery_customnext';
116 public static $opt_not_live_content = 'not_live_content';
117 public static $opt_not_live_on = 'not_live_on';
118 public static $opt_not_live_on_channel = 'not_live_on_channel';
119 public static $opt_admin_off_scripts = 'admin_off_scripts';
120 public static $opt_defer_js = 'defer_js';
121 public static $opt_defer_jquery = 'defer_jquery';
122 public static $opt_ajax_save = 'ajax_save';
123 public static $opt_onboarded = 'onboarded';
124 public static $opt_show_pointer = 'show_pointer';
125 public static $opt_alloptions = 'youtubeprefs_alloptions';
126 public static $alloptions = null;
127 public static $yt_options = array();
128 public static $dft_bpts = array(array('bp' => array('min' => 0, 'max' => 767), 'cols' => 1));
129 public static $dft_roles = array('administrator', 'editor', 'author', 'contributor', 'subscriber');
130 public static $epbase = 'https://www.embedplus.com';
131 public static $double_plugin = false;
132 public static $scriptsprinted = 0;
133 public static $min = '.min';
134 public static $badentities = array('&#215;', '×', '&#8211;', '', '&amp;', '&#038;', '&#38;');
135 public static $goodliterals = array('x', 'x', '--', '--', '&', '&', '&');
136 public static $wizard_hook = '';
137 public static $onboarding_hook = '';
138 public static $admin_page_hooks = array();
139 public static $the_content_filters = array(
140 'wptexturize',
141 'wpautop',
142 'shortcode_unautop',
143 'prepend_attachment',
144 'wp_make_content_images_responsive',
145 'wp_filter_content_tags',
146 'do_shortcode',
147 'convert_smilies'
148 );
149 public static $get_api_key_msg = 'The ### feature now requires a (free) YouTube API key from Google. Please follow the easy steps <a href="https://www.youtube.com/watch?v=ZCfrNvu6nMc" target="_blank">in this video</a> to create and save your API key.';
150 public static $boilerplate_api_error_message = ' Please make sure you performed the <a href="https://www.youtube.com/watch?v=ZCfrNvu6nMc" target="_blank">steps in this video</a> to create and save a proper server API key.';
151 public static $dft_gdpr_consent_message = '<p><strong>Please accept YouTube cookies to play this video.</strong> By accepting you will be accessing content from YouTube, a service provided by an external third party.</p><p><a href="https://policies.google.com/privacy" target="_blank">YouTube privacy policy</a></p><p>If you accept this notice, your choice will be saved and the page will refresh.</p>';
152 ///////////////////////////////////////////////////////////////////////////////////////////////////
153 ///////////////////////////////////////////////////////////////////////////////////////////////////
154 ///////////////////////////////////////////////////////////////////////////////////////////////////
155 ///////////////////////////////////////////////////////////////////////////////////////////////////
156
157 public static $oldytregex = '@^\s*https?://(?:www\.)?(?:(?:youtube.com/(?:(?:watch)|(?:embed)|(?:playlist))(?:/live_stream){0,1}/{0,1}\?)|(?:youtu.be/))([^\s"]+)\s*$@im';
158 public static $ytregex = '@^[\r\t ]*https?://(?:www\.)?(?:(?:youtube.com/(?:(?:watch)|(?:embed)|(?:playlist))(?:/live_stream){0,1}/{0,1}\?)|(?:youtu.be/))([^\s"]+)[\r\t ]*$@im';
159 public static $justurlregex = '@https?://(?:www\.)?(?:(?:youtube.com/(?:(?:watch)|(?:embed)|(?:playlist))(?:/live_stream){0,1}/{0,1}\?)|(?:youtu.be/))([^\[\s"]+)@i';
160
161 ///////////////////////////////////////////////////////////////////////////////////////////////////
162 ///////////////////////////////////////////////////////////////////////////////////////////////////
163 ///////////////////////////////////////////////////////////////////////////////////////////////////
164
165 public function __construct()
166 {
167 if (defined('EMBEDPLUS_BASE_URL'))
168 {
169 self::$epbase = EMBEDPLUS_BASE_URL;
170 }
171 register_deactivation_hook(__FILE__, array(self::class, 'on_deactivation'));
172 add_action('admin_init', array(self::class, 'check_double_plugin_warning'));
173 add_action('admin_notices', array(self::class, 'separate_version_message'));
174
175 self::$alloptions = get_option(self::$opt_alloptions);
176 if (self::$alloptions == false || version_compare(self::$alloptions[self::$opt_version], self::$version, '<'))
177 {
178 self::initoptions();
179 }
180
181 if ((defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) || self::$alloptions[self::$opt_debugmode] == 1)
182 {
183 self::$min = '';
184 }
185
186
187 if (self::$alloptions[self::$opt_oldspacing] == 1)
188 {
189 self::$ytregex = self::$oldytregex;
190 }
191
192 self::$optembedwidth = intval(get_option('embed_size_w'));
193 self::$optembedheight = intval(get_option('embed_size_h'));
194
195 self::$yt_options = array(
196 self::$opt_autoplay,
197 self::$opt_cc_load_policy,
198 self::$opt_cc_lang_pref,
199 self::$opt_iv_load_policy,
200 self::$opt_loop,
201 self::$opt_rel,
202 self::$opt_fs,
203 self::$opt_playsinline,
204 self::$opt_autohide,
205 self::$opt_controls,
206 self::$opt_disablekb,
207 self::$opt_hl,
208 self::$opt_theme,
209 self::$opt_color,
210 self::$opt_listType,
211 'index',
212 'list',
213 'start',
214 'end',
215 'channel'
216 );
217
218 add_action('media_buttons', array(self::class, 'media_button_wizard'), 11);
219
220
221 self::do_ytprefs();
222 add_action('admin_menu', array(self::class, 'ytprefs_plugin_menu'));
223 add_filter('plugin_action_links_' . plugin_basename(__FILE__), array(self::class, 'my_plugin_action_links'));
224
225 if (!is_admin())
226 {
227 if (self::$alloptions[self::$opt_old_script_method] == 1)
228 {
229 add_action('wp_print_scripts', array(self::class, 'jsvars'));
230 add_action('wp_enqueue_scripts', array(self::class, 'jsvars'));
231 }
232
233 add_action('wp_enqueue_scripts', array(self::class, 'ytprefsscript'), 100);
234 add_action('wp_enqueue_scripts', array(self::class, 'fitvids'), 101);
235 }
236
237 add_filter('ytprefs_filter_the_content_light', array(self::class, 'filter_the_content_light'));
238
239 add_action("wp_ajax_my_embedplus_onboarding_save_ajax", array(self::class, 'onboarding_save_ajax'));
240 add_action("wp_ajax_my_embedplus_settings_save_ajax", array(self::class, 'settings_save_ajax'));
241 add_action("wp_ajax_my_embedplus_onboarding_save_apikey_ajax", array(self::class, 'onboarding_save_apikey_ajax'));
242 add_action("wp_ajax_my_embedplus_glance_vids", array(self::class, 'my_embedplus_glance_vids'));
243 add_action("wp_ajax_my_embedplus_glance_count", array(self::class, 'my_embedplus_glance_count'));
244 add_action("wp_ajax_my_embedplus_dismiss_double_plugin_warning", array(self::class, 'my_embedplus_dismiss_double_plugin_warning'));
245 add_action("wp_ajax_my_embedplus_gallery_page", array(self::class, 'my_embedplus_gallery_page'));
246 add_action("wp_ajax_nopriv_my_embedplus_gallery_page", array(self::class, 'my_embedplus_gallery_page'));
247 add_action('admin_enqueue_scripts', array(self::class, 'admin_enqueue_scripts'), 10, 1);
248
249 if (!empty(self::$alloptions[self::$opt_not_live_on_channel]))
250 {
251 add_action("wp_footer", array(self::class, 'live_fallback_template'));
252 }
253 /////////////////////////////////////
254 include_once(EPYTGB_INCLUDES_PATH . 'gutenberg_hooks.php');
255 }
256
257 public static function separate_version_message()
258 {
259 if (current_user_can('manage_options') && self::$alloptions[self::$opt_pro] && strlen(trim(self::$alloptions[self::$opt_pro])) > 10)
260 {
261 $class = 'notice notice-error is-dismissible';
262 $message = 'Important message to Pro users: From version 11.7 onward, you must <a href="https://www.embedplus.com/youtube-pro/download/?prokey=' . esc_attr(self::$alloptions[self::$opt_pro]) . '" target="_blank">download the separate plugin here</a> to regain your Pro features. All your settings will automatically migrate after installing the separate Pro download. Thank you for your support and patience during this transition.';
263
264 printf('<div class="%1$s"><p>%2$s</p></div>', esc_attr($class), wp_kses_post($message));
265 }
266 }
267
268 public static function live_fallback_template()
269 {
270 echo '<script type="text/x-template" id="epyt-live-fallback">' . base64_encode(apply_filters('ytprefs_filter_the_content_light', wp_kses_post(self::$alloptions[self::$opt_not_live_content]))) . '</script>';
271 }
272
273 public static function defer_scripts($tag, $handle, $src)
274 {
275 $defer = array(
276 '__dispload__',
277 '__ytprefs__',
278 '__dynload__',
279 '__ytprefs__bar',
280 '__ytprefsfitvids__',
281 '__jquery_cookie__'
282 );
283
284 if (self::$alloptions[self::$opt_defer_jquery] == 1 && !is_admin())
285 {
286 array_push($defer, 'jquery', 'jquery-core', 'jquery-migrate');
287 }
288
289 if (in_array($handle, $defer) && stripos($tag, ' defer') === false)
290 {
291 $tag = str_replace(' src', ' defer src', $tag);
292 }
293
294 return $tag;
295 }
296
297 public static function my_plugin_action_links($links)
298 {
299 if (is_array($links))
300 {
301 $links[] = '<a href="' . esc_url(admin_url('admin.php?page=youtube-my-preferences')) . '">Settings</a>';
302 $links[] = '<a href="https://www.embedplus.com/dashboard/pro-easy-video-analytics.aspx?ref=actionlinks" target="_blank">Pro Version</a>';
303 }
304 return $links;
305 }
306
307 public static function show_glance_list()
308 {
309 $glancehref = self::show_glance();
310 $cnt = self::get_glance_count();
311
312 //display via list
313 return '<li class="page-count">
314 <a href="' . $glancehref . '" class="thickbox ytprefs_glance_button" id="ytprefs_glance_button" title="YouTube Embeds At a Glance">' . number_format_i18n($cnt) . ' With YouTube</a>
315 </li>';
316 }
317
318 public static function show_glance_table()
319 {
320 $glancehref = self::show_glance();
321 $cnt = self::get_glance_count();
322 return
323 '<tr>
324 <td class="first b"><a title="YouTube Embeds At a Glance" href="' . $glancehref . '" class="thickbox ytprefs_glance_button">' . number_format_i18n($cnt) . '</a></td>
325 <td class="t"><a title="YouTube Embeds At a Glance" href="' . $glancehref . '" id="ytprefs_glance_button" class="thickbox ytprefs_glance_button">With YouTube</a></td>
326 </tr>';
327 }
328
329 public static function get_glance_count()
330 {
331 global $wpdb;
332 $query_sql = "
333 SELECT count(*) as mytotal
334 FROM $wpdb->posts
335 WHERE (post_content LIKE '%youtube.com/%' OR post_content LIKE '%youtu.be/%')
336 AND post_status = 'publish'";
337
338 $query_result = $wpdb->get_results($query_sql, OBJECT);
339
340 return intval($query_result[0]->mytotal);
341 }
342
343 public static function show_glance()
344 {
345 $glancehref = admin_url('admin.php?page=youtube-ep-glance') . '&random=' . rand(1, 1000) . '&TB_iframe=true&width=780&height=800';
346 return $glancehref;
347 }
348
349 public static function glance_page()
350 {
351 ?>
352 <div class="wrap">
353 <style type="text/css">
354 #wphead {display:none;}
355 #wpbody{margin-left: 0px;}
356 .wrap {font-family: Arial; padding: 0px 10px 0px 10px; line-height: 180%;}
357 .bold {font-weight: bold;}
358 .orange {color: #f85d00;}
359 sup.orange {text-transform: lowercase; font-weight: bold; color: #f85d00;}
360 #adminmenuback {display: none;}
361 #adminmenu, adminmenuwrap {display: none;}
362 #wpcontent, .auto-fold #wpcontent {margin-left: 0px;}
363 #wpadminbar {display:none;}
364 html.wp-toolbar {padding: 0px;}
365 #footer, #wpfooter, .auto-fold #wpfooter {display: none;}
366 #wpfooter {clear: both}
367 .acctitle {background-color: #dddddd; border-radius: 5px; padding: 7px 15px 7px 15px; cursor: pointer; margin: 10px; font-weight: bold; font-size: 12px;}
368 .acctitle:hover {background-color: #cccccc;}
369 .accbox {display: none; position: relative; margin: 5px 8px 30px 15px; clear: both; line-height: 180%;}
370 .accclose {position: absolute; top: -38px; right: 5px; cursor: pointer; width: 24px; height: 24px;}
371 .accloader {padding-right: 20px;}
372 .accthumb {display: block; width: 300px; float: left; margin-right: 25px;}
373 .accinfo {width: 300px; float: left;}
374 .accvidtitle {font-weight: bold; font-size: 16px;}
375 .accthumb img {width: 300px; height: auto; display: block;}
376 .clearboth {clear: both;}
377 .pad20 {padding: 20px;}
378 .center {text-align: center;}
379 #screen-meta-links {display: none;}
380 </style>
381 <script type="text/javascript">
382 function accclose(ele)
383 {
384 jQuery(ele).parent('.accbox').hide(400);
385 }
386
387 (function ($j)
388 {
389 $j(document).ready(function ()
390 {
391
392
393 $j('.acctitle').on('click', function ()
394 {
395 var $acctitle = $j(this);
396 var $accbox = $j(this).parent().children('.accbox');
397 var pid = $accbox.attr("data-postid");
398 $acctitle.prepend('<img alt="loading" class="accloader" src="<?php echo plugins_url('images/ajax-loader.gif', __FILE__) ?>" />');
399 jQuery.ajax({
400 type: "post",
401 dataType: "json",
402 timeout: 30000,
403 url: window._EPYTA_ ? window._EPYTA_.wpajaxurl : ajaxurl,
404 data: {action: 'my_embedplus_glance_vids', postid: pid},
405 success: function (response)
406 {
407 if (response.type === "success")
408 {
409 $accbox.html(response.data),
410 $accbox.show(400);
411 }
412 else
413 {
414 }
415 },
416 error: function (xhr, ajaxOptions, thrownError)
417 {
418
419 },
420 complete: function ()
421 {
422 $acctitle.children('.accloader').remove();
423 }
424
425 });
426 });
427 });
428 })(jQuery);</script>
429 <?php
430 global $wpdb;
431 $query_sql = "
432 SELECT SQL_CALC_FOUND_ROWS *
433 FROM $wpdb->posts
434 WHERE (post_content LIKE '%youtube.com/%' OR post_content LIKE '%youtu.be/%')
435 AND post_status = 'publish'
436 order by post_date DESC LIMIT 0, 10";
437
438 $query_result = $wpdb->get_results($query_sql, OBJECT);
439
440 if ($query_result !== null)
441 {
442 $total = $wpdb->get_var("SELECT FOUND_ROWS();");
443 global $post;
444 echo '<h2>10 Latest Posts/Pages with YouTube Videos (' . intval($total) . ' Total)</h2>';
445 ?>
446
447 We recommend using this page as an easy way to check the results of the global default settings you make (e.g. hide annotations) on your recent embeds. Or, simply use it as an index to jump right to your posts that contain YouTube embeds.
448
449 <?php
450 if ($total > 0)
451 {
452 echo '<ul class="accord">';
453 foreach ($query_result as $post)
454 {
455 echo '<li>';
456 setup_postdata($post);
457 the_title('<div class="acctitle">', ' &raquo;</div>');
458 echo '<div class="accbox" data-postid="' . $post->ID . '"></div><div class="clearboth"></div></li>';
459 }
460 echo '</ul>';
461 }
462 else
463 {
464 echo '<p class="center bold orange">You currently do not have any YouTube embeds yet.</p>';
465 }
466 }
467
468 wp_reset_postdata();
469 ?>
470 To remove this feature from your dashboard, simply uncheck <i>Show "At a Glance" Embed Links</i> in the <a target="_blank" href="<?php echo admin_url('admin.php?page=youtube-my-preferences#jumpdefaults') ?>">plugin settings page &raquo;</a>.
471
472 </div>
473 <?php
474 }
475
476 public static function is_ajax()
477 {
478 $requested_with = filter_input(INPUT_SERVER, 'HTTP_X_REQUESTED_WITH');
479 $is_ajax = (function_exists('wp_doing_ajax') && wp_doing_ajax() || (!empty($requested_with) && strtolower($requested_with) == 'xmlhttprequest') || (defined('DOING_AJAX') && DOING_AJAX));
480 if ($is_ajax)
481 {
482 header('HTTP/1.1 200 OK');
483 }
484 return $is_ajax;
485 }
486
487 public static function my_embedplus_glance_vids()
488 {
489 $result = array();
490 if (self::is_ajax())
491 {
492 if (!current_user_can('edit_posts'))
493 {
494 wp_send_json_error('Unauthorized');
495 die();
496 }
497 $postid = intval($_REQUEST['postid']);
498 $currpost = get_post($postid);
499
500 $thehtml = '<img alt="close" class="accclose" onclick="accclose(this)" src="' . plugins_url('images/accclose.png', __FILE__) . '" />';
501
502 $matches = array();
503 $ismatch = preg_match_all(self::$justurlregex, $currpost->post_content, $matches);
504
505 if ($ismatch)
506 {
507 foreach ($matches[0] as $match)
508 {
509 $link = trim(preg_replace('/&amp;/i', '&', $match));
510 $link = preg_replace('/\s/', '', $link);
511 $link = trim(str_replace(self::$badentities, self::$goodliterals, $link));
512
513 $linkparamstemp = explode('?', $link);
514
515 $linkparams = array();
516 if (count($linkparamstemp) > 1)
517 {
518 $linkparams = self::keyvalue($linkparamstemp[1], true);
519 }
520 if (strpos($linkparamstemp[0], 'youtu.be') !== false && !isset($linkparams['v']))
521 {
522 $vtemp = explode('/', $linkparamstemp[0]);
523 $linkparams['v'] = array_pop($vtemp);
524 }
525
526 $vidid = $linkparams['v'];
527
528 if ($vidid != null)
529 {
530 try
531 {
532 $odata = self::get_oembed('https://youtube.com/watch?v=' . $vidid, 1920, 1280);
533 $postlink = get_permalink($postid);
534 if ($odata != null && !is_wp_error($odata))
535 {
536 $_name = esc_attr(sanitize_text_field($odata->title));
537 $_description = esc_attr(sanitize_text_field($odata->author_name));
538 $_thumbnailUrl = esc_url("https://i.ytimg.com/vi/" . $vidid . "/0.jpg");
539
540 $thehtml .= '<a target="_blank" href="' . $postlink . '" class="accthumb"><img alt="YouTube Video" src="' . $_thumbnailUrl . '" /></a>';
541 $thehtml .= '<div class="accinfo">';
542 $thehtml .= '<a target="_blank" href="' . $postlink . '" class="accvidtitle">' . $_name . '</a>';
543 $thehtml .= '<div class="accdesc">' . (strlen($_description) > 400 ? substr($_description, 0, 400) . "..." : $_description) . '</div>';
544 $thehtml .= '</div>';
545 $thehtml .= '<div class="clearboth pad20"></div>';
546 }
547 else
548 {
549 $thehtml .= '<p class="center bold orange">This <a target="_blank" href="' . $postlink . '">post/page</a> contains a video that has been removed from YouTube.';
550 $thehtml .= '<br><a target="_blank" href="https://www.embedplus.com/dashboard/pro-easy-video-analytics.aspx?ref=glancevids">Activate delete video tracking to catch these cases &raquo;</a>';
551 $thehtml .= '</strong>';
552 }
553 }
554 catch (Exception $ex)
555 {
556
557 }
558 }
559 else if (isset($linkparams['list']))
560 {
561 // if playlist
562 try
563 {
564 $odata = self::get_oembed('https://youtube.com/playlist?list=' . $linkparams['list'], 1920, 1280);
565 $postlink = get_permalink($postid);
566 if ($odata != null && !is_wp_error($odata))
567 {
568 $_name = esc_attr(sanitize_text_field($odata->title));
569 $_description = esc_attr(sanitize_text_field($odata->author_name));
570 $_thumbnailUrl = esc_url($odata->thumbnail_url);
571
572 $thehtml .= '<a target="_blank" href="' . $postlink . '" class="accthumb"><img alt="YouTube Video" src="' . $_thumbnailUrl . '" /></a>';
573 $thehtml .= '<div class="accinfo">';
574 $thehtml .= '<a target="_blank" href="' . $postlink . '" class="accvidtitle">' . $_name . '</a>';
575 $thehtml .= '<div class="accdesc">' . (strlen($_description) > 400 ? substr($_description, 0, 400) . "..." : $_description) . '</div>';
576 $thehtml .= '</div>';
577 $thehtml .= '<div class="clearboth pad20"></div>';
578 }
579 else
580 {
581 $thehtml .= '<p class="center bold orange">This <a target="_blank" href="' . $postlink . '">post/page</a> contains a video that has been removed from YouTube.';
582 $thehtml .= '<br><a target="_blank" href="https://www.embedplus.com/dashboard/pro-easy-video-analytics.aspx?ref=glancevids">Activate delete video tracking to catch these cases &raquo;</a>';
583 $thehtml .= '</strong>';
584 }
585 }
586 catch (Exception $ex)
587 {
588
589 }
590 }
591 }
592 }
593
594
595
596 if ($currpost != null)
597 {
598 $result['type'] = 'success';
599 $result['data'] = $thehtml;
600 }
601 else
602 {
603 $result['type'] = 'error';
604 }
605 echo json_encode($result);
606 }
607 else
608 {
609 $result['type'] = 'error';
610 header("Location: " . $_SERVER["HTTP_REFERER"]);
611 }
612 die();
613 }
614
615 public static function my_embedplus_glance_count()
616 {
617 $result = array();
618 if (self::is_ajax())
619 {
620 if (!current_user_can('edit_posts'))
621 {
622 wp_send_json_error('Unauthorized');
623 die();
624 }
625 $thehtml = '';
626
627 try
628 {
629 if (version_compare(get_bloginfo('version'), '3.8', '>='))
630 {
631 $result['container'] = '#dashboard_right_now ul';
632 $thehtml .= self::show_glance_list();
633 }
634 else
635 {
636 $result['container'] = '#dashboard_right_now .table_content table tbody';
637 $thehtml .= self::show_glance_table();
638 }
639 $result['type'] = 'success';
640 $result['data'] = $thehtml;
641 }
642 catch (Exception $e)
643 {
644 $result['type'] = 'error';
645 }
646
647 echo json_encode($result);
648 }
649 else
650 {
651 $result['type'] = 'error';
652 header("Location: " . $_SERVER["HTTP_REFERER"]);
653 }
654 die();
655 }
656
657 public static function try_get_ytid($url)
658 {
659 $theytid = null;
660 if (strpos($url, 'v=') !== false)
661 {
662 $url_params = explode('?', $url);
663 $kvp = self::keyvalue($url_params[1], true);
664 $theytid = $kvp['v'];
665 }
666 else if (strpos($url, "youtu.be") !== false)
667 {
668 $shortpath = explode('/', parse_url($url, PHP_URL_PATH));
669 $theytid = $shortpath[1];
670 }
671 return $theytid;
672 }
673
674 public static function wizard()
675 {
676 ?>
677 <div class="wrap" id="epyt_wiz_wrap">
678 <div class="smallnote center"> Please periodically check the YouTube plugin tab on your admin panel to review the latest options. </div>
679
680 <?php
681 $form_valid = true;
682 $acc_expand = '';
683 $get_pro_link = self::$epbase . '/dashboard/pro-easy-video-analytics.aspx?ref=wizard';
684
685
686
687 $step1_api_error_msg = ' Please confirm that the link works in your browser, and that <em>the owner of the video allowed embed sharing permissions (otherwise, contact the owner of the video to allow embedding)</em>. Then copy that full link in your address bar to paste here. If you are sure your link is correct, then (1) your API key may be too restrictive (<a target="_blank" href="https://console.developers.google.com/apis/credentials">check here</a>) or (2) you have reached your Google quota (<a href="https://console.developers.google.com/apis/dashboard" target="_blank">check here</a>). You can apply to Google for a <a href="https://services.google.com/fb/forms/ytapiquotarequest/" target="_blank">quota increase here</a>.';
688 $step1_video_errors = '';
689 $step1_video_error_invalid = 'Sorry, that does not seem to be a link to an existing video. Please confirm that the link works in your browser, and that <em>the owner of the video allowed embed sharing permissions (otherwise, contact the owner of the video to allow embedding)</em>. Then copy that full link in your address bar to paste here.';
690 $step1_playlist_errors = '';
691 $step1_playlist_error_invalid = 'Sorry, that does not seem to be a link to an existing playlist. Please confirm that the link works in your browser, and that <em>the owner of the playlist allowed embed sharing permissions (otherwise, contact the owner of the video to allow embedding)</em>. Then copy that full link in your address bar to paste here.';
692 $step1_channel_errors = '';
693 $step1_channel_error_invalid = 'Sorry, that does not seem to be a link to an existing video. ' . $step1_api_error_msg;
694 $step1_live_errors = '';
695 $step1_live_error_invalid = 'Sorry, that does not seem to be a valid link to an existing live video. ' . $step1_api_error_msg;
696 $step1_livechannel_errors = '';
697 $step1_livechannel_error_invalid = __('Sorry, that does not seem to be a link to an existing channel. Note: the custom channel name will not work. Please enter either a) the official channel format shown above, or b) any any single video belonging to the channel and the plugin can retrieve the official channel format for you.', 'text_domain');
698
699 $if_live_preview = false;
700
701 $theytid = null;
702 $theplaylistid = null;
703 $submit_type = null;
704
705 if (isset($_POST['wizform_submit']))
706 {
707 check_admin_referer('_epyt_wiz', '_epyt_nonce');
708
709 $submit_type = sanitize_text_field($_POST['wizform_submit']);
710 if ($submit_type === 'step1_video')
711 {
712 // validate
713 $search = sanitize_text_field(trim($_POST['txtUrl']));
714
715 try
716 {
717 if (empty($search))
718 {
719 throw new Exception();
720 }
721 else
722 {
723 // cleanup
724 $search = str_replace('/shorts/', '/watch?v=', $search);
725 }
726 if (preg_match(self::$justurlregex, $search))
727 {
728 //$search = esc_url($search);
729
730 try
731 {
732 $theytid = self::try_get_ytid($search);
733
734 if ($theytid == null)
735 {
736 $form_valid = false;
737 $step1_video_errors = $step1_video_error_invalid;
738 $acc_expand = 'h3_video';
739 }
740 else
741 {
742
743 $odata = self::get_oembed('http://youtube.com/watch?v=' . $theytid, 1920, 1280);
744 if (is_object($odata))
745 {
746 ?>
747
748 <div id="step2_video" class="center">
749
750 <h2>
751 <?php
752 if (isset($odata->title))
753 {
754 echo sanitize_text_field($odata->title);
755 }
756 ?>
757 </h2>
758 <p class="center">
759 <a class="ui-button ui-widget ui-corner-all" href="<?php echo $get_pro_link; ?>" target="_blank"><span class="ui-icon ui-icon-gear"></span> Customize (PRO)</a>
760 &nbsp; <a class="ui-button ui-widget ui-corner-all inserttopost" rel="[embedyt] https://www.youtube.com/watch?v=<?php echo esc_attr($theytid) ?>[/embedyt]"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span> Insert Into Editor</a>
761 </p>
762 &nbsp; Or Copy Code:
763 <span class="copycode">[embedyt] https://www.youtube.com/watch?v=<?php echo esc_attr($theytid) ?>[/embedyt]</span>
764 <div class="clearboth" style="height: 10px;">
765 </div>
766 <div class="ep-wizard-preview-video-wrapper">
767 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/<?php echo esc_attr($theytid) ?>?rel=0" allowfullscreen="" frameborder="0"></iframe>
768 </div>
769
770 </div>
771 <?php
772 }
773 else
774 {
775 $form_valid = false;
776 $step1_video_errors = $step1_video_error_invalid;
777 $acc_expand = 'h3_video';
778 }
779 }
780 }
781 catch (Exception $ex)
782 {
783 $form_valid = false;
784 $step1_video_errors = $step1_video_error_invalid;
785 $acc_expand = 'h3_video';
786 }
787 }
788 else
789 {
790 $search_options = new stdClass();
791 $search_options->q = $search;
792 $search_options->pageToken = null;
793 ?>
794 <div id="step2_video_search" class="center">
795 <h2>You searched for: <em class="orange"><?php echo sanitize_text_field($search); ?></em> </h2>
796
797 <?php
798 $search_page = self::get_search_page($search_options);
799 echo $search_page->html;
800 ?>
801 </div>
802 <?php
803 }
804
805 // // if valid, set and display next step
806 // if not,form_valid = false and set accordion expander and error messages
807 }
808 catch (Exception $ex)
809 {
810 $form_valid = false;
811 $step1_video_errors = $step1_video_error_invalid;
812 $acc_expand = 'h3_video';
813 }
814 }
815 else if ($submit_type === 'step1_playlist')
816 {
817 $search = sanitize_text_field(trim($_POST['txtUrlPlaylist']));
818 try
819 {
820 if (empty($search))
821 {
822 throw new Exception();
823 }
824 if (preg_match(self::$justurlregex, $search))
825 {
826 try
827 {
828 $theytid = null;
829 try
830 {
831 $theytid = self::try_get_ytid($search);
832 }
833 catch (Exception $ex)
834 {
835
836 }
837
838 $urlparams = explode('?', $search);
839 $qvars = array();
840 parse_str($urlparams[1], $qvars);
841 $theplaylistid = $qvars["list"];
842
843 $odata = self::get_oembed('https://youtube.com/playlist?list=' . $theplaylistid, 1920, 1280);
844
845 if (is_object($odata))
846 {
847 $rel = 'https://www.youtube.com/embed?listType=playlist&list=' . (esc_attr($theplaylistid) . (empty($theytid) ? '' : '&v=' . esc_attr($theytid)));
848 ?>
849
850 <div id="step2_playlist" class="center">
851
852 <h2>
853 <?php
854 if (isset($odata->title))
855 {
856 echo 'Playlist: ' . sanitize_text_field($odata->title);
857 }
858 ?>
859 </h2>
860 <p class="center">
861 <a class="ui-button ui-widget ui-corner-all inserttopost" rel="[embedyt] <?php echo $rel; ?>[/embedyt]"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span> Insert as Playlist</a>
862 &nbsp; <a class="ui-button ui-widget ui-corner-all inserttopost" rel="[embedyt] <?php echo $rel . '&layout=gallery'; ?>[/embedyt]"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span> Insert as Gallery</a>
863 &nbsp; <a class="ui-button ui-widget ui-corner-all" href="<?php echo $get_pro_link; ?>" target="_blank"><span class="ui-icon ui-icon-gear"></span> Customize (PRO)</a>
864 </p>
865 <p>
866 Or Copy Code:
867 </p>
868 <p>
869 Playlist Layout: <span class="copycode">[embedyt] <?php echo $rel; ?>[/embedyt]</span>
870 </p>
871 <p>
872 Gallery Layout: <span class="copycode">[embedyt] <?php echo $rel . '&layout=gallery'; ?>[/embedyt]</span>
873 </p>
874 <div class="clearboth" style="height: 10px;">
875 </div>
876 <div class="ep-wizard-preview-video-wrapper">
877 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="<?php echo $rel; ?>" allowfullscreen="" frameborder="0"></iframe>
878 </div>
879 </div>
880 <?php
881 }
882 else
883 {
884 $form_valid = false;
885 $step1_playlist_errors = $step1_playlist_error_invalid;
886 $acc_expand = 'h3_playlist';
887 }
888 }
889 catch (Exception $ex)
890 {
891 $form_valid = false;
892 $step1_playlist_errors = $step1_playlist_error_invalid;
893 $acc_expand = 'h3_playlist';
894 }
895 }
896 }
897 catch (Exception $ex)
898 {
899 $form_valid = false;
900 $step1_playlist_errors = $step1_playlist_error_invalid;
901 $acc_expand = 'h3_playlist';
902 }
903 }
904 else if ($submit_type === 'step1_channel')
905 {
906 $search = sanitize_text_field(trim($_POST['txtUrlChannel']));
907 try
908 {
909 if (empty($search))
910 {
911 throw new Exception();
912 }
913 if (preg_match(self::$justurlregex, $search) || preg_match('@/channel/(.+)@', $search))
914 {
915 try
916 {
917 $thechannel = null;
918 if (preg_match(self::$justurlregex, $search))
919 {
920 // single id
921 $theytid = null;
922 try
923 {
924 $theytid = self::try_get_ytid($search);
925 }
926 catch (Exception $ex)
927 {
928
929 }
930 $chanvid = null;
931 if ($theytid)
932 {
933 $chanvid = self::get_video_snippet($theytid);
934 }
935 if ($chanvid)
936 {
937 $thechannel = self::get_channel_snippet($chanvid->snippet->channelId);
938 }
939 }
940 else
941 {
942 // channel id
943 $chanmatch = array();
944 preg_match('@/channel/(.+)@', $search, $chanmatch);
945 if (!empty($chanmatch))
946 {
947 $thechannel = self::get_channel_snippet($chanmatch[1]);
948 }
949 }
950 if ($thechannel)
951 {
952 $theplaylistid = $thechannel->contentDetails->relatedPlaylists->uploads;
953 $rel = 'https://www.youtube.com/embed?listType=playlist&list=' . (esc_attr($theplaylistid));
954 ?>
955
956 <div id="step2_channel" class="center">
957
958 <h2>
959 <?php
960 echo 'Channel: ' . sanitize_text_field($thechannel->snippet->title);
961 ?>
962 </h2>
963 <p class="center">
964 <a class="ui-button ui-widget ui-corner-all inserttopost" rel="[embedyt] <?php echo $rel; ?>[/embedyt]"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span> Insert as Playlist</a>
965 &nbsp; <a class="ui-button ui-widget ui-corner-all inserttopost" rel="[embedyt] <?php echo $rel . '&layout=gallery'; ?>[/embedyt]"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span> Insert as Gallery</a>
966 &nbsp; <a class="ui-button ui-widget ui-corner-all" href="<?php echo $get_pro_link; ?>" target="_blank"><span class="ui-icon ui-icon-gear"></span> Customize (PRO)</a>
967 </p>
968 <p>
969 Or Copy Code:
970 </p>
971 <p>
972 Playlist Layout: <span class="copycode">[embedyt] <?php echo $rel; ?>[/embedyt]</span>
973 </p>
974 <p>
975 Gallery Layout: <span class="copycode">[embedyt] <?php echo $rel . '&layout=gallery'; ?>[/embedyt]</span>
976 </p>
977 <div class="clearboth" style="height: 10px;">
978 </div>
979 <div class="ep-wizard-preview-video-wrapper">
980 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="<?php echo $rel; ?>" allowfullscreen="" frameborder="0"></iframe>
981 </div>
982 </div>
983 <?php
984 }
985 else
986 {
987 $form_valid = false;
988 $step1_channel_errors = $step1_channel_error_invalid;
989 $acc_expand = 'h3_channel';
990 }
991 }
992 catch (Exception $ex)
993 {
994 $form_valid = false;
995 $step1_channel_errors = $step1_channel_error_invalid;
996 $acc_expand = 'h3_channel';
997 }
998 }
999 }
1000 catch (Exception $ex)
1001 {
1002 $form_valid = false;
1003 $step1_channel_errors = $step1_channel_error_invalid;
1004 $acc_expand = 'h3_channel';
1005 }
1006 }
1007 else if ($submit_type === 'step1_livechannel')
1008 {
1009 $search = sanitize_text_field(trim($_POST['txtUrlLiveChannel']));
1010 try
1011 {
1012 if (empty($search))
1013 {
1014 throw new Exception();
1015 }
1016 if (preg_match(self::$justurlregex, $search) || preg_match('@/channel/(.+)@', $search))
1017 {
1018 try
1019 {
1020 $thechannelid = null;
1021 if (preg_match(self::$justurlregex, $search))
1022 {
1023 // single id
1024 $theytid = null;
1025 try
1026 {
1027 $theytid = self::try_get_ytid($search);
1028 }
1029 catch (Exception $ex)
1030 {
1031
1032 }
1033 $chanvid = null;
1034 if ($theytid)
1035 {
1036 $chanvid = self::get_video_snippet($theytid);
1037 }
1038 if ($chanvid)
1039 {
1040 $thechannelid = $chanvid->snippet->channelId;
1041 }
1042 }
1043 else
1044 {
1045 // channel id
1046 $chanmatch = array();
1047 preg_match('@/channel/(.+)@', $search, $chanmatch);
1048 if (!empty($chanmatch))
1049 {
1050 $thechannelid = $chanmatch[1];
1051 }
1052 }
1053 if (!empty($thechannelid))
1054 {
1055 $rel = 'https://www.youtube.com/embed/live_stream?channel=' . (esc_attr($thechannelid));
1056
1057 $final_title = esc_url('https://www.youtube.com/channel/' . $thechannelid);
1058 $final_title_prefix = 'Live stream from channel';
1059 $doing_live = true;
1060 ?>
1061
1062 <div id="step2_livechannel" class="center">
1063 <h2>
1064 <?php
1065 echo 'Live stream from channel: ' . esc_url('https://www.youtube.com/channel/' . $thechannelid);
1066 ?>
1067 </h2>
1068 <p class="center">
1069 <a class="ui-button ui-widget ui-corner-all inserttopost" rel="[embedyt] https://www.youtube.com/embed/live_stream?channel=<?php echo esc_attr($thechannelid) ?>[/embedyt]"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span> Insert Into Editor</a>
1070 &nbsp;
1071 <a class="ui-button ui-widget ui-corner-all" href="<?php echo $get_pro_link; ?>" target="_blank"><span class="ui-icon ui-icon-gear"></span> Customize (PRO)</a>
1072 </p>
1073 &nbsp; Or Copy Code:
1074 <span class="copycode">[embedyt] https://www.youtube.com/embed/live_stream?channel=<?php echo esc_attr($thechannelid) ?>[/embedyt]</span>
1075 <div class="clearboth" style="height: 10px;">
1076 </div>
1077 <p>
1078 <?php _e('If you see a black/empty YouTube player, then it likely means that you do not have any currently running or future live streams that are scheduled in your channel, so the plugin isn\'t getting any data from the YouTube API to show. If you want to continue to use the channel based live stream embedding method, we suggest regularly scheduling one or more live streams, or using the live stream fallback content feature, so the player is not black/empty.', 'text_domain'); ?>
1079 </p>
1080 <div class="ep-wizard-preview-video-wrapper">
1081 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/live_stream?channel=<?php echo esc_attr($thechannelid) ?>" allowfullscreen="" frameborder="0"></iframe>
1082 </div>
1083 </div>
1084 <?php
1085 }
1086 else
1087 {
1088 $form_valid = false;
1089 $step1_livechannel_errors = $step1_livechannel_error_invalid;
1090 $acc_expand = 'h3_live';
1091 }
1092 }
1093 catch (Exception $ex)
1094 {
1095 $form_valid = false;
1096 $step1_livechannel_errors = $step1_livechannel_error_invalid;
1097 $acc_expand = 'h3_live';
1098 }
1099 }
1100 else
1101 {
1102 $form_valid = false;
1103 $step1_livechannel_errors = $step1_livechannel_error_invalid;
1104 $acc_expand = 'h3_live';
1105 }
1106 }
1107 catch (Exception $ex)
1108 {
1109 $form_valid = false;
1110 $step1_livechannel_errors = $step1_livechannel_error_invalid;
1111 $acc_expand = 'h3_live';
1112 }
1113 }
1114 else if ($submit_type === 'step1_live')
1115 {
1116 $search = sanitize_text_field(trim($_POST['txtUrlLive']));
1117 try
1118 {
1119 if (empty($search))
1120 {
1121 throw new Exception();
1122 }
1123
1124 try
1125 {
1126 $theytid = null;
1127 try
1128 {
1129 $theytid = self::try_get_ytid($search);
1130 }
1131 catch (Exception $ex)
1132 {
1133
1134 }
1135 $live_attempt = self::get_video_snippet($theytid);
1136 if ($live_attempt)
1137 {
1138 $if_live_preview = $live_attempt->id;
1139 $final_title = sanitize_text_field($live_attempt->snippet->title);
1140 $final_title_prefix = 'Live Stream';
1141 }
1142 $rel = 'https://www.youtube.com/watch?v=' . (esc_attr($theytid)) . '&live=1';
1143 $doing_live = true;
1144 ?>
1145 <div id="step2_live" class="center">
1146
1147 <h2>
1148 <?php
1149 echo 'Live Stream (or Premiere): ' . sanitize_text_field($live_attempt->snippet->title);
1150 ?>
1151 </h2>
1152 <p class="center">
1153 <a class="ui-button ui-widget ui-corner-all inserttopost" rel="[embedyt] <?php echo $rel; ?>[/embedyt]"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span> Insert Into Editor</a>
1154 &nbsp; <a class="ui-button ui-widget ui-corner-all" href="<?php echo $get_pro_link; ?>" target="_blank"><span class="ui-icon ui-icon-gear"></span> Customize (PRO)</a>
1155 </p>
1156 <p>
1157 Or Copy Code:
1158 </p>
1159 <p>
1160 <span class="copycode">[embedyt] <?php echo $rel; ?>[/embedyt]</span>
1161 </p>
1162 <div class="clearboth" style="height: 10px;">
1163 </div>
1164 <?php
1165 if ($if_live_preview)
1166 {
1167 ?>
1168 <div class="ep-wizard-preview-video-wrapper">
1169 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/<?php echo esc_attr($if_live_preview) ?>?rel=0" allowfullscreen="" frameborder="0"></iframe>
1170 </div>
1171 <?php
1172 }
1173 ?>
1174 <p>
1175 <?php _e('<strong>Is your live stream not working?</strong> Read more here: <a href="https://support.google.com/youtube/answer/2474026?hl=en" target="_blank">https://support.google.com/youtube/answer/2474026?hl=en</a>', 'text_domain'); ?>
1176 </p>
1177 </div>
1178 <?php
1179 }
1180 catch (Exception $ex)
1181 {
1182 $form_valid = false;
1183 $step1_live_errors = $step1_live_error_invalid;
1184 $acc_expand = 'h3_live';
1185 }
1186 }
1187 catch (Exception $ex)
1188 {
1189 $form_valid = false;
1190 $step1_live_errors = $step1_live_error_invalid;
1191 $acc_expand = 'h3_live';
1192 }
1193 }
1194 else
1195 {
1196 $form_valid = false;
1197 $acc_expand = 'h3none';
1198 }
1199 }
1200
1201 if (!isset($_POST['wizform_submit']) || ($form_valid === false))
1202 {
1203 if ($form_valid === false)
1204 {
1205 ?>
1206 <script type="text/javascript">
1207 var _EPYTWIZ_ = _EPYTWIZ_ || {};
1208 _EPYTWIZ_.acc_expand = '<?php echo sanitize_key($acc_expand) ?>';</script>
1209 <?php
1210 }
1211 ?>
1212
1213 <div class="wiz-accordion">
1214 <h3 class="header-go"> <a href="<?php echo admin_url('admin.php?page=youtube-my-preferences#jumpdefaults'); ?>">Check my general YouTube embedding instructions and settings. </a></h3>
1215 <div class="header-go-content"></div>
1216 <h3 id="h3_video"> <a href="#"><?php _e('Embed a single video, or YouTube short.', 'text_domain'); ?></a></h3>
1217 <div>
1218 <h4 class="center">Single video directions</h4>
1219 <p>
1220 <?php _e('Paste the url of a single video below (examples: <em>https://www.youtube.com/watch?v=YVvn8dpSAt0</em> or <em>https://www.youtube.com/shorts/J38Yq85ZoyY</em>)', 'text_domain'); ?>
1221 </p>
1222 <form name="wizform_video" method="post" action="" class="wizform" id="wizform_video">
1223 <?php wp_nonce_field('_epyt_wiz', '_epyt_nonce', true); ?>
1224 <div class="center txt-button-align">
1225 <input name="txtUrl" maxlength="200" id="txtUrl" class="txturlpastecustom ui-widget ui-widget-content ui-corner-all" placeholder="Paste URL here" type="text"> <button name="wizform_submit" class="ui-button ui-widget ui-corner-all" type="submit" value="step1_video">Submit</button>
1226 </div>
1227 <p class="badpaste orange bold" style="display: none;">
1228 Please do not paste full embedcode above, only simple links to the YouTube video.
1229 <br />
1230 We have attempted to correct it above, but please doublecheck!
1231 </p>
1232 </form>
1233 <?php echo $step1_video_errors ? '<p class="orange bold">' . $step1_video_errors . '</p>' : ''; ?>
1234 <p><em>Note: You can also search YouTube videos by title in the text box above (example: <em>TED talks</em>). However, searching will use a significant amount of your YouTube API quota.</em></p>
1235 </div>
1236 <h3 id="h3_playlist"> <a href="#">Embed a playlist. </a></h3>
1237 <div>
1238 <h4 class="center">Playlist directions</h4>
1239 <div class="playlist-tabs">
1240 <ul>
1241 <li><a href="#ptabs-1">Self-contained layout directions</a></li>
1242 <li><a href="#ptabs-2">Gallery layout directions</a></li>
1243 </ul>
1244 <div id="ptabs-1">
1245 <img src="<?php echo plugins_url('/images/icon-playlist-self.jpg', __FILE__) ?>" class="icon-playlist" />
1246 <ol>
1247 <li>Go to the page for the playlist that lists all of its videos (<a href="https://www.youtube.com/playlist?list=PL70DEC2B0568B5469" target="_blank">Example &raquo;</a>). </li>
1248 <li>You may then click on the video that you want the playlist to start with (this step only applies to self-contained playlists. You cannot pick a starter for gallery layout directions).</li>
1249 <li>Copy the URL in your browser and paste it in the textbox below. You'll notice that a playlist URL contains the playlist ID (e.g. "PL...")</li>
1250 <li>Click "Get Playlist" to continue.</li>
1251 </ol>
1252 <div class="clearboth">
1253 </div>
1254 </div>
1255 <div id="ptabs-2">
1256 <img src="<?php echo plugins_url('/images/icon-playlist-gallery.jpg', __FILE__) ?>" class="icon-playlist" />
1257 <ol>
1258 <li>Go to the page for the playlist that lists all of its videos (<a href="https://www.youtube.com/playlist?list=PL70DEC2B0568B5469" target="_blank">Example &raquo;</a>). </li>
1259 <li>Copy the URL in your browser and paste it in the textbox below. You'll notice that a playlist URL contains the playlist ID (e.g. "PL...")</li>
1260 <li>Click "Get Playlist" to continue.</li>
1261 </ol>
1262 <div class="clearboth">
1263 </div>
1264 </div>
1265 </div>
1266
1267 <form name="wizform_playlist" method="post" action="" class="wizform" id="wizform_playlist">
1268 <?php wp_nonce_field('_epyt_wiz', '_epyt_nonce', true); ?>
1269 <div class="center txt-button-align">
1270 <input name="txtUrlPlaylist" maxlength="200" id="txtUrlPlaylist" class="txturlpastecustom ui-widget ui-widget-content ui-corner-all" placeholder="Paste the playlist link here" type="text">
1271 <button name="wizform_submit" class="ui-button ui-widget ui-corner-all" type="submit" value="step1_playlist">Get Playlist</button>
1272 </div>
1273 </form>
1274 <?php echo $step1_playlist_errors ? '<p class="orange bold">' . $step1_playlist_errors . '</p>' : ''; ?>
1275 </div>
1276 <h3 id="h3_channel"> <a href="#">Embed a channel. </a></h3>
1277 <div>
1278 <h4 class="center">Channel directions</h4>
1279 <?php
1280 if (!self::has_api_key())
1281 {
1282 echo str_replace('###', '"search for channel"', self::$get_api_key_msg);
1283 }
1284 else
1285 {
1286 ?>
1287 <p>
1288 <?php _e('If you already know the direct link to the channel ID, enter it below. <br>Example: https://www.youtube.com<strong>/channel/</strong>UCnM5iMGiKsZg-iOlIO2ZkdQ <p class="error-channel-format smallnote">Note: the following format will not work: https://www.youtube.com<strong>/c/</strong>customchannelname If you cannot locate the proper channel ID format above, then try the other method below.</p> ', 'text_domain'); ?>
1289 </p>
1290 <p>
1291 Or, simply enter a link to any single video that belongs to the user's channel, and the plugin will find the channel for you.<br>Example: https://www.youtube.com/watch?v=YVvn8dpSAt0
1292 </p>
1293 <form name="wizform_channel" method="post" action="" class="wizform" id="wizform_channel">
1294 <?php wp_nonce_field('_epyt_wiz', '_epyt_nonce', true); ?>
1295 <div class="center txt-button-align">
1296 <input name="txtUrlChannel" maxlength="200" id="txtUrlChannel" class="txturlpastecustom ui-widget ui-widget-content ui-corner-all" placeholder="Paste YouTube link here" type="text"> <button name="wizform_submit" class="ui-button ui-widget ui-corner-all" type="submit" value="step1_channel">Get Channel</button>
1297 </div>
1298 <p class="badpaste orange bold" style="display: none;">
1299 Please do not paste full embedcode above, only simple links to the YouTube video.
1300 <br />
1301 We have attempted to correct it above, but please doublecheck!
1302 </p>
1303 </form>
1304 <?php echo $step1_channel_errors ? '<p class="orange bold">' . $step1_channel_errors . '</p>' : ''; ?>
1305 <?php
1306 }
1307 ?>
1308 </div>
1309 <h3 id="h3_live"> <a href="#">Embed a live stream or premiere video. </a></h3>
1310 <div>
1311 <h4 class="center">Live stream or premiere directions</h4>
1312 <?php
1313 if (!self::has_api_key())
1314 {
1315 echo str_replace('###', 'live stream', self::$get_api_key_msg);
1316 }
1317 else
1318 {
1319 ?>
1320 <div class="livestream-tabs">
1321 <ul>
1322 <li><a href="#livestream-tabs-2">Channel-based livestream (upgrade required)</a></li>
1323 <li><a href="#livestream-tabs-1">Direct link to livestream or premiere video</a></li>
1324 </ul>
1325 <div id="livestream-tabs-1">
1326 <p>
1327 This will embed a specific live stream or premiere video.
1328 </p>
1329 <ol>
1330 <li>
1331 Paste in the direct URL of the live stream or premiere below and click Submit. <br> Example: https://www.youtube.com/watch?v=<strong>5qap5aO4i9A</strong>
1332 </li>
1333 <li>
1334 On the next screen, customize or insert your video.
1335 </li>
1336 </ol>
1337 <form name="wizform_live" method="post" action="" class="wizform" id="wizform_live">
1338 <?php wp_nonce_field('_epyt_wiz', '_epyt_nonce', true); ?>
1339 <div class="center txt-button-align">
1340 <input name="txtUrlLive" maxlength="200" id="txtUrlLive" class="ui-widget ui-widget-content ui-corner-all" placeholder="Paste YouTube link here" type="text"> <button name="wizform_submit" class="ui-button ui-widget ui-corner-all" type="submit" value="step1_live">Submit</button>
1341 </div>
1342 </form>
1343 <?php echo $step1_live_errors ? '<p class="orange bold">' . $step1_live_errors . '</p>' : ''; ?>
1344 </div>
1345 <div id="livestream-tabs-2">
1346 <div class="alert">
1347 <p>
1348 Unfortunately, Google has recently removed their YouTube API feature that used to support automatic channel-based live streams. It appears they won't change things back. However, you do have a couple of choices:
1349 </p>
1350 <ol>
1351 <li>Use "Direct link" live streams, as explained in the other tab. The trade-off is that you will have to manually post and take down your future live streams every time they start and when they end, respectively.</li>
1352 <li>Or <a href="<?php echo self::$epbase ?>/dashboard/pro-easy-video-analytics.aspx" target="_blank">upgrade to Pro</a>, which has a solution that brings back all the "set it and forget it" features of channel-based embeds. We spent a significant amount of time developing a stable, long-term solution around YouTube's limitations, so we are releasing this effort exclusively to our Pro customers.</li>
1353 </ol>
1354
1355 </div>
1356 <?php echo $step1_livechannel_errors ? '<p class="orange bold">' . $step1_livechannel_errors . '</p>' : ''; ?>
1357 </div>
1358 </div>
1359 <?php
1360 }
1361 ?>
1362 </div>
1363 <h3 class="header-go"> <a href="<?php echo self::$epbase . '/dashboard/pro-easy-video-analytics.aspx?ref=wizardacc'; ?>">Check my performance, blocked countries, deleted videos, etc. (PRO) </a></h3>
1364 <div class="header-go-content"></div>
1365 </div>
1366 <?php
1367 }
1368 ?>
1369 </div>
1370 <?php
1371 }
1372
1373 public static function has_api_key()
1374 {
1375 if (isset(self::$alloptions[self::$opt_apikey]) && strlen(trim(self::$alloptions[self::$opt_apikey])) > 0)
1376 {
1377 return true;
1378 }
1379
1380 return false;
1381 }
1382
1383 public static function get_live_snippet($channel)
1384 {
1385 $apiEndpoint = 'https://www.googleapis.com/youtube/v3/search?order=date&part=snippet&maxResults=1&type=video&eventType=live&safeSearch=none&videoEmbeddable=true&key=' . self::$alloptions[self::$opt_apikey]
1386 . '&channelId=' . urlencode($channel);
1387 $apiResult = wp_remote_get($apiEndpoint, array('timeout' => self::$curltimeout, 'headers' => array('referer' => site_url())));
1388
1389 if (is_wp_error($apiResult))
1390 {
1391 return false;
1392 }
1393
1394 $jsonResult = json_decode($apiResult['body']);
1395
1396 if (isset($jsonResult->error))
1397 {
1398 return false;
1399 }
1400
1401 if (isset($jsonResult->items) && $jsonResult->items != null && is_array($jsonResult->items) && count($jsonResult->items))
1402 {
1403 return $jsonResult->items[0];
1404 }
1405
1406 return false;
1407 }
1408
1409 public static function get_video_snippet($vid)
1410 {
1411 $apiEndpoint = 'https://www.googleapis.com/youtube/v3/videos?part=snippet&maxResults=1&key=' . self::$alloptions[self::$opt_apikey]
1412 . '&id=' . urlencode($vid);
1413 $apiResult = wp_remote_get($apiEndpoint, array('timeout' => self::$curltimeout, 'headers' => array('referer' => site_url())));
1414
1415 if (is_wp_error($apiResult))
1416 {
1417 return false;
1418 }
1419
1420 $jsonResult = json_decode($apiResult['body']);
1421
1422 if (isset($jsonResult->error))
1423 {
1424 return false;
1425 }
1426
1427 if (isset($jsonResult->items) && $jsonResult->items != null && is_array($jsonResult->items) && count($jsonResult->items))
1428 {
1429 return $jsonResult->items[0];
1430 }
1431
1432 return false;
1433 }
1434
1435 public static function get_channel_snippet($channid)
1436 {
1437 $apiEndpoint = 'https://www.googleapis.com/youtube/v3/channels?part=contentDetails,snippet&key=' . self::$alloptions[self::$opt_apikey]
1438 . '&id=' . urlencode($channid);
1439 $apiResult = wp_remote_get($apiEndpoint, array('timeout' => self::$curltimeout, 'headers' => array('referer' => site_url())));
1440
1441 if (is_wp_error($apiResult))
1442 {
1443 return false;
1444 }
1445
1446 $jsonResult = json_decode($apiResult['body']);
1447
1448 if (isset($jsonResult->error))
1449 {
1450 return false;
1451 }
1452
1453 if (isset($jsonResult->items) && $jsonResult->items != null && is_array($jsonResult->items) && count($jsonResult->items))
1454 {
1455 return $jsonResult->items[0];
1456 }
1457
1458 return false;
1459 }
1460
1461 public static function clean_api_error($raw_message)
1462 {
1463 return htmlspecialchars(strip_tags(preg_replace('@&key=[^& ]+@i', '&key=*******', $raw_message)), ENT_QUOTES, 'UTF-8');
1464 }
1465
1466 public static function clean_api_error_html($raw_message, $add_boilerplate)
1467 {
1468 $clean_html = '<div>Sorry, there was a YouTube error.</div>';
1469 if (current_user_can('manage_options'))
1470 {
1471 $clean_html = '<div>Sorry, there was a YouTube API error: <em>' . self::clean_api_error($raw_message) . '</em>' .
1472 ( $add_boilerplate ? self::$boilerplate_api_error_message : '' ) .
1473 '</div>';
1474 }
1475 return $clean_html;
1476 }
1477
1478 public static function get_search_page($options)
1479 {
1480 $gallobj = new stdClass();
1481 $pageSize = 30;
1482
1483 if (!self::has_api_key())
1484 {
1485 $gallobj->html = '<div>' . str_replace('###', 'search', self::$get_api_key_msg) . '</div>';
1486 return $gallobj;
1487 }
1488
1489 $apiEndpoint = 'https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=' . $pageSize . '&type=video&safeSearch=none&videoEmbeddable=true&key=' . self::$alloptions[self::$opt_apikey]
1490 . '&q=' . urlencode($options->q);
1491 if (!empty($options->pageToken))
1492 {
1493 $apiEndpoint .= '&pageToken=' . $options->pageToken;
1494 }
1495
1496 $code = '';
1497 $apiResult = wp_remote_get($apiEndpoint, array('timeout' => self::$curltimeout, 'headers' => array('referer' => site_url())));
1498
1499 if (is_wp_error($apiResult))
1500 {
1501 $gallobj->html = self::clean_api_error_html($apiResult->get_error_message(), true);
1502 return $gallobj;
1503 }
1504
1505 $jsonResult = json_decode($apiResult['body']);
1506
1507 if (isset($jsonResult->error))
1508 {
1509 if (isset($jsonResult->error->message))
1510 {
1511 $gallobj->html = self::clean_api_error_html($jsonResult->error->message, true);
1512 return $gallobj;
1513 }
1514 $gallobj->html = '<div>Sorry, there may be an issue with your YouTube API key. ' . self::$boilerplate_api_error_message . '</div>';
1515 return $gallobj;
1516 }
1517
1518 $totalResults = $jsonResult->pageInfo->totalResults;
1519
1520 $nextPageToken = '';
1521 $prevPageToken = '';
1522 if (isset($jsonResult->nextPageToken))
1523 {
1524 $nextPageToken = $jsonResult->nextPageToken;
1525 }
1526
1527 if (isset($jsonResult->prevPageToken))
1528 {
1529 $prevPageToken = $jsonResult->prevPageToken;
1530 }
1531
1532 $cnt = 0;
1533
1534 $code .= '<div class="epyt-search-results">';
1535
1536 if (isset($jsonResult->items) && $jsonResult->items != null && is_array($jsonResult->items))
1537 {
1538 foreach ($jsonResult->items as $item)
1539 {
1540
1541 $thumb = new stdClass();
1542
1543 $thumb->id = isset($item->snippet->resourceId->videoId) ? $item->snippet->resourceId->videoId : null;
1544 $thumb->id = $thumb->id ? $thumb->id : (isset($item->id->videoId) ? $item->id->videoId : null);
1545
1546 if ($thumb->id)
1547 {
1548 $thumb->title = $item->snippet->title;
1549
1550 if (isset($item->snippet->thumbnails->high->url))
1551 {
1552 $thumb->img = $item->snippet->thumbnails->high->url;
1553 $thumb->quality = 'high';
1554 }
1555 elseif (isset($item->snippet->thumbnails->default->url))
1556 {
1557 $thumb->img = $item->snippet->thumbnails->default->url;
1558 $thumb->quality = 'default';
1559 }
1560 elseif (isset($item->snippet->thumbnails->medium->url))
1561 {
1562 $thumb->img = $item->snippet->thumbnails->medium->url;
1563 $thumb->quality = 'medium';
1564 }
1565 else
1566 {
1567 $thumb->img = plugins_url('/images/deleted-video-thumb.png', __FILE__);
1568 $thumb->quality = 'medium';
1569 }
1570
1571 $code .= self::get_search_result_html($thumb, $options);
1572 $cnt++;
1573 $code .= '<div class="clear-both"></div>';
1574 }
1575 }
1576 }
1577
1578 $code .= '<div class="clear-both"></div></div>';
1579
1580 $totalPages = ceil($totalResults / $pageSize);
1581 $pagination = '<div class="epyt-pagination">';
1582
1583 $txtprev = self::$alloptions[self::$opt_gallery_customarrows] ? self::$alloptions[self::$opt_gallery_customprev] : _('Prev');
1584 $pagination .= '<div tabindex="0" role="button" class="epyt-pagebutton epyt-prev ' . (empty($prevPageToken) ? ' hide ' : '') . '" data-q="' . esc_attr($options->q)
1585 . '" data-pagetoken="' . esc_attr($prevPageToken)
1586 . '"><div class="epyt-arrow">&laquo;</div> <div>' . $txtprev . '</div></div>';
1587
1588
1589 $pagination .= '<div class="epyt-pagenumbers ' . ($totalPages > 1 ? '' : 'hide') . '">';
1590 $pagination .= '<div class="epyt-current">1</div><div class="epyt-pageseparator"> / </div><div class="epyt-totalpages">' . $totalPages . '</div>';
1591 $pagination .= '</div>';
1592
1593 $txtnext = self::$alloptions[self::$opt_gallery_customarrows] ? self::$alloptions[self::$opt_gallery_customnext] : _('Next');
1594 $pagination .= '<div tabindex="0" role="button" class="epyt-pagebutton epyt-next' . (empty($nextPageToken) ? ' hide ' : '') . '" data-q="' . esc_attr($options->q)
1595 . '" data-pagetoken="' . esc_attr($nextPageToken)
1596 . '"><div>' . $txtnext . '</div> <div class="epyt-arrow">&raquo;</div></div>';
1597
1598 $pagination .= '<div class="epyt-loader"><img alt="loading" width="16" height="11" src="' . plugins_url('images/gallery-page-loader.gif', __FILE__) . '"></div>';
1599 $pagination .= '</div>';
1600
1601 $code = $pagination . $code . $pagination;
1602 $gallobj->html = $code;
1603 return $gallobj;
1604 }
1605
1606 public static function get_search_result_html($thumb, $options)
1607 {
1608 $get_pro_link = self::$epbase . '/dashboard/pro-easy-video-analytics.aspx?ref=searchresult';
1609 $escId = esc_attr($thumb->id);
1610 $code = '';
1611
1612 $code .= '<div class="resultdiv" data-vid="' . $escId . '">
1613 <div class="resultinfo">
1614 <a class="pointer thumb load-movie" style="background-image: url(' . esc_url($thumb->img) . ')"></a>
1615 <a class="resulttitle pointer load-movie"><span class="ui-icon ui-icon-circle-triangle-e"></span> ' . sanitize_text_field($thumb->title) . '</a>
1616 <br>
1617 <span style="display: block;" id="scrollwatch' . $escId . '"></span>
1618 <div class="resultsubinfo">
1619 <p>
1620 <a class="ui-button ui-widget ui-corner-all" href="' . $get_pro_link . '" target="_blank"><span class="ui-icon ui-icon-gear"></span> Customize (PRO)</a>
1621 &nbsp; <a class="ui-button ui-widget ui-corner-all inserttopost" rel="[embedyt] https://www.youtube.com/watch?v=' . $escId . '[/embedyt]"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span> Insert Into Editor</a>
1622 </p>
1623 &nbsp; Or Copy Code:
1624 <span class="copycode">[embedyt] https://www.youtube.com/watch?v=' . $escId . '[/embedyt]</span>
1625 </div>
1626 </div>
1627 <div class="clearboth"></div>
1628 </div>
1629 <div id="moviecontainer' . $escId . '" class="center moviecontainer relative" style="display: none;">
1630 Preview: <a id="closeme' . $escId . '" class="closeme" data-vid="' . $escId . '">
1631 &times;
1632 </a>
1633 <div id="watch' . $escId . '">
1634 </div>
1635 </div>';
1636
1637 return $code;
1638 }
1639
1640 public static function user_in_roles_any($user, $roles)
1641 {
1642 foreach ($user->roles as $idx => $r)
1643 {
1644 if (in_array($r, $roles))
1645 {
1646 return true;
1647 }
1648 }
1649 return false;
1650 }
1651
1652 public static function is_restrict_wizard()
1653 {
1654 $curr_user = wp_get_current_user();
1655 if (
1656 $curr_user->ID // logged in
1657 && isset(self::$alloptions[self::$opt_restrict_wizard]) && self::$alloptions[self::$opt_restrict_wizard] == 1 // restricting
1658 && is_array(self::$alloptions[self::$opt_restrict_wizard_roles]) && !self::user_in_roles_any($curr_user, self::$alloptions[self::$opt_restrict_wizard_roles])
1659 )
1660 {
1661 return true;
1662 }
1663 return false;
1664 }
1665
1666 public static function media_button_wizard()
1667 {
1668 if (self::is_restrict_wizard())
1669 {
1670 return;
1671 }
1672
1673 add_thickbox();
1674
1675 $wizhref = admin_url('admin.php?page=youtube-ep-wizard') .
1676 '&random=' . rand(1, 1000) .
1677 '&TB_iframe=true&width=950&height=800';
1678 ?>
1679 <a href="<?php echo esc_attr($wizhref); ?>" class="thickbox button ytprefs_media_link" id="ytprefs_wiz_button" title="Visual YouTube Search Tool and Wizard - For easier embedding"><span></span> YouTube</a>
1680 <?php
1681 }
1682
1683 public static function check_double_plugin_warning()
1684 {
1685 if (is_plugin_active('embedplus-for-wordpress/embedplus.php'))
1686 {
1687 add_action('admin_notices', array(self::class, "double_plugin_warning"));
1688 }
1689 }
1690
1691 public static function double_plugin_warning()
1692 {
1693 global $pagenow;
1694 $user_id = get_current_user_id();
1695 if ($pagenow != 'plugins.php' || get_user_meta($user_id, 'embedplus_double_plugin_warning', true) != 1)
1696 {
1697 //echo '<div class="error">' . $_SERVER['QUERY_STRING'] .'</div>';
1698 if ($pagenow == 'plugins.php' || strpos($_SERVER['QUERY_STRING'], 'youtube-my-preferences') !== false ||
1699 strpos($_SERVER['QUERY_STRING'], 'embedplus-video-analytics-dashboard') !== false ||
1700 strpos($_SERVER['QUERY_STRING'], 'youtube-ep-analytics-dashboard') !== false ||
1701 strpos($_SERVER['QUERY_STRING'], 'embedplus-official-options') !== false)
1702 {
1703 ?>
1704 <style type="text/css">
1705 .embedpluswarning img
1706 {
1707 vertical-align: text-bottom;
1708 }
1709 div.bgyellow {background-color: #FCFC94; position: relative;}
1710 a.epxout, a.epxout:hover {font-weight: bold; color: #ffffff; background-color: #ff8888; text-decoration: none;
1711 border-radius: 20px; font-size: 15px; position: absolute; top: 3px; right: 3px;
1712 line-height: 20px; text-align: center; width: 20px; height: 20px; display: block; cursor: pointer;}
1713 </style>
1714 <div class="error bgyellow embedpluswarningbox">
1715 <p class="embedpluswarning">
1716 <?php
1717 if ($pagenow == 'plugins.php')
1718 {
1719 echo '<a class="epxout">&times;</a>';
1720 }
1721 ?>
1722 Seems like you have two different YouTube plugins by the EmbedPlus Team installed; this one and <b>Advanced YouTube Embed.</b> We strongly suggest keeping only the one you prefer, so that they don't conflict with each other while trying to create your embeds.
1723 </p>
1724 </div>
1725
1726 <script type="text/javascript">
1727 (function ($)
1728 {
1729 $(document).ready(function ()
1730 {
1731 $('.epxout').on('click', function ()
1732 {
1733 $.ajax({
1734 type: "post",
1735 dataType: "json",
1736 timeout: 30000,
1737 url: window._EPYTA_ ? window._EPYTA_.wpajaxurl : ajaxurl,
1738 data: {action: 'my_embedplus_dismiss_double_plugin_warning'},
1739 success: function (response)
1740 {
1741 if (response.type === "success")
1742 {
1743 $(".embedpluswarningbox").hide();
1744 }
1745 },
1746 error: function (xhr, ajaxOptions, thrownError)
1747 {
1748 },
1749 complete: function ()
1750 {
1751 }
1752 });
1753 });
1754 });
1755 })(jQuery);</script>
1756 <?php
1757 }
1758 }
1759 }
1760
1761 public static function my_embedplus_dismiss_double_plugin_warning()
1762 {
1763 $result = array();
1764 if (self::is_ajax())
1765 {
1766 if (!current_user_can('manage_options'))
1767 {
1768 wp_send_json_error('Unauthorized');
1769 die();
1770 }
1771 $user_id = get_current_user_id();
1772 update_user_meta($user_id, 'embedplus_double_plugin_warning', 1);
1773 $result['type'] = 'success';
1774 echo json_encode($result);
1775 }
1776 else
1777 {
1778 $result['type'] = 'error';
1779 header("Location: " . $_SERVER["HTTP_REFERER"]);
1780 }
1781 die();
1782 }
1783
1784 public static function jsvars()
1785 {
1786 $loggedin = current_user_can('edit_posts');
1787 if (!($loggedin && self::$alloptions[self::$opt_admin_off_scripts]))
1788 {
1789 ?>
1790 <script data-cfasync="false">
1791 window._EPYT_ = window._EPYT_ || {
1792 ajaxurl: "<?php echo admin_url('admin-ajax.php'); ?>",
1793 security: "<?php echo wp_create_nonce('embedplus-nonce'); ?>",
1794 gallery_scrolloffset: <?php echo intval(self::$alloptions[self::$opt_gallery_scrolloffset]) ?>,
1795 eppathtoscripts: "<?php echo plugins_url('scripts/', __FILE__); ?>",
1796 eppath: "<?php echo plugins_url('/', __FILE__); ?>",
1797 epresponsiveselector: <?php echo self::get_responsiveselector(); ?>,
1798 version: "<?php echo esc_attr(self::$alloptions[self::$opt_version]) ?>",
1799 epdovol: true,
1800 evselector: '<?php echo self::get_evselector(); ?>',
1801 ajax_compat: <?php echo self::$alloptions[self::$opt_ajax_compat] == '1' ? 'true' : 'false' ?>,
1802 maxres_facade: '<?php echo esc_attr(self::$alloptions[self::$opt_maxres_facade]) ?>',
1803 ytapi_load: '<?php echo esc_attr(self::$alloptions[self::$opt_ytapi_load]) ?>',
1804 pause_others: <?php echo self::$alloptions[self::$opt_pause_others] == '1' ? 'true' : 'false' ?>,
1805 facade_mode: <?php echo self::$alloptions[self::$opt_facade_mode] == '1' ? 'true' : 'false' ?>,
1806 not_live_on_channel: <?php echo self::$alloptions[self::$opt_not_live_on_channel] == '1' ? 'true' : 'false' ?>,
1807 stopMobileBuffer: <?php echo self::$alloptions[self::$opt_stop_mobile_buffer] == '1' ? 'true' : 'false' ?>
1808 };</script>
1809 <?php
1810 }
1811 }
1812
1813 public static function fitvids()
1814 {
1815 $loggedin = current_user_can('edit_posts');
1816 if (!($loggedin && self::$alloptions[self::$opt_admin_off_scripts]) && (self::$alloptions[self::$opt_responsive] || self::$alloptions[self::$opt_widgetfit]))
1817 {
1818 wp_enqueue_script('__ytprefsfitvids__', plugins_url('scripts/fitvids' . self::$min . '.js', __FILE__), array('__ytprefs__'), self::$version, true);
1819 }
1820 }
1821
1822 public static function initoptions()
1823 {
1824 global $wpdb;
1825 $arroptions = get_option(self::$opt_alloptions);
1826 if ($arroptions !== false)
1827 {
1828 $bak = str_replace('.', '_', $arroptions[self::$opt_version]);
1829 add_option(self::$opt_alloptions . '_backup_' . $bak, $arroptions, '', 'no');
1830 $sql = "update " . $wpdb->options . " set autoload = 'no' where option_name like '" . self::$opt_alloptions . "\_backup\_%'";
1831 $wpdb->query($sql);
1832 }
1833
1834 // backup settings for migration
1835 if (isset($arroptions[self::$opt_pro]) && strlen(trim($arroptions[self::$opt_pro])) > 10)
1836 {
1837 add_option(self::$opt_alloptions . '_migrate', $arroptions);
1838 }
1839
1840 //vanilla defaults
1841 $_center = 0;
1842 $_glance = 0;
1843 $_autoplay = 0;
1844 $_cc_load_policy = 0;
1845 $_cc_lang_pref = '';
1846 $_iv_load_policy = 1;
1847 $_loop = 0;
1848 $_rel = 1;
1849 $_fs = 1;
1850 $_theme = 'dark';
1851 $_color = 'red';
1852 $_autohide = 2;
1853 $_pro = '';
1854 $_nocookie = 0;
1855 $_gb_compat = 1;
1856 $_facade_mode = 0;
1857 $_facade_autoplay = 1;
1858 $_gdpr_consent = 0;
1859 $_gdpr_consent_message = self::$dft_gdpr_consent_message;
1860 $_gdpr_consent_button = 'Accept YouTube Content';
1861 $_playlistorder = 0;
1862 $_acctitle = 0;
1863 $_migrate = 0;
1864 $_migrate_youtube = 0;
1865 $_migrate_embedplusvideo = 0;
1866 $_controls = 1;
1867 $_disablekb = 0;
1868 $_oldspacing = 1;
1869 $_frontend_only = 1;
1870 $_responsive = 0;
1871 $_responsive_all = 1;
1872 $_widgetfit = 1;
1873 $_evselector_light = 0;
1874 $_stop_mobile_buffer = 1;
1875 $_restrict_wizard = 0;
1876 $_restrict_wizard_roles = self::$dft_roles;
1877 $_ajax_compat = 0;
1878 $_maxres_facade = 'eager';
1879 $_ytapi_load = 'light';
1880 $_defaultdims = 1;
1881 $_defaultwidth = isset($GLOBALS['content_width']) && is_numeric($GLOBALS['content_width']) ? intval($GLOBALS['content_width']) : 800;
1882 $_defaultheight = intval($_defaultwidth * 9.0 / 16.0);
1883 $_playsinline = 0;
1884 $_origin = 0;
1885 $_pause_others = 0;
1886 $_defaultvol = 0;
1887 $_vol = '';
1888 $_apikey = '';
1889 $_hl = '';
1890 $_dohl = 0;
1891 $_gallery_columns = 3;
1892 $_gallery_collapse_grid = 0;
1893 $_gallery_collapse_grid_breaks = self::$dft_bpts;
1894 $_gallery_scrolloffset = 20;
1895 $_gallery_hideprivate = 1;
1896 $_gallery_showtitle = 1;
1897 $_gallery_showpaging = 1;
1898 $_gallery_autonext = 0;
1899 $_gallery_thumbplay = 1;
1900 $_gallery_channelsub = 0;
1901 $_gallery_channelsublink = '';
1902 $_gallery_channelsubtext = 'Subscribe to my channel';
1903 $_gallery_customarrows = 0;
1904 $_gallery_customprev = 'Prev';
1905 $_gallery_customnext = 'Next';
1906 $_gallery_pagesize = 15;
1907 $_not_live_content = '';
1908 $_not_live_on = 0;
1909 $_not_live_on_channel = 0;
1910 $_debugmode = 0;
1911 $_uninstall_data = 0;
1912 $_admin_off_scripts = 0;
1913 $_defer_js = 0;
1914 $_defer_jquery = 0;
1915 $_ajax_save = 1;
1916 $_show_pointer = 1;
1917 $_onboarded = 0;
1918 $_old_script_method = 0;
1919
1920 //update vanilla to previous settings if exists
1921 if ($arroptions !== false)
1922 {
1923 $_center = self::tryget($arroptions, self::$opt_center, 0);
1924 $_glance = self::tryget($arroptions, self::$opt_glance, $_glance);
1925 $_autoplay = self::tryget($arroptions, self::$opt_autoplay, 0);
1926 $_debugmode = self::tryget($arroptions, self::$opt_debugmode, 0);
1927 $_uninstall_data = self::tryget($arroptions, self::$opt_uninstall_data, 0);
1928 $_old_script_method = self::tryget($arroptions, self::$opt_old_script_method, 0);
1929 $_cc_load_policy = self::tryget($arroptions, self::$opt_cc_load_policy, 0);
1930 $_cc_lang_pref = self::tryget($arroptions, self::$opt_cc_lang_pref, $_cc_lang_pref);
1931 $_iv_load_policy = self::tryget($arroptions, self::$opt_iv_load_policy, 1);
1932 $_loop = self::tryget($arroptions, self::$opt_loop, 0);
1933 $_rel = self::tryget($arroptions, self::$opt_rel, 1);
1934 $_fs = self::tryget($arroptions, self::$opt_fs, 1);
1935 $_playsinline = self::tryget($arroptions, self::$opt_playsinline, 0);
1936 $_origin = self::tryget($arroptions, self::$opt_origin, 1);
1937 $_hl = self::tryget($arroptions, self::$opt_hl, '');
1938 $_dohl = self::tryget($arroptions, self::$opt_dohl, 0);
1939 $_theme = self::tryget($arroptions, self::$opt_theme, 'dark');
1940 $_color = self::tryget($arroptions, self::$opt_color, 'red');
1941 $_autohide = self::tryget($arroptions, self::$opt_autohide, 2);
1942 $_pro = self::tryget($arroptions, self::$opt_pro, '');
1943 $_nocookie = self::tryget($arroptions, self::$opt_nocookie, 0);
1944 $_gb_compat = self::tryget($arroptions, self::$opt_gb_compat, $_gb_compat);
1945 $_facade_mode = self::tryget($arroptions, self::$opt_facade_mode, $_facade_mode);
1946 $_facade_autoplay = self::tryget($arroptions, self::$opt_facade_autoplay, $_facade_autoplay);
1947 $_gdpr_consent = self::tryget($arroptions, self::$opt_gdpr_consent, $_gdpr_consent);
1948 $_gdpr_consent_message = self::tryget($arroptions, self::$opt_gdpr_consent_message, $_gdpr_consent_message);
1949 $_gdpr_consent_button = self::tryget($arroptions, self::$opt_gdpr_consent_button, $_gdpr_consent_button);
1950 $_playlistorder = self::tryget($arroptions, self::$opt_playlistorder, 0);
1951 $_acctitle = self::tryget($arroptions, self::$opt_acctitle, 0);
1952 $_migrate = self::tryget($arroptions, self::$opt_migrate, 0);
1953 $_migrate_youtube = self::tryget($arroptions, self::$opt_migrate_youtube, 0);
1954 $_migrate_embedplusvideo = self::tryget($arroptions, self::$opt_migrate_embedplusvideo, 0);
1955 $_controls = self::tryget($arroptions, self::$opt_controls, 1);
1956 $_controls = $_controls == 2 ? 1 : $_controls;
1957 $_disablekb = self::tryget($arroptions, self::$opt_disablekb, 0);
1958 $_oldspacing = self::tryget($arroptions, self::$opt_oldspacing, 1);
1959 $_frontend_only = self::tryget($arroptions, self::$opt_frontend_only, $_frontend_only);
1960 $_responsive = self::tryget($arroptions, self::$opt_responsive, $_responsive);
1961 $_responsive_all = self::tryget($arroptions, self::$opt_responsive_all, $_responsive_all);
1962 $_widgetfit = self::tryget($arroptions, self::$opt_widgetfit, 1);
1963 $_evselector_light = self::tryget($arroptions, self::$opt_evselector_light, 0);
1964 $_stop_mobile_buffer = self::tryget($arroptions, self::$opt_stop_mobile_buffer, 1);
1965 $_restrict_wizard = self::tryget($arroptions, self::$opt_restrict_wizard, 0);
1966 $_restrict_wizard_roles = self::tryget($arroptions, self::$opt_restrict_wizard_roles, self::$dft_roles);
1967 $_ajax_compat = self::tryget($arroptions, self::$opt_ajax_compat, 0);
1968 $_maxres_facade = self::tryget($arroptions, self::$opt_maxres_facade, $_maxres_facade);
1969 $_ytapi_load = self::tryget($arroptions, self::$opt_ytapi_load, $_ytapi_load);
1970 $_defaultdims = self::tryget($arroptions, self::$opt_defaultdims, $_defaultdims);
1971 $_defaultwidth = self::tryget($arroptions, self::$opt_defaultwidth, $_defaultwidth);
1972 $_defaultheight = self::tryget($arroptions, self::$opt_defaultheight, $_defaultheight);
1973 $_pause_others = self::tryget($arroptions, self::$opt_pause_others, $_pause_others);
1974 $_defaultvol = self::tryget($arroptions, self::$opt_defaultvol, 0);
1975 $_vol = self::tryget($arroptions, self::$opt_vol, '');
1976 $_apikey = self::tryget($arroptions, self::$opt_apikey, '');
1977 $_gallery_pagesize = self::tryget($arroptions, self::$opt_gallery_pagesize, 15);
1978 $_gallery_columns = self::tryget($arroptions, self::$opt_gallery_columns, 3);
1979 $_gallery_collapse_grid = self::tryget($arroptions, self::$opt_gallery_collapse_grid, 0);
1980 $_gallery_collapse_grid_breaks = self::tryget($arroptions, self::$opt_gallery_collapse_grid_breaks, self::$dft_bpts);
1981 $_gallery_scrolloffset = self::tryget($arroptions, self::$opt_gallery_scrolloffset, 20);
1982 $_gallery_hideprivate = self::tryget($arroptions, self::$opt_gallery_hideprivate, $_gallery_hideprivate);
1983 $_gallery_showtitle = self::tryget($arroptions, self::$opt_gallery_showtitle, 1);
1984 $_gallery_showpaging = self::tryget($arroptions, self::$opt_gallery_showpaging, 1);
1985 $_gallery_autonext = self::tryget($arroptions, self::$opt_gallery_autonext, 0);
1986 $_gallery_thumbplay = self::tryget($arroptions, self::$opt_gallery_thumbplay, 1);
1987 $_gallery_channelsub = self::tryget($arroptions, self::$opt_gallery_channelsub, $_gallery_channelsub);
1988 $_gallery_channelsublink = self::tryget($arroptions, self::$opt_gallery_channelsublink, $_gallery_channelsublink);
1989 $_gallery_channelsubtext = self::tryget($arroptions, self::$opt_gallery_channelsubtext, $_gallery_channelsubtext);
1990 $_gallery_customarrows = self::tryget($arroptions, self::$opt_gallery_customarrows, $_gallery_customarrows);
1991 $_gallery_customnext = self::tryget($arroptions, self::$opt_gallery_customnext, $_gallery_customnext);
1992 $_gallery_customprev = self::tryget($arroptions, self::$opt_gallery_customprev, $_gallery_customprev);
1993 $_not_live_content = self::tryget($arroptions, self::$opt_not_live_content, $_not_live_content);
1994 $_not_live_content = empty($_not_live_content) ? $_not_live_content : trim($_not_live_content);
1995 $_not_live_on = self::tryget($arroptions, self::$opt_not_live_on, empty($_not_live_content) ? 0 : $_not_live_on);
1996 $_not_live_on_channel = self::tryget($arroptions, self::$opt_not_live_on_channel, $_not_live_on_channel);
1997 $_admin_off_scripts = self::tryget($arroptions, self::$opt_admin_off_scripts, $_admin_off_scripts);
1998 $_defer_js = self::tryget($arroptions, self::$opt_defer_js, $_defer_js);
1999 $_defer_jquery = self::tryget($arroptions, self::$opt_defer_jquery, $_defer_jquery);
2000 $_ajax_save = self::tryget($arroptions, self::$opt_ajax_save, $_ajax_save);
2001 $_show_pointer = self::tryget($arroptions, self::$opt_show_pointer, $_show_pointer);
2002 $_onboarded = 0; // self::tryget($arroptions, self::$opt_onboarded, $_onboarded);
2003 }
2004 else
2005 {
2006 $_oldspacing = 0;
2007 }
2008
2009 $all = array(
2010 self::$opt_version => self::$version,
2011 self::$opt_center => $_center,
2012 self::$opt_glance => $_glance,
2013 self::$opt_autoplay => $_autoplay,
2014 self::$opt_cc_load_policy => $_cc_load_policy,
2015 self::$opt_cc_lang_pref => $_cc_lang_pref,
2016 self::$opt_iv_load_policy => $_iv_load_policy,
2017 self::$opt_loop => $_loop,
2018 self::$opt_rel => $_rel,
2019 self::$opt_fs => $_fs,
2020 self::$opt_playsinline => $_playsinline,
2021 self::$opt_origin => $_origin,
2022 self::$opt_autohide => $_autohide,
2023 self::$opt_hl => $_hl,
2024 self::$opt_dohl => $_dohl,
2025 self::$opt_theme => $_theme,
2026 self::$opt_color => $_color,
2027 self::$opt_pro => $_pro,
2028 self::$opt_nocookie => $_nocookie,
2029 self::$opt_gb_compat => $_gb_compat,
2030 self::$opt_facade_mode => $_facade_mode,
2031 self::$opt_facade_autoplay => $_facade_autoplay,
2032 self::$opt_gdpr_consent => $_gdpr_consent,
2033 self::$opt_gdpr_consent_message => $_gdpr_consent_message,
2034 self::$opt_gdpr_consent_button => $_gdpr_consent_button,
2035 self::$opt_playlistorder => $_playlistorder,
2036 self::$opt_acctitle => $_acctitle,
2037 self::$opt_migrate => $_migrate,
2038 self::$opt_migrate_youtube => $_migrate_youtube,
2039 self::$opt_migrate_embedplusvideo => $_migrate_embedplusvideo,
2040 self::$opt_controls => $_controls,
2041 self::$opt_disablekb => $_disablekb,
2042 self::$opt_oldspacing => $_oldspacing,
2043 self::$opt_frontend_only => $_frontend_only,
2044 self::$opt_responsive => $_responsive,
2045 self::$opt_responsive_all => $_responsive_all,
2046 self::$opt_widgetfit => $_widgetfit,
2047 self::$opt_evselector_light => $_evselector_light,
2048 self::$opt_stop_mobile_buffer => $_stop_mobile_buffer,
2049 self::$opt_restrict_wizard => $_restrict_wizard,
2050 self::$opt_restrict_wizard_roles => $_restrict_wizard_roles,
2051 self::$opt_ajax_compat => $_ajax_compat,
2052 self::$opt_maxres_facade => $_maxres_facade,
2053 self::$opt_ytapi_load => $_ytapi_load,
2054 self::$opt_defaultdims => $_defaultdims,
2055 self::$opt_defaultwidth => $_defaultwidth,
2056 self::$opt_defaultheight => $_defaultheight,
2057 self::$opt_pause_others => $_pause_others,
2058 self::$opt_defaultvol => $_defaultvol,
2059 self::$opt_vol => $_vol,
2060 self::$opt_apikey => $_apikey,
2061 self::$opt_gallery_columns => $_gallery_columns,
2062 self::$opt_gallery_collapse_grid => $_gallery_collapse_grid,
2063 self::$opt_gallery_collapse_grid_breaks => $_gallery_collapse_grid_breaks,
2064 self::$opt_gallery_scrolloffset => $_gallery_scrolloffset,
2065 self::$opt_gallery_hideprivate => $_gallery_hideprivate,
2066 self::$opt_gallery_showtitle => $_gallery_showtitle,
2067 self::$opt_gallery_showpaging => $_gallery_showpaging,
2068 self::$opt_gallery_autonext => $_gallery_autonext,
2069 self::$opt_gallery_thumbplay => $_gallery_thumbplay,
2070 self::$opt_gallery_channelsub => $_gallery_channelsub,
2071 self::$opt_gallery_channelsublink => $_gallery_channelsublink,
2072 self::$opt_gallery_channelsubtext => $_gallery_channelsubtext,
2073 self::$opt_gallery_customarrows => $_gallery_customarrows,
2074 self::$opt_gallery_customnext => $_gallery_customnext,
2075 self::$opt_gallery_customprev => $_gallery_customprev,
2076 self::$opt_gallery_pagesize => $_gallery_pagesize,
2077 self::$opt_not_live_content => $_not_live_content,
2078 self::$opt_not_live_on => $_not_live_on,
2079 self::$opt_not_live_on_channel => $_not_live_on_channel,
2080 self::$opt_debugmode => $_debugmode,
2081 self::$opt_uninstall_data => $_uninstall_data,
2082 self::$opt_admin_off_scripts => $_admin_off_scripts,
2083 self::$opt_defer_js => $_defer_js,
2084 self::$opt_defer_jquery => $_defer_jquery,
2085 self::$opt_ajax_save => $_ajax_save,
2086 self::$opt_show_pointer => $_show_pointer,
2087 self::$opt_onboarded => $_onboarded,
2088 self::$opt_old_script_method => $_old_script_method
2089 );
2090
2091 update_option(self::$opt_alloptions, $all);
2092 update_option('embed_autourls', 1);
2093 self::$alloptions = get_option(self::$opt_alloptions);
2094 }
2095
2096 public static function tryget($array, $key, $default = null)
2097 {
2098 return isset($array[$key]) ? $array[$key] : $default;
2099 }
2100
2101 public static function wp_above_version($ver)
2102 {
2103 global $wp_version;
2104 if (version_compare($wp_version, $ver, '>='))
2105 {
2106 return true;
2107 }
2108 return false;
2109 }
2110
2111 public static function do_ytprefs()
2112 {
2113 //add_filter('autoptimize_filter_js_exclude', array(self::class, 'ao_override_jsexclude'), 10, 1);
2114 if (
2115 !is_admin() || (self::$alloptions[self::$opt_frontend_only] != 1)
2116 //|| (function_exists('wp_doing_ajax') && wp_doing_ajax())
2117 )
2118 {
2119 add_filter('the_content', array(self::class, 'apply_prefs_content'), 1);
2120 add_filter('widget_text', array(self::class, 'apply_prefs_widget'), 1);
2121 //add_filter('bjll/skip_classes', array(self::class, 'bjll_skip_classes'), 10, 2);
2122
2123 add_filter('sgo_lazy_load_exclude_classes', array(self::class, 'exclude_lazy_sgo'));
2124
2125 add_shortcode('embedyt', array(self::class, 'apply_prefs_shortcode'));
2126 if (self::$alloptions[self::$opt_migrate] == 1)
2127 {
2128 if (self::$alloptions[self::$opt_migrate_youtube] == 1)
2129 {
2130 add_shortcode('youtube', array(self::class, 'apply_prefs_shortcode_youtube'));
2131 add_shortcode('youtube_video', array(self::class, 'apply_prefs_shortcode_youtube'));
2132 }
2133 if (self::$alloptions[self::$opt_migrate_embedplusvideo] == 1)
2134 {
2135 add_shortcode('embedplusvideo', array(self::class, 'apply_prefs_shortcode_embedplusvideo'));
2136 }
2137 }
2138 }
2139
2140 if (self::$alloptions[self::$opt_defer_js] == 1)
2141 {
2142 add_filter('script_loader_tag', array(self::class, 'defer_scripts'), 10, 3);
2143 }
2144 }
2145
2146 public static function ao_override_jsexclude($exclude)
2147 {
2148 if (strpos($exclude, 'ytprefs' . self::$min . '.js') === false)
2149 {
2150 return $exclude . ',ytprefs' . self::$min . '.js,__ytprefs__';
2151 }
2152 return $exclude;
2153 }
2154
2155 public static function exclude_lazy_sgo($classes)
2156 {
2157 $classes[] = '__youtube_prefs__';
2158 return $classes;
2159 }
2160
2161 public static function apply_prefs_shortcode($atts, $content = null)
2162 {
2163 $content = trim($content);
2164 $currfilter = current_filter();
2165 if (preg_match(self::$justurlregex, $content))
2166 {
2167 return self::get_html(array($content), strpos($currfilter, 'widget_text') === 0 ? false : true, false);
2168 }
2169 return '';
2170 }
2171
2172 public static function apply_prefs_shortcode_youtube($atts, $content = null)
2173 {
2174 $content = 'https://www.youtube.com/watch?v=' . trim($content);
2175 $currfilter = current_filter();
2176 if (preg_match(self::$justurlregex, $content))
2177 {
2178 return self::get_html(array($content), $currfilter == 'widget_text' ? false : true, false);
2179 }
2180 return '';
2181 }
2182
2183 public static function apply_prefs_shortcode_embedplusvideo($atts, $content = null)
2184 {
2185 $atts = shortcode_atts(array(
2186 "height" => self::$defaultheight,
2187 "width" => self::$defaultwidth,
2188 "vars" => "",
2189 "standard" => "",
2190 "id" => "ep" . rand(10000, 99999)
2191 ), $atts);
2192
2193 $epvars = $atts['vars'];
2194 $epvars = preg_replace('/\s/', '', $epvars);
2195 $epvars = preg_replace('/¬/', '&not', $epvars);
2196 $epvars = str_replace('&amp;', '&', $epvars);
2197
2198 $epparams = self::keyvalue($epvars, true);
2199
2200 if (isset($epparams) && isset($epparams['ytid']))
2201 {
2202 $start = isset($epparams['start']) && is_numeric($epparams['start']) ? '&start=' . intval($epparams['start']) : '';
2203 $end = isset($epparams['end']) && is_numeric($epparams['end']) ? '&end=' . intval($epparams['end']) : '';
2204 $end = isset($epparams['stop']) && is_numeric($epparams['stop']) ? '&end=' . intval($epparams['stop']) : '';
2205
2206 $url = 'https://www.youtube.com/watch?v=' . trim($epparams['ytid']) . $start . $end;
2207
2208 $currfilter = current_filter();
2209 if (preg_match(self::$justurlregex, $url))
2210 {
2211 return self::get_html(array($url), $currfilter == 'widget_text' ? false : true, false);
2212 }
2213 }
2214 return '';
2215 }
2216
2217 public static function apply_prefs_content($content)
2218 {
2219 $content = preg_replace_callback(self::$ytregex, array(self::class, "get_html_content"), $content);
2220 return $content;
2221 }
2222
2223 public static function apply_prefs_widget($content)
2224 {
2225 $content = preg_replace_callback(self::$ytregex, array(self::class, "get_html_widget"), $content);
2226 return $content;
2227 }
2228
2229 public static function get_html_content($m)
2230 {
2231 return self::get_html($m, true, true);
2232 }
2233
2234 public static function get_html_widget($m)
2235 {
2236 return self::get_html($m, false, true);
2237 }
2238
2239 public static function get_gallery_page($options)
2240 {
2241 $gallobj = new stdClass();
2242
2243 $options->pageSize = min(intval($options->pageSize), 50);
2244 $options->columns = intval($options->columns) == 0 ? 3 : intval($options->columns);
2245 $options->showTitle = intval($options->showTitle);
2246 $options->showPaging = intval($options->showPaging);
2247 $options->autonext = intval($options->autonext);
2248 $options->thumbplay = intval($options->thumbplay);
2249
2250 if (empty($options->apiKey))
2251 {
2252 $gallobj->html = '<div>Please enter your YouTube API key to embed galleries.</div>';
2253 return $gallobj;
2254 }
2255
2256 $apiEndpoint = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet,status&playlistId=' . $options->playlistId
2257 . '&maxResults=' . $options->pageSize
2258 . '&key=' . $options->apiKey;
2259 if ($options->pageToken != null)
2260 {
2261 $apiEndpoint .= '&pageToken=' . $options->pageToken;
2262 }
2263
2264 $code = '';
2265 $init_id = null;
2266
2267 $apiResult = wp_remote_get($apiEndpoint, array('timeout' => self::$curltimeout, 'headers' => array('referer' => site_url())));
2268
2269 if (is_wp_error($apiResult))
2270 {
2271 $gallobj->html = self::clean_api_error_html($apiResult->get_error_message(), true);
2272 return $gallobj;
2273 }
2274
2275 if (self::$alloptions[self::$opt_debugmode] == 1 && current_user_can('manage_options'))
2276 {
2277 $redactedEndpoint = preg_replace('@&key=[^&]+@i', '&key=PRIVATE', $apiEndpoint);
2278 $active_plugins = get_option('active_plugins');
2279 $gallobj->html = '<pre onclick="_EPADashboard_.selectText(this);" class="epyt-debug">CLICK this debug text to auto-select all. Then, COPY the selection.' . "\n\n" .
2280 'THIS IS DEBUG MODE OUTPUT. UNCHECK THE OPTION IN THE SETTINGS PAGE ONCE YOU ARE DONE DEBUGGING TO PUT THINGS BACK TO NORMAL.' . "\n\n" . $redactedEndpoint . "\n\n" . print_r($apiResult, true) . "\n\nActive Plugins\n\n" . print_r($active_plugins, true) . '</pre>';
2281 return $gallobj;
2282 }
2283
2284 $jsonResult = json_decode($apiResult['body']);
2285
2286 if (isset($jsonResult->error))
2287 {
2288 if (isset($jsonResult->error->message))
2289 {
2290 $gallobj->html = self::clean_api_error_html($jsonResult->error->message, true);
2291 return $gallobj;
2292 }
2293 $gallobj->html = '<div>Sorry, there may be an issue with your YouTube API key. ' . self::$boilerplate_api_error_message . '</div>';
2294 return $gallobj;
2295 }
2296
2297
2298
2299 $resultsPerPage = $options->pageSize; // $jsonResult->pageInfo->resultsPerPage;
2300 $totalResults = $jsonResult->pageInfo->totalResults;
2301
2302 $nextPageToken = '';
2303 $prevPageToken = '';
2304 if (isset($jsonResult->nextPageToken))
2305 {
2306 $nextPageToken = $jsonResult->nextPageToken;
2307 }
2308
2309 if (isset($jsonResult->prevPageToken))
2310 {
2311 $prevPageToken = $jsonResult->prevPageToken;
2312 }
2313
2314 $cnt = 0;
2315 $colclass = ' epyt-cols-' . $options->columns . ' ';
2316 $code .= '<div class="epyt-gallery-allthumbs ' . $colclass . '">';
2317
2318 if (isset($jsonResult->items) && $jsonResult->items != null && is_array($jsonResult->items))
2319 {
2320 if (strpos($options->playlistId, 'UU') === 0)
2321 {
2322 // sort only channels
2323 usort($jsonResult->items, array(self::class, 'compare_vid_date')); // sorts in place
2324 }
2325
2326 foreach ($jsonResult->items as $item)
2327 {
2328
2329 $thumb = new stdClass();
2330
2331 $thumb->id = isset($item->snippet->resourceId->videoId) ? $item->snippet->resourceId->videoId : null;
2332 $thumb->id = $thumb->id ? $thumb->id : $item->id->videoId;
2333 $thumb->title = $options->showTitle ? $item->snippet->title : '';
2334 $thumb->privacyStatus = isset($item->status->privacyStatus) ? $item->status->privacyStatus : null;
2335
2336 if ($thumb->privacyStatus == 'private' && self::$alloptions[self::$opt_gallery_hideprivate] == 1)
2337 {
2338 continue;
2339 }
2340
2341 if ($cnt == 0 && $options->pageToken == null)
2342 {
2343 $init_id = $thumb->id;
2344 }
2345
2346 if ($thumb->privacyStatus == 'private')
2347 {
2348 $thumb->img = plugins_url('/images/private.png', __FILE__);
2349 $thumb->quality = 'medium';
2350 }
2351 else
2352 {
2353 if (isset($item->snippet->thumbnails->high->url))
2354 {
2355 $thumb->img = $item->snippet->thumbnails->high->url;
2356 $thumb->quality = 'high';
2357 }
2358 elseif (isset($item->snippet->thumbnails->default->url))
2359 {
2360 $thumb->img = $item->snippet->thumbnails->default->url;
2361 $thumb->quality = 'default';
2362 }
2363 elseif (isset($item->snippet->thumbnails->medium->url))
2364 {
2365 $thumb->img = $item->snippet->thumbnails->medium->url;
2366 $thumb->quality = 'medium';
2367 }
2368 else
2369 {
2370 $thumb->img = plugins_url('/images/deleted-video-thumb.png', __FILE__);
2371 $thumb->quality = 'medium';
2372 }
2373 }
2374
2375 $code .= self::get_thumbnail_html($thumb, $options);
2376 $cnt++;
2377
2378 if ($cnt % $options->columns === 0)
2379 {
2380 $code .= '<div class="epyt-gallery-rowbreak"></div>';
2381 }
2382 }
2383 }
2384
2385 $code .= '<div class="epyt-gallery-clear"></div></div>';
2386
2387 $totalPages = ceil($totalResults / $resultsPerPage);
2388 $pagination = '<div class="epyt-pagination ' . ($options->showPaging == 0 ? 'epyt-hide-pagination' : '') . '">';
2389
2390 $txtprev = self::$alloptions[self::$opt_gallery_customarrows] ? self::$alloptions[self::$opt_gallery_customprev] : _('Prev');
2391 $pagination .= '<div tabindex="0" role="button" class="epyt-pagebutton epyt-prev ' . (empty($prevPageToken) ? ' hide ' : '') . '" data-playlistid="' . esc_attr($options->playlistId)
2392 . '" data-pagesize="' . intval($options->pageSize)
2393 . '" data-pagetoken="' . esc_attr($prevPageToken)
2394 . '" data-epcolumns="' . intval($options->columns)
2395 . '" data-showtitle="' . intval($options->showTitle)
2396 . '" data-showpaging="' . intval($options->showPaging)
2397 . '" data-autonext="' . intval($options->autonext)
2398 . '" data-thumbplay="' . intval($options->thumbplay)
2399 . '"><div class="epyt-arrow">&laquo;</div> <div>' . $txtprev . '</div></div>';
2400
2401
2402 $pagination .= '<div class="epyt-pagenumbers ' . ($totalPages > 1 ? '' : 'hide') . '">';
2403 $pagination .= '<div class="epyt-current">1</div><div class="epyt-pageseparator"> / </div><div class="epyt-totalpages">' . $totalPages . '</div>';
2404 $pagination .= '</div>';
2405
2406 $txtnext = self::$alloptions[self::$opt_gallery_customarrows] ? self::$alloptions[self::$opt_gallery_customnext] : _('Next');
2407 $pagination .= '<div tabindex="0" role="button" class="epyt-pagebutton epyt-next' . (empty($nextPageToken) ? ' hide ' : '') . '" data-playlistid="' . esc_attr($options->playlistId)
2408 . '" data-pagesize="' . intval($options->pageSize)
2409 . '" data-pagetoken="' . esc_attr($nextPageToken)
2410 . '" data-epcolumns="' . intval($options->columns)
2411 . '" data-showtitle="' . intval($options->showTitle)
2412 . '" data-showpaging="' . intval($options->showPaging)
2413 . '" data-autonext="' . intval($options->autonext)
2414 . '" data-thumbplay="' . intval($options->thumbplay)
2415 . '"><div>' . $txtnext . '</div> <div class="epyt-arrow">&raquo;</div></div>';
2416
2417 $pagination .= '<div class="epyt-loader"><img alt="loading" width="16" height="11" src="' . plugins_url('images/gallery-page-loader.gif', __FILE__) . '"></div>';
2418 $pagination .= '</div>';
2419
2420 // if ($options->showPaging == 0)
2421 // {
2422 // $pagination = '<div class="epyt-pagination"></div>';
2423 // }
2424 $code = $pagination . $code . $pagination;
2425 $gallobj->html = $code;
2426 $gallobj->init_id = $init_id;
2427 return $gallobj;
2428 }
2429
2430 public static function compare_vid_date($a, $b)
2431 {
2432 if ($a->snippet->publishedAt == $b->snippet->publishedAt)
2433 {
2434 return 0;
2435 }
2436 return ($a->snippet->publishedAt > $b->snippet->publishedAt) ? -1 : 1;
2437 }
2438
2439 public static function get_thumbnail_html($thumb, $options)
2440 {
2441 $escId = esc_attr($thumb->id);
2442 $code = '';
2443 $code .= '<div tabindex="0" role="button" data-videoid="' . $escId . '" class="epyt-gallery-thumb">';
2444
2445 $code .= (self::gdpr_mode() ? '<div class="epyt-gallery-img-box"><div class="epyt-gallery-img epyt-gallery-img-gdpr">' :
2446 '<div class="epyt-gallery-img-box"><div class="epyt-gallery-img" style="background-image: url(' . esc_attr($thumb->img) . ')">') .
2447 '<div class="epyt-gallery-playhover"><img alt="play" class="epyt-play-img" width="30" height="23" src="' . plugins_url('images/playhover.png', __FILE__) . '" data-no-lazy="1" data-skipgform_ajax_framebjll="" /><div class="epyt-gallery-playcrutch"></div></div>' .
2448 '</div></div>';
2449
2450
2451 if (!empty($thumb->title))
2452 {
2453 $code .= '<div class="epyt-gallery-title">' . esc_html($thumb->title) . '</div>';
2454 }
2455 else
2456 {
2457 $code .= '<div class="epyt-gallery-notitle"><span>' . esc_html($thumb->title) . '</span></div>';
2458 }
2459 $code .= '</div>';
2460 return $code;
2461 }
2462
2463 public static function my_embedplus_gallery_page()
2464 {
2465 if (self::is_ajax())
2466 {
2467 //check_ajax_referer('embedplus-nonce', 'security');
2468 $options = (object) $_POST['options'];
2469 $options->apiKey = self::$alloptions[self::$opt_apikey];
2470 echo self::get_gallery_page($options)->html;
2471 die();
2472 }
2473 }
2474
2475 public static function get_html($m, $iscontent, $isoverride)
2476 {
2477 //$time_start = microtime(true);
2478
2479 $link = trim(str_replace(self::$badentities, self::$goodliterals, $m[0]));
2480
2481 $link = preg_replace('/\s/', '', $link);
2482 $linkparamstemp = explode('?', $link);
2483
2484 $linkparams = array();
2485 if (count($linkparamstemp) > 1)
2486 {
2487 $linkparams = self::keyvalue($linkparamstemp[1], true);
2488 }
2489 if (strpos($linkparamstemp[0], 'youtu.be') !== false && !isset($linkparams['v']))
2490 {
2491 $vtemp = explode('/', $linkparamstemp[0]);
2492 $linkparams['v'] = array_pop($vtemp);
2493 }
2494
2495 if (isset($linkparams['live']) && $linkparams['live'] == '1')
2496 {
2497 $live_error_msg = ' To embed live videos, please make sure you performed the <a href="https://www.youtube.com/watch?v=ZCfrNvu6nMc" target="_blank">steps in this video</a> to create and save a proper server API key.';
2498 if (isset(self::$alloptions[self::$opt_apikey]))
2499 {
2500 if (isset($linkparams['channel']))
2501 {
2502 $linkparams['live_stream'] = 1;
2503 if (false) // takes up too much quota;
2504 {
2505 try
2506 {
2507 $ytapilink_live = 'https://www.googleapis.com/youtube/v3/search?order=date&maxResults=1&type=video&eventType=live&safeSearch=none&videoEmbeddable=true&channelId=' . $linkparams['channel'] . '&part=snippet&key=' . self::$alloptions[self::$opt_apikey];
2508 $apidata_live = wp_remote_get($ytapilink_live, array('timeout' => self::$curltimeout, 'headers' => array('referer' => site_url())));
2509 if (!is_wp_error($apidata_live))
2510 {
2511 $raw = wp_remote_retrieve_body($apidata_live);
2512 if (!empty($raw))
2513 {
2514 $json = json_decode($raw, true);
2515 if (!isset($json['error']) && is_array($json) && count($json['items']))
2516 {
2517 $linkparams['v'] = $json['items'][0]['id']['videoId'];
2518 }
2519 else if (isset($json['error']))
2520 {
2521 return $live_error_msg; // . ' <em>(Error code ' . $json['error']->code . ': ' . $json['error']->message . ')</em>';
2522 }
2523 }
2524 }
2525 }
2526 catch (Exception $ex)
2527 {
2528 return $live_error_msg;
2529 }
2530 }
2531 }
2532 else if (isset($linkparams['v']))
2533 {
2534 ////////////////////// process single video live stream
2535 try
2536 {
2537 if (self::$alloptions[self::$opt_not_live_on])
2538 {
2539 // if not_live_content isn't being used, just process as a normal single video. otherwise: if not currently live (nor upcoming?), unset $linkparams['v']
2540 $not_live_content = trim(htmlspecialchars_decode(wp_strip_all_tags(self::$alloptions[self::$opt_not_live_content], true), ENT_QUOTES));
2541 if (!empty($not_live_content))
2542 {
2543 $ytapilink_live = 'https://www.googleapis.com/youtube/v3/videos?id=' . $linkparams['v'] . '&part=snippet&key=' . self::$alloptions[self::$opt_apikey];
2544 $apidata_live = wp_remote_get($ytapilink_live, array('timeout' => self::$curltimeout, 'headers' => array('referer' => site_url())));
2545 if (!is_wp_error($apidata_live))
2546 {
2547 $raw = wp_remote_retrieve_body($apidata_live);
2548 if (!empty($raw))
2549 {
2550 $json = json_decode($raw, true);
2551 if (!isset($json['error']) && is_array($json) && count($json['items']))
2552 {
2553 if (isset($json['items'][0]['snippet']['liveBroadcastContent']) && $json['items'][0]['snippet']['liveBroadcastContent'] != 'live')
2554 {
2555 unset($linkparams['v']);
2556 }
2557 }
2558 else if (isset($json['error']))
2559 {
2560 return $live_error_msg; // . ' <em>(Error code ' . $json['error']->code . ': ' . $json['error']->message . ')</em>';
2561 }
2562 }
2563 }
2564 }
2565 }
2566 }
2567 catch (Exception $ex)
2568 {
2569 return $live_error_msg;
2570 }
2571 }
2572 }
2573 else
2574 {
2575 return $live_error_msg;
2576 }
2577
2578 if (!isset($linkparams['v']) && !isset($linkparams['live_stream']))
2579 {
2580 return apply_filters('ytprefs_filter_the_content_light', wp_kses_post(self::$alloptions[self::$opt_not_live_content]));
2581 }
2582 }
2583
2584 if (stripos($linkparamstemp[0], 'live_stream') !== false)
2585 {
2586 $linkparams['live_stream'] = 1;
2587 }
2588
2589 $youtubebaseurl = 'youtube';
2590 $voloutput = '';
2591 $acctitle = '';
2592 $relstop = '';
2593
2594 $finalparams = $linkparams + self::$alloptions;
2595
2596 self::init_dimensions($link, $linkparams, $finalparams);
2597
2598 if (self::$alloptions[self::$opt_nocookie] == 1)
2599 {
2600 $youtubebaseurl = 'youtube-nocookie';
2601 }
2602
2603 if (self::$alloptions[self::$opt_defaultvol] == 1)
2604 {
2605 $voloutput = ' data-vol="' . self::$alloptions[self::$opt_vol] . '" ';
2606 }
2607
2608 if (is_numeric(self::$alloptions[self::$opt_rel]) && intval(self::$alloptions[self::$opt_rel]) === -1)
2609 {
2610 $relstop = ' data-relstop="1" ';
2611 }
2612
2613 if (!empty($finalparams[self::$opt_loop]))
2614 {
2615 $relstop = '';
2616 }
2617
2618 if (self::$alloptions[self::$opt_dohl] == 1)
2619 {
2620 $locale = get_locale();
2621 $finalparams[self::$opt_hl] = $locale;
2622 }
2623 else
2624 {
2625 unset($finalparams[self::$opt_hl]);
2626 }
2627
2628 $centercode = '';
2629 if ($finalparams[self::$opt_center] == 1)
2630 {
2631 $centercode = ' style="display: block; margin: 0px auto;" ';
2632 }
2633
2634 if (self::$alloptions[self::$opt_acctitle] == 1)
2635 {
2636 try
2637 {
2638 //attr escape
2639 if (self::$oembeddata)
2640 {
2641 $acctitle = self::$oembeddata->title;
2642 }
2643 else
2644 {
2645
2646 if (isset($linkparams['list']))
2647 {
2648 $odata = self::get_oembed('https://youtube.com/playlist?list=' . $linkparams['list'], 1920, 1280);
2649 if (is_object($odata) && isset($odata->title))
2650 {
2651 $acctitle = $odata->title;
2652 }
2653 }
2654 else if (isset($linkparams['v']))
2655 {
2656 $odata = self::get_oembed('https://youtube.com/watch?v=' . $linkparams['v'], 1920, 1280);
2657 if (is_object($odata) && isset($odata->title))
2658 {
2659 $acctitle = $odata->title;
2660 }
2661 }
2662 }
2663
2664 if ($acctitle)
2665 {
2666 $acctitle = ' title="' . esc_attr($acctitle) . '" ';
2667 }
2668 else
2669 {
2670 $acctitle = ' title="YouTube player" ';
2671 }
2672 }
2673 catch (Exception $e)
2674 {
2675
2676 }
2677 }
2678 else
2679 {
2680 $acctitle = ' title="YouTube player" ';
2681 }
2682
2683 // playlist cleanup
2684 $videoidoutput = isset($linkparams['v']) ? $linkparams['v'] : '';
2685
2686 if ((self::$alloptions[self::$opt_playlistorder] == 1 || isset($finalparams['plindex'])) && isset($finalparams['list']))
2687 {
2688 try
2689 {
2690 $videoidoutput = '';
2691 if (isset($finalparams['plindex']))
2692 {
2693 $finalparams['index'] = intval($finalparams['plindex']);
2694 }
2695 }
2696 catch (Exception $ex)
2697 {
2698
2699 }
2700 }
2701
2702 $galleryWrapper1 = '';
2703 $galleryWrapper2 = '';
2704 $galleryCode = '';
2705 $galleryid_ifm_data = '';
2706 if (isset($finalparams['layout']) && strtolower($finalparams['layout']) == 'gallery' && isset($finalparams['list']))
2707 {
2708 $gallery_options = new stdClass();
2709 $gallery_options->playlistId = $finalparams['list'];
2710 $gallery_options->pageToken = null;
2711 $gallery_options->pageSize = $finalparams[self::$opt_gallery_pagesize];
2712 $gallery_options->columns = intval($finalparams[self::$opt_gallery_columns]);
2713 $gallery_options->showTitle = intval($finalparams[self::$opt_gallery_showtitle]);
2714 $gallery_options->showPaging = intval($finalparams[self::$opt_gallery_showpaging]);
2715 $gallery_options->autonext = intval($finalparams[self::$opt_gallery_autonext]);
2716 $gallery_options->thumbplay = intval($finalparams[self::$opt_gallery_thumbplay]);
2717 $gallery_options->apiKey = self::$alloptions[self::$opt_apikey];
2718
2719 $galleryid = 'epyt_gallery_' . rand(10000, 99999);
2720 $galleryid_ifm_data = ' data-epytgalleryid="' . $galleryid . '" ';
2721
2722 $subbutton = '';
2723 if (isset($finalparams[self::$opt_gallery_channelsub]) && $finalparams[self::$opt_gallery_channelsub] == 1)
2724 {
2725 $subbutton = '<div class="epyt-gallery-subscribe"><a target="_blank" class="epyt-gallery-subbutton" href="' .
2726 esc_url(self::$alloptions[self::$opt_gallery_channelsublink]) . '?sub_confirmation=1"><img alt="subscribe" src="' . plugins_url('images/play-subscribe.png', __FILE__) . '" />' .
2727 htmlspecialchars(self::$alloptions[self::$opt_gallery_channelsubtext], ENT_QUOTES, 'UTF-8') . '</a></div>';
2728 }
2729
2730 $gallery_page_obj = self::get_gallery_page($gallery_options);
2731
2732 $galleryWrapper1 = '<div class="epyt-gallery" data-currpage="1" id="' . $galleryid . '">';
2733 $galleryWrapper2 = '</div>';
2734 $galleryCode = $subbutton . '<div class="epyt-gallery-list">' . $gallery_page_obj->html . '</div>';
2735 $videoidoutput = isset($gallery_page_obj->init_id) ? $gallery_page_obj->init_id : '';
2736 }
2737
2738 if (!empty($voloutput) && isset($finalparams['autoplay']) && $finalparams['autoplay'] == 1)
2739 {
2740 $voloutput .= ' data-epautoplay="1" ';
2741 $finalparams['autoplay'] = 0;
2742 }
2743
2744 if (!empty($relstop) && isset($finalparams['rel']) && intval($finalparams['rel']) === -1)
2745 {
2746 $finalparams['rel'] = 0;
2747 }
2748
2749 if (!empty($finalparams['live_stream']))
2750 {
2751 $videoidoutput = 'live_stream';
2752 }
2753
2754 $begin_responsive = '';
2755 $end_responsive = '';
2756 $dim_attrs = ' width="' . self::$defaultwidth . '" height="' . self::$defaultheight . '" ';
2757 if ($finalparams[self::$opt_responsive] == 1)
2758 {
2759 $begin_responsive = '<div class="epyt-video-wrapper">';
2760 $end_responsive = '</div>';
2761 }
2762
2763 $begin_gb_wrapper = '';
2764 $end_gb_wrapper = '';
2765 if ($iscontent && !$isoverride && $finalparams[self::$opt_gb_compat] == 1 && current_theme_supports('responsive-embeds'))// self::using_gutenberg())
2766 {
2767 // don't do the following if: overriding default YT, is widget
2768 $begin_gb_wrapper = '<figure class="wp-block-embed wp-block-embed-youtube is-type-video is-provider-youtube epyt-figure"><div class="wp-block-embed__wrapper">';
2769 //wp-block-embed-youtube is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio
2770 $end_gb_wrapper = '</div></figure>';
2771 }
2772 $iframe_id = rand(10000, 99999);
2773
2774 $code1 = $begin_gb_wrapper . $begin_responsive;
2775 $code_iframe1 = $code_iframe2 = '';
2776 if ($videoidoutput != 'live_stream' && $finalparams[self::$opt_facade_mode] == 1)
2777 {
2778 $facade_img_src = '';
2779 if (!empty($videoidoutput))
2780 {
2781 $facade_img_src = ' src="https://i.ytimg.com/vi/' . $videoidoutput . ($finalparams[self::$opt_maxres_facade] == 'eager' ? '/maxresdefault.jpg' : '/hqdefault.jpg') . '" ';
2782 }
2783 else if (isset($finalparams['list']))
2784 {
2785 $facade_img_src = ' data-facadeoembed="playlist?list=' . $finalparams['list'] . '" ';
2786 }
2787 $acctitle = str_replace('title="', 'alt="', $acctitle);
2788 $facade_autoplay = $finalparams[self::$opt_facade_autoplay] == 1 ? ' data-epautoplay="1" ' : '';
2789 $code_iframe1 = '<div ' . $centercode . ' id="_ytid_' . $iframe_id . '" ' . $dim_attrs . ' data-origwidth="' . self::$defaultwidth . '" data-origheight="' . self::$defaultheight . '" ' . $relstop .
2790 'data-facadesrc="https://www.' . $youtubebaseurl . '.com/embed/' . $videoidoutput . '?';
2791 $code_iframe2 = '" class="__youtube_prefs__ epyt-facade' . (!empty($finalparams['live_stream']) ? ' epyt-live-channel ' : '') . ($iscontent ? '' : ' __youtube_prefs_widget__ ') . ($isoverride ? ' epyt-is-override ' : '') . ' no-lazyload"' .
2792 $voloutput . $galleryid_ifm_data . $facade_autoplay . '><img data-spai-excluded="true" class="epyt-facade-poster skip-lazy" loading="lazy" ' . $acctitle . $facade_img_src . ' />' .
2793 '<button class="epyt-facade-play" aria-label="Play"><svg data-no-lazy="1" height="100%" version="1.1" viewBox="0 0 68 48" width="100%"><path class="ytp-large-play-button-bg" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f00"></path><path d="M 45,24 27,14 27,34" fill="#fff"></path></svg></button>' .
2794 '</div>';
2795 }
2796 else
2797 {
2798 $code_iframe1 = '<iframe ' . $centercode . ' id="_ytid_' . $iframe_id . '" ' . $dim_attrs . ' data-origwidth="' . self::$defaultwidth . '" data-origheight="' . self::$defaultheight . '" ' . $relstop .
2799 'src="https://www.' . $youtubebaseurl . '.com/embed/' . $videoidoutput . '?';
2800 $code_iframe2 = '" class="__youtube_prefs__ ' . (!empty($finalparams['live_stream']) ? ' epyt-live-channel ' : '') . ($iscontent ? '' : ' __youtube_prefs_widget__ ') . ($isoverride ? ' epyt-is-override ' : '') . ' no-lazyload"' .
2801 $voloutput . $acctitle . $galleryid_ifm_data . ' allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen data-no-lazy="1" data-skipgform_ajax_framebjll=""></iframe>';
2802 }
2803
2804 $code2 = $end_responsive . $end_gb_wrapper;
2805
2806 $code1 .= $code_iframe1;
2807 $code2 = $code_iframe2 . $code2;
2808
2809 $origin = '';
2810
2811 try
2812 {
2813 if (self::$alloptions[self::$opt_origin] == 1)
2814 {
2815 $url_parts = parse_url(site_url());
2816 $origin = 'origin=' . $url_parts['scheme'] . '://' . $url_parts['host'] . '&';
2817 }
2818 }
2819 catch (Exception $e)
2820 {
2821 $origin = '';
2822 }
2823 $finalsrc = (self::$alloptions[self::$opt_ytapi_load] == 'never' ? '' : 'enablejsapi=1&') . $origin;
2824
2825 if (count($finalparams) > 1)
2826 {
2827 foreach ($finalparams as $key => $value)
2828 {
2829 if (in_array($key, self::$yt_options))
2830 {
2831 if (!empty($galleryCode) && ($key == 'listType' || $key == 'list'))
2832 {
2833
2834 }
2835 else
2836 {
2837 if (!((isset($finalparams['live']) || isset($finalparams['live_stream'])) && $key == 'loop')) // don't add loop for channel streaming
2838 {
2839 $finalsrc .= htmlspecialchars($key, ENT_QUOTES, 'UTF-8') . '=' . htmlspecialchars($value, ENT_QUOTES, 'UTF-8') . '&';
2840 if ($key == 'loop' && $value == 1 && !isset($finalparams['list']))
2841 {
2842 $finalsrc .= 'playlist=' . $finalparams['v'] . '&';
2843 }
2844 }
2845 }
2846 }
2847 }
2848 }
2849
2850 if (self::gdpr_mode())
2851 {
2852 $code1 = '<div ' . $centercode . ' id="_ytid_' . rand(10000, 99999) . '"'; //'" width="' . self::$defaultwidth . '" height="' . self::$defaultheight . '" ';
2853 $code2 = ' class="__youtube_prefs__ __youtube_prefs_gdpr__ ' . ($iscontent ? '' : ' __youtube_prefs_widget__') . ($isoverride ? ' epyt-is-override ' : '') . '" allowfullscreen data-no-lazy="1" data-skipgform_ajax_framebjll="">' .
2854 apply_filters('ytprefs_filter_the_content_light', wp_kses_post(self::$alloptions[self::$opt_gdpr_consent_message])) .
2855 '<button type="button" class="__youtube_prefs_gdpr__">' . trim(sanitize_text_field(self::$alloptions[self::$opt_gdpr_consent_button])) .
2856 '<img src="' . plugins_url('images/icon-check.png', __FILE__) . '" alt="accept" data-no-lazy="1" data-skipgform_ajax_framebjll="" /></button>' .
2857 '</div>';
2858 $finalsrc = '';
2859 }
2860
2861 $code = $galleryWrapper1 . $code1 . $finalsrc . $code2 . $galleryCode . $galleryWrapper2;
2862 //. '<!--' . $m[0] . '-->';
2863 self::$defaultheight = null;
2864 self::$defaultwidth = null;
2865 self::$oembeddata = null;
2866
2867 return $code;
2868 }
2869
2870 public static function using_gutenberg()
2871 {
2872 global $wp_version;
2873 if ((version_compare($wp_version, '5.0', '>=') && !is_plugin_active('classic-editor/classic-editor.php')) || is_plugin_active('gutenberg/gutenberg.php'))
2874 {
2875 return true;
2876 }
2877 return false;
2878 }
2879
2880 public static function gdpr_mode()
2881 {
2882 return (bool) self::$alloptions[self::$opt_gdpr_consent] && filter_input(INPUT_COOKIE, self::$gdpr_cookie_name, FILTER_SANITIZE_NUMBER_INT) != 1;
2883 }
2884
2885 public static function filter_the_content_light($content)
2886 {
2887 //global $wp_filter;
2888 //$the_content_filters_current = $wp_filter['the_content']->callbacks;
2889
2890 for ($i = 0; $i < count(self::$the_content_filters); $i++)
2891 {
2892 if (function_exists(self::$the_content_filters[$i]) && !(self::wp_above_version('5.5') && self::$the_content_filters[$i] === 'wp_make_content_images_responsive'))
2893 {
2894 $content = call_user_func(self::$the_content_filters[$i], $content);
2895 }
2896 }
2897 return $content;
2898 }
2899
2900 public static function debuglog($str)
2901 {
2902 $handle = fopen(__DIR__ . "\\debug.txt", "a+");
2903 fwrite($handle, $str);
2904 fclose($handle);
2905 }
2906
2907 public static function keyvalue($qry, $includev)
2908 {
2909 $ytvars = explode('&', $qry);
2910 $ytkvp = array();
2911 foreach ($ytvars as $k => $v)
2912 {
2913 $kvp = explode('=', $v);
2914 if (count($kvp) == 2 && ($includev || strtolower($kvp[0]) != 'v'))
2915 {
2916 $ytkvp[$kvp[0]] = $kvp[1];
2917 }
2918 }
2919
2920 return $ytkvp;
2921 }
2922
2923 public static function secondsToDuration($seconds)
2924 {
2925 $remaining = $seconds;
2926 $parts = array();
2927 $multipliers = array(
2928 'hours' => 3600,
2929 'minutes' => 60,
2930 'seconds' => 1
2931 );
2932
2933 foreach ($multipliers as $type => $m)
2934 {
2935 $parts[$type] = (int) ($remaining / $m);
2936 $remaining -= ($parts[$type] * $m);
2937 }
2938
2939 return $parts;
2940 }
2941
2942 public static function formatDuration($parts)
2943 {
2944 $default = array(
2945 'hours' => 0,
2946 'minutes' => 0,
2947 'seconds' => 0
2948 );
2949
2950 extract(array_merge($default, $parts));
2951
2952 return "T{$hours}H{$minutes}M{$seconds}S";
2953 }
2954
2955 public static function init_dimensions($url, $urlkvp, $finalparams)
2956 {
2957 // get default dimensions; try embed size in settings, then try theme's content width, then just 480px
2958 if (self::$defaultwidth == null)
2959 {
2960 global $content_width;
2961 if (empty($content_width))
2962 {
2963 $content_width = $GLOBALS['content_width'];
2964 }
2965
2966 if (isset($urlkvp['width']) && is_numeric($urlkvp['width']))
2967 {
2968 self::$defaultwidth = $urlkvp['width'];
2969 }
2970 else if (self::$alloptions[self::$opt_defaultdims] == 1 && (isset(self::$alloptions[self::$opt_defaultwidth]) && is_numeric(self::$alloptions[self::$opt_defaultwidth])))
2971 {
2972 self::$defaultwidth = self::$alloptions[self::$opt_defaultwidth];
2973 }
2974 else if (self::$optembedwidth)
2975 {
2976 self::$defaultwidth = self::$optembedwidth;
2977 }
2978 else if ($content_width)
2979 {
2980 self::$defaultwidth = $content_width;
2981 }
2982 else
2983 {
2984 self::$defaultwidth = 480;
2985 }
2986
2987
2988
2989 if (isset($urlkvp['height']) && is_numeric($urlkvp['height']))
2990 {
2991 self::$defaultheight = $urlkvp['height'];
2992 }
2993 else if (self::$alloptions[self::$opt_defaultdims] == 1 && (isset(self::$alloptions[self::$opt_defaultheight]) && is_numeric(self::$alloptions[self::$opt_defaultheight])))
2994 {
2995 self::$defaultheight = self::$alloptions[self::$opt_defaultheight];
2996 }
2997 else
2998 {
2999 self::$defaultheight = self::get_aspect_height($url, self::$defaultwidth);
3000 }
3001 }
3002 }
3003
3004 public static function get_oembed($url, $height, $width)
3005 {
3006 if (stripos($url, 'listType=playlist') !== false && stripos($url, '/embed') !== false)
3007 {
3008 $url = str_replace('/embed', '/playlist', $url);
3009 }
3010 if (file_exists(ABSPATH . WPINC . '/class-wp-oembed.php'))
3011 {
3012 require_once(ABSPATH . WPINC . '/class-wp-oembed.php');
3013 }
3014 else
3015 {
3016 require_once(ABSPATH . WPINC . '/class-oembed.php');
3017 }
3018 $oembed = _wp_oembed_get_object();
3019 $args = array();
3020 $args['width'] = $width;
3021 $args['height'] = $height;
3022 $args['discover'] = false;
3023 self::$oembeddata = $oembed->fetch('https://www.youtube.com/oembed', $url, $args);
3024 return self::$oembeddata;
3025 }
3026
3027 public static function get_aspect_height($url, $widthbox)
3028 {
3029 // attempt to get aspect ratio correct height from oEmbed
3030 $aspectheight = round(($widthbox * 9) / 16, 0);
3031
3032 if ($url)
3033 {
3034 $odata = self::get_oembed($url, $widthbox, $widthbox);
3035
3036 if ($odata)
3037 {
3038 $aspectheight = $odata->height;
3039 }
3040 }
3041
3042 return $aspectheight;
3043 }
3044
3045 public static function ytprefs_plugin_menu()
3046 {
3047 self::$admin_page_hooks[] = add_menu_page('EmbedPlus for YouTube Settings', 'EmbedPlus for YouTube', 'manage_options', 'youtube-my-preferences', array(self::class, 'ytprefs_show_options'), 'dashicons-video-alt3', '10.000392854349');
3048 self::$admin_page_hooks[] = add_submenu_page('youtube-my-preferences', '', '', 'manage_options', 'youtube-my-preferences', array(self::class, 'ytprefs_show_options'));
3049
3050 self::$admin_page_hooks[] = add_submenu_page('youtube-my-preferences_nomenu', 'YouTube Posts', 'YouTube Posts', 'manage_options', 'youtube-ep-glance', array(self::class, 'glance_page'));
3051 self::$admin_page_hooks[] = self::$wizard_hook = add_submenu_page('youtube-my-preferences_nomenu', 'EmbedPlus for YouTube Wizard', 'Wizard', 'edit_posts', 'youtube-ep-wizard', array(self::class, 'wizard'));
3052 self::$admin_page_hooks[] = self::$onboarding_hook = add_submenu_page('youtube-my-preferences_nomenu', 'EmbedPlus for YouTube Setup', 'Setup', 'manage_options', 'youtube-ep-onboarding', array(self::class, 'ytprefs_show_onboarding'));
3053 }
3054
3055 public static function custom_admin_pointers_check()
3056 {
3057 if (!self::$alloptions[self::$opt_show_pointer])
3058 {
3059 return false;
3060 }
3061 $admin_pointers = self::custom_admin_pointers();
3062 foreach ($admin_pointers as $pointer => $array)
3063 {
3064 if ($array['active'])
3065 {
3066 return true;
3067 }
3068 }
3069 }
3070
3071 public static function glance_script()
3072 {
3073 add_thickbox();
3074 ?>
3075 <script type="text/javascript">
3076 function widen_ytprefs_glance()
3077 {
3078 setTimeout(function ()
3079 {
3080 jQuery("#TB_window").animate({marginLeft: '-' + parseInt((780 / 2), 10) + 'px', width: '780px'}, 300);
3081 jQuery("#TB_window iframe").animate({width: '780px'}, 300);
3082 }, 15);
3083 }
3084
3085 (function ($j)
3086 {
3087 $j(document).ready(function ()
3088 {
3089
3090 $j.ajax({
3091 type: "post",
3092 dataType: "json",
3093 timeout: 30000,
3094 url: window._EPYTA_ ? window._EPYTA_.wpajaxurl : ajaxurl,
3095 data: {action: 'my_embedplus_glance_count'},
3096 success: function (response)
3097 {
3098 if (response.type === "success")
3099 {
3100 $j(response.container).append(response.data);
3101 $j(".ytprefs_glance_button").on('click', widen_ytprefs_glance);
3102 $j(window).on('resize', widen_ytprefs_glance);
3103 if (typeof ep_do_pointers === 'function')
3104 {
3105 //ep_do_pointers($j);
3106 }
3107 }
3108 else
3109 {
3110 }
3111 },
3112 error: function (xhr, ajaxOptions, thrownError)
3113 {
3114
3115 },
3116 complete: function ()
3117 {
3118 }
3119 });
3120 });
3121 })(jQuery);</script>
3122 <?php
3123 }
3124
3125 public static function custom_admin_pointers_footer()
3126 {
3127 $admin_pointers = self::custom_admin_pointers();
3128 ?>
3129 <script type="text/javascript">
3130 /* <![CDATA[ */
3131 function ep_do_pointers($)
3132 {
3133 <?php
3134 foreach ($admin_pointers as $pointer => $array)
3135 {
3136 if ($array['active'])
3137 {
3138 ?>
3139 $('<?php echo $array['anchor_id']; ?>').pointer({
3140 pointerClass: 'wp-pointer ytprefs-pointer',
3141 content: '<?php echo $array['content']; ?>',
3142 position: {
3143 edge: '<?php echo $array['edge']; ?>',
3144 align: '<?php echo $array['align']; ?>'
3145 },
3146 close: function ()
3147 {
3148 $.post(window._EPYTA_ ? window._EPYTA_.wpajaxurl : ajaxurl, {
3149 pointer: '<?php echo $pointer; ?>',
3150 action: 'dismiss-wp-pointer'
3151 });
3152 }
3153 }).pointer('open');
3154 <?php
3155 }
3156 }
3157 ?>
3158 }
3159
3160 ep_do_pointers(jQuery); // switch off all pointers via js ooopointer
3161 /* ]]> */
3162 </script>
3163 <?php
3164 }
3165
3166 public static function custom_admin_pointers()
3167 {
3168 $dismissed = explode(',', (string) get_user_meta(get_current_user_id(), 'dismissed_wp_pointers', true));
3169 $version = str_replace('.', '_', self::$version); // replace all periods in version with an underscore
3170 $prefix = 'custom_admin_pointers' . $version . '_';
3171
3172 $new_pointer_content = '<h3>' . __('New Update') . '</h3>'; // ooopointer
3173
3174 $new_pointer_content .= '<p>'; // ooopointer
3175 $new_pointer_content .= 'This version improves compatibility with WordPress 7.1 for both free and <a target=_blank href="' . self::$epbase . '/dashboard/pro-easy-video-analytics.aspx?ref=frompointer">Pro</a> plugins, and optimizes the caching feature for the Pro plugin.';
3176 if (!empty(self::$alloptions[self::$opt_pro]) && strlen(trim(self::$alloptions[self::$opt_pro])) > 0)
3177 {
3178 $new_pointer_content .= ' <strong>Important message to Pro users</strong>: From version 11.7 onward, you must <a href="https://www.embedplus.com/youtube-pro/download/?prokey=' . esc_attr(self::$alloptions[self::$opt_pro]) . '" target="_blank">download the separate plugin here</a> to regain your Pro features. All your settings will automatically migrate after installing the separate Pro download. Thank you for your support and patience during this transition.';
3179 }
3180
3181 $new_pointer_content .= '</p>';
3182
3183 return array(
3184 $prefix . 'new_items' => array(
3185 'content' => $new_pointer_content,
3186 'anchor_id' => 'a.toplevel_page_youtube-my-preferences', //'#ytprefs_glance_button',
3187 'edge' => 'top',
3188 'align' => 'left',
3189 'active' => (!in_array($prefix . 'new_items', $dismissed))
3190 ),
3191 );
3192 }
3193
3194 public static function postchecked($idx)
3195 {
3196 return isset($_POST[$idx]) && $_POST[$idx] == (true || 'on');
3197 }
3198
3199 public static function settings_nav()
3200 {
3201 ?>
3202
3203 <h3 class="nav-tab-wrapper">
3204 <a class="nav-tab nav-tab-active" href="#jumpdefaults">Defaults</a>
3205 <a class="nav-tab" href="#jumpapikey">API Key</a>
3206 <a class="nav-tab" href="#jumpwiz">Wizard</a>
3207 <a class="nav-tab" href="#jumpgallery">Galleries</a>
3208 <a class="nav-tab href-link" style="background-color: #daebf1;" target="_blank" href="<?php echo self::$epbase . "/dashboard/pro-easy-video-analytics.aspx?ref=protab" ?>">Upgrade?</a>
3209 <a class="nav-tab" href="#jumpperformance">Performance</a>
3210 <a class="nav-tab" href="#jumpcompat">Compatibility</a>
3211 <a class="nav-tab" href="#jumpprivacy">Security & Privacy</a>
3212 <a class="nav-tab" href="#jumphowto">Embed Manually</a>
3213 <a class="nav-tab" href="#jumpsupport">Support</a>
3214 </h3>
3215 <?php
3216 }
3217
3218 public static function ytprefs_show_options()
3219 {
3220 if (!current_user_can('manage_options'))
3221 {
3222 wp_die(__('You do not have sufficient permissions to access this page.'));
3223 }
3224
3225 if (self::$double_plugin)
3226 {
3227 self::double_plugin_warning();
3228 }
3229
3230 $ytprefs_submitted = 'ytprefs_submitted';
3231
3232 // Read in existing option values from database
3233
3234 $all = get_option(self::$opt_alloptions);
3235
3236 // See if the user has posted us some information
3237 // If they did, this hidden field will be set to 'Y'
3238 if (isset($_POST[$ytprefs_submitted]) && $_POST[$ytprefs_submitted] == 'Y' && check_admin_referer('_epyt_save', '_epyt_nonce'))
3239 {
3240 $result = self::settings_save($all);
3241 $all = get_option(self::$opt_alloptions);
3242 ?>
3243 <div class="updated"><p><strong><?php echo wp_kses_post($result['message']) ?></strong></p></div>
3244 <?php
3245 }
3246 ?>
3247
3248 <style type="text/css">
3249 .wrap {font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",Arial,sans-serif; color: #000000;}
3250 .wrap-ytprefs {max-width: 1064px;}
3251 h1 span {vertical-align: middle;}
3252 #ytform p, #ytform .p { line-height: 20px; margin: 18px 0; }
3253 .ytindent {padding: 0px 0px 0px 20px; font-size: 13px; margin-bottom: 100px;}
3254 .ytindent ul, .ytindent p {font-size: 13px;}
3255 .shadow {-webkit-box-shadow: 0px 0px 20px 0px #000000; box-shadow: 0px 0px 20px 0px #000000;}
3256 .gopro {margin: 0px;}
3257 .gopro img {vertical-align: middle;
3258 width: 19px;
3259 height: 19px;
3260 padding-bottom: 4px;}
3261 .gopro li {margin-bottom: 0px;}
3262 .orange {color: #f85d00;}
3263 .bold {font-weight: bold;}
3264 .grey{color: #888888;}
3265 #goprobox {border-radius: 15px; padding: 10px 15px 15px 15px; border: 3px solid #CCE5EC; position: relative;}
3266 .pronon {font-weight: bold; color: #f85d00;}
3267 ul.reglist li {margin-left: 30px; list-style: disc outside none;}
3268 .procol {width: 475px; float: left;}
3269 .ytindent .procol ul {font-size: 12px;}
3270 .smallnote, .ytindent .smallnote {font-style: italic; font-size: 11px;}
3271 .italic {font-style: italic;}
3272 .ytindent h3 {font-size: 16px; line-height: 22px; margin: 5px 0px 10px 0px;}
3273 #wizleftlink {float: left; display: block; width: 240px; font-style: italic; text-align: center; text-decoration: none;}
3274 .button-primary {white-space: nowrap;}
3275 p.submit {margin: 10px 0 0 0; padding: 10px 0 5px 0;}
3276 .wp-core-ui p.submit .button-primary {
3277 font-weight: bold;
3278 font-size: 21px; min-height: 50px; padding: 0 20px 1px;
3279 }
3280 .wp-core-ui p.submit .button-primary[disabled] {
3281 opacity: .4;
3282 transition: opacity ease-in-out .3s;
3283 }
3284 .wp-core-ui p.submit .button-primary[disabled]:after {
3285 content: url(<?php echo admin_url('images/wpspin_light.gif') ?>);
3286 padding-left: 3px;
3287 }
3288 p.submit em {display: inline-block; padding-left: 20px; vertical-align: middle; width: 240px; margin-top: -6px;}
3289 #opt_pro {box-shadow: 0px 0px 5px 0px #1870D5; width: 320px;vertical-align: top;}
3290 #goprobox h3 {font-size: 14px;}
3291 .chx {border-left: 5px solid rgba(100, 100, 100,.1); margin-bottom: 20px;}
3292 .chx p {margin: 0px 0px 5px 0px;}
3293 .cuz {background-image: linear-gradient(to bottom,#4983FF,#0C5597) !important; color: #ffffff;}
3294 .brightpro {background-image: linear-gradient(to bottom,#ff5500,#cc2200) !important; color: #ffffff;}
3295 #boxdefaultdims {font-weight: bold; padding: 0px 10px; <?php echo $all[self::$opt_defaultdims] ? '' : 'display: none;' ?>}
3296 #boxcustomarrows {font-weight: bold; padding: 0px 10px; <?php echo $all[self::$opt_gallery_customarrows] ? 'display: block;' : 'display: none;' ?>}
3297 #boxchannelsub {font-weight: bold; padding: 0px 10px; <?php echo $all[self::$opt_gallery_channelsub] ? 'display: block;' : 'display: none;' ?>}
3298 #box_collapse_grid {font-weight: bold; padding: 0px 10px; <?php echo isset($all[self::$opt_gallery_collapse_grid]) && $all[self::$opt_gallery_collapse_grid] ? 'display: block;' : 'display: none;' ?>}
3299 #box_restrict_wizard {padding: 0px 10px; <?php echo isset($all[self::$opt_restrict_wizard]) && $all[self::$opt_restrict_wizard] ? 'display: block;' : 'display: none;' ?>}
3300 #box_restrict_wizard label {display: block; margin: 5px 10px;}
3301 .textinput {border-width: 2px !important;}
3302 input[type=text]::placeholder {font-weight: normal;}
3303 h3.sect {border-radius: 10px; background-color: #D9E9F7; padding: 5px 5px 5px 10px; position: relative; font-weight: bold;}
3304 h3.sect a {text-decoration: none; color: #E20000;}
3305 h3.sect a.button-primary {color: #ffffff;}
3306 h4.sect {border-radius: 10px; background-color: #D9E9F7; padding: 5px 5px 5px 10px; position: relative; font-weight: bold;}
3307
3308 .nav-tab-wrapper sup {line-height: 0;}
3309 .ytnav {margin-bottom: 15px;}
3310 .ytnav a {font-weight: bold; display: inline-block; padding: 5px 10px; margin: 0px 15px 0px 0px; border: 1px solid #cccccc; border-radius: 6px;
3311 text-decoration: none; background-color: #ffffff;}
3312 .ytnav a:last-child {margin-right: 0;}
3313 .jumper {height: 25px;}
3314 .ssschema {float: right; width: 350px; height: auto; margin-right: 10px;}
3315 .ssfb {float: right; height: auto; margin-right: 10px; margin-left: 15px; margin-bottom: 10px;}
3316 .totop {position: absolute; right: 20px; top: 5px; color: #444444; font-size: 11px;}
3317 input[type=checkbox] {border: 1px solid #000000;}
3318 .chktitle {display: inline-block; padding: 1px 5px 1px 5px; border-radius: 3px; background-color: #ffffff; border: 1px solid #dddddd;}
3319 b, strong {font-weight: bold;}
3320 input.checkbox[disabled], input[type=radio][disabled] {border: 1px dashed #444444;}
3321 .pad10 {padding: 10px;}
3322 #boxdohl {font-weight: bold; padding: 0px 10px; <?php echo $all[self::$opt_dohl] ? '' : 'display: none;' ?>}
3323 #boxdefaultvol {font-weight: bold; padding: 0px 10px; <?php echo $all[self::$opt_defaultvol] ? '' : 'display: none;' ?>}
3324 .vol-output {display: none; width: 30px; color: #008800;}
3325 .vol-range {background-color: #dddddd; border-radius: 3px; cursor: pointer;}
3326 input#vol {vertical-align: middle;}
3327 .vol-seeslider {display: none;}
3328 .indent-option {margin-left: 25px;}
3329 #boxmigratelist { <?php echo $all[self::$opt_migrate] ? '' : 'display: none;' ?>}
3330 #boxresponsive_all { <?php echo $all[self::$opt_responsive] ? '' : 'display: none;' ?> padding-left: 25px; border-left: 5px solid rgba(100, 100, 100,.1); margin-left: 5px;}
3331 .apikey-video{margin-left: 3%; display: inline-block; width: 50%; position: relative; padding-top: 29%}
3332 .apikey-video iframe{display: block; width: 100%; height: 100%; position: absolute; top: 0; left: 0;}
3333 #boxnocookie {display: inline-block; border-radius: 3px; padding: 2px 4px 2px 4px; color: red; <?php echo $all[self::$opt_nocookie] ? '' : 'display: none;' ?>}
3334 #boxapinever {display: none; color: red;}
3335 input[type="radio"]:checked ~ #boxapinever {display: block;}
3336 #box_facade_mode { color: red; <?php echo (bool) $all[self::$opt_facade_mode] ? 'display: block;' : 'display: none;' ?>}
3337 #box_gdpr_consent { color: red; <?php echo (bool) $all[self::$opt_gdpr_consent] ? 'display: block;' : 'display: none;' ?>}
3338 .strike {text-decoration: line-through;}
3339 .upgchecks { padding: 20px; border: 1px dotted #777777; background-color: #fcfcfc; }
3340 .clearboth {clear: both;}
3341 div.hr {clear: both; border-bottom: 1px dotted #A8BDD8; margin: 20px 0 20px 0;}
3342 .wp-pointer-buttons a.close {margin-top: 0 !important;}
3343 .pad20{padding: 20px 0 20px 0;}
3344 .ssgallery {float: right; width: 130px; height: auto; margin-left: 15px; border: 3px solid #ffffff;}
3345 .sssubscribe{display: block; width: 400px; height: auto;}
3346 .ssaltgallery {float: right; height: auto; margin-right: 10px; margin-left: 15px; margin-bottom: 10px; width: 350px;}
3347 .sspopupplayer {float: right; height: auto; margin-right: 10px; margin-left: 15px; margin-bottom: 10px; width: 350px;}
3348 .sshidethumbimg {float: right; height: auto; margin-right: 10px; margin-left: 40px; margin-bottom: 10px; width: 315px;}
3349 .sswizardbutton { max-width: 70%; height: auto;}
3350 .save-changes-follow {position: fixed; z-index: 10000; bottom: 0; right: 0; background-color: #ffffff; padding: 0 20px; border-top-left-radius: 20px; border: 2px solid #aaaaaa; border-right-width: 0; border-bottom-width: 0;
3351 -webkit-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.75);
3352 -moz-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.75);
3353 box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.75); }
3354 .alertify .ajs-body .ajs-content {line-height: 2.5em;}
3355 #jumpmonetize h2:first-child {margin-bottom: 0;}
3356
3357 .wrap-ytprefs h2.nav-tab-wrapper {
3358 margin:22px 0 0 0;
3359 }
3360
3361 .wrap-ytprefs h3 .nav-tab {
3362 padding: 5px 10px;
3363 }
3364
3365 .wrap-ytprefs section {
3366 display:none;
3367 padding-top:15px;
3368 }
3369 .wrap-ytprefs section#jumpdefaults {
3370 display:block;
3371 }
3372 .wrap-ytprefs .no-js section {
3373 display: block;
3374 }
3375
3376 .gdpr-options-left {
3377 width: 65%;
3378 float: left;
3379 clear: left;
3380 }
3381
3382 .gdpr-options-right {
3383 width: 33%;
3384 float: right;
3385 margin-top: 20px;
3386 }
3387
3388 .gdpr-options-right .img-gdpr-message {
3389 width: 100%;
3390 height: auto;
3391 }
3392
3393 iframe#gdpr_consent_message_ifr {
3394 min-height: 250px !important;
3395 }
3396
3397 section#jumpwiz hr {
3398 margin: 20px 0 20px 0;
3399 }
3400 .wiztab-screenshots {
3401 float: right;
3402 max-width: 50%;
3403 height: auto;
3404 clear: right;
3405 margin-left: 30px;
3406 margin-bottom: 15px;
3407 display: block;
3408 border: 5px solid #dddddd;
3409 }
3410
3411 .epyt-deprecated {
3412 color: #aaaaaa;
3413 }
3414
3415 input[type="checkbox"] + label .check-note {
3416 display: none;
3417 }
3418
3419 input[type="checkbox"]:checked + label .check-note {
3420 display: inline;
3421 }
3422
3423 .not-live-content {
3424 opacity: .3;
3425 }
3426
3427 #not_live_on:checked ~ .not-live-content, #not_live_on_channel:checked ~ .not-live-content {
3428 opacity: 1;
3429 }
3430
3431 #facade_mode ~ .box_facade_mode {
3432 opacity: .3;
3433 }
3434
3435 #facade_mode:checked ~ .box_facade_mode {
3436 opacity: 1;
3437 }
3438
3439 #defer_js ~ .box_defer_jquery {
3440 opacity: .3;
3441 }
3442
3443 #defer_js:checked ~ .box_defer_jquery {
3444 opacity: 1;
3445 }
3446
3447 .epyt-fitvid {
3448 width: 100%;
3449 padding-top: 56.25%;
3450 position: relative;
3451 }
3452
3453 .epyt-fitvid iframe {
3454 position: absolute;
3455 top: 0;
3456 left:0;
3457 right: 0;
3458 bottom: 0;
3459 width: 100%;
3460 height: 100%;
3461 }
3462
3463 .wiztab-pagebuilder {
3464 width: 50%;
3465 float: left;
3466 padding: 20px;
3467 box-sizing: border-box;
3468 }
3469
3470 </style>
3471 <div class="wrap wrap-ytprefs">
3472 <h1><span class="dashicons-before dashicons-video-alt3"></span> <?php echo __('EmbedPlus for YouTube Settings') ?></h1>
3473 <?php
3474 self::settings_nav();
3475 ?>
3476
3477 <div class="ytindent">
3478 <form name="form1" method="post" action="" id="ytform">
3479 <input type="hidden" name="<?php echo $ytprefs_submitted; ?>" value="Y">
3480 <?php wp_nonce_field('_epyt_save', '_epyt_nonce', true); ?>
3481 <section class="pattern" id="jumpapikey">
3482 <h2>
3483 YouTube API Key
3484 </h2>
3485 <p>
3486 Some features (such as galleries, and some wizard features) now require you to create a free YouTube API key from Google.
3487 The instructions for this are very specific, so we created a video for you that's hopefully easy to follow: <a href="https://www.embedplus.com/how-to-create-a-youtube-api-key.aspx" target="_blank">Click this link</a> and follow the steps on the page. Then save your API key below.
3488 </p>
3489 <p>
3490 <b class="chktitle">YouTube API Key:</b>
3491 <input type="text" name="<?php echo self::$opt_apikey; ?>" id="<?php echo self::$opt_apikey; ?>" value="<?php echo esc_attr(trim($all[self::$opt_apikey])); ?>" class="textinput" style="width: 250px;">
3492 </p>
3493 </section>
3494
3495 <section class="pattern" id="jumpdefaults">
3496 <h2>
3497 <?php _e("Default YouTube Options") ?>
3498 </h2>
3499 <p>
3500 <?php _e("One of the benefits of using this plugin is that you can set site-wide default options for all your videos (click \"Save Changes\" when finished). However, you can also override them (and more) on a per-video basis. Directions on how to do that are in the next tab.") ?>
3501 </p>
3502
3503 <div class="ytindent chx">
3504 <p>
3505 <input name="<?php echo self::$opt_glance; ?>" id="<?php echo self::$opt_glance; ?>" <?php checked($all[self::$opt_glance], 1); ?> type="checkbox" class="checkbox">
3506 <label for="<?php echo self::$opt_glance; ?>"><?php _e('<b class="chktitle">At a glance:</b> Show "At a Glance" Embed Links on the dashboard homepage.') ?></label>
3507 </p>
3508 <p>
3509 <input name="<?php echo self::$opt_center; ?>" id="<?php echo self::$opt_center; ?>" <?php checked($all[self::$opt_center], 1); ?> type="checkbox" class="checkbox">
3510 <label for="<?php echo self::$opt_center; ?>"><?php _e('<b class="chktitle">Centering:</b> Automatically center all your videos (not necessary if all your videos span the whole width of your blog).') ?></label>
3511 </p>
3512 <p>
3513 <input name="<?php echo self::$opt_autoplay; ?>" id="<?php echo self::$opt_autoplay; ?>" <?php checked($all[self::$opt_autoplay], 1); ?> type="checkbox" class="checkbox">
3514 <label for="<?php echo self::$opt_autoplay; ?>">
3515 <?php _e('<b class="chktitle">Autoplay:</b> Automatically start playing your videos.') ?>
3516 <strong>Note:</strong> If you're embedding videos from your own monetized YouTube channel, we advise you to read YouTube's resource page on ads on embedded videos:
3517 <a href="https://support.google.com/youtube/answer/132596?hl=en" target="_blank">https://support.google.com/youtube/answer/132596?hl=en</a>
3518 You'll see that videos that you want to monetize "should be embedded using the standard click-to-play embed and NOT a scripted play."
3519 Unchecking this option guarantees standard click-to-play gallery embedding.
3520 (Another Note: Desktop browsers like <a href="https://developers.google.com/youtube/iframe_api_reference#Mobile_considerations" target="_blank">Chrome and Safari are moving towards preventing autoplay for any video</a>. But, your chances are improved if you set your videos to initially start muted.)
3521 </label>
3522 </p>
3523 <p>
3524 <input name="<?php echo self::$opt_iv_load_policy; ?>" id="<?php echo self::$opt_iv_load_policy; ?>" <?php checked($all[self::$opt_iv_load_policy], 1); ?> type="checkbox" class="checkbox">
3525 <label for="<?php echo self::$opt_iv_load_policy; ?>"><?php _e('<b class="chktitle">Annotations:</b> Show annotations by default.') ?></label>
3526 </p>
3527 <p>
3528 <input name="<?php echo self::$opt_loop; ?>" id="<?php echo self::$opt_loop; ?>" <?php checked($all[self::$opt_loop], 1); ?> type="checkbox" class="checkbox">
3529 <label for="<?php echo self::$opt_loop; ?>"><?php _e('<b class="chktitle">Looping:</b> Loop all your videos. Note: this feature is incompatible with the "hide related videos" feature.') ?></label>
3530 </p>
3531 <p>
3532 <label>
3533 <b class="chktitle">Related Videos:</b>
3534 Show or hide related and recommended videos at the end of playback.
3535 <br>
3536 </label>
3537 <input type="radio" name="<?php echo self::$opt_rel; ?>" id="<?php echo self::$opt_rel; ?>-1" value="-1" <?php checked($all[self::$opt_rel], -1); ?>>
3538 <label for="<?php echo self::$opt_rel; ?>-1">Hide related videos at the end of playback</label> &nbsp;&nbsp;
3539 <input type="radio" name="<?php echo self::$opt_rel; ?>" id="<?php echo self::$opt_rel; ?>0" value="0" <?php checked($all[self::$opt_rel], 0); ?>>
3540 <label for="<?php echo self::$opt_rel; ?>0">Show related videos only from the video's channel</label> &nbsp;&nbsp;
3541 <input type="radio" name="<?php echo self::$opt_rel; ?>" id="<?php echo self::$opt_rel; ?>1" value="1" <?php checked($all[self::$opt_rel], 1); ?>>
3542 <label for="<?php echo self::$opt_rel; ?>1">Show related videos</label> &nbsp;&nbsp;
3543 </p>
3544 <p>
3545 <input name="<?php echo self::$opt_fs; ?>" id="<?php echo self::$opt_fs; ?>" <?php checked($all[self::$opt_fs], 1); ?> type="checkbox" class="checkbox">
3546 <label for="<?php echo self::$opt_fs; ?>"><?php _e('<b class="chktitle">Show Fullscreen Button:</b> Show the fullscreen button.') ?></label>
3547 </p>
3548 <p>
3549 <input name="<?php echo self::$opt_acctitle; ?>" id="<?php echo self::$opt_acctitle; ?>" <?php checked($all[self::$opt_acctitle], 1); ?> type="checkbox" class="checkbox">
3550 <label for="<?php echo self::$opt_acctitle; ?>"><b class="chktitle">Accessible Title Attributes: </b> Improve accessibility by using title attributes for screen reader support. It should help your site pass functional accessibility evaluations (FAE). </label>
3551 </p>
3552 <p>
3553 <input name="<?php echo self::$opt_color; ?>" id="<?php echo self::$opt_color; ?>" <?php checked($all[self::$opt_color], 'red'); ?> type="checkbox" class="checkbox">
3554 <label for="<?php echo self::$opt_color; ?>"><?php _e('<b class="chktitle">Red Progress Bar:</b> Use the red progress bar (uncheck to use a white progress bar).') ?></label>
3555 </p>
3556 <p>
3557 <input name="<?php echo self::$opt_defaultdims; ?>" id="<?php echo self::$opt_defaultdims; ?>" <?php checked($all[self::$opt_defaultdims], 1); ?> type="checkbox" class="checkbox">
3558 <span id="boxdefaultdims">
3559 Width: <input type="number" min="200" name="<?php echo self::$opt_defaultwidth; ?>" id="<?php echo self::$opt_defaultwidth; ?>" value="<?php echo esc_attr(trim($all[self::$opt_defaultwidth])); ?>" class="textinput" style="width: 75px;"> &nbsp;
3560 Height: <input type="number" min="200" name="<?php echo self::$opt_defaultheight; ?>" id="<?php echo self::$opt_defaultheight; ?>" value="<?php echo esc_attr(trim($all[self::$opt_defaultheight])); ?>" class="textinput" style="width: 75px;">
3561 </span>
3562
3563 <label for="<?php echo self::$opt_defaultdims; ?>"><?php _e('<b class="chktitle">Default Dimensions:</b> Make your videos have a default size, for better loading performance and consistency. Recommended: 800 x 450 (NOTE: If responsive sizing is also turned on, your videos will be responsive but also keep this aspect ratio.). Also, according to YouTube guidelines, the player must be a minimum of 200 x 200 (or recommended 480 x 270 for 16:9 ratio players) in order to display correctly.') ?></label>
3564 </p>
3565 <p>
3566 <input name="<?php echo self::$opt_responsive; ?>" id="<?php echo self::$opt_responsive; ?>" <?php checked($all[self::$opt_responsive], 1); ?> type="checkbox" class="checkbox">
3567 <label for="<?php echo self::$opt_responsive; ?>"><?php _e('<b class="chktitle">Responsive Video Sizing:</b> Make your videos responsive so that they dynamically fit in all screen sizes (smart phone, PC and tablet). NOTE: While this is checked, any custom hardcoded widths and heights you may have set will dynamically change too. <b>Uncheck this if your theme already properly handles responsive video sizing.</b>') ?></label>
3568 <div id="boxresponsive_all">
3569 <input type="radio" name="<?php echo self::$opt_responsive_all; ?>" id="<?php echo self::$opt_responsive_all; ?>1" value="1" <?php checked($all[self::$opt_responsive_all], 1); ?> >
3570 <label for="<?php echo self::$opt_responsive_all; ?>1">Responsive for all YouTube videos</label> &nbsp;&nbsp;
3571 <input type="radio" name="<?php echo self::$opt_responsive_all; ?>" id="<?php echo self::$opt_responsive_all; ?>0" value="0" <?php checked($all[self::$opt_responsive_all], 0); ?> >
3572 <label for="<?php echo self::$opt_responsive_all; ?>0">Responsive for only videos embedded via this plugin</label>
3573 </div>
3574 </p>
3575 <p>
3576 <input name="<?php echo self::$opt_widgetfit; ?>" id="<?php echo self::$opt_widgetfit; ?>" <?php checked($all[self::$opt_widgetfit], 1); ?> type="checkbox" class="checkbox">
3577 <label for="<?php echo self::$opt_widgetfit; ?>"><?php _e('<b class="chktitle">Autofit Widget Videos:</b> Make each video that you embed in a widget area automatically fit the width of its container.') ?></label>
3578 </p>
3579 <p>
3580 <input name="<?php echo self::$opt_playsinline; ?>" id="<?php echo self::$opt_playsinline; ?>" <?php checked($all[self::$opt_playsinline], 1); ?> type="checkbox" class="checkbox">
3581 <label for="<?php echo self::$opt_playsinline; ?>">
3582 <b class="chktitle">iOS Playback:</b> Check this to allow your embeds to play inline within your page when viewed on iOS (iPhone and iPad) browsers. Uncheck it to have iOS launch your embeds in fullscreen instead.
3583 <em>Disclaimer: YouTube/Google has issues with this iOS related parameter, but we are providing it here in the event that they support it consistently.</em>
3584 </label>
3585 </p>
3586 <p>
3587 <input name="<?php echo self::$opt_controls; ?>" id="<?php echo self::$opt_controls; ?>" <?php checked($all[self::$opt_controls], 1); ?> type="checkbox" class="checkbox">
3588 <label for="<?php echo self::$opt_controls; ?>"><b class="chktitle">Show Controls:</b> Show the player's control bar. Unchecking this option creates a cleaner look but limits what your viewers can control (play position, volume, etc.).</label>
3589 </p>
3590 <p>
3591 <input name="<?php echo self::$opt_disablekb; ?>" id="<?php echo self::$opt_disablekb; ?>" <?php checked($all[self::$opt_disablekb], 1); ?> type="checkbox" class="checkbox">
3592 <label for="<?php echo self::$opt_disablekb; ?>"><b class="chktitle">Disable Keyboard Controls:</b> Prevent users from using keyboard controls (spacebar to play/pause, arrow keys to seek, etc.).</label>
3593 </p>
3594 <p>
3595 <input name="<?php echo self::$opt_defaultvol; ?>" id="<?php echo self::$opt_defaultvol; ?>" <?php checked($all[self::$opt_defaultvol], 1); ?> type="checkbox" class="checkbox">
3596 <label for="<?php echo self::$opt_defaultvol; ?>">
3597 <b class="chktitle">Volume Initialization: </b>
3598 Set an initial volume level for all of your embedded videos. Check this and you'll see a <span class="vol-seeslider">slider</span> <span class="vol-seetextbox">textbox</span> for setting the start volume to a value between 0 (mute) and 100 (max) percent. Leaving it unchecked means you want the visitor's default behavior. This feature is experimental and is less predictable on a page with more than one embed. Read more about why you might want to <a href="<?php echo self::$epbase ?>/mute-volume-youtube-wordpress.aspx" target="_blank">initialize YouTube embed volume here &raquo;</a>
3599 </label>
3600 <span id="boxdefaultvol">
3601 Volume: <span class="vol-output"></span> <input min="0" max="100" step="1" type="text" name="<?php echo self::$opt_vol; ?>" id="<?php echo self::$opt_vol; ?>" value="<?php echo esc_attr(trim($all[self::$opt_vol])); ?>" >
3602 </span>
3603 </p>
3604
3605 <p>
3606 <input name="<?php echo self::$opt_pause_others; ?>" id="<?php echo self::$opt_pause_others; ?>" <?php checked($all[self::$opt_pause_others], 1); ?> type="checkbox" class="checkbox">
3607 <label for="<?php echo self::$opt_pause_others; ?>">
3608 <b class="chktitle"><?php _e('Simultaneous Playback Control:', 'youtube-embed-plus'); ?></b>
3609 <?php _e('You can enable/disable the ability for visitors to have separate videos running at the same time on the same page. Check this to automatically pause other players while the current player is playing. (Note: this feature is not guaranteed to work with videos embedded from other plugins).', 'youtube-embed-plus'); ?>
3610 </label>
3611 </p>
3612
3613 <p>
3614 <input name="<?php echo self::$opt_cc_load_policy; ?>" id="<?php echo self::$opt_cc_load_policy; ?>" <?php checked($all[self::$opt_cc_load_policy], 1); ?> type="checkbox" class="checkbox">
3615 <label for="<?php echo self::$opt_cc_load_policy; ?>"><?php _e('<b class="chktitle">Closed Captions:</b> Turn on closed captions by default.') ?></label>
3616 </p>
3617 <?php
3618 $lang_codes = [
3619 ["Abkhazian", "аҧсуа бызшәа, аҧсшәа", "ab", "abk", "abk"],
3620 ["Afar", "Afaraf", "aa", "aar", "aar"],
3621 ["Afrikaans", "Afrikaans", "af", "afr", "afr"],
3622 ["Akan", "Akan", "ak", "aka", "aka"],
3623 ["Albanian", "Shqip", "sq", "sqi", "alb"],
3624 ["Amharic", "አማርኛ", "am", "amh", "amh"],
3625 ["Arabic", "العربية", "ar", "ara", "ara"],
3626 ["Aragonese", "aragonés", "an", "arg", "arg"],
3627 ["Armenian", "Հայերեն", "hy", "hye", "arm"],
3628 ["Assamese", "�
3629 সমীয়া", "as", "asm", "asm"],
3630 ["Avaric", "авар мацӀ, магӀарул мацӀ", "av", "ava", "ava"],
3631 ["Avestan", "avesta", "ae", "ave", "ave"],
3632 ["Aymara", "aymar aru", "ay", "aym", "aym"],
3633 ["Azerbaijani", "azərbaycan dili", "az", "aze", "aze"],
3634 ["Bambara", "bamanankan", "bm", "bam", "bam"],
3635 ["Bashkir", "башҡорт теле", "ba", "bak", "bak"],
3636 ["Basque", "euskara, euskera", "eu", "eus", "baq"],
3637 ["Belarusian", "беларуская мова", "be", "bel", "bel"],
3638 ["Bengali", "বাংলা", "bn", "ben", "ben"],
3639 ["Bihari languages", "भोजपुरी", "bh", "bih", "bih"],
3640 ["Bislama", "Bislama", "bi", "bis", "bis"],
3641 ["Bosnian", "bosanski jezik", "bs", "bos", "bos"],
3642 ["Breton", "brezhoneg", "br", "bre", "bre"],
3643 ["Bulgarian", "български език", "bg", "bul", "bul"],
3644 ["Burmese", "ဗမာ�
3645 ာ", "my", "mya", "bur"],
3646 ["Catalan, Valencian", "català, valencià", "ca", "cat", "cat"],
3647 ["Chamorro", "Chamoru", "ch", "cha", "cha"],
3648 ["Chechen", "но�
3649 чийн мотт", "ce", "che", "che"],
3650 ["Chichewa, Chewa, Nyanja", "chiCheŵa, chinyanja", "ny", "nya", "nya"],
3651 ["Chinese", "中文 (Zhōngwén), 汉语, 漢語", "zh", "zho", "chi"],
3652 ["Chuvash", "чӑваш чӗл�
3653 и", "cv", "chv", "chv"],
3654 ["Cornish", "Kernewek", "kw", "cor", "cor"],
3655 ["Corsican", "corsu, lingua corsa", "co", "cos", "cos"],
3656 ["Cree", "ᓀᐦᐃᔭᐍᐏᐣ", "cr", "cre", "cre"],
3657 ["Croatian", "hrvatski jezik", "hr", "hrv", "hrv"],
3658 ["Czech", "čeština, český jazyk", "cs", "ces", "cze"],
3659 ["Danish", "dansk", "da", "dan", "dan"],
3660 ["Divehi, Dhivehi, Maldivian", "ދިވެހި", "dv", "div", "div"],
3661 ["Dutch, Flemish", "Nederlands, Vlaams", "nl", "nld", "dut"],
3662 ["Dzongkha", "རྫོང་ཁ", "dz", "dzo", "dzo"],
3663 ["English", "English", "en", "eng", "eng"],
3664 ["Esperanto", "Esperanto", "eo", "epo", "epo"],
3665 ["Estonian", "eesti, eesti keel", "et", "est", "est"],
3666 ["Ewe", "Eʋegbe", "ee", "ewe", "ewe"],
3667 ["Faroese", "føroyskt", "fo", "fao", "fao"],
3668 ["Fijian", "vosa Vakaviti", "fj", "fij", "fij"],
3669 ["Finnish", "suomi, suomen kieli", "fi", "fin", "fin"],
3670 ["French", "français, langue française", "fr", "fra", "fre"],
3671 ["Fulah", "Fulfulde, Pulaar, Pular", "ff", "ful", "ful"],
3672 ["Galician", "Galego", "gl", "glg", "glg"],
3673 ["Georgian", "ქართული", "ka", "kat", "geo"],
3674 ["German", "Deutsch", "de", "deu", "ger"],
3675 ["Greek, Modern (1453–)", "ελληνικά", "el", "ell", "gre"],
3676 ["Guarani", "Avañe'", "gn", "grn", "grn"],
3677 ["Gujarati", "ગુજરાતી", "gu", "guj", "guj"],
3678 ["Haitian, Haitian Creole", "Kreyòl ayisyen", "ht", "hat", "hat"],
3679 ["Hausa", "(Hausa) هَوُسَ", "ha", "hau", "hau"],
3680 ["Hebrew", "עברית", "he", "heb", "heb"],
3681 ["Herero", "Otjiherero", "hz", "her", "her"],
3682 ["Hindi", "हिन्दी, हिंदी", "hi", "hin", "hin"],
3683 ["Hiri Motu", "Hiri Motu", "ho", "hmo", "hmo"],
3684 ["Hungarian", "magyar", "hu", "hun", "hun"],
3685 ["Interlingua (International Auxiliary Language Association)", "Interlingua", "ia", "ina", "ina"],
3686 ["Indonesian", "Bahasa Indonesia", "id", "ind", "ind"],
3687 ["Interlingue, Occidental", "(originally:) Occidental, (after WWII:) Interlingue", "ie", "ile", "ile"],
3688 ["Irish", "Gaeilge", "ga", "gle", "gle"],
3689 ["Igbo", "Asụsụ Igbo", "ig", "ibo", "ibo"],
3690 ["Inupiaq", "Iñupiaq, Iñupiatun", "ik", "ipk", "ipk"],
3691 ["Ido", "Ido", "io", "ido", "ido"],
3692 ["Icelandic", "Íslenska", "is", "isl", "ice"],
3693 ["Italian", "Italiano", "it", "ita", "ita"],
3694 ["Inuktitut", "ᐃᓄᒃᑎᑐᑦ", "iu", "iku", "iku"],
3695 ["Japanese", "日本語 (にほんご)", "ja", "jpn", "jpn"],
3696 ["Javanese", "ꦧꦱꦗꦮ, Basa Jawa", "jv", "jav", "jav"],
3697 ["Kalaallisut, Greenlandic", "kalaallisut, kalaallit oqaasii", "kl", "kal", "kal"],
3698 ["Kannada", "ಕನ್ನಡ", "kn", "kan", "kan"],
3699 ["Kanuri", "Kanuri", "kr", "kau", "kau"],
3700 ["Kashmiri", "कश्मीरी, كش�
3701 يري‎", "ks", "kas", "kas"],
3702 ["Kazakh", "қазақ тілі", "kk", "kaz", "kaz"],
3703 ["Central Khmer", "ខ្មែរ, ខេមរភាសា, ភាសាខ្មែរ", "km", "khm", "khm"],
3704 ["Kikuyu, Gikuyu", "Gĩkũyũ", "ki", "kik", "kik"],
3705 ["Kinyarwanda", "Ikinyarwanda", "rw", "kin", "kin"],
3706 ["Kirghiz, Kyrgyz", "Кыргызча, Кыргыз тили", "ky", "kir", "kir"],
3707 ["Komi", "коми кыв", "kv", "kom", "kom"],
3708 ["Kongo", "Kikongo", "kg", "kon", "kon"],
3709 ["Korean", "한국어", "ko", "kor", "kor"],
3710 ["Kurdish", "Kurdî, کوردی‎", "ku", "kur", "kur"],
3711 ["Kuanyama, Kwanyama", "Kuanyama", "kj", "kua", "kua"],
3712 ["Latin", "latine, lingua latina", "la", "lat", "lat"],
3713 ["Luxembourgish, Letzeburgesch", "Lëtzebuergesch", "lb", "ltz", "ltz"],
3714 ["Ganda", "Luganda", "lg", "lug", "lug"],
3715 ["Limburgan, Limburger, Limburgish", "Limburgs", "li", "lim", "lim"],
3716 ["Lingala", "Lingála", "ln", "lin", "lin"],
3717 ["Lao", "ພາສາລາວ", "lo", "lao", "lao"],
3718 ["Lithuanian", "lietuvių kalba", "lt", "lit", "lit"],
3719 ["Luba-Katanga", "Kiluba", "lu", "lub", "lub"],
3720 ["Latvian", "latviešu valoda", "lv", "lav", "lav"],
3721 ["Manx", "Gaelg, Gailck", "gv", "glv", "glv"],
3722 ["Macedonian", "македонски јазик", "mk", "mkd", "mac"],
3723 ["Malagasy", "fiteny malagasy", "mg", "mlg", "mlg"],
3724 ["Malay", "Bahasa Melayu, بهاس �
3725 لايو‎", "ms", "msa", "may"],
3726 ["Malayalam", "മലയാളം", "ml", "mal", "mal"],
3727 ["Maltese", "Malti", "mt", "mlt", "mlt"],
3728 ["Maori", "te reo Māori", "mi", "mri", "mao"],
3729 ["Marathi", "मराठी", "mr", "mar", "mar"],
3730 ["Marshallese", "Kajin M̧ajeļ", "mh", "mah", "mah"],
3731 ["Mongolian", "Монгол �
3732 эл", "mn", "mon", "mon"],
3733 ["Nauru", "Dorerin Naoero", "na", "nau", "nau"],
3734 ["Navajo, Navaho", "Diné bizaad", "nv", "nav", "nav"],
3735 ["North Ndebele", "isiNdebele", "nd", "nde", "nde"],
3736 ["Nepali", "नेपाली", "ne", "nep", "nep"],
3737 ["Ndonga", "Owambo", "ng", "ndo", "ndo"],
3738 ["Norwegian Bokmål", "Norsk Bokmål", "nb", "nob", "nob"],
3739 ["Norwegian Nynorsk", "Norsk Nynorsk", "nn", "nno", "nno"],
3740 ["Norwegian", "Norsk", "no", "nor", "nor"],
3741 ["Sichuan Yi, Nuosu", "ꆈꌠ꒿ Nuosuhxop", "ii", "iii", "iii"],
3742 ["South Ndebele", "isiNdebele", "nr", "nbl", "nbl"],
3743 ["Occitan", "occitan, lenga d'òc", "oc", "oci", "oci"],
3744 ["Ojibwa", "ᐊᓂᔑᓈᐯᒧᐎᓐ", "oj", "oji", "oji"],
3745 ["Church Slavic, Old Slavonic, Church Slavonic, Old Bulgarian, Old Church Slavonic", "ѩзыкъ словѣньскъ", "cu", "chu", "chu"],
3746 ["Oromo", "Afaan Oromoo", "om", "orm", "orm"],
3747 ["Oriya", "ଓଡ଼ିଆ", "or", "ori", "ori"],
3748 ["Ossetian, Ossetic", "ирон æвзаг", "os", "oss", "oss"],
3749 ["Punjabi, Panjabi", "ਪੰਜਾਬੀ, پنجابی‎", "pa", "pan", "pan"],
3750 ["Pali", "पालि, पाळि", "pi", "pli", "pli"],
3751 ["Persian", "فارسی", "fa", "fas", "per"],
3752 ["Polish", "język polski, polszczyzna", "pl", "pol", "pol"],
3753 ["Pashto, Pushto", "پښتو", "ps", "pus", "pus"],
3754 ["Portuguese", "Português", "pt", "por", "por"],
3755 ["Quechua", "Runa Simi, Kichwa", "qu", "que", "que"],
3756 ["Romansh", "Rumantsch Grischun", "rm", "roh", "roh"],
3757 ["Rundi", "Ikirundi", "rn", "run", "run"],
3758 ["Romanian, Moldavian, Moldovan", "Română", "ro", "ron", "rum"],
3759 ["Russian", "русский", "ru", "rus", "rus"],
3760 ["Sanskrit", "संस्कृतम्", "sa", "san", "san"],
3761 ["Sardinian", "sardu", "sc", "srd", "srd"],
3762 ["Sindhi", "सिन्धी, سنڌي، سندھی‎", "sd", "snd", "snd"],
3763 ["Northern Sami", "Davvisámegiella", "se", "sme", "sme"],
3764 ["Samoan", "gagana fa'a Samoa", "sm", "smo", "smo"],
3765 ["Sango", "yângâ tî sängö", "sg", "sag", "sag"],
3766 ["Serbian", "српски језик", "sr", "srp", "srp"],
3767 ["Gaelic, Scottish Gaelic", "Gàidhlig", "gd", "gla", "gla"],
3768 ["Shona", "chiShona", "sn", "sna", "sna"],
3769 ["Sinhala, Sinhalese", "සිංහල", "si", "sin", "sin"],
3770 ["Slovak", "Slovenčina, Slovenský Jazyk", "sk", "slk", "slo"],
3771 ["Slovenian", "Slovenski Jezik, Slovenščina", "sl", "slv", "slv"],
3772 ["Somali", "Soomaaliga, af Soomaali", "so", "som", "som"],
3773 ["Southern Sotho", "Sesotho", "st", "sot", "sot"],
3774 ["Spanish, Castilian", "Español", "es", "spa", "spa"],
3775 ["Sundanese", "Basa Sunda", "su", "sun", "sun"],
3776 ["Swahili", "Kiswahili", "sw", "swa", "swa"],
3777 ["Swati", "SiSwati", "ss", "ssw", "ssw"],
3778 ["Swedish", "Svenska", "sv", "swe", "swe"],
3779 ["Tamil", "தமிழ்", "ta", "tam", "tam"],
3780 ["Telugu", "తెలుగు", "te", "tel", "tel"],
3781 ["Tajik", "тоҷикӣ, toçikī, تاجیکی‎", "tg", "tgk", "tgk"],
3782 ["Thai", "ไทย", "th", "tha", "tha"],
3783 ["Tigrinya", "ትግርኛ", "ti", "tir", "tir"],
3784 ["Tibetan", "བོད་ཡིག", "bo", "bod", "tib"],
3785 ["Turkmen", "Türkmen, Түркмен", "tk", "tuk", "tuk"],
3786 ["Tagalog", "Wikang Tagalog", "tl", "tgl", "tgl"],
3787 ["Tswana", "Setswana", "tn", "tsn", "tsn"],
3788 ["Tonga (Tonga Islands)", "Faka Tonga", "to", "ton", "ton"],
3789 ["Turkish", "Türkçe", "tr", "tur", "tur"],
3790 ["Tsonga", "Xitsonga", "ts", "tso", "tso"],
3791 ["Tatar", "татар теле, tatar tele", "tt", "tat", "tat"],
3792 ["Twi", "Twi", "tw", "twi", "twi"],
3793 ["Tahitian", "Reo Tahiti", "ty", "tah", "tah"],
3794 ["Uighur, Uyghur", "ئۇيغۇرچە‎, Uyghurche", "ug", "uig", "uig"],
3795 ["Ukrainian", "Українська", "uk", "ukr", "ukr"],
3796 ["Urdu", "اردو", "ur", "urd", "urd"],
3797 ["Uzbek", "Oʻzbek, Ўзбек, أۇزبېك‎", "uz", "uzb", "uzb"],
3798 ["Venda", "Tshivenḓa", "ve", "ven", "ven"],
3799 ["Vietnamese", "Tiếng Việt", "vi", "vie", "vie"],
3800 ["Volapük", "Volapük", "vo", "vol", "vol"],
3801 ["Walloon", "Walon", "wa", "wln", "wln"],
3802 ["Welsh", "Cymraeg", "cy", "cym", "wel"],
3803 ["Wolof", "Wollof", "wo", "wol", "wol"],
3804 ["Western Frisian", "Frysk", "fy", "fry", "fry"],
3805 ["Xhosa", "isiXhosa", "xh", "xho", "xho"],
3806 ["Yiddish", "ייִדיש", "yi", "yid", "yid"],
3807 ["Yoruba", "Yorùbá", "yo", "yor", "yor"],
3808 ["Zhuang, Chuang", "Saɯ cueŋ�
3809 , Saw cuengh", "za", "zha", "zha"],
3810 ["Zulu", "isiZulu", "zu", "zul", "zul"]
3811 ];
3812
3813 $selected_val = trim($all[self::$opt_cc_lang_pref]);
3814 ?>
3815 <p>
3816 <label for="<?php echo self::$opt_cc_lang_pref; ?>"><b class="chktitle">Closed Captions Language:</b></label>
3817 <select name="<?php echo self::$opt_cc_lang_pref; ?>" id="<?php echo self::$opt_cc_lang_pref; ?>" style="width: 260px;">
3818 <option <?php echo '' == $selected_val ? 'selected' : '' ?> value="">Default/Unspecified</option>
3819 <?php
3820 foreach ($lang_codes as $idx => $lang_row)
3821 {
3822 $iso_code = $lang_row[2];
3823 $iso_label = $lang_row[0] . ' - ' . $lang_row[1];
3824 ?>
3825 <option <?php echo $iso_code == $selected_val ? 'selected' : '' ?> value="<?php echo $iso_code ?>"><?php echo $iso_label ?></option>
3826 <?php
3827 }
3828 ?>
3829 </select>
3830 Select the preferred default language for closed captions (when available).
3831 </p>
3832 <p>
3833 <input name="<?php echo self::$opt_dohl; ?>" id="<?php echo self::$opt_dohl; ?>" <?php checked($all[self::$opt_dohl], 1); ?> type="checkbox" class="checkbox">
3834 <label for="<?php echo self::$opt_dohl; ?>"><b class="chktitle">Player Localization / Internationalization: </b>
3835 Automatically detect your site's default language (using get_locale) and set your YouTube embeds interface language so that it matches. Specifically, this will set the player's tooltips and caption track if your language is natively supported by YouTube. We suggest checking this if English is not your site's default language. <a href="<?php echo self::$epbase ?>/youtube-iso-639-1-language-codes.aspx" target="_blank">See here for more details &raquo;</a></label>
3836 </p>
3837 <p>
3838 <input name="<?php echo self::$opt_playlistorder; ?>" id="<?php echo self::$opt_playlistorder; ?>" <?php checked($all[self::$opt_playlistorder], 1); ?> type="checkbox" class="checkbox">
3839 <label for="<?php echo self::$opt_playlistorder; ?>">
3840 <b class="chktitle">Self-contained Playlist Ordering:</b>
3841 Note: This option does <strong class="orange">NOT</strong> apply to galleries. It applies only to these kinds of <em>self-contained playlists</em> (Example: <a target="_blank" href="https://www.youtube.com/watch?v=J50PlRZHH9I&t=3m20s">https://www.youtube.com/watch?v=J50PlRZHH9I&t=3m20s</a>).
3842 If you're trying to control the order of a <em>gallery</em> instead, then you must be the owner of the playlist, go to YouTube.com, and reorder it there. This plugin can only order a <em>gallery</em> the way the owner ordered the source playlist.
3843 Check this option if you just want your <em>self-contained playlists</em> to begin with the latest added video by default. (Unchecking this will force playlists to always start with your selected specific video, even if you add videos to the playlist later).
3844 </label>
3845 </p>
3846 <p>
3847 <input name="<?php echo self::$opt_onboarded; ?>" id="<?php echo self::$opt_onboarded; ?>" <?php checked($all[self::$opt_onboarded], 1); ?> type="checkbox" class="checkbox">
3848 <label for="<?php echo self::$opt_onboarded; ?>">
3849 <b class="chktitle">Hide Quick Setup Guide:</b>
3850 Check this to hide the installation setup wizard when this page loads.
3851 </label>
3852 </p>
3853 <p>
3854 <input name="<?php echo self::$opt_show_pointer; ?>" id="<?php echo self::$opt_show_pointer; ?>" <?php checked($all[self::$opt_show_pointer], 1); ?> type="checkbox" class="checkbox">
3855 <label for="<?php echo self::$opt_show_pointer; ?>">
3856 <b class="chktitle">Show New Feature Notice:</b>
3857 Show admin notice of new plugin features after updates.
3858 </label>
3859 </p>
3860 <div id="not_live_content_scroll" class="p">
3861 <p>
3862 <b class="chktitle">Use "Not Live" Fallback Content For Live Streams:</b> (<a href="<?php echo self::$epbase ?>/how-to-embed-a-youtube-livestream-in-wordpress.aspx" target="_blank">More info here</a>)
3863 This feature lets you display alternate content if your live stream is not currently active. This feature works for <strong>direct link</strong> live streams
3864 (more info about channel-based live streams below).
3865 </p>
3866 <div class="ytindent chx">
3867 <input name="<?php echo self::$opt_not_live_on; ?>" id="<?php echo self::$opt_not_live_on; ?>" <?php checked($all[self::$opt_not_live_on], 1); ?> type="checkbox" class="checkbox">
3868 <label for="<?php echo self::$opt_not_live_on; ?>"><span class="chktitle">Turn on for <b>direct link</b> live streams:</span>
3869 When your direct-link embed is not streaming live, the YouTube live player usually displays a countdown after the user clicks the play button.
3870 Instead of showing that player, you can display some "coming soon" content in that space for your visitors to see until your video begins to live stream.
3871 The plugin will automatically switch to your video's live stream once it's active. In the <em>"Not Live" Fallback Content</em> box below, enter what you would like to appear until then.
3872 You can even insert shortcodes from our plugin into the box below (shortcodes from other plugins may or may not work correctly).
3873 If you just want to show the standard countdown player that YouTube provides, don't use this feature.
3874 <strong>NOTE: Turning this on for direct-link live streams uses a significant amount of your YouTube API quota. We suggest unchecking it if your site has high traffic. If you chose to use this feature, do <u>not</u> put another live stream embed below.</strong>
3875 </label>
3876 <br>
3877 <br>
3878 <input disabled id="<?php echo self::$opt_not_live_on_channel; ?>" type="checkbox" class="checkbox">
3879 <label><span class="chktitle">Turn on for <b>channel</b> live streams: <sup class="orange">upgrade required</sup></span>
3880 Unfortunately, Google has recently removed their YouTube API feature that used to support channel-based live streams. It appears they won't change things back. However, you do have a couple of choices:
3881 <ol>
3882 <li>Use "Direct link" live streams, as explained above. The trade-off is that you will have to manually post and take down your future live streams every time they start and when they end, respectively.</li>
3883 <li>Or <a href="<?php echo self::$epbase ?>/dashboard/pro-easy-video-analytics.aspx" target="_blank">upgrade to Pro</a>, which has a solution that brings back all the "set it and forget it" features of channel-based embeds. We spent a significant amount of time developing a stable, long-term solution around YouTube's limitations, so we are releasing this effort exclusively to our Pro customers.</li>
3884 </ol>
3885 </label>
3886 <div class="p not-live-content">
3887 <p>
3888 <b>"Not Live" Fallback Content:</b>
3889 </p>
3890 <?php
3891 wp_editor(wp_kses_post($all[self::$opt_not_live_content]), self::$opt_not_live_content, array('textarea_rows' => 7));
3892 ?>
3893 </div>
3894 </div>
3895 </div>
3896 </div>
3897 </section>
3898 <section class="pattern" id="jumpprivacy">
3899 <h2>Security Options</h2>
3900 <p>
3901 <input name="<?php echo self::$opt_restrict_wizard; ?>" id="<?php echo self::$opt_restrict_wizard; ?>" <?php checked($all[self::$opt_restrict_wizard], 1); ?> type="checkbox" class="checkbox">
3902 <label for="<?php echo self::$opt_restrict_wizard; ?>">
3903 <b class="chktitle">Restrict Wizard Button:</b> Select which roles can use the EmbedPlus for YouTube wizard button. For example, you may wish to hide the button from contributors submitting content on the front end.
3904 </label>
3905 <br>
3906 <span id="box_restrict_wizard" class="chx">
3907 <?php
3908 foreach (self::$dft_roles as $idx => $role)
3909 {
3910 ?>
3911 <label>
3912 <input type="checkbox" name="<?php echo self::$opt_restrict_wizard_roles . '[]' ?>" value="<?php echo esc_attr($role) ?>" <?php echo in_array($role, $all[self::$opt_restrict_wizard_roles]) ? 'checked' : '' ?>>
3913 <?php echo esc_html(ucfirst($role)); ?>s
3914 </label>
3915 <?php
3916 }
3917 ?>
3918 </span>
3919 </p>
3920 <p>
3921 <input name="<?php echo self::$opt_origin; ?>" id="<?php echo self::$opt_origin; ?>" <?php checked($all[self::$opt_origin], 1); ?> type="checkbox" class="checkbox">
3922 <label for="<?php echo self::$opt_origin; ?>"><b class="chktitle">Extra Player Security: </b>
3923 Add site origin information with each embed code as an extra security measure. In YouTube's/Google's own words, checking this option "protects against malicious third-party JavaScript being injected into your page and hijacking control of your YouTube player." We especially recommend checking it as it adds higher security than the built-in YouTube embedding method that comes with the current version of WordPress (i.e. oembed).
3924 </label>
3925 </p>
3926
3927 <h2>Privacy Options</h2>
3928 <p>These options may help with privacy restrictions such as GDPR and the EU Cookie Law.</p>
3929 <div class="ytindent chx">
3930 <p>
3931 <b class="chktitle">YouTube API Loading:</b> Choose when to load the YouTube API. The "Restricted" or "Never" options will help with GDPR compliance:
3932 <ul class="indent-option">
3933 <li><label><input type="radio" name="<?php echo self::$opt_ytapi_load ?>" value="light" <?php checked($all[self::$opt_ytapi_load], 'light'); ?> /> <em>Restricted</em> - (Recommended) Only load the API on pages that have a YouTube video.</label></li>
3934 <li><label>
3935 <input type="radio" name="<?php echo self::$opt_ytapi_load ?>" value="never" <?php checked($all[self::$opt_ytapi_load], 'never'); ?> /> <em>Never</em> - Do not load the YouTube API. Note: The "Never" choice may break a few features such as Volume Initialization and Gallery Continuous/Auto Play.
3936 <div id="boxapinever">
3937 Note: Checking this option may break some features such as the ones listed below:
3938 <ul class="list-ul">
3939 <li>Galleries</li>
3940 <li>Hide related videos at the end of playback</li>
3941 <li>Volume initialization</li>
3942 <li>Simultaneous playback control</li>
3943 <li>Playing video on mobile devices</li>
3944 </ul>
3945 </div>
3946 </label></li>
3947 <li><label><input type="radio" name="<?php echo self::$opt_ytapi_load ?>" value="always" <?php checked($all[self::$opt_ytapi_load], 'always'); ?> /> <em>Always</em> - Load the API on all pages. In most cases, the "Always" choice is not necessary.</label></li>
3948 </ul>
3949 </p>
3950
3951
3952 <p>
3953 <input name="<?php echo self::$opt_gdpr_consent; ?>" id="<?php echo self::$opt_gdpr_consent; ?>" <?php checked($all[self::$opt_gdpr_consent], 1); ?> type="checkbox" class="checkbox">
3954 <label for="<?php echo self::$opt_gdpr_consent; ?>">
3955 <b class="chktitle">Privacy/GDPR - Show Consent Message:</b> Ask for consent before loading YouTube content. A message will be displayed in place of the YouTube video, as shown in the screenshot below. Once the visitor approves consent, the YouTube content will load. You can customize the message text and the button text in the next 2 options.
3956 See this feature demonstrated in <a href="https://www.youtube.com/watch?v=lm_HIic6obw" target="_blank">this video</a>.
3957 </label>
3958 <span id="box_gdpr_consent">
3959 Note: If your visitors click a red accept button but your site doesn't reveal the video, you probably have a caching plugin. There should be a setting in your caching plugin to prevent caching the consent cookie. The name of the consent cookie is: <code>ytprefs_gdpr_consent</code>
3960 </span>
3961 </p>
3962
3963 <p>
3964 <label for="<?php echo self::$opt_gdpr_consent_message; ?>">
3965 <b class="chktitle">Privacy/GDPR - Consent Message Text:</b>
3966 Below you can customize the message that will appear to visitors before they accept YouTube content:
3967 </label>
3968 <div class="clearboth"></div>
3969 <div class="gdpr-options-left">
3970 <?php
3971 wp_editor(wp_kses_post($all[self::$opt_gdpr_consent_message]), self::$opt_gdpr_consent_message, array(
3972 'textarea_rows' => 22,
3973 'media_buttons' => false,
3974 'teeny' => true
3975 ));
3976 ?>
3977 </div>
3978 <div class="gdpr-options-right">
3979 <p><em>Example of message and button:</em></p>
3980
3981 <img src="<?php echo plugins_url('images/ss-gdpr-message.png', __FILE__) ?>" alt="GDPR Consent Message Example" class="img-gdpr-message" />
3982 </div>
3983
3984 </p>
3985 <div class="clearboth"></div>
3986 <p>
3987 <label for="<?php echo self::$opt_gdpr_consent_button; ?>">
3988 <b class="chktitle">Privacy/GDPR - Consent Button Text:</b>
3989 This is the text for the red "Accept" button that appears with the above privacy/GDPR message:
3990 </label>
3991 <br>
3992 <input type="text" placeholder="Example: Accept YouTube Content" name="<?php echo self::$opt_gdpr_consent_button; ?>" id="<?php echo self::$opt_gdpr_consent_button; ?>" value="<?php echo esc_attr(trim($all[self::$opt_gdpr_consent_button])); ?>" class="textinput regular-text"/>
3993 </p>
3994
3995 <p>
3996 <input name="<?php echo self::$opt_nocookie; ?>" id="<?php echo self::$opt_nocookie; ?>" <?php checked($all[self::$opt_nocookie], 1); ?> type="checkbox" class="checkbox">
3997 <label for="<?php echo self::$opt_nocookie; ?>">
3998 <b class="chktitle">No Cookies:</b> Prevent YouTube from leaving tracking cookies on your visitors browsers unless they actual play the videos. This is coded to apply this behavior on links in your past post as well.
3999 <div id="boxnocookie">
4000 Note: Checking this option may introduce issues to features that depend YouTube's API, such as the ones listed below. We suggest testing them out to make sure you are still pleased with the results:
4001 <ul class="list-ul">
4002 <li>Galleries</li>
4003 <li>Hide related videos at the end of playback</li>
4004 <li>Volume initialization</li>
4005 <li>Simultaneous playback control</li>
4006 <li>Playing video on mobile devices</li>
4007 </ul>
4008 </div>
4009 </label>
4010 </p>
4011 </div>
4012 </section>
4013
4014 <section class="pattern" id="jumpwiz">
4015 <h2>Visual YouTube Wizard Directions</h2>
4016 <p>
4017 While you're writing your post or page, you have the ability to search YouTube and insert videos, playlists, and even galleries right from your editor. Below are directions for each type of WordPress editor.
4018 For <strong>pagebuilder instructions</strong>, scroll down to the "Pagebuilder Tips" section.
4019 </p>
4020 <h3>Classic Editor</h3>
4021 <img class="wiztab-screenshots" src="<?php echo plugins_url('images/ss-wiz-classic.png', __FILE__) ?>">
4022 <p>
4023 Simply click the EmbedPlus for YouTube wizard button found above
4024 your post editor to start the wizard (see image to the right to locate this button). There, you'll have several options for different types of embeds.
4025 Each embed code will have an "Insert Into Editor" button that you can click to directly embed the desired video link to your post without having to copy and paste.
4026 </p>
4027 <hr class="clearboth">
4028 <h3>Widgets</h3>
4029 <img class="wiztab-screenshots" src="<?php echo plugins_url('images/ss-wiz-widget.png', __FILE__) ?>">
4030 <p>
4031 To insert a video in a widget area, use the Text widget that comes with WordPress. Simply click the EmbedPlus for YouTube wizard button found above
4032 the widget textbox to start the wizard (see image to the right to locate this button). There, you'll have several options for different types of embeds.
4033 Each embed code will have an "Insert Into Editor" button that you can click to directly embed the desired video link to your post without having to copy and paste.
4034 </p>
4035 <hr class="clearboth"/>
4036 <h3>Gutenberg Block Editor</h3>
4037 <img class="wiztab-screenshots" src="<?php echo plugins_url('images/ss-wiz-gbblock.png', __FILE__) ?>">
4038 <p>
4039 Click on the (+) sign for the block editor list. The EmbedPlus for YouTube Wizard block is located under the "Embeds" category (make sure you choose "YouTube <strong>Wizard</strong>" not "YouTube").
4040 Then your page will show a placeholder where you can launch the wizard. In the wizard, you'll have several options for different types of embeds.
4041 Each embed code will have an "Insert Into Editor" button that you can click to directly embed the desired video link to your post without having to copy and paste.
4042 You'll also be able to preview and interact with your embed without having to view the page on the front end.
4043 </p>
4044 <hr class="clearboth"/>
4045 <h3>Gutenberg Classic Block</h3>
4046 <img class="wiztab-screenshots" src="<?php echo plugins_url('images/ss-wiz-gbclassicblock.png', __FILE__) ?>">
4047 <p>
4048 Are you using Gutenberg but not quite ready to start using all the blocks? Well, you can still access our wizard if you wish to continue using Gutenberg's Classic block.
4049 The Classic block brings back the former editor you used before WordPress, and so we've added a button to it you can use to launch the wizard (see example on the right).
4050 Simply click the wizard button to start the wizard. There, you'll have several options for different types of embeds.
4051 Each embed code will have an "Insert Into Editor" button that you can click to directly embed the desired video link to your post without having to copy and paste.
4052 </p>
4053 <hr class="clearboth"/>
4054 <h3>Pro Customization</h3>
4055 <img class="wiztab-screenshots" src="<?php echo plugins_url('images/ssprowizard.png', __FILE__) ?>">
4056 <p>
4057 <a href="<?php echo self::$epbase ?>/dashboard/pro-easy-video-analytics.aspx?ref=wizdirections" target="_blank"><b>Even more options are available to PRO users, no matter which editor you choose!</b></a>
4058 Simply click the "Customize" button in the wizard to further personalize each of your embeds without having to manually add special codes yourself.
4059 The customize button will allow you to easily override most of the above default options for that embed.
4060 </p>
4061 <hr class="clearboth"/>
4062 <h2 id="jumppagebuilder">Pagebuilder Tips</h2>
4063 <p>
4064 Most page builders have a text widget in which our plugin's wizard can be launched. Watch the videos below for some popular ones, namely Elementor, Beaver Builder, and SiteOrigin.
4065 </p>
4066 <p>
4067 <em>Note: Please do not check the "Also Defer jQuery" option if you use a pagebuilder. Some pagebuilders cannot work if jQuery is deferred.</em>
4068 </p>
4069 <div class="wiztab-pagebuilder">
4070 <h3>Beaver Builder</h3>
4071 <div class="epyt-fitvid">
4072 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/bPgz0jyt7TE?rel=0" allowfullscreen="" frameborder="0"></iframe>
4073 </div>
4074 </div>
4075 <div class="wiztab-pagebuilder">
4076 <h3>Elementor</h3>
4077 <div class="epyt-fitvid">
4078 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/ldNfIGRTxDU?rel=0" allowfullscreen="" frameborder="0"></iframe>
4079 </div>
4080 </div>
4081 <div class="wiztab-pagebuilder">
4082 <h3>Site Origin</h3>
4083 <div class="epyt-fitvid">
4084 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/7QNYw_g-7WM?rel=0" allowfullscreen="" frameborder="0"></iframe>
4085 </div>
4086 </div>
4087 <div class="wiztab-pagebuilder">
4088 <h3>Visual Composer</h3>
4089 <div class="epyt-fitvid">
4090 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/FWBQc9XhAqM?rel=0" allowfullscreen="" frameborder="0"></iframe>
4091 </div>
4092 </div>
4093 <div class="wiztab-pagebuilder">
4094 <h3>WPBakery</h3>
4095 <div class="epyt-fitvid">
4096 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/7T5wPoEujN8?rel=0" allowfullscreen="" frameborder="0"></iframe>
4097 </div>
4098 </div>
4099 <div class="wiztab-pagebuilder">
4100 <p>
4101 If you don't see your page builder listed above, don't worry. For pretty much any page builder with a short code widget, you can also embed your video, gallery, live stream, or premiere by creating the short code using the plugin's wizard and then embedding the code in the short code widget or text widget of your page builder of choice.
4102 </p>
4103 </div>
4104 </section>
4105
4106 <section class="pattern" id="jumpgallery">
4107 <h2>Gallery Settings and Directions</h2>
4108 <img class="ssgallery" src="<?php echo plugins_url('images/ssgallery.png', __FILE__) ?>">
4109 <p>
4110 <a target="_blank" href="<?php echo self::$epbase ?>/responsive-youtube-playlist-channel-gallery-for-wordpress.aspx">You can now make playlist embeds (and channel-playlist embeds) have a gallery layout &raquo;</a>. <strong>First, you must obtain your YouTube API key</strong>.
4111 Don't worry, it's an easy process. Just <a href="https://www.youtube.com/watch?v=ZCfrNvu6nMc" target="_blank">click this link &raquo;</a> and follow the video on that page to get your server API key. Since Google updates their API Key generation directions frequently, follow the general steps shown in the video.
4112 Then paste your API key in the "API Key" tab, and click the "Save Changes" button.
4113 </p>
4114
4115 <p>
4116 Below are the global settings for galleries. If you want each of your galleries to have custom settings, <a href="<?php echo self::$epbase ?>/dashboard/pro-easy-video-analytics.aspx?ref=galleryglobal" target="_blank">go PRO</a> for more options:
4117 </p>
4118 <div class="ytindent chx">
4119
4120 <p>
4121 <label for="<?php echo self::$opt_gallery_pagesize; ?>"><b class="chktitle">Gallery Page Size:</b></label>
4122 <select name="<?php echo self::$opt_gallery_pagesize; ?>" id="<?php echo self::$opt_gallery_pagesize; ?>" style="width: 60px;">
4123 <?php
4124 $gps_val = intval(trim($all[self::$opt_gallery_pagesize]));
4125 $gps_val = min($gps_val, 50);
4126 for ($gps = 1; $gps <= 50; $gps++)
4127 {
4128 ?><option <?php echo $gps_val == $gps ? 'selected' : '' ?> value="<?php echo $gps ?>"><?php echo $gps ?></option>
4129 <?php
4130 }
4131 ?>
4132 </select>
4133 Enter how many thumbnails per page should be shown at once (YouTube allows a maximum of 50 per page).
4134 </p>
4135 <p>
4136 <label for="<?php echo self::$opt_gallery_columns; ?>"><b class="chktitle">Number of Columns:</b></label>
4137 <input name="<?php echo self::$opt_gallery_columns; ?>" min="1" id="<?php echo self::$opt_gallery_columns; ?>" type="number" class="textinput" style="width: 60px;" value="<?php echo esc_attr(trim($all[self::$opt_gallery_columns])); ?>">
4138 Enter how many thumbnails can fit per row.
4139 </p>
4140 <p>
4141 <input name="<?php echo self::$opt_gallery_collapse_grid; ?>" id="<?php echo self::$opt_gallery_collapse_grid; ?>" <?php checked($all[self::$opt_gallery_collapse_grid], 1); ?> type="checkbox" class="checkbox">
4142 <label for="<?php echo self::$opt_gallery_collapse_grid; ?>">
4143 <b class="chktitle">Stack Thumbnails for Mobile:</b> Check this option to responsively stack thumbnails on smaller screens, for the grid layout.
4144 </label>
4145 <span id="box_collapse_grid">
4146 <?php
4147 foreach ($all[self::$opt_gallery_collapse_grid_breaks] as $idx => $bpts)
4148 {
4149 ?>
4150 On screens up to
4151 <input type="number" name="<?php echo self::$opt_gallery_collapse_grid_breaks . '[' . $idx . '][bp][max]'; ?>"
4152 id="<?php echo self::$opt_gallery_collapse_grid_breaks . '[' . $idx . '][bp][max]'; ?>"
4153 value="<?php echo intval(trim($bpts['bp']['max'])); ?>" class="textinput" style="width: 70px;">px wide, stack thumbnails to 1 column.
4154 <input type="hidden" name="<?php echo self::$opt_gallery_collapse_grid_breaks . '[' . $idx . '][cols]'; ?>"
4155 id="<?php echo self::$opt_gallery_collapse_grid_breaks . '[' . $idx . '][cols]'; ?>"
4156 value="<?php echo intval(trim($bpts['cols'])); ?>">
4157 <input type="hidden" name="<?php echo self::$opt_gallery_collapse_grid_breaks . '[' . $idx . '][bp][min]'; ?>"
4158 id="<?php echo self::$opt_gallery_collapse_grid_breaks . '[' . $idx . '][bp][min]'; ?>"
4159 value="<?php echo intval(trim($bpts['bp']['min'])); ?>">
4160 <?php
4161 }
4162 ?>
4163 <span class="smallnote grey pad20"><br>Note: a common mobile screen width is 767 pixels.</span>
4164 </span>
4165 </p>
4166 <p>
4167 <input name="<?php echo self::$opt_gallery_showpaging; ?>" id="<?php echo self::$opt_gallery_showpaging; ?>" <?php checked($all[self::$opt_gallery_showpaging], 1); ?> type="checkbox" class="checkbox">
4168 <label for="<?php echo self::$opt_gallery_showpaging; ?>"><b class="chktitle">Show Pagination:</b> Show the Next/Previous buttons and page numbering.
4169 It might be useful to hide pagination if you want your gallery to display just a subset of videos from a playlist or channel. That is, only the first page of videos (defined by your page size) will be visible to your visitors if these buttons are hidden.
4170 </label>
4171 </p>
4172 <p>
4173 <input name="<?php echo self::$opt_gallery_customarrows; ?>" id="<?php echo self::$opt_gallery_customarrows; ?>" <?php checked($all[self::$opt_gallery_customarrows], 1); ?> type="checkbox" class="checkbox">
4174 <label for="<?php echo self::$opt_gallery_customarrows; ?>">
4175 <b class="chktitle">Custom Next/Previous Text:</b> If you want your gallery viewers to see something besides "Next" and "Prev" when browsing through thumbnails, enter your replacement text here. This feature can be quite useful for non-English sites. For example, a French site might replace Prev with Pr&eacute;c&eacute;dent and Next with Suivant.
4176 </label>
4177 <span id="boxcustomarrows">
4178 Previous Page: <input type="text" name="<?php echo self::$opt_gallery_customprev; ?>" id="<?php echo self::$opt_gallery_customprev; ?>" value="<?php echo esc_attr(trim($all[self::$opt_gallery_customprev])); ?>" class="textinput" style="width: 100px;"> &nbsp;
4179 Next Page: <input type="text" name="<?php echo self::$opt_gallery_customnext; ?>" id="<?php echo self::$opt_gallery_customnext; ?>" value="<?php echo esc_attr(trim($all[self::$opt_gallery_customnext])); ?>" class="textinput" style="width: 100px;">
4180 </span>
4181 </p>
4182 <p>
4183 <input name="<?php echo self::$opt_gallery_channelsub; ?>" id="<?php echo self::$opt_gallery_channelsub; ?>" <?php checked($all[self::$opt_gallery_channelsub], 1); ?> type="checkbox" class="checkbox">
4184 <label for="<?php echo self::$opt_gallery_channelsub; ?>">
4185 <b class="chktitle">Show Subscribe Button: </b> Are you the channel owner for all your galleries? Check this box to add a "Subscribe" button to all your galleries as shown below. This might help you convert your site's visitors to YouTube subscribers of your channel.
4186 </label>
4187 <span id="boxchannelsub">
4188 Paste Channel URL: <input type="text" placeholder="Example: https://www.youtube.com/user/YourChannel" name="<?php echo self::$opt_gallery_channelsublink; ?>" id="<?php echo self::$opt_gallery_channelsublink; ?>" value="<?php echo esc_url(trim($all[self::$opt_gallery_channelsublink])); ?>" class="textinput regular-text"> &nbsp;
4189 Button text: <input type="text" name="<?php echo self::$opt_gallery_channelsubtext; ?>" id="<?php echo self::$opt_gallery_channelsubtext; ?>" value="<?php echo esc_attr(trim($all[self::$opt_gallery_channelsubtext])); ?>" class="textinput" style="width: 200px;">
4190 </span>
4191 </p>
4192 <p><img class="sssubscribe" src="<?php echo plugins_url('images/sssubscribe.png', __FILE__) ?>"></p>
4193
4194 <p>
4195 <label for="<?php echo self::$opt_gallery_scrolloffset; ?>"><b class="chktitle">Scroll Offset:</b></label>
4196 <input name="<?php echo self::$opt_gallery_scrolloffset; ?>" id="<?php echo self::$opt_gallery_scrolloffset; ?>" type="number" class="textinput" style="width: 60px;" value="<?php echo esc_attr(trim($all[self::$opt_gallery_scrolloffset])); ?>">
4197 After you click on a thumbnail, the gallery will automatically smooth scroll up to the actual player. If you need it to scroll a few pixels further, increase this number.
4198 </p>
4199 <p>
4200 <input name="<?php echo self::$opt_gallery_showtitle; ?>" id="<?php echo self::$opt_gallery_showtitle; ?>" <?php checked($all[self::$opt_gallery_showtitle], 1); ?> type="checkbox" class="checkbox">
4201 <label for="<?php echo self::$opt_gallery_showtitle; ?>"><b class="chktitle">Show Thumbnail Title:</b> Show titles with each thumbnail.</label>
4202 </p>
4203 <p>
4204 <input name="<?php echo self::$opt_gallery_hideprivate; ?>" id="<?php echo self::$opt_gallery_hideprivate; ?>" <?php checked($all[self::$opt_gallery_hideprivate], 1); ?> type="checkbox" class="checkbox">
4205 <label for="<?php echo self::$opt_gallery_hideprivate; ?>"><b class="chktitle">Hide Private Thumbnails:</b> Hide thumbnails for videos in a playlist that cannot be embedded yet. Note: This may make some page sizes look uneven.</label>
4206 </p>
4207 <p>
4208 <input name="<?php echo self::$opt_gallery_autonext; ?>" id="<?php echo self::$opt_gallery_autonext; ?>" <?php checked($all[self::$opt_gallery_autonext], 1); ?> type="checkbox" class="checkbox">
4209 <label for="<?php echo self::$opt_gallery_autonext; ?>"><b class="chktitle">Automatic Continuous Play:</b> Automatically play the next video in the gallery as soon as the current video finished.
4210 <strong>Note:</strong> If you're embedding videos from your own monetized YouTube channel, we advise you to read YouTube's resource page on ads on embedded videos:
4211 <a href="https://support.google.com/youtube/answer/132596?hl=en" target="_blank">https://support.google.com/youtube/answer/132596?hl=en</a>
4212 You'll see that videos that you want to monetize "should be embedded using the standard click-to-play embed and NOT a scripted play."
4213 Unchecking this option guarantees standard click-to-play gallery embedding.
4214 </label>
4215 </p>
4216 <p>
4217 <input name="<?php echo self::$opt_gallery_thumbplay; ?>" id="<?php echo self::$opt_gallery_thumbplay; ?>" <?php checked($all[self::$opt_gallery_thumbplay], 1); ?> type="checkbox" class="checkbox">
4218 <label for="<?php echo self::$opt_gallery_thumbplay; ?>"><b class="chktitle">Thumbnail Click Plays Video:</b>
4219 Clicking on a gallery thumbnail autoplays the video. Uncheck this and visitors must also click the video's play button after clicking the thumbnail
4220 (uncheck this option for standard click-to-play gallery embedding).
4221 </label>
4222 </p>
4223 <div class="pad20">
4224 <p>
4225 Ready to get started with an actual gallery? Just click the plugin wizard button and pick your desired gallery embedding choice.
4226 </p>
4227 <p><img class="sswizardbutton" src="<?php echo plugins_url('images/sswizardbutton.jpg', __FILE__) ?>"></p>
4228 </div>
4229 </div>
4230 </section>
4231
4232 <section class="pattern" id="jumpcompat">
4233 <h2>Compatibility Settings</h2>
4234 <p>
4235 With tens of thousands of active users, our plugin may not work with every plugin out there. Below are some settings you may wish to try out.
4236 </p>
4237 <div class="ytindent chx">
4238 <p>
4239 <input name="<?php echo self::$opt_ajax_save; ?>" id="<?php echo self::$opt_ajax_save; ?>" <?php checked($all[self::$opt_ajax_save], 1); ?> type="checkbox" class="checkbox">
4240 <label for="<?php echo self::$opt_ajax_save; ?>">
4241 <b class="chktitle">Save Settings with AJAX: </b>
4242 Turn this option off if you are having trouble saving your settings.
4243 </label>
4244 </p>
4245 <p>
4246 <input name="<?php echo self::$opt_gb_compat; ?>" id="<?php echo self::$opt_gb_compat; ?>" <?php checked($all[self::$opt_gb_compat], 1); ?> type="checkbox" class="checkbox">
4247 <label for="<?php echo self::$opt_gb_compat; ?>">
4248 <b class="chktitle">Gutenberg Block Editor Theme Spacing: </b>
4249 Check this option to fix possible issues with spacing below your videos. You may also want to try combining this option with Responsive Sizing.
4250 </label>
4251 </p>
4252 <p>
4253 <input name="<?php echo self::$opt_old_script_method; ?>" id="<?php echo self::$opt_old_script_method; ?>" <?php checked($all[self::$opt_old_script_method], 1); ?> type="checkbox" class="checkbox">
4254 <label for="<?php echo self::$opt_old_script_method; ?>">
4255 <b class="chktitle">Use Legacy Scripts: </b>
4256 This is a legacy option for users with theme issues that require backwards compatibility (v.10.5 or earlier). It may also help with caching plugin or CDN plugin issues.
4257 </label>
4258 </p>
4259 <p>
4260 <input name="<?php echo self::$opt_admin_off_scripts; ?>" id="<?php echo self::$opt_admin_off_scripts; ?>" <?php checked($all[self::$opt_admin_off_scripts], 1); ?> type="checkbox" class="checkbox">
4261 <label for="<?php echo self::$opt_admin_off_scripts; ?>">
4262 <b class="chktitle">Turn Off Scripts While Editing: </b>
4263 Front-end editors and visual pagebuilders often run Javascript while you're in edit mode. Check this to turn off this plugin's Javascript during edit mode, if you see conflicts.
4264 Don't worry, all other visitors to your site will still view your site normally.
4265 </label>
4266 </p>
4267 <p>
4268 <input name="<?php echo self::$opt_migrate; ?>" id="<?php echo self::$opt_migrate; ?>" <?php checked($all[self::$opt_migrate], 1); ?> type="checkbox" class="checkbox">
4269 <label for="<?php echo self::$opt_migrate; ?>">
4270 <b class="chktitle">Migrate Shortcodes: </b> Inherit shortcodes from other plugins. This is useful for when a plugin becomes deprecated, or you simply prefer this plugin's features.
4271 </label>
4272 <div id="boxmigratelist">
4273 <ul>
4274 <li><input name="<?php echo self::$opt_migrate_embedplusvideo; ?>" id="<?php echo self::$opt_migrate_embedplusvideo; ?>" <?php checked($all[self::$opt_migrate_embedplusvideo], 1); ?> type="checkbox" class="checkbox"><label for="<?php echo self::$opt_migrate_embedplusvideo; ?>"><b>"YouTube Advanced Embed":</b> <code>[embedplusvideo]</code> shortcode</label></li>
4275 <li><input name="<?php echo self::$opt_migrate_youtube; ?>" id="<?php echo self::$opt_migrate_youtube; ?>" <?php checked($all[self::$opt_migrate_youtube], 1); ?> type="checkbox" class="checkbox"><label for="<?php echo self::$opt_migrate_youtube; ?>"><b>"YouTube Embed":</b> <code>[youtube]</code> and <code>[youtube_video]</code> shortcodes</label></li>
4276 <li class="smallnote orange" style="list-style: none;">This feature is beta. More shortcodes coming.</li>
4277 </ul>
4278
4279 </div>
4280 </p>
4281 <p>
4282 <input name="<?php echo self::$opt_oldspacing; ?>" id="<?php echo self::$opt_oldspacing; ?>" <?php checked($all[self::$opt_oldspacing], 1); ?> type="checkbox" class="checkbox">
4283 <label for="<?php echo self::$opt_oldspacing; ?>">
4284 <b class="chktitle">Legacy Spacing:</b> Continue the spacing style from version 4.0 and older. Those versions required you to manually add spacing above and below your video. Unchecking this will automatically add the spacing.
4285 </label>
4286 </p>
4287 <p>
4288 <input name="<?php echo self::$opt_frontend_only; ?>" id="<?php echo self::$opt_frontend_only; ?>" <?php checked($all[self::$opt_frontend_only], 1); ?> type="checkbox" class="checkbox">
4289 <label for="<?php echo self::$opt_frontend_only; ?>">
4290 <b class="chktitle">Don't Run Shortcode In Admin:</b>
4291 Checking this will only allow the shortcode to run on the front-end of your website, and not in the admin area.
4292 </label>
4293 </p>
4294 <p>
4295 <input name="<?php echo self::$opt_evselector_light; ?>" id="<?php echo self::$opt_evselector_light; ?>" <?php checked($all[self::$opt_evselector_light], 1); ?> type="checkbox" class="checkbox">
4296 <label for="<?php echo self::$opt_evselector_light; ?>">
4297 <b class="chktitle">Theme Video Problems: </b>
4298 Check this option if you're having issues with autoplayed videos or background videos etc. that have been generated by your theme.
4299 </label>
4300 </p>
4301 <p>
4302 <input name="<?php echo self::$opt_stop_mobile_buffer; ?>" id="<?php echo self::$opt_stop_mobile_buffer; ?>" <?php checked($all[self::$opt_stop_mobile_buffer], 1); ?> type="checkbox" class="checkbox">
4303 <label for="<?php echo self::$opt_stop_mobile_buffer; ?>">
4304 <b class="chktitle">Mobile Autoplay Problems: </b>
4305 Autoplay works for desktop, but mobile devices don't allow autoplay due to network carrier data charges. For mobile devices, this option may help the player to properly display the video for the visitor to click on.
4306 (<strong>Note:</strong> Desktop browsers like <a href="https://developers.google.com/youtube/iframe_api_reference#Mobile_considerations" target="_blank">Chrome and Safari are moving towards preventing autoplay for any video</a>. But, your chances are improved if you set your videos to initially start muted.)
4307 </label>
4308 </p>
4309 <p>
4310 <input name="<?php echo self::$opt_ajax_compat; ?>" id="<?php echo self::$opt_ajax_compat; ?>" <?php checked($all[self::$opt_ajax_compat], 1); ?> type="checkbox" class="checkbox">
4311 <label for="<?php echo self::$opt_ajax_compat; ?>">
4312 <b class="chktitle">Ajax Theme:</b>
4313 If you have a theme that loads pages with AJAX transitions, try checking this option.
4314 </label>
4315 </p>
4316 <p>
4317 <input name="<?php echo self::$opt_debugmode; ?>" id="<?php echo self::$opt_debugmode; ?>" <?php checked($all[self::$opt_debugmode], 1); ?> type="checkbox" class="checkbox">
4318 <label for="<?php echo self::$opt_debugmode; ?>">
4319 <b class="chktitle">Debug Mode: </b> If you ask for support, we may ask you to turn on debug mode here.
4320 It may print out some diagnostic info so that we can help you solve your issue.
4321 </label>
4322 </p>
4323 <p>
4324 <input name="<?php echo self::$opt_uninstall_data; ?>" id="<?php echo self::$opt_uninstall_data; ?>" <?php checked($all[self::$opt_uninstall_data], 1); ?> type="checkbox" class="checkbox">
4325 <label for="<?php echo self::$opt_uninstall_data; ?>">
4326 <b class="chktitle">Delete Options When Uninstalling:</b> Checking this box will permanently delete your options the next time you uninstall the plugin. Leave it unchecked
4327 to preserve your options between installations.
4328 </label>
4329 </p>
4330 </div>
4331
4332
4333 </section>
4334 <section class="pattern" id="jumphowto">
4335 <h2>Manual Embedding</h2>
4336 <p>
4337 <strong>We strongly recommend using the wizard in your editor to embed.</strong> However, if you choose to manually embed code, follow some legacy instructions below.
4338 </p>
4339 <h3>
4340 Manually Embed a YouTube Video or Playlist &nbsp; <a class="smallnote" href="#jumpgallery">(For gallery directions, go here &raquo;)</a>
4341 </h3>
4342 <p>
4343 <b>For videos:</b> <i>Method 1 - </i> Do you already have a URL to the video you want to embed in a post, page, or even a widget? All you have to do is paste it on its own line, as shown below (including the https:// part). Easy, eh?<br>
4344 <i>Method 2 - </i> If you want to do some formatting (e.g. add HTML to center a video) or have two or more videos next to each other on the same line, wrap each link with the <code>[embedyt]...[/embedyt]</code> shortcode. <b>Tip for embedding videos on the same line:</b> As shown in the example image below, decrease the size of each video so that they fit together on the same line (See the "How To Override Defaults" section for height and width instructions).
4345 </p>
4346 <p>
4347 <b>For galleries:</b> <a href="#jumpgallery">Click here</a> to scroll down to gallery settings and directions.
4348 </p>
4349 <p>
4350 <b>For self-contained playlists:</b> Go to the page for the playlist that lists all of its videos (<a target="_blank" href="https://www.youtube.com/playlist?list=PLsRNoUx8w3rPxNGCQYBPobGxNj1BfDT7P">Example &raquo;</a>). Click on the video that you want the playlist to start with. Copy and paste that browser URL into your blog on its own line. If you want the first video to always be the latest video in your playlist, check the option "Playlist Ordering" in the settings down below (you will also see this option available if you use the Pro Wizard). If you want to have two or more playlists next to each other on the same line, wrap each link with the <code>[embedyt]...[/embedyt]</code> shortcode.
4351 </p>
4352 <p>
4353 <b>For self-contained channel playlists:</b> At your editor, click on the <img style="vertical-align: text-bottom;" src="<?php echo plugins_url('images/wizbuttonbig.png', __FILE__) ?>"> wizard button and choose the option <i>Search for a video or channel to insert in my editor.</i> Then, click on the <i>channel playlist</i> option there (instead of <i>single video</i>). Search for the channel username and follow the rest of the directions there.
4354 </p>
4355 <p>
4356 <strong>For directly embedding in your theme with PHP:</strong>
4357 If you need to use PHP directly, we still recommend using the wizard to create the shortcode--but instead of pressing the "Insert" button, just copy the shortcode the wizard gives you. Then use the <code>do_shortcode()</code> function in your theme, like this:
4358 <br>
4359 <code>&lt;?php echo do_shortcode('[embedyt]....[/embedyt]'); ?&gt;</code>
4360 </p>
4361 <p>
4362 <b>Examples:</b><br><br>
4363 <img style="width: 900px; height: auto;" class="shadow" src="<?php echo plugins_url('images/sshowto.png', __FILE__) ?>" />
4364 </p>
4365 <p>
4366 Always follow these rules for any URL:
4367 </p>
4368 <ul class="reglist">
4369 <li>Make sure the URL is really on its own line by itself. Or, if you need multiple videos on the same line, make sure each URL is wrapped properly with the shortcode (Example: <code>[embedyt]http://www.youtube.com/watch?v=ABCDEFGHIJK&width=400&height=250[/embedyt]</code>)</li>
4370 <li>Make sure the URL is <strong>not</strong> an active hyperlink (i.e., it should just be plain text). Otherwise, highlight the URL and click the "unlink" button in your editor: <img src="<?php echo plugins_url('images/unlink.png', __FILE__) ?>"/></li>
4371 <li>Make sure you did <strong>not</strong> format or align the URL in any way. If your URL still appears in your actual post instead of a video, highlight it and click the "remove formatting" button (formatting can be invisible sometimes): <img src="<?php echo plugins_url('images/erase.png', __FILE__) ?>"/></li>
4372 <li>If you really want to align the video, try wrapping the link with the shortcode first. For example: <code>[embedyt]http://www.youtube.com/watch?v=ABCDEFGHIJK[/embedyt]</code> Using the shortcode also allows you to have two or more videos next to each other on the same line. Just put the shortcoded links together on the same line. For example:<br>
4373 <code>[embedyt]http://www.youtube.com/watch?v=ABCDEF[/embedyt] [embedyt]http://www.youtube.com/watch?v=GHIJK[/embedyt]</code>
4374 </li>
4375 </ul>
4376
4377
4378 <h3>
4379 <?php _e("How To Manually Override Defaults / Other Options") ?>
4380 </h3>
4381 <p>
4382 Suppose you have a few videos that need to be different from the above defaults. You can add options to the end of a link as displayed below to override the above defaults. Each option should begin with '&'.
4383 <br><span class="orange">PRO users: You can use the <a href="<?php echo self::$epbase . '/dashboard/pro-easy-video-analytics.aspx?ref=manual' ?>" target="_blank">customize</a> buttons that you will see inside the wizard, instead of memorizing the following codes.</span>
4384 </p>
4385 <?php
4386 _e('<ul class="reglist">');
4387 _e("<li><strong>width</strong> - Sets the width of your player. If omitted, the default width will be the width of your theme's content.<em> Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&width=500</strong>&height=350</em></li>");
4388 _e("<li><strong>height</strong> - Sets the height of your player. <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA&width=500<strong>&height=350</strong></em> </li>");
4389 _e("<li><strong>autoplay</strong> - Set this to 1 to autoplay the video (or 0 to play the video once). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&autoplay=1</strong></em> (Note: Desktop browsers like Chrome and Safari are moving towards preventing autoplay for any video. But, your chances are improved if you set your videos to initially start muted.) </li>");
4390 _e("<li><strong>cc_load_policy</strong> - Set this to 1 to turn on closed captioning (or 0 to leave them off). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&cc_load_policy=1</strong></em> </li>");
4391 _e("<li><strong>iv_load_policy</strong> - Set this to 3 to turn off annotations (or 1 to show them). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&iv_load_policy=3</strong></em> </li>");
4392 _e("<li><strong>loop</strong> - Set this to 1 to loop the video (or 0 to not loop). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&loop=1</strong></em> </li>");
4393 _e("<li><strong>rel</strong> - Set this to 0 to not show related videos at the end of playing (or 1 to show them). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&rel=0</strong></em> </li>");
4394 _e("<li><strong>fs</strong> - Set this to 0 to hide the fullscreen button (or 1 to show it). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&fs=0</strong></em> </li>");
4395 _e("<li><strong>color</strong> - Set this to 'white' to make the player have a white progress bar (or 'red' for a red progress bar). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&color=white</strong></em> </li>");
4396 _e("<li><strong>controls</strong> - Set this to 0 to completely hide the video controls (or 1 to show it). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&controls=0</strong></em> </li>");
4397 _e("<li><strong>disablekb</strong> - Set this to 1 to disable keyboard controls (or 0 to enable them). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&disablekb=1</strong></em> </li>");
4398 _e("<li><strong>playsinline</strong> - Set this to 1 to allow videos play inline with the page on iOS browsers. (Set to 0 to have iOS launch videos in fullscreen instead). <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&playsinline=1</strong></em> </li>");
4399 _e("<li><strong>origin</strong> - Set this to 1 to add the 'origin' parameter for extra JavaScript security. <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA<strong>&origin=1</strong></em> </li>");
4400 _e('</ul>');
4401
4402 _e("<p>You can also start and end each individual video at particular times. Like the above, each option should begin with '&'</p>");
4403 _e('<ul class="reglist">');
4404 _e("<li><strong>start</strong> - Sets the time (in seconds) to start the video. <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA&width=500&height=350<strong>&start=20</strong></em> </li>");
4405 _e("<li><strong>end</strong> - Sets the time (in seconds) to stop the video. <em>Example: http://www.youtube.com/watch?v=quwebVjAEJA&width=500&height=350<strong>&end=100</strong></em> </li>");
4406 _e('</ul>');
4407 ?>
4408 </section>
4409
4410 <section class="pattern" id="jumpperformance">
4411 <h2><?php _e('Performance Settings & Tips', 'youtube-embed-plus'); ?></h2>
4412 <p>
4413 <?php _e('On this page, we describe performance options to help optimize page speed times of your pages containing YouTube embeds.', 'youtube-embed-plus'); ?>
4414 </p>
4415 <div class="p">
4416 <input name="<?php echo self::$opt_facade_mode; ?>" id="<?php echo self::$opt_facade_mode; ?>" <?php checked($all[self::$opt_facade_mode], 1); ?> type="checkbox" class="checkbox">
4417 <label for="<?php echo self::$opt_facade_mode ?>">
4418 <b class="chktitle"><?php _e('Facade Mode:', 'youtube-embed-plus'); ?> <sup class="orange">new</sup></b>
4419 <?php _e('This improves performance by loading a lighter version of the player, until it is clicked. Then the real player loads (note: for live streams, the real player is always loaded). We have tested this feature in multiple cases and found it to successfully improve your Lighthouse performance score by addressing the following recommendation: "Some third-party resources can be lazy loaded with a facade."', 'youtube-embed-plus'); ?>
4420 <a href="https://www.youtube.com/watch?v=W7PKUjVBDNE" target="_blank"><?php _e('See an example of this feature at work.', 'youtube-embed-plus'); ?></a>
4421 </label>
4422 <div class="p box_facade_mode">
4423 <input name="<?php echo self::$opt_facade_autoplay; ?>" id="<?php echo self::$opt_facade_autoplay; ?>" type="checkbox" class="checkbox" <?php checked($all[self::$opt_facade_autoplay], 1); ?>>
4424 <label for="<?php echo self::$opt_facade_autoplay ?>">
4425 <b class="chktitle"><?php _e('Autoplay On Facade Click:', 'youtube-embed-plus'); ?></b>
4426 <span>
4427 <?php _e('After clicking once on the facade (aka light thumbnail), it is replaced with the real player. Check this option to have the real player play immediately, otherwise it will require an additional click. Note that checking this option will use YouTube\'s autoplay feature, which will not contribute toward play counts. If you\'re embedding videos from someone else\'s channel, we recommend checking this. If you\'re embedding videos that are from your channel, then you should self-evaluate the tradeoff involving play counts and additional clicking.', 'youtube-embed-plus'); ?>
4428 </span>
4429 </label>
4430 <br>
4431 <br>
4432 <label>
4433 <b class="chktitle"><?php _e('Force Maximum Quality for Facade Images: <sup class="orange">new</sup>', 'text_domain') ?></b>
4434 <?php _e('Attempt to load the maximum resolution image for the facade image. This max quality image does not exist for all videos, so you have a few choices below.', 'text_domain'); ?>
4435 </label>
4436 <ul class="indent-option">
4437 <li>
4438 <input type="radio" name="<?php echo self::$opt_maxres_facade; ?>" id="<?php echo self::$opt_maxres_facade; ?>_eager" value="eager" <?php checked($all[self::$opt_maxres_facade], 'eager'); ?>>
4439 <label for="<?php echo self::$opt_maxres_facade; ?>_eager"> <?php _e("<em>Eager:</em> Try loading the max resolution image by default. If the max-res image does not exist for the video, the next highest available resolution will immediately load instead. This option is best for websites that embed videos having very high resolutions (i.e. the max-res images will likely exist).", 'text_domain') ?> </label> <br>
4440 </li>
4441 <li>
4442 <input type="radio" name="<?php echo self::$opt_maxres_facade; ?>" id="<?php echo self::$opt_maxres_facade; ?>_soft" value="soft" <?php checked($all[self::$opt_maxres_facade], 'soft'); ?>>
4443 <label for="<?php echo self::$opt_maxres_facade; ?>_soft"> <?php _e("<em>Soft:</em> Load a relatively high resolution image that is guaranteed to exist, but immediately try updating the image to maximum resolution if it exists. This option is best for sites with some videos that may have a missing max resolution image.", 'text_domain') ?> </label> <br>
4444 </li>
4445 <li>
4446 <input type="radio" name="<?php echo self::$opt_maxres_facade; ?>" id="<?php echo self::$opt_maxres_facade; ?>_off" value="off" <?php checked($all[self::$opt_maxres_facade], 'off'); ?>>
4447 <label for="<?php echo self::$opt_maxres_facade; ?>_off"><?php _e("<em>Off:</em> Don't try to maximize facade image quality. Just load the relatively high resolution image that all videos have.", 'text_domain') ?></label> <br>
4448 </li>
4449 </ul>
4450 </div>
4451 </div>
4452 <div class="p">
4453 <input name="<?php echo self::$opt_defer_js; ?>" id="<?php echo self::$opt_defer_js; ?>" <?php checked($all[self::$opt_defer_js], 1); ?> type="checkbox" class="checkbox">
4454 <label for="<?php echo self::$opt_defer_js ?>">
4455 <b class="chktitle"><?php _e('Defer Javascript:', 'youtube-embed-plus'); ?></b>
4456 <?php _e('JavaScript (JS) deferral is a common website performance option that can offer significant improvements of page speed. You can reduce the initial load time of your page by allowing this plugin\'s scripts to begin execution only after a page is loaded. You may receive a better GTMetrix score with this option turned on. Note: This feature is compatible with most sites, but turn it off if you are having issues.', 'youtube-embed-plus'); ?>
4457 </label>
4458 <div class="p box_defer_jquery">
4459 <input name="<?php echo self::$opt_defer_jquery; ?>" id="<?php echo self::$opt_defer_jquery; ?>" type="checkbox" class="checkbox" <?php checked($all[self::$opt_defer_jquery], 1); ?>>
4460 <label for="<?php echo self::$opt_defer_jquery ?>">
4461 <b class="chktitle"><?php _e('Also Defer jQuery:', 'youtube-embed-plus'); ?></b>
4462 <span style="color: red;">
4463 <?php _e('Note: Do NOT check this option if you are using a pagebuilder. Furthermore, defering jQuery may improve your GTMetrix score even more, but might not be compatible with your theme or other plugins (especially if they are not defering their own scripts). Use this option with caution.', 'youtube-embed-plus'); ?>
4464 </span>
4465 </label>
4466 </div>
4467 </div>
4468 <p><?php _e('Note: Since the YouTube player is loaded in its own iframe from YouTube\'s servers, browser restrictions prevent this plugin from directly deferring the JS inside the iframe. However, if you upgrade to Pro, you can use the lazy loading feature <a href="#jumpupgrade">described here &raquo;</a> to further improve your page speeds or try out facade mode.', 'youtube-embed-plus'); ?></p>
4469 </section>
4470
4471 <div class="save-changes-follow"> <?php self::save_changes_button(isset($_POST[$ytprefs_submitted]) && $_POST[$ytprefs_submitted] == 'Y'); ?> </div>
4472 </form>
4473
4474 <section class="pattern" id="jumpupgrade">
4475 <div class="upgchecks">
4476 <h3 class="sect">Want the PRO Features?</h3>
4477 <p>
4478 Below are descriptions for some of our PRO features for more gallery customization options, faster page loading, enhanced SEO, and more. Simply purchase and install our separate PRO plugin (the PRO plugin automatically works for all your past embed links).
4479 </p>
4480 <p>
4481 <input disabled type="checkbox" class="checkbox">
4482 <label>
4483 <b class="chktitle">Lazy-Loading for Performance:</b> <span class="pronon">(PRO Users)</span>
4484 Lazy-loading can speed up your page loads by loading the player only until it is visible on the screen.
4485 <a href="https://www.youtube.com/watch?v=omNdJvXDCLo" target="_blank">See an example here</a>.
4486 An added bonus to this option is that you have the choice of several types of eye-catching lazy-loading effects that will make your YouTube embeds bounce, flip, pulse, or slide as they lazy load on the screen. Check this box to select your desired effect. <a target="_blank" href="<?php echo self::$epbase ?>/add-special-effects-to-youtube-embeds-in-wordpress.aspx">Read more here &raquo;</a>
4487 </label>
4488 </p>
4489 <div class="hr"></div>
4490 <p>
4491 <img class="ssaltgallery" src="<?php echo plugins_url('images/ss-live-chat.jpg', __FILE__) ?>" />
4492 <input disabled type="checkbox" class="checkbox">
4493 <label>
4494 <b class="chktitle"><?php _e('Enable Live Chat:', 'youtube-embed-plus') ?></b> <span class="pronon"><?php _e('(PRO Users)', 'youtube-embed-plus') ?></span> <?php _e('<sup class="orange">new</sup>') ?> <?php _e('Add more interaction to your site by including the YouTube live chat box as part of each live stream embed. Note that live chat can also be an option for earning money from your audience by using the Super Chat feature. <a href="https://creatoracademy.youtube.com/page/lesson/superchat" target="_blank">Learn more here</a>.') ?>
4495 <strong class="check-note"><?php _e('<span class="orange">NOTE:</span> In wide containers, the chat box will appear to the right of the player. It will appear below the player when the container is less than 964px. Also, Google/YouTube disables live chat on mobile devices. So for mobile phones and tablets, the chat box will be hidden.') ?></strong>
4496 </label>
4497 <br>
4498 <br>
4499 </p>
4500 <div class="hr"></div>
4501 <p>
4502 <img class="ssaltgallery" src="<?php echo plugins_url('images/ssaltgalleryall.jpg', __FILE__) ?>" />
4503 <select disabled>
4504 <option value="">Gallery Style</option>
4505 </select>
4506 <label>
4507 <b class="chktitle">Advanced Gallery Customization Options: </b> <span class="pronon">(PRO Users)</span>
4508 Switch from the grid style of the free version to another gallery style. Right now, we provide a vertical (single column) and horizontal (single row) list style as alternatives to the grid, with more designs coming. These current alternatives were inspired by the standard YouTube playlist player's "table of contents," except our gallery's video lists are always visible and shown under the playing video.
4509 <a target="_blank" href="<?php echo self::$epbase ?>/responsive-youtube-playlist-channel-gallery-for-wordpress.aspx">Read more here &raquo;</a>
4510 </label>
4511 </p>
4512
4513 <div class="hr"></div>
4514 <p>
4515 <img class="ssaltgallery" src="<?php echo plugins_url('images/ssverticallayout.png', __FILE__) ?>" />
4516 <input disabled type="checkbox" class="checkbox">
4517 <label>
4518 <b class="chktitle">Show Gallery Descriptions (for vertical list styling): </b> <span class="pronon">(PRO Users)</span>
4519 For the vertical list layout, this option will show full video descriptions (taken directly from YouTube.com) with each thumbnail. Note: these descriptions only apply the vertical list layout; other layouts don't have enough room.
4520 </label>
4521 </p>
4522 <div class="hr"></div>
4523 <p>
4524 <img class="ssaltgallery" src="<?php echo plugins_url('images/ssaltgallerycircles.jpg', __FILE__) ?>" />
4525 <select disabled>
4526 <option value="">Select Thumbnail Shape</option>
4527 </select>
4528 <label>
4529 <b class="chktitle">Gallery Thumbnail Shape: </b> <span class="pronon">(PRO Users)</span>
4530 Differentiate your gallery by showing different thumbnail shapes. We currently offer rectangle and circle shapes.
4531 <a target="_blank" href="<?php echo self::$epbase ?>/responsive-youtube-playlist-channel-gallery-for-wordpress.aspx">Read more here &raquo;</a>
4532 </label>
4533 </p>
4534
4535 <div class="hr"></div>
4536 <p>
4537 <img class="sspopupplayer" src="<?php echo plugins_url('images/sspopupplayer.jpg', __FILE__) ?>" />
4538 <label>
4539 <b class="chktitle">Gallery Video Display Mode: </b> <span class="pronon">(PRO Users)</span>
4540 Display your gallery videos simply above the thumbnails (default), or as a popup lightbox. Choosing "popup lightbox" will make your videos lazy-loaded, which will provide some performance benefits since the YouTube player is not initially loaded with your page. It's loaded with a popup only when a user clicks a thumbnail.
4541 </label>
4542 <br>
4543 <input type="radio" disabled> Default &nbsp; <input type="radio" disabled> Popup lightbox
4544 </p>
4545
4546 <div class="hr"></div>
4547
4548 <p>
4549 <img class="sshidethumbimg" src="<?php echo plugins_url('images/sshidethumbimg.jpg', __FILE__) ?>" />
4550 <input disabled type="checkbox" class="checkbox">
4551 <label>
4552 <b class="chktitle">Hide Thumbnail Images:</b> <span class="pronon">(PRO Users)</span>
4553 (For "Grid" and "Vertical List" gallery layouts only) Hide the image for each thumbnail, leaving just the text. This can improve performance when imagery is not important.
4554 <a href="<?php echo self::$epbase ?>/responsive-youtube-playlist-channel-gallery-for-wordpress.aspx" target="_blank">See an example here &raquo;</a>
4555 </label>
4556 </p>
4557
4558 <div class="hr"></div>
4559 <p>
4560 <input disabled type="checkbox" class="checkbox">
4561 <label>
4562 <b class="chktitle">Faster Page Loads (Caching): </b> <span class="pronon">(PRO Users)</span>
4563 Use embed caching to speed up your page loads. By default, WordPress needs to request information from YouTube.com's servers for every video you embed, every time a page is loaded. These data requests can add time to your total page load time. Turn on this feature to cache that data (instead of having to request for the same information every time you load a page). This should then make your pages that have videos load faster. It's been noted that even small speed ups in page load can help increase visitor engagement, retention, and conversions. Caching also makes galleries run faster.
4564 </label>
4565 <div class="indent-option">
4566 <label>
4567 <b class="chktitle">Cache Lifetime (hours): </b>
4568 <input disabled value="24" type="number">
4569 Tip: If your pages rarely change, you may wish to set this to a much higher value than 24 hours.
4570 </label>
4571 </div>
4572 </p>
4573 <div class="hr"></div>
4574
4575 <p>
4576 <input disabled type="checkbox" class="checkbox">
4577 <label>
4578 <b class="chktitle">Video SEO Tags:</b> <span class="pronon">(PRO Users)</span> Update your YouTube embeds with Google, Bing, and Yahoo friendly schema markup for videos.
4579 </label>
4580 </p>
4581 <div class="hr"></div>
4582 <p>
4583 <input disabled type="checkbox" class="checkbox">
4584 <label>
4585 <b class="chktitle">Facebook Open Graph Markup:</b> <span class="pronon">(PRO Users)</span> Include Facebook Open Graph markup with the videos you embed with this plugin. We follow the guidelines for videos as described here: <a href="https://developers.facebook.com/docs/sharing/webmasters#media" target="_blank">https://developers.facebook.com/docs/sharing/webmasters#media</a>
4586 </label>
4587 </p>
4588 <div class="hr"></div>
4589 <p>
4590 <img class="ssfb" src="<?php echo plugins_url('images/youtube_thumbnail_sample.jpg', __FILE__) ?>" />
4591 <input disabled type="checkbox" class="checkbox">
4592 <label>
4593 <b class="chktitle">Featured Thumbnail Images:</b> <span class="pronon">(PRO Users)</span>
4594 Automatically grab the thumbnail image of the first video embedded in each post or page, and use it as the featured image.
4595 All you have to do is click Update on a post or page and the plugin does the rest!
4596 (Example shown on the right) <a target="_blank" href="<?php echo self::$epbase ?>/add-youtube-video-thumbnails-featured-image-wordpress.aspx">Read more here &raquo;</a>
4597 </label>
4598 </p>
4599 <div class="hr"></div>
4600 <p>
4601 <a href="<?php echo self::$epbase ?>/dashboard/pro-easy-video-analytics.aspx?ref=protabfooter" target="_blank">Purchase and download the PRO plugin to get the above and several other features &raquo;</a>
4602 </p>
4603 <div class="clearboth"></div>
4604 </div>
4605
4606 </section>
4607
4608 <section class="pattern" id="jumpsupport">
4609 <h2>Plugin Support</h2>
4610
4611 <div id="nonprosupport">
4612 <p>
4613 Here is a short video explaining a few of the plugin's features:
4614 </p>
4615 <div class="epyt-fitvid">
4616 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/QDdvXBqfrzM?rel=0" allowfullscreen="" frameborder="0"></iframe>
4617 </div>
4618 <p>
4619 We've also found that a common support request has been from users that are pasting video links on single lines, as required, but are not seeing the video embed show up. One of these suggestions is usually the fix:
4620 </p>
4621 <ul class="reglist">
4622 <li>Make sure the URL is really on its own line by itself. Or, if you need multiple videos on the same line, make sure each URL is wrapped properly with the shortcode (Example: <code>[embedyt]http://www.youtube.com/watch?v=ABCDEFGHIJK&width=400&height=250[/embedyt]</code>)</li>
4623 <li>Make sure the URL is not an active hyperlink (i.e., it should just be plain text). Otherwise, highlight the URL and click the "unlink" button in your editor: <img src="<?php echo plugins_url('images/unlink.png', __FILE__) ?>"/>.</li>
4624 <li>Make sure you did <strong>not</strong> format or align the URL in any way. If your URL still appears in your actual post instead of a video, highlight it and click the "remove formatting" button (formatting can be invisible sometimes): <img src="<?php echo plugins_url('images/erase.png', __FILE__) ?>"/></li>
4625 <li>Try wrapping the URL with the <code>[embedyt]...[/embedyt]</code> shortcode. For example: <code>[embedyt]http://www.youtube.com/watch?v=ABCDEFGHIJK[/embedyt]</code> Using the shortcode also allows you to have two or more videos next to each other on the same line. Just put the shortcoded links together on the same line. For example:<br>
4626 <code>[embedyt]http://www.youtube.com/watch?v=ABCDEF&width=400&height=250[/embedyt] [embedyt]http://www.youtube.com/watch?v=GHIJK&width=400&height=250[/embedyt]</code>
4627 <br> TIP: As shown above, decrease the size of each video so that they fit together on the same line (See the "How To Override Defaults" section for height and width instructions)
4628 </li>
4629 <li>If you upload a new video to a playlist or channel and that video is not yet showing up on a gallery you embedded, you should clear/reset any caching plugins you have. This will force your site to retrieve the freshest version of your playlist and/or channel video listing. If you don't reset you cache, then you'll have to wait until cache lifetime expires.</li>
4630 <li>Finally, there's a slight chance your custom theme is the issue, if you have one. To know for sure, we suggest temporarily switching to one of the default WordPress themes (e.g., "Twenty Fourteen") just to see if your video does appear. If it suddenly works, then your custom theme is the issue. You can switch back when done testing.</li>
4631 <li>If your videos always appear full size, try turning off "Responsive video sizing."</li>
4632 <li>If none of the above work, you can contact us here if you still have issues: ext@embedplus.com. We'll try to respond within a week.</li>
4633 </ul>
4634 <p>
4635 Deactivating the No Cookies option has also been proven to solve player errors.
4636 </p>
4637 <p>
4638 We also have a YouTube channel. We use it to provide users with some helper videos and a way to keep updated on new features as they are introduced. <a href="https://www.youtube.com/subscription_center?add_user=EmbedPlus" target="_blank">Subscribe for tips and updates here &raquo;</a>
4639 </p>
4640 </div>
4641 <br>
4642 </section>
4643 </div>
4644 </div>
4645 <script type="text/javascript">
4646 (function ($)
4647 {
4648 window.savevalidate = function (e)
4649 {
4650 var $formDefaults = $(e.target);
4651 var valid = true;
4652 var $tabFocus = '';
4653 var alertmessage = '';
4654 if (jQuery("#<?php echo self::$opt_defaultdims; ?>").is(":checked"))
4655 {
4656 if (!(jQuery.isNumeric(jQuery.trim(jQuery("#<?php echo self::$opt_defaultwidth; ?>").val())) &&
4657 jQuery.isNumeric(jQuery.trim(jQuery("#<?php echo self::$opt_defaultheight; ?>").val()))))
4658 {
4659 alertmessage += "Please enter valid numbers for default height and width, or uncheck the option.";
4660 jQuery("#boxdefaultdims input").css("background-color", "#ffcccc").css("border", "2px solid #000000");
4661 valid = false;
4662 $tabFocus = $("#<?php echo self::$opt_defaultdims; ?>").closest('section');
4663 }
4664 }
4665
4666 if (jQuery("#<?php echo self::$opt_gallery_customarrows; ?>").is(":checked"))
4667 {
4668 if (!jQuery.trim(jQuery("#<?php echo self::$opt_gallery_customprev; ?>").val()) ||
4669 !jQuery.trim(jQuery("#<?php echo self::$opt_gallery_customnext; ?>").val()))
4670 {
4671 alertmessage += "Please enter valid text for both the custom gallery Prev and Next buttons, or uncheck the option.";
4672 jQuery("#boxcustomarrows input").css("background-color", "#ffcccc").css("border", "2px solid #000000");
4673 valid = false;
4674 $tabFocus = $("#<?php echo self::$opt_gallery_customarrows; ?>").closest('section');
4675 }
4676 }
4677
4678
4679 if (jQuery("#<?php echo self::$opt_gallery_channelsub; ?>").is(":checked"))
4680 {
4681 if (!jQuery.trim(jQuery("#<?php echo self::$opt_gallery_channelsublink; ?>").val()) ||
4682 !jQuery.trim(jQuery("#<?php echo self::$opt_gallery_channelsubtext; ?>").val()))
4683 {
4684 alertmessage += "Please enter valid text for both the subscribe text and subscribe URL, or uncheck the option.";
4685 jQuery("#boxchannelsub input").css("background-color", "#ffcccc").css("border", "2px solid #000000");
4686 valid = false;
4687 $tabFocus = $("#<?php echo self::$opt_gallery_channelsub; ?>").closest('section');
4688 }
4689 }
4690
4691
4692 if (jQuery("#<?php echo self::$opt_gallery_collapse_grid; ?>").is(":checked"))
4693 {
4694 var emptyStacks = [];
4695 jQuery("#box_collapse_grid input").each(function ()
4696 {
4697 var val = jQuery(this).val();
4698 if (jQuery.trim(val) === '' || !jQuery.isNumeric(val))
4699 {
4700 emptyStacks.push(this);
4701 jQuery(this).css("background-color", "#ffcccc").css("outline", "2px solid #000000");
4702 }
4703 });
4704 if (emptyStacks.length)
4705 {
4706 alertmessage += "Please enter a valid number for the gallery stacking screen width.";
4707 valid = false;
4708 $tabFocus = $("#<?php echo self::$opt_gallery_collapse_grid; ?>").closest('section');
4709 }
4710 }
4711
4712
4713
4714 if (jQuery("#<?php echo self::$opt_defaultvol; ?>").is(":checked"))
4715 {
4716 if (!(jQuery.isNumeric(jQuery.trim(jQuery("#<?php echo self::$opt_vol; ?>").val()))))
4717 {
4718 alertmessage += "Please enter a number between 0 and 100 for the default volume, or uncheck the option.";
4719 jQuery("#boxdefaultvol input").css("background-color", "#ffcccc").css("border", "2px solid #000000");
4720 valid = false;
4721 $tabFocus = $("#<?php echo self::$opt_defaultvol; ?>").closest('section');
4722 }
4723 }
4724
4725 if (!valid)
4726 {
4727 alertify.alert(alertmessage);
4728 var tabSelector = '.wrap-ytprefs .nav-tab-wrapper .nav-tab[href=#' + $tabFocus.attr('id') + ']';
4729 $(tabSelector).trigger('click');
4730 }
4731 if (!$formDefaults.find('#ajax_save').is(':checked'))
4732 {
4733 return valid;
4734 }
4735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////// MAIN PREFS AJAX SAVE
4736 if (valid)
4737 {
4738 e.preventDefault();
4739 (window.tinyMCE || window.tinymce).triggerSave();
4740 $formDefaults.find('.ytprefs-submit').prop('disabled', true);
4741
4742 var formData = $formDefaults.ytprefsFormJSON();
4743 formData.action = 'my_embedplus_settings_save_ajax';
4744
4745 $.ajax({
4746 type: "post",
4747 dataType: "json",
4748 timeout: 30000,
4749 url: window._EPYTA_ ? window._EPYTA_.wpajaxurl : ajaxurl,
4750 data: formData,
4751 success: function (response)
4752 {
4753 alertify.alert(response ? response.message : 'Sorry, there was an error submitting your settings.', function ()
4754 {
4755 if (response.type == 'success')
4756 {
4757 window.top.location.href = window._EPYTA_.admin_url_ytprefs;
4758 }
4759 });
4760 },
4761 error: function (xhr, ajaxOptions, thrownError)
4762 {
4763 alertify.alert('Sorry, there was an error saving your settings. ' + (thrownError ? thrownError : ''));
4764 },
4765 complete: function ()
4766 {
4767 $formDefaults.find('.ytprefs-submit').prop('disabled', false);
4768 }
4769 });
4770 }
4771 };
4772
4773 var mydomain = escape("http://" + window.location.host.toString());
4774 jQuery(document).ready(function ($)
4775 {
4776 $(document).on('click', '.wrap-ytprefs .nav-tab-wrapper a, .epyt-jumptab', function ()
4777 {
4778 $a = $(this);
4779 if (!$a.hasClass('href-link'))
4780 {
4781 $('.wrap-ytprefs .nav-tab-wrapper a').removeClass('nav-tab-active');
4782 $a.addClass('nav-tab-active');
4783 $('.wrap-ytprefs section').hide();
4784 $('.wrap-ytprefs section').filter($a.attr('rel') ? $a.attr('rel') : $a.attr('href')).fadeIn(200);
4785 return false;
4786 }
4787 });
4788
4789 if (window.location.hash && window.location.hash == '#jumpmonetize')
4790 {
4791 setTimeout(function ()
4792 {
4793 window.scrollTo(0, 0);
4794 }, 1);
4795 $('.wrap-ytprefs .nav-tab-wrapper a[href="' + window.location.hash + '"]').trigger('click');
4796 }
4797
4798 $('#ytform').on('submit', function (e)
4799 {
4800 return window.savevalidate(e);
4801 });
4802
4803 jQuery('#<?php echo self::$opt_defaultdims; ?>').on('change', function ()
4804 {
4805 if (jQuery(this).is(":checked"))
4806 {
4807 jQuery("#boxdefaultdims").show(500);
4808 }
4809 else
4810 {
4811 jQuery("#boxdefaultdims").hide(500);
4812 }
4813
4814 });
4815 jQuery('#<?php echo self::$opt_gallery_customarrows; ?>').on('change', function ()
4816 {
4817 if (jQuery(this).is(":checked"))
4818 {
4819 jQuery("#boxcustomarrows").show(500);
4820 }
4821 else
4822 {
4823 jQuery("#boxcustomarrows").hide(500);
4824 }
4825
4826 });
4827 jQuery('#<?php echo self::$opt_gallery_collapse_grid; ?>').on('change', function ()
4828 {
4829 if (jQuery(this).is(":checked"))
4830 {
4831 jQuery("#box_collapse_grid").show(500);
4832 }
4833 else
4834 {
4835 jQuery("#box_collapse_grid").hide(500);
4836 }
4837 });
4838 jQuery('#<?php echo self::$opt_restrict_wizard; ?>').on('change', function ()
4839 {
4840 if (jQuery(this).is(":checked"))
4841 {
4842 jQuery("#box_restrict_wizard").show(500);
4843 }
4844 else
4845 {
4846 jQuery("#box_restrict_wizard").hide(500);
4847 }
4848 });
4849
4850 jQuery('#<?php echo self::$opt_gallery_channelsub; ?>').on('change', function ()
4851 {
4852 if (jQuery(this).is(":checked"))
4853 {
4854 jQuery("#boxchannelsub").show(500);
4855 }
4856 else
4857 {
4858 jQuery("#boxchannelsub").hide(500);
4859 }
4860
4861 });
4862 jQuery('#<?php echo self::$opt_responsive; ?>').on('change', function ()
4863 {
4864 if (jQuery(this).is(":checked"))
4865 {
4866 jQuery("#boxresponsive_all").show(500);
4867 }
4868 else
4869 {
4870 jQuery("#boxresponsive_all").hide(500);
4871 }
4872 });
4873 jQuery('#<?php echo self::$opt_migrate; ?>').on('change', function ()
4874 {
4875 if (jQuery(this).is(":checked"))
4876 {
4877 jQuery("#boxmigratelist").show(500);
4878 }
4879 else
4880 {
4881 jQuery("#boxmigratelist").hide(500);
4882 }
4883 });
4884 jQuery('#<?php echo self::$opt_nocookie; ?>').on('change', function ()
4885 {
4886 if (jQuery(this).is(":checked"))
4887 {
4888 jQuery("#boxnocookie").show(500);
4889 }
4890 else
4891 {
4892 jQuery("#boxnocookie").hide(500);
4893 }
4894
4895 });
4896 jQuery('#<?php echo self::$opt_gdpr_consent; ?>').on('change', function ()
4897 {
4898 if (jQuery(this).is(":checked"))
4899 {
4900 jQuery("#box_gdpr_consent").show(500);
4901 }
4902 else
4903 {
4904 jQuery("#box_gdpr_consent").hide(500);
4905 }
4906
4907 });
4908
4909 jQuery('#<?php echo self::$opt_defaultvol; ?>').on('change', function ()
4910 {
4911 if (jQuery(this).is(":checked"))
4912 {
4913 jQuery("#boxdefaultvol").show(500);
4914 }
4915 else
4916 {
4917 jQuery("#boxdefaultvol").hide(500);
4918 }
4919
4920 });
4921 var rangedetect = document.createElement("input");
4922 rangedetect.setAttribute("type", "range");
4923 var canrange = rangedetect.type !== "text";
4924 //canrange = false;
4925 if (canrange)
4926 {
4927 $("input#vol").prop("type", "range").addClass("vol-range").on("input change", function ()
4928 {
4929 $('.vol-output').text($(this).val() > 0 ? $(this).val() + '%' : 'Mute');
4930 });
4931 $('.vol-output').css("display", "inline-block").text($("input#vol").val() > 0 ? $("input#vol").val() + '%' : 'Mute');
4932 $('.vol-seeslider').show();
4933 $('.vol-seetextbox').hide();
4934 }
4935 else
4936 {
4937 $("input#vol").width(40);
4938 }
4939
4940 $('#defer_js').on('change', function ()
4941 {
4942 if (!$(this).is(':checked'))
4943 {
4944 $('#defer_jquery').prop('checked', false).prop('disabled', true);
4945 }
4946 else
4947 {
4948 $('#defer_jquery').prop('disabled', false);
4949 }
4950 });
4951
4952 });
4953 })(jQuery);
4954 </script>
4955
4956 <a href="<?php echo esc_attr(admin_url('admin.php?page=youtube-ep-onboarding') . '&random=' . rand(1, 1000) . '&TB_iframe=true&width=950&height=800'); ?>" class="thickbox ytprefs-onboarding-launch" id="ytprefs-onboarding-launch" title="EmbedPlus for YouTube Setup Guide"></a>
4957
4958 <?php
4959 if (function_exists('add_thickbox'))
4960 {
4961 add_thickbox();
4962 }
4963 }
4964
4965 public static function settings_save($all)
4966 {
4967 $new_options = array();
4968 $new_options[self::$opt_center] = self::postchecked(self::$opt_center) ? 1 : 0;
4969 $new_options[self::$opt_glance] = self::postchecked(self::$opt_glance) ? 1 : 0;
4970 $new_options[self::$opt_autoplay] = self::postchecked(self::$opt_autoplay) ? 1 : 0;
4971 $new_options[self::$opt_debugmode] = self::postchecked(self::$opt_debugmode) ? 1 : 0;
4972 $new_options[self::$opt_uninstall_data] = self::postchecked(self::$opt_uninstall_data) ? 1 : 0;
4973 $new_options[self::$opt_admin_off_scripts] = self::postchecked(self::$opt_admin_off_scripts) ? 1 : 0;
4974 $new_options[self::$opt_defer_js] = self::postchecked(self::$opt_defer_js) ? 1 : 0;
4975 $new_options[self::$opt_defer_jquery] = self::postchecked(self::$opt_defer_jquery) ? 1 : 0;
4976 $new_options[self::$opt_ajax_save] = self::postchecked(self::$opt_ajax_save) ? 1 : 0;
4977 $new_options[self::$opt_show_pointer] = self::postchecked(self::$opt_show_pointer) ? 1 : 0;
4978 $new_options[self::$opt_old_script_method] = self::postchecked(self::$opt_old_script_method) ? 1 : 0;
4979 $new_options[self::$opt_cc_load_policy] = self::postchecked(self::$opt_cc_load_policy) ? 1 : 0;
4980 $new_options[self::$opt_iv_load_policy] = self::postchecked(self::$opt_iv_load_policy) ? 1 : 3;
4981 $new_options[self::$opt_loop] = self::postchecked(self::$opt_loop) ? 1 : 0;
4982 $new_options[self::$opt_fs] = self::postchecked(self::$opt_fs) ? 1 : 0;
4983 $new_options[self::$opt_playsinline] = self::postchecked(self::$opt_playsinline) ? 1 : 0;
4984 $new_options[self::$opt_origin] = self::postchecked(self::$opt_origin) ? 1 : 0;
4985 $new_options[self::$opt_controls] = self::postchecked(self::$opt_controls) ? 1 : 0;
4986 $new_options[self::$opt_disablekb] = self::postchecked(self::$opt_disablekb) ? 1 : 0;
4987 $new_options[self::$opt_color] = self::postchecked(self::$opt_color) ? 'red' : 'white';
4988 $new_options[self::$opt_nocookie] = self::postchecked(self::$opt_nocookie) ? 1 : 0;
4989 $new_options[self::$opt_gb_compat] = self::postchecked(self::$opt_gb_compat) ? 1 : 0;
4990 $new_options[self::$opt_facade_mode] = self::postchecked(self::$opt_facade_mode) ? 1 : 0;
4991 $new_options[self::$opt_facade_autoplay] = self::postchecked(self::$opt_facade_autoplay) ? 1 : 0;
4992 $new_options[self::$opt_gdpr_consent] = self::postchecked(self::$opt_gdpr_consent) ? 1 : 0;
4993 $new_options[self::$opt_playlistorder] = self::postchecked(self::$opt_playlistorder) ? 1 : 0;
4994 $new_options[self::$opt_acctitle] = self::postchecked(self::$opt_acctitle) ? 1 : 0;
4995 $new_options[self::$opt_migrate] = self::postchecked(self::$opt_migrate) ? 1 : 0;
4996 $new_options[self::$opt_migrate_youtube] = self::postchecked(self::$opt_migrate_youtube) ? 1 : 0;
4997 $new_options[self::$opt_migrate_embedplusvideo] = self::postchecked(self::$opt_migrate_embedplusvideo) ? 1 : 0;
4998 $new_options[self::$opt_oldspacing] = self::postchecked(self::$opt_oldspacing) ? 1 : 0;
4999 $new_options[self::$opt_frontend_only] = self::postchecked(self::$opt_frontend_only) ? 1 : 0;
5000 $new_options[self::$opt_responsive] = self::postchecked(self::$opt_responsive) ? 1 : 0;
5001 $new_options[self::$opt_widgetfit] = self::postchecked(self::$opt_widgetfit) ? 1 : 0;
5002 $new_options[self::$opt_evselector_light] = self::postchecked(self::$opt_evselector_light) ? 1 : 0;
5003 $new_options[self::$opt_stop_mobile_buffer] = self::postchecked(self::$opt_stop_mobile_buffer) ? 1 : 0;
5004 $new_options[self::$opt_restrict_wizard] = self::postchecked(self::$opt_restrict_wizard) ? 1 : 0;
5005 $new_options[self::$opt_ajax_compat] = self::postchecked(self::$opt_ajax_compat) ? 1 : 0;
5006 $new_options[self::$opt_defaultdims] = self::postchecked(self::$opt_defaultdims) ? 1 : 0;
5007 $new_options[self::$opt_pause_others] = self::postchecked(self::$opt_pause_others) ? 1 : 0;
5008 $new_options[self::$opt_defaultvol] = self::postchecked(self::$opt_defaultvol) ? 1 : 0;
5009 $new_options[self::$opt_dohl] = self::postchecked(self::$opt_dohl) ? 1 : 0;
5010 $new_options[self::$opt_onboarded] = self::postchecked(self::$opt_onboarded) ? 1 : 0;
5011 $new_options[self::$opt_not_live_on] = self::postchecked(self::$opt_not_live_on) ? 1 : 0;
5012 $new_options[self::$opt_not_live_on_channel] = self::postchecked(self::$opt_not_live_on_channel) ? 1 : 0;
5013 $new_options[self::$opt_gallery_hideprivate] = self::postchecked(self::$opt_gallery_hideprivate) ? 1 : 0;
5014 $new_options[self::$opt_gallery_showtitle] = self::postchecked(self::$opt_gallery_showtitle) ? 1 : 0;
5015 $new_options[self::$opt_gallery_showpaging] = self::postchecked(self::$opt_gallery_showpaging) ? 1 : 0;
5016 $new_options[self::$opt_gallery_autonext] = self::postchecked(self::$opt_gallery_autonext) ? 1 : 0;
5017 $new_options[self::$opt_gallery_thumbplay] = self::postchecked(self::$opt_gallery_thumbplay) ? 1 : 0;
5018 $new_options[self::$opt_gallery_channelsub] = self::postchecked(self::$opt_gallery_channelsub) ? 1 : 0;
5019 $new_options[self::$opt_gallery_customarrows] = self::postchecked(self::$opt_gallery_customarrows) ? 1 : 0;
5020 $new_options[self::$opt_gallery_collapse_grid] = self::postchecked(self::$opt_gallery_collapse_grid) ? 1 : 0;
5021
5022 $new_options[self::$opt_cc_lang_pref] = sanitize_title($_POST[self::$opt_cc_lang_pref]);
5023
5024 $_rel = 0;
5025 try
5026 {
5027 $_rel = is_numeric(trim($_POST[self::$opt_rel])) ? intval(trim($_POST[self::$opt_rel])) : $_rel;
5028 }
5029 catch (Exception $ex)
5030 {
5031
5032 }
5033 $new_options[self::$opt_rel] = $_rel;
5034
5035
5036 $_gdpr_consent_message = '';
5037 try
5038 {
5039 $_gdpr_consent_message = wp_kses_post(stripslashes($_POST[self::$opt_gdpr_consent_message]));
5040 }
5041 catch (Exception $ex)
5042 {
5043 $_gdpr_consent_message = '';
5044 }
5045 $new_options[self::$opt_gdpr_consent_message] = $_gdpr_consent_message;
5046
5047 $_gdpr_consent_button = '';
5048 try
5049 {
5050 $_gdpr_consent_button = wp_kses_post(stripslashes($_POST[self::$opt_gdpr_consent_button]));
5051 }
5052 catch (Exception $ex)
5053 {
5054 $_gdpr_consent_button = '';
5055 }
5056 $new_options[self::$opt_gdpr_consent_button] = $_gdpr_consent_button;
5057
5058 $_ytapi_load = 'light';
5059 try
5060 {
5061 $_ytapi_load_temp = $_POST[self::$opt_ytapi_load];
5062 if (in_array($_ytapi_load_temp, array('always', 'light', 'never')))
5063 {
5064 $_ytapi_load = $_ytapi_load_temp;
5065 }
5066 }
5067 catch (Exception $ex)
5068 {
5069
5070 }
5071 $new_options[self::$opt_ytapi_load] = $_ytapi_load;
5072
5073 $_maxres_facade = 'eager';
5074 try
5075 {
5076 $_maxres_facade_temp = filter_input(INPUT_POST, self::$opt_maxres_facade);
5077 if (in_array($_maxres_facade_temp, array('eager', 'soft', 'off')))
5078 {
5079 $_maxres_facade = $_maxres_facade_temp;
5080 }
5081 }
5082 catch (Exception $ex)
5083 {
5084
5085 }
5086 $new_options[self::$opt_maxres_facade] = $_maxres_facade;
5087
5088 $_restrict_wizard_roles = self::$dft_roles;
5089 try
5090 {
5091 $_restrict_wizard_roles = is_array($_POST[self::$opt_restrict_wizard_roles]) ? $_POST[self::$opt_restrict_wizard_roles] : $_restrict_wizard_roles;
5092 }
5093 catch (Exception $ex)
5094 {
5095
5096 }
5097 $new_options[self::$opt_restrict_wizard_roles] = $_restrict_wizard_roles;
5098
5099
5100 $_defaultwidth = '';
5101 try
5102 {
5103 $_defaultwidth = is_numeric(trim($_POST[self::$opt_defaultwidth])) ? intval(trim($_POST[self::$opt_defaultwidth])) : $_defaultwidth;
5104 }
5105 catch (Exception $ex)
5106 {
5107
5108 }
5109 $new_options[self::$opt_defaultwidth] = $_defaultwidth;
5110
5111 $_defaultheight = '';
5112 try
5113 {
5114 $_defaultheight = is_numeric(trim($_POST[self::$opt_defaultheight])) ? intval(trim($_POST[self::$opt_defaultheight])) : $_defaultheight;
5115 }
5116 catch (Exception $ex)
5117 {
5118
5119 }
5120 $new_options[self::$opt_defaultheight] = $_defaultheight;
5121
5122 $_responsive_all = 1;
5123 try
5124 {
5125 $_responsive_all = is_numeric(trim($_POST[self::$opt_responsive_all])) ? intval(trim($_POST[self::$opt_responsive_all])) : $_responsive_all;
5126 }
5127 catch (Exception $ex)
5128 {
5129
5130 }
5131 $new_options[self::$opt_responsive_all] = $_responsive_all;
5132
5133 $_vol = '';
5134 try
5135 {
5136 $_vol = is_numeric(trim($_POST[self::$opt_vol])) ? intval(trim($_POST[self::$opt_vol])) : $_vol;
5137 }
5138 catch (Exception $ex)
5139 {
5140
5141 }
5142 $new_options[self::$opt_vol] = $_vol;
5143
5144 $_gallery_pagesize = 15;
5145 try
5146 {
5147 $_gallery_pagesize = is_numeric(trim($_POST[self::$opt_gallery_pagesize])) ? intval(trim($_POST[self::$opt_gallery_pagesize])) : $_gallery_pagesize;
5148 }
5149 catch (Exception $ex)
5150 {
5151
5152 }
5153 $new_options[self::$opt_gallery_pagesize] = $_gallery_pagesize;
5154
5155
5156 $_gallery_columns = 3;
5157 try
5158 {
5159 $_gallery_columns = is_numeric(trim($_POST[self::$opt_gallery_columns])) ? intval(trim($_POST[self::$opt_gallery_columns])) : $_gallery_columns;
5160 }
5161 catch (Exception $ex)
5162 {
5163
5164 }
5165 $new_options[self::$opt_gallery_columns] = $_gallery_columns;
5166
5167
5168 $_gallery_collapse_grid_breaks = self::$dft_bpts;
5169 try
5170 {
5171 $_gallery_collapse_grid_breaks = is_array($_POST[self::$opt_gallery_collapse_grid_breaks]) ? $_POST[self::$opt_gallery_collapse_grid_breaks] : $_gallery_collapse_grid_breaks;
5172 }
5173 catch (Exception $ex)
5174 {
5175
5176 }
5177 $new_options[self::$opt_gallery_collapse_grid_breaks] = $_gallery_collapse_grid_breaks;
5178
5179
5180
5181 $_gallery_scrolloffset = 20;
5182 try
5183 {
5184 $_gallery_scrolloffset = is_numeric(trim($_POST[self::$opt_gallery_scrolloffset])) ? intval(trim($_POST[self::$opt_gallery_scrolloffset])) : $_gallery_scrolloffset;
5185 }
5186 catch (Exception $ex)
5187 {
5188
5189 }
5190 $new_options[self::$opt_gallery_scrolloffset] = $_gallery_scrolloffset;
5191
5192 $_gallery_channelsublink = '';
5193 try
5194 {
5195 $_gallery_channelsublink = trim(strip_tags($_POST[self::$opt_gallery_channelsublink]));
5196 $pieces = explode('?', $_gallery_channelsublink);
5197 $_gallery_channelsublink = trim($pieces[0]);
5198 }
5199 catch (Exception $ex)
5200 {
5201 $_gallery_channelsublink = '';
5202 }
5203 $new_options[self::$opt_gallery_channelsublink] = $_gallery_channelsublink;
5204
5205
5206 $_gallery_channelsubtext = '';
5207 try
5208 {
5209 $_gallery_channelsubtext = stripslashes(trim($_POST[self::$opt_gallery_channelsubtext]));
5210 }
5211 catch (Exception $ex)
5212 {
5213 $_gallery_channelsubtext = '';
5214 }
5215 $new_options[self::$opt_gallery_channelsubtext] = $_gallery_channelsubtext;
5216
5217
5218 $_gallery_custom_prev = 'Prev';
5219 try
5220 {
5221 $_gallery_custom_prev = trim(strip_tags($_POST[self::$opt_gallery_customprev]));
5222 }
5223 catch (Exception $ex)
5224 {
5225 $_gallery_custom_prev = 'Prev';
5226 }
5227 $new_options[self::$opt_gallery_customprev] = $_gallery_custom_prev;
5228
5229
5230 $_gallery_custom_next = 'Next';
5231 try
5232 {
5233 $_gallery_custom_next = trim(strip_tags($_POST[self::$opt_gallery_customnext]));
5234 }
5235 catch (Exception $ex)
5236 {
5237 $_gallery_custom_next = 'Next';
5238 }
5239 $new_options[self::$opt_gallery_customnext] = $_gallery_custom_next;
5240
5241
5242 $_not_live_content = '';
5243 try
5244 {
5245 $_not_live_content = wp_kses_post(stripslashes($_POST[self::$opt_not_live_content]));
5246 }
5247 catch (Exception $ex)
5248 {
5249 $_not_live_content = '';
5250 }
5251 $new_options[self::$opt_not_live_content] = $_not_live_content;
5252
5253
5254 $_apikey = '';
5255 try
5256 {
5257 $_apikey = trim(str_replace(array(' ', "'", '"'), array('', '', ''), strip_tags($_POST[self::$opt_apikey])));
5258 }
5259 catch (Exception $ex)
5260 {
5261 $_apikey = '';
5262 }
5263 $new_options[self::$opt_apikey] = $_apikey;
5264
5265
5266 $all = $new_options + $all;
5267
5268 update_option(self::$opt_alloptions, $all);
5269 return array(
5270 'type' => 'success',
5271 'message' => 'Changes were saved. <em>If you are using a separate caching plugin and you do not see your changes after saving, <strong class="orange">you need to reset your cache.</strong></em>'
5272 );
5273 }
5274
5275 public static function settings_save_ajax()
5276 {
5277 $result = array();
5278 if (check_ajax_referer('_epyt_save', '_epyt_nonce', false) && current_user_can('manage_options'))
5279 {
5280 $all = get_option(self::$opt_alloptions);
5281 $result = self::settings_save($all);
5282 }
5283 else
5284 {
5285 $result['type'] = 'error';
5286 $result['message'] = 'Sorry, there was a problem saving your settings.';
5287 }
5288 echo json_encode($result);
5289 die();
5290 }
5291
5292 public static function onboarding_save_valid(&$input)
5293 {
5294 $messages = array();
5295 try
5296 {
5297 $input[self::$opt_responsive] = intval($input[self::$opt_responsive]);
5298 $input[self::$opt_responsive_all] = intval($input[self::$opt_responsive_all]);
5299 $input[self::$opt_defer_js] = intval($input[self::$opt_defer_js]);
5300 $input[self::$opt_disablekb] = intval($input[self::$opt_disablekb]);
5301
5302 $input[self::$opt_gallery_pagesize] = intval($input[self::$opt_gallery_pagesize]);
5303 $input[self::$opt_gallery_columns] = intval($input[self::$opt_gallery_columns]);
5304 $input[self::$opt_not_live_content] = wp_kses_post(stripslashes($input[self::$opt_not_live_content]));
5305 $input[self::$opt_not_live_on] = intval($input[self::$opt_not_live_on]);
5306 $input[self::$opt_not_live_on_channel] = intval($input[self::$opt_not_live_on_channel]);
5307
5308 if (!in_array($input[self::$opt_ytapi_load], array('always', 'light', 'never')))
5309 {
5310 $input[self::$opt_ytapi_load] = 'light';
5311 }
5312 $input[self::$opt_facade_mode] = intval($input[self::$opt_facade_mode]);
5313 $input[self::$opt_facade_autoplay] = intval($input[self::$opt_facade_autoplay]);
5314 $input[self::$opt_gdpr_consent] = intval($input[self::$opt_gdpr_consent]);
5315 $input[self::$opt_gdpr_consent_message] = wp_kses_post(stripslashes($input[self::$opt_gdpr_consent_message]));
5316 $input[self::$opt_gdpr_consent_button] = wp_kses_post(stripslashes($input[self::$opt_gdpr_consent_button]));
5317 $input[self::$opt_nocookie] = intval($input[self::$opt_nocookie]);
5318 }
5319 catch (Exception $ex)
5320 {
5321 $messages[] = 'Please enter valid data.';
5322 }
5323
5324 if (empty($messages))
5325 {
5326 return true;
5327 }
5328 return $messages;
5329 }
5330
5331 public static function onboarding_save()
5332 {
5333 $result = array();
5334 $default = array(
5335 self::$opt_rel => 1,
5336 self::$opt_disablekb => 0,
5337 self::$opt_responsive => 0,
5338 self::$opt_responsive_all => 0,
5339 self::$opt_defer_js => 0,
5340 self::$opt_gallery_pagesize => 15,
5341 self::$opt_gallery_columns => 3,
5342 self::$opt_not_live_content => '',
5343 self::$opt_not_live_on => 0,
5344 self::$opt_not_live_on_channel => 0,
5345 self::$opt_ytapi_load => 'light',
5346 self::$opt_facade_mode => 0,
5347 self::$opt_facade_autoplay => 1,
5348 self::$opt_gdpr_consent => 0,
5349 self::$opt_gdpr_consent_message => self::$dft_gdpr_consent_message,
5350 self::$opt_gdpr_consent_button => 'Accept YouTube Content',
5351 self::$opt_nocookie => 0
5352 );
5353
5354
5355 $input = shortcode_atts($default, stripslashes_deep($_POST));
5356 $valid = self::onboarding_save_valid($input);
5357 if ($valid === true)
5358 {
5359 self::update_option_set($input);
5360 $result['type'] = 'success';
5361 }
5362 else
5363 {
5364 $result['type'] = 'error';
5365 $result['message'] = implode('<br/>', $valid);
5366 }
5367
5368 return $result;
5369 }
5370
5371 public static function onboarding_save_ajax()
5372 {
5373 $result = array();
5374 if (self::is_ajax() && self::ajax_referer() && current_user_can('manage_options'))
5375 {
5376 $result = self::onboarding_save();
5377 }
5378 else
5379 {
5380 $result['type'] = 'error';
5381 $result['message'] = 'Sorry, there was a problem saving the data.';
5382 }
5383 echo json_encode($result);
5384 die();
5385 }
5386
5387 public static function onboarding_save_apikey_valid(&$input)
5388 {
5389 $messages = array();
5390 try
5391 {
5392 $input[self::$opt_apikey] = trim(str_replace(array(' ', "'", '"'), array('', '', ''), strip_tags($input[self::$opt_apikey])));
5393 }
5394 catch (Exception $ex)
5395 {
5396 $messages[] = 'Please enter a valid API key.';
5397 }
5398
5399 if (empty($messages))
5400 {
5401 return true;
5402 }
5403 return $messages;
5404 }
5405
5406 public static function onboarding_save_apikey()
5407 {
5408 $result = array();
5409 $default = array(
5410 self::$opt_apikey => '',
5411 );
5412
5413 $input = shortcode_atts($default, stripslashes_deep($_POST));
5414 $valid = self::onboarding_save_apikey_valid($input);
5415 if ($valid === true)
5416 {
5417 self::update_option_set($input);
5418 $result['type'] = 'success';
5419 }
5420 else
5421 {
5422 $result['type'] = 'error';
5423 $result['message'] = implode('<br/>', $valid);
5424 }
5425
5426 return $result;
5427 }
5428
5429 public static function onboarding_save_apikey_ajax()
5430 {
5431 $result = array();
5432 if (self::is_ajax() && self::ajax_referer() && current_user_can('manage_options'))
5433 {
5434 $result = self::onboarding_save_apikey();
5435 }
5436 else
5437 {
5438 $result['type'] = 'error';
5439 $result['message'] = 'Sorry, there was a problem saving the data.';
5440 }
5441 echo json_encode($result);
5442 die();
5443 }
5444
5445 public static function ytprefs_show_onboarding()
5446 {
5447
5448 if (!current_user_can('manage_options'))
5449 {
5450 wp_die(__('You do not have sufficient permissions to access this page.'));
5451 }
5452 if (self::$double_plugin)
5453 {
5454 self::double_plugin_warning();
5455 }
5456 $all = get_option(self::$opt_alloptions);
5457
5458 $do_once = array(
5459 self::$opt_onboarded => 1
5460 );
5461 self::update_option_set($do_once);
5462 ?>
5463 <div class="wrap wrap-ytprefs-onboarding">
5464 <div class="ytprefs-ob-title">
5465 EmbedPlus for YouTube Setup Guide
5466 </div>
5467 <div class="relative">
5468 <div class="ytprefs-ob-step ytprefs-ob-step1 active-step">
5469 <div class="ytprefs-ob-content">
5470 <div class="ytprefs-ob-block">
5471 <p>
5472 With so many options available in this plugin, we created this easy setup guide to help you quickly learn about its <strong>most common settings and newest features</strong>. We hope it will get you embedding videos, galleries, and/or live streams sooner.
5473 </p>
5474 <p>
5475 You'll have an opportunity to see and set many other options after completing this setup guide.
5476 </p>
5477 </div>
5478 </div>
5479
5480 <div class="ytprefs-ob-content ytprefs-ob-content1">
5481 <h2>
5482 Below, check all that apply:<br><em>I'm interested in embedding...</em>
5483 </h2>
5484 <div class="ytprefs-hover-icons">
5485 <img class="yob-single-icon" src="<?php echo plugins_url('images/icon-player-single.png', __FILE__) ?>"/>
5486 <img class="yob-gallery-icon" src="<?php echo plugins_url('images/icon-playlist-gallery.png', __FILE__) ?>"/>
5487 <img class="yob-standalone-icon" src="<?php echo plugins_url('images/icon-playlist-self.png', __FILE__) ?>"/>
5488 <img class="yob-live-icon" src="<?php echo plugins_url('images/icon-player-live.png', __FILE__) ?>"/>
5489 <img class="yob-privacy-icon" src="<?php echo plugins_url('images/icon-player-privacy.png', __FILE__) ?>"/>
5490 <!-- <img class="yob-monetize-icon" src="<?php echo plugins_url('images/icon-player-money.png', __FILE__) ?>"/>-->
5491 </div>
5492 <ul class="ytprefs-ob-filter">
5493 <li><label><input type="checkbox" data-obfilter="yob-single" /> Single videos.</label></li>
5494 <li><label><input type="checkbox" data-obfilter="yob-gallery" /> Galleries of playlists or channels (displays thumbnails and a player).</label></li>
5495 <li><label><input type="checkbox" data-obfilter="yob-standalone" /> Self-contained playlists or channels (no thumbnails, just YouTube's standard playlist player).</label></li>
5496 <li><label><input type="checkbox" data-obfilter="yob-live" /> Live streams or premieres.</label></li>
5497 <li style="display:none;"><label><input type="checkbox" data-obfilter="yob-privacy" /> With GDPR / privacy features.</label></li>
5498 <!-- <li><label><input type="checkbox" data-obfilter="yob-monetize" /> Relevant video ads that earn me up to 10x higher CPMs (revenue) than display advertising.</label></li>-->
5499 </ul>
5500 <div class="ytprefs-ob-nav">
5501 <button type="button" class="button-secondary ytprefs-ob-nav-close">Cancel</button>
5502 <button type="button" disabled class="button-primary ytprefs-ob-nav-next">Next &raquo;</button>
5503 </div>
5504 <h2>
5505 Intro Video
5506 </h2>
5507 <p>
5508 Want a quick visual overview? Here's a preview of some of the free features of the plugin.
5509 </p>
5510 <div class="epyt-fitvid">
5511 <iframe allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/QDdvXBqfrzM?rel=0" allowfullscreen="" frameborder="0"></iframe>
5512 </div>
5513 <p>
5514 </p>
5515 </div>
5516 </div>
5517 <div class="ytprefs-ob-step ytprefs-ob-step2">
5518 <div class="ytprefs-ob-content">
5519 <h2>
5520 You're interested in:
5521 </h2>
5522
5523 <form id="form-onboarding">
5524 <input type="hidden" name="action" value="my_embedplus_onboarding_save_ajax"/>
5525
5526 <div class="ytprefs-ob-setting yob-single yob-gallery yob-standalone yob-live">
5527 <label>
5528 <b class="chktitle">Related Videos:</b>
5529 Show or hide related and recommended videos at the end of playback.
5530 <br>
5531 </label>
5532 <input type="radio" name="<?php echo self::$opt_rel; ?>" id="<?php echo self::$opt_rel; ?>-1" value="-1" <?php checked($all[self::$opt_rel], -1); ?>>
5533 <label for="<?php echo self::$opt_rel; ?>-1">Hide related videos at the end of playback</label> &nbsp;&nbsp;
5534 <input type="radio" name="<?php echo self::$opt_rel; ?>" id="<?php echo self::$opt_rel; ?>0" value="0" <?php checked($all[self::$opt_rel], 0); ?>>
5535 <label for="<?php echo self::$opt_rel; ?>0">Show related videos only from the video's channel</label> &nbsp;&nbsp;
5536 <input type="radio" name="<?php echo self::$opt_rel; ?>" id="<?php echo self::$opt_rel; ?>1" value="1" <?php checked($all[self::$opt_rel], 1); ?>>
5537 <label for="<?php echo self::$opt_rel; ?>1">Show related videos</label> &nbsp;&nbsp;
5538 </div>
5539 <div class="ytprefs-ob-setting yob-single yob-gallery yob-standalone">
5540 <input value="1" name="<?php echo self::$opt_facade_mode; ?>" id="<?php echo self::$opt_facade_mode; ?>" <?php checked($all[self::$opt_facade_mode], 1); ?> type="checkbox" class="checkbox">
5541 <label for="<?php echo self::$opt_facade_mode ?>">
5542 <b class="chktitle"><?php _e('Facade Mode:', 'youtube-embed-plus'); ?> <sup class="orange">new</sup></b>
5543 <?php _e('This improves performance by loading a lighter version of the player, until it is clicked. Then the real player loads (note: for live streams, the real player is always loaded). We have tested this feature in multiple cases and found it to successfully improve your Lighthouse performance score by addressing the following recommendation: "Some third-party resources can be lazy loaded with a facade."', 'youtube-embed-plus'); ?>
5544 <a href="https://www.youtube.com/watch?v=W7PKUjVBDNE" target="_blank"><?php _e('See an example of this feature at work.', 'youtube-embed-plus'); ?></a>
5545 </label>
5546 <div class="p box_facade_mode">
5547 <input value="1" name="<?php echo self::$opt_facade_autoplay; ?>" id="<?php echo self::$opt_facade_autoplay; ?>" type="checkbox" class="checkbox" <?php checked($all[self::$opt_facade_autoplay], 1); ?>>
5548 <label for="<?php echo self::$opt_facade_autoplay ?>">
5549 <b class="chktitle"><?php _e('Autoplay On Facade Click:', 'youtube-embed-plus'); ?></b>
5550 <span>
5551 <?php _e('After clicking once on the facade (aka light thumbnail), it is replaced with the real player. Check this option to have the real player play immediately, otherwise it will require an additional click. Note that checking this option will use YouTube\'s autoplay feature, which will not contribute toward play counts. If you\'re embedding videos from someone else\'s channel, we recommend checking this. If you\'re embedding videos that are from your channel, then you should self-evaluate the tradeoff involving play counts and additional clicking.', 'youtube-embed-plus'); ?>
5552 </span>
5553 </label>
5554 </div>
5555 </div>
5556 <div class="ytprefs-ob-setting yob-single yob-gallery yob-standalone yob-live">
5557 <input value="1" name="<?php echo self::$opt_responsive; ?>" id="<?php echo self::$opt_responsive; ?>" <?php checked($all[self::$opt_responsive], 1); ?> type="checkbox" class="checkbox">
5558 <label for="<?php echo self::$opt_responsive; ?>"><?php _e('<b class="chktitle">Responsive Video Sizing:</b> Make your videos responsive so that they dynamically fit in all screen sizes (smart phone, PC and tablet). NOTE: While this is checked, any custom hardcoded widths and heights you may have set will dynamically change too. <b>Do not check this if your theme already handles responsive video sizing.</b>') ?></label>
5559 <p id="boxresponsive_all" class="ytindent">
5560 <input type="radio" name="<?php echo self::$opt_responsive_all; ?>" id="<?php echo self::$opt_responsive_all; ?>1" value="1" <?php checked($all[self::$opt_responsive_all], 1); ?> >
5561 <label for="<?php echo self::$opt_responsive_all; ?>1">Responsive for all YouTube videos</label> &nbsp;&nbsp;
5562 <input type="radio" name="<?php echo self::$opt_responsive_all; ?>" id="<?php echo self::$opt_responsive_all; ?>0" value="0" <?php checked($all[self::$opt_responsive_all], 0); ?> >
5563 <label for="<?php echo self::$opt_responsive_all; ?>0">Responsive for only videos embedded via this plugin</label>
5564 </p>
5565 </div>
5566 <div class="ytprefs-ob-setting yob-gallery">
5567 <label for="<?php echo self::$opt_gallery_pagesize; ?>"><b class="chktitle">Default Gallery Page Size:</b></label>
5568 <select name="<?php echo self::$opt_gallery_pagesize; ?>" id="<?php echo self::$opt_gallery_pagesize; ?>" style="width: 60px;">
5569 <?php
5570 $gps_val = intval(trim($all[self::$opt_gallery_pagesize]));
5571 $gps_val = min($gps_val, 50);
5572 for ($gps = 1; $gps <= 50; $gps++)
5573 {
5574 ?><option <?php echo $gps_val == $gps ? 'selected' : '' ?> value="<?php echo $gps ?>"><?php echo $gps ?></option>
5575 <?php
5576 }
5577 ?>
5578 </select>
5579 Enter how many thumbnails per page should be shown at once (YouTube allows a maximum of 50 per page). You can later use the embedding wizard to customize this for specific galleries.
5580 </div>
5581
5582 <div class="ytprefs-ob-setting yob-gallery">
5583 <label for="<?php echo self::$opt_gallery_columns; ?>"><b class="chktitle">Default Gallery Number of Columns:</b></label>
5584 <input name="<?php echo self::$opt_gallery_columns; ?>" id="<?php echo self::$opt_gallery_columns; ?>" type="number" class="textinput" style="width: 60px;" value="<?php echo esc_attr(trim($all[self::$opt_gallery_columns])); ?>">
5585 Enter how many thumbnails can fit per row. You can later use the embedding wizard to customize this for specific galleries.
5586 </div>
5587 <div class="ytprefs-ob-setting yob-live">
5588 <p>
5589 <b class="chktitle">Use "Not Live" Fallback Content For Live Streams:</b> (<a href="<?php echo self::$epbase ?>/how-to-embed-a-youtube-livestream-in-wordpress.aspx" target="_blank">More info here</a>)
5590 This feature lets you display alternate content if your live stream is not currently active. This feature works for <strong>direct link</strong> live streams (more info about channel-based live streams below).
5591 </p>
5592 <div class="ytindent chx">
5593 <input value="1" name="<?php echo self::$opt_not_live_on; ?>" id="<?php echo self::$opt_not_live_on; ?>" <?php checked($all[self::$opt_not_live_on], 1); ?> type="checkbox" class="checkbox">
5594 <label for="<?php echo self::$opt_not_live_on; ?>"><span class="chktitle">Turn on for <b>direct link</b> live streams:</span>
5595 When your direct-link embed is not streaming live, the YouTube live player usually displays a countdown after the user clicks the play button.
5596 Instead of showing that player, you can display some "coming soon" content in that space for your visitors to see until your video begins to live stream.
5597 The plugin will automatically switch to your video's live stream once it's active. In the <em>"Not Live" Fallback Content</em> box below, enter what you would like to appear until then.
5598 You can even insert shortcodes from our plugin into the box below (shortcodes from other plugins may or may not work correctly).
5599 If you just want to show the standard countdown player that YouTube provides, don't use this feature.
5600 <strong>NOTE: Turning this on for direct-link live streams uses a significant amount of your YouTube API quota. We suggest unchecking it if your site has high traffic. If you chose to use this feature, do not put another live stream embed below.</strong>
5601 </label>
5602 <br>
5603 <br>
5604 <input disabled id="<?php echo self::$opt_not_live_on_channel; ?>" type="checkbox" class="checkbox">
5605 <label><span class="chktitle">Turn on for <b>channel</b> live streams (<span class="orange">upgrade required</span>) </span>
5606 Unfortunately, Google has recently removed their YouTube API feature that used to support channel-based live streams. It appears they won't change things back. However, you do have a couple of choices:
5607 <ol>
5608 <li>Use "Direct link" live streams, as explained above. The trade-off is that you will have to manually post and take down your future live streams every time they start and when they end, respectively.</li>
5609 <li>Or <a href="<?php echo self::$epbase ?>/dashboard/pro-easy-video-analytics.aspx" target="_blank">upgrade to Pro</a>, which has a solution that brings back all the "set it and forget it" features of channel-based embeds. We spent a significant amount of time developing a stable, long-term solution around YouTube's limitations, so we are releasing this effort exclusively to our Pro customers.</li>
5610 </ol>
5611 </label>
5612 <div class="p not-live-content">
5613 <p>
5614 <b>"Not Live" Fallback Content:</b>
5615 </p>
5616 <?php
5617 wp_editor(wp_kses_post($all[self::$opt_not_live_content]), self::$opt_not_live_content, array('textarea_rows' => 7));
5618 ?>
5619 </div>
5620 </div>
5621 </div>
5622
5623 <div class="ytprefs-ob-setting yob-privacy">
5624 <b class="chktitle">YouTube API Loading:</b> Choose when to load the YouTube API. The "Restricted" or "Never" options will help with GDPR compliance:
5625 <ul class="indent-option">
5626 <li><label><input type="radio" name="<?php echo self::$opt_ytapi_load ?>" value="light" <?php checked($all[self::$opt_ytapi_load], 'light'); ?> /> <em>Restricted</em> - (Recommended) Only load the API on pages that have a YouTube video.</label></li>
5627 <li><label><input type="radio" name="<?php echo self::$opt_ytapi_load ?>" value="never" <?php checked($all[self::$opt_ytapi_load], 'never'); ?> /> <em>Never</em> - Do not load the YouTube API. Note: The "Never" choice may break a few features such as Volume Initialization and Gallery Continuous/Auto Play.</label></li>
5628 <li><label><input type="radio" name="<?php echo self::$opt_ytapi_load ?>" value="always" <?php checked($all[self::$opt_ytapi_load], 'always'); ?> /> <em>Always</em> - Load the API on all pages. In most cases, the "Always" choice is not necessary.</label></li>
5629 </ul>
5630 </div>
5631
5632
5633 <div class="ytprefs-ob-setting yob-privacy">
5634 <input value="1" name="<?php echo self::$opt_gdpr_consent; ?>" id="<?php echo self::$opt_gdpr_consent; ?>" <?php checked($all[self::$opt_gdpr_consent], 1); ?> type="checkbox" class="checkbox">
5635 <label for="<?php echo self::$opt_gdpr_consent; ?>">
5636 <b class="chktitle">Privacy/GDPR - Show Consent Message:</b> Ask for consent before loading YouTube content. A message will be displayed in place of the YouTube video, as shown in the screenshot below. Once the visitor approves consent, the YouTube content will load. You can customize the message text and the button text in the next 2 options.
5637 </label>
5638 </div>
5639
5640
5641 <div class="ytprefs-ob-setting yob-privacy">
5642 <label for="<?php echo self::$opt_gdpr_consent_message; ?>">
5643 <b class="chktitle">Privacy/GDPR - Consent Message Text:</b>
5644 Below you can customize the message that will appear to visitors before they accept YouTube content:
5645 </label>
5646 <div class="clearboth"></div>
5647 <div class="gdpr-options-left">
5648 <?php
5649 wp_editor(wp_kses_post($all[self::$opt_gdpr_consent_message]), self::$opt_gdpr_consent_message, array(
5650 'textarea_rows' => 22,
5651 'media_buttons' => false,
5652 'teeny' => true
5653 ));
5654 ?>
5655 </div>
5656 <div class="gdpr-options-right">
5657 <p><em>Example of message and button:</em></p>
5658
5659 <img src="<?php echo plugins_url('images/ss-gdpr-message.png', __FILE__) ?>" alt="GDPR Consent Message Example" class="img-gdpr-message" />
5660 </div>
5661
5662 </div>
5663
5664 <div class="clearboth"></div>
5665 <div class="ytprefs-ob-setting yob-privacy">
5666 <label for="<?php echo self::$opt_gdpr_consent_button; ?>">
5667 <b class="chktitle">Privacy/GDPR - Consent Button Text:</b>
5668 This is the text for the red "Accept" button that appears with the above privacy/GDPR message:
5669 </label>
5670 <br>
5671 <input type="text" placeholder="Example: Accept YouTube Content" name="<?php echo self::$opt_gdpr_consent_button; ?>" id="<?php echo self::$opt_gdpr_consent_button; ?>" value="<?php echo esc_attr(trim($all[self::$opt_gdpr_consent_button])); ?>" class="textinput regular-text"/>
5672 </div>
5673
5674 <div class="ytprefs-ob-setting yob-privacy">
5675 <input value="1" name="<?php echo self::$opt_nocookie; ?>" id="<?php echo self::$opt_nocookie; ?>" <?php checked($all[self::$opt_nocookie], 1); ?> type="checkbox" class="checkbox">
5676 <label for="<?php echo self::$opt_nocookie; ?>">
5677 <b class="chktitle">No Cookies:</b> Prevent YouTube from leaving tracking cookies on your visitors browsers unless they actual play the videos. This is coded to apply this behavior on links in your past post as well.
5678 <span id="boxnocookie">
5679 Checking this option may introduce issues to features that depend YouTube's API, such as galleries and playlists. Furthermore, videos on mobile devices may have problems if you leave this checked. We suggest testing this out to make sure you are pleased with the results.
5680 </span>
5681 </label>
5682 </div>
5683
5684 <div class="ytprefs-ob-nav">
5685 <button type="button" class="button-secondary ytprefs-ob-nav-prev">&laquo; Previous</button>
5686 <button type="submit" class="button-primary ytprefs-ob-nav-next">Save & Next &raquo;</button>
5687 </div>
5688 </form>
5689 </div>
5690 </div>
5691 <div class="ytprefs-ob-step ytprefs-ob-step3">
5692 <div class="ytprefs-ob-content">
5693 <h2>
5694 YouTube API Key
5695 </h2>
5696 <form id="form-onboarding-apikey">
5697 <input type="hidden" name="action" value="my_embedplus_onboarding_save_apikey_ajax"/>
5698 <p>
5699 Some features (such as galleries, and some wizard features) now require you to create a free YouTube API key from Google.
5700 </p>
5701 <?php
5702 if (!empty($all[self::$opt_apikey]) && strlen($all[self::$opt_apikey]) > 0)
5703 {
5704 ?>
5705 <p class="ytprefs-ob-success">
5706 Great! You already have an API key.
5707 </p>
5708 <?php
5709 }
5710 else
5711 {
5712 ?>
5713 <p>
5714 The instructions for this are very specific, so we created a video for you that's hopefully easy to follow: <a href="https://www.embedplus.com/how-to-create-a-youtube-api-key.aspx" target="_blank">Click this link</a> and follow the steps on the page. Then save your API key here.
5715 </p>
5716 <?php
5717 }
5718 ?>
5719 <p>
5720 <input type="text" placeholder="Paste your YouTube API key here" name="<?php echo self::$opt_apikey; ?>" id="<?php echo self::$opt_apikey; ?>" value="<?php echo esc_attr(trim($all[self::$opt_apikey])); ?>" class="regular-text" style='max-width: 40%;'>
5721 </p>
5722
5723 <div class="ytprefs-ob-nav">
5724 <div class="ytprefs-ob-nav-ultimate">
5725 <button type="button" class="button-secondary ytprefs-ob-nav-prev">&laquo; Previous</button>
5726 <button type="button" class="button-secondary ytprefs-ob-nav-close">I'll do this later.</button>
5727 <button type="submit" class="button-primary ytprefs-ob-nav-next">Save & Finish</button>
5728 </div>
5729 <div class="ytprefs-ob-nav-penultimate ytprefs-ob-nav-hide">
5730 <button type="button" class="button-secondary ytprefs-ob-nav-prev">&laquo; Previous</button>
5731 <button type="button" class="button-secondary ytprefs-ob-nav-skip">I'll do this later &raquo;</button>
5732 <button type="submit" class="button-primary ytprefs-ob-nav-next">Save & Next &raquo;</button>
5733 </div>
5734 </div>
5735 </form>
5736 </div>
5737 </div>
5738 <div class="ytprefs-ob-step ytprefs-ob-step4">
5739 <div class="ytprefs-ob-content">
5740 <div class="ytprefs-ob-nav">
5741 <button type="button" class="button-secondary ytprefs-ob-nav-prev">&laquo; Previous</button>
5742 <button type="button" class="button-primary ytprefs-ob-nav-close">Finish</button>
5743 </div>
5744 </div>
5745 </div>
5746
5747 </div>
5748 </div>
5749 <?php
5750 }
5751
5752 public static function save_changes_button($submitted)
5753 {
5754 $button_label = 'Save Changes';
5755 if ($submitted)
5756 {
5757 $button_label = 'Changes Saved';
5758 ?>
5759 <script type="text/javascript">
5760 jQuery(document).ready(function ()
5761 {
5762 setTimeout(function ()
5763 {
5764 jQuery('.ytprefs-submit').text('Save Changes');
5765 }, 3000);
5766 });</script>
5767 <?php
5768 }
5769 ?>
5770 <p class="submit">
5771 <button type="submit" name="Submit" class="button-primary ytprefs-submit"><?php _e($button_label) ?></button>
5772 <em>If you're using a separate caching plugin and you do not see your changes after saving, <strong class="orange">you need to reset your cache.</strong></em>
5773 </p>
5774 <?php
5775 }
5776
5777 public static function ytprefsscript()
5778 {
5779 $loggedin = current_user_can('edit_posts');
5780 if (!($loggedin && self::$alloptions[self::$opt_admin_off_scripts]))
5781 {
5782 wp_enqueue_style(
5783 '__EPYT__style', plugins_url('styles/ytprefs' . self::$min . '.css', __FILE__), array(), self::$version
5784 );
5785 $cols = floatval(self::$alloptions[self::$opt_gallery_columns]);
5786 $cols = $cols == 0 ? 3.0 : $cols;
5787 $colwidth = 100.0 / $cols;
5788 $custom_css = "
5789 .epyt-gallery-thumb {
5790 width: " . round($colwidth, 3) . "%;
5791 }
5792 ";
5793
5794 if (self::$alloptions[self::$opt_gallery_collapse_grid] == 1)
5795 {
5796 foreach (self::$alloptions[self::$opt_gallery_collapse_grid_breaks] as $idx => $bpts)
5797 {
5798 $custom_css .= "
5799 @media (min-width:" . $bpts['bp']['min'] . "px) and (max-width: " . $bpts['bp']['max'] . "px) {
5800 .epyt-gallery-rowbreak {
5801 display: none;
5802 }
5803 .epyt-gallery-allthumbs[class*=\"epyt-cols\"] .epyt-gallery-thumb {
5804 width: " . round(100.0 / intval($bpts['cols']), 3) . "% !important;
5805 }
5806 }";
5807 }
5808 }
5809
5810 wp_add_inline_style('__EPYT__style', $custom_css);
5811
5812 wp_enqueue_script('__ytprefs__', plugins_url('scripts/ytprefs' . self::$min . '.js', __FILE__), array('jquery'), self::$version);
5813
5814 if (self::$alloptions[self::$opt_old_script_method] != 1)
5815 {
5816 $my_script_vars = array(
5817 'ajaxurl' => admin_url('admin-ajax.php'),
5818 'security' => wp_create_nonce('embedplus-nonce'),
5819 'gallery_scrolloffset' => intval(self::$alloptions[self::$opt_gallery_scrolloffset]),
5820 'eppathtoscripts' => plugins_url('scripts/', __FILE__),
5821 'eppath' => plugins_url('/', __FILE__),
5822 'epresponsiveselector' => self::get_responsiveselector(),
5823 'epdovol' => true,
5824 'version' => self::$alloptions[self::$opt_version],
5825 'evselector' => self::get_evselector(),
5826 'ajax_compat' => self::$alloptions[self::$opt_ajax_compat] == '1' ? true : false,
5827 'maxres_facade' => esc_attr(self::$alloptions[self::$opt_maxres_facade]),
5828 'ytapi_load' => self::$alloptions[self::$opt_ytapi_load],
5829 'pause_others' => self::$alloptions[self::$opt_pause_others] == '1' ? true : false,
5830 'stopMobileBuffer' => self::$alloptions[self::$opt_stop_mobile_buffer] == '1' ? true : false,
5831 'facade_mode' => self::$alloptions[self::$opt_facade_mode] == '1' ? true : false,
5832 'not_live_on_channel' => self::$alloptions[self::$opt_not_live_on_channel] == '1' ? true : false
5833 );
5834
5835 wp_localize_script('__ytprefs__', '_EPYT_', $my_script_vars);
5836 }
5837
5838 if ((bool) self::$alloptions[self::$opt_gdpr_consent])
5839 {
5840 wp_enqueue_script('__jquery_cookie__', plugins_url('scripts/jquery.cookie' . self::$min . '.js', __FILE__), array('jquery'), self::$version);
5841 }
5842
5843
5844 ////////////////////// cloudflare accomodation
5845 //add_filter('script_loader_tag', array(self::class, 'set_cfasync'), 10, 3);
5846 }
5847 }
5848
5849 public static function set_cfasync($tag, $handle, $src)
5850 {
5851 if ('__ytprefs__' !== $handle)
5852 {
5853 return $tag;
5854 }
5855 return str_replace('<script', '<script data-cfasync="false" ', $tag);
5856 }
5857
5858 public static function get_evselector()
5859 {
5860 $evselector = 'iframe.__youtube_prefs__[src], iframe[src*="youtube.com/embed/"], iframe[src*="youtube-nocookie.com/embed/"]';
5861
5862 if (self::$alloptions[self::$opt_evselector_light] == 1)
5863 {
5864 $evselector = 'iframe.__youtube_prefs__[src]';
5865 }
5866
5867 return $evselector;
5868 }
5869
5870 public static function get_responsiveselector()
5871 {
5872 $responsiveselector = '[]';
5873 if (self::$alloptions[self::$opt_widgetfit] == 1)
5874 {
5875 $responsiveselector = '["iframe.__youtube_prefs_widget__"]';
5876 }
5877 if (self::$alloptions[self::$opt_responsive] == 1)
5878 {
5879 if (self::$alloptions[self::$opt_responsive_all] == 1)
5880 {
5881 $responsiveselector = '["iframe.__youtube_prefs__","iframe[src*=\'youtube.com\']","iframe[src*=\'youtube-nocookie.com\']","iframe[data-ep-src*=\'youtube.com\']","iframe[data-ep-src*=\'youtube-nocookie.com\']","iframe[data-ep-gallerysrc*=\'youtube.com\']"]';
5882 }
5883 else
5884 {
5885 $responsiveselector = '["iframe.__youtube_prefs__"]';
5886 }
5887 }
5888 return $responsiveselector;
5889 }
5890
5891 public static function admin_enqueue_scripts($hook)
5892 {
5893 if (in_array($hook, self::$admin_page_hooks))
5894 {
5895 wp_enqueue_style('__ytprefs_admin__alertify_css', plugins_url('styles/alertify/alertify' . self::$min . '.css', __FILE__), array(), self::$version);
5896 wp_enqueue_style('__ytprefs_admin__alertify_theme_css', plugins_url('styles/alertify/themes/default' . self::$min . '.css', __FILE__), array(), self::$version);
5897 wp_enqueue_script('__ytprefs_admin__alertify_js', plugins_url('scripts/alertify/alertify' . self::$min . '.js', __FILE__), array(), self::$version);
5898 wp_enqueue_script('__ytprefs_admin__alertify_defaults_js', plugins_url('scripts/alertify/alertify-defaults' . self::$min . '.js', __FILE__), array(), self::$version);
5899 }
5900
5901 wp_enqueue_style('embedplusyoutube', plugins_url('scripts/embedplus_mce' . self::$min . '.css', __FILE__), array(), self::$version);
5902 wp_enqueue_script('__ytprefs_admin__', plugins_url('scripts/ytprefs-admin' . self::$min . '.js', __FILE__), array('jquery', 'jquery-effects-fade'), self::$version, false);
5903 $admin_script_vars = array(
5904 'wpajaxurl' => admin_url('admin-ajax.php'),
5905 'wizhref' => admin_url('admin.php?page=youtube-ep-wizard') . '&random=' . rand(1, 1000) . '&TB_iframe=true&width=950&height=800',
5906 'manage_options' => current_user_can('manage_options'),
5907 'security' => wp_create_nonce('embedplus-nonce'),
5908 'onboarded' => self::$alloptions[self::$opt_onboarded],
5909 'epbase' => self::$epbase,
5910 'admin_url' => admin_url(),
5911 'admin_url_ytprefs' => admin_url('admin.php?page=youtube-my-preferences'),
5912 //'epblogwidth' => self::get_blogwidth(),
5913 //'epprokey' => self::$alloptions[self::$opt_pro],
5914 //'epbasesite' => self::$epbase,
5915 //'epversion' => self::$version,
5916 //'myytdefaults' => http_build_query(self::$alloptions),
5917 //'eppluginadminurl' => admin_url('admin.php?page=youtube-my-preferences')
5918 );
5919 wp_localize_script('__ytprefs_admin__', '_EPYTA_', $admin_script_vars);
5920
5921 if (function_exists('add_thickbox'))
5922 {
5923 add_thickbox();
5924 }
5925
5926
5927 if ((get_bloginfo('version') >= '3.3') && self::custom_admin_pointers_check())
5928 {
5929 add_action('admin_print_footer_scripts', array(self::class, 'custom_admin_pointers_footer'));
5930 wp_enqueue_script('wp-pointer');
5931 wp_enqueue_style('wp-pointer');
5932 }
5933
5934 if (self::$alloptions['glance'] == 1)
5935 {
5936 add_action('admin_print_footer_scripts', array(self::class, 'glance_script'));
5937 }
5938
5939 if ($hook == self::$wizard_hook)
5940 {
5941 wp_enqueue_style('__ytprefs_admin__wizard_ui', plugins_url('styles/jquery-ui' . self::$min . '.css', __FILE__), array(), self::$version);
5942 wp_enqueue_style('__ytprefs_admin__wizard', plugins_url('styles/ytprefs-wizard' . self::$min . '.css', __FILE__), array(), self::$version);
5943 wp_enqueue_script('__ytprefs_admin__wizard_script', plugins_url('scripts/ytprefs-wizard' . self::$min . '.js', __FILE__), array('jquery', 'jquery-ui-accordion', 'jquery-ui-tabs'), self::$version);
5944 }
5945
5946 if ($hook == self::$onboarding_hook)
5947 {
5948 wp_enqueue_style('__ytprefs_admin__onboarding_animate', plugins_url('scripts/embdyn' . self::$min . '.css', __FILE__), array(), self::$version);
5949 wp_enqueue_style('__ytprefs_admin__onboarding_ui', plugins_url('styles/jquery-ui' . self::$min . '.css', __FILE__), array(), self::$version);
5950 wp_enqueue_style('__ytprefs_admin__onboarding', plugins_url('styles/ytprefs-onboarding' . self::$min . '.css', __FILE__), array(), self::$version);
5951 }
5952 }
5953
5954 public static function get_blogwidth()
5955 {
5956 $blogwidth = null;
5957 try
5958 {
5959 $embed_size_w = intval(get_option('embed_size_w'));
5960
5961 global $content_width;
5962 if (empty($content_width))
5963 {
5964 $content_width = $GLOBALS['content_width'];
5965 }
5966
5967 $blogwidth = $embed_size_w ? $embed_size_w : ($content_width ? $content_width : 450);
5968 }
5969 catch (Exception $ex)
5970 {
5971
5972 }
5973
5974 $blogwidth = preg_replace('/\D/', '', $blogwidth); //may have px
5975
5976 return $blogwidth;
5977 }
5978
5979 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5980 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5981 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5982
5983 private static function ajax_referer()
5984 {
5985 return check_ajax_referer('embedplus-nonce', 'security', false);
5986 }
5987
5988 public static function base_url()
5989 {
5990 $parsed = parse_url(site_url());
5991 return $parsed['scheme'] . '://' . $parsed['host'];
5992 }
5993
5994 public static function on_deactivation()
5995 {
5996 }
5997
5998 private static function update_option_set($new_options)
5999 {
6000 $all = get_option(self::$opt_alloptions);
6001 $all = $new_options + $all;
6002 update_option(self::$opt_alloptions, $all);
6003 self::$alloptions = get_option(self::$opt_alloptions);
6004 }
6005
6006 public static function gb_block_assets()
6007 {
6008 // frontend+backend styles.
6009 wp_enqueue_style('epytgb-style-css', plugins_url('dist/blocks.style.build.css', __FILE__), array('wp-blocks'), self::$version);
6010 }
6011
6012 public static function gb_editor_assets()
6013 {
6014 // backend styels
6015 self::ytprefsscript();
6016 self::fitvids();
6017 if (!empty(self::$alloptions[self::$opt_not_live_on_channel]))
6018 {
6019 add_action("admin_print_footer_scripts", array(self::class, 'live_fallback_template'));
6020 }
6021
6022 if (!self::is_restrict_wizard() && current_user_can('edit_posts'))
6023 {
6024 // Scripts.
6025 wp_enqueue_script(
6026 'epytgb-block-js', // Handle.
6027 plugins_url('/dist/blocks.build.js', __FILE__), // Block.build.js: We register the block here. Built with Webpack.
6028 array('wp-blocks', 'wp-i18n', 'wp-element'), // Dependencies, defined above.
6029 self::$version, true // Enqueue the script in the footer.
6030 );
6031
6032 // Styles.
6033 wp_enqueue_style(
6034 'epytgb-block-editor-css', // Handle.
6035 plugins_url('dist/blocks.editor.build.css', __FILE__), // Block editor CSS.
6036 array('wp-edit-blocks'), // Dependency to include the CSS after it.
6037 self::$version
6038 );
6039
6040 // Tiny MCE
6041 wp_enqueue_style('__ytprefs_admin__tinymce_css', plugins_url('styles/epyt_mce_wizard_button' . self::$min . '.css', __FILE__), array(), self::$version);
6042 }
6043 }
6044
6045 public static function gb_classic_block_setup()
6046 {
6047 if (!self::is_restrict_wizard() && current_user_can('edit_posts'))
6048 {
6049 add_thickbox();
6050 add_filter("mce_external_plugins", array(self::class, "gb_add_tinymce_plugin"));
6051 add_filter('mce_buttons_2', array(self::class, 'gb_register_tinymce_button'));
6052 }
6053 }
6054
6055 public static function gb_add_tinymce_plugin($plugin_array)
6056 {
6057 $plugin_array['epyt_mce_wizard_button'] = plugins_url('scripts/epyt_mce_wizard_button' . self::$min . '.js', __FILE__) . '?ver=' . self::$version;
6058 return $plugin_array;
6059 }
6060
6061 public static function gb_register_tinymce_button($buttons)
6062 {
6063 array_push($buttons, "epyt_mce_wizard_button");
6064 return $buttons;
6065 }
6066
6067 public static function gb_svg_defs()
6068 {
6069 ?>
6070 <svg style="height: 0 !important; width: 0 !important; display: absolute !important; top: 0 !important; left: 0 !important;"><defs><style>.epytcls-1{fill:red;}.epytcls-2{fill-rule:evenodd;fill:url(#radial-gradient);}.epytcls-3{fill:#31aaff;}.epytcls-4{fill:#fff;}</style><radialGradient id="radial-gradient" cx="193" cy="85.85" r="77.53" gradientUnits="userSpaceOnUse"><stop offset="0.17" stop-color="#fff"/><stop offset="0.68" stop-color="#31aaff"/></radialGradient></defs></svg>
6071 <?php
6072 }
6073
6074 public static function gb_canvas_svg_styles()
6075 {
6076 // The block editor canvas is an iframe, so the gradient and class rules that
6077 // gb_svg_defs() prints into the admin document are out of scope for the icon
6078 // rendered inside it. Restate them for the canvas only.
6079 if (!is_admin())
6080 {
6081 return;
6082 }
6083
6084 wp_register_style('epytgb-canvas-svg-css', false, array(), self::$version);
6085 wp_enqueue_style('epytgb-canvas-svg-css');
6086 wp_add_inline_style('epytgb-canvas-svg-css', '.editor-styles-wrapper .epytcls-1{fill:red;}.editor-styles-wrapper .epytcls-2{fill-rule:evenodd;fill:#31aaff;}.editor-styles-wrapper .epytcls-3{fill:#31aaff;}.editor-styles-wrapper .epytcls-4{fill:#fff;}');
6087 }
6088
6089 public static function gb_register_block_types()
6090 {
6091 if (function_exists('register_block_type'))
6092 {
6093 register_block_type(
6094 'epyt/youtube', array(
6095 'attributes' => array(
6096 'shortcode' => array(
6097 'type' => 'string'
6098 )
6099 ),
6100 'render_callback' => array(self::class, 'gb_render_callback_youtube'),
6101 )
6102 );
6103 }
6104 }
6105
6106 public static function gb_render_callback_youtube($attributes, $content)
6107 {
6108 if ($attributes && $attributes['shortcode'] && strpos($attributes['shortcode'], '[') === 0)
6109 {
6110 $render = do_shortcode($attributes['shortcode']);
6111 if (empty($render) && stripos($attributes['shortcode'], 'live=1') !== false)
6112 {
6113 $render = '<em>This is a live embed that is not currently streaming. You can optionally fill out the <a href="' . admin_url('admin.php?page=youtube-my-preferences') . '#not_live_content_scroll" target="_blank">Not Live Content</a> field in the YouTube plugin\'s Default Settings.</em>';
6114 }
6115 return $render;
6116 }
6117 return isset($attributes['shortcode']) ? $attributes['shortcode'] : '';
6118 }
6119
6120 }
6121
6122 // constants
6123 define('EPYT_BASE_URL', rtrim(plugins_url('', __FILE__), "\\/") . '/');
6124 define('EPYTGB_INCLUDES_PATH', rtrim(dirname(__FILE__), "\\/") . '/includes/gutenberg/');
6125
6126 $youtubeplgplus = new YouTubePrefs();
6127
6128
6129
6130
6131