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