PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.1.6
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.1.6
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 3 years ago Extend_Elementor_Controls.php 1 year ago Feature_Enhancer.php 1 year ago Helper.php 1 year ago
Helper.php
1276 lines
1 <?php
2
3 namespace EmbedPress\Includes\Classes;
4
5 use EmbedPress\Providers\TemplateLayouts\YoutubeLayout;
6 use EmbedPress\Shortcode;
7
8 if (!defined('ABSPATH')) {
9 exit;
10 } // Exit if accessed directly
11
12 class Helper
13 {
14
15 /**
16 * Parse a query string into an associative array.
17 *
18 * If multiple values are found for the same key, the value of that key
19 * value pair will become an array. This function does not parse nested
20 * PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will
21 * be parsed into ['foo[a]' => '1', 'foo[b]' => '2']).
22 *
23 * @param string $str Query string to parse
24 * @param int|bool $urlEncoding How the query string is encoded
25 *
26 * @return array
27 */
28
29 public function __construct()
30 {
31 add_action('wp_ajax_lock_content_form_handler', [$this, 'lock_content_form_handler']);
32 add_action('wp_ajax_nopriv_lock_content_form_handler', [$this, 'lock_content_form_handler']);
33
34
35 add_action('wp_ajax_loadmore_data_handler', [$this, 'loadmore_data_handler']);
36 add_action('wp_ajax_nopriv_loadmore_data_handler', [$this, 'loadmore_data_handler']);
37
38
39 add_action('wp_ajax_fetch_video_description', [$this, 'ajax_video_popup_description']);
40 add_action('wp_ajax_nopriv_fetch_video_description', [$this, 'ajax_video_popup_description']);
41 }
42
43 public function ajax_video_popup_description()
44 {
45 if (isset($_POST['vid'])) {
46 $api_key = self::get_api_key();
47 $vid = sanitize_text_field($_POST['vid']);
48
49 $video_data = Helper::get_youtube_video_data($api_key, $vid);
50
51 if ($video_data) {
52 ob_start();
53 ?>
54 <div class="video-description">
55 <?php echo YoutubeLayout::generate_youtube_video_description($video_data); ?>
56 </div>
57 <?php
58 $description_html = ob_get_clean();
59 wp_send_json_success(['description' => $description_html]);
60 } else {
61 wp_send_json_error(['error' => 'Failed to fetch video data.']);
62 }
63 } else {
64 wp_send_json_error(['error' => 'Invalid video ID.']);
65 }
66 }
67
68 public static function get_api_key()
69 {
70 $settings = (array) get_option(EMBEDPRESS_PLG_NAME . ':youtube', []);
71 return !empty($settings['api_key']) ? $settings['api_key'] : '';
72 }
73
74 public static function parse_query($str, $urlEncoding = true)
75 {
76 $result = [];
77
78 if ($str === '') {
79 return $result;
80 }
81
82 if ($urlEncoding === true) {
83 $decoder = function ($value) {
84 return rawurldecode(str_replace('+', ' ', $value));
85 };
86 } elseif ($urlEncoding === PHP_QUERY_RFC3986) {
87 $decoder = 'rawurldecode';
88 } elseif ($urlEncoding === PHP_QUERY_RFC1738) {
89 $decoder = 'urldecode';
90 } else {
91 $decoder = function ($str) {
92 return $str;
93 };
94 }
95
96 foreach (explode('&', $str) as $kvp) {
97 $parts = explode('=', $kvp, 2);
98 $key = $decoder($parts[0]);
99 $value = isset($parts[1]) ? $decoder($parts[1]) : null;
100 if (!isset($result[$key])) {
101 $result[$key] = $value;
102 } else {
103 if (!is_array($result[$key])) {
104 $result[$key] = [$result[$key]];
105 }
106 $result[$key][] = $value;
107 }
108 }
109
110 return $result;
111 }
112 public static function get_pdf_renderer()
113 {
114 // $renderer = EMBEDPRESS_URL_ASSETS . 'pdf/web/viewer.html';
115
116 $renderer = admin_url('admin-ajax.php?action=get_viewer');
117
118 // @TODO; apply settings query args here
119 return $renderer;
120 }
121
122 public static function get_extension_from_file_url($url)
123 {
124 $urlSplit = explode(".", $url);
125 $ext = end($urlSplit);
126 return $ext;
127 }
128
129 public static function is_file_url($url)
130 {
131 $pattern = '/\.([0-9a-z]+)(?=[?#])|(\.)(?:[\w]+)$/i';
132 return preg_match($pattern, $url) === 1;
133 }
134
135 public static function is_opensea($url)
136 {
137 return strpos($url, "opensea.io") !== false;
138 }
139 public static function is_youtube_channel($url)
140 {
141 return (bool) (preg_match('~(?:https?:\/\/)?(?:www\.)?(?:youtube.com\/)(?:channel\/|c\/|user\/|@)(\w+)~i', (string) $url));
142 }
143
144 public static function is_youtube($url)
145 {
146 return (bool) (preg_match('~(?:https?://)?(?:www\.)?(?:youtube\.com|youtu\.be)/watch\?v=([^&]+)~i', (string) $url));
147 }
148
149 // Saved sources data temporary in wp_options table
150 public static function get_source_data($blockid, $source_url, $source_option_name, $source_temp_option_name)
151 {
152
153
154 if (self::is_youtube_channel($source_url)) {
155 $source_name = 'YoutubeChannel';
156 } else if (self::is_youtube($source_url)) {
157 $source_name = 'Youtube';
158 } else if (!empty(self::is_file_url($source_url))) {
159 $source_name = 'document_' . self::get_extension_from_file_url($source_url);
160 } else if (self::is_opensea($source_url)) {
161 $source_name = 'OpenSea';
162 } else {
163 Shortcode::get_embera_instance();
164 $collectios = Shortcode::get_collection();
165 $provider = $collectios->findProviders($source_url);
166
167 if (!empty($provider[$source_url])) {
168 $source_name = $provider[$source_url]->getProviderName();
169 } else {
170 $host = parse_url($source_url, PHP_URL_HOST);
171 if ($host) {
172 $parts = explode('.', $host);
173 if (count($parts) > 1) {
174 $source_name = $parts[1];
175 } else {
176 // Handle the case where the host doesn't have at least two parts
177 $source_name = $host;
178 }
179 } else {
180 // Handle the case where parse_url fails
181 $source_name = 'unknown';
182 }
183 }
184 }
185
186 if (!empty($blockid) && $blockid != 'undefined') {
187 $sources = json_decode(get_option($source_temp_option_name), true);
188
189 if (!$sources) {
190 $sources = array();
191 }
192 $exists = false;
193
194 foreach ($sources as $i => $source) {
195 if ($source['id'] === $blockid) {
196 $sources[$i]['source']['name'] = $source_name;
197 $sources[$i]['source']['url'] = $source_url;
198 $exists = true;
199 break;
200 }
201 }
202
203 if (!$exists) {
204 $sources[] = array('id' => $blockid, 'source' => array('name' => $source_name, 'url' => $source_url, 'count' => 1));
205 }
206
207 update_option($source_temp_option_name, json_encode($sources));
208 }
209 }
210
211 // Saved source data when post updated
212 public static function get_save_source_data_on_post_update($source_option_name, $source_temp_option_name)
213 {
214
215 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
216 return;
217 }
218 $temp_data = json_decode(get_option($source_temp_option_name), true);
219 $source_data = json_decode(get_option($source_option_name), true);
220 if (!$temp_data) {
221 $temp_data = array();
222 }
223 if (!$source_data) {
224 $source_data = array();
225 }
226
227 $sources = array_merge($temp_data, $source_data);
228
229 $unique_sources = array();
230 foreach ($sources as $source) {
231 $unique_sources[$source['id']] = $source;
232 }
233
234 $unique_sources = array_values($unique_sources);
235
236 delete_option($source_temp_option_name);
237
238 update_option($source_option_name, json_encode($unique_sources));
239 }
240
241 //Delete source data from option table when widget is removed
242 public static function get_delete_source_data($blockid, $source_option_name, $source_temp_option_name)
243 {
244 if (!empty($blockid) && $blockid != 'undefined') {
245 $sources = json_decode(get_option($source_option_name), true);
246 $temp_sources = json_decode(get_option($source_temp_option_name), true);
247 if ($sources) {
248 foreach ($sources as $i => $source) {
249 if ($source['id'] === $blockid) {
250 unset($sources[$i]);
251 break;
252 }
253 }
254 update_option($source_option_name, json_encode(array_values($sources)));
255 }
256 if ($temp_sources) {
257 foreach ($temp_sources as $i => $source) {
258 if ($source['id'] === $blockid) {
259 unset($temp_sources[$i]);
260 break;
261 }
262 }
263 update_option($source_temp_option_name, json_encode(array_values($temp_sources)));
264 }
265 }
266 wp_die();
267 }
268
269 //Delete source temporary data when reload without update or publish
270 public static function get_delete_source_temp_data_on_reload($source_temp_option_name)
271 {
272 $source_temp_data = json_decode(get_option($source_temp_option_name), true);
273 if ($source_temp_data) {
274 delete_option($source_temp_option_name);
275 }
276 }
277
278 public static function get_file_title($url)
279 {
280 return get_the_title(attachment_url_to_postid($url));
281 }
282
283 public static function get_hash()
284 {
285 $hash_key = get_option(EMBEDPRESS_PLG_NAME . '_hash_key');
286 if (!$hash_key) {
287 $hash_key = wp_hash_password(wp_generate_password(30));
288 update_option(EMBEDPRESS_PLG_NAME . '_hash_key', $hash_key);
289 }
290 return $hash_key;
291 }
292
293 public function lock_content_form_handler()
294 {
295
296 $client_id = isset($_POST['client_id']) ? sanitize_text_field($_POST['client_id']) : '';
297 $password = isset($_POST['password']) ? sanitize_text_field($_POST['password']) : '';
298 $post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
299
300 $epbase64 = get_post_meta($post_id, 'ep_base_' . $client_id, false);
301 $hash_key = get_post_meta($post_id, 'hash_key_' . $client_id, false);
302
303 // Set the decryption key and initialization vector (IV)
304 $key = self::get_hash();
305
306 // Decode the base64 encoded cipher
307 $cipher = base64_decode($epbase64);
308 // Decrypt the cipher using AES-128-CBC encryption
309
310 $wp_pass_key = hash('sha256', wp_salt(32) . md5($password));
311 $iv = substr($wp_pass_key, 0, 16);
312 if ($wp_pass_key === $hash_key) {
313 setcookie("password_correct_", $password, time() + 3600);
314
315 $embed = openssl_decrypt($cipher, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv) . '<script>
316 const now = new Date();
317 const time = now.getTime();
318 const expireTime = time + 1000 * 60 * 60 * 24 * 30;
319 now.setTime(expireTime);
320 document.cookie = "password_correct_' . esc_js($client_id) . '=' . esc_js($hash_key) . '; expires=" + now.toUTCString() + "; path=/";
321 </script>';
322 } else {
323 $embed = 0;
324 }
325
326 // Process the form data and return a response
327 $response = array(
328 'success' => true,
329 'password' => $password,
330 'embedHtml' => $embed,
331 );
332
333 wp_send_json($response);
334 }
335
336 public static function display_password_form($client_id = '', $embedHtml = '', $pass_hash_key = '', $attributes = [])
337 {
338 $lock_heading = !empty($attributes['lockHeading']) ? sanitize_text_field($attributes['lockHeading']) : '';
339 $lock_subheading = !empty($attributes['lockSubHeading']) ? sanitize_text_field($attributes['lockSubHeading']) : '';
340 $lock_error_message = !empty($attributes['lockErrorMessage']) ? sanitize_text_field($attributes['lockErrorMessage']) : '';
341 $footer_message = !empty($attributes['footerMessage']) ? sanitize_text_field($attributes['footerMessage']) : '';
342 $password_placeholder = !empty($attributes['passwordPlaceholder']) ? sanitize_text_field($attributes['passwordPlaceholder']) : '';
343 $button_text = !empty($attributes['submitButtonText']) ? sanitize_text_field($attributes['submitButtonText']) : '';
344 $unlocking_text = !empty($attributes['submitUnlockingText']) ? sanitize_text_field($attributes['submitUnlockingText']) : '';
345 $enable_footer_message = !empty($attributes['enableFooterMessage']) ? sanitize_text_field($attributes['enableFooterMessage']) : '';
346
347
348 // Set the encryption key and initialization vector (IV)
349 $key = self::get_hash();
350
351 $salt = wp_salt(32);
352 $wp_hash_key = hash('sha256', $salt . $pass_hash_key);
353 $iv = substr($wp_hash_key, 0, 16);
354
355
356 // Encrypt the plaintext using AES-128-CBC encryption
357 $cipher = openssl_encrypt($embedHtml, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
358
359 // Base64 encode the encrypted cipher
360 $encrypted_data = base64_encode($cipher);
361
362 update_post_meta(get_the_ID(), 'ep_base_' . $client_id, $encrypted_data);
363 update_post_meta(get_the_ID(), 'hash_key_' . $client_id, $wp_hash_key);
364
365 $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>';
366
367 echo '
368 <div class="password-form-container">
369 <h2>' . esc_html($lock_heading) . '</h2>
370 <p>' . esc_html($lock_subheading) . ' </p>
371 <form class="password-form" method="post" class="password-form" data-unlocking-text="' . esc_attr($unlocking_text) . '">
372
373 <div class="password-field">
374 <span class="lock-icon">' . $lock_icon . '</span>
375 <input type="password" name="pass_' . esc_attr($client_id) . '" placeholder="' . esc_attr($password_placeholder) . '" required>
376 </div>
377 <input type="hidden" name="ep_client_id" value="' . esc_attr($client_id) . '">
378 <input type="hidden" name="post_id" value="' . esc_attr(get_the_ID()) . '">
379
380 <input type="submit" name="password_submit" value="' . esc_attr($button_text) . '">
381 <div class="error-message hidden">' . esc_html($lock_error_message) . '</div>
382 </form>
383 ' . (!empty($enable_footer_message) ? '<p class="need-access-message">' . esc_html($footer_message) . '</p>' : '') . '
384 </div>
385 ';
386 }
387
388 // Check if the user has already entered the correct password
389 public static function is_password_correct($client_id)
390 {
391 if (isset($_COOKIE['password_correct_' . $client_id])) {
392 return $_COOKIE['password_correct_' . $client_id];
393 } else {
394 return false;
395 }
396 }
397
398 public static function customLogo($embedHTML, $atts)
399 {
400 $x = !empty($atts['logoX']) ? $atts['logoX'] : 0;
401 $y = !empty($atts['logoY']) ? $atts['logoY'] : 0;
402 $uniqid = !empty($atts['url']) ? '.ose-uid-' . md5($atts['url']) : '';
403
404 $brandUrl = !empty($atts['customlogoUrl']) ? $atts['customlogoUrl'] : '';
405 $opacity = !empty($atts['logoOpacity']) ? $atts['logoOpacity'] : '';
406
407 $cssClass = !empty($atts['url']) ? '.ose-uid-' . md5($atts['url']) : '.ose-youtube';
408
409
410
411 ob_start(); ?>
412 <style type="text/css">
413 <?php echo esc_html($cssClass); ?> {
414 position: relative;
415 }
416
417 <?php echo esc_html($cssClass); ?>.watermark {
418 border: 0;
419 position: absolute;
420 bottom: <?php echo esc_html($y); ?>%;
421 right: <?php echo esc_html($x); ?>%;
422 max-width: 150px;
423 max-height: 75px;
424 opacity: 0.25;
425 z-index: 5;
426 -o-transition: opacity 0.5s ease-in-out;
427 -moz-transition: opacity 0.5s ease-in-out;
428 -webkit-transition: opacity 0.5s ease-in-out;
429 transition: opacity 0.5s ease-in-out;
430 opacity: <?php echo esc_html($opacity); ?>;
431 }
432
433 <?php echo esc_html($cssClass); ?>.watermark:hover {
434 opacity: 1;
435 }
436 </style>
437 <?php
438
439
440 $style = ob_get_clean();
441
442 if (!class_exists('\simple_html_dom')) {
443 include_once EMBEDPRESS_PATH_CORE . 'simple_html_dom.php';
444 }
445
446 $cta = '';
447 $img = '';
448
449 if (!empty($atts['customlogo'])) {
450 $img = '<img src="' . esc_url($atts['customlogo']) . '"/>';
451
452 $imgDom = str_get_html($img);
453 $imgDom = $imgDom->find('img', 0);
454 $imgDom->setAttribute('class', 'watermark ep-custom-logo');
455 $imgDom->removeAttribute('style');
456 $imgDom->setAttribute('width', 'auto');
457 $imgDom->setAttribute('height', 'auto');
458 ob_start();
459 echo $imgDom;
460
461 $cta .= ob_get_clean();
462
463 $imgDom->clear();
464 unset($img, $imgDom);
465
466 if (!empty($brandUrl)) {
467 $cta = '<a href="' . esc_url($brandUrl) . '" target="_blank">' . $cta . '</a>';
468 }
469 $dom = str_get_html($embedHTML);
470
471 $wrapDiv = $dom->find($uniqid, 0);
472
473 if (!empty($wrapDiv) && is_object($wrapDiv)) {
474 $wrapDiv->innertext .= $cta;
475 }
476
477 ob_start();
478 echo $wrapDiv;
479
480 $markup = ob_get_clean();
481
482 $dom->clear();
483 unset($dom, $wrapDiv);
484
485 $embedHTML = $style . $markup;
486 }
487
488 return $embedHTML;
489 }
490
491
492 public static function embed_content_share($content_id = '', $attributes = [])
493 {
494
495 $share_position = !empty($attributes['sharePosition']) ? $attributes['sharePosition'] : 'right';
496 $custom_thumnail = !empty($attributes['customThumbnail']) ? urlencode($attributes['customThumbnail']) : '';
497 $custom_title = !empty($attributes['customTitle']) ? urlencode($attributes['customTitle']) : '';
498 $custom_description = !empty($attributes['customDescription']) ? urlencode($attributes['customDescription']) : '';
499
500 $page_url = urlencode(get_permalink() . '?hash=' . $content_id);
501
502 $social_icons = '<div class="ep-social-share-wraper"><div class="ep-social-share share-position-' . esc_attr($share_position) . '">';
503 $social_icons .= '<a href="https://www.facebook.com/sharer/sharer.php?u=' . $page_url . '" class="ep-social-icon facebook" target="_blank">
504 <svg width="64px" height="64px" fill="#000000" viewBox="0 -6 512 512" xmlns="http://www.w3.org/2000/svg">
505 <path d="M0 0h512v500H0z" fill="#475a96"/>
506 <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"/>
507 </svg>
508 </a>';
509 $social_icons .= '<a href="https://twitter.com/intent/tweet?url=' . $page_url . '&text=' . $custom_title . '" class="ep-social-icon twitter" target="_blank">
510 <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 248 204">
511 <path fill="#ffffff"
512 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" />
513 </svg>
514 </a>';
515 $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">
516
517 <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>
518
519 </a>';
520
521 $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">
522
523 <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"
524 viewBox="0 0 310 310" xml:space="preserve">
525 <g id="XMLID_801_">
526 <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
527 C77.16,101.969,74.922,99.73,72.16,99.73z"/>
528 <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
529 c22.626,0,41.033-18.41,41.033-41.038C82.1,18.743,63.692,0.341,41.066,0.341z"/>
530 <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
531 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
532 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
533 C310,145.43,300.549,94.761,230.454,94.761z"/>
534 </g>
535 </svg>
536 </a>';
537 $social_icons .= '</div></div>';
538
539 return $social_icons;
540 }
541
542 public static function ep_get_elementor_widget_settings($page_settings = '', $id = '', $widgetType = '')
543 {
544
545 $data = json_decode($page_settings, true);
546
547 // Search for the element with the given ID
548 $element = null;
549 foreach ($data as $section) {
550 foreach ($section['elements'] as $column) {
551 foreach ($column['elements'] as $el) {
552 if ($el['id'] == $id && $el['elType'] == 'widget' && $el['widgetType'] == $widgetType) {
553 $element = $el;
554 break 3;
555 }
556 }
557 }
558 }
559
560 // Output the element code
561 if ($element) {
562 return $element;;
563 }
564 }
565
566 public static function ep_get_popup_icon()
567 {
568 $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>';
569
570 return $svg;
571 }
572 public static function ep_get_download_icon()
573 {
574 $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>';
575
576 return $svg;
577 }
578
579 public static function ep_get_print_icon()
580 {
581 $svg = '<div class="ep-doc-print-icon" ><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24">
582 <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"/>
583 </svg></div>';
584
585 return $svg;
586 }
587
588 public static function ep_get_fullscreen_icon()
589 {
590 $svg = '<div class="ep-doc-fullscreen-icon"><svg width="25" height="25" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
591 <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"/>
592 </svg></div>';
593
594 return $svg;
595 }
596 public static function ep_get_minimize_icon()
597 {
598 $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>';
599
600 return $svg;
601 }
602 public static function ep_get_draw_icon()
603 {
604 $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>';
605
606 return $svg;
607 }
608
609 public static function get_insta_video_icon()
610 {
611 $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">
612 <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>';
613
614 return $svg;
615 }
616
617 public static function get_insta_image_carousel_icon()
618 {
619 $svg = '<svg aria-label="Carousel" class="x1lliihq x1n2onr6" color="#FFF" fill="#FFF" height="25" viewBox="0 0 43.636 43.636" width="25">
620 <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>';
621
622 return $svg;
623 }
624
625 public static function get_insta_image_icon()
626 {
627 $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>';
628
629 return $svg;
630 }
631
632 public static function get_insta_like_icon()
633 {
634 $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>';
635
636 return $svg;
637 }
638 public static function get_insta_comment_icon()
639 {
640 $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>';
641
642 return $svg;
643 }
644 public static function get_instagram_icon()
645 {
646 $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>';
647
648 return $svg;
649 }
650
651 public static function get_google_presentation_url($embedded_url)
652 {
653 $parsed_url = parse_url($embedded_url);
654 $base_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . $parsed_url['path'];
655 $base_url = strtok($base_url, '?');
656 $base_url = rtrim($base_url, '/');
657 return $base_url;
658 }
659
660 public static function check_media_format($url)
661 {
662 $pattern1 = '/\.(mp4|mov|avi|wmv|flv|mkv|webm|mpeg|mpg)$/i';
663 $pattern2 = '/\.(mp3|wav|ogg|aac)$/i';
664
665 $isVideo = preg_match($pattern1, $url);
666 $isAudio = preg_match($pattern2, $url);
667
668 $is_self_hosted = false;
669 $format = '';
670
671 if (!empty($isVideo) || !empty($isAudio)) {
672 $is_self_hosted = true;
673 if (!empty($isVideo)) {
674 $format = 'video';
675 } else if (!empty($isAudio)) {
676 $format = 'audio';
677 }
678 }
679
680 if (!$is_self_hosted) {
681 return [
682 'selhosted' => false,
683 ];
684 }
685
686 return [
687 'selhosted' => true,
688 'format' => $format,
689 ];
690 }
691
692 // Ajax Methods get instagram feed data
693 public function loadmore_data_handler()
694 {
695 $connected_account_type = isset($_POST['connected_account_type']) ? sanitize_text_field($_POST['connected_account_type']) : 'personal';
696 $hashtag_id = isset($_POST['hashtag_id']) ? sanitize_text_field($_POST['hashtag_id']) : '';
697 $feed_type = isset($_POST['feed_type']) ? sanitize_text_field($_POST['feed_type']) : 'user_aacount_type';
698 $user_id = isset($_POST['user_id']) ? sanitize_text_field($_POST['user_id']) : '';
699 $loadmore_key = isset($_POST['loadmore_key']) ? sanitize_text_field($_POST['loadmore_key']) : '';
700 $nonce = isset($_POST['_nonce']) ? sanitize_text_field($_POST['_nonce']) : '';
701 $params = isset($_POST['params']) ? sanitize_text_field($_POST['params']) : '';
702 // $params = json_decode($params, true);
703 $params = stripslashes($params); // Remove extra backslashes
704 $params = json_decode($params, true);
705
706 // Verify nonce
707 if (!wp_verify_nonce($nonce, 'ep_nonce')) {
708 wp_send_json_error('Invalid nonce');
709 wp_die(); // Terminate script execution if nonce is invalid
710 }
711
712 $feeds_data = get_option('ep_instagram_feed_data');
713 $user_data = $feeds_data[$user_id]['feed_userinfo'];
714
715 if ($feed_type == 'hashtag_type') {
716 $feeds_data = get_option('ep_instagram_hashtag_feed');
717 }
718
719
720 $profile_picture_url = isset($user_data['profile_picture_url']) ? $user_data['profile_picture_url'] : '';
721
722 if ($feed_type === 'user_account_type' && isset($feeds_data[$loadmore_key]['feed_posts'])) {
723 $feed_posts = $feeds_data[$loadmore_key]['feed_posts'];
724 } else if ($feed_type === 'hashtag_type' && isset($feeds_data[$loadmore_key])) {
725 $feed_posts = $feeds_data[$loadmore_key];
726 } else {
727 $feed_posts = ['error'];
728 }
729
730
731 if (is_array($feed_posts) && count($feed_posts) > 0) {
732 $loaded_posts = isset($_POST['loaded_posts']) ? intval($_POST['loaded_posts']) : 0;
733 $posts_per_page = isset($_POST['posts_per_page']) ? intval($_POST['posts_per_page']) : 0;
734
735 $post_index = $loaded_posts + 1;
736 $start_index = $loaded_posts;
737
738 $next_posts = array_slice($feed_posts, $start_index, $posts_per_page);
739
740 ob_start();
741
742 if (is_array($next_posts) && count($next_posts) > 0) :
743 foreach ($next_posts as $post) :
744 $caption = !empty($post['caption']) ? $post['caption'] : '';
745 $media_type = !empty($post['media_type']) ? $post['media_type'] : '';
746 $media_url = !empty($post['media_url']) ? $post['media_url'] : '';
747 $permalink = !empty($post['permalink']) ? $post['permalink'] : '';
748 $timestamp = !empty($post['timestamp']) ? $post['timestamp'] : '';
749 $username = !empty($post['username']) ? $post['username'] : '';
750 $like_count = !empty($post['like_count']) ? $post['like_count'] : 0;
751 $comments_count = !empty($post['comments_count']) ? $post['comments_count'] : 0;
752
753 $post['profile_picture_url'] = $profile_picture_url;
754 $post['show_likes_count'] = isset($params['show_likes_count']) ? $params['show_likes_count'] : false;
755 $post['show_comments_count'] = isset($params['show_comments_count']) ? $params['show_comments_count'] : false;
756 $post['popup_follow_button'] = isset($params['popup_follow_button']) ? $params['popup_follow_button'] : true;
757 $post['popup_follow_button_text'] = isset($params['popup_follow_button_text']) ? $params['popup_follow_button_text'] : 'Follow';
758 ?>
759
760 <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); ?>">
761 <?php
762
763 if (!empty($hashtag_id) && $media_type == 'CAROUSEL_ALBUM') {
764 if (isset($post['children']['data'][0]['media_url'])) {
765 $hashtag_media_url = $post['children']['data'][0]['media_url'];
766 $hashtag_media_type = $post['children']['data'][0]['media_type'];
767
768 if ($hashtag_media_type == 'VIDEO') {
769 echo '<video class="insta-gallery-image" src="' . esc_url($hashtag_media_url) . '"></video>';
770 } else {
771 echo ' <img class="insta-gallery-image" src="' . esc_url($hashtag_media_url) . '" alt="' . esc_attr('image') . '">';
772 }
773 }
774 } else {
775 if ($media_type == 'VIDEO') {
776 echo '<video class="insta-gallery-image" src="' . esc_url($media_url) . '"></video>';
777 } else {
778 echo ' <img class="insta-gallery-image" src="' . esc_url($media_url) . '" alt="' . esc_attr('image') . '">';
779 }
780 }
781 ?>
782
783 <div class="insta-gallery-item-type">
784 <div class="insta-gallery-item-type-icon">
785 <?php
786 if ($media_type == 'VIDEO') {
787 echo Helper::get_insta_video_icon();
788 } else if ($media_type == 'CAROUSEL_ALBUM') {
789 echo Helper::get_insta_image_carousel_icon();
790 } else {
791 echo Helper::get_insta_image_icon();
792 }
793 ?>
794 </div>
795 </div>
796 <div class="insta-gallery-item-info">
797 <?php if (strtolower($connected_account_type) === 'business') : ?>
798 <div class="insta-item-reaction-count">
799 <div class="insta-gallery-item-likes">
800 <?php echo Helper::get_insta_like_icon();
801 echo esc_html($like_count); ?>
802 </div>
803 <div class="insta-gallery-item-comments">
804 <?php echo Helper::get_insta_comment_icon();
805 echo esc_html($comments_count); ?>
806 </div>
807 </div>
808 <?php else : ?>
809 <div class="insta-gallery-item-permalink">
810 <?php echo Helper::get_instagram_icon(); ?>
811 </div>
812 <?php endif; ?>
813 </div>
814 </div>
815
816 <?php $post_index++;
817 endforeach;
818 endif;
819
820 $feed_item = ob_get_clean();
821
822 $next_start_index = $start_index + count($next_posts);
823
824 wp_send_json(array(
825 'html' => $feed_item,
826 'next_post_index' => $next_start_index,
827 'total_feed_posts' => count($feed_posts)
828 ));
829 } else {
830 wp_send_json('');
831 }
832 }
833
834 public static function getCalendlyUuid($url)
835 {
836 $pattern = '/\/([0-9a-fA-F-]+)$/';
837 if (preg_match($pattern, $url, $matches)) {
838 $uuid = $matches[1];
839 return $uuid;
840 }
841 return '';
842 }
843
844 public static function getCalendlyUserInfo($access_token)
845 {
846 $transient_name = 'calendly_user_info_' . $access_token;
847 $user_info = get_transient($transient_name);
848 if (false === $user_info) {
849 $user_endpoint = 'https://api.calendly.com/users/me';
850 $headers = array(
851 'Authorization' => "Bearer $access_token",
852 'Content-Type' => 'application/json',
853 );
854 $args = array(
855 'headers' => $headers,
856 );
857 $response = wp_remote_get($user_endpoint, $args);
858 if (!is_wp_error($response) && 200 === wp_remote_retrieve_response_code($response)) {
859 $user_info = wp_remote_retrieve_body($response);
860 set_transient($transient_name, $user_info, 3600);
861 } else {
862 return false;
863 }
864 }
865
866 return $user_info;
867 }
868
869
870
871 public static function getCalaendlyEventTypes($user_uri, $access_token)
872 {
873 // Attempt to retrieve the data from the transient
874 $events_list = get_transient('calendly_events_list_' . md5($access_token));
875
876 if (false === $events_list) {
877 // If the data is not in the transient, fetch it from the API
878 $events_endpoint = "https://api.calendly.com/event_types?user=$user_uri";
879
880 $headers = array(
881 'Authorization' => "Bearer $access_token",
882 'Content-Type' => 'application/json',
883 );
884
885 $args = array(
886 'headers' => $headers,
887 );
888
889 $response = wp_remote_get($events_endpoint, $args);
890
891 if (!is_wp_error($response)) {
892 $body = wp_remote_retrieve_body($response);
893 $events_list = json_decode($body, true);
894
895 // Store the data in a transient for a specified time (e.g., 1 hour)
896 set_transient('calendly_events_list', $events_list, HOUR_IN_SECONDS);
897
898 return $events_list;
899 }
900 }
901
902 return $events_list;
903 }
904
905 public static function getListEventInvitee($uuid, $access_token)
906 {
907 // Attempt to retrieve the data from the transient
908 $invitee_list = get_transient('calendly_invitee_list_' . md5($access_token));
909
910 if (false === $invitee_list) {
911 // If the data is not in the transient, fetch it from the API
912 $events_endpoint = "https://api.calendly.com/scheduled_events/$uuid/invitees";
913
914 $headers = array(
915 'Authorization' => "Bearer $access_token",
916 'Content-Type' => 'application/json',
917 );
918
919 $args = array(
920 'headers' => $headers,
921 );
922
923 $response = wp_remote_get($events_endpoint, $args);
924
925 if (!is_wp_error($response)) {
926 $body = wp_remote_retrieve_body($response);
927 $invitee_list = json_decode($body, true);
928
929 // Store the data in a transient for a specified time (e.g., 1 hour)
930 set_transient('calendly_invitee_list', $invitee_list, HOUR_IN_SECONDS);
931
932 return $invitee_list;
933 }
934 }
935
936 return $invitee_list;
937 }
938
939 public static function getCalaendlyScheduledEvents($user_uri, $access_token)
940 {
941 // Attempt to retrieve the data from the transient
942 $events_list = get_transient('calendly_events_list_' . md5($access_token));
943
944 if (false === $events_list) {
945 // If the data is not in the transient, fetch it from the API
946 $events_endpoint = "https://api.calendly.com/scheduled_events?user=$user_uri";
947
948 $headers = array(
949 'Authorization' => "Bearer $access_token",
950 'Content-Type' => 'application/json',
951 );
952
953 $args = array(
954 'headers' => $headers,
955 );
956
957 $response = wp_remote_get($events_endpoint, $args);
958
959 if (!is_wp_error($response)) {
960 $body = wp_remote_retrieve_body($response);
961 $events_list = json_decode($body, true);
962
963 // Store the data in a transient for a specified time (e.g., 1 hour)
964 set_transient('calendly_events_list', $events_list, HOUR_IN_SECONDS);
965
966 return $events_list;
967 }
968 }
969
970 return $events_list;
971 }
972
973
974 public static function parseDuration($durationString)
975 {
976 list($minutes, $seconds) = explode(':', $durationString);
977 return intval($minutes) * 60 + intval($seconds);
978 }
979
980
981
982
983 public static function is_pro_active()
984 {
985 if (defined('EMBEDPRESS_SL_ITEM_SLUG')) {
986 return true;
987 }
988 return false;
989 }
990
991
992 public static function getInstagramUserInfo($accessToken, $accountType, $userId, $is_sync = false)
993 {
994 if ($is_sync) {
995 // If $is_sync is true, don't use transient
996 $use_transient = false;
997 } else {
998 // If $is_sync is false, use transient
999 $transient_key = 'instagram_user_info_' . $userId;
1000 $use_transient = true;
1001 }
1002
1003 if ($use_transient && false !== ($userInfo = get_transient($transient_key))) {
1004 // If transient exists, return cached user info
1005 return $userInfo;
1006 }
1007
1008 if (strtolower($accountType) === 'business') {
1009 $api_url = 'https://graph.facebook.com/' . $userId . '?fields=biography,id,username,website,followers_count,media_count,profile_picture_url,name&access_token=' . $accessToken;
1010 } else {
1011 $api_url = "https://graph.instagram.com/me?fields=id,username,account_type,media_count,followers_count,biography,website&access_token={$accessToken}";
1012 }
1013
1014 $connected_account_type = $accountType;
1015
1016 $userInfoResponse = wp_remote_get($api_url);
1017
1018 if (is_wp_error($userInfoResponse)) {
1019 echo 'Error: Unable to retrieve Instagram user information.';
1020 } else {
1021 $userInfoBody = wp_remote_retrieve_body($userInfoResponse);
1022 $userInfo = json_decode($userInfoBody, true);
1023
1024 $userInfo['connected_account_type'] = $connected_account_type;
1025 $userInfo['access_token'] = $accessToken;
1026
1027
1028 if (!isset($userInfo['profile_picture_url'])) {
1029 $userInfo['profile_picture_url'] = '';
1030 }
1031
1032 // If not using transient, cache the user info for an hour
1033 if ($use_transient) {
1034 set_transient($transient_key, $userInfo, HOUR_IN_SECONDS);
1035 }
1036
1037 return $userInfo;
1038 }
1039 }
1040
1041
1042 // Get Instagram posts, videos, reels
1043 public static function getInstagramPosts($access_token, $account_type, $userId, $limit = 100, $is_sync = false)
1044 {
1045 if ($is_sync) {
1046 // If $is_sync is true, don't use transient
1047 $use_transient = false;
1048 } else {
1049 // If $is_sync is false, use transient
1050 $transient_key = 'instagram_posts_' . $userId;
1051 $use_transient = true;
1052 }
1053
1054 if ($use_transient && false !== ($posts = get_transient($transient_key))) {
1055 // If transient exists, return cached posts
1056 return $posts;
1057 }
1058
1059 if (strtolower($account_type) === 'business') {
1060 $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;
1061 } else {
1062 $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";
1063 }
1064
1065 $postsResponse = wp_remote_get($api_url);
1066
1067 if (is_wp_error($postsResponse)) {
1068 echo 'Error: Unable to retrieve Instagram posts.';
1069 } else {
1070 $postsBody = wp_remote_retrieve_body($postsResponse);
1071 $posts = json_decode($postsBody, true);
1072
1073 if (empty($posts['data'])) {
1074 return 'Please add Instagram Access Token';
1075 }
1076
1077 // If not using transient, cache the posts for an hour
1078 if ($use_transient) {
1079 set_transient($transient_key, $posts['data'], HOUR_IN_SECONDS);
1080 }
1081
1082 return $posts['data'];
1083 }
1084 }
1085
1086 public static function get_enable_settings_data_for_scripts($settings)
1087 {
1088 $settings_data = [
1089 'enabled_ads' => isset($settings['adManager']) && $settings['adManager'] === 'yes' ? 'yes' : '',
1090
1091 'enabled_custom_player' => isset($settings['emberpress_custom_player']) && $settings['emberpress_custom_player'] === 'yes' ? 'yes' : '',
1092
1093 'enabled_instafeed' => isset($settings['embedpress_pro_embeded_source']) && $settings['embedpress_pro_embeded_source'] === 'instafeed' ? 'yes' : '',
1094
1095 'enabled_docs_custom_viewer' => isset($settings['embedpress_document_viewer']) && $settings['embedpress_document_viewer'] === 'custom' ? 'yes' : '',
1096 ];
1097
1098 update_option('enabled_elementor_scripts', $settings_data);
1099 }
1100
1101 public static function get_options_value($key)
1102 {
1103 $g_settings = get_option(EMBEDPRESS_PLG_NAME);
1104
1105 if (isset($g_settings[$key])) {
1106 return $g_settings[$key];
1107 }
1108 return '';
1109 }
1110 public static function get_branding_value($key, $provider)
1111 {
1112 $settings = get_option(EMBEDPRESS_PLG_NAME . ':' . $provider, []);
1113
1114 if (isset($settings['branding']) && $settings['branding'] === 'yes' && isset($settings[$key])) {
1115 return $settings[$key];
1116 }
1117 return '';
1118 }
1119
1120
1121 public static function format_number($number)
1122 {
1123 if ($number >= 1000000000) {
1124 return number_format($number / 1000000000, 1) . 'b';
1125 } elseif ($number >= 1000000) {
1126 return number_format($number / 1000000, 1) . 'm';
1127 } elseif ($number >= 1000) {
1128 return number_format($number / 1000, 1) . 'k';
1129 } else {
1130 return $number;
1131 }
1132 }
1133
1134 public static function get_id($item)
1135 {
1136 $vid = isset($item->snippet->resourceId->videoId) ? $item->snippet->resourceId->videoId : null;
1137 $vid = $vid ? $vid : (isset($item->id->videoId) ? $item->id->videoId : null);
1138 $vid = $vid ? $vid : (isset($item->id) ? $item->id : null);
1139 return $vid;
1140 }
1141
1142 public static function clean_api_error($raw_message)
1143 {
1144 return htmlspecialchars(strip_tags(preg_replace('@&key=[^& ]+@i', '&key=*******', $raw_message)));
1145 }
1146
1147 public static function clean_api_error_html($raw_message)
1148 {
1149 $clean_html = '';
1150 if ((defined('REST_REQUEST') && REST_REQUEST) || current_user_can('manage_options')) {
1151 $clean_html = '<div>' . __('EmbedPress: ', 'embedpress') . self::clean_api_error($raw_message) . '</div>';
1152 }
1153 return $clean_html;
1154 }
1155
1156 public static function get_thumbnail_url($item, $quality, $privacyStatus)
1157 {
1158 $url = "";
1159 if ($privacyStatus == 'private') {
1160 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/private.png';
1161 } elseif (isset($item->snippet->thumbnails->{$quality}->url)) {
1162 $url = $item->snippet->thumbnails->{$quality}->url;
1163 } elseif (isset($item->snippet->thumbnails->medium->url)) {
1164 $url = $item->snippet->thumbnails->medium->url;
1165 } elseif (isset($item->snippet->thumbnails->default->url)) {
1166 $url = $item->snippet->thumbnails->default->url;
1167 } elseif (isset($item->snippet->thumbnails->high->url)) {
1168 $url = $item->snippet->thumbnails->high->url;
1169 } else {
1170 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/deleted-video-thumb.png';
1171 }
1172 return $url;
1173 }
1174
1175 public static function compare_vid_date($a, $b)
1176 {
1177 $dateA = strtotime($a->snippet->publishedAt);
1178 $dateB = strtotime($b->snippet->publishedAt);
1179
1180 // Sort in descending order (newest first)
1181 return $dateB - $dateA;
1182 }
1183
1184
1185 public static function get_youtube_video_data($api_key, $video_id)
1186 {
1187 // Set a unique transient name based on the video ID
1188 $transient_name = 'youtube_video_data_' . $video_id;
1189
1190 // Try to get data from the transient cache
1191 $video_data = get_transient($transient_name);
1192
1193 // If no cached data, fetch from the API
1194 if ($video_data === false) {
1195 // YouTube Data API URL
1196 $url = "https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id={$video_id}&key={$api_key}";
1197
1198 // Fetch the data from the API
1199 $response = wp_remote_get($url);
1200
1201 if (is_wp_error($response)) {
1202 return false; // Return false if there is an error
1203 }
1204
1205 $body = wp_remote_retrieve_body($response);
1206 $video_data = json_decode($body, true);
1207
1208 if (isset($video_data['items'][0])) {
1209 $video_data = $video_data['items'][0];
1210
1211 // Cache the data in a transient for 12 hours
1212 set_transient($transient_name, $video_data, 24 * HOUR_IN_SECONDS);
1213 } else {
1214 return false; // Return false if no data found
1215 }
1216 }
1217
1218 return $video_data;
1219 }
1220
1221 public static function trimTitle($title, $wordCount)
1222 {
1223 $words = explode(' ', $title);
1224
1225 if (count($words) <= $wordCount) {
1226 return $title; // No trimming needed
1227 }
1228
1229 $trimmedWords = array_slice($words, 0, $wordCount);
1230
1231 return implode(' ', $trimmedWords) . ' ...';
1232 }
1233
1234 public static function timeAgo($datetime)
1235 {
1236 $now = new \DateTime();
1237 $date = new \DateTime($datetime);
1238 $interval = $now->diff($date);
1239
1240 if ($interval->y > 0) {
1241 return $interval->y . ' year' . ($interval->y > 1 ? 's' : '') . ' ago';
1242 } elseif ($interval->m > 0) {
1243 return $interval->m . ' month' . ($interval->m > 1 ? 's' : '') . ' ago';
1244 } elseif ($interval->d > 0) {
1245 return $interval->d . ' day' . ($interval->d > 1 ? 's' : '') . ' ago';
1246 } elseif ($interval->h > 0) {
1247 return $interval->h . ' hour' . ($interval->h > 1 ? 's' : '') . ' ago';
1248 } elseif ($interval->i > 0) {
1249 return $interval->i . ' minute' . ($interval->i > 1 ? 's' : '') . ' ago';
1250 } else {
1251 return 'just now';
1252 }
1253 }
1254
1255 public static function removeQuote($attributes)
1256 {
1257 $parsedAttributes = [];
1258
1259 $regex = '/^on.*/i';
1260
1261 foreach ($attributes as $key => $value) {
1262 if (is_string($value)) {
1263 $cleanValue = str_replace(['"', "'"], '', $value);
1264 } else {
1265 $cleanValue = $value;
1266 }
1267
1268 if (!preg_match($regex, $key)) {
1269 $parsedAttributes[$key] = $cleanValue;
1270 }
1271 }
1272
1273 return $parsedAttributes;
1274 }
1275 }
1276