PluginProbe ʕ •ᴥ•ʔ
Essential Addons for Elementor – Popular Elementor Templates & Widgets / 6.6.9
Essential Addons for Elementor – Popular Elementor Templates & Widgets v6.6.9
6.6.9 6.6.8 6.6.7 6.6.6 6.6.5 6.6.4 6.6.3 5.7.3 5.7.4 5.8.0 5.8.1 5.8.10 5.8.11 5.8.12 5.8.13 5.8.14 5.8.15 5.8.16 5.8.18 5.8.2 5.8.3 5.8.4 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.10 5.9.11 5.9.12 5.9.13 5.9.14 5.9.15 5.9.16 5.9.17 5.9.18 5.9.19 5.9.2 5.9.20 5.9.21 5.9.22 5.9.23 5.9.24 5.9.25 5.9.26 5.9.27 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 6.0.1 6.0.10 6.0.11 6.0.12 6.0.13 6.0.14 6.0.15 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.0.8 6.0.9 6.1.0 6.1.1 6.1.10 6.1.11 trunk 6.1.12 1.0.0 6.1.13 1.0.1 6.1.14 1.1.0 6.1.15 2.0 6.1.17 2.1 6.1.18 2.10.0 6.1.19 2.10.1 6.1.2 2.10.2 6.1.20 2.10.3 6.1.3 2.10.4 6.1.4 2.10.5 6.1.5 2.2.0 6.1.6 2.2.1 6.1.7 2.2.2 6.1.8 2.2.3 6.1.9 2.2.4 6.2.0 2.2.5 6.2.1 2.3.0 6.2.2 2.3.1 6.2.3 2.4.0 6.2.4 2.4.1 6.3.0 2.4.2 6.3.1 2.4.3 6.3.2 2.5.0 6.3.3 2.6.0 6.4.0 2.7.0 6.5.0 2.7.1 6.5.1 2.7.10 6.5.10 2.7.11 6.5.11 2.7.2 6.5.12 2.7.3 6.5.13 2.7.4 6.5.2 2.7.5 6.5.3 2.7.6 6.5.4 2.7.7 6.5.5 2.7.8 6.5.6 2.7.9 6.5.7 2.8.0 6.5.8 2.8.1 6.5.9 2.8.2 6.6.0 2.8.3 6.6.1 2.8.4 6.6.2 2.8.5 2.8.6 2.8.7 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.4.1 3.1.5 3.2.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.5.0 3.5.1 3.5.2 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 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.2 3.9.3 3.9.4 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.8 4.3.9 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.6.6 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.7.5 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 5.0.0 5.0.1 5.0.10 5.0.11 5.0.12 5.0.13 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.2.0 5.2.1 5.2.2 5.2.3 5.2.4 5.3.0 5.3.1 5.3.2 5.4.6 5.5.5 5.6.5 5.7.2
essential-addons-for-elementor-lite / includes / Classes / Helper.php
essential-addons-for-elementor-lite / includes / Classes Last commit date
AllTraits.php 1 year ago Asset_Builder.php 9 months ago Bootstrap.php 2 weeks ago Compatibility_Support.php 2 months ago Elements_Manager.php 7 months ago Helper.php 1 month ago Migration.php 5 months ago Plugin_Usage_Tracker.php 5 months ago WPDeveloper_Core_Installer.php 5 months ago WPDeveloper_Notice.php 2 months ago WPDeveloper_Plugin_Installer.php 5 months ago WPDeveloper_Setup_Wizard.php 2 months ago index.php 3 years ago
Helper.php
2089 lines
1 <?php
2
3 namespace Essential_Addons_Elementor\Classes;
4
5 use Elementor\Utils;
6
7 if (!defined('ABSPATH')) {
8 exit;
9 } // Exit if accessed directly
10
11 use \Elementor\Controls_Manager;
12 use Elementor\Icons_Manager;
13 use Elementor\Plugin;
14
15 class Helper
16 {
17
18
19 const EAEL_ALLOWED_HTML_TAGS = [
20 'article',
21 'aside',
22 'details',
23 'dialog',
24 'div',
25 'figcaption',
26 'figure',
27 'footer',
28 'h1',
29 'h2',
30 'h3',
31 'h4',
32 'h5',
33 'h6',
34 'header',
35 'hgroup',
36 'main',
37 'nav',
38 'p',
39 'section',
40 'span',
41 'summary',
42 ];
43
44 /**
45 * It stores all faqs data for all ea elements
46 * @since 5.1.9
47 */
48 public static $eael_advanced_accordion_faq = [];
49
50 /**
51 * Returns all the faqs in one instance
52 *
53 * @since 5.1.9
54 * @return array
55 */
56 public static function get_eael_advanced_accordion_faq(){
57 $json = [];
58 if( count( self::$eael_advanced_accordion_faq ) ) {
59 $json = [
60 '@context' => 'https://schema.org',
61 '@type' => 'FAQPage',
62 'mainEntity' => self::$eael_advanced_accordion_faq,
63 ];
64 }
65
66 return $json;
67 }
68
69 /**
70 * Adds faq to the faq list
71 * @since 5.1.9
72 * @param array $faq single faq data - question and answer
73 */
74 public static function set_eael_advanced_accordion_faq( $faq ){
75 return self::$eael_advanced_accordion_faq[] = $faq;
76 }
77
78 /**
79 * Include a file with variables
80 *
81 * @param $file_path
82 * @param $variables
83 *
84 * @return string
85 * @since 4.2.2
86 */
87 public static function include_with_variable( $file_path, $variables = [])
88 {
89 if (file_exists($file_path)) {
90 extract($variables);
91
92 ob_start();
93
94 include $file_path;
95
96 return ob_get_clean();
97 }
98
99 return '';
100 }
101
102 /**
103 * check EAEL extension can load this page or post
104 *
105 * @param $id page or post id
106 *
107 * @return bool
108 * @since 4.0.4
109 */
110 public static function prevent_extension_loading($post_id)
111 {
112 $template_name = get_post_meta($post_id, '_elementor_template_type', true);
113 $template_list = [
114 'header',
115 'footer',
116 'single',
117 'post',
118 'page',
119 // 'archive',
120 'search-results',
121 'error-404',
122 // 'product',
123 // 'product-archive',
124 'section',
125 ];
126
127 return in_array($template_name, $template_list);
128 }
129
130 public static function str_to_css_id( $str ) {
131 $str = strtolower( $str );
132
133 //Make alphanumeric (removes all other characters)
134 $str = preg_replace( "/[^a-z0-9_\s-]/", "", $str );
135
136 //Clean up multiple dashes or whitespaces
137 $str = preg_replace( "/[\s-]+/", " ", $str );
138
139 //Convert whitespaces and underscore to dash
140 $str = preg_replace( "/[\s_]/", "-", $str );
141
142 return $str;
143 }
144
145 public static function fix_old_query($settings)
146 {
147 $update_query = false;
148
149 foreach ($settings as $key => $value) {
150 if (strpos($key, 'eaeposts_') !== false) {
151 $settings[str_replace('eaeposts_', '', $key)] = $value;
152 $update_query = true;
153 }
154 }
155
156 if ($update_query) {
157 global $wpdb;
158
159 $post_id = get_the_ID();
160 $data = get_post_meta($post_id, '_elementor_data', true);
161 $data = str_replace('eaeposts_', '', $data);
162
163 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
164 $wpdb->update(
165 $wpdb->postmeta,
166 [
167 'meta_value' => $data,
168 ],
169 [
170 'post_id' => $post_id,
171 'meta_key' => '_elementor_data',
172 ]
173 );
174 }
175
176 return $settings;
177 }
178
179 public static function get_query_args($settings = [], $post_type = 'post')
180 {
181 $settings = wp_parse_args( $settings, [
182 'post_type' => $post_type,
183 'posts_ids' => [],
184 'orderby' => 'date',
185 'order' => 'desc',
186 'posts_per_page' => 3,
187 'offset' => 0,
188 'post__not_in' => [],
189 ] );
190
191 $args = [
192 'orderby' => $settings['orderby'],
193 'order' => $settings['order'],
194 'ignore_sticky_posts' => 1,
195 'post_status' => 'publish',
196 'posts_per_page' => $settings['posts_per_page'],
197 'offset' => $settings['offset'],
198 ];
199
200 if ( 'by_id' === $settings['post_type'] ) {
201 $args['post_type'] = 'any';
202 $args['post__in'] = empty( $settings['posts_ids'] ) ? [ 0 ] : $settings['posts_ids'];
203 } else {
204 $args['post_type'] = $settings['post_type'];
205 $args['tax_query'] = [];
206
207 $taxonomies = get_object_taxonomies( $settings['post_type'], 'objects' );
208
209 foreach ( $taxonomies as $object ) {
210 $setting_key = $object->name . '_ids';
211
212 if ( ! empty( $settings[ $setting_key ] ) ) {
213 $args['tax_query'][] = [
214 'taxonomy' => $object->name,
215 'field' => 'term_id',
216 'terms' => $settings[ $setting_key ],
217 ];
218 }
219 }
220
221 if ( ! empty( $args['tax_query'] ) ) {
222 $args['tax_query']['relation'] = isset( $settings['tax_query_relation'] ) ? $settings['tax_query_relation'] : 'AND';
223 }
224 }
225
226 if ( $args['orderby'] === 'most_viewed' ) {
227 $args['orderby'] = 'meta_value_num';
228 $args['meta_key'] = '_eael_post_view_count';
229 }
230
231 // Handle custom field sorting
232 if ( $args['orderby'] === 'meta_value' && ! empty( $settings['meta_key'] ) ) {
233 $args['meta_key'] = sanitize_text_field( $settings['meta_key'] );
234
235 // Set the appropriate orderby based on meta_type
236 $meta_type = ! empty( $settings['meta_type'] ) ? $settings['meta_type'] : 'CHAR';
237
238 switch ( $meta_type ) {
239 case 'NUMERIC':
240 $args['orderby'] = 'meta_value_num';
241 break;
242 case 'DATE':
243 case 'DATETIME':
244 $args['orderby'] = 'meta_value';
245 $args['meta_type'] = $meta_type;
246 break;
247 case 'CHAR':
248 default:
249 $args['orderby'] = 'meta_value';
250 $args['meta_type'] = 'CHAR';
251 break;
252 }
253 }
254
255 if ( ! empty( $settings['posts_by_current_user'] ) && 'yes' === $settings['posts_by_current_user'] ) {
256 $args['author__in'] = [ get_current_user_id() ];
257 } elseif ( ! empty( $settings['authors'] ) ) {
258 $args['author__in'] = $settings['authors'];
259 }
260
261 if ( ! empty( $settings['post__not_in'] ) ) {
262 $args['post__not_in'] = $settings['post__not_in'];
263 }
264
265 if( 'product' === $post_type && function_exists('whols_lite') ){
266 $args['meta_query'] = array_filter( apply_filters( 'woocommerce_product_query_meta_query', $args['meta_query'], new \WC_Query() ) );
267 }
268
269 return $args;
270 }
271
272 /**
273 * Go Premium
274 *
275 */
276 public static function go_premium($wb)
277 {
278 $wb->start_controls_section(
279 'eael_section_pro',
280 [
281 'label' => __('Go Premium for More Features', 'essential-addons-for-elementor-lite'),
282 ]
283 );
284
285 $wb->add_control(
286 'eael_control_get_pro',
287 [
288 'label' => __('Unlock more possibilities', 'essential-addons-for-elementor-lite'),
289 'type' => Controls_Manager::CHOOSE,
290 'options' => [
291 '1' => [
292 'title' => '',
293 'icon' => 'fa fa-unlock-alt',
294 ],
295 ],
296 'default' => '1',
297 'description' => '<span class="pro-feature"> Get the <a href="https://wpdeveloper.com/upgrade/ea-pro" target="_blank">Pro version</a> for more stunning elements and customization options.</span>',
298 ]
299 );
300
301 $wb->end_controls_section();
302 }
303
304 /**
305 * Get All POst Types
306 * @return array
307 */
308 public static function get_post_types()
309 {
310 $post_types = get_post_types(['public' => true, 'show_in_nav_menus' => true], 'objects');
311 $post_types = wp_list_pluck($post_types, 'label', 'name');
312
313 return array_diff_key($post_types, ['elementor_library', 'attachment']);
314 }
315
316
317 /**
318 * Get All POst Types
319 * @todo should be removed on future version
320 * @return array
321 */
322 public static function get_allowed_post_types()
323 {
324 return self::get_post_types();
325 }
326
327 /**
328 * Get all types of post.
329 *
330 * @param string $post_type
331 *
332 * @return array
333 */
334 public static function get_post_list($post_type = 'any')
335 {
336 return self::get_query_post_list($post_type);
337 }
338
339 /**
340 * POst Orderby Options
341 *
342 * @return array
343 */
344 public static function get_post_orderby_options()
345 {
346 $orderby = array(
347 'ID' => __( 'Post ID', 'essential-addons-for-elementor-lite' ),
348 'author' => __( 'Post Author', 'essential-addons-for-elementor-lite' ),
349 'title' => __( 'Title', 'essential-addons-for-elementor-lite' ),
350 'date' => __( 'Date', 'essential-addons-for-elementor-lite' ),
351 'modified' => __( 'Last Modified Date', 'essential-addons-for-elementor-lite' ),
352 'parent' => __( 'Parent Id', 'essential-addons-for-elementor-lite' ),
353 'rand' => __( 'Random', 'essential-addons-for-elementor-lite' ),
354 'comment_count' => __( 'Comment Count', 'essential-addons-for-elementor-lite' ),
355 'most_viewed' => __( 'Most Viewed', 'essential-addons-for-elementor-lite' ),
356 'menu_order' => __( 'Menu Order', 'essential-addons-for-elementor-lite' ),
357 'meta_value' => __( 'Custom Field', 'essential-addons-for-elementor-lite' )
358 );
359
360 return $orderby;
361 }
362
363 /**
364 * Get Post Categories
365 *
366 * @return array
367 */
368 public static function get_terms_list($taxonomy = 'category', $key = 'term_id')
369 {
370 $options = [];
371 $terms = get_terms([
372 'taxonomy' => $taxonomy,
373 'hide_empty' => true,
374 ]);
375
376 if (!empty($terms) && !is_wp_error($terms)) {
377 foreach ($terms as $term) {
378 $options[$term->{$key}] = $term->name;
379 }
380 }
381
382 return $options;
383 }
384
385 /**
386 * Get all elementor page templates
387 *
388 * @param null $type
389 *
390 * @return array
391 */
392 public static function get_elementor_templates($type = null)
393 {
394 $options = [];
395
396 if ($type) {
397 $args = [
398 'post_type' => 'elementor_library',
399 'posts_per_page' => -1,
400 ];
401 $args['tax_query'] = [
402 [
403 'taxonomy' => 'elementor_library_type',
404 'field' => 'slug',
405 'terms' => $type,
406 ],
407 ];
408
409 $page_templates = get_posts($args);
410
411 if (!empty($page_templates) && !is_wp_error($page_templates)) {
412 foreach ($page_templates as $post) {
413 $options[$post->ID] = $post->post_title;
414 }
415 }
416 } else {
417 $options = self::get_query_post_list('elementor_library');
418 }
419
420 return $options;
421 }
422
423 /**
424 * Get all Authors
425 *
426 * @return array
427 */
428 public static function get_authors_list() {
429 $args = [
430 'capability' => [ 'edit_posts' ],
431 'has_published_posts' => true,
432 'fields' => [
433 'ID',
434 'display_name',
435 ],
436 ];
437
438 // Capability queries were only introduced in WP 5.9.
439 if ( version_compare( $GLOBALS['wp_version'], '5.9-alpha', '<' ) ) {
440 $args['who'] = 'authors';
441 unset( $args['capability'] );
442 }
443
444 $users = get_users( $args );
445
446 if ( ! empty( $users ) ) {
447 return wp_list_pluck( $users, 'display_name', 'ID' );
448 }
449
450 return [];
451 }
452
453 /**
454 * Get all Tags
455 *
456 * @param array $args
457 *
458 * @return array
459 */
460 public static function get_tags_list($args = array())
461 {
462 $options = [];
463 $tags = get_tags($args);
464
465 if (!is_wp_error($tags) && !empty($tags)) {
466 foreach ($tags as $tag) {
467 $options[$tag->term_id] = $tag->name;
468 }
469 }
470
471 return $options;
472 }
473
474 /**
475 * Get all taxonomies by post
476 *
477 * @param array $args
478 *
479 * @param string $output
480 * @param string $operator
481 *
482 * @return array
483 */
484 public static function get_taxonomies_by_post($args = [], $output = 'names', $operator = 'and')
485 {
486 global $wp_taxonomies;
487
488 $field = ('names' === $output) ? 'name' : false;
489
490 // Handle 'object_type' separately.
491 if (isset($args['object_type'])) {
492 $object_type = (array) $args['object_type'];
493 unset($args['object_type']);
494 }
495
496 $taxonomies = wp_filter_object_list($wp_taxonomies, $args, $operator);
497
498 if (isset($object_type)) {
499 foreach ($taxonomies as $tax => $tax_data) {
500 if (!array_intersect($object_type, $tax_data->object_type)) {
501 unset($taxonomies[$tax]);
502 }
503 }
504 }
505
506 if ($field) {
507 $taxonomies = wp_list_pluck($taxonomies, $field);
508 }
509
510 return $taxonomies;
511 }
512
513 /**
514 * Get Contact Form 7 [ if exists ]
515 */
516 public static function get_wpcf7_list()
517 {
518 $options = array();
519
520 if (function_exists('wpcf7')) {
521 $wpcf7_form_list = get_posts(array(
522 'post_type' => 'wpcf7_contact_form',
523 'showposts' => 999,
524 ));
525 $options[0] = esc_html__('Select a Contact Form', 'essential-addons-for-elementor-lite');
526 if (!empty($wpcf7_form_list) && !is_wp_error($wpcf7_form_list)) {
527 foreach ($wpcf7_form_list as $post) {
528 $options[$post->ID] = $post->post_title;
529 }
530 } else {
531 $options[0] = esc_html__('Create a Form First', 'essential-addons-for-elementor-lite');
532 }
533 }
534 return $options;
535 }
536
537 /**
538 * Get Gravity Form [ if exists ]
539 *
540 * @return array
541 */
542 public static function get_gravity_form_list()
543 {
544 $options = array();
545
546 if (class_exists('GFCommon')) {
547 $gravity_forms = \RGFormsModel::get_forms(null, 'title');
548
549 if (!empty($gravity_forms) && !is_wp_error($gravity_forms)) {
550
551 $options[0] = esc_html__('Select Gravity Form', 'essential-addons-for-elementor-lite');
552 foreach ($gravity_forms as $form) {
553 $options[$form->id] = $form->title;
554 }
555
556 } else {
557 $options[0] = esc_html__('Create a Form First', 'essential-addons-for-elementor-lite');
558 }
559 }
560
561 return $options;
562 }
563
564 /**
565 * Get WeForms Form List
566 *
567 * @return array
568 */
569 public static function get_weform_list()
570 {
571 $wpuf_form_list = get_posts(array(
572 'post_type' => 'wpuf_contact_form',
573 'showposts' => 999,
574 ));
575
576 $options = array();
577
578 if (!empty($wpuf_form_list) && !is_wp_error($wpuf_form_list)) {
579 $options[0] = esc_html__('Select weForm', 'essential-addons-for-elementor-lite');
580 foreach ($wpuf_form_list as $post) {
581 $options[$post->ID] = $post->post_title;
582 }
583 } else {
584 $options[0] = esc_html__('Create a Form First', 'essential-addons-for-elementor-lite');
585 }
586
587 return $options;
588 }
589
590 /**
591 * Get Ninja Form List
592 *
593 * @return array
594 */
595 public static function get_ninja_form_list()
596 {
597 $options = array();
598
599 if (class_exists('Ninja_Forms')) {
600 $contact_forms = Ninja_Forms()->form()->get_forms();
601
602 if (!empty($contact_forms) && !is_wp_error($contact_forms)) {
603
604 $options[0] = esc_html__('Select Ninja Form', 'essential-addons-for-elementor-lite');
605
606 foreach ($contact_forms as $form) {
607 $options[$form->get_id()] = $form->get_setting('title');
608 }
609 }
610 } else {
611 $options[0] = esc_html__('Create a Form First', 'essential-addons-for-elementor-lite');
612 }
613
614 return $options;
615 }
616
617 /**
618 * Get Caldera Form List
619 *
620 * @return array
621 */
622 public static function get_caldera_form_list()
623 {
624 $options = array();
625
626 if (class_exists('Caldera_Forms')) {
627 $contact_forms = \Caldera_Forms_Forms::get_forms(true, true);
628
629 if (!empty($contact_forms) && !is_wp_error($contact_forms)) {
630 $options[0] = esc_html__('Select Caldera Form', 'essential-addons-for-elementor-lite');
631 foreach ($contact_forms as $form) {
632 $options[$form['ID']] = $form['name'];
633 }
634 }
635 } else {
636 $options[0] = esc_html__('Create a Form First', 'essential-addons-for-elementor-lite');
637 }
638
639 return $options;
640 }
641
642 /**
643 * Get WPForms List
644 *
645 * @return array
646 */
647 public static function get_wpforms_list()
648 {
649 $options = array();
650
651 if (class_exists('\WPForms\WPForms')) {
652 $args = array(
653 'post_type' => 'wpforms',
654 'posts_per_page' => -1,
655 );
656
657 $contact_forms = get_posts($args);
658
659 if (!empty($contact_forms) && !is_wp_error($contact_forms)) {
660 $options[0] = esc_html__('Select a WPForm', 'essential-addons-for-elementor-lite');
661 foreach ($contact_forms as $post) {
662 $options[$post->ID] = $post->post_title;
663 }
664 }
665 } else {
666 $options[0] = esc_html__('Create a Form First', 'essential-addons-for-elementor-lite');
667 }
668
669 return $options;
670 }
671
672
673
674 public static function get_ninja_tables_list()
675 {
676 $tables = get_posts([
677 'post_type' => 'ninja-table',
678 'post_status' => 'publish',
679 'posts_per_page' => '-1',
680 ]);
681
682 if (!empty($tables)) {
683 return wp_list_pluck($tables, 'post_title', 'ID');
684 }
685
686 return [];
687 }
688
689 public static function get_terms_as_list($term_type = 'category', $length = 1)
690 {
691 $terms = get_the_terms( get_the_ID(), $term_type );
692
693 if ($term_type === 'category') {
694 $terms = get_the_category();
695 }
696
697 if ($term_type === 'tags') {
698 $terms = get_the_tags();
699 }
700
701 if (empty($terms)) {
702 return;
703 }
704
705 $count = 0;
706
707 $html = '<ul class="post-carousel-categories">';
708 foreach ($terms as $term) {
709 if ( $count === absint( $length ) ) {
710 break;
711 }
712 $link = ($term_type === 'category') ? get_category_link($term->term_id) : get_tag_link($term->term_id);
713 $html .= '<li>';
714 $html .= '<a href="' . esc_url($link) . '">';
715 $html .= esc_html( $term->name );
716 $html .= '</a>';
717 $html .= '</li>';
718 $count++;
719 }
720 $html .= '</ul>';
721
722 return $html;
723
724 }
725
726 /**
727 * Returns product categories list
728 *
729 * @return string
730 */
731 public static function get_product_categories_list($terms_name) {
732 global $product;
733
734 if ( ! is_a( $product, 'WC_Product' ) ) {
735 return '';
736 }
737
738 $separator = '';
739 $before = '<ul class="eael-product-cats"><li>';
740 $after = '</li></ul>';
741
742 return get_the_term_list( $product->get_id(), $terms_name, $before, $separator, $after );
743 }
744
745 /**
746 * This function is responsible for counting doc post under a category.
747 *
748 * @param int $term_count
749 * @param int $term_id
750 * @return int $term_count;
751 */
752 public static function get_doc_post_count($term_count = 0, $term_id = 0)
753 {
754 $tax_terms = get_terms([
755 'taxonomy' => 'doc_category',
756 'child_of' => $term_id
757 ]);
758
759 foreach ($tax_terms as $tax_term) {
760 $term_count += $tax_term->count;
761 }
762
763 return $term_count;
764 }
765
766 public static function get_dynamic_args(array $settings, array $args)
767 {
768 if ( $settings['post_type'] === 'source_dynamic' && ( is_archive() || is_search() ) ) {
769 $data = get_queried_object();
770
771 if (isset($data->post_type)) {
772 $args['post_type'] = $data->post_type;
773 $args['tax_query'] = [];
774 } else {
775 global $wp_query;
776 $args['post_type'] = $wp_query->query_vars['post_type'];
777 if(!empty($wp_query->query_vars['s'])){
778 $args['s'] = $wp_query->query_vars['s'];
779 $args['offset'] = 0;
780 }
781 }
782
783 if ( isset( $data->taxonomy ) ) {
784 $args[ 'tax_query' ][] = [
785 'taxonomy' => $data->taxonomy,
786 'field' => 'term_id',
787 'terms' => $data->term_id,
788 ];
789 }
790
791 if (get_query_var('author') > 0) {
792 $args['author__in'] = get_query_var('author');
793 }
794
795 if (get_query_var('s')!='') {
796 $args['s'] = get_query_var('s');
797 }
798
799 if (get_query_var('year') || get_query_var('monthnum') || get_query_var('day')) {
800 $args['date_query'] = [
801 'year' => get_query_var('year'),
802 'month' => get_query_var('monthnum'),
803 'day' => get_query_var('day'),
804 ];
805 }
806
807 if (!empty($args['tax_query'])) {
808 $args['tax_query']['relation'] = 'AND';
809 }
810
811 $args[ 'meta_query' ] = [ 'relation' => 'AND' ];
812 $show_stock_out_products = isset( $settings['eael_product_out_of_stock_show'] ) ? $settings['eael_product_out_of_stock_show'] : 'yes';
813
814 if ( get_option( 'woocommerce_hide_out_of_stock_items' ) == 'yes' || 'yes' !== $show_stock_out_products ) {
815 $args[ 'meta_query' ][] = [
816 'key' => '_stock_status',
817 'value' => 'instock'
818 ];
819 }
820 if( 'product' === $args['post_type'] && function_exists('whols_lite') ){
821 $args['meta_query'] = array_filter( apply_filters( 'woocommerce_product_query_meta_query', $args['meta_query'], new \WC_Query() ) );
822 }
823 }
824
825 return $args;
826 }
827
828 public static function get_multiple_kb_terms($prettify = false, $term_id = true)
829 {
830 $args = [
831 'taxonomy' => 'knowledge_base',
832 'hide_empty' => true,
833 'parent' => 0,
834 ];
835
836 $terms = get_terms($args);
837
838 if (is_wp_error($terms)) {
839 return [];
840 }
841
842 if ($prettify) {
843 $pretty_taxonomies = [];
844
845 foreach ($terms as $term) {
846 $pretty_taxonomies[$term_id ? $term->term_id : $term->slug] = $term->name;
847 }
848
849 return $pretty_taxonomies;
850 }
851
852 return $terms;
853 }
854
855 public static function get_betterdocs_multiple_kb_status()
856 {
857 if (\BetterDocs_DB::get_settings('multiple_kb') == 1) {
858 return 'true';
859 }
860
861 return '';
862 }
863
864 public static function get_query_post_list($post_type = 'any', $limit = -1, $search = '')
865 {
866 global $wpdb;
867 $where = '';
868 $data = [];
869
870 if (-1 == $limit) {
871 $limit = '';
872 } elseif (0 == $limit) {
873 $limit = "limit 0,1";
874 } else {
875 $limit = $wpdb->prepare(" limit 0,%d", esc_sql($limit));
876 }
877
878 if ('any' === $post_type) {
879 $in_search_post_types = get_post_types(['exclude_from_search' => false]);
880 if (empty($in_search_post_types)) {
881 $where .= ' AND 1=0 ';
882 } else {
883 $where .= " AND {$wpdb->posts}.post_type IN ('" . join("', '",
884 array_map('esc_sql', $in_search_post_types)) . "')";
885 }
886 } elseif (!empty($post_type)) {
887 $where .= $wpdb->prepare(" AND {$wpdb->posts}.post_type = %s", esc_sql($post_type));
888 }
889
890 if (!empty($search)) {
891 $where .= $wpdb->prepare(" AND {$wpdb->posts}.post_title LIKE %s", '%' . esc_sql($search) . '%');
892 }
893
894 $query = "select post_title,ID from $wpdb->posts where post_status = 'publish' $where $limit";
895
896 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
897 $results = $wpdb->get_results($query);
898 if (!empty($results)) {
899 foreach ($results as $row) {
900 $data[$row->ID] = $row->post_title;
901 }
902 }
903 return $data;
904 }
905
906 public static function eael_get_widget_settings( $page_id, $widget_id ) {
907 $document = Plugin::$instance->documents->get( $page_id );
908 $settings = [];
909 if ( $document ) {
910 $elements = Plugin::instance()->documents->get( $page_id )->get_elements_data();
911 $widget_data = self::find_element_recursive( $elements, $widget_id );
912 if (!empty($widget_data) && is_array($widget_data)) {
913 $widget = Plugin::instance()->elements_manager->create_element_instance( $widget_data );
914 }
915 if ( !empty($widget) ) {
916 $settings = $widget->get_settings_for_display();
917 }
918 }
919 return $settings;
920 }
921
922 /**
923 * Get Widget data.
924 *
925 * @param array $elements Element array.
926 * @param string $form_id Element ID.
927 *
928 * @return bool|array
929 */
930 public static function find_element_recursive( $elements, $form_id ) {
931
932 foreach ( $elements as $element ) {
933 if ( $form_id === $element['id'] ) {
934 return $element;
935 }
936
937 if ( ! empty( $element['elements'] ) ) {
938 $element = self::find_element_recursive( $element['elements'], $form_id );
939
940 if ( $element ) {
941 return $element;
942 }
943 }
944 }
945
946 return false;
947 }
948
949 /**
950 * eael_pagination
951 * Generate post pagination
952 *
953 * @param $args array wp_query param
954 * @param $settings array Elementor widget setting data
955 *
956 * @access public
957 * @return string|void
958 * @since 3.3.0
959 */
960 public static function eael_pagination ($args, $settings) {
961
962 $pagination_Count = intval( $args['total_post'] ?? 0 );
963 $paginationLimit = intval( $settings['eael_product_grid_products_count'] ) ?: 4;
964 $pagination_Paginationlist = ceil( $pagination_Count / $paginationLimit );
965 $widget_id = sanitize_key( $settings['eael_widget_id'] );
966 $page_id = intval( $settings['eael_page_id'] );
967 $next_label = $settings['pagination_next_label'];
968 $adjacents = "2";
969 $setPagination = "";
970 $template_info = [
971 'dir' => 'free',
972 'file_name' => 'default',
973 'name' => $settings['eael_widget_name']
974 ];
975
976 if ( ! empty( $settings['eael_dynamic_template_Layout'] ) ) {
977 $template_info['file_name'] = $settings['eael_dynamic_template_Layout'];
978 } else if ( ! empty( $settings['eael_product_grid_template'] ) ) {
979 $template_info['file_name'] = $settings['eael_product_grid_template'];
980 }
981
982 if( $pagination_Paginationlist > 0 ){
983
984 $setPagination .="<nav id='{$widget_id}-eael-pagination' class='eael-woo-pagination' data-plimit='$paginationLimit' data-totalpage ='{$args['total_post']}' data-widgetid='{$widget_id}' data-pageid='$page_id' data-args='".http_build_query( $args )."' data-template='".json_encode( $template_info, 1 )."'>";
985 $setPagination .="<ul class='page-numbers'>";
986
987 if ( $pagination_Paginationlist < 7 + ($adjacents * 2) ){
988 for ( $pagination = 1; $pagination <= $pagination_Paginationlist; $pagination ++ ) {
989 $active = ( $pagination == 0 || $pagination == 1 ) ? 'current' : '';
990 $setPagination .= sprintf("<li><a href='javascript:void(0);' id='post' class='page-numbers %s' data-pnumber='%2\$d'>%2\$d</a></li>" , esc_attr( $active ) ,esc_html( $pagination ) );
991 }
992
993 } else if ( $pagination_Paginationlist >= 5 + ($adjacents * 2) ){
994 for ( $pagination = 1; $pagination <= 4 + ( $adjacents * 2 ); $pagination ++ ) {
995 $active = ( $pagination == 0 || $pagination == 1 ) ? 'current' : '';
996 $setPagination .= sprintf("<li><a href='javascript:void(0);' id='post' class='page-numbers %s' data-pnumber='%2\$d'>%2\$d</a></li>" ,esc_attr( $active ) ,esc_html( $pagination ) );
997 }
998
999 $setPagination .="<li class='pagitext dots'>...</li>";
1000 $setPagination .= sprintf("<li><a href='javascript:void(0);' id='post' class='page-numbers %s' data-pnumber='%2\$d'>%2\$d</a></li>" ,esc_attr( $active ) ,esc_html( $pagination ) );
1001 }
1002
1003 if ($pagination_Paginationlist > 1) {
1004 $setPagination .= "<li class='pagitext'><a href='javascript:void(0);' class='page-numbers' data-pnumber='2'>".esc_html( $next_label )."</a></li>";
1005 }
1006
1007 $setPagination .="</ul>";
1008 $setPagination .="</nav>";
1009
1010 return $setPagination;
1011 }
1012 }
1013
1014 public static function eael_product_quick_view ($product, $settings, $widget_id) {
1015
1016 $sale_badge_align = isset( $settings['eael_product_sale_badge_alignment'] ) ? $settings['eael_product_sale_badge_alignment'] : '';
1017 $sale_badge_preset = isset( $settings['eael_product_sale_badge_preset'] ) ? $settings['eael_product_sale_badge_preset'] : '';
1018 $sale_text = ! empty( $settings['eael_product_carousel_sale_text'] ) ? $settings['eael_product_carousel_sale_text'] : (! empty( $settings['eael_product_sale_text'] ) ? $settings['eael_product_sale_text'] :( !empty( $settings['eael_product_gallery_sale_text'] ) ? $settings['eael_product_gallery_sale_text'] : 'Sale!' ));
1019 $stockout_text = ! empty( $settings['eael_product_carousel_stockout_text'] ) ? $settings['eael_product_carousel_stockout_text'] : (! empty( $settings['eael_product_stockout_text'] ) ? $settings['eael_product_stockout_text'] : ( !empty($settings['eael_product_gallery_stockout_text']) ? $settings['eael_product_gallery_stockout_text'] : 'Stock Out' ));
1020 $tag = ! empty( $settings['eael_product_quick_view_title_tag'] ) ? self::eael_validate_html_tag( $settings['eael_product_quick_view_title_tag'] ) : 'h1';
1021
1022 remove_action( 'eael_woo_single_product_summary', 'woocommerce_template_single_title', 5 );
1023 add_action( 'eael_woo_single_product_summary', function () use ( $tag ) {
1024 printf('<%1$s class="eael-product-quick-view-title product_title entry-title">%2$s</%1$s>',esc_html( $tag ), wp_kses( get_the_title(), Helper::eael_allowed_tags() ));
1025 }, 5 );
1026
1027 // Quick View Buy Now button — rendered inside form.cart via woocommerce_after_add_to_cart_button hook
1028 $qv_buy_now_enabled = isset( $settings['eael_product_carousel_qv_buy_now'] ) && 'yes' === $settings['eael_product_carousel_qv_buy_now'];
1029 if ( $qv_buy_now_enabled && $product->is_purchasable() && $product->is_in_stock() ) {
1030 $qv_buy_now_text = ! empty( $settings['eael_product_carousel_qv_buy_now_text'] ) ? $settings['eael_product_carousel_qv_buy_now_text'] : '';
1031 $qv_buy_now_icon = ! empty( $settings['eael_product_carousel_qv_buy_now_icon'] ) ? $settings['eael_product_carousel_qv_buy_now_icon'] : [];
1032 $qv_checkout_url = wc_get_checkout_url();
1033
1034 add_action( 'woocommerce_after_add_to_cart_button', function () use ( $qv_buy_now_text, $qv_buy_now_icon, $qv_checkout_url ) {
1035 ?>
1036 <button type="button" class="eael-popup-buy-now-button" data-checkout-url="<?php echo esc_url( $qv_checkout_url ); ?>" aria-label="<?php echo esc_attr( $qv_buy_now_text ? $qv_buy_now_text : __( 'Buy Now', 'essential-addons-for-elementor-lite' ) ); ?>">
1037 <?php if ( ! empty( $qv_buy_now_icon['value'] ) ) {
1038 Icons_Manager::render_icon( $qv_buy_now_icon, [ 'aria-hidden' => 'true' ] );
1039 } ?>
1040 <?php if ( ! empty( $qv_buy_now_text ) ) { ?>
1041 <span class="eael-buy-now-text"><?php echo esc_html( $qv_buy_now_text ); ?></span>
1042 <?php } ?>
1043 </button>
1044 <?php
1045 } );
1046 }
1047
1048 $popup_classes = array();
1049
1050 if ( isset( $settings['eael_product_quick_view_hide_categories'] ) && 'yes' === $settings['eael_product_quick_view_hide_categories'] ) {
1051 $popup_classes[] = 'eael-quick-view-hide-categories';
1052 }
1053 if ( isset( $settings['eael_product_quick_view_hide_quantity'] ) && 'yes' === $settings['eael_product_quick_view_hide_quantity'] ) {
1054 $popup_classes[] = 'eael-quick-view-hide-quantity';
1055 }
1056 ?>
1057
1058 <div id="eaproduct<?php echo esc_attr( $widget_id . $product->get_id() ); ?>" class="eael-product-popup
1059 eael-product-zoom-in woocommerce">
1060 <div class="eael-product-modal-bg"></div>
1061 <div class="eael-product-popup-details <?php echo esc_attr( implode( ' ', $popup_classes ) ); ?>">
1062 <div id="product-<?php esc_attr( get_the_ID() ); ?>" <?php post_class( 'product' ); ?>>
1063 <div class="eael-product-image-wrap">
1064 <?php
1065 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1066 echo ( ! $product->is_in_stock() ? '<span class="eael-onsale outofstock '.esc_attr( $sale_badge_preset ).' '.esc_attr( $sale_badge_align ).'">'. Helper::eael_wp_kses( $stockout_text ) .'</span>' : ($product->is_on_sale() ? '<span class="eael-onsale '.esc_attr( $sale_badge_preset ).' '.esc_attr( $sale_badge_align ).'">' . Helper::eael_wp_kses( $sale_text ) . '</span>' : '') );
1067 do_action( 'eael_woo_single_product_image' );
1068 ?>
1069 </div>
1070 <div class="eael-product-details-wrap">
1071 <?php do_action( 'eael_woo_single_product_summary' ); ?>
1072 </div>
1073 </div>
1074 <button class="eael-product-popup-close"><i class="fas fa-times"></i></button>
1075 </div>
1076
1077 </div>
1078 <?php
1079 }
1080
1081 public static function eael_avoid_redirect_to_single_page() {
1082 return '';
1083 }
1084
1085 public static function eael_woo_product_grid_actions() {
1086
1087 add_filter( 'woocommerce_add_to_cart_form_action', self::eael_avoid_redirect_to_single_page(), 10 );
1088 add_action( 'eael_woo_before_product_loop', 'woocommerce_output_all_notices', 30 );
1089
1090 }
1091
1092 public static function get_local_plugin_data( $basename = '' ) {
1093 if ( empty( $basename ) ) {
1094 return false;
1095 }
1096
1097 if ( !function_exists( 'get_plugins' ) ) {
1098 include_once ABSPATH . 'wp-admin/includes/plugin.php';
1099 }
1100
1101 $plugins = get_plugins();
1102
1103 if ( !isset( $plugins[ $basename ] ) ) {
1104 return false;
1105 }
1106
1107 return $plugins[ $basename ];
1108 }
1109
1110 /**
1111 * eael_validate_html_tag
1112 * @param $tag
1113 * @return mixed|string
1114 */
1115 public static function eael_validate_html_tag( $tag ){
1116 return in_array( strtolower( (string) $tag ), self::EAEL_ALLOWED_HTML_TAGS ) ? $tag : 'div';
1117 }
1118
1119 /**
1120 *
1121 * Strip tag based on allowed html tag
1122 * eael_wp_kses
1123 * @param $text
1124 * @return string
1125 */
1126 public static function eael_wp_kses( $text ) {
1127 if ( empty( $text ) ) {
1128 return '';
1129 }
1130 return wp_kses( $text, self::eael_allowed_tags(), array_merge( wp_allowed_protocols(), [ 'data' ] ) );
1131 }
1132
1133 /**
1134 * List of allowed protocols for wp_kses
1135 *
1136 * eael_allowed_protocols
1137 * @return array
1138 */
1139 public static function eael_allowed_protocols( $extra = [] ) {
1140 $protocols = array_merge( wp_allowed_protocols(), [ 'data' ] );
1141 if ( count( $extra ) > 0 ) {
1142 $protocols = array_merge( $protocols, $extra );
1143 }
1144 return $protocols;
1145 }
1146
1147 /**
1148 * List of allowed html tag for wp_kses
1149 *
1150 * eael_allowed_tags
1151 * @return array
1152 */
1153 public static function eael_allowed_tags( $extra = [] ) {
1154 $allowed_tags = [
1155 'a' => [
1156 'href' => [],
1157 'title' => [],
1158 'class' => [],
1159 'rel' => [],
1160 'id' => [],
1161 'style' => [],
1162 'target' => [],
1163 'data-elementor-open-lightbox' => [],
1164 ],
1165 'q' => [
1166 'cite' => [],
1167 'class' => [],
1168 'id' => [],
1169 ],
1170 'img' => [
1171 'src' => [],
1172 'alt' => [],
1173 'title' => [],
1174 'height' => [],
1175 'width' => [],
1176 'class' => [],
1177 'id' => [],
1178 'data-lazy-src' => [],
1179 'data-src' => [],
1180 'data-srcset' => [],
1181 'loading' => [],
1182 'srcset' => [],
1183 'sizes' => [],
1184 'decoding' => [],
1185 'fetchpriority' => [],
1186 ],
1187 'span' => [
1188 'class' => [],
1189 'id' => [],
1190 'style' => []
1191 ],
1192 'dfn' => [
1193 'class' => [],
1194 'id' => [],
1195 'style' => []
1196 ],
1197 'time' => [
1198 'datetime' => [],
1199 'class' => [],
1200 'id' => [],
1201 'style' => [],
1202 ],
1203 'cite' => [
1204 'title' => [],
1205 'class' => [],
1206 'id' => [],
1207 'style' => [],
1208 ],
1209 'hr' => [
1210 'class' => [],
1211 'id' => [],
1212 'style' => [],
1213 ],
1214 'b' => [
1215 'class' => [],
1216 'id' => [],
1217 'style' => [],
1218 ],
1219 'p' => [
1220 'class' => [],
1221 'id' => [],
1222 'style' => []
1223 ],
1224 'i' => [
1225 'class' => [],
1226 'id' => [],
1227 'style' => []
1228 ],
1229 'u' => [
1230 'class' => [],
1231 'id' => [],
1232 'style' => []
1233 ],
1234 's' => [
1235 'class' => [],
1236 'id' => [],
1237 'style' => [],
1238 ],
1239 'br' => [],
1240 'em' => [
1241 'class' => [],
1242 'id' => [],
1243 'style' => []
1244 ],
1245 'code' => [
1246 'class' => [],
1247 'id' => [],
1248 'style' => [],
1249 ],
1250 'mark' => [
1251 'class' => [],
1252 'id' => [],
1253 'style' => [],
1254 ],
1255 'small' => [
1256 'class' => [],
1257 'id' => [],
1258 'style' => []
1259 ],
1260 'abbr' => [
1261 'title' => [],
1262 'class' => [],
1263 'id' => [],
1264 'style' => [],
1265 ],
1266 'strong' => [
1267 'class' => [],
1268 'id' => [],
1269 'style' => []
1270 ],
1271 'del' => [
1272 'class' => [],
1273 'id' => [],
1274 'style' => []
1275 ],
1276 'ins' => [
1277 'class' => [],
1278 'id' => [],
1279 'style' => []
1280 ],
1281 'sub' => [
1282 'class' => [],
1283 'id' => [],
1284 'style' => [],
1285 ],
1286 'sup' => [
1287 'class' => [],
1288 'id' => [],
1289 'style' => [],
1290 ],
1291 'div' => [
1292 'class' => [],
1293 'id' => [],
1294 'style' => []
1295 ],
1296 'strike' => [
1297 'class' => [],
1298 'id' => [],
1299 'style' => [],
1300 ],
1301 'acronym' => [],
1302 'h1' => [
1303 'class' => [],
1304 'id' => [],
1305 'style' => [],
1306 ],
1307 'h2' => [
1308 'class' => [],
1309 'id' => [],
1310 'style' => [],
1311 ],
1312 'h3' => [
1313 'class' => [],
1314 'id' => [],
1315 'style' => [],
1316 ],
1317 'h4' => [
1318 'class' => [],
1319 'id' => [],
1320 'style' => [],
1321 ],
1322 'h5' => [
1323 'class' => [],
1324 'id' => [],
1325 'style' => [],
1326 ],
1327 'h6' => [
1328 'class' => [],
1329 'id' => [],
1330 'style' => [],
1331 ],
1332 'center' => [
1333 'class' => [],
1334 'id' => [],
1335 'style' => [],
1336 ],
1337 'ul' => [
1338 'class' => [],
1339 'id' => [],
1340 'style' => [],
1341 ],
1342 'ol' => [
1343 'class' => [],
1344 'id' => [],
1345 'style' => [],
1346 ],
1347 'li' => [
1348 'class' => [],
1349 'id' => [],
1350 'style' => [],
1351 ],
1352 'table' => [
1353 'class' => [],
1354 'id' => [],
1355 'style' => [],
1356 'dir' => [],
1357 'align' => [],
1358 ],
1359 'thead' => [
1360 'class' => [],
1361 'id' => [],
1362 'style' => [],
1363 'align' => [],
1364 ],
1365 'tbody' => [
1366 'class' => [],
1367 'id' => [],
1368 'style' => [],
1369 'align' => [],
1370 ],
1371 'tfoot' => [
1372 'class' => [],
1373 'id' => [],
1374 'style' => [],
1375 'align' => [],
1376 ],
1377 'th' => [
1378 'class' => [],
1379 'id' => [],
1380 'style' => [],
1381 'align' => [],
1382 'colspan' => [],
1383 'rowspan' => [],
1384 ],
1385 'tr' => [
1386 'class' => [],
1387 'id' => [],
1388 'style' => [],
1389 'align' => [],
1390 ],
1391 'td' => [
1392 'class' => [],
1393 'id' => [],
1394 'style' => [],
1395 'align' => [],
1396 'colspan' => [],
1397 'rowspan' => [],
1398 ],
1399 'header' => [
1400 'class' => [],
1401 'id' => [],
1402 'style' => [],
1403 ],
1404 'iframe' => [
1405 'class' => [],
1406 'id' => [],
1407 'style' => [],
1408 'title' => [],
1409 'width' => [],
1410 'height' => [],
1411 'src' => [],
1412 'allowfullscreen' => []
1413 ],
1414 'pre' => [
1415 'class' => [],
1416 'id' => [],
1417 'style' => [],
1418 ],
1419 'blockquote' => [
1420 'cite' => true, // URL of the source (HTML spec)
1421 'class' => true,
1422 'id' => true,
1423 'style' => true, // only if you intentionally allow inline styles
1424 ],
1425 'form' => [
1426 'action' => true,
1427 'method' => true,
1428 'id' => true,
1429 'class' => true,
1430 'name' => true,
1431 'novalidate' => true,
1432 ],
1433 'input' => [
1434 'type' => true,
1435 'name' => true,
1436 'value' => true,
1437 'placeholder' => true,
1438 'id' => true,
1439 'class' => true,
1440 'checked' => true,
1441 'disabled' => true,
1442 'required' => true,
1443 'readonly' => true,
1444 'min' => true,
1445 'max' => true,
1446 'step' => true,
1447 'maxlength' => true,
1448 'pattern' => true,
1449 'autocomplete'=> true,
1450 ],
1451 'textarea' => [
1452 'name' => true,
1453 'rows' => true,
1454 'cols' => true,
1455 'placeholder' => true,
1456 'id' => true,
1457 'class' => true,
1458 'required' => true,
1459 'readonly' => true,
1460 ],
1461 'select' => [
1462 'name' => true,
1463 'id' => true,
1464 'class' => true,
1465 'required' => true,
1466 'multiple' => true,
1467 ],
1468 'option' => [
1469 'value' => true,
1470 'selected' => true,
1471 'disabled' => true,
1472 ],
1473 'label' => [
1474 'for' => true,
1475 'class'=> true,
1476 ],
1477 'button' => [
1478 'type' => true,
1479 'id' => true,
1480 'class' => true,
1481 'disabled' => true,
1482 ],
1483 // Semantic Layout Tags
1484 'main' => [
1485 'class' => true,
1486 'id' => true,
1487 'style' => true,
1488 ],
1489 'section' => [
1490 'class' => true,
1491 'id' => true,
1492 'style' => true,
1493 ],
1494 'article' => [
1495 'class' => true,
1496 'id' => true,
1497 'style' => true,
1498 ],
1499 'aside' => [
1500 'class' => true,
1501 'id' => true,
1502 'style' => true,
1503 ],
1504 'nav' => [
1505 'class' => true,
1506 'id' => true,
1507 'style' => true,
1508 ],
1509 'footer' => [
1510 'class' => true,
1511 'id' => true,
1512 'style' => true,
1513 ],
1514 'hgroup' => [
1515 'class' => true,
1516 'id' => true,
1517 'style' => true,
1518 ],
1519 // Rich Media Tags
1520 'video' => [
1521 'src' => true,
1522 'poster' => true,
1523 'controls' => true,
1524 'autoplay' => true,
1525 'loop' => true,
1526 'muted' => true,
1527 'preload' => true,
1528 'width' => true,
1529 'height' => true,
1530 'class' => true,
1531 'id' => true,
1532 'style' => true,
1533 ],
1534 'audio' => [
1535 'src' => true,
1536 'controls' => true,
1537 'autoplay' => true,
1538 'loop' => true,
1539 'muted' => true,
1540 'preload' => true,
1541 'class' => true,
1542 'id' => true,
1543 'style' => true,
1544 ],
1545 'source' => [
1546 'src' => true,
1547 'type' => true,
1548 'media' => true,
1549 ],
1550 'track' => [
1551 'src' => true,
1552 'kind' => true,
1553 'srclang' => true,
1554 'label' => true,
1555 'default' => true,
1556 ],
1557 // Advanced Lists
1558 'dl' => [
1559 'class' => true,
1560 'id' => true,
1561 'style' => true,
1562 ],
1563 'dt' => [
1564 'class' => true,
1565 'id' => true,
1566 'style' => true,
1567 ],
1568 'dd' => [
1569 'class' => true,
1570 'id' => true,
1571 'style' => true,
1572 ],
1573 // Figures
1574 'figure' => [
1575 'class' => true,
1576 'id' => true,
1577 'style' => true,
1578 ],
1579 'figcaption' => [
1580 'class' => true,
1581 'id' => true,
1582 'style' => true,
1583 ],
1584 // Advanced Table Tags
1585 'caption' => [
1586 'class' => true,
1587 'id' => true,
1588 'style' => true,
1589 ],
1590 'colgroup' => [
1591 'span' => true,
1592 'class' => true,
1593 'id' => true,
1594 'style' => true,
1595 ],
1596 'col' => [
1597 'span' => true,
1598 'class' => true,
1599 'id' => true,
1600 'style' => true,
1601 ],
1602 // Interactive Elements
1603 'details' => [
1604 'open' => true,
1605 'class' => true,
1606 'id' => true,
1607 'style' => true,
1608 ],
1609 'summary' => [
1610 'class' => true,
1611 'id' => true,
1612 'style' => true,
1613 ],
1614 'dialog' => [
1615 'open' => true,
1616 'class' => true,
1617 'id' => true,
1618 'style' => true,
1619 ],
1620 // Extended Form Tags
1621 'fieldset' => [
1622 'disabled' => true,
1623 'form' => true,
1624 'name' => true,
1625 'class' => true,
1626 'id' => true,
1627 'style' => true,
1628 ],
1629 'legend' => [
1630 'class' => true,
1631 'id' => true,
1632 'style' => true,
1633 ],
1634 'optgroup' => [
1635 'label' => true,
1636 'disabled' => true,
1637 ],
1638 'datalist' => [
1639 'id' => true,
1640 'class' => true,
1641 ],
1642 'output' => [
1643 'for' => true,
1644 'form' => true,
1645 'name' => true,
1646 'class' => true,
1647 'id' => true,
1648 'style' => true,
1649 ],
1650 'progress' => [
1651 'value' => true,
1652 'max' => true,
1653 'class' => true,
1654 'id' => true,
1655 'style' => true,
1656 ],
1657 'meter' => [
1658 'value' => true,
1659 'min' => true,
1660 'max' => true,
1661 'low' => true,
1662 'high' => true,
1663 'optimum' => true,
1664 'class' => true,
1665 'id' => true,
1666 'style' => true,
1667 ],
1668 // Text Semantics
1669 'kbd' => [
1670 'class' => true,
1671 'id' => true,
1672 'style' => true,
1673 ],
1674 'samp' => [
1675 'class' => true,
1676 'id' => true,
1677 'style' => true,
1678 ],
1679 'var' => [
1680 'class' => true,
1681 'id' => true,
1682 'style' => true,
1683 ],
1684 // International Typography
1685 'ruby' => [
1686 'class' => true,
1687 'id' => true,
1688 'style' => true,
1689 ],
1690 'rt' => [
1691 'class' => true,
1692 'id' => true,
1693 'style' => true,
1694 ],
1695 'rp' => [
1696 'class' => true,
1697 'id' => true,
1698 'style' => true,
1699 ],
1700 ];
1701
1702 if ( count( $extra ) > 0 ) {
1703 $allowed_tags = array_merge_recursive( $allowed_tags, $extra );
1704 }
1705
1706 return apply_filters( 'eael_allowed_tags', $allowed_tags );
1707 }
1708
1709 /**
1710 * List of allowed icon/svg tags for wp_kses
1711 *
1712 * eael_allowed_icon_tags
1713 * @return array
1714 */
1715 public static function eael_allowed_icon_tags(){
1716 return [
1717 'svg' => [
1718 'class' => [],
1719 'aria-hidden' => [],
1720 'aria-labelledby' => [],
1721 'role' => [],
1722 'xmlns' => [],
1723 'width' => [],
1724 'height' => [],
1725 'viewbox' => []
1726 ],
1727 'g' => [ 'fill' => [] ],
1728 'title' => [ 'title' => [] ],
1729 'path' => [
1730 'd' => [],
1731 'fill' => [],
1732 'transform' => []
1733 ],
1734 'i' => [
1735 'class' => [],
1736 'id' => [],
1737 'style' => []
1738 ],
1739 'img' => [
1740 'src' => [],
1741 'alt' => [],
1742 'height' => [],
1743 'width' => [],
1744 'class' => [],
1745 'id' => [],
1746 'style' => []
1747 ],
1748 ];
1749 }
1750
1751 public static function eael_fetch_color_or_global_color($settings, $control_name=''){
1752 if( !isset($settings[$control_name])) {
1753 return '';
1754 }
1755
1756 $color = $settings[$control_name];
1757
1758 if(!empty($settings['__globals__']) && !empty($settings['__globals__'][$control_name])){
1759 $color = $settings['__globals__'][$control_name];
1760 $color_arr = explode('?id=', $color); //E.x. 'globals/colors/?id=primary'
1761
1762 $color_name = count($color_arr) > 1 ? $color_arr[1] : '';
1763 if( !empty($color_name) ) {
1764 $color = "var( --e-global-color-$color_name )";
1765 }
1766 }
1767
1768 return $color;
1769 }
1770
1771 /**
1772 * Get Render Icon
1773 *
1774 * Used to get render Icon for \Elementor\Controls_Manager::ICONS
1775 * @param array $icon Icon Type, Icon value
1776 * @param array $attributes Icon HTML Attributes
1777 * @param string $tag Icon HTML tag, defaults to <i>
1778 *
1779 * @return mixed|string
1780 */
1781 public static function get_render_icon( $icon, $attributes = [], $tag = 'i' ) {
1782 if ( empty( $icon['library'] ) ) {
1783 return false;
1784 }
1785
1786 $output = '';
1787
1788 /**
1789 * When the library value is svg it means that it's a SVG media attachment uploaded by the user.
1790 * Otherwise, it's the name of the font family that the icon belongs to.
1791 */
1792 if ( 'svg' === $icon['library'] ) {
1793 $output = method_exists( 'Elementor\Icons_Manager', 'render_uploaded_svg_icon' ) ? Icons_Manager::render_uploaded_svg_icon( $icon['value'] ) : '';
1794 } else {
1795 $output = method_exists( 'Elementor\Icons_Manager', 'render_font_icon' ) ? Icons_Manager::render_font_icon( $icon, $attributes, $tag ) : '';
1796 }
1797
1798 return $output;
1799 }
1800
1801 /**
1802 * Get SVG html by Icon
1803 *
1804 * Used to get svg attributes from Icon class for SVG Drawing widget
1805 * @param string $icon Icon
1806 *
1807 * @return string
1808 */
1809 public static function get_svg_by_icon( $icon, $attributes = [] ) {
1810 if ( empty( $icon ) || empty( $icon['value'] ) || empty( $icon['library'] ) ) return '';
1811
1812 $svg_html = "";
1813
1814 $icon_name = str_replace( [ 'fas fa-', 'fab fa-', 'far fa-' ], '', $icon['value'] );
1815 $library = str_replace( 'fa-', '', $icon['library'] );
1816 $svg_object = file_get_contents( EAEL_PLUGIN_PATH . "assets/front-end/js/lib-view/icons/{$library}.json" );
1817 $svg_object = json_decode( $svg_object, true );
1818 $i_class = str_replace(' ', '-', $icon['value']);
1819
1820 if ( empty( $svg_object['icons'][$icon_name] ) ) return $svg_html;
1821
1822 $icon = $svg_object['icons'][$icon_name];
1823 $view_box = "0 0 {$icon[0]} {$icon[1]}";
1824 $svg_html .= "<svg ";
1825
1826 $color = '';
1827 if( ! empty( $attributes ) ) {
1828 $color = $attributes['fill'] ?? '';
1829 unset( $attributes['fill'] );
1830 foreach ( $attributes as $key => $value ) {
1831 $svg_html .= $value ? "{$key}='{$value}' " : '';
1832 }
1833 }
1834 $svg_html .= " class='svg-inline--". $i_class ." eael-svg-icon' aria-hidden='true' data-icon='store' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='{$view_box}' >";
1835 $svg_html .= "<path fill='{$color}' d='{$icon[4]}'></path>";
1836 $svg_html .= "</svg>";
1837
1838 return $svg_html;
1839 }
1840
1841 /**
1842 * Get product image src and Product gallery's first image src
1843 *
1844 * @since 5.1.9
1845 * @return array
1846 */
1847 public static function eael_get_woo_product_gallery_image_srcs( $product, $image_size ){
1848 $image_id = $product->get_image_id();
1849 $image_gallery_ids = $product->get_gallery_image_ids();
1850
1851 $src = function_exists('wc_placeholder_img_src') ? wc_placeholder_img_src() : '';
1852
1853 if ( $image_id ) {
1854 $src = wp_get_attachment_image_src( $image_id, $image_size );
1855 $src = is_array($src) ? $src[0] : $src;
1856 }
1857
1858 $src_hover = count( $image_gallery_ids ) ? wp_get_attachment_image_src( $image_gallery_ids[0], $image_size ) : '';
1859 $src_hover = is_array($src_hover) ? $src_hover[0] : $src_hover;
1860
1861 return [
1862 'src' => $src,
1863 'src_hover' => $src_hover,
1864 ];
1865 }
1866
1867 /**
1868 * Sanitize a 'relation' operator.
1869 *
1870 * @param string $relation Raw relation key from the query argument.
1871 *
1872 * @return string Sanitized relation ('AND' or 'OR').
1873 * @since 5.3.2
1874 *
1875 */
1876 public static function eael_sanitize_relation( $relation ) {
1877 if ( 'OR' === strtoupper( $relation ) ) {
1878 return 'OR';
1879 } else {
1880 return 'AND';
1881 }
1882 }
1883
1884 /**
1885 * Get all ordered products by the user
1886 * @return boolean|array order ids
1887 * @since 5.8.9
1888 */
1889 public static function eael_get_all_user_ordered_products() {
1890 $user_id = get_current_user_id();
1891
1892 if( ! $user_id ) {
1893 return false;
1894 }
1895
1896 $args = array(
1897 'customer_id' => $user_id,
1898 'limit' => -1,
1899 );
1900
1901 $orders = wc_get_orders($args);
1902 $product_ids = [];
1903
1904 foreach( $orders as $order ){
1905 $items = $order->get_items();
1906
1907 foreach($items as $item){
1908 $product_ids[] = $item->get_product_id();
1909 }
1910 }
1911
1912 return $product_ids;
1913 }
1914
1915 /**
1916 * Get current device by screen size
1917 *
1918 *
1919 * @return string device name.
1920 * @since 5.9.1
1921 *
1922 */
1923 public static function eael_get_current_device_by_screen() {
1924 if ( ! session_id() ) {
1925 session_start( [
1926 'read_and_close' => true,
1927 ] );
1928 }
1929
1930 if ( isset( $_SESSION['eael_screen'] ) && ! empty( $breakpoints = Plugin::$instance->breakpoints->get_breakpoints_config() ) ) {
1931 $breakpoints = array_filter( $breakpoints, function ( $breakpoint ) {
1932 return $breakpoint['is_enabled'];
1933 } );
1934
1935 if ( isset( $breakpoints['widescreen'] ) ) {
1936 $widescreen = $breakpoints['widescreen'];
1937 unset( $breakpoints['widescreen'] );
1938 $breakpoints['desktop'] = $widescreen;
1939 }else{
1940 $breakpoints['desktop'] = [
1941 'value' => 2400
1942 ];
1943 }
1944
1945 $current_screen = intval( $_SESSION['eael_screen'] );
1946 foreach ( $breakpoints as $device => $screen ) {
1947 if ( $current_screen <= $screen['value'] ) {
1948 return $device;
1949 }
1950 }
1951
1952 return "widescreen";
1953 }
1954
1955 // If no match is found, you can return a default value or handle it as needed.
1956 return "unknown";
1957 }
1958
1959 public static function get_all_acf_fields() {
1960
1961 if ( ! class_exists( 'ACF' ) || ! function_exists( 'acf_get_field_groups' ) ) {
1962 return [];
1963 }
1964
1965 $acf_field_groups = acf_get_field_groups();
1966
1967 if ( empty( $acf_field_groups ) ) return [];
1968
1969 $acf_fields = [];
1970 foreach( $acf_field_groups as $group ){
1971 $default_acf_fields = acf_get_fields( $group['key'] );
1972 if ( ! empty( $default_acf_fields ) ) {
1973 foreach( $default_acf_fields as $field ) {
1974 $acf_fields[ $field['name'] ] = [
1975 'ID' => $field['ID'],
1976 'key' => $field['key'],
1977 'label' => $field['label'] ?? '',
1978 'name' => $field['name'] ?? '',
1979 'type' => $field['type'],
1980 'group' => $group['title'] ?? '',
1981 ];
1982 }
1983 }
1984 }
1985
1986 return $acf_fields;
1987 }
1988
1989 public static function eael_get_attachment_id_from_url( $attachment_url ) {
1990 global $wpdb;
1991
1992 // Strip the image size from the file name (if any)
1993 $attachment_url = preg_replace( '/-\d+x\d+(?=\.[^.\s]{2,4}$)/i', '', $attachment_url );
1994
1995 // Prepare the query to search in the 'guid' column in 'wp_posts'
1996 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1997 $attachment_id = $wpdb->get_var( $wpdb->prepare(
1998 "SELECT ID FROM $wpdb->posts WHERE guid = %s AND post_type = 'attachment'", $attachment_url
1999 ));
2000
2001 return $attachment_id;
2002 }
2003
2004 public static function eael_rating_markup( $rating, $count ) {
2005 $html = '';
2006 if ( 0 == $rating ) {
2007 $html = '<div class="eael-star-rating star-rating">';
2008 $html .= wc_get_star_rating_html( $rating, $count );
2009 $html .= '</div>';
2010 }
2011 return $html;
2012 }
2013
2014 //WooCommerce Helper Function
2015 public static function get_product_variation( $product_id = false ) {
2016 return wc_get_product( get_the_ID() );
2017 }
2018
2019 public static function get_product( $product_id = false ) {
2020 if ( 'product_variation' === get_post_type() ) {
2021 return self::get_product_variation( $product_id );
2022 }
2023 $product = wc_get_product( $product_id );
2024 if ( ! $product ) {
2025 $product = wc_get_product();
2026 }
2027 return $product;
2028 }
2029
2030 public static function eael_onpage_edit_template_markup( $page_id, $template_id, $return = false ) {
2031 if ( $return ) {
2032 ob_start();
2033 }
2034
2035 if ( Plugin::$instance->editor->is_edit_mode() ) {
2036 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
2037 $active_doc = !empty( $_GET['active-document'] ) ? sanitize_text_field( wp_unslash( $_GET['active-document'] ) ) : 0;
2038 $mode = $active_doc === $template_id ? 'save' : 'edit';
2039 ?>
2040 <div class='eael-onpage-edit-template-wrapper'>
2041 <div class='eael-onpage-edit-template' data-eael-template-id='<?php echo esc_attr( $template_id ); ?>'
2042 data-page-id='<?php echo esc_attr( $page_id ); ?>' data-mode='<?php echo esc_attr( $mode ); ?>'>
2043 <i class='eicon-edit'></i>
2044 <span><?php esc_html_e( 'Edit Template', 'essential-addons-for-elementor-lite' ); ?></span>
2045 </div>
2046 </div>
2047 <?php
2048 if ( $mode === 'save' ) {
2049 ?>
2050 <script>
2051 (function ($) {
2052 let $this = $("[data-eael-template-id='<?php echo esc_js( $template_id ); ?>']");
2053 $this.find('span').text('Save & Back');
2054 $this.find('i').addClass('eicon-arrow-left').removeClass('eicon-edit');
2055 $this.closest('.eael-onpage-edit-template-wrapper').addClass('eael-onpage-edit-activate').parent().addClass('eael-widget-otea-active');
2056 })(jQuery);
2057 </script>
2058 <?php
2059 }
2060 }
2061
2062 if ( $return ) {
2063 return ob_get_clean();
2064 }
2065 }
2066
2067 public static function eael_e_optimized_markup(){
2068 return Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
2069 }
2070
2071 //Get revision id by post id
2072 public static function current_revision_id( $post_id = null ) {
2073 $current_revision_id = $post_id ?? get_the_ID();
2074 $autosave = Utils::get_post_autosave( $current_revision_id );
2075
2076 if ( is_object( $autosave ) ) {
2077 $current_revision_id = $autosave->ID;
2078 }
2079
2080 return $current_revision_id;
2081 }
2082
2083 public static function is_elementor_publish_template( $template_id ) {
2084 $template_id = absint( $template_id );
2085
2086 return get_post_status( $template_id ) === 'publish' && get_post_type( $template_id ) === 'elementor_library';
2087 }
2088 }
2089