PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.3.1
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.3.1
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 / Helper.php
embedpress / EmbedPress / Includes / Classes Last commit date
Elementor_Enhancer.php 1 year 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 Feature_Enhancer.php 1 year ago Helper.php 11 months ago PermalinkHelper.php 10 months ago
Helper.php
1610 lines
1 <?php
2
3 namespace EmbedPress\Includes\Classes;
4
5 use EmbedPress\Providers\TemplateLayouts\YoutubeLayout;
6 use EmbedPress\Shortcode;
7
8 use Elementor\Plugin;
9
10
11 if (!defined('ABSPATH')) {
12 exit;
13 } // Exit if accessed directly
14
15 class Helper
16 {
17
18 /**
19 * Parse a query string into an associative array.
20 *
21 * If multiple values are found for the same key, the value of that key
22 * value pair will become an array. This function does not parse nested
23 * PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will
24 * be parsed into ['foo[a]' => '1', 'foo[b]' => '2']).
25 *
26 * @param string $str Query string to parse
27 * @param int|bool $urlEncoding How the query string is encoded
28 *
29 * @return array
30 */
31
32 public function __construct()
33 {
34 add_action('wp_ajax_lock_content_form_handler', [$this, 'lock_content_form_handler']);
35 add_action('wp_ajax_nopriv_lock_content_form_handler', [$this, 'lock_content_form_handler']);
36
37
38 add_action('wp_ajax_loadmore_data_handler', [$this, 'loadmore_data_handler']);
39 add_action('wp_ajax_nopriv_loadmore_data_handler', [$this, 'loadmore_data_handler']);
40
41
42 add_action('wp_ajax_fetch_video_description', [$this, 'ajax_video_popup_description']);
43 add_action('wp_ajax_nopriv_fetch_video_description', [$this, 'ajax_video_popup_description']);
44 }
45
46 public function ajax_video_popup_description()
47 {
48 if (isset($_POST['vid'])) {
49 $api_key = self::get_api_key();
50 $vid = sanitize_text_field($_POST['vid']);
51
52 $video_data = Helper::get_youtube_video_data($api_key, $vid);
53
54 if ($video_data) {
55 ob_start();
56 ?>
57 <div class="video-description">
58 <?php echo YoutubeLayout::generate_youtube_video_description($video_data); ?>
59 </div>
60 <?php
61 $description_html = ob_get_clean();
62 wp_send_json_success(['description' => $description_html]);
63 } else {
64 wp_send_json_error(['error' => 'Failed to fetch video data.']);
65 }
66 } else {
67 wp_send_json_error(['error' => 'Invalid video ID.']);
68 }
69 }
70
71 public static function get_api_key()
72 {
73 $settings = (array) get_option(EMBEDPRESS_PLG_NAME . ':youtube', []);
74 return !empty($settings['api_key']) ? $settings['api_key'] : '';
75 }
76
77 public static function parse_query($str, $urlEncoding = true)
78 {
79 $result = [];
80
81 if ($str === '') {
82 return $result;
83 }
84
85 if ($urlEncoding === true) {
86 $decoder = function ($value) {
87 return rawurldecode(str_replace('+', ' ', $value));
88 };
89 } elseif ($urlEncoding === PHP_QUERY_RFC3986) {
90 $decoder = 'rawurldecode';
91 } elseif ($urlEncoding === PHP_QUERY_RFC1738) {
92 $decoder = 'urldecode';
93 } else {
94 $decoder = function ($str) {
95 return $str;
96 };
97 }
98
99 foreach (explode('&', $str) as $kvp) {
100 $parts = explode('=', $kvp, 2);
101 $key = $decoder($parts[0]);
102 $value = isset($parts[1]) ? $decoder($parts[1]) : null;
103 if (!isset($result[$key])) {
104 $result[$key] = $value;
105 } else {
106 if (!is_array($result[$key])) {
107 $result[$key] = [$result[$key]];
108 }
109 $result[$key][] = $value;
110 }
111 }
112
113 return $result;
114 }
115 public static function get_pdf_renderer()
116 {
117 // $renderer = EMBEDPRESS_URL_ASSETS . 'pdf/web/viewer.html';
118
119 $renderer = admin_url('admin-ajax.php?action=get_viewer');
120
121 // @TODO; apply settings query args here
122 return $renderer;
123 }
124
125 public static function get_extension_from_file_url($url)
126 {
127 $urlSplit = explode(".", $url);
128 $ext = end($urlSplit);
129 return $ext;
130 }
131
132 public static function is_file_url($url)
133 {
134 $pattern = '/\.([0-9a-z]+)(?=[?#])|(\.)(?:[\w]+)$/i';
135 return preg_match($pattern, $url) === 1;
136 }
137
138 public static function is_opensea($url)
139 {
140 return strpos($url, "opensea.io") !== false;
141 }
142 public static function is_youtube_channel($url)
143 {
144 return (bool) (preg_match('~(?:https?:\/\/)?(?:www\.)?(?:youtube.com\/)(?:channel\/|c\/|user\/|@)(\w+)~i', (string) $url));
145 }
146
147 public static function is_youtube($url)
148 {
149 return (bool) (preg_match('~(?:https?://)?(?:www\.)?(?:youtube\.com|youtu\.be)/watch\?v=([^&]+)~i', (string) $url));
150 }
151
152 // Saved sources data temporary in wp_options table
153 public static function get_source_data($blockid, $source_url, $source_option_name, $source_temp_option_name)
154 {
155
156
157 if (self::is_youtube_channel($source_url)) {
158 $source_name = 'YoutubeChannel';
159 } else if (self::is_youtube($source_url)) {
160 $source_name = 'Youtube';
161 } else if (!empty(self::is_file_url($source_url))) {
162 $source_name = 'document_' . self::get_extension_from_file_url($source_url);
163 } else if (self::is_opensea($source_url)) {
164 $source_name = 'OpenSea';
165 } else {
166 Shortcode::get_embera_instance();
167 $collectios = Shortcode::get_collection();
168 $provider = $collectios->findProviders($source_url);
169
170 if (!empty($provider[$source_url])) {
171 $source_name = $provider[$source_url]->getProviderName();
172 } else {
173 $host = parse_url($source_url, PHP_URL_HOST);
174 if ($host) {
175 $parts = explode('.', $host);
176 if (count($parts) > 1) {
177 $source_name = $parts[1];
178 } else {
179 // Handle the case where the host doesn't have at least two parts
180 $source_name = $host;
181 }
182 } else {
183 // Handle the case where parse_url fails
184 $source_name = 'unknown';
185 }
186 }
187 }
188
189 if (!empty($blockid) && $blockid != 'undefined') {
190 $sources = json_decode(get_option($source_temp_option_name), true);
191
192 if (!$sources) {
193 $sources = array();
194 }
195 $exists = false;
196
197 foreach ($sources as $i => $source) {
198 if ($source['id'] === $blockid) {
199 $sources[$i]['source']['name'] = $source_name;
200 $sources[$i]['source']['url'] = $source_url;
201 $exists = true;
202 break;
203 }
204 }
205
206 if (!$exists) {
207 $sources[] = array('id' => $blockid, 'source' => array('name' => $source_name, 'url' => $source_url, 'count' => 1));
208 }
209
210 update_option($source_temp_option_name, json_encode($sources));
211 }
212 }
213
214 // Saved source data when post updated
215 public static function get_save_source_data_on_post_update($source_option_name, $source_temp_option_name)
216 {
217
218 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
219 return;
220 }
221 $temp_data = json_decode(get_option($source_temp_option_name), true);
222 $source_data = json_decode(get_option($source_option_name), true);
223 if (!$temp_data) {
224 $temp_data = array();
225 }
226 if (!$source_data) {
227 $source_data = array();
228 }
229
230 $sources = array_merge($temp_data, $source_data);
231
232 $unique_sources = array();
233 foreach ($sources as $source) {
234 $unique_sources[$source['id']] = $source;
235 }
236
237 $unique_sources = array_values($unique_sources);
238
239 delete_option($source_temp_option_name);
240
241 update_option($source_option_name, json_encode($unique_sources));
242 }
243
244 //Delete source data from option table when widget is removed
245 public static function get_delete_source_data($blockid, $source_option_name, $source_temp_option_name)
246 {
247 if (!empty($blockid) && $blockid != 'undefined') {
248 $sources = json_decode(get_option($source_option_name), true);
249 $temp_sources = json_decode(get_option($source_temp_option_name), true);
250 if ($sources) {
251 foreach ($sources as $i => $source) {
252 if ($source['id'] === $blockid) {
253 unset($sources[$i]);
254 break;
255 }
256 }
257 update_option($source_option_name, json_encode(array_values($sources)));
258 }
259 if ($temp_sources) {
260 foreach ($temp_sources as $i => $source) {
261 if ($source['id'] === $blockid) {
262 unset($temp_sources[$i]);
263 break;
264 }
265 }
266 update_option($source_temp_option_name, json_encode(array_values($temp_sources)));
267 }
268 }
269 wp_die();
270 }
271
272 //Delete source temporary data when reload without update or publish
273 public static function get_delete_source_temp_data_on_reload($source_temp_option_name)
274 {
275 $source_temp_data = json_decode(get_option($source_temp_option_name), true);
276 if ($source_temp_data) {
277 delete_option($source_temp_option_name);
278 }
279 }
280
281 public static function get_file_title($url)
282 {
283 return get_the_title(attachment_url_to_postid($url));
284 }
285
286 public static function get_hash()
287 {
288 $hash_key = get_option(EMBEDPRESS_PLG_NAME . '_hash_key');
289 if (!$hash_key) {
290 $hash_key = wp_hash_password(wp_generate_password(30));
291 update_option(EMBEDPRESS_PLG_NAME . '_hash_key', $hash_key);
292 }
293 return $hash_key;
294 }
295
296 public function lock_content_form_handler()
297 {
298
299 $client_id = isset($_POST['client_id']) ? sanitize_text_field($_POST['client_id']) : '';
300 $password = isset($_POST['password']) ? sanitize_text_field($_POST['password']) : '';
301 $post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
302
303 $epbase64 = get_post_meta($post_id, 'ep_base_' . $client_id, false);
304 $hash_key = get_post_meta($post_id, 'hash_key_' . $client_id, false);
305
306 // Set the decryption key and initialization vector (IV)
307 $key = self::get_hash();
308
309 // Decode the base64 encoded cipher
310 $cipher = base64_decode($epbase64);
311 // Decrypt the cipher using AES-128-CBC encryption
312
313 $wp_pass_key = hash('sha256', wp_salt(32) . md5($password));
314 $iv = substr($wp_pass_key, 0, 16);
315 if ($wp_pass_key === $hash_key) {
316 setcookie("password_correct_", $password, time() + 3600);
317
318 $embed = openssl_decrypt($cipher, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv) . '<script>
319 const now = new Date();
320 const time = now.getTime();
321 const expireTime = time + 1000 * 60 * 60 * 24 * 30;
322 now.setTime(expireTime);
323 document.cookie = "password_correct_' . esc_js($client_id) . '=' . esc_js($hash_key) . '; expires=" + now.toUTCString() + "; path=/";
324 </script>';
325 } else {
326 $embed = 0;
327 }
328
329 // Process the form data and return a response
330 $response = array(
331 'success' => true,
332 'password' => $password,
333 'embedHtml' => $embed,
334 );
335
336 wp_send_json($response);
337 }
338
339 public static function display_password_form($client_id = '', $embedHtml = '', $pass_hash_key = '', $attributes = [])
340 {
341 $lock_heading = !empty($attributes['lockHeading']) ? sanitize_text_field($attributes['lockHeading']) : '';
342 $lock_subheading = !empty($attributes['lockSubHeading']) ? sanitize_text_field($attributes['lockSubHeading']) : '';
343 $lock_error_message = !empty($attributes['lockErrorMessage']) ? sanitize_text_field($attributes['lockErrorMessage']) : '';
344 $footer_message = !empty($attributes['footerMessage']) ? sanitize_text_field($attributes['footerMessage']) : '';
345 $password_placeholder = !empty($attributes['passwordPlaceholder']) ? sanitize_text_field($attributes['passwordPlaceholder']) : '';
346 $button_text = !empty($attributes['submitButtonText']) ? sanitize_text_field($attributes['submitButtonText']) : '';
347 $unlocking_text = !empty($attributes['submitUnlockingText']) ? sanitize_text_field($attributes['submitUnlockingText']) : '';
348 $enable_footer_message = !empty($attributes['enableFooterMessage']) ? sanitize_text_field($attributes['enableFooterMessage']) : '';
349
350
351 // Set the encryption key and initialization vector (IV)
352 $key = self::get_hash();
353
354 $salt = wp_salt(32);
355 $wp_hash_key = hash('sha256', $salt . $pass_hash_key);
356 $iv = substr($wp_hash_key, 0, 16);
357
358
359 // Encrypt the plaintext using AES-128-CBC encryption
360 $cipher = openssl_encrypt($embedHtml, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
361
362 // Base64 encode the encrypted cipher
363 $encrypted_data = base64_encode($cipher);
364
365 update_post_meta(get_the_ID(), 'ep_base_' . $client_id, $encrypted_data);
366 update_post_meta(get_the_ID(), 'hash_key_' . $client_id, $wp_hash_key);
367
368 $lock_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><g fill="#6354a5" class="color134563 svgShape"><path d="M46.3 28.7h-3v-6.4C43.3 16.1 38.2 11 32 11c-6.2 0-11.3 5.1-11.3 11.3v6.4h-3v-6.4C17.7 14.4 24.1 8 32 8s14.3 6.4 14.3 14.3v6.4" fill="#6354a5" class="color000000 svgShape"></path><path d="M44.8 55.9H19.2c-2.6 0-4.8-2.2-4.8-4.8V31.9c0-2.6 2.2-4.8 4.8-4.8h25.6c2.6 0 4.8 2.2 4.8 4.8v19.2c0 2.7-2.2 4.8-4.8 4.8zM19.2 30.3c-.9 0-1.6.7-1.6 1.6v19.2c0 .9.7 1.6 1.6 1.6h25.6c.9 0 1.6-.7 1.6-1.6V31.9c0-.9-.7-1.6-1.6-1.6H19.2z" fill="#6354a5" class="color000000 svgShape"></path><path d="M35.2 36.7c0 1.8-1.4 3.2-3.2 3.2s-3.2-1.4-3.2-3.2 1.4-3.2 3.2-3.2 3.2 1.5 3.2 3.2" fill="#6354a5" class="color000000 svgShape"></path><path d="M32.8 36.7h-1.6l-1.6 9.6h4.8l-1.6-9.6" fill="#6354a5" class="color000000 svgShape"></path></g></svg>';
369
370 echo '
371 <div class="password-form-container">
372 <h2>' . esc_html($lock_heading) . '</h2>
373 <p>' . esc_html($lock_subheading) . ' </p>
374 <form class="password-form" method="post" class="password-form" data-unlocking-text="' . esc_attr($unlocking_text) . '">
375
376 <div class="password-field">
377 <span class="lock-icon">' . $lock_icon . '</span>
378 <input type="password" name="pass_' . esc_attr($client_id) . '" placeholder="' . esc_attr($password_placeholder) . '" required>
379 </div>
380 <input type="hidden" name="ep_client_id" value="' . esc_attr($client_id) . '">
381 <input type="hidden" name="post_id" value="' . esc_attr(get_the_ID()) . '">
382
383 <input type="submit" name="password_submit" value="' . esc_attr($button_text) . '">
384 <div class="error-message hidden">' . esc_html($lock_error_message) . '</div>
385 </form>
386 ' . (!empty($enable_footer_message) ? '<p class="need-access-message">' . esc_html($footer_message) . '</p>' : '') . '
387 </div>
388 ';
389 }
390
391 // Check if the user has already entered the correct password
392 public static function is_password_correct($client_id)
393 {
394 if (isset($_COOKIE['password_correct_' . $client_id])) {
395 return $_COOKIE['password_correct_' . $client_id];
396 } else {
397 return false;
398 }
399 }
400
401 public static function customLogo($embedHTML, $atts)
402 {
403 $x = !empty($atts['logoX']) ? $atts['logoX'] : 0;
404 $y = !empty($atts['logoY']) ? $atts['logoY'] : 0;
405 $uniqid = !empty($atts['url']) ? '.ose-uid-' . md5($atts['url']) : '';
406
407 $brandUrl = !empty($atts['customlogoUrl']) ? $atts['customlogoUrl'] : '';
408 $opacity = !empty($atts['logoOpacity']) ? $atts['logoOpacity'] : '';
409
410 $cssClass = !empty($atts['url']) ? '.ose-uid-' . md5($atts['url']) : '.ose-youtube';
411
412
413
414 ob_start(); ?>
415 <style type="text/css">
416 <?php echo esc_html($cssClass); ?> {
417 position: relative;
418 }
419
420 <?php echo esc_html($cssClass); ?>.watermark {
421 border: 0;
422 position: absolute;
423 bottom: <?php echo esc_html($y); ?>%;
424 right: <?php echo esc_html($x); ?>%;
425 max-width: 150px;
426 max-height: 75px;
427 opacity: 0.25;
428 z-index: 5;
429 -o-transition: opacity 0.5s ease-in-out;
430 -moz-transition: opacity 0.5s ease-in-out;
431 -webkit-transition: opacity 0.5s ease-in-out;
432 transition: opacity 0.5s ease-in-out;
433 opacity: <?php echo esc_html($opacity); ?>;
434 }
435
436 <?php echo esc_html($cssClass); ?>.watermark:hover {
437 opacity: 1;
438 }
439 </style>
440 <?php
441
442
443 $style = ob_get_clean();
444
445 if (!class_exists('\simple_html_dom')) {
446 include_once EMBEDPRESS_PATH_CORE . 'simple_html_dom.php';
447 }
448
449 $cta = '';
450 $img = '';
451
452 if (!empty($atts['customlogo'])) {
453 $img = '<img src="' . esc_url($atts['customlogo']) . '"/>';
454
455 $imgDom = str_get_html($img);
456 $imgDom = $imgDom->find('img', 0);
457 $imgDom->setAttribute('class', 'watermark ep-custom-logo');
458 $imgDom->removeAttribute('style');
459 $imgDom->setAttribute('width', 'auto');
460 $imgDom->setAttribute('height', 'auto');
461 ob_start();
462 echo $imgDom;
463
464 $cta .= ob_get_clean();
465
466 $imgDom->clear();
467 unset($img, $imgDom);
468
469 if (!empty($brandUrl)) {
470 $cta = '<a href="' . esc_url($brandUrl) . '" target="_blank">' . $cta . '</a>';
471 }
472 $dom = str_get_html($embedHTML);
473
474 $wrapDiv = $dom->find($uniqid, 0);
475
476 if (!empty($wrapDiv) && is_object($wrapDiv)) {
477 $wrapDiv->innertext .= $cta;
478 }
479
480 ob_start();
481 echo $wrapDiv;
482
483 $markup = ob_get_clean();
484
485 $dom->clear();
486 unset($dom, $wrapDiv);
487
488 $embedHTML = $style . $markup;
489 }
490
491 return $embedHTML;
492 }
493
494
495 public static function embed_content_share($content_id = '', $attributes = [])
496 {
497 $share_position = !empty($attributes['sharePosition']) ? $attributes['sharePosition'] : 'right';
498 $custom_thumnail = !empty($attributes['customThumbnail']) ? $attributes['customThumbnail'] : '';
499 $custom_title = !empty($attributes['customTitle']) ? $attributes['customTitle'] : '';
500 $custom_description = !empty($attributes['customDescription']) ? $attributes['customDescription'] : '';
501
502 // Create a unique hash based on content attributes
503 $content_hash = md5($custom_thumnail . $custom_title . $custom_description . $content_id);
504
505 // Encode for URL usage
506 $custom_thumnail = urlencode($custom_thumnail);
507 $custom_title = urlencode($custom_title);
508 $custom_description = urlencode($custom_description);
509
510 // Get social share options with defaults
511 $facebook_enabled = isset($attributes['shareFacebook']) ? $attributes['shareFacebook'] !== false : true;
512 $twitter_enabled = isset($attributes['shareTwitter']) ? $attributes['shareTwitter'] !== false : true;
513 $pinterest_enabled = isset($attributes['sharePinterest']) ? $attributes['sharePinterest'] !== false : true;
514 $linkedin_enabled = isset($attributes['shareLinkedin']) ? $attributes['shareLinkedin'] !== false : true;
515 $style = isset($attributes['width']) ? 'style="max-width: '.esc_attr($attributes['width']).'px;"' : '';
516
517
518 $page_url = urlencode(get_permalink() . '?hash=' . $content_id . '&unique=' . $content_hash);
519
520 $social_icons = '<div class="ep-social-share-wraper"'.$style.' ><div class="ep-social-share share-position-' . esc_attr($share_position) . '">';
521
522
523 // Facebook
524 if ($facebook_enabled) {
525 $social_icons .= '<a href="https://www.facebook.com/sharer/sharer.php?u=' . $page_url . '" class="ep-social-icon facebook" target="_blank">
526 <svg width="64px" height="64px" fill="#000000" viewBox="0 -6 512 512" xmlns="http://www.w3.org/2000/svg">
527 <path d="M0 0h512v500H0z" fill="#475a96"/>
528 <path d="m375.72 112.55h-237.43c-8.137 0-14.73 6.594-14.73 14.73v237.43c0 8.135 6.594 14.73 14.73 14.73h127.83v-103.36h-34.781v-40.28h34.781v-29.705c0-34.473 21.055-53.244 51.807-53.244 14.73 0 27.391 1.097 31.08 1.587v36.026l-21.328 0.01c-16.725 0-19.963 7.947-19.963 19.609v25.717h39.887l-5.193 40.28h-34.693v103.36h68.012c8.135 0 14.73-6.596 14.73-14.73v-237.43c-1e-3 -8.137-6.596-14.73-14.731-14.73z" fill="#fff"/>
529 </svg>
530 </a>';
531 }
532
533 // Twitter
534 if ($twitter_enabled) {
535 $social_icons .= '<a href="https://twitter.com/intent/tweet?url=' . $page_url . '&text=' . $custom_title . '" class="ep-social-icon twitter" target="_blank">
536 <svg viewBox="0 0 24 24" aria-hidden="true" fill="#fff" class="r-4qtqp9 r-yyyyoo r-dnmrzs r-bnwqim r-lrvibr r-m6rgpd r-lrsllp r-1nao33i r-16y2uox r-8kz0gk"><g><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></g></svg>
537 </a>';
538 }
539
540 // Pinterest
541 if ($pinterest_enabled) {
542 $social_icons .= '<a href="http://pinterest.com/pin/create/button/?url=' . $page_url . '&media=' . $custom_thumnail . '&description=' . $custom_description . '" class="ep-social-icon pinterest" target="_blank">
543
544 <svg xmlns="http://www.w3.org/2000/svg" height="800" width="1200" viewBox="-36.42015 -60.8 315.6413 364.8"><path d="M121.5 0C54.4 0 0 54.4 0 121.5 0 173 32 217 77.2 234.7c-1.1-9.6-2-24.4.4-34.9 2.2-9.5 14.2-60.4 14.2-60.4s-3.6-7.3-3.6-18c0-16.9 9.8-29.5 22-29.5 10.4 0 15.4 7.8 15.4 17.1 0 10.4-6.6 26-10.1 40.5-2.9 12.1 6.1 22 18 22 21.6 0 38.2-22.8 38.2-55.6 0-29.1-20.9-49.4-50.8-49.4-34.6 0-54.9 25.9-54.9 52.7 0 10.4 4 21.6 9 27.7 1 1.2 1.1 2.3.8 3.5-.9 3.8-3 12.1-3.4 13.8-.5 2.2-1.8 2.7-4.1 1.6-15.2-7.1-24.7-29.2-24.7-47.1 0-38.3 27.8-73.5 80.3-73.5 42.1 0 74.9 30 74.9 70.2 0 41.9-26.4 75.6-63 75.6-12.3 0-23.9-6.4-27.8-14 0 0-6.1 23.2-7.6 28.9-2.7 10.6-10.1 23.8-15.1 31.9 11.4 3.5 23.4 5.4 36 5.4 67.1 0 121.5-54.4 121.5-121.5C243 54.4 188.6 0 121.5 0z" fill="#fff"/></svg>
545
546 </a>';
547 }
548
549 // LinkedIn
550 if ($linkedin_enabled) {
551 $social_icons .= '<a href="https://www.linkedin.com/shareArticle?mini=true&url=' . $page_url. '" class="ep-social-icon linkedin" target="_blank">
552
553 <svg fill="#ffffff" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
554 viewBox="0 0 310 310" xml:space="preserve">
555 <g id="XMLID_801_">
556 <path id="XMLID_802_" d="M72.16,99.73H9.927c-2.762,0-5,2.239-5,5v199.928c0,2.762,2.238,5,5,5H72.16c2.762,0,5-2.238,5-5V104.73
557 C77.16,101.969,74.922,99.73,72.16,99.73z"/>
558 <path id="XMLID_803_" d="M41.066,0.341C18.422,0.341,0,18.743,0,41.362C0,63.991,18.422,82.4,41.066,82.4
559 c22.626,0,41.033-18.41,41.033-41.038C82.1,18.743,63.692,0.341,41.066,0.341z"/>
560 <path id="XMLID_804_" d="M230.454,94.761c-24.995,0-43.472,10.745-54.679,22.954V104.73c0-2.761-2.238-5-5-5h-59.599
561 c-2.762,0-5,2.239-5,5v199.928c0,2.762,2.238,5,5,5h62.097c2.762,0,5-2.238,5-5v-98.918c0-33.333,9.054-46.319,32.29-46.319
562 c25.306,0,27.317,20.818,27.317,48.034v97.204c0,2.762,2.238,5,5,5H305c2.762,0,5-2.238,5-5V194.995
563 C310,145.43,300.549,94.761,230.454,94.761z"/>
564 </g>
565 </svg>
566 </a>';
567 }
568
569 $social_icons .= '</div></div>';
570
571 return $social_icons;
572 }
573
574 public static function ep_get_elementor_widget_settings($page_settings = '', $id = '', $widgetType = '') {
575 if (empty($page_settings)) {
576 return [];
577 }
578
579 $data = json_decode($page_settings, true);
580 $element_setting = null;
581
582 Plugin::$instance->db->iterate_data($data, function ($element) use (&$element_setting, $widgetType, $id) {
583
584 if ($element['id'] == $id && $element['elType'] == 'widget' && $element['widgetType'] == $widgetType) {
585 $element_setting[] = $element['settings'];
586 }
587
588 });
589
590 return $element_setting;
591 }
592
593
594
595 public static function ep_get_popup_icon()
596 {
597 $svg = '<div class="ep-doc-popup-icon" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" xml:space="preserve"><path fill="#fff" d="M5 3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-6l-2-2v8H5V5h8l-2-2H5zm9 0 2.7 2.7-7.5 7.5 1.7 1.7 7.5-7.5L21 10V3h-7z"/><path style="fill:none" d="M0 0h24v24H0z"/></svg></div>';
598
599 return $svg;
600 }
601 public static function ep_get_download_icon()
602 {
603 $svg = '<div class="ep-doc-download-icon" ><svg width="25" height="25" viewBox="0 0 0.6 0.6" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" fill-rule="evenodd" d="M.525.4A.025.025 0 0 1 .55.422v.053A.075.075 0 0 1 .479.55H.125A.075.075 0 0 1 .05.479V.425A.025.025 0 0 1 .1.422v.053A.025.025 0 0 0 .122.5h.353A.025.025 0 0 0 .5.478V.425A.025.025 0 0 1 .525.4ZM.3.05a.025.025 0 0 1 .025.025v.24L.357.283A.025.025 0 0 1 .39.281l.002.002a.025.025 0 0 1 .002.033L.392.318.317.393.316.394.314.395.311.397.308.398.305.399.301.4H.295L.292.399.289.398.287.397.285.395A.025.025 0 0 1 .283.393L.208.318A.025.025 0 0 1 .241.281l.002.002.032.032v-.24A.025.025 0 0 1 .3.05Z"/></svg></div>';
604
605 return $svg;
606 }
607
608 public static function ep_get_print_icon()
609 {
610 $svg = '<div class="ep-doc-print-icon" ><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24">
611 <path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z" fill="#fff"/>
612 </svg></div>';
613
614 return $svg;
615 }
616
617 public static function ep_get_fullscreen_icon()
618 {
619 $svg = '<div class="ep-doc-fullscreen-icon"><svg width="25" height="25" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
620 <path d="m3 15 .117.007a1 1 0 0 1 .876.876L4 16v4h4l.117.007a1 1 0 0 1 0 1.986L8 22H3l-.117-.007a1 1 0 0 1-.876-.876L2 21v-5l.007-.117a1 1 0 0 1 .876-.876L3 15Zm18 0a1 1 0 0 1 .993.883L22 16v5a1 1 0 0 1-.883.993L21 22h-5a1 1 0 0 1-.117-1.993L16 20h4v-4a1 1 0 0 1 .883-.993L21 15ZM8 2a1 1 0 0 1 .117 1.993L8 4H4v4a1 1 0 0 1-.883.993L3 9a1 1 0 0 1-.993-.883L2 8V3a1 1 0 0 1 .883-.993L3 2h5Zm13 0 .117.007a1 1 0 0 1 .876.876L22 3v5l-.007.117a1 1 0 0 1-.876.876L21 9l-.117-.007a1 1 0 0 1-.876-.876L20 8V4h-4l-.117-.007a1 1 0 0 1 0-1.986L16 2h5Z" fill="#fff"/>
621 </svg></div>';
622
623 return $svg;
624 }
625 public static function ep_get_minimize_icon()
626 {
627 $svg = '<div class="ep-doc-minimize-icon" style="display:none"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" style="enable-background:new 0 0 385.331 385.331" xml:space="preserve" width="20" height="20"><path fill="#fff" d="M13.751 8.131h5.62c0.355 0 0.619 -0.28 0.619 -0.634 0 -0.355 -0.265 -0.615 -0.619 -0.614h-4.995V1.878c0 -0.355 -0.27 -0.624 -0.624 -0.624s-0.624 0.27 -0.624 0.624v5.62c0 0.002 0.001 0.003 0.001 0.004 0 0.002 -0.001 0.003 -0.001 0.005 0 0.348 0.276 0.625 0.624 0.624zM6.244 1.259c-0.354 0 -0.614 0.265 -0.614 0.619v4.995H0.624c-0.355 0 -0.624 0.27 -0.624 0.624 0 0.355 0.27 0.624 0.624 0.624h5.62c0.002 0 0.003 -0.001 0.004 -0.001 0.002 0 0.003 0.001 0.005 0.001 0.348 0 0.624 -0.276 0.624 -0.624V1.878c0 -0.354 -0.28 -0.619 -0.634 -0.619zm0.005 10.61H0.629c-0.355 0.001 -0.619 0.28 -0.619 0.634 0 0.355 0.265 0.615 0.619 0.614h4.995v5.005c0 0.355 0.27 0.624 0.624 0.624 0.355 0 0.624 -0.27 0.624 -0.624V12.502c0 -0.002 -0.001 -0.003 -0.001 -0.004 0 -0.002 0.001 -0.003 0.001 -0.005 0 -0.348 -0.276 -0.624 -0.624 -0.624zm13.127 0H13.756c-0.002 0 -0.003 0.001 -0.004 0.001 -0.002 0 -0.003 -0.001 -0.005 -0.001 -0.348 0 -0.624 0.276 -0.624 0.624v5.62c0 0.355 0.28 0.619 0.634 0.619 0.354 0.001 0.614 -0.265 0.614 -0.619v-4.995H19.376c0.355 0 0.624 -0.27 0.624 -0.624s-0.27 -0.624 -0.624 -0.625z"/><g/><g/><g/><g/><g/><g/></svg></div>';
628
629 return $svg;
630 }
631 public static function ep_get_draw_icon()
632 {
633 $svg = '<div class="ep-doc-draw-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="m15 7.5 2.5 2.5m-10 10L19.25 8.25c0.69 -0.69 0.69 -1.81 0 -2.5v0c-0.69 -0.69 -1.81 -0.69 -2.5 0L5 17.5V20h2.5Zm0 0h8.379C17.05 20 18 19.05 18 17.879v0c0 -0.563 -0.224 -1.103 -0.621 -1.5L17 16M4.5 5c2 -2 5.5 -1 5.5 1 0 2.5 -6 2.5 -6 5 0 0.876 0.533 1.526 1.226 2" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>';
634
635 return $svg;
636 }
637
638 public static function get_insta_video_icon()
639 {
640 $svg = '<svg class="insta-video-icon" aria-label="Clip" class="x1lliihq x1n2onr6" color="#FFF" fill="#FFF" height="20" viewBox="1.111 1.111 24.444 24.447" width="20">
641 <path d="m14.248 1.111 3.304 5.558h-6.2L8.408 1.146c.229-.014.466-.024.713-.03l.379-.005Zm2.586 0h.331c3.4 0 4.964.838 6.267 2.097a6.674 6.674 0 0 1 1.773 3.133l.078.328H20.14l-3.307-5.558ZM6.093 1.53l2.74 5.139H1.382a6.678 6.678 0 0 1 4.38-5.033ZM16.91 15.79l-5.05-2.916a1.01 1.01 0 0 0-1.507.742l-.009.133v5.831a1.011 1.011 0 0 0 1.394.933l.121-.059 5.05-2.916a1.01 1.01 0 0 0 .111-1.674l-.111-.076-5.05-2.916ZM1.132 8.891h24.404l.017.4.003.21v7.666c0 3.401-.839 4.966-2.098 6.267-1.279 1.238-2.778 2.062-5.922 2.121l-.371.003H9.501c-3.4 0-4.963-.839-6.267-2.099-1.238-1.278-2.06-2.776-2.12-5.922l-.003-.37V9.501l.003-.21Z" fill-rule="evenodd" /></svg>';
642
643 return $svg;
644 }
645
646 public static function get_insta_image_carousel_icon()
647 {
648 $svg = '<svg aria-label="Carousel" class="x1lliihq x1n2onr6" color="#FFF" fill="#FFF" height="25" viewBox="0 0 43.636 43.636" width="25">
649 <path d="M31.636 27V10a4.695 4.695 0 0 0-4.727-4.727H10A4.695 4.695 0 0 0 5.273 10v17A4.695 4.695 0 0 0 10 31.727h17c2.545-.091 4.636-2.182 4.636-4.727zm4-13.364v14.636c0 4.091-3.364 7.455-7.455 7.455H13.545c-.545 0-.818.636-.455 1 .909 1 2.182 1.636 3.727 1.636h12.182a9.35 9.35 0 0 0 9.364-9.364V16.818a5.076 5.076 0 0 0-1.636-3.727c-.455-.364-1.091 0-1.091.545z" /></svg>';
650
651 return $svg;
652 }
653
654 public static function get_insta_image_icon()
655 {
656 $svg = '<svg width="22" height="22" viewBox="0 0 0.6 0.6" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M.175.05A.125.125 0 0 0 .05.175v.25A.125.125 0 0 0 .175.55h.25A.125.125 0 0 0 .55.425v-.25A.125.125 0 0 0 .425.05h-.25ZM.2.225a.025.025 0 1 1 .05 0 .025.025 0 0 1-.05 0ZM.225.15a.075.075 0 1 0 0 .15.075.075 0 0 0 0-.15Zm.138.205A.025.025 0 0 1 .398.351l.048.042A.025.025 0 1 0 .479.355L.43.312a.075.075 0 0 0-.107.011l-.04.05a.024.024 0 0 1-.032.005.074.074 0 0 0-.099.015L.118.432a.025.025 0 0 0 .038.033l.035-.04A.024.024 0 0 1 .223.42.074.074 0 0 0 .322.405l.04-.05Z" fill="#fff"/></svg>';
657
658 return $svg;
659 }
660
661 public static function get_insta_like_icon()
662 {
663 $svg = '<svg version="1.1" id="Uploaded to svgrepo.com" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 0.8 0.8" xml:space="preserve"><path d="M.225.25C.225.264.214.275.2.275S.175.264.175.25.186.225.2.225.225.236.225.25zM.75.3C.75.453.589.582.485.65a1.06 1.06 0 0 1-.073.044.025.025 0 0 1-.024 0A1.049 1.049 0 0 1 .315.65C.211.582.05.453.05.3a.2.2 0 0 1 .2-.2.199.199 0 0 1 .15.068A.199.199 0 0 1 .55.1a.2.2 0 0 1 .2.2zM.25.25a.05.05 0 1 0-.1 0 .05.05 0 0 0 .1 0z" style="fill:#fff"/></svg>';
664
665 return $svg;
666 }
667 public static function get_insta_comment_icon()
668 {
669 $svg = '<svg fill="#fff" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 2.5 2.5" xml:space="preserve"><path d="M2.374.446a.063.063 0 0 0-.061-.057H.991a.063.063 0 0 0-.063.057H.927v.328h.559c.029 0 .053.022.056.051h.001v.731h.275l.162.162a.063.063 0 0 0 .116-.035v-.127h.217a.063.063 0 0 0 .06-.051h.002V.446h-.001z"/><path d="M1.361.899H.18A.056.056 0 0 0 .125.95v.946h.001a.057.057 0 0 0 .054.045h.194v.113a.057.057 0 0 0 .104.032l.145-.145h.738c.027 0 .05-.02.056-.045h.001V.95h-.001a.056.056 0 0 0-.056-.051z"/></svg>';
670
671 return $svg;
672 }
673 public static function get_instagram_icon()
674 {
675 $svg = '<svg version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" xml:space="preserve" width="1285" height="400"><style>.st0{fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}</style><path class="st0" d="M14.375 19.375h-8.75c-2.75 0-5-2.25-5-5v-8.75c0-2.75 2.25-5 5-5h8.75c2.75 0 5 2.25 5 5v8.75c0 2.75-2.25 5-5 5z"/><path class="st0" d="M14.375 10A4.375 4.375 0 0 1 10 14.375 4.375 4.375 0 0 1 5.625 10a4.375 4.375 0 0 1 8.75 0zm1.25-5.625A.625.625 0 0 1 15 5a.625.625 0 0 1-.625-.625.625.625 0 0 1 1.25 0z"/></svg>';
676
677 return $svg;
678 }
679
680 public static function get_google_presentation_url($embedded_url)
681 {
682 $parsed_url = parse_url($embedded_url);
683 $base_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . $parsed_url['path'];
684 $base_url = strtok($base_url, '?');
685 $base_url = rtrim($base_url, '/');
686 return $base_url;
687 }
688
689 public static function check_media_format($url)
690 {
691 $pattern1 = '/\.(mp4|mov|avi|wmv|flv|mkv|webm|mpeg|mpg)$/i';
692 $pattern2 = '/\.(mp3|wav|ogg|aac)$/i';
693
694 $isVideo = preg_match($pattern1, $url);
695 $isAudio = preg_match($pattern2, $url);
696
697 $is_self_hosted = false;
698 $format = '';
699
700 if (!empty($isVideo) || !empty($isAudio)) {
701 $is_self_hosted = true;
702 if (!empty($isVideo)) {
703 $format = 'video';
704 } else if (!empty($isAudio)) {
705 $format = 'audio';
706 }
707 }
708
709 if (!$is_self_hosted) {
710 return [
711 'selhosted' => false,
712 ];
713 }
714
715 return [
716 'selhosted' => true,
717 'format' => $format,
718 ];
719 }
720
721 // Ajax Methods get instagram feed data
722 public function loadmore_data_handler()
723 {
724 $connected_account_type = isset($_POST['connected_account_type']) ? sanitize_text_field($_POST['connected_account_type']) : 'personal';
725 $hashtag_id = isset($_POST['hashtag_id']) ? sanitize_text_field($_POST['hashtag_id']) : '';
726 $feed_type = isset($_POST['feed_type']) ? sanitize_text_field($_POST['feed_type']) : 'user_aacount_type';
727 $user_id = isset($_POST['user_id']) ? sanitize_text_field($_POST['user_id']) : '';
728 $loadmore_key = isset($_POST['loadmore_key']) ? sanitize_text_field($_POST['loadmore_key']) : '';
729 $nonce = isset($_POST['_nonce']) ? sanitize_text_field($_POST['_nonce']) : '';
730 $params = isset($_POST['params']) ? sanitize_text_field($_POST['params']) : '';
731 // $params = json_decode($params, true);
732 $params = stripslashes($params); // Remove extra backslashes
733 $params = json_decode($params, true);
734
735 // Verify nonce
736 if (!wp_verify_nonce($nonce, 'ep_nonce')) {
737 wp_send_json_error('Invalid nonce');
738 wp_die(); // Terminate script execution if nonce is invalid
739 }
740
741 $feeds_data = get_option('ep_instagram_feed_data');
742 $user_data = $feeds_data[$user_id]['feed_userinfo'];
743
744 if ($feed_type == 'hashtag_type') {
745 $feeds_data = get_option('ep_instagram_hashtag_feed');
746 }
747
748
749 $profile_picture_url = isset($user_data['profile_picture_url']) ? $user_data['profile_picture_url'] : '';
750
751 if ($feed_type === 'user_account_type' && isset($feeds_data[$loadmore_key]['feed_posts'])) {
752 $feed_posts = $feeds_data[$loadmore_key]['feed_posts'];
753 } else if ($feed_type === 'hashtag_type' && isset($feeds_data[$loadmore_key])) {
754 $feed_posts = $feeds_data[$loadmore_key];
755 } else {
756 $feed_posts = ['error'];
757 }
758
759
760 if (is_array($feed_posts) && count($feed_posts) > 0) {
761 $loaded_posts = isset($_POST['loaded_posts']) ? intval($_POST['loaded_posts']) : 0;
762 $posts_per_page = isset($_POST['posts_per_page']) ? intval($_POST['posts_per_page']) : 0;
763
764 $post_index = $loaded_posts + 1;
765 $start_index = $loaded_posts;
766
767 $next_posts = array_slice($feed_posts, $start_index, $posts_per_page);
768
769 ob_start();
770
771 if (is_array($next_posts) && count($next_posts) > 0) :
772 foreach ($next_posts as $post) :
773 $caption = !empty($post['caption']) ? $post['caption'] : '';
774 $media_type = !empty($post['media_type']) ? $post['media_type'] : '';
775 $media_url = !empty($post['media_url']) ? $post['media_url'] : '';
776 $permalink = !empty($post['permalink']) ? $post['permalink'] : '';
777 $timestamp = !empty($post['timestamp']) ? $post['timestamp'] : '';
778 $username = !empty($post['username']) ? $post['username'] : '';
779 $like_count = !empty($post['like_count']) ? $post['like_count'] : 0;
780 $comments_count = !empty($post['comments_count']) ? $post['comments_count'] : 0;
781
782 $post['profile_picture_url'] = $profile_picture_url;
783 $post['show_likes_count'] = isset($params['show_likes_count']) ? $params['show_likes_count'] : false;
784 $post['show_comments_count'] = isset($params['show_comments_count']) ? $params['show_comments_count'] : false;
785 $post['popup_follow_button'] = isset($params['popup_follow_button']) ? $params['popup_follow_button'] : true;
786 $post['popup_follow_button_text'] = isset($params['popup_follow_button_text']) ? $params['popup_follow_button_text'] : 'Follow';
787 ?>
788
789 <div class="insta-gallery-item cg-carousel__slide js-carousel__slide" data-insta-postid="<?php echo esc_attr($post['id']) ?>" data-postindex="<?php echo esc_attr($post_index); ?>" data-postdata="<?php echo htmlspecialchars(json_encode($post), ENT_QUOTES, 'UTF-8'); ?>" data-media-type="<?php echo esc_attr($media_type); ?>">
790 <?php
791
792 if (!empty($hashtag_id) && $media_type == 'CAROUSEL_ALBUM') {
793 if (isset($post['children']['data'][0]['media_url'])) {
794 $hashtag_media_url = $post['children']['data'][0]['media_url'];
795 $hashtag_media_type = $post['children']['data'][0]['media_type'];
796
797 if ($hashtag_media_type == 'VIDEO') {
798 echo '<video class="insta-gallery-image" src="' . esc_url($hashtag_media_url) . '"></video>';
799 } else {
800 echo ' <img class="insta-gallery-image" src="' . esc_url($hashtag_media_url) . '" alt="' . esc_attr('image') . '">';
801 }
802 }
803 } else {
804 if ($media_type == 'VIDEO') {
805 echo '<video class="insta-gallery-image" src="' . esc_url($media_url) . '"></video>';
806 } else {
807 echo ' <img class="insta-gallery-image" src="' . esc_url($media_url) . '" alt="' . esc_attr('image') . '">';
808 }
809 }
810 ?>
811
812 <div class="insta-gallery-item-type">
813 <div class="insta-gallery-item-type-icon">
814 <?php
815 if ($media_type == 'VIDEO') {
816 echo Helper::get_insta_video_icon();
817 } else if ($media_type == 'CAROUSEL_ALBUM') {
818 echo Helper::get_insta_image_carousel_icon();
819 } else {
820 echo Helper::get_insta_image_icon();
821 }
822 ?>
823 </div>
824 </div>
825 <div class="insta-gallery-item-info">
826 <?php if (strtolower($connected_account_type) === 'business') : ?>
827 <div class="insta-item-reaction-count">
828 <div class="insta-gallery-item-likes">
829 <?php echo Helper::get_insta_like_icon();
830 echo esc_html($like_count); ?>
831 </div>
832 <div class="insta-gallery-item-comments">
833 <?php echo Helper::get_insta_comment_icon();
834 echo esc_html($comments_count); ?>
835 </div>
836 </div>
837 <?php else : ?>
838 <div class="insta-gallery-item-permalink">
839 <?php echo Helper::get_instagram_icon(); ?>
840 </div>
841 <?php endif; ?>
842 </div>
843 </div>
844
845 <?php $post_index++;
846 endforeach;
847 endif;
848
849 $feed_item = ob_get_clean();
850
851 $next_start_index = $start_index + count($next_posts);
852
853 wp_send_json(array(
854 'html' => $feed_item,
855 'next_post_index' => $next_start_index,
856 'total_feed_posts' => count($feed_posts)
857 ));
858 } else {
859 wp_send_json('');
860 }
861 }
862
863 public static function getCalendlyUuid($url)
864 {
865 $pattern = '/\/([0-9a-fA-F-]+)$/';
866 if (preg_match($pattern, $url, $matches)) {
867 $uuid = $matches[1];
868 return $uuid;
869 }
870 return '';
871 }
872
873 public static function getCalendlyUserInfo($access_token)
874 {
875 $transient_name = 'calendly_user_info_' . $access_token;
876 $user_info = get_transient($transient_name);
877 if (false === $user_info) {
878 $user_endpoint = 'https://api.calendly.com/users/me';
879 $headers = array(
880 'Authorization' => "Bearer $access_token",
881 'Content-Type' => 'application/json',
882 );
883 $args = array(
884 'headers' => $headers,
885 );
886 $response = wp_remote_get($user_endpoint, $args);
887 if (!is_wp_error($response) && 200 === wp_remote_retrieve_response_code($response)) {
888 $user_info = wp_remote_retrieve_body($response);
889 set_transient($transient_name, $user_info, 3600);
890 } else {
891 return false;
892 }
893 }
894
895 return $user_info;
896 }
897
898
899
900 public static function getCalaendlyEventTypes($user_uri, $access_token)
901 {
902 // Attempt to retrieve the data from the transient
903 $events_list = get_transient('calendly_events_list_' . md5($access_token));
904
905 if (false === $events_list) {
906 // If the data is not in the transient, fetch it from the API
907 $events_endpoint = "https://api.calendly.com/event_types?user=$user_uri";
908
909 $headers = array(
910 'Authorization' => "Bearer $access_token",
911 'Content-Type' => 'application/json',
912 );
913
914 $args = array(
915 'headers' => $headers,
916 );
917
918 $response = wp_remote_get($events_endpoint, $args);
919
920 if (!is_wp_error($response)) {
921 $body = wp_remote_retrieve_body($response);
922 $events_list = json_decode($body, true);
923
924 // Store the data in a transient for a specified time (e.g., 1 hour)
925 set_transient('calendly_events_list', $events_list, HOUR_IN_SECONDS);
926
927 return $events_list;
928 }
929 }
930
931 return $events_list;
932 }
933
934 public static function getListEventInvitee($uuid, $access_token)
935 {
936 // Attempt to retrieve the data from the transient
937 $invitee_list = get_transient('calendly_invitee_list_' . md5($access_token));
938
939 if (false === $invitee_list) {
940 // If the data is not in the transient, fetch it from the API
941 $events_endpoint = "https://api.calendly.com/scheduled_events/$uuid/invitees";
942
943 $headers = array(
944 'Authorization' => "Bearer $access_token",
945 'Content-Type' => 'application/json',
946 );
947
948 $args = array(
949 'headers' => $headers,
950 );
951
952 $response = wp_remote_get($events_endpoint, $args);
953
954 if (!is_wp_error($response)) {
955 $body = wp_remote_retrieve_body($response);
956 $invitee_list = json_decode($body, true);
957
958 // Store the data in a transient for a specified time (e.g., 1 hour)
959 set_transient('calendly_invitee_list', $invitee_list, HOUR_IN_SECONDS);
960
961 return $invitee_list;
962 }
963 }
964
965 return $invitee_list;
966 }
967
968 public static function getCalaendlyScheduledEvents($user_uri, $access_token)
969 {
970 // Attempt to retrieve the data from the transient
971 $events_list = get_transient('calendly_events_list_' . md5($access_token));
972
973 if (false === $events_list) {
974 // If the data is not in the transient, fetch it from the API
975 $events_endpoint = "https://api.calendly.com/scheduled_events?user=$user_uri";
976
977 $headers = array(
978 'Authorization' => "Bearer $access_token",
979 'Content-Type' => 'application/json',
980 );
981
982 $args = array(
983 'headers' => $headers,
984 );
985
986 $response = wp_remote_get($events_endpoint, $args);
987
988 if (!is_wp_error($response)) {
989 $body = wp_remote_retrieve_body($response);
990 $events_list = json_decode($body, true);
991
992 // Store the data in a transient for a specified time (e.g., 1 hour)
993 set_transient('calendly_events_list', $events_list, HOUR_IN_SECONDS);
994
995 return $events_list;
996 }
997 }
998
999 return $events_list;
1000 }
1001
1002
1003 public static function parseDuration($durationString)
1004 {
1005 list($minutes, $seconds) = explode(':', $durationString);
1006 return intval($minutes) * 60 + intval($seconds);
1007 }
1008
1009
1010
1011
1012 public static function is_pro_active()
1013 {
1014 if (defined('EMBEDPRESS_SL_ITEM_SLUG')) {
1015 return true;
1016 }
1017 return false;
1018 }
1019
1020 /**
1021 * Check if pro features should be enabled based on license status
1022 *
1023 * @return bool True if pro features should be enabled, false otherwise
1024 */
1025 public static function is_pro_features_enabled()
1026 {
1027 // First check if pro plugin is active
1028 if (!self::is_pro_active()) {
1029 return false;
1030 }
1031
1032 // Get license status
1033 $license_status = get_option('embedpress_pro_software__license_status', '');
1034
1035 // Pro features are enabled only if license is valid
1036 return $license_status === 'valid';
1037 }
1038
1039 /**
1040 * Get detailed license information
1041 *
1042 * @return array License information including status, key, and data
1043 */
1044 public static function get_license_info()
1045 {
1046 $is_pro_active = self::is_pro_active();
1047 $license_status = '';
1048 $license_key = '';
1049 $license_data = [];
1050 $is_features_enabled = false;
1051
1052 if ($is_pro_active) {
1053 $license_status = get_option('embedpress_pro_software__license_status', '');
1054 $license_data_raw = get_transient('embedpress_pro_software__license_data');
1055
1056 if ($license_data_raw) {
1057 $license_data = json_decode(json_encode($license_data_raw), true);
1058 $license_key = isset($license_data['license_key']) ? $license_data['license_key'] : '';
1059 }
1060
1061 $is_features_enabled = ($license_status === 'valid');
1062 }
1063
1064 return [
1065 'is_pro_active' => $is_pro_active,
1066 'license_status' => $license_status,
1067 'license_key' => $license_key,
1068 'license_data' => $license_data,
1069 'is_features_enabled' => $is_features_enabled,
1070 'status_message' => self::get_license_status_message($is_pro_active, $license_status)
1071 ];
1072 }
1073
1074 /**
1075 * Display license warning notice for pro features
1076 *
1077 * @param string $context Context where the notice is displayed (e.g., 'analytics', 'branding')
1078 * @return string HTML for the license warning notice
1079 */
1080 public static function get_pro_feature_notice($context = '')
1081 {
1082 $license_info = self::get_license_info();
1083
1084 if (!$license_info['is_pro_active']) {
1085 return '<div class="embedpress-pro-notice embedpress-notice-warning">
1086 <p><strong>' . __('EmbedPress Pro Required', 'embedpress') . '</strong></p>
1087 <p>' . __('This feature requires EmbedPress Pro. Please install and activate EmbedPress Pro to access this feature.', 'embedpress') . '</p>
1088 </div>';
1089 }
1090
1091 if (!$license_info['is_features_enabled']) {
1092 $message = $license_info['status_message'];
1093 $action_text = '';
1094 $action_link = admin_url('admin.php?page=embedpress&page_type=license');
1095
1096 switch ($license_info['license_status']) {
1097 case 'expired':
1098 $action_text = __('Renew License', 'embedpress');
1099 break;
1100 case 'invalid':
1101 case 'site_inactive':
1102 case 'disabled':
1103 case 'revoked':
1104 $action_text = __('Activate License', 'embedpress');
1105 break;
1106 default:
1107 $action_text = __('Activate License', 'embedpress');
1108 break;
1109 }
1110
1111 return '<div class="embedpress-pro-notice embedpress-notice-error">
1112 <p><strong>' . __('Pro Features Disabled', 'embedpress') . '</strong></p>
1113 <p>' . esc_html($message) . '</p>
1114 <p><a href="' . esc_url($action_link) . '" class="button button-primary">' . esc_html($action_text) . '</a></p>
1115 </div>';
1116 }
1117
1118 return '';
1119 }
1120
1121 /**
1122 * Initialize license checking hooks
1123 */
1124 public static function init_license_hooks()
1125 {
1126 // Add filter to disable pro features when license is not valid
1127 add_filter('embedpress_pro_features_enabled', [__CLASS__, 'is_pro_features_enabled']);
1128
1129 // Add action to show license notices in admin
1130 add_action('admin_notices', [__CLASS__, 'show_license_admin_notices']);
1131
1132 // Add styles for license notices
1133 add_action('admin_head', [__CLASS__, 'add_license_notice_styles']);
1134 }
1135
1136 /**
1137 * Show license admin notices
1138 */
1139 public static function show_license_admin_notices()
1140 {
1141 // Only show on EmbedPress admin pages
1142 if (!isset($_GET['page']) || $_GET['page'] !== 'embedpress') {
1143 return;
1144 }
1145
1146 $license_info = self::get_license_info();
1147
1148 if ($license_info['is_pro_active'] && !$license_info['is_features_enabled']) {
1149 $message = $license_info['status_message'];
1150 $action_link = admin_url('admin.php?page=embedpress&page_type=license');
1151 $action_text = $license_info['license_status'] === 'expired' ? __('Renew License', 'embedpress') : __('Activate License', 'embedpress');
1152
1153 echo '<div class="notice notice-warning is-dismissible">
1154 <p><strong>' . __('EmbedPress Pro Features Disabled', 'embedpress') . '</strong></p>
1155 <p>' . esc_html($message) . '</p>
1156 <p><a href="' . esc_url($action_link) . '" class="button button-primary">' . esc_html($action_text) . '</a></p>
1157 </div>';
1158 }
1159 }
1160
1161 /**
1162 * Add CSS styles for license notices
1163 */
1164 public static function add_license_notice_styles()
1165 {
1166 echo '<style>
1167 .embedpress-pro-notice {
1168 padding: 15px;
1169 margin: 15px 0;
1170 border-left: 4px solid #dc3545;
1171 background: #fff;
1172 box-shadow: 0 1px 1px rgba(0,0,0,.04);
1173 }
1174 .embedpress-pro-notice.embedpress-notice-warning {
1175 border-left-color: #ffb900;
1176 }
1177 .embedpress-pro-notice.embedpress-notice-error {
1178 border-left-color: #dc3545;
1179 }
1180 .embedpress-pro-notice p {
1181 margin: 0.5em 0;
1182 }
1183 .embedpress-pro-notice strong {
1184 color: #23282d;
1185 }
1186 .embedpress-text-error {
1187 color: #dc3545 !important;
1188 }
1189 .embedpress-text-warning {
1190 color: #ffb900 !important;
1191 }
1192 </style>';
1193 }
1194
1195 /**
1196 * Get user-friendly license status message
1197 *
1198 * @param bool $is_pro_active Whether pro plugin is active
1199 * @param string $license_status Current license status
1200 * @return string User-friendly status message
1201 */
1202 public static function get_license_status_message($is_pro_active, $license_status)
1203 {
1204 if (!$is_pro_active) {
1205 return __('EmbedPress Pro is not installed or activated.', 'embedpress');
1206 }
1207
1208 switch ($license_status) {
1209 case 'valid':
1210 return __('Your license is active and valid.', 'embedpress');
1211 case 'expired':
1212 return __('Your license has expired. Please renew to continue receiving updates and support.', 'embedpress');
1213 case 'invalid':
1214 case 'site_inactive':
1215 return __('Your license is not active for this URL. Please activate your license.', 'embedpress');
1216 case 'disabled':
1217 case 'revoked':
1218 return __('Your license key has been disabled or revoked.', 'embedpress');
1219 case 'missing':
1220 return __('License key is missing. Please enter your license key.', 'embedpress');
1221 case 'http_error':
1222 return __('Unable to verify license due to connection issues. Please try again later.', 'embedpress');
1223 case '':
1224 case false:
1225 default:
1226 return __('Please activate your license key to enable EmbedPress Pro features.', 'embedpress');
1227 }
1228 }
1229
1230
1231 public static function getInstagramUserInfo($accessToken, $accountType, $userId, $is_sync = false)
1232 {
1233 if ($is_sync) {
1234 // If $is_sync is true, don't use transient
1235 $use_transient = false;
1236 } else {
1237 // If $is_sync is false, use transient
1238 $transient_key = 'instagram_user_info_' . $userId;
1239 $use_transient = true;
1240 }
1241
1242 if ($use_transient && false !== ($userInfo = get_transient($transient_key))) {
1243 // If transient exists, return cached user info
1244 return $userInfo;
1245 }
1246
1247 if (strtolower($accountType) === 'business') {
1248 $api_url = 'https://graph.facebook.com/' . $userId . '?fields=biography,id,username,website,followers_count,media_count,profile_picture_url,name&access_token=' . $accessToken;
1249 } else {
1250 $api_url = "https://graph.instagram.com/me?fields=id,username,account_type,media_count,followers_count,biography,website&access_token={$accessToken}";
1251 }
1252
1253 $connected_account_type = $accountType;
1254
1255 $userInfoResponse = wp_remote_get($api_url);
1256
1257 if (is_wp_error($userInfoResponse)) {
1258 echo 'Error: Unable to retrieve Instagram user information.';
1259 } else {
1260 $userInfoBody = wp_remote_retrieve_body($userInfoResponse);
1261 $userInfo = json_decode($userInfoBody, true);
1262
1263 $userInfo['connected_account_type'] = $connected_account_type;
1264 $userInfo['access_token'] = $accessToken;
1265
1266
1267 if (!isset($userInfo['profile_picture_url'])) {
1268 $userInfo['profile_picture_url'] = '';
1269 }
1270
1271 // If not using transient, cache the user info for an hour
1272 if ($use_transient) {
1273 set_transient($transient_key, $userInfo, HOUR_IN_SECONDS);
1274 }
1275
1276 return $userInfo;
1277 }
1278 }
1279
1280
1281 // Get Instagram posts, videos, reels
1282 public static function getInstagramPosts($access_token, $account_type, $userId, $limit = 100, $is_sync = false)
1283 {
1284 if ($is_sync) {
1285 // If $is_sync is true, don't use transient
1286 $use_transient = false;
1287 } else {
1288 // If $is_sync is false, use transient
1289 $transient_key = 'instagram_posts_' . $userId;
1290 $use_transient = true;
1291 }
1292
1293 if ($use_transient && false !== ($posts = get_transient($transient_key))) {
1294 // If transient exists, return cached posts
1295 return $posts;
1296 }
1297
1298 if (strtolower($account_type) === 'business') {
1299 $api_url = 'https://graph.facebook.com/v17.0/' . $userId . '/media?fields=media_url,media_product_type,thumbnail_url,caption,id,media_type,timestamp,username,comments_count,like_count,permalink,children%7Bmedia_url,id,media_type,timestamp,permalink,thumbnail_url%7D&limit=' . $limit . '&access_token=' . $access_token;
1300 } else {
1301 $api_url = "https://graph.instagram.com/me/media?fields=id,caption,media_type,media_url,children{media_url,id,media_type},permalink,timestamp,username,thumbnail_url&limit=$limit&access_token=$access_token";
1302 }
1303
1304 $postsResponse = wp_remote_get($api_url);
1305
1306 if (is_wp_error($postsResponse)) {
1307 echo 'Error: Unable to retrieve Instagram posts.';
1308 } else {
1309 $postsBody = wp_remote_retrieve_body($postsResponse);
1310 $posts = json_decode($postsBody, true);
1311
1312 if (empty($posts['data'])) {
1313 return 'Please add Instagram Access Token';
1314 }
1315
1316 // If not using transient, cache the posts for an hour
1317 if ($use_transient) {
1318 set_transient($transient_key, $posts['data'], HOUR_IN_SECONDS);
1319 }
1320
1321 return $posts['data'];
1322 }
1323 }
1324
1325 public static function get_enable_settings_data_for_scripts($settings)
1326 {
1327 $settings_data = [
1328 'enabled_ads' => isset($settings['adManager']) && $settings['adManager'] === 'yes' ? 'yes' : '',
1329
1330 'enabled_custom_player' => isset($settings['emberpress_custom_player']) && $settings['emberpress_custom_player'] === 'yes' ? 'yes' : '',
1331
1332 'enabled_instafeed' => isset($settings['embedpress_pro_embeded_source']) && $settings['embedpress_pro_embeded_source'] === 'instafeed' ? 'yes' : '',
1333
1334 'enabled_docs_custom_viewer' => isset($settings['embedpress_document_viewer']) && $settings['embedpress_document_viewer'] === 'custom' ? 'yes' : '',
1335 ];
1336
1337 update_option('enabled_elementor_scripts', $settings_data);
1338 }
1339
1340 public static function get_options_value($key)
1341 {
1342 $g_settings = get_option(EMBEDPRESS_PLG_NAME);
1343
1344 if(isset($g_settings['enableEmbedResizeWidth']) && $g_settings['enableEmbedResizeWidth'] == 1){
1345 $g_settings['enableEmbedResizeWidth'] = 600;
1346 update_option(EMBEDPRESS_PLG_NAME, $g_settings);
1347 }
1348 if(isset($g_settings['enableEmbedResizeHeight']) && $g_settings['enableEmbedResizeHeight'] == 1){
1349 $g_settings['enableEmbedResizeHeight'] = 600;
1350 update_option(EMBEDPRESS_PLG_NAME, $g_settings);
1351 }
1352
1353 if (isset($g_settings[$key])) {
1354 return $g_settings[$key];
1355 }
1356
1357 return '';
1358 }
1359
1360
1361
1362 public static function get_branding_value($key, $provider)
1363 {
1364 $settings = get_option(EMBEDPRESS_PLG_NAME . ':' . $provider, []);
1365
1366 // Check if provider has custom branding enabled and the specific key set
1367 if (isset($settings['branding']) && $settings['branding'] === 'yes') {
1368 // If provider has custom logo, use it
1369 if (isset($settings[$key]) && !empty($settings[$key])) {
1370 return $settings[$key];
1371 }
1372
1373 // If branding is enabled but no custom logo, use global brand as fallback
1374 if ($key === 'logo_url') {
1375 $global_logo = self::get_global_brand_logo_url();
1376 if (!empty($global_logo)) {
1377 return $global_logo;
1378 }
1379 }
1380 }
1381
1382 return '';
1383 }
1384
1385 /**
1386 * Get global brand logo URL
1387 *
1388 * @return string
1389 */
1390 public static function get_global_brand_logo_url()
1391 {
1392 $global_brand_settings = get_option(EMBEDPRESS_PLG_NAME . ':global_brand', []);
1393 return isset($global_brand_settings['logo_url']) ? $global_brand_settings['logo_url'] : '';
1394 }
1395
1396 /**
1397 * Get global brand logo ID
1398 *
1399 * @return int
1400 */
1401 public static function get_global_brand_logo_id()
1402 {
1403 $global_brand_settings = get_option(EMBEDPRESS_PLG_NAME . ':global_brand', []);
1404 return isset($global_brand_settings['logo_id']) ? intval($global_brand_settings['logo_id']) : 0;
1405 }
1406
1407
1408 public static function format_number($number)
1409 {
1410 if ($number >= 1000000000) {
1411 return number_format($number / 1000000000, 1) . 'b';
1412 } elseif ($number >= 1000000) {
1413 return number_format($number / 1000000, 1) . 'm';
1414 } elseif ($number >= 1000) {
1415 return number_format($number / 1000, 1) . 'k';
1416 } else {
1417 return $number;
1418 }
1419 }
1420
1421 public static function get_id($item)
1422 {
1423 $vid = isset($item->snippet->resourceId->videoId) ? $item->snippet->resourceId->videoId : null;
1424 $vid = $vid ? $vid : (isset($item->id->videoId) ? $item->id->videoId : null);
1425 $vid = $vid ? $vid : (isset($item->id) ? $item->id : null);
1426 return $vid;
1427 }
1428
1429 public static function clean_api_error($raw_message)
1430 {
1431 return htmlspecialchars(strip_tags(preg_replace('@&key=[^& ]+@i', '&key=*******', $raw_message)));
1432 }
1433
1434 public static function clean_api_error_html($raw_message)
1435 {
1436 $clean_html = '';
1437 if ((defined('REST_REQUEST') && REST_REQUEST) || current_user_can('manage_options')) {
1438 $clean_html = '<div>' . __('EmbedPress: ', 'embedpress') . self::clean_api_error($raw_message) . '</div>';
1439 }
1440 return $clean_html;
1441 }
1442
1443 public static function get_thumbnail_url($item, $quality, $privacyStatus)
1444 {
1445 $url = "";
1446 if ($privacyStatus == 'private') {
1447 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/private.png';
1448 } elseif (isset($item->snippet->thumbnails->{$quality}->url)) {
1449 $url = $item->snippet->thumbnails->{$quality}->url;
1450 } elseif (isset($item->snippet->thumbnails->medium->url)) {
1451 $url = $item->snippet->thumbnails->medium->url;
1452 } elseif (isset($item->snippet->thumbnails->default->url)) {
1453 $url = $item->snippet->thumbnails->default->url;
1454 } elseif (isset($item->snippet->thumbnails->high->url)) {
1455 $url = $item->snippet->thumbnails->high->url;
1456 } else {
1457 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/deleted-video-thumb.png';
1458 }
1459 return $url;
1460 }
1461
1462 public static function compare_vid_date($a, $b)
1463 {
1464 $dateA = strtotime($a->snippet->publishedAt);
1465 $dateB = strtotime($b->snippet->publishedAt);
1466
1467 // Sort in descending order (newest first)
1468 return $dateB - $dateA;
1469 }
1470
1471
1472 public static function get_youtube_video_data($api_key, $video_id)
1473 {
1474 // Set a unique transient name based on the video ID
1475 $transient_name = 'youtube_video_data_' . $video_id;
1476
1477 // Try to get data from the transient cache
1478 $video_data = get_transient($transient_name);
1479
1480 // If no cached data, fetch from the API
1481 if ($video_data === false) {
1482 // YouTube Data API URL
1483 $url = "https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id={$video_id}&key={$api_key}";
1484
1485 // Fetch the data from the API
1486 $response = wp_remote_get($url);
1487
1488 if (is_wp_error($response)) {
1489 return false; // Return false if there is an error
1490 }
1491
1492 $body = wp_remote_retrieve_body($response);
1493 $video_data = json_decode($body, true);
1494
1495 if (isset($video_data['items'][0])) {
1496 $video_data = $video_data['items'][0];
1497
1498 // Cache the data in a transient for 12 hours
1499 set_transient($transient_name, $video_data, 24 * HOUR_IN_SECONDS);
1500 } else {
1501 return false; // Return false if no data found
1502 }
1503 }
1504
1505 return $video_data;
1506 }
1507
1508 public static function trimTitle($title, $wordCount)
1509 {
1510 $words = explode(' ', $title);
1511
1512 if (count($words) <= $wordCount) {
1513 return $title; // No trimming needed
1514 }
1515
1516 $trimmedWords = array_slice($words, 0, $wordCount);
1517
1518 return implode(' ', $trimmedWords) . ' ...';
1519 }
1520
1521 public static function timeAgo($datetime)
1522 {
1523 $now = new \DateTime();
1524 $date = new \DateTime($datetime);
1525 $interval = $now->diff($date);
1526
1527 if ($interval->y > 0) {
1528 return $interval->y . ' year' . ($interval->y > 1 ? 's' : '') . ' ago';
1529 } elseif ($interval->m > 0) {
1530 return $interval->m . ' month' . ($interval->m > 1 ? 's' : '') . ' ago';
1531 } elseif ($interval->d > 0) {
1532 return $interval->d . ' day' . ($interval->d > 1 ? 's' : '') . ' ago';
1533 } elseif ($interval->h > 0) {
1534 return $interval->h . ' hour' . ($interval->h > 1 ? 's' : '') . ' ago';
1535 } elseif ($interval->i > 0) {
1536 return $interval->i . ' minute' . ($interval->i > 1 ? 's' : '') . ' ago';
1537 } else {
1538 return 'just now';
1539 }
1540 }
1541
1542 public static function removeQuote($attributes)
1543 {
1544 $parsedAttributes = [];
1545
1546 $regex = '/^on.*/i';
1547
1548 foreach ($attributes as $key => $value) {
1549 if (is_string($value)) {
1550 $cleanValue = str_replace(['"', "'"], '', $value);
1551 } else {
1552 $cleanValue = $value;
1553 }
1554
1555 if (!preg_match($regex, $key)) {
1556 $parsedAttributes[$key] = $cleanValue;
1557 }
1558 }
1559
1560 return $parsedAttributes;
1561 }
1562
1563 public static function getBooleanParam($param, $default = false)
1564 {
1565 return isset($param) && is_string($param) && ($param == 'true' || $param == 'yes') ? 'true' : ($default ? 'true' : 'false');
1566 }
1567
1568 public static function has_allowed_roles($allowed_roles = [])
1569 {
1570
1571 if (empty($allowed_roles) || (count($allowed_roles) == 1 && empty($allowed_roles[0]))) {
1572 return true;
1573 }
1574 $current_user = wp_get_current_user();
1575 $user_roles = $current_user->roles;
1576
1577 return !empty(array_intersect($user_roles, $allowed_roles));
1578 }
1579
1580 public static function get_elementor_global_color($settings, $key)
1581 {
1582
1583 $global_color = $settings[$key];
1584
1585 if (isset($settings['__globals__'][$key])) {
1586 $color_setting = $settings['__globals__'][$key];
1587
1588 if (strpos($color_setting, 'globals/colors?id=') === 0) {
1589 // It's a global color reference
1590 $global_id = str_replace('globals/colors?id=', '', $color_setting);
1591
1592 $kit = Plugin::$instance->kits_manager->get_current_settings();
1593
1594 $system_colors = isset($kit['system_colors']) ? $kit['system_colors'] : [];
1595 $custom_colors = isset($kit['custom_colors']) ? $kit['custom_colors'] : [];
1596 $global_colors = array_merge($system_colors, $custom_colors);
1597
1598 foreach ($global_colors as $color) {
1599
1600 if ($color['_id'] === $global_id) {
1601 $global_color = $color['color']; // Found a match, set the color
1602 break;
1603 }
1604 }
1605 }
1606 }
1607 return $global_color;
1608 }
1609 }
1610