register_ajax_action( 'enable_safe_mode', [ $this, 'ajax_enable_safe_mode' ] ); $ajax->register_ajax_action( 'disable_safe_mode', [ $this, 'disable_safe_mode' ] ); } /** * @param Tools $tools_page */ public function add_admin_button( $tools_page ) { $tools_page->add_fields( Settings::TAB_GENERAL, 'tools', [ 'safe_mode' => [ 'label' => esc_html__( 'Safe Mode', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => $this->is_enabled() ? 'global' : '', 'options' => [ '' => esc_html__( 'Disable', 'elementor' ), 'global' => esc_html__( 'Enable', 'elementor' ), ], 'desc' => esc_html__( 'Safe Mode allows you to troubleshoot issues by only loading the editor, without loading the theme or any other plugin.', 'elementor' ), ], ], ] ); } public function on_update_safe_mode( $value ) { if ( 'yes' === $value || 'global' === $value ) { $this->enable_safe_mode(); } else { $this->disable_safe_mode(); } return $value; } /** * @throws \Exception */ public function ajax_enable_safe_mode( $data ) { if ( ! current_user_can( 'install_plugins' ) ) { throw new \Exception( 'Access denied.' ); } // It will run `$this->>update_safe_mode`. update_option( 'elementor_safe_mode', 'yes' ); $document = Plugin::$instance->documents->get( $data['editor_post_id'] ); if ( $document ) { return add_query_arg( 'elementor-mode', 'safe', $document->get_edit_url() ); } return false; } public function enable_safe_mode() { if ( ! current_user_can( 'install_plugins' ) ) { return; } WP_Filesystem(); $this->update_allowed_plugins(); if ( ! is_dir( WPMU_PLUGIN_DIR ) ) { wp_mkdir_p( WPMU_PLUGIN_DIR ); add_option( 'elementor_safe_mode_created_mu_dir', true ); } if ( ! is_dir( WPMU_PLUGIN_DIR ) ) { wp_die( esc_html__( 'Cannot enable Safe Mode', 'elementor' ) ); } $results = copy_dir( __DIR__ . '/mu-plugin/', WPMU_PLUGIN_DIR ); if ( is_wp_error( $results ) ) { return; } $token = hash( 'sha256', wp_rand() ); // Only who own this key can use 'elementor-safe-mode'. update_option( self::OPTION_TOKEN, $token ); // Save for later use. setcookie( self::OPTION_TOKEN, $token, time() + HOUR_IN_SECONDS, COOKIEPATH, '', is_ssl(), true ); } public function disable_safe_mode() { if ( ! current_user_can( 'install_plugins' ) ) { return; } $file_path = WP_CONTENT_DIR . '/mu-plugins/elementor-safe-mode.php'; if ( file_exists( $file_path ) ) { unlink( $file_path ); } if ( get_option( 'elementor_safe_mode_created_mu_dir' ) ) { // It will be removed only if it's empty and don't have other mu-plugins. @rmdir( WPMU_PLUGIN_DIR ); } delete_option( 'elementor_safe_mode' ); delete_option( 'elementor_safe_mode_allowed_plugins' ); delete_option( 'theme_mods_elementor-safe' ); delete_option( 'elementor_safe_mode_created_mu_dir' ); delete_option( self::OPTION_TOKEN ); setcookie( self::OPTION_TOKEN, '', 1, '', '', is_ssl(), true ); } public function filter_preview_url( $url ) { return add_query_arg( 'elementor-mode', 'safe', $url ); } public function filter_template() { return ELEMENTOR_PATH . 'modules/page-templates/templates/canvas.php'; } public function print_safe_mode_css() { ?> print_safe_mode_css() ?>
is_allowed_post_type() ) { return; } $this->print_safe_mode_css(); ?> ' . esc_html__( 'Disable Safe Mode', 'elementor' ) . ''; return $actions; } public function on_deactivated_plugin( $plugin ) { if ( ELEMENTOR_PLUGIN_BASE === $plugin ) { $this->disable_safe_mode(); return; } $allowed_plugins = get_option( 'elementor_safe_mode_allowed_plugins', [] ); $plugin_key = array_search( $plugin, $allowed_plugins, true ); if ( $plugin_key ) { unset( $allowed_plugins[ $plugin_key ] ); update_option( 'elementor_safe_mode_allowed_plugins', $allowed_plugins ); } } public function update_allowed_plugins() { $allowed_plugins = [ 'elementor' => ELEMENTOR_PLUGIN_BASE, ]; if ( defined( 'ELEMENTOR_PRO_PLUGIN_BASE' ) ) { $allowed_plugins['elementor_pro'] = ELEMENTOR_PRO_PLUGIN_BASE; } if ( defined( 'WC_PLUGIN_BASENAME' ) ) { $allowed_plugins['woocommerce'] = WC_PLUGIN_BASENAME; } update_option( 'elementor_safe_mode_allowed_plugins', $allowed_plugins ); } public function __construct() { if ( current_user_can( 'install_plugins' ) ) { add_action( 'elementor/admin/after_create_settings/elementor-tools', [ $this, 'add_admin_button' ] ); } add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); $plugin_file = self::MU_PLUGIN_FILE_NAME; add_filter( "plugin_action_links_{$plugin_file}", [ $this, 'plugin_action_links' ] ); // Use pre_update, in order to catch cases that $value === $old_value and it not updated. add_filter( 'pre_update_option_elementor_safe_mode', [ $this, 'on_update_safe_mode' ], 10, 2 ); add_action( 'elementor/safe_mode/init', [ $this, 'run_safe_mode' ] ); add_action( 'elementor/editor/footer', [ $this, 'print_try_safe_mode' ] ); if ( $this->is_enabled() ) { add_action( 'activated_plugin', [ $this, 'update_allowed_plugins' ] ); add_action( 'deactivated_plugin', [ $this, 'on_deactivated_plugin' ] ); } } private function is_allowed_post_type() { $allowed_post_types = [ 'post', 'page', 'product', Source_Local::CPT, ]; $current_post_type = get_post_type( Plugin::$instance->editor->get_post_id() ); return in_array( $current_post_type, $allowed_post_types ); } }