PluginProbe
Easy Elements for Elementor – Addons & Website Templates / trunk
Easy Elements for Elementor – Addons & Website Templates vtrunk
1.5.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.6 1.4.7 1.4.8 1.4.5 1.4.4 1.4.3 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 All 47 releases
easy-elements / includes / helper-functions.php

helper-functions.php in Easy Elements for Elementor – Addons & Website Templates trunk, at includes/helper-functions.php

1,257 lines 48.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 if ( ! function_exists( 'easyel_allowed_html' ) ) {
7 /**
8 * Returns allowed HTML tags and attributes for wp_kses.
9 *
10 * Covers all HTML used in the product gallery output including
11 * SVG elements, Swiper markup, form elements, and data attributes.
12 *
13 * @since 1.0.0
14 *
15 * @return array Allowed HTML tags with their attributes.
16 */
17 function easyel_allowed_html() {
18
19 $global_attributes = array(
20 'class' => true,
21 'id' => true,
22 'style' => true,
23 'title' => true,
24 'role' => true,
25 'tabindex' => true,
26 'aria-label' => true,
27 'aria-live' => true,
28 'aria-atomic' => true,
29 'aria-current' => true,
30 'aria-controls' => true,
31 'aria-disabled' => true,
32 'aria-hidden' => true,
33 'aria-expanded' => true,
34 'aria-selected' => true,
35 'aria-describedby' => true,
36 'aria-labelledby' => true,
37 'aria-haspopup' => true,
38 'aria-pressed' => true,
39 'aria-checked' => true,
40 'aria-valuenow' => true,
41 'aria-valuemin' => true,
42 'aria-valuemax' => true,
43 'data-*' => true,
44 );
45
46 $allowed_tags = array(
47
48 // Structural
49 'div' => $global_attributes,
50 'span' => $global_attributes,
51 'section' => $global_attributes,
52 'article' => $global_attributes,
53 'aside' => $global_attributes,
54 'header' => $global_attributes,
55 'footer' => $global_attributes,
56 'main' => $global_attributes,
57 'figure' => $global_attributes,
58 'figcaption' => $global_attributes,
59 'nav' => $global_attributes,
60 'ul' => $global_attributes,
61 'ol' => array_merge( $global_attributes, array(
62 'start' => true,
63 'reversed' => true,
64 'type' => true,
65 )),
66 'li' => array_merge( $global_attributes, array(
67 'value' => true,
68 )),
69
70 // Headings
71 'h1' => $global_attributes,
72 'h2' => $global_attributes,
73 'h3' => $global_attributes,
74 'h4' => $global_attributes,
75 'h5' => $global_attributes,
76 'h6' => $global_attributes,
77
78 // Text / Inline
79 'p' => $global_attributes,
80 'a' => array_merge( $global_attributes, array(
81 'href' => true,
82 'target' => true,
83 'rel' => true,
84 'download' => true,
85 )),
86 'strong' => $global_attributes,
87 'b' => $global_attributes,
88 'em' => $global_attributes,
89 'i' => $global_attributes,
90 'u' => $global_attributes,
91 's' => $global_attributes,
92 'small' => $global_attributes,
93 'sub' => $global_attributes,
94 'sup' => $global_attributes,
95 'br' => $global_attributes,
96 'hr' => $global_attributes,
97 'abbr' => $global_attributes,
98 'cite' => $global_attributes,
99 'code' => $global_attributes,
100 'pre' => $global_attributes,
101 'mark' => $global_attributes,
102 'del' => array_merge( $global_attributes, array(
103 'datetime' => true,
104 )),
105 'ins' => array_merge( $global_attributes, array(
106 'datetime' => true,
107 )),
108 'bdi' => $global_attributes,
109 'bdo' => array_merge( $global_attributes, array(
110 'dir' => true,
111 )),
112 'time' => array_merge( $global_attributes, array(
113 'datetime' => true,
114 )),
115
116 // Images
117 'img' => array_merge( $global_attributes, array(
118 'src' => true,
119 'srcset' => true,
120 'sizes' => true,
121 'alt' => true,
122 'width' => true,
123 'height' => true,
124 'loading' => true,
125 'decoding' => true,
126 'fetchpriority' => true,
127 'crossorigin' => true,
128 'usemap' => true,
129 'ismap' => true,
130 )),
131 'picture' => $global_attributes,
132 'source' => array_merge( $global_attributes, array(
133 'src' => true,
134 'srcset' => true,
135 'sizes' => true,
136 'media' => true,
137 'type' => true,
138 )),
139
140 // Video / Audio
141 'video' => array_merge( $global_attributes, array(
142 'src' => true,
143 'poster' => true,
144 'width' => true,
145 'height' => true,
146 'autoplay' => true,
147 'controls' => true,
148 'loop' => true,
149 'muted' => true,
150 'playsinline' => true,
151 'preload' => true,
152 )),
153 'audio' => array_merge( $global_attributes, array(
154 'src' => true,
155 'autoplay' => true,
156 'controls' => true,
157 'loop' => true,
158 'muted' => true,
159 'preload' => true,
160 )),
161 'iframe' => array_merge( $global_attributes, array(
162 'src' => true,
163 'width' => true,
164 'height' => true,
165 'frameborder' => true,
166 'allow' => true,
167 'allowfullscreen' => true,
168 'loading' => true,
169 'sandbox' => true,
170 'name' => true,
171 )),
172
173 // Form elements
174 'form' => array_merge( $global_attributes, array(
175 'action' => true,
176 'method' => true,
177 'enctype' => true,
178 'name' => true,
179 'target' => true,
180 'novalidate' => true,
181 'autocomplete' => true,
182 )),
183 'input' => array_merge( $global_attributes, array(
184 'type' => true,
185 'name' => true,
186 'value' => true,
187 'placeholder' => true,
188 'min' => true,
189 'max' => true,
190 'step' => true,
191 'checked' => true,
192 'disabled' => true,
193 'readonly' => true,
194 'required' => true,
195 'autofocus' => true,
196 'autocomplete' => true,
197 'inputmode' => true,
198 'pattern' => true,
199 'size' => true,
200 'maxlength' => true,
201 'minlength' => true,
202 'multiple' => true,
203 'accept' => true,
204 'list' => true,
205 'form' => true,
206 )),
207 'button' => array_merge( $global_attributes, array(
208 'type' => true,
209 'name' => true,
210 'value' => true,
211 'disabled' => true,
212 'form' => true,
213 )),
214 'label' => array_merge( $global_attributes, array(
215 'for' => true,
216 )),
217 'select' => array_merge( $global_attributes, array(
218 'name' => true,
219 'multiple' => true,
220 'disabled' => true,
221 'required' => true,
222 'size' => true,
223 'autocomplete' => true,
224 'form' => true,
225 )),
226 'option' => array_merge( $global_attributes, array(
227 'value' => true,
228 'selected' => true,
229 'disabled' => true,
230 'label' => true,
231 )),
232 'optgroup' => array_merge( $global_attributes, array(
233 'label' => true,
234 'disabled' => true,
235 )),
236 'textarea' => array_merge( $global_attributes, array(
237 'name' => true,
238 'rows' => true,
239 'cols' => true,
240 'placeholder' => true,
241 'disabled' => true,
242 'readonly' => true,
243 'required' => true,
244 'maxlength' => true,
245 'minlength' => true,
246 'wrap' => true,
247 'autocomplete' => true,
248 'form' => true,
249 )),
250 'fieldset' => array_merge( $global_attributes, array(
251 'disabled' => true,
252 'form' => true,
253 'name' => true,
254 )),
255 'legend' => $global_attributes,
256
257 // Table
258 'table' => array_merge( $global_attributes, array(
259 'border' => true,
260 'cellpadding' => true,
261 'cellspacing' => true,
262 'width' => true,
263 )),
264 'thead' => $global_attributes,
265 'tbody' => $global_attributes,
266 'tfoot' => $global_attributes,
267 'tr' => $global_attributes,
268 'th' => array_merge( $global_attributes, array(
269 'colspan' => true,
270 'rowspan' => true,
271 'scope' => true,
272 'abbr' => true,
273 'headers' => true,
274 )),
275 'td' => array_merge( $global_attributes, array(
276 'colspan' => true,
277 'rowspan' => true,
278 'headers' => true,
279 )),
280 'caption' => $global_attributes,
281 'colgroup' => array_merge( $global_attributes, array(
282 'span' => true,
283 )),
284 'col' => array_merge( $global_attributes, array(
285 'span' => true,
286 )),
287
288 // SVG
289 'svg' => array_merge( $global_attributes, array(
290 'xmlns' => true,
291 'viewBox' => true,
292 'viewbox' => true,
293 'width' => true,
294 'height' => true,
295 'fill' => true,
296 'stroke' => true,
297 'stroke-width' => true,
298 'stroke-linecap' => true,
299 'stroke-linejoin' => true,
300 'enable-background' => true,
301 'preserveAspectRatio' => true,
302 'x' => true,
303 'y' => true,
304 'opacity' => true,
305 'transform' => true,
306 'clip-path' => true,
307 'clip-rule' => true,
308 'mask' => true,
309 'overflow' => true,
310 'version' => true,
311 'xml:space' => true,
312 'xmlns:xlink' => true,
313 'focusable' => true,
314 )),
315 'path' => array_merge( $global_attributes, array(
316 'd' => true,
317 'fill' => true,
318 'fill-rule' => true,
319 'fill-opacity' => true,
320 'stroke' => true,
321 'stroke-width' => true,
322 'stroke-linecap' => true,
323 'stroke-linejoin' => true,
324 'stroke-dasharray' => true,
325 'stroke-dashoffset' => true,
326 'stroke-opacity' => true,
327 'opacity' => true,
328 'transform' => true,
329 'clip-path' => true,
330 'clip-rule' => true,
331 )),
332 'circle' => array_merge( $global_attributes, array(
333 'cx' => true,
334 'cy' => true,
335 'r' => true,
336 'fill' => true,
337 'fill-opacity' => true,
338 'stroke' => true,
339 'stroke-width' => true,
340 'opacity' => true,
341 'transform' => true,
342 )),
343 'ellipse' => array_merge( $global_attributes, array(
344 'cx' => true,
345 'cy' => true,
346 'rx' => true,
347 'ry' => true,
348 'fill' => true,
349 'fill-opacity' => true,
350 'stroke' => true,
351 'stroke-width' => true,
352 'opacity' => true,
353 'transform' => true,
354 )),
355 'rect' => array_merge( $global_attributes, array(
356 'x' => true,
357 'y' => true,
358 'width' => true,
359 'height' => true,
360 'rx' => true,
361 'ry' => true,
362 'fill' => true,
363 'fill-opacity' => true,
364 'stroke' => true,
365 'stroke-width' => true,
366 'opacity' => true,
367 'transform' => true,
368 )),
369 'line' => array_merge( $global_attributes, array(
370 'x1' => true,
371 'y1' => true,
372 'x2' => true,
373 'y2' => true,
374 'stroke' => true,
375 'stroke-width' => true,
376 'stroke-linecap' => true,
377 'opacity' => true,
378 'transform' => true,
379 )),
380 'polyline' => array_merge( $global_attributes, array(
381 'points' => true,
382 'fill' => true,
383 'stroke' => true,
384 'stroke-width' => true,
385 'stroke-linecap' => true,
386 'stroke-linejoin' => true,
387 'opacity' => true,
388 'transform' => true,
389 )),
390 'polygon' => array_merge( $global_attributes, array(
391 'points' => true,
392 'fill' => true,
393 'fill-rule' => true,
394 'stroke' => true,
395 'stroke-width' => true,
396 'opacity' => true,
397 'transform' => true,
398 )),
399 'g' => array_merge( $global_attributes, array(
400 'fill' => true,
401 'fill-rule' => true,
402 'stroke' => true,
403 'stroke-width' => true,
404 'opacity' => true,
405 'transform' => true,
406 'clip-path' => true,
407 )),
408 'defs' => $global_attributes,
409 'symbol' => array_merge( $global_attributes, array(
410 'viewBox' => true,
411 'viewbox' => true,
412 'width' => true,
413 'height' => true,
414 'fill' => true,
415 'overflow' => true,
416 )),
417 'use' => array_merge( $global_attributes, array(
418 'href' => true,
419 'xlink:href' => true,
420 'x' => true,
421 'y' => true,
422 'width' => true,
423 'height' => true,
424 'fill' => true,
425 'stroke' => true,
426 )),
427 'clipPath' => $global_attributes,
428 'linearGradient' => array_merge( $global_attributes, array(
429 'x1' => true,
430 'y1' => true,
431 'x2' => true,
432 'y2' => true,
433 'gradientUnits' => true,
434 'gradientTransform' => true,
435 )),
436 'radialGradient' => array_merge( $global_attributes, array(
437 'cx' => true,
438 'cy' => true,
439 'r' => true,
440 'fx' => true,
441 'fy' => true,
442 'gradientUnits' => true,
443 'gradientTransform' => true,
444 )),
445 'stop' => array_merge( $global_attributes, array(
446 'offset' => true,
447 'stop-color' => true,
448 'stop-opacity' => true,
449 )),
450 'text' => array_merge( $global_attributes, array(
451 'x' => true,
452 'y' => true,
453 'dx' => true,
454 'dy' => true,
455 'text-anchor' => true,
456 'font-size' => true,
457 'font-family' => true,
458 'font-weight' => true,
459 'fill' => true,
460 'opacity' => true,
461 'transform' => true,
462 )),
463 'tspan' => array_merge( $global_attributes, array(
464 'x' => true,
465 'y' => true,
466 'dx' => true,
467 'dy' => true,
468 'fill' => true,
469 'font-size' => true,
470 'font-family' => true,
471 'font-weight' => true,
472 )),
473 'mask' => array_merge( $global_attributes, array(
474 'x' => true,
475 'y' => true,
476 'width' => true,
477 'height' => true,
478 'maskUnits' => true,
479 'maskContentUnits' => true,
480 )),
481 'title' => $global_attributes,
482 'desc' => $global_attributes,
483 );
484
485 return apply_filters( 'easyel_allowed_html', $allowed_tags );
486 }
487 }
488
489 add_filter( 'elementor/files/allow_unfiltered_files', '__return_false' );
490
491
492 if ( ! function_exists( 'easyel_premium_addon_active' ) ) {
493 /**
494 * Check if Easy Elements Pro is active.
495 *
496 * Cached per request and filterable for compatibility.
497 *
498 * @return bool
499 */
500 function easyel_premium_addon_active() {
501 static $is_active = null;
502 if ( null === $is_active ) {
503 $detected = defined( 'EASYELEMENTS_PRO_VER' ) || defined( 'EASYELEMENTS_PRO_FILE' );
504 $is_active = (bool) apply_filters( 'easyel_premium_addon_active', $detected );
505 }
506 return $is_active;
507 }
508 }
509
510 if ( ! function_exists( 'easyel_get_pro_extension_keys' ) ) {
511 /**
512 * Option keys for the Pro-only extensions.
513 *
514 * Deliberately free of any __() / translation call so it is safe to use
515 * before the `init` action (e.g. inside option filters that run on
516 * `plugins_loaded`). Mirrors every entry flagged `'is_pro' => true` in
517 * easyel_get_extension_fields() — keep the two lists in sync when adding
518 * or removing a Pro extension.
519 *
520 * @return string[]
521 */
522 function easyel_get_pro_extension_keys() {
523 return [
524 'enable_cursor',
525 'enable_sticky_elements',
526 'enable_cursor_hover_effect',
527 'enable_cursor_move_effect',
528 'enable_scroll_trigger',
529 'enable_parallax_image',
530 'enable_drawsvg',
531 'enable_image_3d_effect',
532 'enable_smooth_scroller',
533 'enable_bounce_animation',
534 'enable_visibility_control',
535 'enable_dynamic_content',
536 'enable_live_copy_paste',
537 'enable_easy_custom_css',
538 'enable_global_badge',
539 'enable_megamenu_builder',
540 'enable_popup_builder',
541 'enable_quick_view',
542 'enable_easyel_compare',
543 'enable_easyel_wishlist',
544 ];
545 }
546 }
547
548 if ( ! function_exists( 'easyel_force_pro_options_off_when_inactive' ) ) {
549 /**
550 * Disable Pro-only options when the Pro add-on is inactive.
551 *
552 * Forces Pro settings to appear disabled without modifying saved values.
553 */
554 function easyel_force_pro_options_off_when_inactive() {
555 if ( easyel_premium_addon_active() ) {
556 return;
557 }
558
559 add_filter( 'option_easy_element_extensions', static function ( $value ) {
560 if ( ! is_array( $value ) ) {
561 return $value;
562 }
563
564 foreach ( easyel_get_pro_extension_keys() as $key ) {
565 if ( isset( $value[ $key ] ) ) {
566 $value[ $key ] = 0;
567 }
568 }
569 return $value;
570 } );
571
572 if ( class_exists( '\\Easyel\\EasyElements\\Admin\\Admin_Settings' ) ) {
573 $instance = \Easyel\EasyElements\Admin\Admin_Settings::get_instance();
574 if ( method_exists( $instance, 'easyel_elements_get_available_widgets' ) ) {
575 foreach ( (array) $instance->easyel_elements_get_available_widgets() as $widget_key => $widget ) {
576 if ( ! empty( $widget['is_pro'] ) ) {
577 add_filter( 'option_easy_element_widget_' . $widget_key, '__return_zero' );
578 }
579 }
580 }
581 }
582 }
583 // Run before init_widgets (which fires on plugins_loaded default 10).
584 add_action( 'plugins_loaded', 'easyel_force_pro_options_off_when_inactive', 5 );
585 }
586
587 if ( ! function_exists( 'easyel_get_pro_clean_version' ) ) {
588 function easyel_get_pro_clean_version() {
589
590 if ( ! defined( 'EASYELEMENTS_PRO_FILE' ) ) {
591 return null;
592 }
593
594 if ( ! function_exists( 'get_file_data' ) ) {
595 require_once ABSPATH . 'wp-admin/includes/plugin.php';
596 }
597
598 $data = get_file_data(
599 EASYELEMENTS_PRO_FILE,
600 [ 'Version' => 'Version' ]
601 );
602
603 return $data['Version'] ?? null;
604 }
605 }
606
607 if ( ! function_exists( 'easyel_get_license_status' ) ) {
608
609 function easyel_get_license_status() {
610 return (string) apply_filters( 'easyel_license_status', 'invalid' );
611 }
612 }
613
614 if ( ! function_exists( 'easyel_get_license_activate_url' ) ) {
615
616 function easyel_get_license_activate_url() {
617 return (string) apply_filters( 'easyel_license_activate_url', '' );
618 }
619 }
620
621 if ( ! function_exists( 'easyel_enable_svg_upload' ) ) {
622 function easyel_enable_svg_upload( $mimes ) {
623 $mimes['svg'] = 'image/svg+xml';
624 $mimes['svgz'] = 'image/svg+xml';
625 return $mimes;
626 }
627 add_filter( 'upload_mimes', 'easyel_enable_svg_upload' );
628 }
629
630 if ( ! function_exists( 'easyel_fix_svg_filetype' ) ) {
631 function easyel_fix_svg_filetype( $data, $file, $filename, $mimes ) {
632 $ext = pathinfo( $filename, PATHINFO_EXTENSION );
633 if ( strtolower( $ext ) === 'svg' || strtolower( $ext ) === 'svgz' ) {
634 $data['ext'] = 'svg';
635 $data['type'] = 'image/svg+xml';
636 }
637 return $data;
638 }
639 add_filter( 'wp_check_filetype_and_ext', 'easyel_fix_svg_filetype', 10, 4 );
640 }
641
642 if ( ! function_exists( 'easyel_handle_sideload_svg' ) ) {
643 function easyel_handle_sideload_svg( $file ) {
644 $ext = pathinfo( $file['name'], PATHINFO_EXTENSION );
645 if ( strtolower( $ext ) === 'svg' || strtolower( $ext ) === 'svgz' ) {
646 $file['type'] = 'image/svg+xml';
647 }
648 return $file;
649 }
650
651 add_filter( 'wp_handle_sideload_prefilter', 'easyel_handle_sideload_svg' );
652 }
653
654 if ( ! function_exists( 'easyel_render_upgrade_pro_button' ) ) {
655
656 function easyel_render_upgrade_pro_button() {
657 ?>
658 <a href="https://wpeasyelements.com/pricing/" class="easyel-btn easyel-decoration-none" target="_blank">
659 <i class="easyelIcon-crown"></i>
660 <?php esc_html_e( 'Upgrade to pro', 'easy-elements' ); ?>
661 </a>
662 <?php
663 }
664 add_action( 'easyel_overview_upgrade_button', 'easyel_render_upgrade_pro_button' );
665 }
666
667 if ( ! function_exists( 'easyel_render_go_premium_tab' ) ) {
668
669 function easyel_render_go_premium_tab() {
670 ?>
671 <div class="easyel-tab-pro-link">
672 <a href="https://wpeasyelements.com/pricing/" class="easyel-nav-tab-pro" target="_blank">
673 <i class="easyelIcon-crown"></i>
674 <?php esc_html_e( 'Go Premium', 'easy-elements' ); ?>
675 </a>
676 </div>
677 <?php
678 }
679 add_action( 'easyel_settings_go_premium', 'easyel_render_go_premium_tab' );
680 }
681
682 if ( ! function_exists( 'easyel_get_cf7_forms' ) ) {
683 /**
684 * Get a list of all CF7 forms
685 *
686 * @return array
687 */
688 function easyel_get_cf7_forms() {
689 $forms = get_posts( [
690 'post_type' => 'wpcf7_contact_form',
691 'post_status' => 'publish',
692 'posts_per_page' => -1,
693 'orderby' => 'title',
694 'order' => 'ASC',
695 ] );
696
697 if ( ! empty( $forms ) ) {
698 return wp_list_pluck( $forms, 'post_title', 'ID' );
699 }
700 return [];
701 }
702 }
703
704
705 // Domain Search Code
706 add_action('template_redirect', function(){
707 // phpcs:ignore WordPress.Security.NonceVerification.Missing
708 if (isset($_POST['easyel_domain_redirect'])) {
709 // phpcs:ignore WordPress.Security.NonceVerification.Missing
710 $domain = isset($_POST['domain']) ? sanitize_text_field(wp_unslash($_POST['domain'])) : '';
711 // phpcs:ignore WordPress.Security.NonceVerification.Missing
712 $base_url = isset($_POST['base_url']) ? esc_url_raw( wp_unslash($_POST['base_url'] ) ) : '';
713
714 if ( !empty($domain) && !empty($base_url) && filter_var($base_url, FILTER_VALIDATE_URL) ) {
715 $redirect_url = esc_url_raw($base_url . urlencode($domain));
716 wp_safe_redirect( $redirect_url );
717 exit;
718 }
719 }
720 });
721
722 function easyel_get_extension_fields() {
723 $fields = [
724 'enable_cursor' => [
725 'label' => __('Magic Cursor', 'easy-elements'),
726 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/magic-cursor.svg',
727 'is_pro' => true,
728 'group' => 'GSAP Extensions',
729 'demo_url' => 'https://wpeasyelements.com/docs/magic-cursor/',
730 'docs_url' => 'https://wpeasyelements.com/docs/magic-cursor/',
731 ],
732 'enable_sticky_elements' => [
733 'label' => __('Sticky Elements', 'easy-elements'),
734 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/sticky-elements.svg',
735 'is_pro' => true,
736 'group' => 'General Extensions',
737 'demo_url' => 'https://wpeasyelements.com/extensions/sticky-elements/',
738 'docs_url' => 'https://wpeasyelements.com/docs/sticky-elements/',
739 ],
740 'enable_cursor_hover_effect' => [
741 'label' => __('Cursor Hover Effect', 'easy-elements'),
742 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/cursor-hover-effect.svg',
743 'is_pro' => true,
744 'group' => 'GSAP Extensions',
745 'demo_url' => 'https://wpeasyelements.com/extensions/cursor-hover-effect/',
746 'docs_url' => 'https://wpeasyelements.com/docs/cursor-hover-effect/',
747 ],
748 'enable_cursor_move_effect' => [
749 'label' => __('Cursor Move Effect', 'easy-elements'),
750 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/cursor-move-effect.svg',
751 'is_pro' => true,
752 'group' => 'GSAP Extensions',
753 'demo_url' => 'https://wpeasyelements.com/extensions/cursor-move-effect/',
754 'docs_url' => 'https://wpeasyelements.com/docs/cursor-move-effect/',
755
756 ],
757 'enable_scroll_trigger' => [
758 'label' => __('ScrollTrigger', 'easy-elements'),
759 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/scrolltrigger.svg',
760 'is_pro' => true,
761 'group' => 'GSAP Extensions',
762 'demo_url' => 'https://wpeasyelements.com/extensions/scroll-trigger/',
763 'docs_url' => 'https://wpeasyelements.com/docs/scrolltrigger/',
764
765 ],
766 'enable_parallax_image' => [
767 'label' => __('Background Parallax', 'easy-elements'),
768 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/background-parallax.svg',
769 'is_pro' => true,
770 'group' => 'GSAP Extensions',
771 'demo_url' => 'https://wpeasyelements.com/extensions/background-parallax/',
772 'docs_url' => 'https://wpeasyelements.com/docs/background-parallax/',
773 ],
774 'enable_drawsvg' => [
775 'label' => __('DrawSVG', 'easy-elements'),
776 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/drawsvg.svg',
777 'is_pro' => true,
778 'upcoming' => true,
779 'group' => 'GSAP Extensions',
780 'demo_url' => '#',
781 'docs_url' => '#',
782 ],
783 'enable_image_3d_effect' => [
784 'label' => __('Image 3D Effect', 'easy-elements'),
785 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/image-3d-effect.svg',
786 'is_pro' => true,
787 'upcoming' => true,
788 'group' => 'GSAP Extensions',
789 'demo_url' => '#',
790 'docs_url' => '#',
791 ],
792 'enable_smooth_scroller' => [
793 'label' => __('Scroll Smoother', 'easy-elements'),
794 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/image-3d-effect.svg',
795 'is_pro' => true,
796 'setting' => true,
797 'group' => 'GSAP Extensions',
798 'demo_url' => 'https://wpeasyelements.com/',
799 'docs_url' => 'https://wpeasyelements.com/docs/scroll-smoother/',
800 ],
801 'enable_bounce_animation' => [
802 'label' => __('Bounce Animation', 'easy-elements'),
803 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/image-3d-effect.svg',
804 'is_pro' => true,
805 'group' => 'GSAP Extensions',
806 'demo_url' => 'https://wpeasyelements.com/extensions/bounce-animation/',
807 'docs_url' => 'https://wpeasyelements.com/docs/bounce-animation/',
808 ],
809 'enable_wrapper_link' => [
810 'label' => __('Wrapper Link', 'easy-elements'),
811 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/wrapper-link.svg',
812 'is_pro' => false,
813 'group' => 'General Extensions',
814 'demo_url' => 'https://wpeasyelements.com/extensions/wrapper-link/',
815 'docs_url' => 'https://wpeasyelements.com/docs/wrapper-link/',
816 ],
817 'enable_post_duplicator' => [
818 'label' => __('Duplicator', 'easy-elements'),
819 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/duplicator.svg',
820 'is_pro' => false,
821 'group' => 'General Extensions',
822 'demo_url' => 'https://wpeasyelements.com/docs/post-page-duplicate/',
823 'docs_url' => 'https://wpeasyelements.com/docs/post-page-duplicate/',
824 ],
825 'enable_postpage_export' => [
826 'label' => __('Easy Export', 'easy-elements'),
827 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/duplicator.svg',
828 'is_pro' => false,
829 'group' => 'General Extensions',
830 'demo_url' => 'https://wpeasyelements.com/extensions/docs/easy-export/',
831 'docs_url' => 'https://wpeasyelements.com/docs/easy-export/',
832 ],
833 'enable_visibility_control' => [
834 'label' => __('Visibility Control', 'easy-elements'),
835 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/visibility-control.svg',
836 'is_pro' => true,
837 'group' => 'General Extensions',
838 'demo_url' => 'https://wpeasyelements.com/extensions/visibility-control/',
839 'docs_url' => 'https://wpeasyelements.com/docs/visibility-control/',
840 ],
841 'enable_dynamic_content' => [
842 'label' => __('Dynamic Content', 'easy-elements'),
843 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/dynamic-content.svg',
844 'is_pro' => true,
845 'group' => 'General Extensions',
846 'demo_url' => 'https://wpeasyelements.com/extensions/dynamic-content/',
847 'docs_url' => 'https://wpeasyelements.com/docs/dynamic-content/',
848 ],
849 'enable_live_copy_paste' => [
850 'label' => __('Live Copy Paste', 'easy-elements'),
851 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/live-copy.svg',
852 'is_pro' => true,
853 'group' => 'General Extensions',
854 'demo_url' => 'https://wpeasyelements.com/extensions/live-copy/',
855 'docs_url' => 'https://wpeasyelements.com/docs/live-copy/',
856 ],
857 'enable_easy_custom_css' => [
858 'label' => __('Custom CSS', 'easy-elements'),
859 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/easy-custom-css.svg',
860 'is_pro' => true,
861 'group' => 'General Extensions',
862 'demo_url' => 'https://wpeasyelements.com/docs/custom-css/',
863 'docs_url' => 'https://wpeasyelements.com/docs/custom-css/',
864 ],
865 'enable_global_badge' => [
866 'label' => __('Global Badge', 'easy-elements'),
867 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/global-badge.svg',
868 'is_pro' => true,
869 'group' => 'General Extensions',
870 'demo_url' => 'https://wpeasyelements.com/extensions/global-badge/',
871 'docs_url' => 'https://wpeasyelements.com/docs/global-badge/',
872 ],
873 'enable_megamenu_builder' => [
874 'label' => __('Megamenu Builder', 'easy-elements'),
875 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/megamenu.svg',
876 'is_pro' => true,
877 'group' => 'General Extensions',
878 'demo_url' => 'https://wpeasyelements.com/megamenu-builder/',
879 'docs_url' => 'https://wpeasyelements.com/docs/megamenu-builder/',
880 ],
881 'enable_reading_progress_bar' => [
882 'label' => __('Reading Progress Bar', 'easy-elements'),
883 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/progressbar.svg',
884 'is_pro' => false,
885 'setting' => true,
886 'group' => 'General Extensions',
887 'demo_url' => 'https://wpeasyelements.com/reading-progress-bar/',
888 'docs_url' => 'https://wpeasyelements.com/docs/reading-progress-bar/',
889 ],
890 'enable_scroll_top' => [
891 'label' => __('Scroll Top', 'easy-elements'),
892 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/arrow-up.svg',
893 'is_pro' => false,
894 'setting' => true,
895 'group' => 'General Extensions',
896 'demo_url' => '',
897 'docs_url' => 'https://wpeasyelements.com/docs/scroll-to-top/',
898 ],
899 'enable_preloader' => [
900 'label' => __( 'Preloader', 'easy-elements' ),
901 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/loader.svg',
902 'is_pro' => false,
903 'setting' => true,
904 'group' => 'General Extensions',
905 'demo_url' => '',
906 'docs_url' => 'https://wpeasyelements.com/docs/preloader/',
907 ],
908 'enable_popup_builder' => [
909 'label' => __('Popup Builder', 'easy-elements'),
910 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/popup-builder.svg',
911 'is_pro' => true,
912 'setting' => true,
913 'group' => 'General Extensions',
914 'demo_url' => 'https://wpeasyelements.com/extensions/popup-builder/',
915 'docs_url' => 'https://wpeasyelements.com/docs/popup-builder/',
916 ],
917 'enable_quick_view' => [
918 'label' => __('Quick View', 'easy-elements'),
919 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/quickview.svg',
920 'is_pro' => true,
921 'setting' => true,
922 'group' => 'WooCommerce Extensions',
923 'demo_url' => 'https://wpeasyelements.com/shop/',
924 'docs_url' => 'https://wpeasyelements.com/docs/quick-view/',
925 ],
926 'enable_easyel_compare' => [
927 'label' => __('Compare', 'easy-elements'),
928 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/compare.svg',
929 'is_pro' => true,
930 'setting' => true,
931 'group' => 'WooCommerce Extensions',
932 'demo_url' => 'https://wpeasyelements.com/shop/',
933 'docs_url' => 'https://wpeasyelements.com/docs/compare/',
934 ],
935 'enable_easyel_wishlist' => [
936 'label' => __('Wishlist', 'easy-elements'),
937 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/wishlist.svg',
938 'is_pro' => true,
939 'setting' => true,
940 'group' => 'WooCommerce Extensions',
941 'demo_url' => 'https://wpeasyelements.com/shop/',
942 'docs_url' => 'https://wpeasyelements.com/docs/wishlist/',
943 ],
944 ];
945
946 return apply_filters('easyel_extension_fields', $fields);
947 }
948
949 function easyel_sanitize_conditions_array( $conditions ) {
950 if ( ! is_array( $conditions ) ) {
951 return [];
952 }
953
954 $sanitized = [];
955 foreach ( $conditions as $cond ) {
956 if ( ! is_array( $cond ) ) continue;
957
958 $sanitized[] = [
959 'include' => isset($cond['include']) ? sanitize_text_field($cond['include']) : 'include',
960 'main' => isset($cond['main']) ? sanitize_text_field($cond['main']) : '',
961 'sub' => isset($cond['sub']) ? sanitize_text_field($cond['sub']) : '',
962 'child_sub' => isset($cond['child_sub']) ? sanitize_text_field($cond['child_sub']) : '',
963 ];
964 }
965
966 return $sanitized;
967 }
968
969 /**
970 * Safely decode JSON or return array as-is
971 */
972 function easyel_safe_json_decode( $data ) {
973 if ( is_string($data) ) {
974 $decoded = json_decode($data, true);
975 if ( json_last_error() === JSON_ERROR_NONE && is_array($decoded) ) {
976 return $decoded;
977 }
978 return [];
979 } elseif ( is_array($data) ) {
980 return $data;
981 } else {
982 return [];
983 }
984 }
985
986 class Easyel_Widget_Injection {
987 public static function init() {
988 add_filter( 'elementor/controls/animations/additional_animations', [ __CLASS__, 'inject_easy_animations' ] );
989 }
990
991 public static function inject_easy_animations( $animations ) {
992 $animations['Easy Animations'] = [
993 'scaleIn' => __( 'Scale In', 'easy-elements' ),
994 ];
995 return $animations;
996 }
997 }
998
999 // Initialize the class
1000 Easyel_Widget_Injection::init();
1001
1002
1003 /**
1004 * Check if a specific Easy Element extension setting is enabled.
1005 *
1006 * @param string $setting_key The key of the setting to check (e.g. 'enable_sticky_elements').
1007 * @return bool True if enabled, false otherwise.
1008 */
1009 function easyel_element_is_enabled( $setting_key ) {
1010 if ( empty( $setting_key ) ) {
1011 return false;
1012 }
1013
1014 $tab_slug = 'extensions';
1015 $settings = get_option( 'easy_element_' . $tab_slug, [] );
1016
1017 // Sanitize and check
1018 $value = isset( $settings[ $setting_key ] ) ? (int) $settings[ $setting_key ] : 0;
1019
1020 return ( $value === 1 );
1021 }
1022
1023 /**
1024 * Backward compatibility alias.
1025 *
1026 * The non-prefixed function name is retained only for compatibility with
1027 * previously released Easy Elements Pro versions. Removing this function
1028 * would break existing installations that still reference
1029 * `easy_element_is_enabled()` and could result in fatal errors.
1030 *
1031 * New code should use `easyel_element_is_enabled()` instead.
1032 */
1033 if ( ! function_exists( 'easy_element_is_enabled' ) ) {
1034 function easy_element_is_enabled( $setting_key ) {
1035 return easyel_element_is_enabled( $setting_key );
1036 }
1037 }
1038
1039
1040 function easyel_translate_hfe_template( $template_id ) {
1041 if ( function_exists( 'pll_get_post' ) ) {
1042 $translated = pll_get_post( $template_id );
1043 if ( $translated ) {
1044 $template_id = $translated;
1045 }
1046 }
1047 if ( has_filter( 'wpml_object_id' ) ) {
1048
1049 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
1050 $translated = apply_filters( 'wpml_object_id', $template_id, 'ee-elementor-hf', true );
1051 if ( $translated ) {
1052 $template_id = $translated;
1053 }
1054 }
1055 return $template_id;
1056 }
1057
1058 add_filter( 'easyel_get_settings_type_header', 'easyel_translate_hfe_template' );
1059 add_filter( 'easyel_get_settings_type_footer', 'easyel_translate_hfe_template' );
1060 add_filter( 'easyel_get_settings_type_easy_topbar', 'easyel_translate_hfe_template' );
1061 add_filter( 'easyel_get_settings_type_easy_after__header', 'easyel_translate_hfe_template' );
1062 add_filter( 'easyel_get_settings_type_before_footer', 'easyel_translate_hfe_template' );
1063
1064 if ( ! function_exists( 'easyel_get_valid_archive_post_types' ) ) {
1065 function easyel_get_valid_archive_post_types() {
1066
1067 $post_types = get_post_types(
1068 [
1069 'public' => true,
1070 'show_in_nav_menus' => true,
1071 ],
1072 'objects'
1073 );
1074
1075 $valid = [];
1076
1077 foreach ( $post_types as $post_type => $pt ) {
1078
1079 if ( ! $pt->has_archive || ! get_post_type_archive_link( $post_type ) ) {
1080 continue;
1081 }
1082
1083 if ( $post_type === 'page' ) {
1084 continue;
1085 }
1086
1087 if (
1088 ! empty( $pt->_builtin ) === false &&
1089 str_starts_with( $post_type, 'elementor' )
1090 ) {
1091 continue;
1092 }
1093
1094 if ( ! $pt->publicly_queryable ) {
1095 continue;
1096 }
1097
1098 $valid[ $post_type ] = $pt;
1099 }
1100
1101 return $valid;
1102 }
1103 }
1104
1105 if ( ! function_exists( 'easyel_get_hierarchical_taxonomies_by_post_type' ) ) {
1106 function easyel_get_hierarchical_taxonomies_by_post_type() {
1107
1108 $map = [];
1109 $post_types = easyel_get_valid_archive_post_types();
1110
1111 foreach ($post_types as $post_type => $pt) {
1112 $taxonomies = get_object_taxonomies($post_type, 'objects');
1113
1114 foreach ($taxonomies as $tax_slug => $tax) {
1115 if (!$tax->public) {
1116 continue;
1117 }
1118
1119 $map[$tax_slug] = [
1120 'post_type' => $post_type,
1121 'taxonomy' => $tax_slug,
1122 ];
1123 }
1124 }
1125
1126 return $map;
1127 }
1128 }
1129
1130 if ( ! function_exists('easyel_theme_builder_child_options') ) {
1131 /**
1132 * Get global condition arrays: needs_child_sub & no_child_sub
1133 *
1134 * @return array
1135 */
1136 function easyel_theme_builder_child_options() {
1137 // Default needs_child_sub
1138 $needs_child_sub = [
1139 'author',
1140 'category',
1141 'child_of_category',
1142 'any_child_of_category',
1143 'in_category',
1144 'in_category_children',
1145 'post_tag',
1146 'in_post_tag',
1147 'child_of',
1148 'any_child_of',
1149 'product_cat',
1150 'product_tag',
1151 'product_brand',
1152 'post',
1153 'page',
1154 'page_by_author',
1155 ];
1156
1157 // Default no_child_sub
1158 $no_child_sub = [
1159 "all",
1160 "front_page",
1161 "not_found404",
1162 "index",
1163 "search",
1164 "date",
1165 "post_archive",
1166 "all_product_archive",
1167 "product_search",
1168 "shop_page",
1169 ];
1170
1171 // Get dynamic archive taxonomies
1172 $archive_taxonomies = function_exists('easyel_get_hierarchical_taxonomies_by_post_type')
1173 ? easyel_get_hierarchical_taxonomies_by_post_type()
1174 : [];
1175
1176 if ( is_array($archive_taxonomies) || is_object($archive_taxonomies) ) {
1177 foreach ($archive_taxonomies as $tax_slug => $data) {
1178 $needs_child_sub[] = $tax_slug;
1179 $needs_child_sub[] = 'child_of_' . $tax_slug;
1180 $needs_child_sub[] = 'any_child_of_' . $tax_slug;
1181
1182 $needs_child_sub[] = 'in_' . $tax_slug;
1183 $needs_child_sub[] = 'in_' . $tax_slug . '_children';
1184 $needs_child_sub[] = $data['post_type'] . '_by_author';
1185
1186 if ( ! empty($data['post_type']) ) {
1187 $no_child_sub[] = $data['post_type']."_archive";
1188 $needs_child_sub[] = $data['post_type'];
1189 }
1190 }
1191 }
1192
1193 return [
1194 'needs_child_sub' => $needs_child_sub,
1195 'no_child_sub' => $no_child_sub,
1196 ];
1197 }
1198 }
1199
1200 if ( ! function_exists( 'easyel_get_prepared_post_id' ) ) {
1201 function easyel_get_prepared_post_id() {
1202
1203 if ( is_singular( 'post' ) ) {
1204 return get_the_ID();
1205 }
1206
1207 $cache_key = 'easyel_latest_post_id';
1208 $post_id = wp_cache_get( $cache_key, 'easyel' );
1209
1210 if ( ! $post_id || get_post_status( $post_id ) !== 'publish' ) {
1211
1212 $latest_post = get_posts([
1213 'post_type' => 'post',
1214 'post_status' => 'publish',
1215 'posts_per_page' => 1,
1216 'orderby' => 'date',
1217 'order' => 'DESC',
1218 'fields' => 'ids',
1219 ]);
1220
1221 $post_id = !empty($latest_post) ? $latest_post[0] : 0;
1222
1223 wp_cache_set( $cache_key, $post_id, 'easyel', 12 * HOUR_IN_SECONDS );
1224 }
1225
1226 return $post_id;
1227 }
1228 }
1229
1230 add_action('template_redirect', function() {
1231 ob_start(function ($html) {
1232 if ( isset($GLOBALS['easyel_force_sticky_header']) && $GLOBALS['easyel_force_sticky_header'] === true ) {
1233 return preg_replace(
1234 '/(class=["\'][^"\']*easy-site-header[^"\']*)/i',
1235 '$1 eel-sticky-header-on',
1236 $html
1237 );
1238 }
1239 return $html;
1240 });
1241
1242 $GLOBALS['easyel_sticky_buffer_level'] = ob_get_level();
1243 });
1244
1245 add_action('shutdown', function() {
1246 if ( ! isset( $GLOBALS['easyel_sticky_buffer_level'] ) ) {
1247 return;
1248 }
1249
1250 $target = (int) $GLOBALS['easyel_sticky_buffer_level'];
1251 while ( ob_get_level() >= $target ) {
1252 if ( ! @ob_end_flush() ) {
1253 break;
1254 }
1255 }
1256 unset( $GLOBALS['easyel_sticky_buffer_level'] );
1257 }, 0);