Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/essential-addons-for-elementor-lite/essential_adons_elementor.php
+++ b/essential-addons-for-elementor-lite/essential_adons_elementor.php
@@ -4,7 +4,7 @@
* Description: The Essential plugin you install after Elementor! Packed with 100+ stunning elements like Data Table, Event Calendar, Filterable Gallery, WooCommerce.
* Plugin URI: https://essential-addons.com/
* Author: WPDeveloper
- * Version: 6.6.9
+ * Version: 6.6.10
* Author URI: https://wpdeveloper.com/
* Text Domain: essential-addons-for-elementor-lite
* Domain Path: /languages
@@ -27,7 +27,7 @@
define( 'EAEL_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
define( 'EAEL_PLUGIN_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) );
define( 'EAEL_PLUGIN_URL', trailingslashit( plugins_url( '/', __FILE__ ) ) );
-define( 'EAEL_PLUGIN_VERSION', '6.6.9' );
+define( 'EAEL_PLUGIN_VERSION', '6.6.10' );
define( 'EAEL_ASSET_PATH', wp_upload_dir()['basedir'] . '/essential-addons-elementor' );
define( 'EAEL_ASSET_URL', wp_upload_dir()['baseurl'] . '/essential-addons-elementor' );
/**
--- a/essential-addons-for-elementor-lite/includes/Classes/Bootstrap.php
+++ b/essential-addons-for-elementor-lite/includes/Classes/Bootstrap.php
@@ -219,9 +219,21 @@
//rank math support
add_filter('rank_math/researches/toc_plugins', [$this, 'toc_rank_math_support']);
-// if(defined('WPML_TM_VERSION')){
-// add_filter( 'elementor/documents/get/post_id',[$this, 'eael_wpml_template_translation']);
-// }
+ // Translate embedded Elementor templates/documents (saved templates used by
+ // Advanced Tabs, Advanced Accordion, Info Box, etc.) to the current language.
+ // eael_wpml_template_translation() handles both WPML and Polylang. Previously
+ // this was disabled and gated to WPML only, so Polylang sites always rendered
+ // the source-language template.
+ if ( defined( 'WPML_TM_VERSION' ) || defined( 'POLYLANG_VERSION' ) || function_exists( 'pll_get_post_language' ) ) {
+ add_filter( 'elementor/documents/get/post_id', [ $this, 'eael_wpml_template_translation' ] );
+ }
+
+ // Polylang has no Elementor integration, so the template library is not
+ // translatable by default. Opt it in so saved templates can be mapped to the
+ // current language (and managed from Polylang's UI).
+ if ( defined( 'POLYLANG_VERSION' ) || function_exists( 'pll_get_post_language' ) ) {
+ add_filter( 'pll_get_post_types', [ $this, 'eael_pll_translate_elementor_library' ], 10, 2 );
+ }
//templately plugin support
if( !class_exists('TemplatelyPlugin') && !get_option('eael_templately_promo_hide') ) {
--- a/essential-addons-for-elementor-lite/includes/Classes/Helper.php
+++ b/essential-addons-for-elementor-lite/includes/Classes/Helper.php
@@ -266,9 +266,89 @@
$args['meta_query'] = array_filter( apply_filters( 'woocommerce_product_query_meta_query', $args['meta_query'], new WC_Query() ) );
}
+ // Polylang: pin the query to the language of the page/document the widget is
+ // on, instead of the ambient (cookie / last-page-load) current language. In
+ // the editor the ambient language flips on every page load, which made the
+ // Post Grid show the wrong language's posts. Skip manual ("by_id") selections
+ // and post types Polylang isn't translating.
+ if ( function_exists( 'pll_get_post_language' ) && 'by_id' !== $settings['post_type'] ) {
+ $eael_is_translated = ! function_exists( 'pll_is_translated_post_type' );
+ if ( ! $eael_is_translated ) {
+ foreach ( (array) $args['post_type'] as $eael_pt ) {
+ if ( 'any' !== $eael_pt && pll_is_translated_post_type( $eael_pt ) ) {
+ $eael_is_translated = true;
+ break;
+ }
+ }
+ }
+
+ if ( $eael_is_translated ) {
+ $eael_lang = self::eael_get_current_language();
+ // Allow integrators to override the pinned language.
+ $eael_lang = apply_filters( 'eael/post_grid/query_lang', $eael_lang, $settings, $args );
+ if ( ! empty( $eael_lang ) ) {
+ $args['lang'] = $eael_lang;
+ }
+ }
+ }
+
return $args;
}
+ /**
+ * Resolve the Polylang language slug a widget's query/content should be pinned
+ * to.
+ *
+ * The Elementor editor (and admin-ajax) "current language" is ambient global
+ * state driven by the pll_language cookie, which flips on every page load. That
+ * made the Post Grid and template widgets follow the last-loaded language rather
+ * than the language of the page the widget actually lives on. We instead derive
+ * the language from the current document/page id so it is deterministic.
+ *
+ * @param int $post_id Optional page/post id to read the language from.
+ *
+ * @return string Language slug, or '' when Polylang is inactive/undeterminable.
+ */
+ public static function eael_get_current_language( $post_id = 0 ) {
+ if ( ! function_exists( 'pll_get_post_language' ) ) {
+ return '';
+ }
+
+ if ( ! $post_id && class_exists( 'ElementorPlugin' ) ) {
+ $document = ElementorPlugin::$instance->documents->get_current();
+ if ( $document ) {
+ $post_id = $document->get_main_id();
+ }
+ }
+
+ if ( ! $post_id ) {
+ $post_id = get_the_ID();
+ }
+
+ $lang = $post_id ? pll_get_post_language( $post_id ) : '';
+
+ if ( ! $lang && function_exists( 'pll_current_language' ) ) {
+ $lang = pll_current_language();
+ }
+
+ return $lang ? $lang : '';
+ }
+
+ /**
+ * Build a language-specific cache-key suffix so translated pages that share a
+ * widget id (e.g. created via Polylang "copy content") don't collide in the
+ * Post Grid transients.
+ *
+ * @param int $post_id Optional page/post id to read the language from.
+ *
+ * @return string e.g. "_lang_es", or '' when no language is resolved.
+ */
+ public static function eael_lang_suffix( $post_id = 0 ) {
+ $lang = self::eael_get_current_language( $post_id );
+
+ return $lang ? '_lang_' . sanitize_key( $lang ) : '';
+ }
+
/**
* Go Premium
*
@@ -2085,4 +2165,32 @@
return get_post_status( $template_id ) === 'publish' && get_post_type( $template_id ) === 'elementor_library';
}
+
+ /**
+ * eael_wpml_translate_media
+ *
+ * Resolve an Elementor MEDIA control value (image/video) to its
+ * WPML-translated attachment so the correct media is shown per language.
+ * Safe to call when WPML / WPML Media Translation is inactive — the
+ * `wpml_object_id` filter simply returns the original id unchanged.
+ *
+ * @param array $media Elementor MEDIA control value (expects 'id' and 'url').
+ *
+ * @return array The media array with translated 'id' and 'url' when available.
+ */
+ public static function eael_wpml_translate_media( $media ) {
+ if ( ! is_array( $media ) || empty( $media['id'] ) ) {
+ return $media;
+ }
+
+ // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $translated_id = apply_filters( 'wpml_object_id', $media['id'], 'attachment', true );
+
+ if ( $translated_id && (int) $translated_id !== (int) $media['id'] ) {
+ $media['id'] = $translated_id;
+ $media['url'] = wp_get_attachment_url( $translated_id );
+ }
+
+ return $media;
+ }
}
--- a/essential-addons-for-elementor-lite/includes/Elements/Adv_Accordion.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Adv_Accordion.php
@@ -1830,7 +1830,7 @@
if ( ! empty( $tab['eael_primary_templates'] ) && Helper::is_elementor_publish_template( $tab['eael_primary_templates'] ) ) {
// WPML Compatibility
if ( ! is_array( $tab['eael_primary_templates'] ) ) {
- $tab['eael_primary_templates'] = apply_filters( 'wpml_object_id', $tab['eael_primary_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $tab['eael_primary_templates'] = apply_filters( 'wpml_object_id', $tab['eael_primary_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
Helper::eael_onpage_edit_template_markup( get_the_ID(), $tab['eael_primary_templates'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Adv_Tabs.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Adv_Tabs.php
@@ -1387,7 +1387,8 @@
} else {
echo '<i class="' . esc_attr( $tab['eael_adv_tabs_tab_title_icon'] ) . '"></i>';
} ?>
- <?php elseif ($tab['eael_adv_tabs_icon_type'] === 'image') : ?>
+ <?php elseif ($tab['eael_adv_tabs_icon_type'] === 'image') :
+ $tab['eael_adv_tabs_tab_title_image'] = Helper::eael_wpml_translate_media( $tab['eael_adv_tabs_tab_title_image'] ); // WPML Media Translation compatibility ?>
<img src="<?php echo esc_url( $tab['eael_adv_tabs_tab_title_image']['url'] ); ?>" alt="<?php echo esc_attr(get_post_meta($tab['eael_adv_tabs_tab_title_image']['id'], '_wp_attachment_image_alt', true)); ?>">
<?php endif; ?>
<?php endif; ?>
@@ -1478,7 +1479,7 @@
// WPML Compatibility
if ( ! is_array( $tab['eael_primary_templates'] ) ) {
- $tab['eael_primary_templates'] = apply_filters( 'wpml_object_id', $tab['eael_primary_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $tab['eael_primary_templates'] = apply_filters( 'wpml_object_id', $tab['eael_primary_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
Helper::eael_onpage_edit_template_markup( $page_id, $tab['eael_primary_templates'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Countdown.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Countdown.php
@@ -1343,7 +1343,7 @@
if ( ! empty( $settings['countdown_expiry_templates'] ) && Helper::is_elementor_publish_template( $settings['countdown_expiry_templates'] ) ) {
// WPML Compatibility
if ( ! is_array( $settings['countdown_expiry_templates'] ) ) {
- $settings['countdown_expiry_templates'] = apply_filters( 'wpml_object_id', $settings['countdown_expiry_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $settings['countdown_expiry_templates'] = apply_filters( 'wpml_object_id', $settings['countdown_expiry_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
Helper::eael_onpage_edit_template_markup( get_the_ID(), $settings['countdown_expiry_templates'] );
@@ -1363,7 +1363,7 @@
if ( ! empty( $settings['countdown_expiry_templates'] ) && Helper::is_elementor_publish_template( $settings['countdown_expiry_templates'] ) ) {
// WPML Compatibility
if ( ! is_array( $settings['countdown_expiry_templates'] ) ) {
- $settings['countdown_expiry_templates'] = apply_filters( 'wpml_object_id', $settings['countdown_expiry_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $settings['countdown_expiry_templates'] = apply_filters( 'wpml_object_id', $settings['countdown_expiry_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
Helper::eael_onpage_edit_template_markup( get_the_ID(), $settings['countdown_expiry_templates'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Cta_Box.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Cta_Box.php
@@ -2134,7 +2134,7 @@
$eael_template_id = $settings['eael_primary_templates'];
// WPML Compatibility
if ( ! is_array( $eael_template_id ) ) {
- $eael_template_id = apply_filters( 'wpml_object_id', $eael_template_id, 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $eael_template_id = apply_filters( 'wpml_object_id', $eael_template_id, 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
if ( Plugin::$instance->editor->is_edit_mode() ) {
--- a/essential-addons-for-elementor-lite/includes/Elements/Data_Table.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Data_Table.php
@@ -1416,6 +1416,7 @@
<?php endif; ?>
<?php
if( $header_title['eael_data_table_header_col_icon_enabled'] == 'true' && $header_title['eael_data_table_header_icon_type'] == 'image' ) :
+ $header_title['eael_data_table_header_col_img'] = Helper::eael_wpml_translate_media( $header_title['eael_data_table_header_col_img'] ); // WPML Media Translation compatibility
$this->add_render_attribute('data_table_th_img'.$i, [
'src' => esc_url( $header_title['eael_data_table_header_col_img']['url'] ),
'class' => 'eael-data-table-th-img',
@@ -1473,7 +1474,7 @@
if ( Helper::is_elementor_publish_template( $table_td[ $j ]['template'] ) ) {
// WPML Compatibility
if ( ! is_array( $table_td[ $j ]['template'] ) ) {
- $table_td[ $j ]['template'] = apply_filters( 'wpml_object_id', $table_td[ $j ]['template'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $table_td[ $j ]['template'] = apply_filters( 'wpml_object_id', $table_td[ $j ]['template'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
Helper::eael_onpage_edit_template_markup( get_the_ID(), $table_td[ $j ]['template'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Feature_List.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Feature_List.php
@@ -1065,6 +1065,7 @@
if ( $item['eael_feature_list_icon_type'] == 'image' ) {
+ $item['eael_feature_list_img'] = Helper::eael_wpml_translate_media( $item['eael_feature_list_img'] ); // WPML Media Translation compatibility
$this->add_render_attribute( 'feature_list_image' . $index, [
'src' => esc_url( $item['eael_feature_list_img']['url'] ),
'class' => 'eael-feature-list-img',
--- a/essential-addons-for-elementor-lite/includes/Elements/Filterable_Gallery.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Filterable_Gallery.php
@@ -3769,6 +3769,7 @@
$video_gallery_yt_privacy = ! empty( $settings['video_gallery_yt_privacy'] ) && 'yes' === $settings['video_gallery_yt_privacy'] ? 1 : 0;
foreach ($gallery_items as $gallery) {
+ $gallery['eael_fg_gallery_img'] = Helper::eael_wpml_translate_media( $gallery['eael_fg_gallery_img'] ); // WPML Media Translation compatibility
$gallery_store[$counter]['title'] = Helper::eael_wp_kses($gallery['eael_fg_gallery_item_name']);
$gallery_store[$counter]['content'] = $this->parse_text_editor( wp_kses( $gallery['eael_fg_gallery_item_content'], Helper::eael_allowed_tags() ) );
$gallery_store[$counter]['id'] = $gallery['_id'];
--- a/essential-addons-for-elementor-lite/includes/Elements/Flip_Box.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Flip_Box.php
@@ -2730,7 +2730,7 @@
if ( ! empty( $settings['eael_flipbox_front_templates'] ) && Helper::is_elementor_publish_template( $settings['eael_flipbox_front_templates'] ) ) {
// WPML Compatibility
if ( ! is_array( $settings['eael_flipbox_front_templates'] ) ) {
- $settings['eael_flipbox_front_templates'] = apply_filters( 'wpml_object_id', $settings['eael_flipbox_front_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $settings['eael_flipbox_front_templates'] = apply_filters( 'wpml_object_id', $settings['eael_flipbox_front_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo Plugin::$instance->frontend->get_builder_content( $settings['eael_flipbox_front_templates'], true );
@@ -2777,7 +2777,7 @@
if ( ! empty( $settings['eael_flipbox_back_templates'] ) && Helper::is_elementor_publish_template( $settings['eael_flipbox_back_templates'] ) ) {
// WPML Compatibility
if ( ! is_array( $settings['eael_flipbox_back_templates'] ) ) {
- $settings['eael_flipbox_back_templates'] = apply_filters( 'wpml_object_id', $settings['eael_flipbox_back_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $settings['eael_flipbox_back_templates'] = apply_filters( 'wpml_object_id', $settings['eael_flipbox_back_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo Plugin::$instance->frontend->get_builder_content( $settings['eael_flipbox_back_templates'], true );
--- a/essential-addons-for-elementor-lite/includes/Elements/Image_Accordion.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Image_Accordion.php
@@ -1059,6 +1059,7 @@
<?php
$active = $img_accordion['eael_accordion_is_active'];
$activeCSS = ( $active === 'yes' ? ' flex: 3 1 0%;' : '' );
+ $img_accordion['eael_accordion_bg'] = Helper::eael_wpml_translate_media( $img_accordion['eael_accordion_bg'] ); // WPML Media Translation compatibility
$this->add_render_attribute(
'eael-image-accordion-item-wrapper-' . $key,
[
--- a/essential-addons-for-elementor-lite/includes/Elements/Info_Box.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Info_Box.php
@@ -2502,6 +2502,7 @@
}
$infobox_image = $this->get_settings('eael_infobox_image');
+ $infobox_image = Helper::eael_wpml_translate_media( $infobox_image ); // WPML Media Translation compatibility
$infobox_image_url = Group_Control_Image_Size::get_attachment_image_src($infobox_image['id'], 'thumbnail', $settings);
if (empty($infobox_image_url)){
$infobox_image_url = $infobox_image['url'];
@@ -2616,7 +2617,7 @@
// WPML Compatibility
if ( ! is_array( $settings['eael_primary_templates'] ) ) {
- $settings['eael_primary_templates'] = apply_filters( 'wpml_object_id', $settings['eael_primary_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ $settings['eael_primary_templates'] = apply_filters( 'wpml_object_id', $settings['eael_primary_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
}
Helper::eael_onpage_edit_template_markup( get_the_ID(), $settings['eael_primary_templates'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Login_Register.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Login_Register.php
@@ -6713,6 +6713,13 @@
$this->page_id_for_popup = get_queried_object_id();
//handle form illustration
+ // WPML Media Translation compatibility
+ if ( ! empty( $this->ds['lr_form_image'] ) ) {
+ $this->ds['lr_form_image'] = HelperCLass::eael_wpml_translate_media( $this->ds['lr_form_image'] );
+ }
+ if ( ! empty( $this->ds['lr_form_logo'] ) ) {
+ $this->ds['lr_form_logo'] = HelperCLass::eael_wpml_translate_media( $this->ds['lr_form_logo'] );
+ }
$form_image_id = ! empty( $this->ds['lr_form_image']['id'] ) ? $this->ds['lr_form_image']['id'] : '';
$this->form_illustration_pos = ! empty( $this->ds['lr_form_image_position'] ) ? $this->ds['lr_form_image_position'] : 'left';
$this->form_illustration_url = Group_Control_Image_Size::get_attachment_image_src( $form_image_id, 'lr_form_image', $this->ds );
--- a/essential-addons-for-elementor-lite/includes/Elements/Post_Grid.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Post_Grid.php
@@ -1827,8 +1827,9 @@
$offset = $settings['offset'] ? absint( $settings['offset'] ) : 0;
$posts_per_page = isset($args['posts_per_page']) && $args['posts_per_page'] > 0 ? $args['posts_per_page'] : -1 ;
- set_transient( 'eael_post_grid_read_more_button_text_'. $this->get_id(), $this->get_settings_for_display('read_more_button_text'), DAY_IN_SECONDS );
- set_transient( 'eael_post_grid_excerpt_expanison_indicator_'. $this->get_id(), $this->get_settings_for_display('excerpt_expanison_indicator'), DAY_IN_SECONDS );
+ $eael_lang_suffix = HelperClass::eael_lang_suffix();
+ set_transient( 'eael_post_grid_read_more_button_text_'. $this->get_id() . $eael_lang_suffix, $this->get_settings_for_display('read_more_button_text'), DAY_IN_SECONDS );
+ set_transient( 'eael_post_grid_excerpt_expanison_indicator_'. $this->get_id() . $eael_lang_suffix, $this->get_settings_for_display('excerpt_expanison_indicator'), DAY_IN_SECONDS );
$settings['read_more_button_text'] = $this->get_settings_for_display('read_more_button_text');
$settings['excerpt_expanison_indicator'] = $this->get_settings_for_display('excerpt_expanison_indicator');
--- a/essential-addons-for-elementor-lite/includes/Elements/Pricing_Table.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Pricing_Table.php
@@ -2573,7 +2573,8 @@
<?php if ('style-1' === $settings['eael_pricing_table_style']) : ?>
<div class="eael-pricing-item <?php echo esc_attr($featured_class); ?>">
<div class="header">
- <<?php echo esc_html($settings['eael_pricing_table_title_tag']); ?> class="title"><?php echo wp_kses( $settings['eael_pricing_table_title'], HelperClass::eael_allowed_tags() ); ?></<?php echo esc_html($settings['eael_pricing_table_title_tag']); ?>>
+ <?php $eael_pricing_table_title_tag = HelperClass::eael_validate_html_tag( $settings['eael_pricing_table_title_tag'] ); ?>
+ <<?php echo esc_html( $eael_pricing_table_title_tag ); ?> class="title"><?php echo wp_kses( $settings['eael_pricing_table_title'], HelperClass::eael_allowed_tags() ); ?></<?php echo esc_html( $eael_pricing_table_title_tag ); ?>>
</div>
<div class="eael-pricing-tag">
<?php
--- a/essential-addons-for-elementor-lite/includes/Elements/Sticky_Video.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Sticky_Video.php
@@ -749,6 +749,9 @@
protected function render()
{
$settings = $this->get_settings_for_display();
+ // WPML Media Translation compatibility
+ $settings['eaelsv_overlay_image'] = Helper::eael_wpml_translate_media( $settings['eaelsv_overlay_image'] );
+ $settings['eaelsv_hosted_url'] = Helper::eael_wpml_translate_media( $settings['eaelsv_hosted_url'] );
$iconNew = $settings['eaelsv_icon_new'];
$sticky = isset( $settings['eaelsv_is_sticky'] ) ? $settings['eaelsv_is_sticky'] : 'yes';
$autoplay = ($settings['eaelsv_autopaly'] == 'yes') ? $settings['eaelsv_autopaly'] : 'no';
--- a/essential-addons-for-elementor-lite/includes/Elements/Team_Member.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Team_Member.php
@@ -1031,6 +1031,7 @@
$settings = $this->get_settings_for_display();
$team_member_image = $settings['eael_team_member_image'] ?? '';
+ $team_member_image = HelperClass::eael_wpml_translate_media( $team_member_image ); // WPML Media Translation compatibility
$image_url = $team_member_image['url'] ?? '';
$alt_text = $settings['eael_team_member_name'] ?? '';
--- a/essential-addons-for-elementor-lite/includes/Elements/Testimonial.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Testimonial.php
@@ -901,6 +901,7 @@
protected function render_testimonial_image() {
$settings = $this->get_settings();
+ $settings['image'] = HelperClass::eael_wpml_translate_media( $settings['image'] ); // WPML Media Translation compatibility
$image = Group_Control_Image_Size::get_attachment_image_html( $settings );
if( ! empty($image) && ! empty($settings['eael_testimonial_enable_avatar']) ) {
ob_start();
--- a/essential-addons-for-elementor-lite/includes/Elements/Woo_Product_Gallery.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Woo_Product_Gallery.php
@@ -3284,6 +3284,7 @@
$all_taxonomy = 'product_tag';
}
+ $settings['eael_all_tab_thumb'] = HelperClass::eael_wpml_translate_media( $settings['eael_all_tab_thumb'] ); // WPML Media Translation compatibility
if ( $show_cat_thumb && !empty($settings['eael_all_tab_thumb']['url'])) {
$show_all_cat_thumb = '<img src="' . esc_url( $settings['eael_all_tab_thumb']['url'] ) . '" />';
} else {
--- a/essential-addons-for-elementor-lite/includes/Traits/Ajax_Handler.php
+++ b/essential-addons-for-elementor-lite/includes/Traits/Ajax_Handler.php
@@ -172,8 +172,9 @@
}
if ( $class == 'Essential_Addons_ElementorElementsPost_Grid' ) {
- $settings['read_more_button_text'] = get_transient( 'eael_post_grid_read_more_button_text_' . $widget_id );
- $settings['excerpt_expanison_indicator'] = get_transient( 'eael_post_grid_excerpt_expanison_indicator_' . $widget_id );
+ $eael_lang_suffix = HelperClass::eael_lang_suffix( $page_id );
+ $settings['read_more_button_text'] = get_transient( 'eael_post_grid_read_more_button_text_' . $widget_id . $eael_lang_suffix );
+ $settings['excerpt_expanison_indicator'] = get_transient( 'eael_post_grid_excerpt_expanison_indicator_' . $widget_id . $eael_lang_suffix );
if ( $settings['orderby'] === 'rand' && ! empty( $_REQUEST['post__not_in'] ) ) {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
--- a/essential-addons-for-elementor-lite/includes/Traits/Helper.php
+++ b/essential-addons-for-elementor-lite/includes/Traits/Helper.php
@@ -488,19 +488,62 @@
/**
* eael_wpml_template_translation
+ *
+ * Resolve an Elementor template/library id to its translation in the current
+ * language. Works for both WPML and Polylang:
+ * - WPML auto-registers elementor_library and answers wpml_object_id.
+ * - Polylang does NOT register elementor_library as translatable by default, so
+ * its wpml_object_id compat filter would return the id unchanged. We therefore
+ * resolve via pll_get_post(), which honours the translation group directly.
+ *
* @param $id
* @return mixed|void
*/
public function eael_wpml_template_translation($id){
$postType = get_post_type( $id );
- if ( 'elementor_library' === $postType ) {
- // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
- return apply_filters( 'wpml_object_id', $id, $postType, true );
+ if ( 'elementor_library' !== $postType ) {
+ return $id;
}
- return $id;
+
+ // Polylang path (independent of the translatable-post-type setting).
+ if ( function_exists( 'pll_get_post' ) && function_exists( 'pll_current_language' ) ) {
+ $lang = pll_current_language();
+ if ( $lang ) {
+ $translated = pll_get_post( $id, $lang );
+ // pll_get_post returns false when no translation exists for $lang;
+ // keep the original id in that case.
+ if ( $translated ) {
+ return $translated;
+ }
+ }
+ return $id;
+ }
+
+ // WPML path.
+ // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+ return apply_filters( 'wpml_object_id', $id, $postType, true );
}
/**
+ * Register Elementor's template library as translatable in Polylang.
+ *
+ * Polylang ships no Elementor integration, so elementor_library is not
+ * translatable out of the box — which means saved templates embedded in EA
+ * widgets cannot be mapped to the current language. Opt the post type in so the
+ * translation group (and Polylang's own UI) works for these templates.
+ *
+ * Hooked to: pll_get_post_types
+ *
+ * @param array $post_types
+ * @param bool $is_settings
+ * @return array
+ */
+ public function eael_pll_translate_elementor_library( $post_types, $is_settings = false ) {
+ $post_types['elementor_library'] = 'elementor_library';
+ return $post_types;
+ }
+
+ /**
* eael_sanitize_template_param
* Removes special characters that are illegal in filenames
*
--- a/essential-addons-for-elementor-lite/includes/Traits/Woo_Product_Comparable.php
+++ b/essential-addons-for-elementor-lite/includes/Traits/Woo_Product_Comparable.php
@@ -1969,6 +1969,19 @@
continue;
}
+ // SECURITY FIX: do not expose non-published / inaccessible products to unauthenticated callers.
+ // Mirrors the quickview handler guards (CVE-2026-1004).
+ $compare_post = get_post( $product_id );
+ if ( ! $product->is_visible() ) {
+ continue;
+ }
+ if ( ! current_user_can( 'edit_post', $product_id ) && ( ! $compare_post || 'publish' !== $compare_post->post_status ) ) {
+ continue;
+ }
+ if ( ! current_user_can( 'edit_post', $product_id ) && post_password_required( $compare_post ) ) {
+ continue;
+ }
+
$product->fields = [];
// custom attributes
@@ -2215,6 +2228,19 @@
continue;
}
+ // SECURITY FIX: do not expose non-published / inaccessible products to unauthenticated callers.
+ // Mirrors the quickview handler guards (CVE-2026-1004).
+ $compare_post = get_post( $product_id );
+ if ( ! $product->is_visible() ) {
+ continue;
+ }
+ if ( ! current_user_can( 'edit_post', $product_id ) && ( ! $compare_post || 'publish' !== $compare_post->post_status ) ) {
+ continue;
+ }
+ if ( ! current_user_can( 'edit_post', $product_id ) && post_password_required( $compare_post ) ) {
+ continue;
+ }
+
$product->fields = [];
// custom attributes