PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.2.3
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.2.3
4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 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 2 years 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
1326 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
498 $share_position = !empty($attributes['sharePosition']) ? $attributes['sharePosition'] : 'right';
499 $custom_thumnail = !empty($attributes['customThumbnail']) ? urlencode($attributes['customThumbnail']) : '';
500 $custom_title = !empty($attributes['customTitle']) ? urlencode($attributes['customTitle']) : '';
501 $custom_description = !empty($attributes['customDescription']) ? urlencode($attributes['customDescription']) : '';
502
503 $page_url = urlencode(get_permalink() . '?hash=' . $content_id);
504
505 $social_icons = '<div class="ep-social-share-wraper"><div class="ep-social-share share-position-' . esc_attr($share_position) . '">';
506 $social_icons .= '<a href="https://www.facebook.com/sharer/sharer.php?u=' . $page_url . '" class="ep-social-icon facebook" target="_blank">
507 <svg width="64px" height="64px" fill="#000000" viewBox="0 -6 512 512" xmlns="http://www.w3.org/2000/svg">
508 <path d="M0 0h512v500H0z" fill="#475a96"/>
509 <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"/>
510 </svg>
511 </a>';
512 $social_icons .= '<a href="https://twitter.com/intent/tweet?url=' . $page_url . '&text=' . $custom_title . '" class="ep-social-icon twitter" target="_blank">
513 <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 248 204">
514 <path fill="#ffffff"
515 d="M221.95 51.29c.15 2.17.15 4.34.15 6.53 0 66.73-50.8 143.69-143.69 143.69v-.04c-27.44.04-54.31-7.82-77.41-22.64 3.99.48 8 .72 12.02.73 22.74.02 44.83-7.61 62.72-21.66-21.61-.41-40.56-14.5-47.18-35.07 7.57 1.46 15.37 1.16 22.8-.87-23.56-4.76-40.51-25.46-40.51-49.5v-.64c7.02 3.91 14.88 6.08 22.92 6.32C11.58 63.31 4.74 33.79 18.14 10.71c25.64 31.55 63.47 50.73 104.08 52.76-4.07-17.54 1.49-35.92 14.61-48.25 20.34-19.12 52.33-18.14 71.45 2.19 11.31-2.23 22.15-6.38 32.07-12.26-3.77 11.69-11.66 21.62-22.2 27.93 10.01-1.18 19.79-3.86 29-7.95-6.78 10.16-15.32 19.01-25.2 26.16z" />
516 </svg>
517 </a>';
518 $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">
519
520 <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>
521
522 </a>';
523
524 $social_icons .= '<a href="https://www.linkedin.com/sharing/share-offsite/?url=' . $page_url . '&title=' . $custom_title . '&summary=' . $custom_description . '&source=LinkedIn" class="ep-social-icon linkedin" target="_blank">
525
526 <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"
527 viewBox="0 0 310 310" xml:space="preserve">
528 <g id="XMLID_801_">
529 <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
530 C77.16,101.969,74.922,99.73,72.16,99.73z"/>
531 <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
532 c22.626,0,41.033-18.41,41.033-41.038C82.1,18.743,63.692,0.341,41.066,0.341z"/>
533 <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
534 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
535 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
536 C310,145.43,300.549,94.761,230.454,94.761z"/>
537 </g>
538 </svg>
539 </a>';
540 $social_icons .= '</div></div>';
541
542 return $social_icons;
543 }
544
545 public static function ep_get_elementor_widget_settings($page_settings = '', $id = '', $widgetType = '')
546 {
547
548 $data = json_decode($page_settings, true);
549
550 // Search for the element with the given ID
551 $element = null;
552 foreach ($data as $section) {
553 foreach ($section['elements'] as $column) {
554 foreach ($column['elements'] as $el) {
555 if ($el['id'] == $id && $el['elType'] == 'widget' && $el['widgetType'] == $widgetType) {
556 $element = $el;
557 break 3;
558 }
559 }
560 }
561 }
562
563 // Output the element code
564 if ($element) {
565 return $element;;
566 }
567 }
568
569 public static function ep_get_popup_icon()
570 {
571 $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>';
572
573 return $svg;
574 }
575 public static function ep_get_download_icon()
576 {
577 $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>';
578
579 return $svg;
580 }
581
582 public static function ep_get_print_icon()
583 {
584 $svg = '<div class="ep-doc-print-icon" ><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24">
585 <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"/>
586 </svg></div>';
587
588 return $svg;
589 }
590
591 public static function ep_get_fullscreen_icon()
592 {
593 $svg = '<div class="ep-doc-fullscreen-icon"><svg width="25" height="25" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
594 <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"/>
595 </svg></div>';
596
597 return $svg;
598 }
599 public static function ep_get_minimize_icon()
600 {
601 $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>';
602
603 return $svg;
604 }
605 public static function ep_get_draw_icon()
606 {
607 $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>';
608
609 return $svg;
610 }
611
612 public static function get_insta_video_icon()
613 {
614 $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">
615 <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>';
616
617 return $svg;
618 }
619
620 public static function get_insta_image_carousel_icon()
621 {
622 $svg = '<svg aria-label="Carousel" class="x1lliihq x1n2onr6" color="#FFF" fill="#FFF" height="25" viewBox="0 0 43.636 43.636" width="25">
623 <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>';
624
625 return $svg;
626 }
627
628 public static function get_insta_image_icon()
629 {
630 $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>';
631
632 return $svg;
633 }
634
635 public static function get_insta_like_icon()
636 {
637 $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>';
638
639 return $svg;
640 }
641 public static function get_insta_comment_icon()
642 {
643 $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>';
644
645 return $svg;
646 }
647 public static function get_instagram_icon()
648 {
649 $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>';
650
651 return $svg;
652 }
653
654 public static function get_google_presentation_url($embedded_url)
655 {
656 $parsed_url = parse_url($embedded_url);
657 $base_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . $parsed_url['path'];
658 $base_url = strtok($base_url, '?');
659 $base_url = rtrim($base_url, '/');
660 return $base_url;
661 }
662
663 public static function check_media_format($url)
664 {
665 $pattern1 = '/\.(mp4|mov|avi|wmv|flv|mkv|webm|mpeg|mpg)$/i';
666 $pattern2 = '/\.(mp3|wav|ogg|aac)$/i';
667
668 $isVideo = preg_match($pattern1, $url);
669 $isAudio = preg_match($pattern2, $url);
670
671 $is_self_hosted = false;
672 $format = '';
673
674 if (!empty($isVideo) || !empty($isAudio)) {
675 $is_self_hosted = true;
676 if (!empty($isVideo)) {
677 $format = 'video';
678 } else if (!empty($isAudio)) {
679 $format = 'audio';
680 }
681 }
682
683 if (!$is_self_hosted) {
684 return [
685 'selhosted' => false,
686 ];
687 }
688
689 return [
690 'selhosted' => true,
691 'format' => $format,
692 ];
693 }
694
695 // Ajax Methods get instagram feed data
696 public function loadmore_data_handler()
697 {
698 $connected_account_type = isset($_POST['connected_account_type']) ? sanitize_text_field($_POST['connected_account_type']) : 'personal';
699 $hashtag_id = isset($_POST['hashtag_id']) ? sanitize_text_field($_POST['hashtag_id']) : '';
700 $feed_type = isset($_POST['feed_type']) ? sanitize_text_field($_POST['feed_type']) : 'user_aacount_type';
701 $user_id = isset($_POST['user_id']) ? sanitize_text_field($_POST['user_id']) : '';
702 $loadmore_key = isset($_POST['loadmore_key']) ? sanitize_text_field($_POST['loadmore_key']) : '';
703 $nonce = isset($_POST['_nonce']) ? sanitize_text_field($_POST['_nonce']) : '';
704 $params = isset($_POST['params']) ? sanitize_text_field($_POST['params']) : '';
705 // $params = json_decode($params, true);
706 $params = stripslashes($params); // Remove extra backslashes
707 $params = json_decode($params, true);
708
709 // Verify nonce
710 if (!wp_verify_nonce($nonce, 'ep_nonce')) {
711 wp_send_json_error('Invalid nonce');
712 wp_die(); // Terminate script execution if nonce is invalid
713 }
714
715 $feeds_data = get_option('ep_instagram_feed_data');
716 $user_data = $feeds_data[$user_id]['feed_userinfo'];
717
718 if ($feed_type == 'hashtag_type') {
719 $feeds_data = get_option('ep_instagram_hashtag_feed');
720 }
721
722
723 $profile_picture_url = isset($user_data['profile_picture_url']) ? $user_data['profile_picture_url'] : '';
724
725 if ($feed_type === 'user_account_type' && isset($feeds_data[$loadmore_key]['feed_posts'])) {
726 $feed_posts = $feeds_data[$loadmore_key]['feed_posts'];
727 } else if ($feed_type === 'hashtag_type' && isset($feeds_data[$loadmore_key])) {
728 $feed_posts = $feeds_data[$loadmore_key];
729 } else {
730 $feed_posts = ['error'];
731 }
732
733
734 if (is_array($feed_posts) && count($feed_posts) > 0) {
735 $loaded_posts = isset($_POST['loaded_posts']) ? intval($_POST['loaded_posts']) : 0;
736 $posts_per_page = isset($_POST['posts_per_page']) ? intval($_POST['posts_per_page']) : 0;
737
738 $post_index = $loaded_posts + 1;
739 $start_index = $loaded_posts;
740
741 $next_posts = array_slice($feed_posts, $start_index, $posts_per_page);
742
743 ob_start();
744
745 if (is_array($next_posts) && count($next_posts) > 0) :
746 foreach ($next_posts as $post) :
747 $caption = !empty($post['caption']) ? $post['caption'] : '';
748 $media_type = !empty($post['media_type']) ? $post['media_type'] : '';
749 $media_url = !empty($post['media_url']) ? $post['media_url'] : '';
750 $permalink = !empty($post['permalink']) ? $post['permalink'] : '';
751 $timestamp = !empty($post['timestamp']) ? $post['timestamp'] : '';
752 $username = !empty($post['username']) ? $post['username'] : '';
753 $like_count = !empty($post['like_count']) ? $post['like_count'] : 0;
754 $comments_count = !empty($post['comments_count']) ? $post['comments_count'] : 0;
755
756 $post['profile_picture_url'] = $profile_picture_url;
757 $post['show_likes_count'] = isset($params['show_likes_count']) ? $params['show_likes_count'] : false;
758 $post['show_comments_count'] = isset($params['show_comments_count']) ? $params['show_comments_count'] : false;
759 $post['popup_follow_button'] = isset($params['popup_follow_button']) ? $params['popup_follow_button'] : true;
760 $post['popup_follow_button_text'] = isset($params['popup_follow_button_text']) ? $params['popup_follow_button_text'] : 'Follow';
761 ?>
762
763 <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); ?>">
764 <?php
765
766 if (!empty($hashtag_id) && $media_type == 'CAROUSEL_ALBUM') {
767 if (isset($post['children']['data'][0]['media_url'])) {
768 $hashtag_media_url = $post['children']['data'][0]['media_url'];
769 $hashtag_media_type = $post['children']['data'][0]['media_type'];
770
771 if ($hashtag_media_type == 'VIDEO') {
772 echo '<video class="insta-gallery-image" src="' . esc_url($hashtag_media_url) . '"></video>';
773 } else {
774 echo ' <img class="insta-gallery-image" src="' . esc_url($hashtag_media_url) . '" alt="' . esc_attr('image') . '">';
775 }
776 }
777 } else {
778 if ($media_type == 'VIDEO') {
779 echo '<video class="insta-gallery-image" src="' . esc_url($media_url) . '"></video>';
780 } else {
781 echo ' <img class="insta-gallery-image" src="' . esc_url($media_url) . '" alt="' . esc_attr('image') . '">';
782 }
783 }
784 ?>
785
786 <div class="insta-gallery-item-type">
787 <div class="insta-gallery-item-type-icon">
788 <?php
789 if ($media_type == 'VIDEO') {
790 echo Helper::get_insta_video_icon();
791 } else if ($media_type == 'CAROUSEL_ALBUM') {
792 echo Helper::get_insta_image_carousel_icon();
793 } else {
794 echo Helper::get_insta_image_icon();
795 }
796 ?>
797 </div>
798 </div>
799 <div class="insta-gallery-item-info">
800 <?php if (strtolower($connected_account_type) === 'business') : ?>
801 <div class="insta-item-reaction-count">
802 <div class="insta-gallery-item-likes">
803 <?php echo Helper::get_insta_like_icon();
804 echo esc_html($like_count); ?>
805 </div>
806 <div class="insta-gallery-item-comments">
807 <?php echo Helper::get_insta_comment_icon();
808 echo esc_html($comments_count); ?>
809 </div>
810 </div>
811 <?php else : ?>
812 <div class="insta-gallery-item-permalink">
813 <?php echo Helper::get_instagram_icon(); ?>
814 </div>
815 <?php endif; ?>
816 </div>
817 </div>
818
819 <?php $post_index++;
820 endforeach;
821 endif;
822
823 $feed_item = ob_get_clean();
824
825 $next_start_index = $start_index + count($next_posts);
826
827 wp_send_json(array(
828 'html' => $feed_item,
829 'next_post_index' => $next_start_index,
830 'total_feed_posts' => count($feed_posts)
831 ));
832 } else {
833 wp_send_json('');
834 }
835 }
836
837 public static function getCalendlyUuid($url)
838 {
839 $pattern = '/\/([0-9a-fA-F-]+)$/';
840 if (preg_match($pattern, $url, $matches)) {
841 $uuid = $matches[1];
842 return $uuid;
843 }
844 return '';
845 }
846
847 public static function getCalendlyUserInfo($access_token)
848 {
849 $transient_name = 'calendly_user_info_' . $access_token;
850 $user_info = get_transient($transient_name);
851 if (false === $user_info) {
852 $user_endpoint = 'https://api.calendly.com/users/me';
853 $headers = array(
854 'Authorization' => "Bearer $access_token",
855 'Content-Type' => 'application/json',
856 );
857 $args = array(
858 'headers' => $headers,
859 );
860 $response = wp_remote_get($user_endpoint, $args);
861 if (!is_wp_error($response) && 200 === wp_remote_retrieve_response_code($response)) {
862 $user_info = wp_remote_retrieve_body($response);
863 set_transient($transient_name, $user_info, 3600);
864 } else {
865 return false;
866 }
867 }
868
869 return $user_info;
870 }
871
872
873
874 public static function getCalaendlyEventTypes($user_uri, $access_token)
875 {
876 // Attempt to retrieve the data from the transient
877 $events_list = get_transient('calendly_events_list_' . md5($access_token));
878
879 if (false === $events_list) {
880 // If the data is not in the transient, fetch it from the API
881 $events_endpoint = "https://api.calendly.com/event_types?user=$user_uri";
882
883 $headers = array(
884 'Authorization' => "Bearer $access_token",
885 'Content-Type' => 'application/json',
886 );
887
888 $args = array(
889 'headers' => $headers,
890 );
891
892 $response = wp_remote_get($events_endpoint, $args);
893
894 if (!is_wp_error($response)) {
895 $body = wp_remote_retrieve_body($response);
896 $events_list = json_decode($body, true);
897
898 // Store the data in a transient for a specified time (e.g., 1 hour)
899 set_transient('calendly_events_list', $events_list, HOUR_IN_SECONDS);
900
901 return $events_list;
902 }
903 }
904
905 return $events_list;
906 }
907
908 public static function getListEventInvitee($uuid, $access_token)
909 {
910 // Attempt to retrieve the data from the transient
911 $invitee_list = get_transient('calendly_invitee_list_' . md5($access_token));
912
913 if (false === $invitee_list) {
914 // If the data is not in the transient, fetch it from the API
915 $events_endpoint = "https://api.calendly.com/scheduled_events/$uuid/invitees";
916
917 $headers = array(
918 'Authorization' => "Bearer $access_token",
919 'Content-Type' => 'application/json',
920 );
921
922 $args = array(
923 'headers' => $headers,
924 );
925
926 $response = wp_remote_get($events_endpoint, $args);
927
928 if (!is_wp_error($response)) {
929 $body = wp_remote_retrieve_body($response);
930 $invitee_list = json_decode($body, true);
931
932 // Store the data in a transient for a specified time (e.g., 1 hour)
933 set_transient('calendly_invitee_list', $invitee_list, HOUR_IN_SECONDS);
934
935 return $invitee_list;
936 }
937 }
938
939 return $invitee_list;
940 }
941
942 public static function getCalaendlyScheduledEvents($user_uri, $access_token)
943 {
944 // Attempt to retrieve the data from the transient
945 $events_list = get_transient('calendly_events_list_' . md5($access_token));
946
947 if (false === $events_list) {
948 // If the data is not in the transient, fetch it from the API
949 $events_endpoint = "https://api.calendly.com/scheduled_events?user=$user_uri";
950
951 $headers = array(
952 'Authorization' => "Bearer $access_token",
953 'Content-Type' => 'application/json',
954 );
955
956 $args = array(
957 'headers' => $headers,
958 );
959
960 $response = wp_remote_get($events_endpoint, $args);
961
962 if (!is_wp_error($response)) {
963 $body = wp_remote_retrieve_body($response);
964 $events_list = json_decode($body, true);
965
966 // Store the data in a transient for a specified time (e.g., 1 hour)
967 set_transient('calendly_events_list', $events_list, HOUR_IN_SECONDS);
968
969 return $events_list;
970 }
971 }
972
973 return $events_list;
974 }
975
976
977 public static function parseDuration($durationString)
978 {
979 list($minutes, $seconds) = explode(':', $durationString);
980 return intval($minutes) * 60 + intval($seconds);
981 }
982
983
984
985
986 public static function is_pro_active()
987 {
988 if (defined('EMBEDPRESS_SL_ITEM_SLUG')) {
989 return true;
990 }
991 return false;
992 }
993
994
995 public static function getInstagramUserInfo($accessToken, $accountType, $userId, $is_sync = false)
996 {
997 if ($is_sync) {
998 // If $is_sync is true, don't use transient
999 $use_transient = false;
1000 } else {
1001 // If $is_sync is false, use transient
1002 $transient_key = 'instagram_user_info_' . $userId;
1003 $use_transient = true;
1004 }
1005
1006 if ($use_transient && false !== ($userInfo = get_transient($transient_key))) {
1007 // If transient exists, return cached user info
1008 return $userInfo;
1009 }
1010
1011 if (strtolower($accountType) === 'business') {
1012 $api_url = 'https://graph.facebook.com/' . $userId . '?fields=biography,id,username,website,followers_count,media_count,profile_picture_url,name&access_token=' . $accessToken;
1013 } else {
1014 $api_url = "https://graph.instagram.com/me?fields=id,username,account_type,media_count,followers_count,biography,website&access_token={$accessToken}";
1015 }
1016
1017 $connected_account_type = $accountType;
1018
1019 $userInfoResponse = wp_remote_get($api_url);
1020
1021 if (is_wp_error($userInfoResponse)) {
1022 echo 'Error: Unable to retrieve Instagram user information.';
1023 } else {
1024 $userInfoBody = wp_remote_retrieve_body($userInfoResponse);
1025 $userInfo = json_decode($userInfoBody, true);
1026
1027 $userInfo['connected_account_type'] = $connected_account_type;
1028 $userInfo['access_token'] = $accessToken;
1029
1030
1031 if (!isset($userInfo['profile_picture_url'])) {
1032 $userInfo['profile_picture_url'] = '';
1033 }
1034
1035 // If not using transient, cache the user info for an hour
1036 if ($use_transient) {
1037 set_transient($transient_key, $userInfo, HOUR_IN_SECONDS);
1038 }
1039
1040 return $userInfo;
1041 }
1042 }
1043
1044
1045 // Get Instagram posts, videos, reels
1046 public static function getInstagramPosts($access_token, $account_type, $userId, $limit = 100, $is_sync = false)
1047 {
1048 if ($is_sync) {
1049 // If $is_sync is true, don't use transient
1050 $use_transient = false;
1051 } else {
1052 // If $is_sync is false, use transient
1053 $transient_key = 'instagram_posts_' . $userId;
1054 $use_transient = true;
1055 }
1056
1057 if ($use_transient && false !== ($posts = get_transient($transient_key))) {
1058 // If transient exists, return cached posts
1059 return $posts;
1060 }
1061
1062 if (strtolower($account_type) === 'business') {
1063 $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;
1064 } else {
1065 $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";
1066 }
1067
1068 $postsResponse = wp_remote_get($api_url);
1069
1070 if (is_wp_error($postsResponse)) {
1071 echo 'Error: Unable to retrieve Instagram posts.';
1072 } else {
1073 $postsBody = wp_remote_retrieve_body($postsResponse);
1074 $posts = json_decode($postsBody, true);
1075
1076 if (empty($posts['data'])) {
1077 return 'Please add Instagram Access Token';
1078 }
1079
1080 // If not using transient, cache the posts for an hour
1081 if ($use_transient) {
1082 set_transient($transient_key, $posts['data'], HOUR_IN_SECONDS);
1083 }
1084
1085 return $posts['data'];
1086 }
1087 }
1088
1089 public static function get_enable_settings_data_for_scripts($settings)
1090 {
1091 $settings_data = [
1092 'enabled_ads' => isset($settings['adManager']) && $settings['adManager'] === 'yes' ? 'yes' : '',
1093
1094 'enabled_custom_player' => isset($settings['emberpress_custom_player']) && $settings['emberpress_custom_player'] === 'yes' ? 'yes' : '',
1095
1096 'enabled_instafeed' => isset($settings['embedpress_pro_embeded_source']) && $settings['embedpress_pro_embeded_source'] === 'instafeed' ? 'yes' : '',
1097
1098 'enabled_docs_custom_viewer' => isset($settings['embedpress_document_viewer']) && $settings['embedpress_document_viewer'] === 'custom' ? 'yes' : '',
1099 ];
1100
1101 update_option('enabled_elementor_scripts', $settings_data);
1102 }
1103
1104 public static function get_options_value($key)
1105 {
1106 $g_settings = get_option(EMBEDPRESS_PLG_NAME);
1107
1108 if (isset($g_settings[$key])) {
1109 return $g_settings[$key];
1110 }
1111 return '';
1112 }
1113 public static function get_branding_value($key, $provider)
1114 {
1115 $settings = get_option(EMBEDPRESS_PLG_NAME . ':' . $provider, []);
1116
1117 if (isset($settings['branding']) && $settings['branding'] === 'yes' && isset($settings[$key])) {
1118 return $settings[$key];
1119 }
1120 return '';
1121 }
1122
1123
1124 public static function format_number($number)
1125 {
1126 if ($number >= 1000000000) {
1127 return number_format($number / 1000000000, 1) . 'b';
1128 } elseif ($number >= 1000000) {
1129 return number_format($number / 1000000, 1) . 'm';
1130 } elseif ($number >= 1000) {
1131 return number_format($number / 1000, 1) . 'k';
1132 } else {
1133 return $number;
1134 }
1135 }
1136
1137 public static function get_id($item)
1138 {
1139 $vid = isset($item->snippet->resourceId->videoId) ? $item->snippet->resourceId->videoId : null;
1140 $vid = $vid ? $vid : (isset($item->id->videoId) ? $item->id->videoId : null);
1141 $vid = $vid ? $vid : (isset($item->id) ? $item->id : null);
1142 return $vid;
1143 }
1144
1145 public static function clean_api_error($raw_message)
1146 {
1147 return htmlspecialchars(strip_tags(preg_replace('@&key=[^& ]+@i', '&key=*******', $raw_message)));
1148 }
1149
1150 public static function clean_api_error_html($raw_message)
1151 {
1152 $clean_html = '';
1153 if ((defined('REST_REQUEST') && REST_REQUEST) || current_user_can('manage_options')) {
1154 $clean_html = '<div>' . __('EmbedPress: ', 'embedpress') . self::clean_api_error($raw_message) . '</div>';
1155 }
1156 return $clean_html;
1157 }
1158
1159 public static function get_thumbnail_url($item, $quality, $privacyStatus)
1160 {
1161 $url = "";
1162 if ($privacyStatus == 'private') {
1163 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/private.png';
1164 } elseif (isset($item->snippet->thumbnails->{$quality}->url)) {
1165 $url = $item->snippet->thumbnails->{$quality}->url;
1166 } elseif (isset($item->snippet->thumbnails->medium->url)) {
1167 $url = $item->snippet->thumbnails->medium->url;
1168 } elseif (isset($item->snippet->thumbnails->default->url)) {
1169 $url = $item->snippet->thumbnails->default->url;
1170 } elseif (isset($item->snippet->thumbnails->high->url)) {
1171 $url = $item->snippet->thumbnails->high->url;
1172 } else {
1173 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/deleted-video-thumb.png';
1174 }
1175 return $url;
1176 }
1177
1178 public static function compare_vid_date($a, $b)
1179 {
1180 $dateA = strtotime($a->snippet->publishedAt);
1181 $dateB = strtotime($b->snippet->publishedAt);
1182
1183 // Sort in descending order (newest first)
1184 return $dateB - $dateA;
1185 }
1186
1187
1188 public static function get_youtube_video_data($api_key, $video_id)
1189 {
1190 // Set a unique transient name based on the video ID
1191 $transient_name = 'youtube_video_data_' . $video_id;
1192
1193 // Try to get data from the transient cache
1194 $video_data = get_transient($transient_name);
1195
1196 // If no cached data, fetch from the API
1197 if ($video_data === false) {
1198 // YouTube Data API URL
1199 $url = "https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id={$video_id}&key={$api_key}";
1200
1201 // Fetch the data from the API
1202 $response = wp_remote_get($url);
1203
1204 if (is_wp_error($response)) {
1205 return false; // Return false if there is an error
1206 }
1207
1208 $body = wp_remote_retrieve_body($response);
1209 $video_data = json_decode($body, true);
1210
1211 if (isset($video_data['items'][0])) {
1212 $video_data = $video_data['items'][0];
1213
1214 // Cache the data in a transient for 12 hours
1215 set_transient($transient_name, $video_data, 24 * HOUR_IN_SECONDS);
1216 } else {
1217 return false; // Return false if no data found
1218 }
1219 }
1220
1221 return $video_data;
1222 }
1223
1224 public static function trimTitle($title, $wordCount)
1225 {
1226 $words = explode(' ', $title);
1227
1228 if (count($words) <= $wordCount) {
1229 return $title; // No trimming needed
1230 }
1231
1232 $trimmedWords = array_slice($words, 0, $wordCount);
1233
1234 return implode(' ', $trimmedWords) . ' ...';
1235 }
1236
1237 public static function timeAgo($datetime)
1238 {
1239 $now = new \DateTime();
1240 $date = new \DateTime($datetime);
1241 $interval = $now->diff($date);
1242
1243 if ($interval->y > 0) {
1244 return $interval->y . ' year' . ($interval->y > 1 ? 's' : '') . ' ago';
1245 } elseif ($interval->m > 0) {
1246 return $interval->m . ' month' . ($interval->m > 1 ? 's' : '') . ' ago';
1247 } elseif ($interval->d > 0) {
1248 return $interval->d . ' day' . ($interval->d > 1 ? 's' : '') . ' ago';
1249 } elseif ($interval->h > 0) {
1250 return $interval->h . ' hour' . ($interval->h > 1 ? 's' : '') . ' ago';
1251 } elseif ($interval->i > 0) {
1252 return $interval->i . ' minute' . ($interval->i > 1 ? 's' : '') . ' ago';
1253 } else {
1254 return 'just now';
1255 }
1256 }
1257
1258 public static function removeQuote($attributes)
1259 {
1260 $parsedAttributes = [];
1261
1262 $regex = '/^on.*/i';
1263
1264 foreach ($attributes as $key => $value) {
1265 if (is_string($value)) {
1266 $cleanValue = str_replace(['"', "'"], '', $value);
1267 } else {
1268 $cleanValue = $value;
1269 }
1270
1271 if (!preg_match($regex, $key)) {
1272 $parsedAttributes[$key] = $cleanValue;
1273 }
1274 }
1275
1276 return $parsedAttributes;
1277 }
1278
1279 public static function getBooleanParam($param, $default = false)
1280 {
1281 return isset($param) && is_string($param) && ($param == 'true' || $param == 'yes') ? 'true' : ($default ? 'true' : 'false');
1282 }
1283
1284 public static function has_allowed_roles($allowed_roles = [])
1285 {
1286
1287 if (empty($allowed_roles) || (count($allowed_roles) == 1 && empty($allowed_roles[0]))) {
1288 return true;
1289 }
1290 $current_user = wp_get_current_user();
1291 $user_roles = $current_user->roles;
1292
1293 return !empty(array_intersect($user_roles, $allowed_roles));
1294 }
1295
1296 public static function get_elementor_global_color($settings, $key)
1297 {
1298
1299 $global_color = $settings[$key];
1300
1301 if (isset($settings['__globals__'][$key])) {
1302 $color_setting = $settings['__globals__'][$key];
1303
1304 if (strpos($color_setting, 'globals/colors?id=') === 0) {
1305 // It's a global color reference
1306 $global_id = str_replace('globals/colors?id=', '', $color_setting);
1307
1308 $kit = Plugin::$instance->kits_manager->get_current_settings();
1309
1310 $system_colors = isset($kit['system_colors']) ? $kit['system_colors'] : [];
1311 $custom_colors = isset($kit['custom_colors']) ? $kit['custom_colors'] : [];
1312 $global_colors = array_merge($system_colors, $custom_colors);
1313
1314 foreach ($global_colors as $color) {
1315
1316 if ($color['_id'] === $global_id) {
1317 $global_color = $color['color']; // Found a match, set the color
1318 break;
1319 }
1320 }
1321 }
1322 }
1323 return $global_color;
1324 }
1325 }
1326