PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.2.8
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.2.8
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 1 year ago
Helper.php
1365 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 public static function getInstagramUserInfo($accessToken, $accountType, $userId, $is_sync = false)
1022 {
1023 if ($is_sync) {
1024 // If $is_sync is true, don't use transient
1025 $use_transient = false;
1026 } else {
1027 // If $is_sync is false, use transient
1028 $transient_key = 'instagram_user_info_' . $userId;
1029 $use_transient = true;
1030 }
1031
1032 if ($use_transient && false !== ($userInfo = get_transient($transient_key))) {
1033 // If transient exists, return cached user info
1034 return $userInfo;
1035 }
1036
1037 if (strtolower($accountType) === 'business') {
1038 $api_url = 'https://graph.facebook.com/' . $userId . '?fields=biography,id,username,website,followers_count,media_count,profile_picture_url,name&access_token=' . $accessToken;
1039 } else {
1040 $api_url = "https://graph.instagram.com/me?fields=id,username,account_type,media_count,followers_count,biography,website&access_token={$accessToken}";
1041 }
1042
1043 $connected_account_type = $accountType;
1044
1045 $userInfoResponse = wp_remote_get($api_url);
1046
1047 if (is_wp_error($userInfoResponse)) {
1048 echo 'Error: Unable to retrieve Instagram user information.';
1049 } else {
1050 $userInfoBody = wp_remote_retrieve_body($userInfoResponse);
1051 $userInfo = json_decode($userInfoBody, true);
1052
1053 $userInfo['connected_account_type'] = $connected_account_type;
1054 $userInfo['access_token'] = $accessToken;
1055
1056
1057 if (!isset($userInfo['profile_picture_url'])) {
1058 $userInfo['profile_picture_url'] = '';
1059 }
1060
1061 // If not using transient, cache the user info for an hour
1062 if ($use_transient) {
1063 set_transient($transient_key, $userInfo, HOUR_IN_SECONDS);
1064 }
1065
1066 return $userInfo;
1067 }
1068 }
1069
1070
1071 // Get Instagram posts, videos, reels
1072 public static function getInstagramPosts($access_token, $account_type, $userId, $limit = 100, $is_sync = false)
1073 {
1074 if ($is_sync) {
1075 // If $is_sync is true, don't use transient
1076 $use_transient = false;
1077 } else {
1078 // If $is_sync is false, use transient
1079 $transient_key = 'instagram_posts_' . $userId;
1080 $use_transient = true;
1081 }
1082
1083 if ($use_transient && false !== ($posts = get_transient($transient_key))) {
1084 // If transient exists, return cached posts
1085 return $posts;
1086 }
1087
1088 if (strtolower($account_type) === 'business') {
1089 $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;
1090 } else {
1091 $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";
1092 }
1093
1094 $postsResponse = wp_remote_get($api_url);
1095
1096 if (is_wp_error($postsResponse)) {
1097 echo 'Error: Unable to retrieve Instagram posts.';
1098 } else {
1099 $postsBody = wp_remote_retrieve_body($postsResponse);
1100 $posts = json_decode($postsBody, true);
1101
1102 if (empty($posts['data'])) {
1103 return 'Please add Instagram Access Token';
1104 }
1105
1106 // If not using transient, cache the posts for an hour
1107 if ($use_transient) {
1108 set_transient($transient_key, $posts['data'], HOUR_IN_SECONDS);
1109 }
1110
1111 return $posts['data'];
1112 }
1113 }
1114
1115 public static function get_enable_settings_data_for_scripts($settings)
1116 {
1117 $settings_data = [
1118 'enabled_ads' => isset($settings['adManager']) && $settings['adManager'] === 'yes' ? 'yes' : '',
1119
1120 'enabled_custom_player' => isset($settings['emberpress_custom_player']) && $settings['emberpress_custom_player'] === 'yes' ? 'yes' : '',
1121
1122 'enabled_instafeed' => isset($settings['embedpress_pro_embeded_source']) && $settings['embedpress_pro_embeded_source'] === 'instafeed' ? 'yes' : '',
1123
1124 'enabled_docs_custom_viewer' => isset($settings['embedpress_document_viewer']) && $settings['embedpress_document_viewer'] === 'custom' ? 'yes' : '',
1125 ];
1126
1127 update_option('enabled_elementor_scripts', $settings_data);
1128 }
1129
1130 public static function get_options_value($key)
1131 {
1132 $g_settings = get_option(EMBEDPRESS_PLG_NAME);
1133
1134 if(isset($g_settings['enableEmbedResizeWidth']) && $g_settings['enableEmbedResizeWidth'] == 1){
1135 $g_settings['enableEmbedResizeWidth'] = 600;
1136 update_option(EMBEDPRESS_PLG_NAME, $g_settings);
1137 }
1138 if(isset($g_settings['enableEmbedResizeHeight']) && $g_settings['enableEmbedResizeHeight'] == 1){
1139 $g_settings['enableEmbedResizeHeight'] = 600;
1140 update_option(EMBEDPRESS_PLG_NAME, $g_settings);
1141 }
1142
1143 if (isset($g_settings[$key])) {
1144 return $g_settings[$key];
1145 }
1146
1147 return '';
1148 }
1149
1150
1151
1152 public static function get_branding_value($key, $provider)
1153 {
1154 $settings = get_option(EMBEDPRESS_PLG_NAME . ':' . $provider, []);
1155
1156 if (isset($settings['branding']) && $settings['branding'] === 'yes' && isset($settings[$key])) {
1157 return $settings[$key];
1158 }
1159 return '';
1160 }
1161
1162
1163 public static function format_number($number)
1164 {
1165 if ($number >= 1000000000) {
1166 return number_format($number / 1000000000, 1) . 'b';
1167 } elseif ($number >= 1000000) {
1168 return number_format($number / 1000000, 1) . 'm';
1169 } elseif ($number >= 1000) {
1170 return number_format($number / 1000, 1) . 'k';
1171 } else {
1172 return $number;
1173 }
1174 }
1175
1176 public static function get_id($item)
1177 {
1178 $vid = isset($item->snippet->resourceId->videoId) ? $item->snippet->resourceId->videoId : null;
1179 $vid = $vid ? $vid : (isset($item->id->videoId) ? $item->id->videoId : null);
1180 $vid = $vid ? $vid : (isset($item->id) ? $item->id : null);
1181 return $vid;
1182 }
1183
1184 public static function clean_api_error($raw_message)
1185 {
1186 return htmlspecialchars(strip_tags(preg_replace('@&key=[^& ]+@i', '&key=*******', $raw_message)));
1187 }
1188
1189 public static function clean_api_error_html($raw_message)
1190 {
1191 $clean_html = '';
1192 if ((defined('REST_REQUEST') && REST_REQUEST) || current_user_can('manage_options')) {
1193 $clean_html = '<div>' . __('EmbedPress: ', 'embedpress') . self::clean_api_error($raw_message) . '</div>';
1194 }
1195 return $clean_html;
1196 }
1197
1198 public static function get_thumbnail_url($item, $quality, $privacyStatus)
1199 {
1200 $url = "";
1201 if ($privacyStatus == 'private') {
1202 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/private.png';
1203 } elseif (isset($item->snippet->thumbnails->{$quality}->url)) {
1204 $url = $item->snippet->thumbnails->{$quality}->url;
1205 } elseif (isset($item->snippet->thumbnails->medium->url)) {
1206 $url = $item->snippet->thumbnails->medium->url;
1207 } elseif (isset($item->snippet->thumbnails->default->url)) {
1208 $url = $item->snippet->thumbnails->default->url;
1209 } elseif (isset($item->snippet->thumbnails->high->url)) {
1210 $url = $item->snippet->thumbnails->high->url;
1211 } else {
1212 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/deleted-video-thumb.png';
1213 }
1214 return $url;
1215 }
1216
1217 public static function compare_vid_date($a, $b)
1218 {
1219 $dateA = strtotime($a->snippet->publishedAt);
1220 $dateB = strtotime($b->snippet->publishedAt);
1221
1222 // Sort in descending order (newest first)
1223 return $dateB - $dateA;
1224 }
1225
1226
1227 public static function get_youtube_video_data($api_key, $video_id)
1228 {
1229 // Set a unique transient name based on the video ID
1230 $transient_name = 'youtube_video_data_' . $video_id;
1231
1232 // Try to get data from the transient cache
1233 $video_data = get_transient($transient_name);
1234
1235 // If no cached data, fetch from the API
1236 if ($video_data === false) {
1237 // YouTube Data API URL
1238 $url = "https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id={$video_id}&key={$api_key}";
1239
1240 // Fetch the data from the API
1241 $response = wp_remote_get($url);
1242
1243 if (is_wp_error($response)) {
1244 return false; // Return false if there is an error
1245 }
1246
1247 $body = wp_remote_retrieve_body($response);
1248 $video_data = json_decode($body, true);
1249
1250 if (isset($video_data['items'][0])) {
1251 $video_data = $video_data['items'][0];
1252
1253 // Cache the data in a transient for 12 hours
1254 set_transient($transient_name, $video_data, 24 * HOUR_IN_SECONDS);
1255 } else {
1256 return false; // Return false if no data found
1257 }
1258 }
1259
1260 return $video_data;
1261 }
1262
1263 public static function trimTitle($title, $wordCount)
1264 {
1265 $words = explode(' ', $title);
1266
1267 if (count($words) <= $wordCount) {
1268 return $title; // No trimming needed
1269 }
1270
1271 $trimmedWords = array_slice($words, 0, $wordCount);
1272
1273 return implode(' ', $trimmedWords) . ' ...';
1274 }
1275
1276 public static function timeAgo($datetime)
1277 {
1278 $now = new \DateTime();
1279 $date = new \DateTime($datetime);
1280 $interval = $now->diff($date);
1281
1282 if ($interval->y > 0) {
1283 return $interval->y . ' year' . ($interval->y > 1 ? 's' : '') . ' ago';
1284 } elseif ($interval->m > 0) {
1285 return $interval->m . ' month' . ($interval->m > 1 ? 's' : '') . ' ago';
1286 } elseif ($interval->d > 0) {
1287 return $interval->d . ' day' . ($interval->d > 1 ? 's' : '') . ' ago';
1288 } elseif ($interval->h > 0) {
1289 return $interval->h . ' hour' . ($interval->h > 1 ? 's' : '') . ' ago';
1290 } elseif ($interval->i > 0) {
1291 return $interval->i . ' minute' . ($interval->i > 1 ? 's' : '') . ' ago';
1292 } else {
1293 return 'just now';
1294 }
1295 }
1296
1297 public static function removeQuote($attributes)
1298 {
1299 $parsedAttributes = [];
1300
1301 $regex = '/^on.*/i';
1302
1303 foreach ($attributes as $key => $value) {
1304 if (is_string($value)) {
1305 $cleanValue = str_replace(['"', "'"], '', $value);
1306 } else {
1307 $cleanValue = $value;
1308 }
1309
1310 if (!preg_match($regex, $key)) {
1311 $parsedAttributes[$key] = $cleanValue;
1312 }
1313 }
1314
1315 return $parsedAttributes;
1316 }
1317
1318 public static function getBooleanParam($param, $default = false)
1319 {
1320 return isset($param) && is_string($param) && ($param == 'true' || $param == 'yes') ? 'true' : ($default ? 'true' : 'false');
1321 }
1322
1323 public static function has_allowed_roles($allowed_roles = [])
1324 {
1325
1326 if (empty($allowed_roles) || (count($allowed_roles) == 1 && empty($allowed_roles[0]))) {
1327 return true;
1328 }
1329 $current_user = wp_get_current_user();
1330 $user_roles = $current_user->roles;
1331
1332 return !empty(array_intersect($user_roles, $allowed_roles));
1333 }
1334
1335 public static function get_elementor_global_color($settings, $key)
1336 {
1337
1338 $global_color = $settings[$key];
1339
1340 if (isset($settings['__globals__'][$key])) {
1341 $color_setting = $settings['__globals__'][$key];
1342
1343 if (strpos($color_setting, 'globals/colors?id=') === 0) {
1344 // It's a global color reference
1345 $global_id = str_replace('globals/colors?id=', '', $color_setting);
1346
1347 $kit = Plugin::$instance->kits_manager->get_current_settings();
1348
1349 $system_colors = isset($kit['system_colors']) ? $kit['system_colors'] : [];
1350 $custom_colors = isset($kit['custom_colors']) ? $kit['custom_colors'] : [];
1351 $global_colors = array_merge($system_colors, $custom_colors);
1352
1353 foreach ($global_colors as $color) {
1354
1355 if ($color['_id'] === $global_id) {
1356 $global_color = $color['color']; // Found a match, set the color
1357 break;
1358 }
1359 }
1360 }
1361 }
1362 return $global_color;
1363 }
1364 }
1365