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