PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.4.10
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.4.10
4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / Includes / Classes / Feature_Enhancer.php
embedpress / EmbedPress / Includes / Classes Last commit date
Analytics 7 months ago Database 5 months ago Elementor_Enhancer.php 6 months ago EmbedPress_Core_Installer.php 6 years ago EmbedPress_Notice.php 2 years ago EmbedPress_Plugin_Usage_Tracker.php 1 year ago Extend_CustomPlayer_Controls.php 1 year ago Extend_Elementor_Controls.php 1 year ago FeatureNoticeManager.php 8 months ago FeatureNotices.php 8 months ago Feature_Enhancer.php 6 months ago Helper.php 5 months ago PermalinkHelper.php 10 months ago README_FEATURE_NOTICES.md 8 months ago
Feature_Enhancer.php
1731 lines
1 <?php
2
3 namespace EmbedPress\Includes\Classes;
4
5 use \EmbedPress\Providers\Youtube;
6 use EmbedPress\Shortcode;
7 use EmbedPress\Includes\Classes\Helper;
8 use \Elementor\Controls_Manager;
9 use EmbedPress\Providers\TemplateLayouts\YoutubeLayout;
10 use EmbedPress\Providers\TikTok;
11 use EmbedPress\Providers\Spreaker;
12 use EmbedPress\Providers\Wrapper;
13 use EmbedPress\Providers\GooglePhotos;
14
15 class Feature_Enhancer
16 {
17 public static $attributes_data;
18
19 public function __construct()
20 {
21 add_filter('embedpress:onAfterEmbed', [$this, 'enhance_youtube'], 90);
22 add_filter('embedpress:onAfterEmbed', [$this, 'enhance_vimeo'], 90);
23 // add_filter('embedpress:onAfterEmbed', [$this, 'enhance_wistia'], 90);
24 add_filter('embedpress:onAfterEmbed', [$this, 'enhance_twitch'], 90);
25 add_filter('embedpress:onAfterEmbed', [$this, 'enhance_dailymotion'], 90);
26 add_filter('embedpress:onAfterEmbed', [$this, 'enhance_soundcloud'], 90);
27 add_filter('embedpress:onAfterEmbed', [$this, 'enhance_missing_title'], 90);
28
29 add_filter(
30 'embedpress_gutenberg_youtube_params',
31 [$this, 'embedpress_gutenberg_register_block_youtube']
32 );
33
34 add_action('init', array($this, 'embedpress_gutenberg_register_block_vimeo'));
35 add_action('embedpress_gutenberg_wistia_block_after_embed', array($this, 'embedpress_wistia_block_after_embed'));
36 add_action('elementor/widget/embedpres_elementor/skins_init', [$this, 'elementor_setting_init']);
37 add_action('wp_ajax_youtube_rest_api', [$this, 'youtube_rest_api']);
38 add_action('wp_ajax_nopriv_youtube_rest_api', [$this, 'youtube_rest_api']);
39 add_action('embedpress_gutenberg_embed', [$this, 'gutenberg_embed'], 10, 2);
40 add_action('wp_ajax_save_source_data', [$this, 'save_source_data']);
41 add_action('save_post', [$this, 'save_source_data_on_post_update'], 10, 3);
42 add_action('wp_ajax_delete_source_data', [$this, 'delete_source_data']);
43 add_action('load-post.php', [$this, 'delete_source_temp_data_on_reload']);
44 add_action('embedpress:isEmbra', [$this, 'isEmbra'], 10, 3);
45 add_action('elementor/editor/after_save', [$this, 'save_el_source_data_on_post_update']);
46
47 add_action('wp_head', [$this, 'embedpress_generate_social_share_meta']);
48
49 add_action('wp_ajax_get_viewer', function () {
50 $pdf = EMBEDPRESS_PATH_BASE . 'assets/pdf/web/viewer.html';
51 // header type html
52 header('Content-Type: text/html');
53 $contents = file_get_contents($pdf);
54 echo str_replace('<head>', '<head><base href="' . EMBEDPRESS_URL_ASSETS. 'pdf/web/' . '">', $contents);
55 die;
56 });
57 add_action('wp_ajax_nopriv_get_viewer', function () {
58 $pdf = EMBEDPRESS_PATH_BASE . 'assets/pdf/web/viewer.html';
59 // header type html
60 header('Content-Type: text/html');
61 $contents = file_get_contents($pdf);
62 echo str_replace('<head>', '<head><base href="' . EMBEDPRESS_URL_ASSETS. 'pdf/web/' . '">', $contents);
63 die;
64 });
65
66 add_action('wp_ajax_get_flipbook_viewer', function () {
67 $pdf = EMBEDPRESS_PATH_BASE . 'assets/pdf-flip-book/viewer.html';
68 // header type html
69 header('Content-Type: text/html');
70 $contents = file_get_contents($pdf);
71 $contents = str_replace('<head>', '<head><base href="' . EMBEDPRESS_URL_ASSETS . 'pdf-flip-book/' . '">', $contents);
72 $contents = str_replace('templates/book-view.html', admin_url('admin-ajax.php?action=get_flipbook_template'), $contents);
73 echo $contents;
74 die;
75 });
76 add_action('wp_ajax_nopriv_get_flipbook_viewer', function () {
77 $pdf = EMBEDPRESS_PATH_BASE . 'assets/pdf-flip-book/viewer.html';
78 // header type html
79 header('Content-Type: text/html');
80 $contents = file_get_contents($pdf);
81 $contents = str_replace('<head>', '<head><base href="' . EMBEDPRESS_URL_ASSETS . 'pdf-flip-book/' . '">', $contents);
82 $contents = str_replace('templates/book-view.html', admin_url('admin-ajax.php?action=get_flipbook_template'), $contents);
83 echo $contents;
84 die;
85 });
86
87 add_action('wp_ajax_get_flipbook_template', function () {
88 $template = EMBEDPRESS_PATH_BASE . 'assets/pdf-flip-book/templates/book-view.html';
89 header('Content-Type: text/html');
90 echo file_get_contents($template);
91 die;
92 });
93 add_action('wp_ajax_nopriv_get_flipbook_template', function () {
94 $template = EMBEDPRESS_PATH_BASE . 'assets/pdf-flip-book/templates/book-view.html';
95 header('Content-Type: text/html');
96 echo file_get_contents($template);
97 die;
98 });
99 }
100
101 public function save_source_data()
102 {
103 if (!isset($_POST['_source_nonce']) || !wp_verify_nonce($_POST['_source_nonce'], 'source_nonce_embedpress')) {
104 return;
105 }
106
107 if (!current_user_can('manage_options')) {
108 return;
109 }
110
111 $source_url = isset($_POST['source_url']) ? $_POST['source_url'] : null;
112 $blockid = isset($_POST['block_id']) ? $_POST['block_id'] : null;
113
114
115 Helper::get_source_data($blockid, $source_url, 'gutenberg_source_data', 'gutenberg_temp_source_data');
116 }
117
118 function save_el_source_data_on_post_update($post_id)
119 {
120 Helper::get_save_source_data_on_post_update('elementor_source_data', 'elementor_temp_source_data');
121 }
122
123 function save_source_data_on_post_update($post_id, $post, $update)
124 {
125 if (!empty(strpos($post->post_content, 'wp:embedpress'))) {
126 Helper::get_save_source_data_on_post_update('gutenberg_source_data', 'gutenberg_temp_source_data');
127 }
128 }
129
130 public function delete_source_data()
131 {
132 if (!isset($_POST['_source_nonce']) || !wp_verify_nonce($_POST['_source_nonce'], 'source_nonce_embedpress')) {
133 return;
134 }
135 if (!current_user_can('manage_options')) {
136 return;
137 }
138
139 $blockid = isset($_POST['block_id']) ? $_POST['block_id'] : '';
140
141 Helper::get_delete_source_data($blockid, 'gutenberg_source_data', 'gutenberg_temp_source_data');
142 }
143
144 public function delete_source_temp_data_on_reload()
145 {
146 Helper::get_delete_source_temp_data_on_reload('gutenberg_temp_source_data');
147 }
148
149 public function isEmbra($isEmbra, $url, $atts)
150 {
151
152 if (strpos($url, 'youtube.com') !== false) {
153 $youtube = new Youtube($url, $atts);
154 if ($youtube->validateUrl($youtube->getUrl(false))) {
155 return true;
156 }
157 }
158 if (strpos($url, 'tiktok.com') !== false) {
159 $tiktok = new TikTok($url, $atts);
160 if ($tiktok->validateUrl($tiktok->getUrl(false))) {
161 return true;
162 }
163 }
164 if (strpos($url, 'spreaker.com') !== false) {
165 $spreaker = new Spreaker($url, $atts);
166 if ($spreaker->validateUrl($spreaker->getUrl(false))) {
167 return true;
168 }
169 }
170
171
172 if (strpos($url, 'photos.app.goo.gl') !== false) {
173 $google_photos = new GooglePhotos($url, $atts);
174
175 if ($google_photos->validateUrl($google_photos->getUrl(false))) {
176 return true;
177 }
178 }
179
180 if (strpos($url, site_url()) !== false) {
181 $wrapper = new Wrapper($url, $atts);
182 if ($wrapper->validateUrl($wrapper->getUrl(false))) {
183 return true;
184 }
185 }
186
187 return $isEmbra;
188 }
189
190 // public function youtube_rest_api()
191 // {
192 // // Instantiate the class
193 // $youtube = new Youtube($config = '');
194
195
196 // // Call the non-static method
197 // // $result = $youtube->someMethod();
198
199 // $result = YoutubeLayout::create_youtube_layout([
200 // 'playlistId' => isset($_POST['playlistid']) ? sanitize_text_field($_POST['playlistid']) : null,
201 // 'pageToken' => isset($_POST['pagetoken']) ? sanitize_text_field($_POST['pagetoken']) : null,
202 // 'ytChannelLayout' => isset($_POST['ytChannelLayout']) ? sanitize_text_field($_POST['ytChannelLayout']) : 'gallery',
203 // 'pagesize' => isset($_POST['pagesize']) ? sanitize_text_field($_POST['pagesize']) : null,
204 // 'currentpage' => isset($_POST['currentpage']) ? sanitize_text_field($_POST['currentpage']) : null,
205 // 'columns' => isset($_POST['epcolumns']) ? sanitize_text_field($_POST['epcolumns']) : null,
206 // 'showTitle' => isset($_POST['showtitle']) ? sanitize_text_field($_POST['showtitle']) : null,
207 // 'showPaging' => isset($_POST['showpaging']) ? sanitize_text_field($_POST['showpaging']) : null,
208 // 'autonext' => isset($_POST['autonext']) ? sanitize_text_field($_POST['autonext']) : null,
209 // 'thumbplay' => isset($_POST['thumbplay']) ? sanitize_text_field($_POST['thumbplay']) : null,
210 // 'thumbnail_quality' => isset($_POST['thumbnail_quality']) ? sanitize_text_field($_POST['thumbnail_quality']) : null,
211 // ], $youtube->layout_data(), $youtube->get_layout());
212
213 // // print_r($youtube->layout_data()); die;
214
215 // wp_send_json($result);
216 // }
217
218 public function youtube_rest_api()
219 {
220 // Instantiate the class
221 $youtube = new Youtube($config = '');
222
223 // echo '<pre>';
224
225 // print_r($_POST);
226
227 $result = $youtube->get_gallery_page([
228 'playlistId' => isset($_POST['playlistid']) ? sanitize_text_field($_POST['playlistid']) : null,
229 'pageToken' => isset($_POST['pagetoken']) ? sanitize_text_field($_POST['pagetoken']) : null,
230 'pagesize' => isset($_POST['pagesize']) ? sanitize_text_field($_POST['pagesize']) : null,
231 'currentpage' => isset($_POST['currentpage']) ? sanitize_text_field($_POST['currentpage']) : null,
232 'columns' => isset($_POST['epcolumns']) ? sanitize_text_field($_POST['epcolumns']) : null,
233 'showTitle' => isset($_POST['showtitle']) ? sanitize_text_field($_POST['showtitle']) : null,
234 'showPaging' => isset($_POST['showpaging']) ? sanitize_text_field($_POST['showpaging']) : null,
235 'autonext' => isset($_POST['autonext']) ? sanitize_text_field($_POST['autonext']) : null,
236 'thumbplay' => isset($_POST['thumbplay']) ? sanitize_text_field($_POST['thumbplay']) : null,
237 'thumbnail_quality' => isset($_POST['thumbnail_quality']) ? sanitize_text_field($_POST['thumbnail_quality']) : null,
238 'channel_url' => isset($_POST['channelUrl']) ? sanitize_text_field($_POST['channelUrl']) : ''
239 ]);
240
241 wp_send_json($result);
242 }
243
244
245 //Check is YouTube single video
246 public function ytValidateUrl($url)
247 {
248 return (bool) (preg_match('~v=(?:[a-z0-9_\-]+)~i', (string) $url));
249 }
250
251 //Check is YouTube live video
252 public function ytValidateLiveUrl($url)
253 {
254 return (bool) (preg_match('/^https?:\/\/(?:www\.)?youtube\.com\/(?:channel\/[\w-]+|@[\w-]+)\/live$/', (string) $url));
255 }
256
257
258 //Check is Wistia validate url
259 public function wistiaValidateUrl($url)
260 {
261 return (bool) (preg_match('#\/medias\\\?\/([a-z0-9]+)\.?#i', (string) $url));
262 }
263
264 //Check is Wistia validate url
265 public function vimeoValidateUrl($url)
266 {
267 return (bool) preg_match('/https?:\/\/(www\.)?vimeo\.com\/\d+/', (string) $url);
268 }
269
270
271
272 // Get wistia block attributes
273 public function get_wistia_block_attributes($attributes)
274 {
275
276 // Embed Options
277 $embedOptions = new \stdClass;
278 $embedOptions->videoFoam = false;
279 $embedOptions->fullscreenButton = (isset($attributes['wfullscreen']) && (bool) $attributes['wfullscreen'] === true);
280 $embedOptions->playbar = (isset($attributes['playbar']) && (bool) $attributes['playbar'] === true);
281
282 $embedOptions->playButton = (isset($attributes['playbutton']) && (bool) $attributes['playbutton'] === true);
283 $embedOptions->smallPlayButton = (isset($attributes['smallplaybutton']) && (bool) $attributes['smallplaybutton'] === true);
284
285 $embedOptions->autoPlay = (isset($attributes['wautoplay']) && (bool) $attributes['wautoplay'] === true);
286 $embedOptions->resumable = (isset($attributes['resumable']) && (bool) $attributes['resumable'] === true);
287
288 if (!empty($attributes['wstarttime'])) {
289 $embedOptions->time = isset($attributes['wstarttime']) ? $attributes['wstarttime'] : '';
290 }
291
292 $embedOptions = apply_filters('embedpress_wistia_block_attributes', $embedOptions, $attributes);
293
294 $pluginList = [];
295
296 if (isset($attributes['scheme'])) {
297 $color = $attributes['scheme'];
298 if (null !== $color) {
299 $embedOptions->playerColor = $color;
300 }
301 }
302
303 // Closed Captions plugin
304 if ($attributes['captions'] === true) {
305 $isCaptionsEnabled = ($attributes['captions'] === true);
306 $isCaptionsEnabledByDefault = ($attributes['captions'] === true);
307 if ($isCaptionsEnabled) {
308 $pluginList['captions-v1'] = [
309 'onByDefault' => $isCaptionsEnabledByDefault,
310 ];
311 }
312 $embedOptions->captions = $isCaptionsEnabled;
313 $embedOptions->captionsDefault = $isCaptionsEnabledByDefault;
314 }
315
316 $embedOptions->plugin = $pluginList;
317
318
319
320 return json_encode($embedOptions);
321 }
322
323 public function gutenberg_embed($embedHTML, $attributes)
324 {
325 $attributes = Helper::removeQuote($attributes);
326
327 if (!empty($attributes['url'])) {
328 $youtube = new Youtube($attributes['url']);
329
330 $is_youtube = $youtube->validateUrl($youtube->getUrl(false));
331 if ($is_youtube && empty($this->ytValidateLiveUrl($attributes['url']))) {
332 $atts = [
333 'width' => intval($attributes['width']),
334 'height' => intval($attributes['height']),
335 'pagesize' => isset($attributes['pagesize']) ? intval($attributes['pagesize']) : 6,
336 'ytChannelLayout' => isset($attributes['ytChannelLayout']) ? $attributes['ytChannelLayout'] : 'gallery',
337 'columns' => isset($attributes['columns']) ? intval($attributes['columns']) : 3,
338 'ispagination' => isset($attributes['ispagination']) ? $attributes['ispagination'] : 0,
339 'gapbetweenvideos' => isset($attributes['gapbetweenvideos']) ? $attributes['gapbetweenvideos'] : 30,
340 ];
341
342 $atts = Helper::removeQuote($atts);
343
344 $urlInfo = Shortcode::parseContent($attributes['url'], true, $atts);
345
346 if (!empty($urlInfo->embed)) {
347 $embedHTML = $urlInfo->embed;
348 }
349 }
350
351 if (!empty($attributes['url']) && ($this->ytValidateUrl($attributes['url']) || $this->ytValidateLiveUrl($attributes['url']))) {
352
353 $atts = [
354 'url' => $attributes['url'],
355 'starttime' => !empty($attributes['starttime']) ? $attributes['starttime'] : '',
356 'endtime' => !empty($attributes['endtime']) ? $attributes['endtime'] : '',
357 'autoplay' => !empty($attributes['autoplay']) ? 1 : 0,
358 'controls' => isset($attributes['controls']) ? $attributes['controls'] : '1',
359 'fullscreen' => !empty($attributes['fullscreen']) ? 1 : 0,
360 'videoannotations' => !empty($attributes['videoannotations']) ? 1 : 0,
361 'progressbarcolor' => !empty($attributes['progressbarcolor']) ? $attributes['progressbarcolor'] : 'red',
362 'closedcaptions' => !empty($attributes['closedcaptions']) ? 1 : 0,
363 'modestbranding' => !empty($attributes['modestbranding']) ? $attributes['modestbranding'] : '',
364 'relatedvideos' => !empty($attributes['relatedvideos']) ? 1 : 0,
365 'muteVideo' => !empty($attributes['muteVideo']) ? 1 : 0,
366 'customlogo' => !empty($attributes['customlogo']) ? $attributes['customlogo'] : '',
367 'logoX' => !empty($attributes['logoX']) ? $attributes['logoX'] : 5,
368 'logoY' => !empty($attributes['logoY']) ? $attributes['logoY'] : 10,
369 'customlogoUrl' => !empty($attributes['customlogoUrl']) ? $attributes['customlogoUrl'] : '',
370 'logoOpacity' => !empty($attributes['logoOpacity']) ? $attributes['logoOpacity'] : 0.6,
371 ];
372
373 $atts = Helper::removeQuote($atts);
374
375 $urlInfo = Shortcode::parseContent($attributes['url'], true, $atts);
376
377 if (!empty($urlInfo->embed)) {
378 $embedHTML = $urlInfo->embed;
379 }
380
381 if (isset($urlInfo->embed) && preg_match('/src=\"(.+?)\"/', $urlInfo->embed, $match)) {
382 $url_full = $match[1];
383 $query = parse_url($url_full, PHP_URL_QUERY);
384
385 parse_str($query ?? '', $params);
386
387 $params['controls'] = isset($attributes['controls']) ? $attributes['controls'] : '1';
388 $params['iv_load_policy'] = !empty($attributes['videoannotations']) ? 1 : 0;
389 $params['fs'] = !empty($attributes['fullscreen']) ? 1 : 0;
390 $params['rel'] = !empty($attributes['relatedvideos']) ? 1 : 0;
391 $params['end'] = !empty($attributes['endtime']) ? $attributes['endtime'] : '';
392 $params['autoplay'] = !empty($attributes['autoplay']) ? 1 : 0;
393 $params['mute'] = !empty($attributes['muteVideo']) ? 1 : 0;
394 $params['start'] = !empty($attributes['starttime']) ? $attributes['starttime'] : '';
395 $params['color'] = !empty($attributes['progressbarcolor']) ? $attributes['progressbarcolor'] : 'red';
396 $params['modestbranding'] = empty($attributes['modestbranding']) ? 0 : 1; // Reverse the condition value for modestbranding. 0 = display, 1 = do not display
397 $params['cc_load_policy'] = !empty($attributes['closedcaptions']) ? 0 : 1;
398
399 preg_match('/(.+)?\?/', $url_full, $url);
400
401 if (empty($url)) {
402 return $embedHTML;
403 }
404
405 $url = $url[1];
406
407 // Reassemble the url with the new variables.
408 $url_modified = $url . '?';
409
410 foreach ($params as $paramName => $paramValue) {
411
412 $and = '&';
413 if (array_key_last($params) === $paramName) {
414 $and = '';
415 }
416
417 if (isset($paramValue) && $paramValue !== '') {
418 $url_modified .= $paramName . '=' . $paramValue . $and;
419 }
420 }
421
422 // Replaces the old url with the new one.
423 $embedHTML = str_replace($url_full, rtrim($url_modified, '&'), $urlInfo->embed);
424 }
425 }
426 }
427
428 if (!empty($attributes['url']) && $this->wistiaValidateUrl($attributes['url'])) {
429
430
431 $embedOptions = $this->get_wistia_block_attributes($attributes);
432
433 // Get the video ID
434 $videoId = $this->getVideoIDFromURL($attributes['url']);
435 $shortVideoId = substr($videoId, 0, 3);
436
437 // Responsive?
438
439 $class = array(
440 'wistia_embed',
441 'wistia_async_' . $videoId
442 );
443
444 $attribs = array(
445 sprintf('id="wistia_%s"', $videoId),
446 sprintf('class="%s"', join(' ', $class)),
447 sprintf('style="width:%spx; height:%spx;"', $attributes['width'], $attributes['height'])
448 );
449
450 $labels = array(
451 'watch_from_beginning' => __('Watch from the beginning', 'embedpress'),
452 'skip_to_where_you_left_off' => __('Skip to where you left off', 'embedpress'),
453 'you_have_watched_it_before' => __(
454 'It looks like you\'ve watched<br />part of this video before!',
455 'embedpress'
456 ),
457 );
458 $labels = json_encode($labels);
459
460 preg_match('/ose-uid-([a-z0-9]*)/', $attributes['embedHTML'], $matches);
461 $uid = $matches[1];
462
463 $html = "<div class=\"embedpress-wrapper ose-wistia ose-uid-{$uid} responsive\">";
464 $html .= '<script src="https://fast.wistia.com/assets/external/E-v1.js" async></script>';
465 $html .= "<script>window.pp_embed_wistia_labels = {$labels};</script>\n";
466 $html .= "<script>window._wq = window._wq || []; _wq.push({\"{$shortVideoId}\": {$embedOptions}});</script>\n";
467 $html .= '<div ' . join(' ', $attribs) . "></div>\n";
468 $html .= '</div>';
469 $embedHTML = $html;
470 }
471
472 if (!empty($attributes['url']) && $this->vimeoValidateUrl($attributes['url'])) {
473
474 $atts = [
475 'url' => $attributes['url'],
476 'vstarttime' => !empty($attributes['vstarttime']) ? $attributes['vstarttime'] : '',
477 'vscheme' => !empty($attributes['vscheme']) ? $attributes['vscheme'] : 'red',
478 'vautoplay' => !empty($attributes['vautoplay']) ? 1 : 0,
479 'vtitle' => !empty($attributes['vtitle']) ? 1 : 0,
480 'vauthor' => !empty($attributes['vauthor']) ? 1 : 0,
481 'vavatar' => !empty($attributes['vavatar']) ? 1 : 0,
482 'vautopause' => !empty($attributes['vautopause']) ? 1 : 0,
483 'vdnt' => !empty($attributes['vdnt']) ? 1 : 0,
484 'customlogo' => !empty($attributes['customlogo']) ? $attributes['customlogo'] : '',
485 'logoX' => !empty($attributes['logoX']) ? $attributes['logoX'] : 5,
486 'logoY' => !empty($attributes['logoY']) ? $attributes['logoY'] : 10,
487 'customlogoUrl' => !empty($attributes['customlogoUrl']) ? $attributes['customlogoUrl'] : '',
488 'logoOpacity' => !empty($attributes['logoOpacity']) ? $attributes['logoOpacity'] : 0.6,
489 ];
490
491 $atts = Helper::removeQuote($atts);
492
493 $urlInfo = Shortcode::parseContent($attributes['url'], true, $atts);
494
495 if (!empty($urlInfo->embed)) {
496 $embedHTML = $urlInfo->embed;
497 }
498
499 if (isset($urlInfo->embed) && preg_match('/src=\"(.+?)\"/', $urlInfo->embed, $match)) {
500 $url_full = $match[1];
501 $query = parse_url($url_full, PHP_URL_QUERY);
502 parse_str($query, $params);
503
504
505 unset($params['amp;dnt']);
506
507 $params['title'] = !empty($attributes['vtitle']) ? 1 : 0;
508 $params['byline'] = !empty($attributes['vauthor']) ? 1 : 0;
509 $params['portrait'] = !empty($attributes['vavatar']) ? 1 : 0;
510 $params['autoplay'] = !empty($attributes['vautoplay']) ? 1 : 0;
511 $params['loop'] = !empty($attributes['vloop']) ? 1 : 0;
512 $params['autopause'] = !empty($attributes['vautopause']) ? 1 : 0;
513 if (empty($attributes['vautopause'])) :
514 $params['dnt'] = !empty($attributes['vdnt']) ? 1 : 0;
515 endif;
516 $params['color'] = !empty($attributes['vscheme']) ? str_replace("#", "", $attributes['vscheme']) : '00ADEF';
517
518 if (!empty($attributes['vstarttime'])) :
519 $params['t'] = !empty($attributes['vstarttime']) ? $attributes['vstarttime'] : '';
520 endif;
521
522 preg_match('/(.+)?\?/', $url_full, $url);
523
524 if (empty($url)) {
525 return $embedHTML;
526 }
527
528 $url = $url[1];
529
530 // Reassemble the url with the new variables.
531 $url_modified = $url . '?';
532
533 // print_r($url_modified);
534
535
536 foreach ($params as $param => $value) {
537 $url_modified = add_query_arg($param, $value, $url_modified);
538 }
539
540 $url_modified = str_replace("&t=", "#t=", $url_modified);
541
542 // Replaces the old url with the new one.
543 $embedHTML = str_replace($url_full, rtrim($url_modified, '&'), $urlInfo->embed);
544 }
545 }
546
547 return $embedHTML;
548 }
549
550
551 public function elementor_setting_init()
552 {
553 $this->remove_classic_filters();
554 add_filter('embedpress_elementor_embed', [Elementor_Enhancer::class, 'youtube'], 10, 2);
555 add_filter('embedpress_elementor_embed', [Elementor_Enhancer::class, 'wistia'], 10, 2);
556 add_filter('embedpress_elementor_embed', [Elementor_Enhancer::class, 'twitch'], 10, 2);
557 add_filter('embedpress_elementor_embed', [Elementor_Enhancer::class, 'soundcloud'], 10, 2);
558 add_filter('embedpress_elementor_embed', [Elementor_Enhancer::class, 'dailymotion'], 10, 2);
559 add_filter('embedpress_elementor_embed', [Elementor_Enhancer::class, 'spotify'], 10, 2);
560 add_filter('embedpress_elementor_embed', [Elementor_Enhancer::class, 'vimeo'], 10, 2);
561 }
562 public function remove_classic_filters()
563 {
564 remove_filter('embedpress:onAfterEmbed', [$this, 'enhance_youtube'], 90);
565 remove_filter('embedpress:onAfterEmbed', [$this, 'enhance_vimeo'], 90);
566 // remove_filter('embedpress:onAfterEmbed', [$this, 'enhance_wistia'], 90);
567 remove_filter('embedpress:onAfterEmbed', [$this, 'enhance_twitch'], 90);
568 remove_filter('embedpress:onAfterEmbed', [$this, 'enhance_dailymotion'], 90);
569 remove_filter('embedpress:onAfterEmbed', [$this, 'enhance_soundcloud'], 90);
570 }
571 public function getOptions($provider = '', $schema = [])
572 {
573 $options = (array) get_option(EMBEDPRESS_PLG_NAME . ':' . $provider, []);
574 if (empty($options) || (count($options) === 1 && empty($options[0]))) {
575 $options = [];
576
577 foreach ($schema as $fieldSlug => $field) {
578 $value = isset($field['default']) ? $field['default'] : "";
579
580 settype($value, isset($field['type']) && in_array(
581 strtolower($field['type']),
582 ['bool', 'boolean', 'int', 'integer', 'float', 'string']
583 ) ? $field['type'] : 'string');
584
585 if ($fieldSlug === "license_key") {
586 $options['license'] = [
587 'key' => true,
588 'status' => "missing",
589 ];
590 } else {
591 $options[$fieldSlug] = $value;
592 }
593 }
594 }
595
596 $options['license'] = [
597 'key' => true,
598 'status' => "missing",
599 ];
600 return apply_filters('emebedpress_get_options', $options);
601 }
602
603 public function get_youtube_params($options)
604 {
605 $params = [];
606
607 // Handle `autoplay` option.
608 if (isset($options['autoplay']) && (bool) $options['autoplay'] === true) {
609 $params['autoplay'] = 1;
610 } else {
611 unset($params['autoplay']);
612 }
613
614 // Handle `controls` option.
615 if (isset($options['controls']) && in_array((int) $options['controls'], [0, 1, 2])) {
616 $params['controls'] = (int) $options['controls'];
617 } else {
618 unset($params['controls']);
619 }
620
621 // Handle `fs` option.
622 if (isset($options['fs']) && in_array((int) $options['fs'], [0, 1])) {
623 $params['fs'] = (int) $options['fs'];
624 } else {
625 unset($params['fs']);
626 }
627
628 // Handle `iv_load_policy` option.
629 if (isset($options['iv_load_policy']) && in_array((int) $options['iv_load_policy'], [1, 3])) {
630 $params['iv_load_policy'] = (int) $options['iv_load_policy'];
631 } else {
632 unset($params['iv_load_policy']);
633 }
634
635 return apply_filters('embedpress_youtube_params', $params);
636 }
637
638 public function get_vimeo_params($options)
639 {
640 $params = [];
641
642 // Handle `display_title` option.
643 if (isset($options['display_title']) && (bool) $options['display_title'] === true) {
644 $params['title'] = 1;
645 } else {
646 $params['title'] = 0;
647 }
648
649 // Handle `autoplay` option.
650 if (!empty($options['autoplay'])) {
651 $params['autoplay'] = 1;
652 } else {
653 unset($params['autoplay']);
654 }
655
656 // Handle `color` option.
657 if (!empty($options['color'])) {
658 $params['color'] = str_replace('#', '', $options['color']);
659 } else {
660 unset($params['color']);
661 }
662 return apply_filters('embedpress_vimeo_params', $params);
663 }
664
665 //--- For CLASSIC AND BLOCK EDITOR
666 public function enhance_youtube($embed)
667 {
668
669
670 $isYoutube = (isset($embed->provider_name) && strtoupper($embed->provider_name) === 'YOUTUBE') || (isset($embed->url) && isset($embed->{$embed->url}) && isset($embed->{$embed->url}['provider_name']) && strtoupper($embed->{$embed->url}['provider_name']) === 'YOUTUBE');
671
672 if (
673 $isYoutube && isset($embed->embed)
674 && preg_match('/<iframe[^>]+src=["\']([^"\']+)[^>]*>/', $embed->embed, $match)
675 ) {
676
677 // for compatibility only, @TODO; remove later after deep testing.
678 $options = $this->getOptions('youtube', $this->get_youtube_settings_schema());
679
680 // Parse the url to retrieve all its info like variables etc.
681 $url_full = $match[1];
682 $query = parse_url($url_full, PHP_URL_QUERY);
683 $query = $query ?? ''; // Ensure $query is a string
684 parse_str($query, $params);
685 // Handle `color` option.
686 if (!empty($options['color'])) {
687 $params['color'] = $options['color'];
688 } else {
689 unset($params['color']);
690 }
691 // Handle `rel` option.
692 if (isset($options['rel']) && in_array((int) $options['rel'], [0, 1])) {
693 $params['rel'] = (int) $options['rel'];
694 } else {
695 unset($params['rel']);
696 }
697
698 // Handle `autoplay` option.
699 if (isset($options['autoplay']) && (bool) $options['autoplay'] === true) {
700 $params['autoplay'] = 1;
701 } else {
702 unset($params['autoplay']);
703 }
704
705 // Handle `controls` option.
706 if (isset($options['controls']) && in_array((int) $options['controls'], [0, 1, 2])) {
707 $params['controls'] = (int) $options['controls'];
708 } else {
709 unset($params['controls']);
710 }
711 if (isset($options['start_time'])) {
712 $params['start'] = $options['start_time'];
713 } else {
714 unset($params['start']);
715 }
716 if (isset($options['end_time'])) {
717 $params['end'] = $options['end_time'];
718 } else {
719 unset($params['end']);
720 }
721
722 // Handle `fs` option.
723 if (isset($options['fs']) && in_array((int) $options['fs'], [0, 1])) {
724 $params['fs'] = (int) $options['fs'];
725 } else {
726 unset($params['fs']);
727 }
728
729 // Handle `iv_load_policy` option.
730 if (isset($options['iv_load_policy']) && in_array((int) $options['iv_load_policy'], [1, 3])) {
731 $params['iv_load_policy'] = (int) $options['iv_load_policy'];
732 } else {
733 unset($params['iv_load_policy']);
734 }
735
736 // pro controls will be handled by the pro so remove it from the free.
737 $pro_controls = ['cc_load_policy', 'modestbranding'];
738 foreach ($pro_controls as $pro_control) {
739 if (isset($params[$pro_control])) {
740 unset($params[$pro_control]);
741 }
742 }
743
744
745 $url = explode('?', $url_full);
746
747 if (isset($url[0])) {
748 $url = $url[0];
749 }
750
751 if (is_object($embed->attributes) && !empty($embed->attributes)) {
752 $attributes = (array) $embed->attributes;
753
754 $params['controls'] = isset($attributes['data-controls']) ? $attributes['data-controls'] : '1';
755 $params['iv_load_policy'] = !empty($attributes['data-videoannotations']) && ($attributes['data-videoannotations'] == 'true') ? 1 : 0;
756 $params['fs'] = !empty($attributes['data-fullscreen']) && ($attributes['data-fullscreen'] == 'true') ? 1 : 0;
757 $params['rel'] = !empty($attributes['data-relatedvideos']) && ($attributes['data-relatedvideos'] == 'true') ? 1 : 0;
758 $params['end'] = !empty($attributes['data-endtime']) ? $attributes['data-endtime'] : '';
759 $params['autoplay'] = !empty($attributes['data-autoplay']) && ($attributes['data-autoplay'] == 'true') ? 1 : 0;
760 $params['mute'] = !empty($attributes['data-muteVideo']) && ($attributes['data-muteVideo'] == 'true') ? 1 : 0;
761 $params['start'] = !empty($attributes['data-starttime']) ? $attributes['data-starttime'] : '';
762 $params['color'] = !empty($attributes['data-progressbarcolor']) ? $attributes['data-progressbarcolor'] : 'red';
763 $params['modestbranding'] = empty($attributes['data-modestbranding']) ? 0 : 1; // Reverse the condition value for modestbranding. 0 = display, 1 = do not display
764 $params['cc_load_policy'] = !empty($attributes['data-closedcaptions']) && ($attributes['data-closedcaptions'] == 'true') ? 0 : 1;
765 $params['playsinline'] = '1';
766
767 }
768
769 // Ensure $url is a string. If $url is an array, convert it to a string or use a specific element.
770 $url_string = is_array($url) ? (isset($url[0]) ? $url[0] : '') : $url;
771
772 // Reassemble the URL with the new variables.
773 $url_modified = $url_string . '?';
774 foreach ($params as $paramName => $paramValue) {
775 $url_modified .= urlencode($paramName) . '=' . urlencode($paramValue) . '&';
776 }
777
778 // Remove the trailing '&' or '?' if no parameters were added.
779 $url_modified = rtrim($url_modified, '&?');
780
781
782 // Replaces the old url with the new one.
783 $embed->embed = str_replace($url_full, rtrim($url_modified, '&'), $embed->embed);
784 }
785
786 return $embed;
787 }
788
789 public function enhance_vimeo($embed)
790 {
791
792
793 if (
794 isset($embed->provider_name)
795 && strtoupper($embed->provider_name) === 'VIMEO'
796 && isset($embed->embed)
797 && preg_match('/src=\"(.+?)\"/', $embed->embed, $match)
798 ) {
799 // old schema is for backward compatibility only @todo; remove it in the next version after deep test
800 $options = $this->getOptions('vimeo', $this->get_vimeo_settings_schema());
801
802 $url_full = $match[1];
803 $params = [];
804
805 // Handle `display_title` option.
806 if (isset($options['display_title']) && (bool) $options['display_title'] === true) {
807 $params['title'] = 1;
808 } else {
809 $params['title'] = 0;
810 }
811
812 // Handle `autoplay` option.
813 if (isset($options['autoplay']) && (bool) $options['autoplay'] === true) {
814 $params['autoplay'] = 1;
815 } else {
816 unset($params['autoplay']);
817 }
818
819 // Handle `color` option.
820 if (!empty($options['color'])) {
821 $params['color'] = str_replace('#', '', $options['color']);
822 } else {
823 unset($params['color']);
824 }
825 // Handle `display_author` option.
826 if (isset($options['display_author']) && (bool) $options['display_author'] === true) {
827 $params['byline'] = 1;
828 } else {
829 $params['byline'] = 0;
830 }
831
832 // Handle `display_avatar` option.
833 if (isset($options['display_avatar']) && (bool) $options['display_avatar'] === true) {
834 $params['portrait'] = 1;
835 } else {
836 $params['portrait'] = 0;
837 }
838
839 // NOTE: 'vimeo_dnt' is actually only 'dnt' in the params, so unset 'dnt' only
840 //@todo; maybe extract unsetting pro vars to a function later
841 $pro_controls = ['loop', 'autopause', 'dnt',];
842 foreach ($pro_controls as $pro_control) {
843 if (isset($params[$pro_control])) {
844 unset($params[$pro_control]);
845 }
846 }
847
848 if (!empty($params['autopause'])) {
849 unset($params['dnt']);
850 unset($params['amp;dnt']);
851 }
852
853 // Reassemble the url with the new variables.
854 $url_modified = str_replace("&amp;dnt=1", "", $url_full);
855
856 if (is_object($embed->attributes) && !empty($embed->attributes)) {
857 $attributes = (array) $embed->attributes;
858
859 $attributes = stringToBoolean($attributes);
860
861
862 $params['title'] = !empty($attributes['data-vtitle']) ? 1 : 0;
863 $params['byline'] = !empty($attributes['data-vauthor']) ? 1 : 0;
864 $params['portrait'] = !empty($attributes['data-vavatar']) ? 1 : 0;
865 $params['autoplay'] = !empty($attributes['data-vautoplay']) ? 1 : 0;
866 $params['loop'] = !empty($attributes['data-vloop']) ? 1 : 0;
867 $params['autopause'] = !empty($attributes['data-vautopause']) ? 1 : 0;
868 if (empty($attributes['data-vautopause'])) :
869 $params['dnt'] = !empty($attributes['data-vdnt']) ? 1 : 0;
870 endif;
871 $params['color'] = !empty($attributes['data-vscheme']) ? str_replace("#", "", $attributes['data-vscheme']) : '00ADEF';
872
873 if (!empty($attributes['data-vstarttime'])) :
874 $params['t'] = !empty($attributes['data-vstarttime']) ? $attributes['data-vstarttime'] : '';
875 endif;
876
877 foreach ($params as $param => $value) {
878 $url_modified = add_query_arg($param, $value, $url_modified);
879 }
880
881 $url_modified = str_replace("&t=", "#t=", $url_modified);
882 } else {
883 foreach ($params as $param => $value) {
884 $url_modified = add_query_arg($param, $value, $url_modified);
885 }
886
887 if (empty($attributes['data-vstarttime']) && isset($options['start_time'])) {
888 $start_time = sanitize_text_field($options['start_time']);
889 $url_modified .= '#t=' . $start_time;
890 }
891 }
892
893 do_action('embedpress_after_modified_url', $url_modified, $url_full, $params);
894
895 // Replaces the old url with the new one.
896 $embed->embed = str_replace($url_full, $url_modified, $embed->embed);
897 }
898
899 return $embed;
900 }
901
902 public function enhance_wistia($embed)
903 {
904
905 if (
906 isset($embed->provider_name)
907 && (strtoupper($embed->provider_name) === 'WISTIA, INC.' || strtoupper($embed->provider_name) === 'WISTIA')
908 && isset($embed->embed)
909 && preg_match('/src=\"(.+?)\"/', $embed->embed, $match)
910 ) {
911 $options = $this->getOptions('wistia', $this->get_wistia_settings_schema());
912
913 $url_full = $match[1];
914
915 // Parse the url to retrieve all its info like variables etc.
916 $query = parse_url($embed->url, PHP_URL_QUERY);
917 $url = str_replace('?' . $query, '', $url_full);
918
919 if ($query !== null) {
920 parse_str($query, $params);
921 }
922
923 // Set the class in the attributes
924 $embed->attributes->class = str_replace('{provider_alias}', 'wistia', $embed->attributes->class);
925 $embed->embed = str_replace('ose-wistia, inc.', 'ose-wistia', $embed->embed);
926
927
928 // Embed Options
929 $embedOptions = new \stdClass;
930 $embedOptions->videoFoam = false;
931 $embedOptions->fullscreenButton = (isset($options['display_fullscreen_button']) && (bool) $options['display_fullscreen_button'] === true);
932 $embedOptions->playbar = (isset($options['display_playbar']) && (bool) $options['display_playbar'] === true);
933
934 $embedOptions->smallPlayButton = (isset($options['small_play_button']) && (bool) $options['small_play_button'] === true);
935
936 $embedOptions->autoPlay = (isset($options['autoplay']) && (bool) $options['autoplay'] === true);
937
938 if (!empty($options['start_time'])) {
939 // $embedOptions->time = isset($options['start_time']) ? $options['start_time'] : 0;
940 }
941
942 if (isset($options['player_color'])) {
943 $color = $options['player_color'];
944 if (null !== $color) {
945 $embedOptions->playerColor = $color;
946 }
947 }
948
949 // Plugins
950 $pluginsBaseURL = plugins_url('assets/js/wistia/min', dirname(__DIR__) . '/embedpress-Wistia.php');
951
952 $pluginList = array();
953
954 // Resumable
955 if (isset($options['plugin_resumable'])) {
956 $isResumableEnabled = $options['plugin_resumable'];
957 if ($isResumableEnabled) {
958 // Add the resumable plugin
959 $pluginList['resumable'] = array(
960 'src' => $pluginsBaseURL . '/resumable.min.js',
961 'async' => false
962 );
963 }
964 }
965
966 // Add a fix for the autoplay and resumable work better together
967 if (isset($options->autoPlay)) {
968 if ($isResumableEnabled) {
969 $pluginList['fixautoplayresumable'] = array(
970 'src' => $pluginsBaseURL . '/fixautoplayresumable.min.js'
971 );
972 }
973 }
974
975 // Focus plugin
976 if (isset($options['plugin_focus'])) {
977 $isFocusEnabled = $options['plugin_focus'];
978 $pluginList['dimthelights'] = array(
979 'src' => $pluginsBaseURL . '/dimthelights.min.js',
980 'autoDim' => $isFocusEnabled
981 );
982 $embedOptions->focus = $isFocusEnabled;
983 }
984
985 // Rewind plugin
986 if (isset($options['plugin_rewind'])) {
987 if ($options['plugin_rewind']) {
988 $embedOptions->rewindTime = isset($options['plugin_rewind_time']) ? (int) $options['plugin_rewind_time'] : 10;
989
990 $pluginList['rewind'] = array(
991 'src' => $pluginsBaseURL . '/rewind.min.js'
992 );
993 }
994 }
995 $embedOptions->plugin = $pluginList;
996
997 $embedOptions = json_encode($embedOptions);
998
999 // Get the video ID
1000 $videoId = $this->getVideoIDFromURL($embed->url);
1001 $shortVideoId = substr($videoId, 0, 3);
1002
1003 // Responsive?
1004
1005 $class = array(
1006 'wistia_embed',
1007 'wistia_async_' . $videoId
1008 );
1009
1010 $attribs = array(
1011 sprintf('id="wistia_%s"', $videoId),
1012 sprintf('class="%s"', join(' ', $class)),
1013 sprintf('style="width:%spx; height:%spx;"', $embed->width, $embed->height)
1014 );
1015
1016 $labels = array(
1017 'watch_from_beginning' => __('Watch from the beginning', 'embedpress'),
1018 'skip_to_where_you_left_off' => __('Skip to where you left off', 'embedpress'),
1019 'you_have_watched_it_before' => __(
1020 'It looks like you\'ve watched<br />part of this video before!',
1021 'embedpress'
1022 ),
1023 );
1024 $labels = json_encode($labels);
1025
1026 preg_match('/ose-uid-([a-z0-9]*)/', $embed->embed, $matches);
1027 $uid = $matches[1];
1028
1029 $html = "<div class=\"embedpress-wrapper ose-wistia ose-uid-{$uid} responsive we\">";
1030 $html .= '<script src="https://fast.wistia.com/assets/external/E-v1.js" async></script>';
1031 $html .= "<script>window.pp_embed_wistia_labels = {$labels};</script>\n";
1032 $html .= "<script>window._wq = window._wq || []; _wq.push({\"{$shortVideoId}\": {$embedOptions}});</script>\n";
1033 $html .= '<div ' . join(' ', $attribs) . "></div>\n";
1034 $html .= '</div>';
1035 $embed->embed = $html;
1036 }
1037
1038 return $embed;
1039 }
1040
1041 public function enhance_twitch($embed_content)
1042 {
1043 $e = isset($embed_content->url) && isset($embed_content->{$embed_content->url}) ? $embed_content->{$embed_content->url} : [];
1044 if (isset($e['provider_name']) && strtoupper($e['provider_name']) === 'TWITCH' && isset($embed_content->embed)) {
1045 $settings = $this->getOptions('twitch', $this->get_twitch_settings_schema());
1046
1047 $atts = isset($embed_content->attributes) ? $embed_content->attributes : [];
1048 $time = '0h0m0s';
1049 $type = $e['type'];
1050 $content_id = $e['content_id'];
1051 $channel = 'channel' === $type ? $content_id : '';
1052 $video = 'video' === $type ? $content_id : '';
1053 $muted = isset($settings['embedpress_pro_twitch_mute']) && ('yes' === $settings['embedpress_pro_twitch_mute']) ? 'true' : 'false';
1054 $full_screen = isset($settings['embedpress_pro_fs']) && ('yes' === $settings['embedpress_pro_fs']) ? 'true' : 'false';
1055 $autoplay = isset($settings['embedpress_pro_twitch_autoplay']) && ('yes' === $settings['embedpress_pro_twitch_autoplay']) ? 'true' : 'false';
1056 $theme = !empty($settings['embedpress_pro_twitch_theme']) ? esc_attr($settings['embedpress_pro_twitch_theme']) : 'dark';
1057
1058 $layout = 'video';
1059 $width = !empty($atts->{'data-width'}) ? (int) $atts->{'data-width'} : 800;
1060 $height = !empty($atts->{'data-height'}) ? (int) $atts->{'data-height'} : 450;
1061 if (!empty($settings['start_time'])) {
1062 $ta = explode(':', gmdate("G:i:s", $settings['start_time']));
1063 $h = $ta[0] . 'h';
1064 $m = ($ta[1] * 1) . 'm';
1065 $s = ($ta[2] * 1) . 's';
1066 $time = $h . $m . $s;
1067 }
1068 $url = "https://embed.twitch.tv?autoplay={$autoplay}&channel={$channel}&height={$height}&layout={$layout}&migration=true&muted={$muted}&theme={$theme}&time={$time}&video={$video}&width={$width}&allowfullscreen={$full_screen}";
1069 $pars_url = wp_parse_url(get_site_url());
1070 $url = !empty($pars_url['host']) ? $url . '&parent=' . $pars_url['host'] : $url;
1071 ob_start();
1072 ?>
1073 <div class="embedpress_wrapper" data-url="<?php echo esc_url($embed_content->url); ?>">
1074 <iframe src="<?php echo esc_url($url); ?>" allowfullscreen="" scrolling="no" frameborder="0" allow="autoplay; fullscreen" title="Twitch" sandbox="allow-modals allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" width="<?php echo esc_attr($width); ?>" height="<?php echo esc_attr($height); ?>" style="max-width: <?php echo esc_attr($width); ?>px; max-height:<?php echo esc_attr($height); ?>px;"></iframe>
1075 </div>
1076 <?php
1077 $c = ob_get_clean();
1078 $embed_content->embed = $c;
1079 }
1080
1081 return $embed_content;
1082 }
1083 public function enhance_dailymotion($embed)
1084 {
1085 $options = $this->getOptions('dailymotion', $this->get_dailymotion_settings_schema());
1086 $isDailymotion = (isset($embed->provider_name) && strtoupper($embed->provider_name) === 'DAILYMOTION') || (isset($embed->url) && isset($embed->{$embed->url}) && isset($embed->{$embed->url}['provider_name']) && strtoupper($embed->{$embed->url}['provider_name']) === 'DAILYMOTION');
1087
1088 if (
1089 $isDailymotion && isset($embed->embed)
1090 && preg_match('/src=\"(.+?)\"/', $embed->embed, $match)
1091 ) {
1092 // Parse the url to retrieve all its info like variables etc.
1093 $url_full = $match[1];
1094 $params = [
1095 'ui-highlight' => str_replace('#', '', isset($options['color']) ? $options['color'] : null),
1096 'mute' => (int) isset($options['mute']) ? $options['mute'] : null,
1097 'autoplay' => (int) isset($options['autoplay']) ? $options['autoplay'] : null,
1098 'controls' => (int) isset($options['controls']) ? $options['controls'] : null,
1099 'ui-start-screen-info' => (int) isset($options['video_info']) ? $options['video_info'] : null,
1100 'endscreen-enable' => 0,
1101 ];
1102
1103 if (isset($options['play_on_mobile']) && $options['play_on_mobile'] == '1') {
1104 $params['playsinline'] = 1;
1105 }
1106 $params['start'] = (int) isset($options['start_time']) ? $options['start_time'] : null;
1107
1108 $params = apply_filters('embedpress_enhance_dailymotion', $params, $options);
1109
1110
1111 $url_modified = $url_full;
1112 foreach ($params as $param => $value) {
1113 $url_modified = add_query_arg($param, $value, $url_modified);
1114 }
1115 $embed->embed = str_replace($url_full, $url_modified, $embed->embed);
1116 }
1117
1118 return $embed;
1119 }
1120 public function enhance_soundcloud($embed)
1121 {
1122
1123 $isSoundcloud = (isset($embed->provider_name) && strtoupper($embed->provider_name) === 'SOUNDCLOUD') || (isset($embed->url) && isset($embed->{$embed->url}) && isset($embed->{$embed->url}['provider_name']) && strtoupper($embed->{$embed->url}['provider_name']) === 'SOUNDCLOUD');
1124
1125 if (
1126 $isSoundcloud && isset($embed->embed)
1127 && preg_match('/src=\"(.+?)\"/', $embed->embed, $match)
1128 ) {
1129 $options = $this->getOptions('soundcloud', $this->get_soundcloud_settings_schema());
1130 // Parse the url to retrieve all its info like variables etc.
1131 $url_full = $match[1];
1132 $params = [
1133 'color' => str_replace('#', '', $options['color']),
1134 'visual' => isset($options['visual']) && $options['visual'] == '1' ? 'true' : 'false',
1135 'auto_play' => isset($options['autoplay']) && $options['autoplay'] == '1' ? 'true' : 'false',
1136 'sharing' => isset($options['share_button']) && $options['share_button'] == '1' ? 'true' : 'false',
1137 'show_comments' => isset($options['comments']) && $options['comments'] == '1' ? 'true' : 'false',
1138 'buying' => 'false',
1139 'download' => 'false',
1140 'show_artwork' => isset($options['artwork']) && $options['artwork'] == '1' ? 'true' : 'false',
1141 'show_playcount' => isset($options['play_count']) && $options['play_count'] == '1' ? 'true' : 'false',
1142 'show_user' => isset($options['username']) && $options['username'] == '1' ? 'true' : 'false',
1143 ];
1144
1145 $params = apply_filters('embedpress_enhance_soundcloud', $params, $options);
1146
1147 $url_modified = $url_full;
1148 foreach ($params as $param => $value) {
1149 $url_modified = add_query_arg($param, $value, $url_modified);
1150 }
1151
1152 // Replaces the old url with the new one.
1153 $embed->embed = str_replace($url_full, $url_modified, $embed->embed);
1154 if ('false' === $params['visual']) {
1155 $embed->embed = str_replace('height="400"', 'height="200 !important"', $embed->embed);
1156 }
1157 }
1158
1159 return $embed;
1160 }
1161 public function embedpress_gutenberg_register_block_youtube($youtube_params)
1162 {
1163 $youtube_options = $this->getOptions('youtube', $this->get_youtube_settings_schema());
1164 return $this->get_youtube_params($youtube_options);
1165 }
1166 public function embedpress_gutenberg_register_block_vimeo()
1167 {
1168 if (function_exists('register_block_type')) :
1169 register_block_type('embedpress/vimeo-block', array(
1170 'attributes' => array(
1171 'url' => array(
1172 'type' => 'string',
1173 'default' => ''
1174 ),
1175 'iframeSrc' => array(
1176 'type' => 'string',
1177 'default' => ''
1178 ),
1179 ),
1180 'render_callback' => [$this, 'embedpress_gutenberg_render_block_vimeo']
1181 ));
1182 endif;
1183 }
1184 public function embedpress_gutenberg_render_block_vimeo($attributes)
1185 {
1186 ob_start();
1187 if (!empty($attributes) && !empty($attributes['iframeSrc'])) :
1188 $vimeo_options = $this->getOptions('vimeo', $this->get_vimeo_settings_schema());
1189 $vimeo_params = $this->get_vimeo_params($vimeo_options);
1190 $iframeUrl = $attributes['iframeSrc'];
1191 $align = 'align' . (isset($attributes['align']) ? $attributes['align'] : 'center');
1192 foreach ($vimeo_params as $param => $value) {
1193 $iframeUrl = add_query_arg($param, $value, $iframeUrl);
1194 }
1195 //@TODO; test responsive without static height width, keeping for now backward compatibility
1196 ?>
1197 <div class="ose-vimeo wp-block-embed-vimeo <?php echo esc_attr($align); ?>">
1198 <iframe src="<?php echo esc_url($iframeUrl); ?>" allowtransparency="true" frameborder="0" width="640" height="360">
1199 </iframe>
1200 </div>
1201 <?php
1202 endif;
1203
1204 return apply_filters('embedpress_gutenberg_block_markup', ob_get_clean());
1205 }
1206 public function get_youtube_settings_schema()
1207 {
1208 return [
1209 'autoplay' => [
1210 'type' => 'bool',
1211 'default' => false
1212 ],
1213 'color' => [
1214 'type' => 'string',
1215 'default' => 'red'
1216 ],
1217 'cc_load_policy' => [
1218 'type' => 'bool',
1219 'default' => false
1220 ],
1221 'controls' => [
1222 'type' => 'string',
1223 'default' => '1'
1224 ],
1225 'fs' => [
1226 'type' => 'bool',
1227 'default' => true
1228 ],
1229 'iv_load_policy' => [
1230 'type' => 'radio',
1231 'default' => '1'
1232 ],
1233 'rel' => [
1234 'type' => 'bool',
1235 'default' => true
1236 ],
1237 'modestbranding' => [
1238 'type' => 'string',
1239 'default' => '0'
1240 ],
1241 'logo_url' => [
1242 'type' => 'url',
1243 ],
1244 'logo_xpos' => [
1245 'type' => 'number',
1246 'default' => 10
1247 ],
1248 'logo_ypos' => [
1249 'type' => 'number',
1250 'default' => 10
1251 ],
1252 'cta_url' => [
1253 'type' => 'url',
1254 ],
1255 'start_time' => [
1256 'type' => 'number',
1257 'default' => 10
1258 ],
1259 'end_time' => [
1260 'type' => 'number',
1261 'default' => 10
1262 ],
1263 ];
1264 }
1265 public function get_vimeo_settings_schema()
1266 {
1267 return array(
1268 'start_time' => [
1269 'type' => 'number',
1270 'default' => 10
1271 ],
1272 'autoplay' => array(
1273 'type' => 'bool',
1274 'default' => false
1275 ),
1276 'loop' => array(
1277 'type' => 'bool',
1278 'default' => false
1279 ),
1280 'autopause' => array(
1281 'type' => 'bool',
1282 'default' => false
1283 ),
1284 'vimeo_dnt' => array(
1285 'type' => 'bool',
1286 'default' => true,
1287 ),
1288 'color' => array(
1289 'type' => 'text',
1290 'default' => '#00adef',
1291 'classes' => 'color-field'
1292 ),
1293 'display_title' => array(
1294 'type' => 'bool',
1295 'default' => true
1296 ),
1297 'display_author' => array(
1298 'type' => 'bool',
1299 'default' => true
1300 ),
1301 'display_avatar' => array(
1302 'type' => 'bool',
1303 'default' => true
1304 )
1305 );
1306 }
1307 public function get_wistia_settings_schema()
1308 {
1309 return array(
1310 'start_time' => [
1311 'type' => 'number',
1312 'default' => 0
1313 ],
1314 'display_fullscreen_button' => array(
1315 'type' => 'bool',
1316 'default' => true
1317 ),
1318 'display_playbar' => array(
1319 'type' => 'bool',
1320 'default' => true
1321 ),
1322 'small_play_button' => array(
1323 'type' => 'bool',
1324 'default' => true
1325 ),
1326 'display_volume_control' => array(
1327 'type' => 'bool',
1328 'default' => true
1329 ),
1330 'autoplay' => array(
1331 'type' => 'bool',
1332 'default' => false
1333 ),
1334 'volume' => array(
1335 'type' => 'text',
1336 'default' => '100'
1337 ),
1338 'player_color' => array(
1339 'type' => 'text',
1340 'default' => '#00adef',
1341 ),
1342 'plugin_resumable' => array(
1343 'type' => 'bool',
1344 'default' => false
1345 ),
1346 'plugin_captions' => array(
1347 'type' => 'bool',
1348 'default' => false
1349 ),
1350 'plugin_captions_default' => array(
1351 'type' => 'bool',
1352 'default' => false
1353 ),
1354 'plugin_focus' => array(
1355 'type' => 'bool',
1356 'default' => false
1357 ),
1358 'plugin_rewind' => array(
1359 'type' => 'bool',
1360 'default' => false
1361 ),
1362 'plugin_rewind_time' => array(
1363 'type' => 'text',
1364 'default' => '10'
1365 ),
1366 );
1367 }
1368
1369
1370 public function getVideoIDFromURL($url)
1371 {
1372 // https://fast.wistia.com/embed/medias/xf1edjzn92.jsonp
1373 // https://ostraining-1.wistia.com/medias/xf1edjzn92
1374 preg_match('#\/medias\\\?\/([a-z0-9]+)\.?#i', $url, $matches);
1375
1376 $id = false;
1377 if (isset($matches[1])) {
1378 $id = $matches[1];
1379 }
1380
1381 return $id;
1382 }
1383 public function embedpress_wistia_block_after_embed($attributes)
1384 {
1385 $embedOptions = $this->embedpress_wistia_pro_get_options();
1386 // Get the video ID
1387 $videoId = $this->getVideoIDFromURL($attributes['url']);
1388 $shortVideoId = $videoId;
1389
1390 $labels = array(
1391 'watch_from_beginning' => __('Watch from the beginning', 'embedpress'),
1392 'skip_to_where_you_left_off' => __('Skip to where you left off', 'embedpress'),
1393 'you_have_watched_it_before' => __('It looks like you\'ve watched<br />part of this video before!', 'embedpress'),
1394 );
1395 $labels = json_encode($labels);
1396
1397
1398 $html = '<script src="https://fast.wistia.com/assets/external/E-v1.js"></script>';
1399 $html .= "<script>window.pp_embed_wistia_labels = {$labels};</script>\n";
1400 $html .= "<script>wistiaEmbed = Wistia.embed( \"{$shortVideoId}\", {$embedOptions} );</script>\n";
1401
1402
1403
1404 echo $html;
1405 }
1406 public function embedpress_wistia_pro_get_options()
1407 {
1408 $options = $this->getOptions('wistia', $this->get_wistia_settings_schema());
1409 // Embed Options
1410 $embedOptions = new \stdClass;
1411 // $embedOptions->videoFoam = true;
1412 $embedOptions->fullscreenButton = (isset($options['display_fullscreen_button']) && (bool) $options['display_fullscreen_button'] === true);
1413 $embedOptions->smallPlayButton = (isset($options['small_play_button']) && (bool) $options['small_play_button'] === true);
1414 $embedOptions->autoPlay = (isset($options['autoplay']) && (bool) $options['autoplay'] === true);
1415
1416 if (isset($options['player_color'])) {
1417 $color = $options['player_color'];
1418 if (null !== $color) {
1419 $embedOptions->playerColor = $color;
1420 }
1421 }
1422
1423 // Plugins
1424 $pluginsBaseURL = plugins_url('assets/js/wistia/min', dirname(__DIR__) . '/embedpress-Wistia.php');
1425
1426 $pluginList = array();
1427
1428 // Resumable
1429 if (isset($options['plugin_resumable'])) {
1430 $isResumableEnabled = $options['plugin_resumable'];
1431 if ($isResumableEnabled) {
1432 // Add the resumable plugin
1433 $pluginList['resumable'] = array(
1434 'src' => '//fast.wistia.com/labs/resumable/plugin.js',
1435 'async' => false
1436 );
1437 }
1438 }
1439 // Add a fix for the autoplay and resumable work better together
1440 //@TODO; check baseurl deeply, not looking good
1441 if ($options['autoplay']) {
1442 if ($isResumableEnabled) {
1443 $pluginList['fixautoplayresumable'] = array(
1444 'src' => $pluginsBaseURL . '/fixautoplayresumable.min.js'
1445 );
1446 }
1447 }
1448
1449
1450 // Focus plugin
1451 if (isset($options['plugin_focus'])) {
1452 $isFocusEnabled = $options['plugin_focus'];
1453 $pluginList['dimthelights'] = array(
1454 'src' => '//fast.wistia.com/labs/dim-the-lights/plugin.js',
1455 'autoDim' => $isFocusEnabled
1456 );
1457 $embedOptions->focus = $isFocusEnabled;
1458 }
1459
1460 $embedOptions->plugin = $pluginList;
1461 $embedOptions = apply_filters('embedpress_wistia_params', $embedOptions);
1462 $embedOptions = json_encode($embedOptions);
1463 return apply_filters('embedpress_wistia_params_after_encode', $embedOptions);
1464 }
1465
1466
1467 public function get_twitch_settings_schema()
1468 {
1469 return [
1470 'start_time' => [
1471 'type' => 'number',
1472 'default' => 0,
1473 ],
1474 'embedpress_pro_twitch_autoplay' => [
1475 'type' => 'string',
1476 'default' => 'no',
1477 ],
1478 'embedpress_pro_twitch_chat' => [
1479 'type' => 'string',
1480 'default' => 'no',
1481 ],
1482
1483 'embedpress_pro_twitch_theme' => [
1484 'type' => 'string',
1485 'default' => 'dark',
1486 ],
1487 'embedpress_pro_fs' => [
1488 'type' => 'string',
1489 'default' => 'yes',
1490 ],
1491 'embedpress_pro_twitch_mute' => [
1492 'type' => 'string',
1493 'default' => 'yes',
1494 ],
1495
1496 ];
1497 }
1498 public function get_dailymotion_settings_schema()
1499 {
1500 return [
1501 'autoplay' => [
1502 'type' => 'string',
1503 'default' => ''
1504 ],
1505 'play_on_mobile' => [
1506 'type' => 'string',
1507 'default' => ''
1508 ],
1509 'color' => [
1510 'type' => 'string',
1511 'default' => '#dd3333'
1512 ],
1513 'mute' => [
1514 'type' => 'string',
1515 'default' => ''
1516 ],
1517 'controls' => [
1518 'type' => 'string',
1519 'default' => '1'
1520 ],
1521 'video_info' => [
1522 'type' => 'string',
1523 'default' => '1'
1524 ],
1525 'show_logo' => [
1526 'type' => 'string',
1527 'default' => '1'
1528 ],
1529 'start_time' => [
1530 'type' => 'string',
1531 'default' => '0'
1532 ],
1533 ];
1534 }
1535 public function get_soundcloud_settings_schema()
1536 {
1537 return [
1538 'visual' => [
1539 'type' => 'string',
1540 'default' => ''
1541 ],
1542 'autoplay' => [
1543 'type' => 'string',
1544 'default' => ''
1545 ],
1546 'play_on_mobile' => [
1547 'type' => 'string',
1548 'default' => ''
1549 ],
1550 'color' => [
1551 'type' => 'string',
1552 'default' => '#dd3333'
1553 ],
1554
1555 'share_button' => [
1556 'type' => 'string',
1557 'default' => ''
1558 ],
1559 'comments' => [
1560 'type' => 'string',
1561 'default' => '1'
1562 ],
1563 'artwork' => [
1564 'type' => 'string',
1565 'default' => ''
1566 ],
1567 'play_count' => [
1568 'type' => 'string',
1569 'default' => '1'
1570 ],
1571 'username' => [
1572 'type' => 'string',
1573 'default' => '1'
1574 ],
1575 'download_button' => [
1576 'type' => 'string',
1577 'default' => '1'
1578 ],
1579 'buy_button' => [
1580 'type' => 'string',
1581 'default' => '1'
1582 ],
1583 ];
1584 }
1585
1586 public function enhance_missing_title($embed)
1587 {
1588
1589 $embed_arr = get_object_vars($embed);
1590
1591 $url = $embed->url;
1592
1593 if (strpos($url, 'gettyimages') !== false) {
1594 $title = $embed_arr[$url]['title'] ?? '';
1595 $embed->embed = $embed->embed . "
1596 <script>
1597 if (typeof gie === 'function') {
1598 gie(function(){
1599 var iframe = document.querySelector('.ose-embedpress-responsive iframe');
1600 if(iframe && !iframe.getAttribute('title')){
1601 iframe.setAttribute('title', '$title')
1602 }
1603 });
1604 }
1605 </script>
1606 ";
1607 }
1608
1609
1610 return $embed;
1611 }
1612
1613
1614 public function embedpress_generate_social_share_meta()
1615 {
1616 $post_id = get_the_ID();
1617 $post = get_post($post_id);
1618 $tags = '';
1619
1620 $thumbnail_url = get_the_post_thumbnail_url($post_id);
1621
1622 if (!empty($_GET['hash'])) {
1623
1624 $id_value = sanitize_text_field($_GET['hash']);
1625 $unique_hash = !empty($_GET['unique']) ? sanitize_text_field($_GET['unique']) : '';
1626
1627 $url = get_the_permalink($post_id);
1628
1629 if (class_exists('Elementor\Plugin') && \Elementor\Plugin::$instance->documents->get(get_the_ID())->is_built_with_elementor()) {
1630
1631 $page_settings = get_post_meta($post_id, '_elementor_data', true);
1632
1633 $ep_settings = Helper::ep_get_elementor_widget_settings($page_settings, $id_value, 'embedpres_elementor');
1634 $pdf_settings = Helper::ep_get_elementor_widget_settings($page_settings, $id_value, 'embedpress_pdf');
1635 $doc_settings = Helper::ep_get_elementor_widget_settings($page_settings, $id_value, 'embedpres_document');
1636
1637 if (is_array($ep_settings) && !empty($ep_settings)) {
1638 $title = !empty($ep_settings[0]['embedpress_content_title']) ? $ep_settings[0]['embedpress_content_title'] : '';
1639
1640 $description = !empty($ep_settings[0]['embedpress_content_descripiton']) ? $ep_settings[0]['embedpress_content_descripiton'] : '';
1641
1642 $image_url = !empty($ep_settings[0]['embedpress_content_share_custom_thumbnail']['url']) ? $ep_settings[0]['embedpress_content_share_custom_thumbnail']['url'] : '';
1643 } else if (is_array($pdf_settings) && !empty($pdf_settings)) {
1644 $title = !empty($pdf_settings[0]['embedpress_pdf_content_title']) ? $pdf_settings[0]['embedpress_pdf_content_title'] : '';
1645
1646 $description = !empty($pdf_settings[0]['embedpress_pdf_content_descripiton']) ? $pdf_settings[0]['embedpress_pdf_content_descripiton'] : '';
1647
1648 $image_url = !empty($pdf_settings[0]['embedpress_pdf_content_share_custom_thumbnail']['url']) ? $pdf_settings[0]['embedpress_pdf_content_share_custom_thumbnail']['url'] : '';
1649 } else if (is_array($doc_settings) && !empty($doc_settings)) {
1650 $title = !empty($doc_settings[0]['embedpress_doc_content_title']) ? $doc_settings[0]['embedpress_doc_content_title'] : '';
1651
1652 $description = !empty($doc_settings[0]['embedpress_doc_content_descripiton']) ? $doc_settings[0]['embedpress_doc_content_descripiton'] : '';
1653
1654 $image_url = !empty($doc_settings[0]['embedpress_doc_content_share_custom_thumbnail']['url']) ? $doc_settings[0]['embedpress_doc_content_share_custom_thumbnail']['url'] : '';
1655 }
1656
1657 if (!empty($image_url)) {
1658 $tags .= "<meta name='twitter:image' content='" . esc_url($image_url) . "'/>\n";
1659 $tags .= "<meta property='og:image' content='" . esc_url($image_url) . "'/>\n";
1660 } else if (!empty($thumbnail_url)) {
1661 $tags .= "<meta name='twitter:image' content='" . esc_url($thumbnail_url) . "'/>\n";
1662 $tags .= "<meta property='og:image' content='" . esc_url($thumbnail_url) . "'/>\n";
1663 }
1664
1665 if (!empty($title)) {
1666 $title = json_decode('"' . $title . '"', JSON_UNESCAPED_UNICODE);
1667 $tags .= "<meta property='og:title' content='" . esc_attr($title) . "'/>\n";
1668 $tags .= "<meta name='title' content='" . esc_attr($title) . "'>\n";
1669 $tags .= "<meta name='twitter:title' content='" . esc_attr($title) . "'/>\n";
1670
1671 }
1672
1673 if (!empty($description)) {
1674 $description = json_decode('"' . $description . '"', JSON_UNESCAPED_UNICODE);
1675 $tags .= "<meta property='og:description' content='" . esc_attr($description) . "'/>\n";
1676 $tags .= "<meta name='description' content='" . esc_attr($description) . "'/>\n";
1677 $tags .= "<meta name='twitter:description' content='" . esc_attr($description) . "'/>\n";
1678
1679 }
1680
1681 } else {
1682
1683 $block_content = $post->post_content;
1684
1685 // Regular expression to match the id and href keys and their values
1686 $thumb = '/(?:"id":"' . $id_value . '"|"clientId":"' . $id_value . '").*?"customThumbnail":"(.*?)"/';
1687 $title_regex = '/(?:"id":"' . $id_value . '"|"clientId":"' . $id_value . '").*?"customTitle":"(.*?)"/';
1688 $description_regex = '/(?:"id":"' . $id_value . '"|"clientId":"' . $id_value . '").*?"customDescription":"(.*?)"/';
1689
1690 // Search for the regex pattern in the string and extract the href value
1691 if (preg_match($thumb, $block_content, $matches1)) {
1692 $image_url = esc_url($matches1[1]);
1693 $tags .= "\n<meta name='twitter:image' content='" . esc_attr($image_url) . "'/>\n";
1694 $tags .= "<meta property='og:image' content='" . esc_attr($image_url) . "'/>\n";
1695
1696 } else if (!empty($thumbnail_url)) {
1697 $tags .= "\n<meta name='twitter:image' content='" . esc_attr($thumbnail_url) . "'/>\n";
1698 $tags .= "<meta property='og:image' content='" . esc_attr($thumbnail_url) . "'/>\n";
1699 }
1700
1701 if (preg_match($title_regex, $block_content, $matches2)) {
1702 $title = json_decode('"' . $matches2[1] . '"', JSON_UNESCAPED_UNICODE);
1703 $tags .= "<meta property='og:title' content='" . esc_attr($title) . "'/>\n";
1704 $tags .= "<meta name='title' content='" . esc_attr($title) . "'>\n";
1705 $tags .= "<meta name='twitter:title' content='" . esc_attr($title) . "'/>\n";
1706
1707 }
1708
1709 if (preg_match($description_regex, $block_content, $matches3)) {
1710 $description = json_decode('"' . $matches3[1] . '"', JSON_UNESCAPED_UNICODE);
1711 $tags .= "<meta property='og:description' content='" . esc_attr($description) . "'/>\n";
1712 $tags .= "<meta name='description' content='" . esc_attr($description) . "'/>\n";
1713 $tags .= "<meta name='twitter:description' content='" . esc_attr($description) . "'/>\n";
1714
1715 }
1716 }
1717
1718 $share_url = !empty($unique_hash) ? "$url?hash=$id_value&unique=$unique_hash" : "$url?hash=$id_value";
1719 $tags .= "<meta property='og:url' content='". $share_url . "'/>\n";
1720 $tags .= "<meta name='twitter:card' content='summary_large_image'/>\n";
1721
1722 // Add Open Graph type for better LinkedIn compatibility
1723 $tags .= "<meta property='og:type' content='article'/>\n";
1724
1725 remove_action('wp_head', 'rel_canonical');
1726
1727 echo $tags;
1728 }
1729 }
1730 }
1731