ed after this filter runs and cannot be re-added,
* to prevent XSS via a wrapper tag that executes script or embeds external content.
*
* @since 4.4.0
*
* @param string[] $tags A list of lowercase HTML tag name strings.
*/
$tags = apply_filters( 'elementor/allowed_html_wrapper_tags', self::ALLOWED_HTML_WRAPPER_TAGS );
self::$resolved_allowed_html_wrapper_tags = self::normalize_allowed_html_wrapper_tags( $tags );
return self::$resolved_allowed_html_wrapper_tags;
}
/**
* Validate an HTML tag against a safe allowed list.
*
* @param string $tag
*
* @return string
*/
public static function validate_html_tag( $tag ) {
return $tag && in_array( strtolower( $tag ), self::get_allowed_html_wrapper_tags(), true ) ? $tag : 'div';
}
/**
* @param array $tags
*
* @return string[]
*/
private static function normalize_allowed_html_wrapper_tags( array $tags ): array {
$normalized_tags = [];
foreach ( $tags as $tag ) {
if ( ! is_string( $tag ) ) {
continue;
}
$tag = strtolower( $tag );
if ( in_array( $tag, self::FORBIDDEN_HTML_WRAPPER_TAGS, true ) ) {
continue;
}
$normalized_tags[] = $tag;
}
return array_values( array_unique( $normalized_tags ) );
}
/**
* Safe print a validated HTML tag.
*
* @param string $tag
*/
public static function print_validated_html_tag( $tag ) {
// PHPCS - the method validate_html_tag is safe.
echo self::validate_html_tag( $tag ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Print internal content (not user input) without escaping.
*/
public static function print_unescaped_internal_string( $internal_string ) {
echo $internal_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Get recently edited posts query.
*
* Returns `WP_Query` of the recent edited posts.
* By default max posts ( $args['posts_per_page'] ) is 3.
*
* @param array $args
*
* @return \WP_Query
*/
public static function get_recently_edited_posts_query( $args = [] ) {
$args = wp_parse_args( $args, [
'no_found_rows' => true,
'post_type' => 'any',
'post_status' => [ 'publish', 'draft' ],
'posts_per_page' => '3',
'meta_key' => '_elementor_edit_mode',
'meta_value' => 'builder',
'orderby' => 'modified',
] );
return new \WP_Query( $args );
}
public static function print_wp_kses_extended( $text, array $tags ) {
$allowed_html = wp_kses_allowed_html( 'post' );
foreach ( $tags as $tag ) {
if ( isset( self::EXTENDED_ALLOWED_HTML_TAGS[ $tag ] ) ) {
$extended_tags = apply_filters( "elementor/extended_allowed_html_tags/{$tag}", self::EXTENDED_ALLOWED_HTML_TAGS[ $tag ] );
$allowed_html = array_replace_recursive( $allowed_html, $extended_tags );
}
}
echo wp_kses( $text, $allowed_html );
}
public static function kses_post_deep( $data ) {
return map_deep( $data, function ( $value ) {
return is_string( $value ) ? wp_kses_post( $value ) : $value;
} );
}
public static function is_elementor_path( $path ) {
$path = wp_normalize_path( $path );
/**
* Elementor related paths.
*
* Filters Elementor related paths.
*
* @param string[] $available_paths
*/
$available_paths = apply_filters( 'elementor/utils/elementor_related_paths', [ ELEMENTOR_PATH ] );
return (bool) ( new Collection( $available_paths ) )
->map( function ( $p ) {
// `untrailingslashit` in order to include other plugins prefixed with elementor.
return untrailingslashit( wp_normalize_path( $p ) );
} )
->find(function ( $p ) use ( $path ) {
return false !== strpos( $path, $p );
} );
}
/**
* @param string $file
* @param mixed ...$args
* @return false|string
*/
public static function file_get_contents( $file, ...$args ) {
if ( ! is_file( $file ) || ! is_readable( $file ) ) {
return false;
}
return file_get_contents( $file, ...$args );
}
public static function get_super_global_value( $super_global, $key ) {
if ( ! isset( $super_global[ $key ] ) ) {
return null;
}
if ( $_FILES === $super_global ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
return isset( $super_global[ $key ]['name'] ) ?
self::sanitize_file_name( $super_global[ $key ] ) :
self::sanitize_multi_upload( $super_global[ $key ] );
}
return wp_kses_post_deep( wp_unslash( $super_global[ $key ] ) );
}
private static function sanitize_multi_upload( $fields ) {
return array_map( function( $field ) {
return array_map( 'self::sanitize_file_name', $field );
}, $fields );
}
private static function sanitize_file_name( $file ) {
$file['name'] = sanitize_file_name( $file['name'] );
return $file;
}
/**
* Return specific object property value if exist from array of keys.
*
* @param array $base_array
* @param array $keys
* @return mixed|null
*/
public static function get_array_value_by_keys( $base_array, $keys ) {
$keys = (array) $keys;
foreach ( $keys as $key ) {
if ( ! isset( $base_array[ $key ] ) ) {
return null;
}
$base_array = $base_array[ $key ];
}
return $base_array;
}
public static function get_cached_callback( $callback, $cache_key, $cache_time = 24 * HOUR_IN_SECONDS ) {
$cache = get_site_transient( $cache_key );
if ( ! $cache ) {
$cache = call_user_func( $callback );
if ( ! is_wp_error( $cache ) ) {
set_site_transient( $cache_key, $cache, $cache_time );
}
}
return $cache;
}
public static function is_sale_time(): bool {
$sale_start_time = gmmktime( 10, 0, 0, 6, 15, 2026 );
$sale_end_time = gmmktime( 3, 59, 0, 6, 17, 2026 );
$now_time = gmdate( 'U' );
return $now_time >= $sale_start_time && $now_time <= $sale_end_time;
}
public static function safe_throw( string $message ) {
if ( ! static::is_elementor_debug() ) {
return;
}
throw new \Exception( esc_html( $message ) );
}
public static function has_invalid_post_permissions( $post ): bool {
$is_image_attachment = 'attachment' === $post->post_type && strpos( $post->post_mime_type, 'image/' ) === 0;
if ( $is_image_attachment ) {
return false;
}
$is_private = 'private' === $post->post_status
&& ! current_user_can( 'read_private_posts', $post->ID );
$not_allowed = 'publish' !== $post->post_status
&& ! current_user_can( 'edit_post', $post->ID );
$password_required = post_password_required( $post->ID )
&& ! current_user_can( 'edit_post', $post->ID );
return $is_private || $not_allowed || $password_required;
}
public static function is_custom_kit_applied() {
return (bool) Plugin::$instance->kits_manager->get_previous_id();
}
public static function decode_string( string $encoded_string, ?string $fallback = '' ) {
try {
return base64_decode( $encoded_string, true ) ?? $fallback;
} catch ( \Exception $e ) {
return $fallback;
}
}
public static function encode_string( string $decoded_string ): string {
return base64_encode( $decoded_string );
}
public static function html_to_plain_text( string $html ): string {
if ( empty( $html ) ) {
return '';
}
$text = preg_replace( '#
#i', ' ', $html );
$text = preg_replace( '#?[a-z][^>]*>#i', ' ', $text );
$text = html_entity_decode( $text, ENT_QUOTES, 'UTF-8' );
$text = str_replace( "\xE2\x80\x8B", '', $text );
return trim( preg_replace( '/\s+/', ' ', $text ) );
}
}
ed after this filter runs and cannot be re-added,
* to prevent XSS via a wrapper tag that executes script or embeds external content.
*
* @since 4.4.0
*
* @param string[] $tags A list of lowercase HTML tag name strings.
*/
$tags = apply_filters( 'elementor/allowed_html_wrapper_tags', self::ALLOWED_HTML_WRAPPER_TAGS );
self::$resolved_allowed_html_wrapper_tags = self::normalize_allowed_html_wrapper_tags( $tags );
return self::$resolved_allowed_html_wrapper_tags;
}
/**
* Validate an HTML tag against a safe allowed list.
*
* @param string $tag
*
* @return string
*/
public static function validate_html_tag( $tag ) {
return $tag && in_array( strtolower( $tag ), self::get_allowed_html_wrapper_tags(), true ) ? $tag : 'div';
}
/**
* @param array $tags
*
* @return string[]
*/
private static function normalize_allowed_html_wrapper_tags( array $tags ): array {
$normalized_tags = [];
foreach ( $tags as $tag ) {
if ( ! is_string( $tag ) ) {
continue;
}
$tag = strtolower( $tag );
if ( in_array( $tag, self::FORBIDDEN_HTML_WRAPPER_TAGS, true ) ) {
continue;
}
$normalized_tags[] = $tag;
}
return array_values( array_unique( $normalized_tags ) );
}
/**
* Safe print a validated HTML tag.
*
* @param string $tag
*/
public static function print_validated_html_tag( $tag ) {
// PHPCS - the method validate_html_tag is safe.
echo self::validate_html_tag( $tag ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Print internal content (not user input) without escaping.
*/
public static function print_unescaped_internal_string( $internal_string ) {
echo $internal_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Get recently edited posts query.
*
* Returns `WP_Query` of the recent edited posts.
* By default max posts ( $args['posts_per_page'] ) is 3.
*
* @param array $args
*
* @return \WP_Query
*/
public static function get_recently_edited_posts_query( $args = [] ) {
$args = wp_parse_args( $args, [
'no_found_rows' => true,
'post_type' => 'any',
'post_status' => [ 'publish', 'draft' ],
'posts_per_page' => '3',
'meta_key' => '_elementor_edit_mode',
'meta_value' => 'builder',
'orderby' => 'modified',
] );
return new \WP_Query( $args );
}
public static function print_wp_kses_extended( $text, array $tags ) {
$allowed_html = wp_kses_allowed_html( 'post' );
foreach ( $tags as $tag ) {
if ( isset( self::EXTENDED_ALLOWED_HTML_TAGS[ $tag ] ) ) {
$extended_tags = apply_filters( "elementor/extended_allowed_html_tags/{$tag}", self::EXTENDED_ALLOWED_HTML_TAGS[ $tag ] );
$allowed_html = array_replace_recursive( $allowed_html, $extended_tags );
}
}
echo wp_kses( $text, $allowed_html );
}
public static function kses_post_deep( $data ) {
return map_deep( $data, function ( $value ) {
return is_string( $value ) ? wp_kses_post( $value ) : $value;
} );
}
public static function is_elementor_path( $path ) {
$path = wp_normalize_path( $path );
/**
* Elementor related paths.
*
* Filters Elementor related paths.
*
* @param string[] $available_paths
*/
$available_paths = apply_filters( 'elementor/utils/elementor_related_paths', [ ELEMENTOR_PATH ] );
return (bool) ( new Collection( $available_paths ) )
->map( function ( $p ) {
// `untrailingslashit` in order to include other plugins prefixed with elementor.
return untrailingslashit( wp_normalize_path( $p ) );
} )
->find(function ( $p ) use ( $path ) {
return false !== strpos( $path, $p );
} );
}
/**
* @param string $file
* @param mixed ...$args
* @return false|string
*/
public static function file_get_contents( $file, ...$args ) {
if ( ! is_file( $file ) || ! is_readable( $file ) ) {
return false;
}
return file_get_contents( $file, ...$args );
}
public static function get_super_global_value( $super_global, $key ) {
if ( ! isset( $super_global[ $key ] ) ) {
return null;
}
if ( $_FILES === $super_global ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
return isset( $super_global[ $key ]['name'] ) ?
self::sanitize_file_name( $super_global[ $key ] ) :
self::sanitize_multi_upload( $super_global[ $key ] );
}
return wp_kses_post_deep( wp_unslash( $super_global[ $key ] ) );
}
private static function sanitize_multi_upload( $fields ) {
return array_map( function( $field ) {
return array_map( 'self::sanitize_file_name', $field );
}, $fields );
}
private static function sanitize_file_name( $file ) {
$file['name'] = sanitize_file_name( $file['name'] );
return $file;
}
/**
* Return specific object property value if exist from array of keys.
*
* @param array $base_array
* @param array $keys
* @return mixed|null
*/
public static function get_array_value_by_keys( $base_array, $keys ) {
$keys = (array) $keys;
foreach ( $keys as $key ) {
if ( ! isset( $base_array[ $key ] ) ) {
return null;
}
$base_array = $base_array[ $key ];
}
return $base_array;
}
public static function get_cached_callback( $callback, $cache_key, $cache_time = 24 * HOUR_IN_SECONDS ) {
$cache = get_site_transient( $cache_key );
if ( ! $cache ) {
$cache = call_user_func( $callback );
if ( ! is_wp_error( $cache ) ) {
set_site_transient( $cache_key, $cache, $cache_time );
}
}
return $cache;
}
public static function is_sale_time(): bool {
$sale_start_time = gmmktime( 10, 0, 0, 6, 15, 2026 );
$sale_end_time = gmmktime( 3, 59, 0, 6, 17, 2026 );
$now_time = gmdate( 'U' );
return $now_time >= $sale_start_time && $now_time <= $sale_end_time;
}
public static function safe_throw( string $message ) {
if ( ! static::is_elementor_debug() ) {
return;
}
throw new \Exception( esc_html( $message ) );
}
public static function has_invalid_post_permissions( $post ): bool {
$is_image_attachment = 'attachment' === $post->post_type && strpos( $post->post_mime_type, 'image/' ) === 0;
if ( $is_image_attachment ) {
return false;
}
$is_private = 'private' === $post->post_status
&& ! current_user_can( 'read_private_posts', $post->ID );
$not_allowed = 'publish' !== $post->post_status
&& ! current_user_can( 'edit_post', $post->ID );
$password_required = post_password_required( $post->ID )
&& ! current_user_can( 'edit_post', $post->ID );
return $is_private || $not_allowed || $password_required;
}
public static function is_custom_kit_applied() {
return (bool) Plugin::$instance->kits_manager->get_previous_id();
}
public static function decode_string( string $encoded_string, ?string $fallback = '' ) {
try {
return base64_decode( $encoded_string, true ) ?? $fallback;
} catch ( \Exception $e ) {
return $fallback;
}
}
public static function encode_string( string $decoded_string ): string {
return base64_encode( $decoded_string );
}
public static function html_to_plain_text( string $html ): string {
if ( empty( $html ) ) {
return '';
}
$text = preg_replace( '#
#i', ' ', $html );
$text = preg_replace( '#?[a-z][^>]*>#i', ' ', $text );
$text = html_entity_decode( $text, ENT_QUOTES, 'UTF-8' );
$text = str_replace( "\xE2\x80\x8B", '', $text );
return trim( preg_replace( '/\s+/', ' ', $text ) );
}
}