PluginProbe
Easy Elements for Elementor – Addons & Website Templates / 1.5.0
Easy Elements for Elementor – Addons & Website Templates v1.5.0
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 1.5.0, at includes/helper-functions.php

1,232 lines 47.5 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 // Use the translation-free key list here: this filter runs on
564 // `plugins_loaded` (before `init`), so it must not call any
565 // translating helper such as easyel_get_extension_fields(), which
566 // would trigger the "_load_textdomain_just_in_time" notice.
567 foreach ( easyel_get_pro_extension_keys() as $key ) {
568 if ( isset( $value[ $key ] ) ) {
569 $value[ $key ] = 0;
570 }
571 }
572 return $value;
573 } );
574
575 if ( class_exists( '\\Easyel\\EasyElements\\Admin\\Admin_Settings' ) ) {
576 $instance = \Easyel\EasyElements\Admin\Admin_Settings::get_instance();
577 if ( method_exists( $instance, 'easyel_elements_get_available_widgets' ) ) {
578 foreach ( (array) $instance->easyel_elements_get_available_widgets() as $widget_key => $widget ) {
579 if ( ! empty( $widget['is_pro'] ) ) {
580 add_filter( 'option_easy_element_widget_' . $widget_key, '__return_zero' );
581 }
582 }
583 }
584 }
585 }
586 // Run before init_widgets (which fires on plugins_loaded default 10).
587 add_action( 'plugins_loaded', 'easyel_force_pro_options_off_when_inactive', 5 );
588 }
589
590 if ( ! function_exists( 'easyel_get_pro_clean_version' ) ) {
591 function easyel_get_pro_clean_version() {
592
593 if ( ! defined( 'EASYELEMENTS_PRO_FILE' ) ) {
594 return null;
595 }
596
597 if ( ! function_exists( 'get_file_data' ) ) {
598 require_once ABSPATH . 'wp-admin/includes/plugin.php';
599 }
600
601 $data = get_file_data(
602 EASYELEMENTS_PRO_FILE,
603 [ 'Version' => 'Version' ]
604 );
605
606 return $data['Version'] ?? null;
607 }
608 }
609
610 if ( ! function_exists( 'easyel_get_license_status' ) ) {
611
612 function easyel_get_license_status() {
613 return (string) apply_filters( 'easyel_license_status', 'invalid' );
614 }
615 }
616
617 if ( ! function_exists( 'easyel_get_license_activate_url' ) ) {
618
619 function easyel_get_license_activate_url() {
620 return (string) apply_filters( 'easyel_license_activate_url', '' );
621 }
622 }
623
624 if ( ! function_exists( 'easyel_enable_svg_upload' ) ) {
625 function easyel_enable_svg_upload( $mimes ) {
626 $mimes['svg'] = 'image/svg+xml';
627 $mimes['svgz'] = 'image/svg+xml';
628 return $mimes;
629 }
630 add_filter( 'upload_mimes', 'easyel_enable_svg_upload' );
631 }
632
633 if ( ! function_exists( 'easyel_fix_svg_filetype' ) ) {
634 function easyel_fix_svg_filetype( $data, $file, $filename, $mimes ) {
635 $ext = pathinfo( $filename, PATHINFO_EXTENSION );
636 if ( strtolower( $ext ) === 'svg' || strtolower( $ext ) === 'svgz' ) {
637 $data['ext'] = 'svg';
638 $data['type'] = 'image/svg+xml';
639 }
640 return $data;
641 }
642 add_filter( 'wp_check_filetype_and_ext', 'easyel_fix_svg_filetype', 10, 4 );
643 }
644
645 if ( ! function_exists( 'easyel_handle_sideload_svg' ) ) {
646 function easyel_handle_sideload_svg( $file ) {
647 $ext = pathinfo( $file['name'], PATHINFO_EXTENSION );
648 if ( strtolower( $ext ) === 'svg' || strtolower( $ext ) === 'svgz' ) {
649 $file['type'] = 'image/svg+xml';
650 }
651 return $file;
652 }
653
654 add_filter( 'wp_handle_sideload_prefilter', 'easyel_handle_sideload_svg' );
655 }
656
657 if ( ! function_exists( 'easyel_get_cf7_forms' ) ) {
658 /**
659 * Get a list of all CF7 forms
660 *
661 * @return array
662 */
663 function easyel_get_cf7_forms() {
664 $forms = get_posts( [
665 'post_type' => 'wpcf7_contact_form',
666 'post_status' => 'publish',
667 'posts_per_page' => -1,
668 'orderby' => 'title',
669 'order' => 'ASC',
670 ] );
671
672 if ( ! empty( $forms ) ) {
673 return wp_list_pluck( $forms, 'post_title', 'ID' );
674 }
675 return [];
676 }
677 }
678
679
680 // Domain Search Code
681 add_action('template_redirect', function(){
682 // phpcs:ignore WordPress.Security.NonceVerification.Missing
683 if (isset($_POST['easyel_domain_redirect'])) {
684 // phpcs:ignore WordPress.Security.NonceVerification.Missing
685 $domain = isset($_POST['domain']) ? sanitize_text_field(wp_unslash($_POST['domain'])) : '';
686 // phpcs:ignore WordPress.Security.NonceVerification.Missing
687 $base_url = isset($_POST['base_url']) ? esc_url_raw( wp_unslash($_POST['base_url'] ) ) : '';
688
689 if ( !empty($domain) && !empty($base_url) && filter_var($base_url, FILTER_VALIDATE_URL) ) {
690 $redirect_url = esc_url_raw($base_url . urlencode($domain));
691 wp_safe_redirect( $redirect_url );
692 exit;
693 }
694 }
695 });
696
697 function easyel_get_extension_fields() {
698 $fields = [
699 'enable_cursor' => [
700 'label' => __('Magic Cursor', 'easy-elements'),
701 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/magic-cursor.svg',
702 'is_pro' => true,
703 'group' => 'GSAP Extensions',
704 'demo_url' => 'https://wpeasyelements.com/docs/magic-cursor/',
705 'docs_url' => 'https://wpeasyelements.com/docs/magic-cursor/',
706 ],
707 'enable_sticky_elements' => [
708 'label' => __('Sticky Elements', 'easy-elements'),
709 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/sticky-elements.svg',
710 'is_pro' => true,
711 'group' => 'General Extensions',
712 'demo_url' => 'https://wpeasyelements.com/extensions/sticky-elements/',
713 'docs_url' => 'https://wpeasyelements.com/docs/sticky-elements/',
714 ],
715 'enable_cursor_hover_effect' => [
716 'label' => __('Cursor Hover Effect', 'easy-elements'),
717 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/cursor-hover-effect.svg',
718 'is_pro' => true,
719 'group' => 'GSAP Extensions',
720 'demo_url' => 'https://wpeasyelements.com/extensions/cursor-hover-effect/',
721 'docs_url' => 'https://wpeasyelements.com/docs/cursor-hover-effect/',
722 ],
723 'enable_cursor_move_effect' => [
724 'label' => __('Cursor Move Effect', 'easy-elements'),
725 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/cursor-move-effect.svg',
726 'is_pro' => true,
727 'group' => 'GSAP Extensions',
728 'demo_url' => 'https://wpeasyelements.com/extensions/cursor-move-effect/',
729 'docs_url' => 'https://wpeasyelements.com/docs/cursor-move-effect/',
730
731 ],
732 'enable_scroll_trigger' => [
733 'label' => __('ScrollTrigger', 'easy-elements'),
734 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/scrolltrigger.svg',
735 'is_pro' => true,
736 'group' => 'GSAP Extensions',
737 'demo_url' => 'https://wpeasyelements.com/extensions/scroll-trigger/',
738 'docs_url' => 'https://wpeasyelements.com/docs/scrolltrigger/',
739
740 ],
741 'enable_parallax_image' => [
742 'label' => __('Background Parallax', 'easy-elements'),
743 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/background-parallax.svg',
744 'is_pro' => true,
745 'group' => 'GSAP Extensions',
746 'demo_url' => 'https://wpeasyelements.com/extensions/background-parallax/',
747 'docs_url' => 'https://wpeasyelements.com/docs/background-parallax/',
748 ],
749 'enable_drawsvg' => [
750 'label' => __('DrawSVG', 'easy-elements'),
751 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/drawsvg.svg',
752 'is_pro' => true,
753 'upcoming' => true,
754 'group' => 'GSAP Extensions',
755 'demo_url' => '#',
756 'docs_url' => '#',
757 ],
758 'enable_image_3d_effect' => [
759 'label' => __('Image 3D Effect', 'easy-elements'),
760 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/image-3d-effect.svg',
761 'is_pro' => true,
762 'upcoming' => true,
763 'group' => 'GSAP Extensions',
764 'demo_url' => '#',
765 'docs_url' => '#',
766 ],
767 'enable_smooth_scroller' => [
768 'label' => __('Scroll Smoother', 'easy-elements'),
769 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/image-3d-effect.svg',
770 'is_pro' => true,
771 'setting' => true,
772 'group' => 'GSAP Extensions',
773 'demo_url' => 'https://wpeasyelements.com/',
774 'docs_url' => 'https://wpeasyelements.com/docs/scroll-smoother/',
775 ],
776 'enable_bounce_animation' => [
777 'label' => __('Bounce Animation', 'easy-elements'),
778 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/image-3d-effect.svg',
779 'is_pro' => true,
780 'group' => 'GSAP Extensions',
781 'demo_url' => 'https://wpeasyelements.com/extensions/bounce-animation/',
782 'docs_url' => 'https://wpeasyelements.com/docs/bounce-animation/',
783 ],
784 'enable_wrapper_link' => [
785 'label' => __('Wrapper Link', 'easy-elements'),
786 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/wrapper-link.svg',
787 'is_pro' => false,
788 'group' => 'General Extensions',
789 'demo_url' => 'https://wpeasyelements.com/extensions/wrapper-link/',
790 'docs_url' => 'https://wpeasyelements.com/docs/wrapper-link/',
791 ],
792 'enable_post_duplicator' => [
793 'label' => __('Duplicator', 'easy-elements'),
794 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/duplicator.svg',
795 'is_pro' => false,
796 'group' => 'General Extensions',
797 'demo_url' => 'https://wpeasyelements.com/docs/post-page-duplicate/',
798 'docs_url' => 'https://wpeasyelements.com/docs/post-page-duplicate/',
799 ],
800 'enable_postpage_export' => [
801 'label' => __('Easy Export', 'easy-elements'),
802 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/duplicator.svg',
803 'is_pro' => false,
804 'group' => 'General Extensions',
805 'demo_url' => 'https://wpeasyelements.com/extensions/docs/easy-export/',
806 'docs_url' => 'https://wpeasyelements.com/docs/easy-export/',
807 ],
808 'enable_visibility_control' => [
809 'label' => __('Visibility Control', 'easy-elements'),
810 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/visibility-control.svg',
811 'is_pro' => true,
812 'group' => 'General Extensions',
813 'demo_url' => 'https://wpeasyelements.com/extensions/visibility-control/',
814 'docs_url' => 'https://wpeasyelements.com/docs/visibility-control/',
815 ],
816 'enable_dynamic_content' => [
817 'label' => __('Dynamic Content', 'easy-elements'),
818 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/dynamic-content.svg',
819 'is_pro' => true,
820 'group' => 'General Extensions',
821 'demo_url' => 'https://wpeasyelements.com/extensions/dynamic-content/',
822 'docs_url' => 'https://wpeasyelements.com/docs/dynamic-content/',
823 ],
824 'enable_live_copy_paste' => [
825 'label' => __('Live Copy Paste', 'easy-elements'),
826 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/live-copy.svg',
827 'is_pro' => true,
828 'group' => 'General Extensions',
829 'demo_url' => 'https://wpeasyelements.com/extensions/live-copy/',
830 'docs_url' => 'https://wpeasyelements.com/docs/live-copy/',
831 ],
832 'enable_easy_custom_css' => [
833 'label' => __('Custom CSS', 'easy-elements'),
834 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/easy-custom-css.svg',
835 'is_pro' => true,
836 'group' => 'General Extensions',
837 'demo_url' => 'https://wpeasyelements.com/docs/custom-css/',
838 'docs_url' => 'https://wpeasyelements.com/docs/custom-css/',
839 ],
840 'enable_global_badge' => [
841 'label' => __('Global Badge', 'easy-elements'),
842 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/global-badge.svg',
843 'is_pro' => true,
844 'group' => 'General Extensions',
845 'demo_url' => 'https://wpeasyelements.com/extensions/global-badge/',
846 'docs_url' => 'https://wpeasyelements.com/docs/global-badge/',
847 ],
848 'enable_megamenu_builder' => [
849 'label' => __('Megamenu Builder', 'easy-elements'),
850 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/megamenu.svg',
851 'is_pro' => true,
852 'group' => 'General Extensions',
853 'demo_url' => 'https://wpeasyelements.com/megamenu-builder/',
854 'docs_url' => 'https://wpeasyelements.com/docs/megamenu-builder/',
855 ],
856 'enable_reading_progress_bar' => [
857 'label' => __('Reading Progress Bar', 'easy-elements'),
858 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/progressbar.svg',
859 'is_pro' => false,
860 'setting' => true,
861 'group' => 'General Extensions',
862 'demo_url' => 'https://wpeasyelements.com/reading-progress-bar/',
863 'docs_url' => 'https://wpeasyelements.com/docs/reading-progress-bar/',
864 ],
865 'enable_scroll_top' => [
866 'label' => __('Scroll Top', 'easy-elements'),
867 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/arrow-up.svg',
868 'is_pro' => false,
869 'setting' => true,
870 'group' => 'General Extensions',
871 'demo_url' => '',
872 'docs_url' => 'https://wpeasyelements.com/docs/scroll-to-top/',
873 ],
874 'enable_preloader' => [
875 'label' => __( 'Preloader', 'easy-elements' ),
876 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/loader.svg',
877 'is_pro' => false,
878 'setting' => true,
879 'group' => 'General Extensions',
880 'demo_url' => '',
881 'docs_url' => 'https://wpeasyelements.com/docs/preloader/',
882 ],
883 'enable_popup_builder' => [
884 'label' => __('Popup Builder', 'easy-elements'),
885 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/popup-builder.svg',
886 'is_pro' => true,
887 'setting' => true,
888 'group' => 'General Extensions',
889 'demo_url' => 'https://wpeasyelements.com/extensions/popup-builder/',
890 'docs_url' => 'https://wpeasyelements.com/docs/popup-builder/',
891 ],
892 'enable_quick_view' => [
893 'label' => __('Quick View', 'easy-elements'),
894 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/quickview.svg',
895 'is_pro' => true,
896 'setting' => true,
897 'group' => 'WooCommerce Extensions',
898 'demo_url' => 'https://wpeasyelements.com/shop/',
899 'docs_url' => 'https://wpeasyelements.com/docs/quick-view/',
900 ],
901 'enable_easyel_compare' => [
902 'label' => __('Compare', 'easy-elements'),
903 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/compare.svg',
904 'is_pro' => true,
905 'setting' => true,
906 'group' => 'WooCommerce Extensions',
907 'demo_url' => 'https://wpeasyelements.com/shop/',
908 'docs_url' => 'https://wpeasyelements.com/docs/compare/',
909 ],
910 'enable_easyel_wishlist' => [
911 'label' => __('Wishlist', 'easy-elements'),
912 'icon' => EASYELEMENTS_DIR_URL . 'includes/Admin/icons/extension/wishlist.svg',
913 'is_pro' => true,
914 'setting' => true,
915 'group' => 'WooCommerce Extensions',
916 'demo_url' => 'https://wpeasyelements.com/shop/',
917 'docs_url' => 'https://wpeasyelements.com/docs/wishlist/',
918 ],
919 ];
920
921 return apply_filters('easyel_extension_fields', $fields);
922 }
923
924 function easyel_sanitize_conditions_array( $conditions ) {
925 if ( ! is_array( $conditions ) ) {
926 return [];
927 }
928
929 $sanitized = [];
930 foreach ( $conditions as $cond ) {
931 if ( ! is_array( $cond ) ) continue;
932
933 $sanitized[] = [
934 'include' => isset($cond['include']) ? sanitize_text_field($cond['include']) : 'include',
935 'main' => isset($cond['main']) ? sanitize_text_field($cond['main']) : '',
936 'sub' => isset($cond['sub']) ? sanitize_text_field($cond['sub']) : '',
937 'child_sub' => isset($cond['child_sub']) ? sanitize_text_field($cond['child_sub']) : '',
938 ];
939 }
940
941 return $sanitized;
942 }
943
944 /**
945 * Safely decode JSON or return array as-is
946 */
947 function easyel_safe_json_decode( $data ) {
948 if ( is_string($data) ) {
949 $decoded = json_decode($data, true);
950 if ( json_last_error() === JSON_ERROR_NONE && is_array($decoded) ) {
951 return $decoded;
952 }
953 return [];
954 } elseif ( is_array($data) ) {
955 return $data;
956 } else {
957 return [];
958 }
959 }
960
961 class Easyel_Widget_Injection {
962 public static function init() {
963 add_filter( 'elementor/controls/animations/additional_animations', [ __CLASS__, 'inject_easy_animations' ] );
964 }
965
966 public static function inject_easy_animations( $animations ) {
967 $animations['Easy Animations'] = [
968 'scaleIn' => __( 'Scale In', 'easy-elements' ),
969 ];
970 return $animations;
971 }
972 }
973
974 // Initialize the class
975 Easyel_Widget_Injection::init();
976
977
978 /**
979 * Check if a specific Easy Element extension setting is enabled.
980 *
981 * @param string $setting_key The key of the setting to check (e.g. 'enable_sticky_elements').
982 * @return bool True if enabled, false otherwise.
983 */
984 function easyel_element_is_enabled( $setting_key ) {
985 if ( empty( $setting_key ) ) {
986 return false;
987 }
988
989 $tab_slug = 'extensions';
990 $settings = get_option( 'easy_element_' . $tab_slug, [] );
991
992 // Sanitize and check
993 $value = isset( $settings[ $setting_key ] ) ? (int) $settings[ $setting_key ] : 0;
994
995 return ( $value === 1 );
996 }
997
998 /**
999 * Backward compatibility alias.
1000 *
1001 * The non-prefixed function name is retained only for compatibility with
1002 * previously released Easy Elements Pro versions. Removing this function
1003 * would break existing installations that still reference
1004 * `easy_element_is_enabled()` and could result in fatal errors.
1005 *
1006 * New code should use `easyel_element_is_enabled()` instead.
1007 */
1008 if ( ! function_exists( 'easy_element_is_enabled' ) ) {
1009 function easy_element_is_enabled( $setting_key ) {
1010 return easyel_element_is_enabled( $setting_key );
1011 }
1012 }
1013
1014
1015 function easyel_translate_hfe_template( $template_id ) {
1016 if ( function_exists( 'pll_get_post' ) ) {
1017 $translated = pll_get_post( $template_id );
1018 if ( $translated ) {
1019 $template_id = $translated;
1020 }
1021 }
1022 if ( has_filter( 'wpml_object_id' ) ) {
1023
1024 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
1025 $translated = apply_filters( 'wpml_object_id', $template_id, 'ee-elementor-hf', true );
1026 if ( $translated ) {
1027 $template_id = $translated;
1028 }
1029 }
1030 return $template_id;
1031 }
1032
1033 add_filter( 'easyel_get_settings_type_header', 'easyel_translate_hfe_template' );
1034 add_filter( 'easyel_get_settings_type_footer', 'easyel_translate_hfe_template' );
1035 add_filter( 'easyel_get_settings_type_easy_topbar', 'easyel_translate_hfe_template' );
1036 add_filter( 'easyel_get_settings_type_easy_after__header', 'easyel_translate_hfe_template' );
1037 add_filter( 'easyel_get_settings_type_before_footer', 'easyel_translate_hfe_template' );
1038
1039 if ( ! function_exists( 'easyel_get_valid_archive_post_types' ) ) {
1040 function easyel_get_valid_archive_post_types() {
1041
1042 $post_types = get_post_types(
1043 [
1044 'public' => true,
1045 'show_in_nav_menus' => true,
1046 ],
1047 'objects'
1048 );
1049
1050 $valid = [];
1051
1052 foreach ( $post_types as $post_type => $pt ) {
1053
1054 if ( ! $pt->has_archive || ! get_post_type_archive_link( $post_type ) ) {
1055 continue;
1056 }
1057
1058 if ( $post_type === 'page' ) {
1059 continue;
1060 }
1061
1062 if (
1063 ! empty( $pt->_builtin ) === false &&
1064 str_starts_with( $post_type, 'elementor' )
1065 ) {
1066 continue;
1067 }
1068
1069 if ( ! $pt->publicly_queryable ) {
1070 continue;
1071 }
1072
1073 $valid[ $post_type ] = $pt;
1074 }
1075
1076 return $valid;
1077 }
1078 }
1079
1080 if ( ! function_exists( 'easyel_get_hierarchical_taxonomies_by_post_type' ) ) {
1081 function easyel_get_hierarchical_taxonomies_by_post_type() {
1082
1083 $map = [];
1084 $post_types = easyel_get_valid_archive_post_types();
1085
1086 foreach ($post_types as $post_type => $pt) {
1087 $taxonomies = get_object_taxonomies($post_type, 'objects');
1088
1089 foreach ($taxonomies as $tax_slug => $tax) {
1090 if (!$tax->public) {
1091 continue;
1092 }
1093
1094 $map[$tax_slug] = [
1095 'post_type' => $post_type,
1096 'taxonomy' => $tax_slug,
1097 ];
1098 }
1099 }
1100
1101 return $map;
1102 }
1103 }
1104
1105 if ( ! function_exists('easyel_theme_builder_child_options') ) {
1106 /**
1107 * Get global condition arrays: needs_child_sub & no_child_sub
1108 *
1109 * @return array
1110 */
1111 function easyel_theme_builder_child_options() {
1112 // Default needs_child_sub
1113 $needs_child_sub = [
1114 'author',
1115 'category',
1116 'child_of_category',
1117 'any_child_of_category',
1118 'in_category',
1119 'in_category_children',
1120 'post_tag',
1121 'in_post_tag',
1122 'child_of',
1123 'any_child_of',
1124 'product_cat',
1125 'product_tag',
1126 'product_brand',
1127 'post',
1128 'page',
1129 'page_by_author',
1130 ];
1131
1132 // Default no_child_sub
1133 $no_child_sub = [
1134 "all",
1135 "front_page",
1136 "not_found404",
1137 "index",
1138 "search",
1139 "date",
1140 "post_archive",
1141 "all_product_archive",
1142 "product_search",
1143 "shop_page",
1144 ];
1145
1146 // Get dynamic archive taxonomies
1147 $archive_taxonomies = function_exists('easyel_get_hierarchical_taxonomies_by_post_type')
1148 ? easyel_get_hierarchical_taxonomies_by_post_type()
1149 : [];
1150
1151 if ( is_array($archive_taxonomies) || is_object($archive_taxonomies) ) {
1152 foreach ($archive_taxonomies as $tax_slug => $data) {
1153 $needs_child_sub[] = $tax_slug;
1154 $needs_child_sub[] = 'child_of_' . $tax_slug;
1155 $needs_child_sub[] = 'any_child_of_' . $tax_slug;
1156
1157 $needs_child_sub[] = 'in_' . $tax_slug;
1158 $needs_child_sub[] = 'in_' . $tax_slug . '_children';
1159 $needs_child_sub[] = $data['post_type'] . '_by_author';
1160
1161 if ( ! empty($data['post_type']) ) {
1162 $no_child_sub[] = $data['post_type']."_archive";
1163 $needs_child_sub[] = $data['post_type'];
1164 }
1165 }
1166 }
1167
1168 return [
1169 'needs_child_sub' => $needs_child_sub,
1170 'no_child_sub' => $no_child_sub,
1171 ];
1172 }
1173 }
1174
1175 if ( ! function_exists( 'easyel_get_prepared_post_id' ) ) {
1176 function easyel_get_prepared_post_id() {
1177
1178 if ( is_singular( 'post' ) ) {
1179 return get_the_ID();
1180 }
1181
1182 $cache_key = 'easyel_latest_post_id';
1183 $post_id = wp_cache_get( $cache_key, 'easyel' );
1184
1185 if ( ! $post_id || get_post_status( $post_id ) !== 'publish' ) {
1186
1187 $latest_post = get_posts([
1188 'post_type' => 'post',
1189 'post_status' => 'publish',
1190 'posts_per_page' => 1,
1191 'orderby' => 'date',
1192 'order' => 'DESC',
1193 'fields' => 'ids',
1194 ]);
1195
1196 $post_id = !empty($latest_post) ? $latest_post[0] : 0;
1197
1198 wp_cache_set( $cache_key, $post_id, 'easyel', 12 * HOUR_IN_SECONDS );
1199 }
1200
1201 return $post_id;
1202 }
1203 }
1204
1205 add_action('template_redirect', function() {
1206 ob_start(function ($html) {
1207 if ( isset($GLOBALS['easyel_force_sticky_header']) && $GLOBALS['easyel_force_sticky_header'] === true ) {
1208 return preg_replace(
1209 '/(class=["\'][^"\']*easy-site-header[^"\']*)/i',
1210 '$1 eel-sticky-header-on',
1211 $html
1212 );
1213 }
1214 return $html;
1215 });
1216
1217 $GLOBALS['easyel_sticky_buffer_level'] = ob_get_level();
1218 });
1219
1220 add_action('shutdown', function() {
1221 if ( ! isset( $GLOBALS['easyel_sticky_buffer_level'] ) ) {
1222 return;
1223 }
1224
1225 $target = (int) $GLOBALS['easyel_sticky_buffer_level'];
1226 while ( ob_get_level() >= $target ) {
1227 if ( ! @ob_end_flush() ) {
1228 break;
1229 }
1230 }
1231 unset( $GLOBALS['easyel_sticky_buffer_level'] );
1232 }, 0);