PluginProbe
Elementor Website Builder – more than just a page builder / 3.7.3
Elementor Website Builder – more than just a page builder v3.7.3
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
← All changes | includes/utils.php +47 -249 4.1.13.7.3 View file →
@@ -1,8 +1,7 @@
1 1 <?php
2 2 namespace Elementor;
3 3
4 -use Elementor\Core\Files\Fonts\Google_Font;
5 4 use Elementor\Core\Utils\Collection;
6 5
7 6 if ( ! defined( 'ABSPATH' ) ) {
8 7 exit; // Exit if accessed directly.
@@ -22,9 +21,9 @@
22 21
23 22 const EDITOR_BREAK_LINES_OPTION_KEY = 'elementor_editor_break_lines';
24 23
25 24 /**
26 - * A list of safe tags for `validate_html_tag` method.
25 + * A list of safe tage for `validate_html_tag` method.
27 26 */
28 27 const ALLOWED_HTML_WRAPPER_TAGS = [
29 28 'a',
30 29 'article',
@@ -29,9 +28,8 @@
29 28 'a',
30 29 'article',
31 30 'aside',
32 31 'button',
33 - 'form',
34 32 'div',
35 33 'footer',
36 34 'h1',
37 35 'h2',
@@ -92,27 +90,10 @@
92 90 ],
93 91 ];
94 92
95 93 /**
96 - * Variables for free to pro upsale modal promotions
97 - */
98 -
99 - const ANIMATED_HEADLINE = 'animated_headline';
100 -
101 - const CTA = 'cta';
102 -
103 - const VIDEO_PLAYLIST = 'video_playlist';
104 -
105 - const TESTIMONIAL_WIDGET = 'testimonial_widget';
106 -
107 - const IMAGE_CAROUSEL = 'image_carousel';
108 -
109 - /**
110 - * Whether WordPress CLI mode is enabled or not.
94 + * Is WP CLI.
111 95 *
112 - * @access public
113 - * @static
114 - *
115 96 * @return bool
116 97 */
117 98 public static function is_wp_cli() {
118 99 return defined( 'WP_CLI' ) && WP_CLI;
@@ -118,8 +99,10 @@
118 99 return defined( 'WP_CLI' ) && WP_CLI;
119 100 }
120 101
121 102 /**
103 + * Is script debug.
104 + *
122 105 * Whether script debug is enabled or not.
123 106 *
124 107 * @since 1.0.0
125 108 * @access public
@@ -124,9 +107,9 @@
124 107 * @since 1.0.0
125 108 * @access public
126 109 * @static
127 110 *
128 - * @return bool
111 + * @return bool True if it's a script debug is active, false otherwise.
129 112 */
130 113 public static function is_script_debug() {
131 114 return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG;
132 115 }
@@ -131,32 +114,8 @@
131 114 return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG;
132 115 }
133 116
134 117 /**
135 - * Whether Elementor debug is enabled or not.
136 - *
137 - * @access public
138 - * @static
139 - *
140 - * @return bool
141 - */
142 - public static function is_elementor_debug() {
143 - return defined( 'ELEMENTOR_DEBUG' ) && ELEMENTOR_DEBUG;
144 - }
145 -
146 - /**
147 - * Whether Elementor test mode is enabled or not.
148 - *
149 - * @access public
150 - * @static
151 - *
152 - * @return bool
153 - */
154 - public static function is_elementor_tests() {
155 - return defined( 'ELEMENTOR_TESTS' ) && ELEMENTOR_TESTS;
156 - }
157 -
158 - /**
159 118 * Get pro link.
160 119 *
161 120 * Retrieve the link to Elementor Pro.
162 121 *
@@ -195,54 +154,38 @@
195 154 * @since 2.1.0
196 155 * @static
197 156 * @access public
198 157 *
199 - * @param string $from
200 - * @param string $to
158 + * @param $from
159 + * @param $to
201 160 *
202 161 * @return string
203 - * @throws \Exception If URLs are missing or invalid URLs provided.
162 + * @throws \Exception
204 163 */
205 164 public static function replace_urls( $from, $to ) {
206 165 $from = trim( $from );
207 166 $to = trim( $to );
208 167
209 - if ( empty( $from ) ) {
210 - throw new \Exception( 'Couldn’t replace your address because the old URL was not provided. Try again by entering the old URL.' );
211 - }
212 -
213 - if ( empty( $to ) ) {
214 - throw new \Exception( 'Couldn’t replace your address because the new URL was not provided. Try again by entering the new URL.' );
215 - }
216 -
217 168 if ( $from === $to ) {
218 - throw new \Exception( 'Couldn’t replace your address because both of the URLs provided are identical. Try again by entering different URLs.' );
169 + throw new \Exception( esc_html__( 'The `from` and `to` URL\'s must be different', 'elementor' ) );
219 170 }
220 171
221 172 $is_valid_urls = ( filter_var( $from, FILTER_VALIDATE_URL ) && filter_var( $to, FILTER_VALIDATE_URL ) );
222 -
223 173 if ( ! $is_valid_urls ) {
224 - throw new \Exception( 'Couldn’t replace your address because at least one of the URLs provided are invalid. Try again by entering valid URLs.' );
174 + throw new \Exception( esc_html__( 'The `from` and `to` URL\'s must be valid URL\'s', 'elementor' ) );
225 175 }
226 176
227 177 global $wpdb;
228 - $escaped_from = str_replace( '/', '\\/', $from );
229 - $escaped_to = str_replace( '/', '\\/', $to );
230 - $meta_value_like = '[%'; // meta_value LIKE '[%' are json formatted
231 178
179 + // @codingStandardsIgnoreStart cannot use `$wpdb->prepare` because it remove's the backslashes
232 180 $rows_affected = $wpdb->query(
233 - $wpdb->prepare(
234 - "UPDATE {$wpdb->postmeta} " .
235 - 'SET `meta_value` = REPLACE(`meta_value`, %s, %s) ' .
236 - "WHERE `meta_key` = '_elementor_data' AND `meta_value` LIKE %s;",
237 - $escaped_from,
238 - $escaped_to,
239 - $meta_value_like
240 - )
241 - );
181 + "UPDATE {$wpdb->postmeta} " .
182 + "SET `meta_value` = REPLACE(`meta_value`, '" . str_replace( '/', '\\\/', $from ) . "', '" . str_replace( '/', '\\\/', $to ) . "') " .
183 + "WHERE `meta_key` = '_elementor_data' AND `meta_value` LIKE '[%' ;" ); // meta_value LIKE '[%' are json formatted
184 + // @codingStandardsIgnoreEnd
242 185
243 186 if ( false === $rows_affected ) {
244 - throw new \Exception( 'An error occurred while replacing URL\'s.' );
187 + throw new \Exception( esc_html__( 'An error occurred', 'elementor' ) );
245 188 }
246 189
247 190 // Allow externals to replace-urls, when they have to.
248 191 $rows_affected += (int) apply_filters( 'elementor/tools/replace-urls', 0, $from, $to );
@@ -247,13 +190,12 @@
247 190 // Allow externals to replace-urls, when they have to.
248 191 $rows_affected += (int) apply_filters( 'elementor/tools/replace-urls', 0, $from, $to );
249 192
250 193 Plugin::$instance->files_manager->clear_cache();
251 - Google_Font::clear_cache();
252 194
253 195 return sprintf(
254 196 /* translators: %d: Number of rows. */
255 - _n( '%d database row affected.', '%d database rows affected.', $rows_affected, 'elementor' ),
197 + _n( '%d row affected.', '%d rows affected.', $rows_affected, 'elementor' ),
256 198 $rows_affected
257 199 );
258 200 }
259 201
@@ -280,9 +222,9 @@
280 222 *
281 223 * Filters whether the post type supports editing with Elementor.
282 224 *
283 225 * @since 1.0.0
284 - * @deprecated 2.2.0 Use `elementor/utils/is_post_support` hook Instead.
226 + * @deprecated 2.2.0 Use `elementor/utils/is_post_support` Instead
285 227 *
286 228 * @param bool $is_supported Whether the post type supports editing with Elementor.
287 229 * @param int $post_id Post ID.
288 230 * @param string $post_type Post type.
@@ -399,10 +341,10 @@
399 341 if ( ! defined( 'DONOTCDN' ) ) {
400 342 define( 'DONOTCDN', true );
401 343 }
402 344
403 - if ( ! defined( 'DONOTCACHEOBJECT' ) ) {
404 - define( 'DONOTCACHEOBJECT', true );
345 + if ( ! defined( 'DONOTCACHCEOBJECT' ) ) {
346 + define( 'DONOTCACHCEOBJECT', true );
405 347 }
406 348
407 349 // Set the headers to prevent caching for the different browsers.
408 350 nocache_headers();
@@ -441,12 +383,12 @@
441 383 * Retrieve a custom URL for creating a new post/page using Elementor.
442 384 *
443 385 * @since 1.9.0
444 386 * @access public
445 - * @deprecated 3.3.0 Use `Plugin::$instance->documents->get_create_new_post_url()` instead.
387 + * @deprecated 3.3.0
446 388 * @static
447 389 *
448 - * @param string $post_type Optional. Post type slug. Default is 'page'.
390 + * @param string $post_type Optional. Post type slug. Default is 'page'.
449 391 * @param string|null $template_type Optional. Query arg 'template_type'. Default is null.
450 392 *
451 393 * @return string A URL for creating new post using Elementor.
452 394 */
@@ -513,14 +455,14 @@
513 455 * @since 2.1.2
514 456 * @access public
515 457 * @static
516 458 */
517 - public static function array_inject( $base_array, $key, $insert ) {
518 - $length = array_search( $key, array_keys( $base_array ), true ) + 1;
459 + public static function array_inject( $array, $key, $insert ) {
460 + $length = array_search( $key, array_keys( $array ), true ) + 1;
519 461
520 - return array_slice( $base_array, 0, $length, true ) +
462 + return array_slice( $array, 0, $length, true ) +
521 463 $insert +
522 - array_slice( $base_array, $length, null, true );
464 + array_slice( $array, $length, null, true );
523 465 }
524 466
525 467 /**
526 468 * Render html attributes
@@ -564,9 +506,9 @@
564 506 * Viewport meta tag.
565 507 *
566 508 * Filters the meta tag containing the viewport information.
567 509 *
568 - * This hook can be used to change the initial viewport meta tag set by Elementor
510 + * This hook can be used to change the intial viewport meta tag set by Elementor
569 511 * and replace it with a different viewport tag.
570 512 *
571 513 * @since 2.5.0
572 514 *
@@ -581,12 +523,11 @@
581 523 /**
582 524 * Add Elementor Config js vars to the relevant script handle,
583 525 * WP will wrap it with <script> tag.
584 526 * To make sure this script runs thru the `script_loader_tag` hook, use a known handle value.
585 - *
586 527 * @param string $handle
587 528 * @param string $js_var
588 - * @param mixed $config
529 + * @param mixed $config
589 530 */
590 531 public static function print_js_config( $handle, $js_var, $config ) {
591 532 $config = wp_json_encode( $config );
592 533
@@ -616,9 +557,9 @@
616 557
617 558 /**
618 559 * Checks a control value for being empty, including a string of '0' not covered by PHP's empty().
619 560 *
620 - * @param mixed $source
561 + * @param mixed $source
621 562 * @param bool|string $key
622 563 *
623 564 * @return bool
624 565 */
@@ -637,30 +578,15 @@
637 578 public static function has_pro() {
638 579 return defined( 'ELEMENTOR_PRO_VERSION' );
639 580 }
640 581
641 - public static function is_pro_installed_and_not_active(): bool {
642 - if ( ! function_exists( 'get_plugins' ) ) {
643 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
644 - }
645 -
646 - $file_path = self::get_elementor_pro_file_path();
647 - $installed_plugins = get_plugins();
648 -
649 - return isset( $installed_plugins[ $file_path ] );
650 - }
651 -
652 - private static function get_elementor_pro_file_path(): string {
653 - return 'elementor-pro/elementor-pro.php';
654 - }
655 -
656 582 /**
657 583 * Convert HTMLEntities to UTF-8 characters
658 584 *
659 - * @param string $html_string
585 + * @param $string
660 586 * @return string
661 587 */
662 - public static function urlencode_html_entities( $html_string ) {
588 + public static function urlencode_html_entities( $string ) {
663 589 $entities_dictionary = [
664 590 '&#145;' => "'", // Opening single quote
665 591 '&#146;' => "'", // Closing single quote
666 592 '&#147;' => '"', // Closing double quote
@@ -673,11 +599,11 @@
673 599 '&#8222;' => '"', // Double low quote
674 600 ];
675 601
676 602 // Decode decimal entities
677 - $html_string = str_replace( array_keys( $entities_dictionary ), array_values( $entities_dictionary ), $html_string );
603 + $string = str_replace( array_keys( $entities_dictionary ), array_values( $entities_dictionary ), $string );
678 604
679 - return rawurlencode( html_entity_decode( $html_string, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) );
605 + return rawurlencode( html_entity_decode( $string, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) );
680 606 }
681 607
682 608 /**
683 609 * Parse attributes that come as a string of comma-delimited key|value pairs.
@@ -729,19 +655,13 @@
729 655 if ( $id === $element['id'] ) {
730 656 return $element;
731 657 }
732 658
733 - $inner_elements = apply_filters(
734 - 'elementor/utils/find_element_recursive/inner_elements',
735 - $element['elements'] ?? [],
736 - $element
737 - );
659 + if ( ! empty( $element['elements'] ) ) {
660 + $element = self::find_element_recursive( $element['elements'], $id );
738 661
739 - if ( ! empty( $inner_elements ) ) {
740 - $found = self::find_element_recursive( $inner_elements, $id );
741 -
742 - if ( $found ) {
743 - return $found;
662 + if ( $element ) {
663 + return $element;
744 664 }
745 665 }
746 666 }
747 667
@@ -756,10 +676,10 @@
756 676 * Fired by `admin_menu` action.
757 677 *
758 678 * @since 3.1.0
759 679 *
760 - * @param string $menu_slug
761 - * @param string $new_label
680 + * @param $menu_slug
681 + * @param $new_label
762 682 * @access public
763 683 */
764 684 public static function change_submenu_first_item_label( $menu_slug, $new_label ) {
765 685 global $submenu;
@@ -778,9 +698,9 @@
778 698 *
779 699 * @return string
780 700 */
781 701 public static function validate_html_tag( $tag ) {
782 - return $tag && in_array( strtolower( $tag ), self::ALLOWED_HTML_WRAPPER_TAGS ) ? $tag : 'div';
702 + return in_array( strtolower( $tag ), self::ALLOWED_HTML_WRAPPER_TAGS ) ? $tag : 'div';
783 703 }
784 704
785 705 /**
786 706 * Safe print a validated HTML tag.
@@ -794,10 +714,10 @@
794 714
795 715 /**
796 716 * Print internal content (not user input) without escaping.
797 717 */
798 - public static function print_unescaped_internal_string( $internal_string ) {
799 - echo $internal_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
718 + public static function print_unescaped_internal_string( $string ) {
719 + echo $string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
800 720 }
801 721
802 722 /**
803 723 * Get recently edited posts query.
@@ -822,9 +742,9 @@
822 742
823 743 return new \WP_Query( $args );
824 744 }
825 745
826 - public static function print_wp_kses_extended( $text, array $tags ) {
746 + public static function print_wp_kses_extended( $string, array $tags ) {
827 747 $allowed_html = wp_kses_allowed_html( 'post' );
828 748
829 749 foreach ( $tags as $tag ) {
830 750 if ( isset( self::EXTENDED_ALLOWED_HTML_TAGS[ $tag ] ) ) {
@@ -832,9 +752,9 @@
832 752 $allowed_html = array_replace_recursive( $allowed_html, $extended_tags );
833 753 }
834 754 }
835 755
836 - echo wp_kses( $text, $allowed_html );
756 + echo wp_kses( $string, $allowed_html );
837 757 }
838 758
839 759 public static function is_elementor_path( $path ) {
840 760 $path = wp_normalize_path( $path );
@@ -858,10 +778,10 @@
858 778 } );
859 779 }
860 780
861 781 /**
862 - * @param string $file
863 - * @param mixed ...$args
782 + * @param $file
783 + * @param mixed ...$args
864 784 * @return false|string
865 785 */
866 786 public static function file_get_contents( $file, ...$args ) {
867 787 if ( ! is_file( $file ) || ! is_readable( $file ) ) {
@@ -866,130 +786,8 @@
866 786 public static function file_get_contents( $file, ...$args ) {
867 787 if ( ! is_file( $file ) || ! is_readable( $file ) ) {
868 788 return false;
869 789 }
790 +
870 791 return file_get_contents( $file, ...$args );
871 - }
872 -
873 - public static function get_super_global_value( $super_global, $key ) {
874 - if ( ! isset( $super_global[ $key ] ) ) {
875 - return null;
876 - }
877 -
878 - if ( $_FILES === $super_global ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
879 - return isset( $super_global[ $key ]['name'] ) ?
880 - self::sanitize_file_name( $super_global[ $key ] ) :
881 - self::sanitize_multi_upload( $super_global[ $key ] );
882 - }
883 -
884 - return wp_kses_post_deep( wp_unslash( $super_global[ $key ] ) );
885 - }
886 -
887 - private static function sanitize_multi_upload( $fields ) {
888 - return array_map( function( $field ) {
889 - return array_map( 'self::sanitize_file_name', $field );
890 - }, $fields );
891 - }
892 -
893 - private static function sanitize_file_name( $file ) {
894 - $file['name'] = sanitize_file_name( $file['name'] );
895 -
896 - return $file;
897 - }
898 -
899 - /**
900 - * Return specific object property value if exist from array of keys.
901 - *
902 - * @param array $base_array
903 - * @param array $keys
904 - * @return mixed|null
905 - */
906 - public static function get_array_value_by_keys( $base_array, $keys ) {
907 - $keys = (array) $keys;
908 - foreach ( $keys as $key ) {
909 - if ( ! isset( $base_array[ $key ] ) ) {
910 - return null;
911 - }
912 - $base_array = $base_array[ $key ];
913 - }
914 - return $base_array;
915 - }
916 -
917 - public static function get_cached_callback( $callback, $cache_key, $cache_time = 24 * HOUR_IN_SECONDS ) {
918 - $cache = get_site_transient( $cache_key );
919 -
920 - if ( ! $cache ) {
921 - $cache = call_user_func( $callback );
922 -
923 - if ( ! is_wp_error( $cache ) ) {
924 - set_site_transient( $cache_key, $cache, $cache_time );
925 - }
926 - }
927 -
928 - return $cache;
929 - }
930 -
931 - public static function is_sale_time(): bool {
932 - $sale_start_time = gmmktime( 12, 0, 0, 11, 25, 2025 );
933 - $sale_end_time = gmmktime( 3, 59, 0, 12, 3, 2025 );
934 -
935 - $now_time = gmdate( 'U' );
936 -
937 - return $now_time >= $sale_start_time && $now_time <= $sale_end_time;
938 - }
939 -
940 - public static function safe_throw( string $message ) {
941 - if ( ! static::is_elementor_debug() ) {
942 - return;
943 - }
944 -
945 - throw new \Exception( esc_html( $message ) );
946 - }
947 -
948 - public static function has_invalid_post_permissions( $post ): bool {
949 - $is_image_attachment = 'attachment' === $post->post_type && strpos( $post->post_mime_type, 'image/' ) === 0;
950 -
951 - if ( $is_image_attachment ) {
952 - return false;
953 - }
954 -
955 - $is_private = 'private' === $post->post_status
956 - && ! current_user_can( 'read_private_posts', $post->ID );
957 -
958 - $not_allowed = 'publish' !== $post->post_status
959 - && ! current_user_can( 'edit_post', $post->ID );
960 -
961 - $password_required = post_password_required( $post->ID )
962 - && ! current_user_can( 'edit_post', $post->ID );
963 -
964 - return $is_private || $not_allowed || $password_required;
965 - }
966 -
967 - public static function is_custom_kit_applied() {
968 - return (bool) Plugin::$instance->kits_manager->get_previous_id();
969 - }
970 -
971 - public static function decode_string( string $encoded_string, ?string $fallback = '' ) {
972 - try {
973 - return base64_decode( $encoded_string, true ) ?? $fallback;
974 - } catch ( \Exception $e ) {
975 - return $fallback;
976 - }
977 - }
978 -
979 - public static function encode_string( string $decoded_string ): string {
980 - return base64_encode( $decoded_string );
981 - }
982 -
983 - public static function html_to_plain_text( string $html ): string {
984 - if ( empty( $html ) ) {
985 - return '';
986 - }
987 -
988 - $text = preg_replace( '#<br\s*/?\s*>#i', ' ', $html );
989 - $text = preg_replace( '#</?[a-z][^>]*>#i', ' ', $text );
990 - $text = html_entity_decode( $text, ENT_QUOTES, 'UTF-8' );
991 - $text = str_replace( "\xE2\x80\x8B", '', $text );
992 -
993 - return trim( preg_replace( '/\s+/', ' ', $text ) );
994 792 }
995 793 }