Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/elementor/core/admin/editor-one-menu/menu/editor-one-custom-elements-menu.php
+++ b/elementor/core/admin/editor-one-menu/menu/editor-one-custom-elements-menu.php
@@ -28,7 +28,7 @@
}
public function get_position(): int {
- return 70;
+ return 80;
}
public function get_slug(): string {
--- a/elementor/core/experiments/manager.php
+++ b/elementor/core/experiments/manager.php
@@ -379,6 +379,15 @@
'minimum_installation_version' => '3.30.0',
],
] );
+
+ $this->add_feature( [
+ 'name' => 'e_panel_promotions',
+ 'title' => esc_html__( 'Panel Promotions', 'elementor' ),
+ 'description' => esc_html__( 'Enable experimental rendering for targeted promotions within the elements panels.', 'elementor' ),
+ 'release_status' => self::RELEASE_STATUS_DEV,
+ 'default' => self::STATE_ACTIVE,
+ 'type' => self::TYPE_HIDDEN,
+ ] );
}
/**
--- a/elementor/core/role-manager/editor-one-role-manager-menu.php
+++ b/elementor/core/role-manager/editor-one-role-manager-menu.php
@@ -34,7 +34,7 @@
}
public function get_position(): int {
- return 40;
+ return 60;
}
public function get_slug(): string {
--- a/elementor/core/utils/promotions/filtered-promotions-manager.php
+++ b/elementor/core/utils/promotions/filtered-promotions-manager.php
@@ -10,6 +10,18 @@
class Filtered_Promotions_Manager {
+ const EDITOR_PANEL_STICKY_FILTER = 'elementor/editor/panel/get_pro_details-sticky';
+
+ public static function get_editor_panel_sticky_promotion(): array {
+ $promotion_data = [
+ 'url' => 'https://go.elementor.com/go-pro-sticky-widget-panel/',
+ 'message' => __( 'Access all Pro widgets.', 'elementor' ),
+ 'button_text' => __( 'Upgrade Now', 'elementor' ),
+ ];
+
+ return self::get_filtered_promotion_data( $promotion_data, self::EDITOR_PANEL_STICKY_FILTER, 'url' );
+ }
+
/**
* @param array $promotion_data
* @param string $filter_name
--- a/elementor/elementor.php
+++ b/elementor/elementor.php
@@ -3,11 +3,11 @@
* Plugin Name: Elementor
* Description: The Elementor Website Builder has it all: drag and drop page builder, Atomic Editor, pixel perfect design, global and reusable style systems, mobile responsive editing, and more. Get started now!
* Plugin URI: https://elementor.com/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash
- * Version: 4.1.3
+ * Version: 4.1.4
* Author: Elementor.com
* Author URI: https://elementor.com/?utm_source=wp-plugins&utm_campaign=author-uri&utm_medium=wp-dash
* Requires PHP: 7.4
- * Requires at least: 6.6
+ * Requires at least: 6.8
* Text Domain: elementor
*
* @package Elementor
@@ -28,7 +28,8 @@
exit; // Exit if accessed directly.
}
-define( 'ELEMENTOR_VERSION', '4.1.3' );
+define( 'ELEMENTOR_VERSION', '4.1.4' );
+define( 'ELEMENTOR_MINIMUM_WP_VERSION', '6.8' );
define( 'ELEMENTOR__FILE__', __FILE__ );
define( 'ELEMENTOR_PLUGIN_BASE', plugin_basename( ELEMENTOR__FILE__ ) );
@@ -66,7 +67,7 @@
if ( ! version_compare( PHP_VERSION, '7.4', '>=' ) ) {
add_action( 'admin_notices', 'elementor_fail_php_version' );
-} elseif ( ! version_compare( get_bloginfo( 'version' ), '6.5', '>=' ) ) {
+} elseif ( ! version_compare( get_bloginfo( 'version' ), ELEMENTOR_MINIMUM_WP_VERSION, '>=' ) ) {
add_action( 'admin_notices', 'elementor_fail_wp_version' );
} else {
require ELEMENTOR_PATH . 'includes/plugin.php';
@@ -112,7 +113,7 @@
sprintf(
/* translators: %s: WordPress version. */
esc_html__( 'Update to version %s and get back to creating!', 'elementor' ),
- '6.5'
+ ELEMENTOR_MINIMUM_WP_VERSION
),
esc_html__( 'Show me how', 'elementor' )
);
--- a/elementor/includes/base/widget-base.php
+++ b/elementor/includes/base/widget-base.php
@@ -380,7 +380,7 @@
'html_wrapper_class' => $this->get_html_wrapper_class(),
'show_in_panel' => $this->show_in_panel(),
'hide_on_search' => $this->hide_on_search(),
- 'upsale_data' => $this->get_upsale_data(),
+ 'upsale_data' => Plugin::$instance->experiments->is_feature_active( 'e_panel_promotions' ) ? null : $this->get_upsale_data(),
'is_dynamic_content' => $this->is_dynamic_content(),
'has_widget_inner_wrapper' => $this->has_widget_inner_wrapper(),
];
--- a/elementor/includes/editor-templates/panel-elements-sticky-promotion.php
+++ b/elementor/includes/editor-templates/panel-elements-sticky-promotion.php
@@ -0,0 +1,16 @@
+<?php
+namespace Elementor;
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+?>
+<div id="elementor-panel-get-pro-elements-sticky">
+ <?php if ( ! Plugin::$instance->experiments->is_feature_active( 'e_panel_promotions' ) ) : ?>
+ <img class="elementor-nerd-box-icon" src="<?php echo ELEMENTOR_ASSETS_URL . 'images/unlock-sticky.svg'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>" loading="lazy" alt="<?php echo esc_attr__( 'Upgrade', 'elementor' ); ?>"/>
+ <?php endif; ?>
+ <div class="elementor-get-pro-sticky-message">
+ <?php echo esc_html( $promotion_data_sticky['message'] ); ?>
+ <a target="_blank" href="<?php echo esc_url( $promotion_data_sticky['url'] ); ?>"><?php echo esc_html( $promotion_data_sticky['button_text'] ); ?></a>
+ </div>
+</div>
--- a/elementor/includes/editor-templates/panel-elements.php
+++ b/elementor/includes/editor-templates/panel-elements.php
@@ -32,12 +32,7 @@
'button_text' => __( 'Upgrade Now', 'elementor' ),
'show_banner' => ! $has_pro,
] );
- $promotion_data_sticky = [
- 'url' => 'https://go.elementor.com/go-pro-sticky-widget-panel/',
- 'message' => __( 'Access all Pro widgets.', 'elementor' ),
- 'button_text' => __( 'Upgrade Now', 'elementor' ),
- ];
- $promotion_data_sticky = Filtered_Promotions_Manager::get_filtered_promotion_data( $promotion_data_sticky, 'elementor/editor/panel/get_pro_details-sticky', 'url' );
+ $promotion_data_sticky = Filtered_Promotions_Manager::get_editor_panel_sticky_promotion();
?>
<?php if ( $get_pro_details['show_banner'] ) : ?>
<div id="elementor-panel-get-pro-elements" class="elementor-nerd-box">
@@ -47,13 +42,13 @@
</div>
<?php endif; ?>
<?php if ( ! $has_pro ) : ?>
- <div id="elementor-panel-get-pro-elements-sticky">
- <img class="elementor-nerd-box-icon" src="<?php echo ELEMENTOR_ASSETS_URL . 'images/unlock-sticky.svg'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>" loading="lazy" alt="<?php echo esc_attr__( 'Upgrade', 'elementor' ); ?>"/>
- <div class="elementor-get-pro-sticky-message">
- <?php echo esc_html( $promotion_data_sticky['message'] ); ?>
- <a target="_blank" href="<?php echo esc_url( $promotion_data_sticky['url'] ); ?>"><?php echo esc_html( $promotion_data_sticky['button_text'] ); ?></a>
- </div>
- </div>
+ <?php require __DIR__ . '/panel-elements-sticky-promotion.php'; ?>
+ <?php endif; ?>
+</script>
+
+<script type="text/template" id="tmpl-elementor-panel-element-sticky-promotion">
+ <?php if ( ! $has_pro ) : ?>
+ <?php require __DIR__ . '/panel-elements-sticky-promotion.php'; ?>
<?php endif; ?>
</script>
@@ -67,7 +62,7 @@
<# if ( 'undefined' !== typeof promotion && promotion ) { #>
<span class="elementor-panel-heading-promotion">
<a href="{{{ promotion.url }}}" target="_blank">
- <i class="eicon-upgrade-crown"></i><?php echo esc_html__( 'Upgrade', 'elementor' ); ?>
+ <i class="eicon-upgrade-crown-full"></i><?php echo esc_html__( 'Upgrade', 'elementor' ); ?>
</a>
</span>
<# } #>
@@ -88,10 +83,9 @@
<button class="elementor-element" data-library-element-type="{{ elType === 'widget' ? widgetType : elType }}">
<# if ( obj.integration ) { #>
<i class="eicon-plug"></i>
- <# } else if ( false === obj.editable && !obj.atomicFormPromotion && !obj.birthdayEasterEgg ) { #>
- <i class="eicon-lock"></i>
- <# } #>
- <# if ( !obj.birthdayEasterEgg && obj.categories.some( category => v4Categories.includes( category ) ) ) { #>
+ <# } else if ( false === obj.editable && !obj.birthdayEasterEgg ) { #>
+ <i class="eicon-upgrade-crown-full"></i>
+ <# } else if ( !obj.birthdayEasterEgg && obj.categories.some( category => v4Categories.includes( category ) ) ) { #>
<i class="eicon-atomic"></i>
<# } #>
<div class="icon">
--- a/elementor/includes/editor-templates/panel.php
+++ b/elementor/includes/editor-templates/panel.php
@@ -1,11 +1,16 @@
<?php
namespace Elementor;
+use ElementorCoreUtilsPromotionsFiltered_Promotions_Manager;
+
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
$document = Plugin::$instance->documents->get( Plugin::$instance->editor->get_post_id() );
+
+$show_editing_panel_sticky_promotion = ! Utils::has_pro() && Plugin::$instance->experiments->is_feature_active( 'e_panel_promotions' );
+$editing_panel_sticky_promotion = $show_editing_panel_sticky_promotion ? Filtered_Promotions_Manager::get_editor_panel_sticky_promotion() : [];
?>
<script type="text/template" id="tmpl-elementor-panel">
<div id="elementor-panel-state-loading">
@@ -196,6 +201,14 @@
<# } #>
</div>
<# } #>
+ <?php if ( $show_editing_panel_sticky_promotion ) : ?>
+ <div class="elementor-panel-editor-sticky-promotion">
+ <div class="elementor-get-pro-sticky-message">
+ <?php echo esc_html( $editing_panel_sticky_promotion['message'] ); ?>
+ <a target="_blank" href="<?php echo esc_url( $editing_panel_sticky_promotion['url'] ); ?>"><?php echo esc_html( $editing_panel_sticky_promotion['button_text'] ); ?></a>
+ </div>
+ </div>
+ <?php endif; ?>
</script>
<script type="text/template" id="tmpl-elementor-panel-schemes-disabled">
--- a/elementor/includes/editor-templates/templates.php
+++ b/elementor/includes/editor-templates/templates.php
@@ -551,7 +551,7 @@
#>
<span class="upgrade-badge">
<a href="{{{ goLink }}}" target="_blank">
- <i class="eicon-upgrade-crown"></i><?php echo esc_html__( 'Upgrade', 'elementor' ); ?>
+ <i class="eicon-upgrade-crown-full"></i><?php echo esc_html__( 'Upgrade', 'elementor' ); ?>
</a>
</span>
<i class="eicon-info upgrade-tooltip" aria-hidden="true"></i>
@@ -647,7 +647,7 @@
#>
<span class="upgrade-badge">
<a href="{{{ goLink }}}" target="_blank">
- <i class="eicon-upgrade-crown"></i><?php echo esc_html__( 'Upgrade', 'elementor' ); ?>
+ <i class="eicon-upgrade-crown-full"></i><?php echo esc_html__( 'Upgrade', 'elementor' ); ?>
</a>
</span>
<# } else { #>
--- a/elementor/includes/managers/controls.php
+++ b/elementor/includes/managers/controls.php
@@ -1270,7 +1270,7 @@
<?php echo esc_html__( 'Display Conditions', 'elementor' ); ?>
</span>
<span class="e-control-display-conditions-promotion__lock-wrapper">
- <i class="eicon-lock e-control-display-conditions-promotion"></i>
+ <i class="eicon-upgrade-crown-full e-control-display-conditions-promotion"></i>
</span>
</div>
<i class="eicon-flow e-control-display-conditions-promotion"></i>
@@ -1336,7 +1336,7 @@
' . $title . '
</label>
<span class="e-control-motion-effects-promotion__lock-wrapper">
- <i class="eicon-lock"></i>
+ <i class="eicon-upgrade-crown-full"></i>
</span>
<div class="elementor-control-input-wrapper">
<label class="elementor-switch elementor-control-unit-2 e-control-' . $id . '-promotion">
@@ -1358,7 +1358,7 @@
' . $title . '
</label>
<span class="e-control-motion-effects-promotion__lock-wrapper">
- <i class="eicon-lock"></i>
+ <i class="eicon-upgrade-crown-full"></i>
</span>
<div class="elementor-control-input-wrapper elementor-control-unit-5 e-control-' . $id . '-promotion">
<div class="select-promotion elementor-control-unit-5">' . esc_html__( 'None', 'elementor' ) . '</div>
--- a/elementor/includes/managers/icons.php
+++ b/elementor/includes/managers/icons.php
@@ -24,7 +24,7 @@
const LOAD_FA4_SHIM_OPTION_KEY = 'elementor_load_fa4_shim';
- const ELEMENTOR_ICONS_VERSION = '5.49.0';
+ const ELEMENTOR_ICONS_VERSION = '5.50.0';
/**
* Tabs.
--- a/elementor/includes/template-library/sources/admin-menu-items/editor-one-templates-menu.php
+++ b/elementor/includes/template-library/sources/admin-menu-items/editor-one-templates-menu.php
@@ -28,7 +28,7 @@
}
public function get_position(): int {
- return 60;
+ return 40;
}
public function get_slug(): string {
--- a/elementor/modules/atomic-widgets/library/atomic-form.php
+++ b/elementor/modules/atomic-widgets/library/atomic-form.php
@@ -0,0 +1,67 @@
+<?php
+namespace ElementorModulesAtomicWidgetsLibrary;
+
+use ElementorModulesLibraryDocumentsLibrary_Document;
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+/**
+ * Elementor Atomic Form library document.
+ *
+ * Elementor atomic form library document handler class is responsible for
+ * handling a document of an atomic form type.
+ *
+ * @since 3.29.0
+ */
+class Atomic_Form extends Library_Document {
+
+ public static function get_properties() {
+ $properties = parent::get_properties();
+
+ $properties['support_kit'] = true;
+
+ return $properties;
+ }
+
+ /**
+ * Get document name.
+ *
+ * Retrieve the document name.
+ *
+ * @since 2.0.0
+ * @access public
+ *
+ * @return string Document name.
+ */
+ public function get_name() {
+ return 'e-form';
+ }
+
+ /**
+ * Get document title.
+ *
+ * Retrieve the document title.
+ *
+ * @since 2.0.0
+ * @access public
+ * @static
+ *
+ * @return string Document title.
+ */
+ public static function get_title() {
+ return esc_html__( 'Atomic Form', 'elementor' );
+ }
+
+ /**
+ * Get Type
+ *
+ * Return the atomic form document type.
+ *
+ * @return string
+ */
+ public static function get_type() {
+ return 'e-form';
+ }
+}
--- a/elementor/modules/atomic-widgets/library/atomic-widgets-library.php
+++ b/elementor/modules/atomic-widgets/library/atomic-widgets-library.php
@@ -12,6 +12,7 @@
public function register_documents() {
Plugin::$instance->documents
->register_document_type( 'e-div-block', Div_Block::get_class_full_name() )
- ->register_document_type( 'e-flexbox', Flexbox::get_class_full_name() );
+ ->register_document_type( 'e-flexbox', Flexbox::get_class_full_name() )
+ ->register_document_type( 'e-form', Atomic_Form::get_class_full_name() );
}
}
--- a/elementor/modules/editor-one/classes/menu-config.php
+++ b/elementor/modules/editor-one/classes/menu-config.php
@@ -84,7 +84,7 @@
public static function get_attribute_mapping(): array {
$default_mapping = [
'e-form-submissions' => [
- 'position' => 50,
+ 'position' => 70,
'icon' => 'send',
],
];
--- a/elementor/modules/editor-one/classes/menu-data-provider.php
+++ b/elementor/modules/editor-one/classes/menu-data-provider.php
@@ -6,6 +6,7 @@
use ElementorCoreAdminEditorOneMenuInterfacesMenu_Item_Third_Level_Interface;
use ElementorCoreAdminEditorOneMenuInterfacesMenu_Item_With_Custom_Url_Interface;
use ElementorPlugin;
+use ElementorUtils;
if ( ! defined( 'ABSPATH' ) ) {
exit;
@@ -292,7 +293,25 @@
}
private function build_flyout_items_with_expanded_third_party(): array {
- return $this->build_flyout_items( true );
+ $items = $this->build_flyout_items( true );
+
+ if ( ! Utils::has_pro() ) {
+ $items[] = $this->build_theme_builder_flyout_item();
+ }
+
+ return $items;
+ }
+
+ private function build_theme_builder_flyout_item(): array {
+ return [
+ 'slug' => 'elementor-theme-builder',
+ 'label' => esc_html__( 'Theme Builder', 'elementor' ),
+ 'url' => $this->get_theme_builder_url(),
+ 'icon' => 'theme-builder',
+ 'group_id' => '',
+ 'priority' => 50,
+ 'has_divider_before' => false,
+ ];
}
private function build_flyout_items( bool $expand_third_party ): array {
--- a/elementor/modules/promotions/admin-menu-items/editor-one-custom-elements-menu.php
+++ b/elementor/modules/promotions/admin-menu-items/editor-one-custom-elements-menu.php
@@ -28,7 +28,7 @@
}
public function get_position(): int {
- return 70;
+ return 80;
}
public function get_slug(): string {
--- a/elementor/modules/promotions/admin-menu-items/editor-one-submissions-menu.php
+++ b/elementor/modules/promotions/admin-menu-items/editor-one-submissions-menu.php
@@ -12,7 +12,7 @@
class Editor_One_Submissions_Menu extends Base_Promotion_Template implements Menu_Item_Third_Level_Interface {
public function get_position(): int {
- return 50;
+ return 70;
}
public function get_slug(): string {
--- a/elementor/modules/promotions/controls/promotion-control.php
+++ b/elementor/modules/promotions/controls/promotion-control.php
@@ -20,7 +20,7 @@
<label for="<?php $this->print_control_uid(); ?>" class="elementor-control-title">{{{ data.label }}}</label>
<# } #>
<span class="e-control-promotion__lock-wrapper">
- <i class="eicon-lock"></i>
+ <i class="eicon-upgrade-crown-full"></i>
</span>
<div class="elementor-control-input-wrapper">
<label class="elementor-switch elementor-control-unit-2 e-control-promotion-switch">
--- a/elementor/modules/promotions/conversion-banner.php
+++ b/elementor/modules/promotions/conversion-banner.php
@@ -247,13 +247,6 @@
'selector' => '#e-home-screen',
'before' => true,
],
- 'update-core' => $default,
- 'edit-post' => $default,
- 'edit-page' => $default,
- 'edit-category' => $default,
- 'edit-post_tag' => $default,
- 'upload' => $default,
- 'media' => $default,
'elementor_page_elementor-settings' => $default,
'elementor_page_elementor-tools' => $default,
'elementor_page_elementor-role-manager' => $default,
@@ -280,23 +273,6 @@
'plugins' => $default,
'plugin-install' => $default,
'plugin-editor' => $default,
- 'users' => $default,
- 'user' => $default,
- 'profile' => $default,
- 'tools' => $default,
- 'import' => $default,
- 'export' => $default,
- 'site-health' => $default,
- 'export-personal-data' => $default,
- 'erase-personal-data' => $default,
- 'options-general' => $default,
- 'options-writing' => $default,
- 'options-reading' => $default,
- 'options-discussion' => $default,
- 'options-media' => $default,
- 'options-permalink' => $default,
- 'options-privacy' => $default,
- 'privacy-policy-guide' => $default,
];
}
}
--- a/elementor/modules/promotions/module.php
+++ b/elementor/modules/promotions/module.php
@@ -5,6 +5,7 @@
use ElementorApi;
use ElementorControls_Manager;
use ElementorCoreBaseModule as Base_Module;
+use ElementorCoreUtilsPromotionsFiltered_Promotions_Manager;
use ElementorModulesPromotionsAdminMenuItemsEditor_One_Custom_Code_Menu;
use ElementorModulesPromotionsAdminMenuItemsEditor_One_Custom_Elements_Menu;
use ElementorModulesPromotionsAdminMenuItemsEditor_One_Fonts_Menu;
@@ -87,6 +88,8 @@
return;
}
+ add_filter( 'elementor/editor/localize_settings', [ $this, 'add_editing_panel_sticky_promotion' ] );
+
add_action( 'elementor/controls/register', function ( Controls_Manager $controls_manager ) {
$controls_manager->register( new ControlsPromotion_Control() );
} );
@@ -166,6 +169,7 @@
'backbone-marionette',
'elementor-editor-modules',
'elementor-v2-ui',
+ 'elementor-v2-icons',
],
ELEMENTOR_VERSION,
true
@@ -216,6 +220,16 @@
];
}
+ public function add_editing_panel_sticky_promotion( array $settings ): array {
+ if ( ! Plugin::$instance->experiments->is_feature_active( 'e_panel_promotions' ) ) {
+ return $settings;
+ }
+
+ $settings['editingPanelStickyPromotion'] = Filtered_Promotions_Manager::get_editor_panel_sticky_promotion();
+
+ return $settings;
+ }
+
public function add_v4_promotions_data( array $settings ): array {
if ( ! current_user_can( 'manage_options' ) ) {
return $settings;
--- a/elementor/modules/promotions/widgets/pro-widget-promotion.php
+++ b/elementor/modules/promotions/widgets/pro-widget-promotion.php
@@ -68,7 +68,7 @@
);
?>
<div class="e-container">
- <span class="e-badge"><i class="eicon-lock" aria-hidden="true"></i> <?php echo esc_html__( 'Pro', 'elementor' ); ?></span>
+ <span class="e-badge"><i class="eicon-upgrade-crown-full" aria-hidden="true"></i> <?php echo esc_html__( 'Pro', 'elementor' ); ?></span>
<p>
<img src="<?php echo esc_url( $promotion['image_url'] ); ?>" loading="lazy" alt="Go Pro">
<?php
--- a/elementor/modules/system-info/admin-menu-items/editor-one-system-menu.php
+++ b/elementor/modules/system-info/admin-menu-items/editor-one-system-menu.php
@@ -28,7 +28,7 @@
}
public function get_position(): int {
- return 80;
+ return 90;
}
public function get_slug(): string {
--- a/elementor/modules/wp-rest/base/query.php
+++ b/elementor/modules/wp-rest/base/query.php
@@ -40,6 +40,8 @@
abstract protected function get_endpoint_registration_args(): array;
+ abstract protected function permission_check( WP_REST_Request $request ): bool;
+
public function register( $endpoint, bool $override_existing_endpoints = false ): void {
register_rest_route( self::NAMESPACE, $endpoint, [
[
@@ -100,10 +102,24 @@
}
- private function validate_access_permission( $request ): bool {
+ protected function validate_access_permission( WP_REST_Request $request ): bool {
$nonce = $request->get_header( self::NONCE_KEY );
- return current_user_can( 'edit_posts' ) && wp_verify_nonce( $nonce, 'wp_rest' );
+ return $this->permission_check( $request ) && wp_verify_nonce( $nonce, 'wp_rest' );
+ }
+
+ protected function filter_keys_conversion_map( array $requested_map, array $allowed_map ): array {
+ $sanitized_map = [];
+
+ foreach ( $requested_map as $source_key => $destination_key ) {
+ if ( ! isset( $allowed_map[ $source_key ] ) ) {
+ continue;
+ }
+
+ $sanitized_map[ $source_key ] = $destination_key;
+ }
+
+ return ! empty( $sanitized_map ) ? $sanitized_map : $allowed_map;
}
/**
--- a/elementor/modules/wp-rest/classes/post-query.php
+++ b/elementor/modules/wp-rest/classes/post-query.php
@@ -13,6 +13,12 @@
const ENDPOINT = 'post';
const SEARCH_FILTER_ACCEPTED_ARGS = 2;
const DEFAULT_FORBIDDEN_POST_TYPES = [ 'e-floating-buttons', 'e-landing-page', 'elementor_library', 'attachment', 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset' ];
+ const SEARCH_IN_CONTENT_KEY = 'search_in_content';
+ const ALLOWED_KEYS_CONVERSION_MAP = [
+ 'ID' => 'id',
+ 'post_title' => 'label',
+ 'post_type' => 'groupLabel',
+ ];
/**
* @param string $search_term The original search query.
@@ -55,12 +61,15 @@
], 200 );
}
- $keys_format_map = $params[ self::KEYS_CONVERSION_MAP_KEY ];
+ $keys_format_map = $this->filter_keys_conversion_map(
+ $params[ self::KEYS_CONVERSION_MAP_KEY ] ?? self::ALLOWED_KEYS_CONVERSION_MAP,
+ self::ALLOWED_KEYS_CONVERSION_MAP
+ );
$requested_count = $params[ self::ITEMS_COUNT_KEY ] ?? 0;
$validated_count = max( $requested_count, 1 );
$post_count = min( $validated_count, self::MAX_RESPONSE_COUNT );
$is_public_only = $params[ self::IS_PUBLIC_KEY ] ?? true;
- $post_types = $this->get_post_types_from_params( $params );
+ $post_types = $this->get_post_types_from_params( $request );
$query_args = [
'post_type' => array_keys( $post_types ),
@@ -95,16 +104,22 @@
'success' => true,
'data' => [
'value' => $posts
+ ->filter( function ( $post ) {
+ return current_user_can( 'read_post', $post->ID );
+ } )
->map( function ( $post ) use ( $keys_format_map, $post_type_labels ) {
- $post_object = (array) $post;
+ $post_type_label = $post->post_type;
- if ( isset( $post_object['post_type'] ) ) {
- $pt_name = $post_object['post_type'];
- if ( isset( $post_type_labels[ $pt_name ] ) ) {
- $post_object['post_type'] = $post_type_labels[ $pt_name ];
- }
+ if ( isset( $post_type_labels[ $post->post_type ] ) ) {
+ $post_type_label = $post_type_labels[ $post->post_type ];
}
+ $post_object = [
+ 'ID' => $post->ID,
+ 'post_title' => $post->post_title,
+ 'post_type' => $post_type_label,
+ ];
+
return $this->translate_keys( $post_object, $keys_format_map );
} )
->all(),
@@ -132,6 +147,10 @@
remove_filter( 'posts_search', [ $this, 'customize_post_query' ], $priority, $accepted_args );
}
+ protected function permission_check( WP_REST_Request $request ): bool {
+ return current_user_can( 'edit_posts' );
+ }
+
protected function get_endpoint_registration_args(): array {
return [
self::INCLUDED_TYPE_KEY => [
@@ -217,9 +236,9 @@
];
}
- private function get_post_types_from_params( $params ) {
- $included_types = $params[ self::INCLUDED_TYPE_KEY ];
- $excluded_types = $params[ self::EXCLUDED_TYPE_KEY ];
+ private function get_post_types_from_params( WP_REST_Request $request ) {
+ $included_types = $request->get_param( self::INCLUDED_TYPE_KEY );
+ $excluded_types = $request->get_param( self::EXCLUDED_TYPE_KEY );
$post_type_query_args = [
'public' => true,
];
--- a/elementor/modules/wp-rest/classes/term-query.php
+++ b/elementor/modules/wp-rest/classes/term-query.php
@@ -138,6 +138,10 @@
remove_filter( 'terms_clauses', [ $this, 'customize_terms_query' ], $priority, $accepted_args );
}
+ protected function permission_check( WP_REST_Request $request ): bool {
+ return current_user_can( 'edit_posts' );
+ }
+
/**
* @return array
*/
--- a/elementor/modules/wp-rest/classes/user-query.php
+++ b/elementor/modules/wp-rest/classes/user-query.php
@@ -85,6 +85,10 @@
return $result;
}
+ protected function permission_check( WP_REST_Request $request ): bool {
+ return current_user_can( 'list_users' );
+ }
+
protected function get_endpoint_registration_args(): array {
return [
self::SEARCH_TERM_KEY => [
--- a/elementor/vendor/autoload.php
+++ b/elementor/vendor/autoload.php
@@ -19,4 +19,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
-return ComposerAutoloaderInit82728f8d2fbed0ecab38cb766f6ae169::getLoader();
+return ComposerAutoloaderInit93b7b927ef351f3c860d6112aa6f6576::getLoader();
--- a/elementor/vendor/composer/autoload_real.php
+++ b/elementor/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
-class ComposerAutoloaderInit82728f8d2fbed0ecab38cb766f6ae169
+class ComposerAutoloaderInit93b7b927ef351f3c860d6112aa6f6576
{
private static $loader;
@@ -24,16 +24,16 @@
require __DIR__ . '/platform_check.php';
- spl_autoload_register(array('ComposerAutoloaderInit82728f8d2fbed0ecab38cb766f6ae169', 'loadClassLoader'), true, true);
+ spl_autoload_register(array('ComposerAutoloaderInit93b7b927ef351f3c860d6112aa6f6576', 'loadClassLoader'), true, true);
self::$loader = $loader = new ComposerAutoloadClassLoader(dirname(__DIR__));
- spl_autoload_unregister(array('ComposerAutoloaderInit82728f8d2fbed0ecab38cb766f6ae169', 'loadClassLoader'));
+ spl_autoload_unregister(array('ComposerAutoloaderInit93b7b927ef351f3c860d6112aa6f6576', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
- call_user_func(ComposerAutoloadComposerStaticInit82728f8d2fbed0ecab38cb766f6ae169::getInitializer($loader));
+ call_user_func(ComposerAutoloadComposerStaticInit93b7b927ef351f3c860d6112aa6f6576::getInitializer($loader));
$loader->register(true);
- $filesToLoad = ComposerAutoloadComposerStaticInit82728f8d2fbed0ecab38cb766f6ae169::$files;
+ $filesToLoad = ComposerAutoloadComposerStaticInit93b7b927ef351f3c860d6112aa6f6576::$files;
$requireFile = Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
--- a/elementor/vendor/composer/autoload_static.php
+++ b/elementor/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
namespace ComposerAutoload;
-class ComposerStaticInit82728f8d2fbed0ecab38cb766f6ae169
+class ComposerStaticInit93b7b927ef351f3c860d6112aa6f6576
{
public static $files = array (
'9db71c6726821ac61284818089584d23' => __DIR__ . '/..' . '/elementor/wp-one-package/runner.php',
@@ -230,9 +230,9 @@
public static function getInitializer(ClassLoader $loader)
{
return Closure::bind(function () use ($loader) {
- $loader->prefixLengthsPsr4 = ComposerStaticInit82728f8d2fbed0ecab38cb766f6ae169::$prefixLengthsPsr4;
- $loader->prefixDirsPsr4 = ComposerStaticInit82728f8d2fbed0ecab38cb766f6ae169::$prefixDirsPsr4;
- $loader->classMap = ComposerStaticInit82728f8d2fbed0ecab38cb766f6ae169::$classMap;
+ $loader->prefixLengthsPsr4 = ComposerStaticInit93b7b927ef351f3c860d6112aa6f6576::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit93b7b927ef351f3c860d6112aa6f6576::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInit93b7b927ef351f3c860d6112aa6f6576::$classMap;
}, null, ClassLoader::class);
}
--- a/elementor/vendor/composer/installed.php
+++ b/elementor/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'elementor/elementor',
'pretty_version' => '4.01.x-dev',
'version' => '4.01.9999999.9999999-dev',
- 'reference' => '9f1305e86ba204d153ba9f078af1d86fb1418a5d',
+ 'reference' => '3e5ebca6574978619e34526d66a98ff4e3e9cb8f',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -13,7 +13,7 @@
'elementor/elementor' => array(
'pretty_version' => '4.01.x-dev',
'version' => '4.01.9999999.9999999-dev',
- 'reference' => '9f1305e86ba204d153ba9f078af1d86fb1418a5d',
+ 'reference' => '3e5ebca6574978619e34526d66a98ff4e3e9cb8f',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -29,8 +29,8 @@
'dev_requirement' => false,
),
'elementor/wp-one-package' => array(
- 'pretty_version' => '1.0.63',
- 'version' => '1.0.63.0',
+ 'pretty_version' => '1.0.64',
+ 'version' => '1.0.64.0',
'reference' => null,
'type' => 'library',
'install_path' => __DIR__ . '/../elementor/wp-one-package',
--- a/elementor/vendor/elementor/wp-one-package/assets/build/editor.asset.php
+++ b/elementor/vendor/elementor/wp-one-package/assets/build/editor.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-element', 'wp-url'), 'version' => '01069f38180e7c38f688');
--- a/elementor/vendor/elementor/wp-one-package/runner.php
+++ b/elementor/vendor/elementor/wp-one-package/runner.php
@@ -30,24 +30,24 @@
$pattern = '#/([^/]+)/vendor/elementor/#';
if ( preg_match( $pattern, __DIR__, $matches ) ) {
- $wp_one_package_versions[ $matches[1] ] = '1.0.63';
+ $wp_one_package_versions[ $matches[1] ] = '1.0.64';
}
-if ( ! function_exists( 'elementor_one_register_1_dot_0_dot_63' ) && function_exists( 'add_action' ) ) {
+if ( ! function_exists( 'elementor_one_register_1_dot_0_dot_64' ) && function_exists( 'add_action' ) ) {
if ( ! class_exists( 'ElementorOneVersions', false ) ) {
require_once __DIR__ . '/src/Versions.php';
add_action( 'plugins_loaded', [ ElementorOneVersions::class, 'initialize_latest_version' ], -15, 0 );
}
- add_action( 'plugins_loaded', 'elementor_one_register_1_dot_0_dot_63', -20, 0 );
+ add_action( 'plugins_loaded', 'elementor_one_register_1_dot_0_dot_64', -20, 0 );
- function elementor_one_register_1_dot_0_dot_63() {
+ function elementor_one_register_1_dot_0_dot_64() {
$versions = ElementorOneVersions::instance();
- $versions->register( '1.0.63', 'elementor_one_initialize_1_dot_0_dot_63' );
+ $versions->register( '1.0.64', 'elementor_one_initialize_1_dot_0_dot_64' );
}
- function elementor_one_initialize_1_dot_0_dot_63() {
+ function elementor_one_initialize_1_dot_0_dot_64() {
// The Loader class will be autoloaded from the highest version source
ElementorOneLoader::init();
}
--- a/elementor/vendor/elementor/wp-one-package/src/Admin/Components/EditorUpdateNotification.php
+++ b/elementor/vendor/elementor/wp-one-package/src/Admin/Components/EditorUpdateNotification.php
@@ -1,224 +0,0 @@
-<?php
-
-namespace ElementorOneAdminComponents;
-
-use ElementorOneCommonSupportedPlugins;
-
-if ( ! defined( 'ABSPATH' ) ) {
- exit; // Exit if accessed directly
-}
-
-/**
- * Class EditorUpdateNotification
- * Handles the editor update notification
- */
-class EditorUpdateNotification {
-
- const DISMISSED_OPTION_NAME = Fields::SETTING_PREFIX . 'editor_update_notification_dismissed';
- const SHOWN_NONCE_META_KEY = Fields::SETTING_PREFIX . 'editor_update_notification_shown_nonce';
- const EDITOR_PLUGIN_FILE = 'elementor/elementor.php';
-
- /**
- * Instance
- *
- * @var EditorUpdateNotification|null
- */
- private static ?EditorUpdateNotification $instance = null;
-
- /**
- * Get instance
- *
- * @return EditorUpdateNotification|null
- */
- public static function instance(): ?EditorUpdateNotification {
- if ( ! self::$instance ) {
- self::$instance = new self();
- }
- return self::$instance;
- }
-
- /**
- * Constructor
- *
- * @return void
- */
- private function __construct() {
- add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
- }
-
- /**
- * Check if the Editor plugin is installed
- *
- * @return bool
- */
- public function is_editor_installed(): bool {
- if ( ! function_exists( 'get_plugins' ) ) {
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
- }
-
- $all_plugins = get_plugins();
-
- return isset( $all_plugins[ self::EDITOR_PLUGIN_FILE ] );
- }
-
- /**
- * Check if the Editor plugin is activated
- *
- * @return bool
- */
- public function is_editor_activated(): bool {
- if ( ! function_exists( 'is_plugin_active' ) ) {
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
- }
-
- return is_plugin_active( self::EDITOR_PLUGIN_FILE );
- }
-
- /**
- * Check if the editor plugin has wp-one-package installed
- *
- * @return bool
- */
- public function editor_has_wp_one_package(): bool {
- global $wp_one_package_versions;
-
- return isset( $wp_one_package_versions[ SupportedPlugins::ELEMENTOR ] );
- }
-
- /**
- * Check if update notification has been dismissed
- *
- * @return bool
- */
- public function is_notification_dismissed(): bool {
- return (bool) get_option( self::DISMISSED_OPTION_NAME, false );
- }
-
- /**
- * Check if already shown recently
- *
- * @return bool
- */
- private function is_shown_recently(): bool {
- $user_id = get_current_user_id();
-
- if ( ! $user_id ) {
- return false;
- }
-
- $stored_nonce = get_user_meta( $user_id, self::SHOWN_NONCE_META_KEY, true );
-
- if ( empty( $stored_nonce ) ) {
- return false;
- }
-
- return false !== wp_verify_nonce( $stored_nonce, self::SHOWN_NONCE_META_KEY );
- }
-
- /**
- * Mark as shown
- *
- * @return void
- */
- private function mark_as_shown(): void {
- $user_id = get_current_user_id();
-
- if ( ! $user_id ) {
- return;
- }
-
- update_user_meta(
- $user_id,
- self::SHOWN_NONCE_META_KEY,
- wp_create_nonce( self::SHOWN_NONCE_META_KEY )
- );
- }
-
- /**
- * Check if we should show the update notification
- *
- * @return bool
- */
- public function should_show_notification(): bool {
- if ( $this->is_shown_recently() ) {
- return false;
- }
-
- if ( $this->is_notification_dismissed() ) {
- return false;
- }
-
- if ( ! $this->is_editor_installed() ) {
- return false;
- }
-
- if ( ! $this->is_editor_activated() ) {
- return false;
- }
-
- return ! $this->editor_has_wp_one_package();
- }
-
- /**
- * Check if current page is an Elementor page
- *
- * @return bool
- */
- private function is_elementor_page(): bool {
- $current_screen = get_current_screen();
-
- if ( ! $current_screen ) {
- return false;
- }
-
- $screen_id = $current_screen->id ?? '';
- $post_type = $current_screen->post_type ?? '';
-
- $is_elementor_screen = strpos( $screen_id, 'elementor' ) !== false
- || strpos( $screen_id, 'e-floating-buttons' ) !== false;
-
- $is_elementor_post_type = strpos( $post_type, 'elementor' ) !== false
- || strpos( $post_type, 'e-floating-buttons' ) !== false;
-
- return $is_elementor_screen || $is_elementor_post_type;
- }
-
- /**
- * Maybe enqueue editor update notification assets
- *
- * @return void
- */
- public function enqueue_scripts() {
- if ( ! $this->is_elementor_page() ) {
- return;
- }
-
- if ( ! $this->should_show_notification() ) {
- return;
- }
-
- $asset_file = ELEMENTOR_ONE_ASSETS_PATH . 'editor.asset.php';
- $asset = file_exists( $asset_file ) ? include $asset_file : [
- 'dependencies' => [ 'wp-element', 'wp-i18n', 'wp-data', 'wp-core-data' ],
- 'version' => '1.0.0',
- ];
-
- wp_enqueue_script(
- 'elementor-one-editor-update-notification',
- ELEMENTOR_ONE_ASSETS_URL . 'editor.js',
- $asset['dependencies'],
- $asset['version'],
- true
- );
-
- wp_localize_script(
- 'elementor-one-editor-update-notification',
- 'elementorOneEditorUpdateNotification',
- [
- 'pluginsUrl' => admin_url( 'plugins.php' ),
- ]
- );
-
- $this->mark_as_shown();
- }
-}
--- a/elementor/vendor/elementor/wp-one-package/src/Admin/Components/Fields.php
+++ b/elementor/vendor/elementor/wp-one-package/src/Admin/Components/Fields.php
@@ -60,11 +60,6 @@
'show_in_rest' => true,
'description' => 'Elementor One Dismiss Connect Alert',
],
- 'editor_update_notification_dismissed' => [
- 'type' => 'boolean',
- 'show_in_rest' => true,
- 'description' => 'Elementor One Dismiss Editor Update Notification',
- ],
];
}
@@ -84,7 +79,6 @@
'siteUrl' => get_site_url(),
'welcomeScreenCompleted' => (bool) get_option( self::SETTING_PREFIX . 'welcome_screen_completed' ),
'dismissConnectAlert' => (bool) get_option( self::SETTING_PREFIX . 'dismiss_connect_alert' ),
- 'editorUpdateNotificationDismissed' => (bool) get_option( self::SETTING_PREFIX . 'editor_update_notification_dismissed' ),
'userLocale' => get_user_locale( get_current_user_id() ),
'isRTL' => is_rtl(),
];
--- a/elementor/vendor/elementor/wp-one-package/src/Admin/Components/Onboarding.php
+++ b/elementor/vendor/elementor/wp-one-package/src/Admin/Components/Onboarding.php
@@ -42,10 +42,23 @@
}
/**
+ * On connect fail
+ * @param Facade $facade
+ * @return void
+ */
+ public function on_connect_fail( Facade $facade ): void {
+ wp_safe_redirect(
+ $facade->utils()->get_admin_url() . '#/home?connect-fail=1'
+ );
+ exit;
+ }
+
+ /**
* Onboarding constructor
* @return void
*/
private function __construct() {
add_action( 'elementor_one/elementor_one_connected', [ $this, 'on_connect' ] );
+ add_action( 'elementor_one/elementor_one_connect_fail', [ $this, 'on_connect_fail' ], 10, 1 );
}
}
--- a/elementor/vendor/elementor/wp-one-package/src/Admin/Controllers/Logs.php
+++ b/elementor/vendor/elementor/wp-one-package/src/Admin/Controllers/Logs.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace ElementorOneAdminControllers;
+
+use ElementorOneAdminConfig;
+use ElementorOneLogStore;
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
+
+/**
+ * Internal logs REST API (elementor-one host only).
+ */
+class Logs extends WP_REST_Controller {
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->namespace = Config::APP_REST_NAMESPACE;
+ $this->rest_base = 'logs';
+
+ add_action( 'rest_api_init', [ $this, 'register_routes' ] );
+ }
+
+ /**
+ * @return void
+ */
+ public function register_routes() {
+ register_rest_route(
+ $this->namespace,
+ '/' . $this->rest_base,
+ [
+ [
+ 'methods' => WP_REST_Server::READABLE,
+ 'callback' => [ $this, 'get_logs' ],
+ 'permission_callback' => [ $this, 'permissions_check' ],
+ ],
+ [
+ 'methods' => WP_REST_Server::DELETABLE,
+ 'callback' => [ $this, 'clear_logs' ],
+ 'permission_callback' => [ $this, 'permissions_check' ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * @param WP_REST_Request $request
+ * @return WP_REST_Response|WP_Error
+ */
+ public function get_logs( WP_REST_Request $request ) {
+ return new WP_REST_Response(
+ [
+ 'entries' => LogStore::instance()->all_newest_first(),
+ ]
+ );
+ }
+
+ /**
+ * @param WP_REST_Request $request
+ * @return WP_REST_Response|WP_Error
+ */
+ public function clear_logs( WP_REST_Request $request ) {
+ LogStore::instance()->clear();
+
+ return new WP_REST_Response(
+ [
+ 'success' => true,
+ ]
+ );
+ }
+
+ /**
+ * @param WP_REST_Request $request
+ * @return bool
+ */
+ public function permissions_check( WP_REST_Request $request ) {
+ return current_user_can( 'manage_options' );
+ }
+}
--- a/elementor/vendor/elementor/wp-one-package/src/Connect/Components/Handler.php
+++ b/elementor/vendor/elementor/wp-one-package/src/Connect/Components/Handler.php
@@ -88,27 +88,30 @@
$code = sanitize_text_field( wp_unslash( $_GET['code'] ?? '' ) );
$state = sanitize_text_field( wp_unslash( $_GET['state'] ?? '' ) );
- // Check if the state is valid
$this->validate_nonce( $state );
try {
- // Exchange the code for an access token and store it
[ 'access_token' => $access_token ] = $this->facade->service()->get_token( GrantTypes::AUTHORIZATION_CODE, $code );
$this->facade->data()->set_share_usage_data( $this->is_share_usage_scope_granted( $access_token ) ? 'yes' : 'no' );
$this->facade->data()->set_owner_user_id( get_current_user_id() );
$this->facade->data()->set_home_url();
} catch ( Throwable $th ) {
$this->facade->logger()->error( 'Unable to handle auth code: ' . $th->getMessage() );
+
+ do_action( 'elementor_one/connect_fail', $this->facade );
+ do_action(
+ 'elementor_one/' . $this->facade->get_config( 'app_prefix' ) . '_connect_fail',
+ $this->facade
+ );
+
+ wp_safe_redirect( $this->facade->utils()->get_admin_url() );
+ exit;
}
- // Trigger the connected event for all apps
do_action( 'elementor_one/connected', $this->facade );
-
- // Trigger the connected event for the app prefix
do_action( 'elementor_one/' . $this->facade->get_config( 'app_prefix' ) . '_connected', $this->facade );
wp_safe_redirect( $this->facade->utils()->get_admin_url() );
-
exit;
}
--- a/elementor/vendor/elementor/wp-one-package/src/Loader.php
+++ b/elementor/vendor/elementor/wp-one-package/src/Loader.php
@@ -71,7 +71,6 @@
ElementorOneAdminComponentsAssets::instance();
ElementorOneAdminComponentsFields::instance();
ElementorOneAdminComponentsOnboarding::instance();
- ElementorOneAdminComponentsEditorUpdateNotification::instance();
}
/**
@@ -84,6 +83,7 @@
new ElementorOneAdminControllersThemes();
new ElementorOneAdminControllersPlugins();
new ElementorOneAdminControllersSettings();
+ new ElementorOneAdminControllersLogs();
}
/**
--- a/elementor/vendor/elementor/wp-one-package/src/LogStore.php
+++ b/elementor/vendor/elementor/wp-one-package/src/LogStore.php
@@ -0,0 +1,155 @@
+<?php
+
+namespace ElementorOne;
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
+
+/**
+ * Ring buffer persisted in a non-autoloaded wp_option.
+ */
+class LogStore {
+
+ public const OPTION_KEY = 'elementor_one_internal_logs';
+
+ public const MAX_ENTRIES = 50;
+
+ public const MAX_MESSAGE_LENGTH = 1048;
+
+ public const MAX_CALL_STACK_LENGTH = 1048;
+
+ /**
+ * @var LogStore|null
+ */
+ private static ?LogStore $instance = null;
+
+ /**
+ * @var bool
+ */
+ private bool $is_writing = false;
+
+ /**
+ * @return LogStore
+ */
+ public static function instance(): LogStore {
+ if ( null === self::$instance ) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * @param string $level
+ * @param string $message
+ * @param array<string, mixed> $context
+ * @return void
+ */
+ public function append( string $level, string $message, array $context = [] ): void {
+ if ( $this->is_writing ) {
+ return;
+ }
+
+ $this->is_writing = true;
+
+ try {
+ $entries = get_option( self::OPTION_KEY, [] );
+
+ if ( ! is_array( $entries ) ) {
+ $entries = [];
+ }
+
+ $entries[] = [
+ 'id' => $this->generate_entry_id(),
+ 'timestamp' => gmdate( 'c' ),
+ 'level' => $level,
+ 'message' => $this->truncate_message( $message ),
+ 'context' => $this->normalize_context( $context ),
+ ];
+
+ if ( count( $entries ) > self::MAX_ENTRIES ) {
+ $entries = array_slice( $entries, -self::MAX_ENTRIES );
+ }
+
+ update_option( self::OPTION_KEY, $entries, false );
+ } catch ( Throwable $e ) {
+ unset( $e );
+ } finally {
+ $this->is_writing = false;
+ }
+ }
+
+ /**
+ * @return array<int, array<string, mixed>>
+ */
+ public function all(): array {
+ $entries = get_option( self::OPTION_KEY, [] );
+
+ if ( ! is_array( $entries ) ) {
+ return [];
+ }
+
+ return $entries;
+ }
+
+ /**
+ * @return array<int, array<string, mixed>>
+ */
+ public function all_newest_first(): array {
+ return array_reverse( $this->all() );
+ }
+
+ /**
+ * @return bool
+ */
+ public function clear(): bool {
+ return delete_option( self::OPTION_KEY );
+ }
+
+ /**
+ * @return string
+ */
+ private function generate_entry_id(): string {
+ if ( function_exists( 'wp_generate_uuid4' ) ) {
+ return wp_generate_uuid4();
+ }
+
+ return uniqid( 'log_', true );
+ }
+
+ /**
+ * @param string $message
+ * @return string
+ */
+ private function truncate_message( string $message ): string {
+ if ( strlen( $message ) <= self::MAX_MESSAGE_LENGTH ) {
+ return $message;
+ }
+
+ return substr( $message, 0, self::MAX_MESSAGE_LENGTH );
+ }
+
+ /**
+ * @param array<string, mixed> $context
+ * @return array{source: string, call_stack: string}
+ */
+ private function normalize_context( array $context ): array {
+ $source = isset( $context['source'] ) && is_string( $context['source'] )
+ ? $context['source']
+ : '';
+
+ $call_stack = isset( $context['call_stack'] ) && is_string( $context['call_stack'] )
+ ? $context['call_stack']
+ : '';
+
+ if ( strlen( $call_stack ) > self::MAX_CALL_STACK_LENGTH ) {
+ $call_stack = substr( $call_stack, 0, self::MAX_CALL_STACK_LENGTH );
+ }
+
+ return [
+ 'source' => $source,
+ 'call_stack' => $call_stack,
+ ];
+ }
+}
--- a/elementor/vendor/elementor/wp-one-package/src/Logger.php
+++ b/elementor/vendor/elementor/wp-one-package/src/Logger.php
@@ -37,19 +37,57 @@
* @return void
*/
private function log( string $log_level, $message ): void {
- $backtrace = debug_backtrace(); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
+ $raw_message = $this->message_to_string( $message );
+ $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
+ $caller = $this->caller_from_backtrace( $backtrace );
+
+ $formatted_message = '[' . $this->prefix . ']: ' . $log_level . ' in ' . $caller . ': ' . $raw_message;
+
+ error_log( $formatted_message ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
+
+ LogStore::instance()->append(
+ $log_level,
+ $raw_message,
+ [
+ 'source' => $this->prefix,
+ 'call_stack' => $caller,
+ ]
+ );
+ }
+
+ /**
+ * @param mixed $message
+ * @return string
+ */
+ private function message_to_string( $message ): string {
+ if ( is_string( $message ) ) {
+ return $message;
+ }
+
+ if ( is_scalar( $message ) ) {
+ return (string) $message;
+ }
+
+ $encoded = wp_json_encode( $message );
+
+ return is_string( $encoded ) ? $encoded : '';
+ }
+
+ /**
+ * @param array<int, array<string, mixed>> $backtrace
+ * @return string
+ */
+ private function caller_from_backtrace( array $backtrace ): string {
$class = $backtrace[2]['class'] ?? null;
$type = $backtrace[2]['type'] ?? null;
- $function = $backtrace[2]['function'];
+ $function = $backtrace[2]['function'] ?? '';
if ( $class ) {
- $message = '[' . $this->prefix . ']: ' . $log_level . ' in ' . "$class$type$function()" . ': ' . $message;
- } else {
- $message = '[' . $this->prefix . ']: ' . $log_level . ' in ' . "$function()" . ': ' . $message;
+ return "$class$type$function()";
}
- error_log( $message ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
+ return "$function()";
}
/**