base/model.php000066600000001135152141417350007276 0ustar00get_css_file_name(); add_action( "elementor/css-file/{$name}/parse", [ $this, 'add_settings_css_rules' ] ); } /** * Save settings. * * Save settings to the database and update the CSS file. * * @since 2.8.0 * @access public * * @param array $settings Settings. * @param int $id Optional. Post ID. Default is `0`. */ public function save_settings( array $settings, $id = 0 ) { parent::save_settings( $settings, $id ); $css_file = $this->get_css_file_for_update( $id ); if ( $css_file ) { $css_file->update(); } } /** * Add settings CSS rules. * * Add new CSS rules to the settings manager. * * Fired by `elementor/css-file/{$name}/parse` action. * * @since 2.8.0 * @access public * * @param CSS_File $css_file The requested CSS file. * */ public function add_settings_css_rules( CSS_File $css_file ) { $model = $this->get_model_for_css_file( $css_file ); $css_file->add_controls_stack_style_rules( $model, $model->get_style_controls(), $model->get_settings(), [ '{{WRAPPER}}' ], [ $model->get_css_wrapper_selector() ] ); } } base/manager.php000066600000020047152141417350007613 0ustar00get_name(); $ajax_manager->register_ajax_action( "save_{$name}_settings", [ $this, 'ajax_save_settings' ] ); } /** * Get model for config. * * Retrieve the model for settings configuration. * * @since 1.6.0 * @access public * @abstract * * @return Model The model object. */ abstract public function get_model_for_config(); /** * Get manager name. * * Retrieve settings manager name. * * @since 1.6.0 * @access public * @abstract */ abstract public function get_name(); /** * Get model. * * Retrieve the model for any given model ID. * * @since 1.6.0 * @access public * * @param int $id Optional. Model ID. Default is `0`. * * @return Model The model. */ final public function get_model( $id = 0 ) { if ( ! isset( $this->models_cache[ $id ] ) ) { $this->create_model( $id ); } return $this->models_cache[ $id ]; } /** * Ajax request to save settings. * * Save settings using an ajax request. * * @since 1.6.0 * @access public * * @param array $request Ajax request. * * @return array Ajax response data. */ final public function ajax_save_settings( $request ) { $data = $request['data']; $id = 0; if ( ! empty( $request['id'] ) ) { $id = $request['id']; } $this->ajax_before_save_settings( $data, $id ); $this->save_settings( $data, $id ); $settings_name = $this->get_name(); $success_response_data = []; /** * Settings success response data. * * Filters the success response data when saving settings using ajax. * * The dynamic portion of the hook name, `$settings_name`, refers to the settings name. * * @since 1.6.0 * @deprecated 2.0.0 Use `elementor/settings/{$settings_name}/success_response_data` filter. * * @param array $success_response_data Success response data. * @param int $id Settings ID. * @param array $data Settings data. */ $success_response_data = apply_filters_deprecated( "elementor/{$settings_name}/settings/success_response_data", [ $success_response_data, $id, $data ], '2.0.0', "elementor/settings/{$settings_name}/success_response_data" ); /** * Settings success response data. * * Filters the success response data when saving settings using ajax. * * The dynamic portion of the hook name, `$settings_name`, refers to the settings name. * * @since 2.0.0 * * @param array $success_response_data Success response data. * @param int $id Settings ID. * @param array $data Settings data. */ $success_response_data = apply_filters( "elementor/settings/{$settings_name}/success_response_data", $success_response_data, $id, $data ); return $success_response_data; } /** * Save settings. * * Save settings to the database. * * @since 1.6.0 * @access public * * @param array $settings Settings. * @param int $id Optional. Post ID. Default is `0`. */ public function save_settings( array $settings, $id = 0 ) { $special_settings = $this->get_special_settings_names(); $settings_to_save = $settings; foreach ( $special_settings as $special_setting ) { if ( isset( $settings_to_save[ $special_setting ] ) ) { unset( $settings_to_save[ $special_setting ] ); } } $this->save_settings_to_db( $settings_to_save, $id ); // Clear cache after save. if ( isset( $this->models_cache[ $id ] ) ) { unset( $this->models_cache[ $id ] ); } } /** * On Elementor init. * * Add editor template for the settings * * Fired by `elementor/init` action. * * @since 2.3.0 * @access public */ public function on_elementor_editor_init() { Plugin::$instance->common->add_template( $this->get_editor_template(), 'text' ); } /** * Get saved settings. * * Retrieve the saved settings from the database. * * @since 1.6.0 * @access protected * @abstract * * @param int $id Post ID. */ abstract protected function get_saved_settings( $id ); /** * Save settings to DB. * * Save settings to the database. * * @since 1.6.0 * @access protected * @abstract * * @param array $settings Settings. * @param int $id Post ID. */ abstract protected function save_settings_to_db( array $settings, $id ); /** * Get special settings names. * * Retrieve the names of the special settings that are not saved as regular * settings. Those settings have a separate saving process. * * @since 1.6.0 * @access protected * * @return array Special settings names. */ protected function get_special_settings_names() { return []; } /** * Ajax before saving settings. * * Validate the data before saving it and updating the data in the database. * * @since 1.6.0 * @access public * * @param array $data Post data. * @param int $id Post ID. */ public function ajax_before_save_settings( array $data, $id ) {} /** * Print the setting template content in the editor. * * Used to generate the control HTML in the editor using Underscore JS * template. The variables for the class are available using `data` JS * object. * * @since 1.6.0 * @access protected * * @param string $name Settings panel name. */ protected function print_editor_template_content( $name ) { ?> <# const tabs = elementor.config.settings..tabs; if ( Object.values( tabs ).length > 1 ) { #>
<# _.each( tabs, function( tabTitle, tabSlug ) { $e.bc.ensureTab( 'panel/-settings', tabSlug ); #>
{{{ tabTitle }}}
<# } ); #>
<# } #>
models_cache[ $id ] = new $class_name( [ 'id' => $id, 'settings' => $this->get_saved_settings( $id ), ] ); } /** * Get editor template. * * Retrieve the final HTML for the editor. * * @since 1.6.0 * @access private * * @return string Settings editor template. */ private function get_editor_template() { $name = $this->get_name(); ob_start(); ?> __( 'Editor Preferences', 'elementor' ), ]; } /** * @since 2.8.0 * @access protected */ protected function _register_controls() { $this->start_controls_section( 'preferences', [ 'tab' => Controls_Manager::TAB_SETTINGS, 'label' => __( 'Preferences', 'elementor' ), ] ); $this->add_control( 'ui_theme', [ 'label' => __( 'UI Theme', 'elementor' ), 'type' => Controls_Manager::SELECT, 'description' => __( 'Set light or dark mode, or use Auto Detect to sync it with your OS setting.', 'elementor' ), 'default' => 'auto', 'options' => [ 'auto' => __( 'Auto Detect', 'elementor' ), 'light' => __( 'Light', 'elementor' ), 'dark' => __( 'Dark', 'elementor' ), ], ] ); $this->add_control( 'edit_buttons', [ 'label' => __( 'Editing Handles', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'description' => __( 'Show editing handles when hovering over the element edit button.', 'elementor' ), ] ); $this->add_control( 'lightbox_in_editor', [ 'label' => __( 'Enable Lightbox In Editor', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', ] ); $this->end_controls_section(); } } editor-preferences/manager.php000066600000002662152141417350012471 0ustar00get_model(); } /** * Get manager name. * * Retrieve settings manager name. * * @since 2.8.0 * @access public */ public function get_name() { return 'editorPreferences'; } /** * Get saved settings. * * Retrieve the saved settings from the database. * * @since 2.8.0 * @access protected * * @param int $id. * @return array * */ protected function get_saved_settings( $id ) { $settings = get_user_meta( get_current_user_id(), self::META_KEY, true ); if ( ! $settings ) { $settings = []; } return $settings; } /** * Save settings to DB. * * Save settings to the database. * * @param array $settings Settings. * @param int $id Post ID. * @since 2.8.0 * @access protected * */ protected function save_settings_to_db( array $settings, $id ) { update_user_meta( get_current_user_id(), self::META_KEY, $settings ); } } manager.php000066600000010515152141417350006700 0ustar00get_name() ] = $manager; } /** * Get settings managers. * * Retrieve registered settings manager(s). * * If no parameter passed, it will retrieve all the settings managers. For * any given parameter it will retrieve a single settings manager if one * exist, or `null` otherwise. * * @since 1.6.0 * @access public * @static * * @param string $manager_name Optional. Settings manager name. Default is * null. * * @return Base\Manager|Base\Manager[] Single settings manager, if it exists, * null if it doesn't exists, or the all * the settings managers if no parameter * defined. */ public static function get_settings_managers( $manager_name = null ) { if ( $manager_name ) { if ( isset( self::$settings_managers[ $manager_name ] ) ) { return self::$settings_managers[ $manager_name ]; } return null; } return self::$settings_managers; } /** * Register default settings managers. * * Register builtin Elementor settings managers. * * @since 1.6.0 * @access private * @static */ private static function register_default_settings_managers() { foreach ( self::$builtin_settings_managers_names as $manager_name ) { $manager_class = __NAMESPACE__ . '\\' . ucfirst( $manager_name ) . '\Manager'; self::add_settings_manager( new $manager_class() ); } } /** * Get settings managers config. * * Retrieve the settings managers configuration. * * @since 1.6.0 * @access public * @static * * @return array The settings managers configuration. */ public static function get_settings_managers_config() { $config = []; $user_can = Plugin::instance()->role_manager->user_can( 'design' ); foreach ( self::$settings_managers as $name => $manager ) { $settings_model = $manager->get_model_for_config(); $tabs = $settings_model->get_tabs_controls(); if ( ! $user_can ) { unset( $tabs['style'] ); } $config[ $name ] = [ 'name' => $manager->get_name(), 'panelPage' => $settings_model->get_panel_page_settings(), 'controls' => $settings_model->get_controls(), 'tabs' => $tabs, 'settings' => $settings_model->get_settings(), ]; if ( $settings_model instanceof CSS_Model ) { $config[ $name ]['cssWrapperSelector'] = $settings_model->get_css_wrapper_selector(); } } return $config; } /** * Get settings frontend config. * * Retrieve the settings managers frontend configuration. * * @since 1.6.0 * @access public * @static * * @return array The settings managers frontend configuration. */ public static function get_settings_frontend_config() { $config = []; foreach ( self::$settings_managers as $name => $manager ) { $settings_model = $manager->get_model_for_config(); if ( $settings_model ) { $config[ $name ] = $settings_model->get_frontend_settings(); } } return $config; } /** * Run settings managers. * * Register builtin Elementor settings managers. * * @since 1.6.0 * @access public * @static */ public static function run() { self::register_default_settings_managers(); } } general/manager.php000066600000010540152141417350010313 0ustar00add_panel_tabs(); } /** * Get manager name. * * Retrieve general settings manager name. * * @since 1.6.0 * @access public * * @return string Manager name. */ public function get_name() { return 'general'; } /** * Get model for config. * * Retrieve the model for settings configuration. * * @since 1.6.0 * @access public * * @return BaseModel The model object. */ public function get_model_for_config() { return $this->get_model(); } /** * Get saved settings. * * Retrieve the saved settings from the site options. * * @since 1.6.0 * @access protected * * @param int $id Post ID. * * @return array Saved settings. */ protected function get_saved_settings( $id ) { $model_controls = Model::get_controls_list(); $settings = []; foreach ( $model_controls as $tab_name => $sections ) { foreach ( $sections as $section_name => $section_data ) { foreach ( $section_data['controls'] as $control_name => $control_data ) { $saved_setting = get_option( $control_name, null ); if ( null !== $saved_setting ) { $settings[ $control_name ] = $saved_setting; } } } } return $settings; } /** * Get CSS file name. * * Retrieve CSS file name for the general settings manager. * * @since 1.6.0 * @access protected * @return string * * @return string CSS file name. */ protected function get_css_file_name() { return 'global'; } /** * Save settings to DB. * * Save general settings to the database, as site options. * * @since 1.6.0 * @access protected * * @param array $settings Settings. * @param int $id Post ID. */ protected function save_settings_to_db( array $settings, $id ) { $model_controls = Model::get_controls_list(); $one_list_settings = []; foreach ( $model_controls as $tab_name => $sections ) { foreach ( $sections as $section_name => $section_data ) { foreach ( $section_data['controls'] as $control_name => $control_data ) { if ( isset( $settings[ $control_name ] ) ) { $one_list_control_name = str_replace( 'elementor_', '', $control_name ); $one_list_settings[ $one_list_control_name ] = $settings[ $control_name ]; update_option( $control_name, $settings[ $control_name ] ); } else { delete_option( $control_name ); } } } } // Save all settings in one list for a future usage if ( ! empty( $one_list_settings ) ) { update_option( self::META_KEY, $one_list_settings ); } else { delete_option( self::META_KEY ); } } /** * Get model for CSS file. * * Retrieve the model for the CSS file. * * @since 1.6.0 * @access protected * * @param Base $css_file The requested CSS file. * * @return BaseModel The model object. */ protected function get_model_for_css_file( Base $css_file ) { return $this->get_model(); } /** * Get CSS file for update. * * Retrieve the CSS file before updating the it. * * @since 1.6.0 * @access protected * * @param int $id Post ID. * * @return Global_CSS The global CSS file object. */ protected function get_css_file_for_update( $id ) { return Global_CSS::create( 'global.css' ); } /** * Add panel tabs. * * Register new panel tab for the lightbox settings. * * @since 1.6.0 * @access private */ private function add_panel_tabs() { Controls_Manager::add_tab( self::PANEL_TAB_LIGHTBOX, __( 'Lightbox', 'elementor' ) ); } } general/model.php000066600000020277152141417350010011 0ustar00 __( 'Global Settings', 'elementor' ), ]; } /** * Get controls list. * * Retrieve the global settings model controls list. * * @since 1.6.0 * @access public * @static * * @return array Controls list. */ public static function get_controls_list() { return [ Controls_Manager::TAB_STYLE => [ 'style' => [ 'label' => __( 'Style', 'elementor' ), 'controls' => [ 'elementor_default_generic_fonts' => [ 'label' => __( 'Default Generic Fonts', 'elementor' ), 'type' => Controls_Manager::TEXT, 'default' => 'Sans-serif', 'description' => __( 'The list of fonts used if the chosen font is not available.', 'elementor' ), 'label_block' => true, ], 'elementor_container_width' => [ 'label' => __( 'Content Width', 'elementor' ) . ' (px)', 'type' => Controls_Manager::NUMBER, 'min' => 300, 'description' => __( 'Sets the default width of the content area (Default: 1140)', 'elementor' ), 'selectors' => [ '.elementor-section.elementor-section-boxed > .elementor-container' => 'max-width: {{VALUE}}px', ], ], 'elementor_space_between_widgets' => [ 'label' => __( 'Widgets Space', 'elementor' ) . ' (px)', 'type' => Controls_Manager::NUMBER, 'min' => 0, 'placeholder' => '20', 'description' => __( 'Sets the default space between widgets (Default: 20)', 'elementor' ), 'selectors' => [ '.elementor-widget:not(:last-child)' => 'margin-bottom: {{VALUE}}px', ], ], 'elementor_stretched_section_container' => [ 'label' => __( 'Stretched Section Fit To', 'elementor' ), 'type' => Controls_Manager::TEXT, 'placeholder' => 'body', 'description' => __( 'Enter parent element selector to which stretched sections will fit to (e.g. #primary / .wrapper / main etc). Leave blank to fit to page width.', 'elementor' ), 'label_block' => true, 'frontend_available' => true, ], 'elementor_page_title_selector' => [ 'label' => __( 'Page Title Selector', 'elementor' ), 'type' => Controls_Manager::TEXT, 'placeholder' => 'h1.entry-title', 'description' => __( 'Elementor lets you hide the page title. This works for themes that have "h1.entry-title" selector. If your theme\'s selector is different, please enter it above.', 'elementor' ), 'label_block' => true, ], ], ], ], Manager::PANEL_TAB_LIGHTBOX => [ 'lightbox' => [ 'label' => __( 'Lightbox', 'elementor' ), 'controls' => [ 'elementor_global_image_lightbox' => [ 'label' => __( 'Image Lightbox', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'description' => __( 'Open all image links in a lightbox popup window. The lightbox will automatically work on any link that leads to an image file.', 'elementor' ), 'frontend_available' => true, ], 'elementor_lightbox_enable_counter' => [ 'label' => __( 'Counter', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'frontend_available' => true, ], 'elementor_lightbox_enable_fullscreen' => [ 'label' => __( 'Fullscreen', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'frontend_available' => true, ], 'elementor_lightbox_enable_zoom' => [ 'label' => __( 'Zoom', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'frontend_available' => true, ], 'elementor_lightbox_enable_share' => [ 'label' => __( 'Share', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'frontend_available' => true, ], 'elementor_lightbox_title_src' => [ 'label' => __( 'Title', 'elementor' ), 'type' => Controls_Manager::SELECT, 'options' => [ '' => __( 'None', 'elementor' ), 'title' => __( 'Title', 'elementor' ), 'caption' => __( 'Caption', 'elementor' ), 'alt' => __( 'Alt', 'elementor' ), 'description' => __( 'Description', 'elementor' ), ], 'default' => 'title', 'frontend_available' => true, ], 'elementor_lightbox_description_src' => [ 'label' => __( 'Description', 'elementor' ), 'type' => Controls_Manager::SELECT, 'options' => [ '' => __( 'None', 'elementor' ), 'title' => __( 'Title', 'elementor' ), 'caption' => __( 'Caption', 'elementor' ), 'alt' => __( 'Alt', 'elementor' ), 'description' => __( 'Description', 'elementor' ), ], 'default' => 'description', 'frontend_available' => true, ], 'elementor_lightbox_color' => [ 'label' => __( 'Background Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '.elementor-lightbox' => 'background-color: {{VALUE}}', ], ], 'elementor_lightbox_ui_color' => [ 'label' => __( 'UI Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '.elementor-lightbox' => '--lightbox-ui-color: {{VALUE}}', ], ], 'elementor_lightbox_ui_color_hover' => [ 'label' => __( 'UI Hover Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '.elementor-lightbox' => '--lightbox-ui-color-hover: {{VALUE}}', ], ], 'elementor_lightbox_text_color' => [ 'label' => __( 'Text Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '.elementor-lightbox' => '--lightbox-text-color: {{VALUE}}', ], ], 'lightbox_icons_size' => [ 'label' => __( 'Toolbar Icons Size', 'elementor' ), 'type' => Controls_Manager::SLIDER, 'selectors' => [ '.elementor-lightbox' => '--lightbox-header-icons-size: {{SIZE}}{{UNIT}}', ], 'separator' => 'before', ], 'lightbox_slider_icons_size' => [ 'label' => __( 'Navigation Icons Size', 'elementor' ), 'type' => Controls_Manager::SLIDER, 'selectors' => [ '.elementor-lightbox' => '--lightbox-navigation-icons-size: {{SIZE}}{{UNIT}}', ], 'separator' => 'before', ], ], ], ], ]; } /** * Register model controls. * * Used to add new controls to the global settings model. * * @since 1.6.0 * @access protected */ protected function _register_controls() { $controls_list = self::get_controls_list(); foreach ( $controls_list as $tab_name => $sections ) { foreach ( $sections as $section_name => $section_data ) { $this->start_controls_section( $section_name, [ 'label' => $section_data['label'], 'tab' => $tab_name, ] ); foreach ( $section_data['controls'] as $control_name => $control_data ) { $this->add_control( $control_name, $control_data ); } $this->end_controls_section(); } } } } page/manager.php000066600000020701152141417350007612 0ustar00editor->is_edit_mode() ) { return null; } if ( Plugin::$instance->editor->is_edit_mode() ) { $post_id = Plugin::$instance->editor->get_post_id(); $document = Plugin::$instance->documents->get_doc_or_auto_save( $post_id ); } else { $post_id = get_the_ID(); $document = Plugin::$instance->documents->get_doc_for_frontend( $post_id ); } if ( ! $document ) { return null; } $model = $this->get_model( $document->get_post()->ID ); if ( $document->is_autosave() ) { $model->set_settings( 'post_status', $document->get_main_post()->post_status ); } return $model; } /** * Ajax before saving settings. * * Validate the data before saving it and updating the data in the database. * * @since 1.6.0 * @access public * * @param array $data Post data. * @param int $id Post ID. * * @throws \Exception If invalid post returned using the `$id`. * @throws \Exception If current user don't have permissions to edit the post. */ public function ajax_before_save_settings( array $data, $id ) { $post = get_post( $id ); if ( empty( $post ) ) { throw new \Exception( 'Invalid post.', Exceptions::NOT_FOUND ); } if ( ! current_user_can( 'edit_post', $id ) ) { throw new \Exception( 'Access denied.', Exceptions::FORBIDDEN ); } // Avoid save empty post title. if ( ! empty( $data['post_title'] ) ) { $post->post_title = $data['post_title']; } if ( isset( $data['post_excerpt'] ) && post_type_supports( $post->post_type, 'excerpt' ) ) { $post->post_excerpt = $data['post_excerpt']; } if ( isset( $data['post_status'] ) ) { $this->save_post_status( $id, $data['post_status'] ); unset( $post->post_status ); } wp_update_post( $post ); // Check updated status if ( DB::STATUS_PUBLISH === get_post_status( $id ) ) { $autosave = wp_get_post_autosave( $post->ID ); if ( $autosave ) { wp_delete_post_revision( $autosave->ID ); } } if ( isset( $data['post_featured_image'] ) && post_type_supports( $post->post_type, 'thumbnail' ) ) { if ( empty( $data['post_featured_image']['id'] ) ) { delete_post_thumbnail( $post->ID ); } else { set_post_thumbnail( $post->ID, $data['post_featured_image']['id'] ); } } if ( Utils::is_cpt_custom_templates_supported() ) { $template = get_metadata( 'post', $post->ID, '_wp_page_template', true ); if ( isset( $data['template'] ) ) { $template = $data['template']; } if ( empty( $template ) ) { $template = 'default'; } // Use `update_metadata` in order to save also for revisions. update_metadata( 'post', $post->ID, '_wp_page_template', $template ); } } /** * @inheritDoc * * Override parent because the page setting moved to document.settings. */ protected function print_editor_template_content( $name ) { ?> <# const tabs = elementor.config.document.settings.tabs; if ( Object.values( tabs ).length > 1 ) { #>
<# _.each( tabs, function( tabTitle, tabSlug ) { #>
{{{ tabTitle }}}
<# } ); #>
<# } #>
get_post_id(); if ( $css_file instanceof Post_Preview ) { $autosave = Utils::get_post_autosave( $post_id ); if ( $autosave ) { $post_id = $autosave->ID; } } return $this->get_model( $post_id ); } /** * Get special settings names. * * Retrieve the names of the special settings that are not saved as regular * settings. Those settings have a separate saving process. * * @since 1.6.0 * @access protected * * @return array Special settings names. */ protected function get_special_settings_names() { return [ 'id', 'post_title', 'post_status', 'template', 'post_excerpt', 'post_featured_image', ]; } /** * @since 2.0.0 * @access public * * @param $post_id * @param $status */ public function save_post_status( $post_id, $status ) { $parent_id = wp_is_post_revision( $post_id ); if ( $parent_id ) { // Don't update revisions post-status return; } $parent_id = $post_id; $post = get_post( $parent_id ); $allowed_post_statuses = get_post_statuses(); if ( isset( $allowed_post_statuses[ $status ] ) ) { $post_type_object = get_post_type_object( $post->post_type ); if ( 'publish' !== $status || current_user_can( $post_type_object->cap->publish_posts ) ) { $post->post_status = $status; } } wp_update_post( $post ); } } page/model.php000066600000007552152141417350007311 0ustar00post = get_post( $data['id'] ); if ( ! $this->post ) { $this->post = new \WP_Post( (object) [] ); } if ( wp_is_post_revision( $this->post->ID ) ) { $this->post_parent = get_post( $this->post->post_parent ); } else { $this->post_parent = $this->post; } parent::__construct( $data ); } /** * Get model name. * * Retrieve page settings model name. * * @since 1.6.0 * @access public * * @return string Model name. */ public function get_name() { return 'page-settings'; } /** * Get model unique name. * * Retrieve page settings model unique name. * * @since 1.6.0 * @access public * * @return string Model unique name. */ public function get_unique_name() { return $this->get_name() . '-' . $this->post->ID; } /** * Get CSS wrapper selector. * * Retrieve the wrapper selector for the page settings model. * * @since 1.6.0 * @access public * * @return string CSS wrapper selector. */ public function get_css_wrapper_selector() { $document = Plugin::$instance->documents->get( $this->post_parent->ID ); return $document->get_css_wrapper_selector(); } /** * Get panel page settings. * * Retrieve the panel setting for the page settings model. * * @since 1.6.0 * @access public * * @return array { * Panel settings. * * @type string $title The panel title. * } */ public function get_panel_page_settings() { $document = Plugin::$instance->documents->get( $this->post->ID ); return [ /* translators: %s: Document title */ 'title' => sprintf( __( '%s Settings', 'elementor' ), $document::get_title() ), ]; } /** * On export post meta. * * When exporting data, check if the post is not using page template and * exclude it from the exported Elementor data. * * @since 1.6.0 * @access public * * @param array $element_data Element data. * * @return array Element data to be exported. */ public function on_export( $element_data ) { if ( ! empty( $element_data['settings']['template'] ) ) { /** * @var \Elementor\Modules\PageTemplates\Module $page_templates_module */ $page_templates_module = Plugin::$instance->modules_manager->get_modules( 'page-templates' ); $is_elementor_template = ! ! $page_templates_module->get_template_path( $element_data['settings']['template'] ); if ( ! $is_elementor_template ) { unset( $element_data['settings']['template'] ); } } return $element_data; } /** * Register model controls. * * Used to add new controls to the page settings model. * * @since 1.6.0 * @access protected */ protected function _register_controls() { // Check if it's a real model, or abstract (for example - on import ) if ( $this->post->ID ) { $document = Plugin::$instance->documents->get_doc_or_auto_save( $this->post->ID ); if ( $document ) { $controls = $document->get_controls(); foreach ( $controls as $control_id => $args ) { $this->add_control( $control_id, $args ); } } } } } validations.php000066600000003177152141474540007615 0ustar00files_manager->clear_cache(); return $input; } } controls.php000066600000015410152141474540007134 0ustar00 '', 'attributes' => [], 'std' => '', 'desc' => '', ]; $field = array_merge( $defaults, $field ); $method_name = $field['type']; if ( ! method_exists( __CLASS__, $method_name ) ) { $method_name = 'text'; } self::$method_name( $field ); } /** * Render text control. * * Generates the final HTML for text controls. * * @since 2.0.0 * @access private * @static * * @param array $field Field data. */ private static function text( array $field ) { if ( empty( $field['attributes']['class'] ) ) { $field['attributes']['class'] = 'regular-text'; } $attributes = Utils::render_html_attributes( $field['attributes'] ); ?> />

$option_value ) : ?>

[], ]; $field = array_merge( $defaults, $field ); $post_types_objects = get_post_types( [ 'public' => true, ], 'objects' ); /** * Filters the list of post type objects used by Elementor. * * @since 2.8.0 * * @param array $post_types_objects List of post type objects used by Elementor. */ $post_types_objects = apply_filters( 'elementor/settings/controls/checkbox_list_cpt/post_type_objects', $post_types_objects ); $field['options'] = []; foreach ( $post_types_objects as $cpt_slug => $post_type ) { if ( in_array( $cpt_slug, $field['exclude'], true ) ) { continue; } $field['options'][ $cpt_slug ] = $post_type->labels->name; } self::checkbox_list( $field ); } /** * Render checkbox list control for user roles. * * Generates the final HTML for checkbox list controls populated with user roles. * * @since 2.0.0 * @access private * @static * * @param array $field Field data. */ private static function checkbox_list_roles( array $field ) { $defaults = [ 'exclude' => [], ]; $field = array_merge( $defaults, $field ); $field['options'] = []; $roles = get_editable_roles(); if ( is_multisite() ) { $roles = [ 'super_admin' => [ 'name' => __( 'Super Admin', 'elementor' ), ], ] + $roles; } foreach ( $roles as $role_slug => $role_data ) { if ( in_array( $role_slug, $field['exclude'] ) ) { continue; } $field['options'][ $role_slug ] = $role_data['name']; } self::checkbox_list( $field ); } /** * Render raw HTML control. * * Generates the final HTML for raw HTML controls. * * @since 2.0.0 * @access private * @static * * @param array $field Field data. */ private static function raw_html( array $field ) { if ( empty( $field['html'] ) ) { return; } ?>

$item ) { if ( 'elementor' === $item ) { $elementor_menu_order[] = 'separator-elementor'; $elementor_menu_order[] = $item; $elementor_menu_order[] = Source_Local::ADMIN_MENU_SLUG; unset( $menu_order[ $elementor_separator ] ); unset( $menu_order[ $elementor_library ] ); } elseif ( ! in_array( $item, [ 'separator-elementor' ], true ) ) { $elementor_menu_order[] = $item; } } // Return order. return $elementor_menu_order; } /** * Register Elementor Pro sub-menu. * * Add new Elementor Pro sub-menu under the main Elementor menu. * * Fired by `admin_menu` action. * * @since 1.0.0 * @access public */ public function register_pro_menu() { add_submenu_page( self::PAGE_ID, __( 'Custom Fonts', 'elementor' ), __( 'Custom Fonts', 'elementor' ), 'manage_options', 'elementor_custom_fonts', [ $this, 'elementor_custom_fonts' ] ); add_submenu_page( self::PAGE_ID, __( 'Custom Icons', 'elementor' ), __( 'Custom Icons', 'elementor' ), 'manage_options', 'elementor_custom_icons', [ $this, 'elementor_custom_icons' ] ); add_submenu_page( self::PAGE_ID, '', ' ' . __( 'Go Pro', 'elementor' ), 'manage_options', 'go_elementor_pro', [ $this, 'handle_external_redirects' ] ); add_submenu_page( Source_Local::ADMIN_MENU_SLUG, __( 'Theme Templates', 'elementor' ), __( 'Theme Builder', 'elementor' ), 'manage_options', 'theme_templates', [ $this, 'elementor_theme_templates' ] ); add_submenu_page( Source_Local::ADMIN_MENU_SLUG, __( 'Popups', 'elementor' ), __( 'Popups', 'elementor' ), 'manage_options', 'popup_templates', [ $this, 'elementor_popups' ] ); } /** * Register Elementor knowledge base sub-menu. * * Add new Elementor knowledge base sub-menu under the main Elementor menu. * * Fired by `admin_menu` action. * * @since 2.0.3 * @access public */ public function register_knowledge_base_menu() { add_submenu_page( self::PAGE_ID, '', __( 'Getting Started', 'elementor' ), 'manage_options', 'elementor-getting-started', [ $this, 'elementor_getting_started' ] ); add_submenu_page( self::PAGE_ID, '', __( 'Get Help', 'elementor' ), 'manage_options', 'go_knowledge_base_site', [ $this, 'handle_external_redirects' ] ); } /** * Go Elementor Pro. * * Redirect the Elementor Pro page the clicking the Elementor Pro menu link. * * Fired by `admin_init` action. * * @since 2.0.3 * @access public */ public function handle_external_redirects() { if ( empty( $_GET['page'] ) ) { return; } if ( 'go_elementor_pro' === $_GET['page'] ) { wp_redirect( Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=wp-menu&utm_campaign=gopro&utm_medium=wp-dash' ) ); die; } if ( 'go_knowledge_base_site' === $_GET['page'] ) { wp_redirect( 'https://go.elementor.com/docs-admin-menu/' ); die; } } /** * Display settings page. * * Output the content for the getting started page. * * @since 2.2.0 * @access public */ public function elementor_getting_started() { if ( User::is_current_user_can_edit_post_type( 'page' ) ) { $create_new_label = __( 'Create Your First Page', 'elementor' ); $create_new_cpt = 'page'; } elseif ( User::is_current_user_can_edit_post_type( 'post' ) ) { $create_new_label = __( 'Create Your First Post', 'elementor' ); $create_new_cpt = 'post'; } ?>

handle_external_redirects(); // Save general settings in one list for a future usage $this->handle_general_settings_update(); $this->maybe_remove_all_admin_notices(); } /** * Change "Settings" menu name. * * Update the name of the Settings admin menu from "Elementor" to "Settings". * * Fired by `admin_menu` action. * * @since 1.0.0 * @access public */ public function admin_menu_change_name() { global $submenu; if ( isset( $submenu['elementor'] ) ) { // @codingStandardsIgnoreStart $submenu['elementor'][0][0] = __( 'Settings', 'elementor' ); // @codingStandardsIgnoreEnd } } /** * Update CSS print method. * * Clear post CSS cache. * * Fired by `add_option_elementor_css_print_method` and * `update_option_elementor_css_print_method` actions. * * @since 1.7.5 * @access public */ public function update_css_print_method() { Plugin::$instance->files_manager->clear_cache(); } /** * Create tabs. * * Return the settings page tabs, sections and fields. * * @since 1.5.0 * @access protected * * @return array An array with the settings page tabs, sections and fields. */ protected function create_tabs() { $validations_class_name = __NAMESPACE__ . '\Settings_Validations'; $default_breakpoints = Responsive::get_default_breakpoints(); return [ self::TAB_GENERAL => [ 'label' => __( 'General', 'elementor' ), 'sections' => [ 'general' => [ 'fields' => [ self::UPDATE_TIME_FIELD => [ 'full_field_id' => self::UPDATE_TIME_FIELD, 'field_args' => [ 'type' => 'hidden', ], 'setting_args' => [ $validations_class_name, 'current_time' ], ], 'cpt_support' => [ 'label' => __( 'Post Types', 'elementor' ), 'field_args' => [ 'type' => 'checkbox_list_cpt', 'std' => [ 'page', 'post' ], 'exclude' => [ 'attachment', 'elementor_library' ], ], 'setting_args' => [ $validations_class_name, 'checkbox_list' ], ], 'disable_color_schemes' => [ 'label' => __( 'Disable Default Colors', 'elementor' ), 'field_args' => [ 'type' => 'checkbox', 'value' => 'yes', 'sub_desc' => __( 'Checking this box will disable Elementor\'s Default Colors, and make Elementor inherit the colors from your theme.', 'elementor' ), ], ], 'disable_typography_schemes' => [ 'label' => __( 'Disable Default Fonts', 'elementor' ), 'field_args' => [ 'type' => 'checkbox', 'value' => 'yes', 'sub_desc' => __( 'Checking this box will disable Elementor\'s Default Fonts, and make Elementor inherit the fonts from your theme.', 'elementor' ), ], ], ], ], 'usage' => [ 'label' => __( 'Improve Elementor', 'elementor' ), 'fields' => [ 'allow_tracking' => [ 'label' => __( 'Usage Data Sharing', 'elementor' ), 'field_args' => [ 'type' => 'checkbox', 'value' => 'yes', 'default' => '', 'sub_desc' => __( 'Become a super contributor by opting in to share non-sensitive plugin data and to get our updates.', 'elementor' ) . sprintf( ' %2$s', 'https://go.elementor.com/usage-data-tracking/', __( 'Learn more.', 'elementor' ) ), ], 'setting_args' => [ __NAMESPACE__ . '\Tracker', 'check_for_settings_optin' ], ], ], ], ], ], self::TAB_STYLE => [ 'label' => __( 'Style', 'elementor' ), 'sections' => [ 'style' => [ 'fields' => [ 'default_generic_fonts' => [ 'label' => __( 'Default Generic Fonts', 'elementor' ), 'field_args' => [ 'type' => 'text', 'std' => 'Sans-serif', 'class' => 'medium-text', 'desc' => __( 'The list of fonts used if the chosen font is not available.', 'elementor' ), ], ], 'container_width' => [ 'label' => __( 'Content Width', 'elementor' ), 'field_args' => [ 'type' => 'number', 'attributes' => [ 'min' => 300, 'placeholder' => '1140', 'class' => 'medium-text', ], 'sub_desc' => 'px', 'desc' => __( 'Sets the default width of the content area (Default: 1140)', 'elementor' ), ], ], 'space_between_widgets' => [ 'label' => __( 'Space Between Widgets', 'elementor' ), 'field_args' => [ 'type' => 'number', 'attributes' => [ 'placeholder' => '20', 'class' => 'medium-text', ], 'sub_desc' => 'px', 'desc' => __( 'Sets the default space between widgets (Default: 20)', 'elementor' ), ], ], 'stretched_section_container' => [ 'label' => __( 'Stretched Section Fit To', 'elementor' ), 'field_args' => [ 'type' => 'text', 'attributes' => [ 'placeholder' => 'body', 'class' => 'medium-text', ], 'desc' => __( 'Enter parent element selector to which stretched sections will fit to (e.g. #primary / .wrapper / main etc). Leave blank to fit to page width.', 'elementor' ), ], ], 'page_title_selector' => [ 'label' => __( 'Page Title Selector', 'elementor' ), 'field_args' => [ 'type' => 'text', 'attributes' => [ 'placeholder' => 'h1.entry-title', 'class' => 'medium-text', ], 'desc' => __( 'Elementor lets you hide the page title. This works for themes that have "h1.entry-title" selector. If your theme\'s selector is different, please enter it above.', 'elementor' ), ], ], 'viewport_lg' => [ 'label' => __( 'Tablet Breakpoint', 'elementor' ), 'field_args' => [ 'type' => 'number', 'attributes' => [ 'placeholder' => $default_breakpoints['lg'], 'min' => $default_breakpoints['md'] + 1, 'max' => $default_breakpoints['xl'] - 1, 'class' => 'medium-text', ], 'sub_desc' => 'px', /* translators: %d: Breakpoint value */ 'desc' => sprintf( __( 'Sets the breakpoint between desktop and tablet devices. Below this breakpoint tablet layout will appear (Default: %dpx).', 'elementor' ), $default_breakpoints['lg'] ), ], ], 'viewport_md' => [ 'label' => __( 'Mobile Breakpoint', 'elementor' ), 'field_args' => [ 'type' => 'number', 'attributes' => [ 'placeholder' => $default_breakpoints['md'], 'min' => $default_breakpoints['sm'] + 1, 'max' => $default_breakpoints['lg'] - 1, 'class' => 'medium-text', ], 'sub_desc' => 'px', /* translators: %d: Breakpoint value */ 'desc' => sprintf( __( 'Sets the breakpoint between tablet and mobile devices. Below this breakpoint mobile layout will appear (Default: %dpx).', 'elementor' ), $default_breakpoints['md'] ), ], ], 'global_image_lightbox' => [ 'label' => __( 'Image Lightbox', 'elementor' ), 'field_args' => [ 'type' => 'checkbox', 'value' => 'yes', 'std' => 'yes', 'sub_desc' => __( 'Open all image links in a lightbox popup window. The lightbox will automatically work on any link that leads to an image file.', 'elementor' ), 'desc' => __( 'You can customize the lightbox design by going to: Top-left hamburger icon > Global Settings > Lightbox.', 'elementor' ), ], ], ], ], ], ], self::TAB_INTEGRATIONS => [ 'label' => __( 'Integrations', 'elementor' ), 'sections' => [], ], self::TAB_ADVANCED => [ 'label' => __( 'Advanced', 'elementor' ), 'sections' => [ 'advanced' => [ 'fields' => [ 'css_print_method' => [ 'label' => __( 'CSS Print Method', 'elementor' ), 'field_args' => [ 'class' => 'elementor_css_print_method', 'type' => 'select', 'options' => [ 'external' => __( 'External File', 'elementor' ), 'internal' => __( 'Internal Embedding', 'elementor' ), ], 'desc' => '', ], ], 'editor_break_lines' => [ 'label' => __( 'Switch Editor Loader Method', 'elementor' ), 'field_args' => [ 'type' => 'select', 'options' => [ '' => __( 'Disable', 'elementor' ), 1 => __( 'Enable', 'elementor' ), ], 'desc' => __( 'For troubleshooting server configuration conflicts.', 'elementor' ), ], ], 'allow_svg' => [ 'label' => __( 'Enable SVG Uploads', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => '', 'options' => [ '' => __( 'Disable', 'elementor' ), 1 => __( 'Enable', 'elementor' ), ], 'desc' => __( 'Please note! Allowing uploads of any files (SVG included) is a potential security risk.', 'elementor' ) . '
' . __( 'Elementor will try to sanitize the SVG files, removing potential malicious code and scripts.', 'elementor' ) . '
' . __( 'We recommend you only enable this feature if you understand the security risks involved.', 'elementor' ), ], ], ], ], ], ], ]; } /** * Get settings page title. * * Retrieve the title for the settings page. * * @since 1.5.0 * @access protected * * @return string Settings page title. */ protected function get_page_title() { return __( 'Elementor', 'elementor' ); } /** * Handle general settings update. * * Save general settings in one list for a future usage. * * @since 2.0.0 * @access private */ private function handle_general_settings_update() { if ( ! empty( $_POST['option_page'] ) && self::PAGE_ID === $_POST['option_page'] && ! empty( $_POST['action'] ) && 'update' === $_POST['action'] ) { check_admin_referer( 'elementor-options' ); $saved_general_settings = get_option( General_Settings_Manager::META_KEY ); if ( ! $saved_general_settings ) { $saved_general_settings = []; } $general_settings = Manager::get_settings_managers( 'general' )->get_model()->get_settings(); foreach ( $general_settings as $setting_key => $setting ) { if ( ! empty( $_POST[ $setting_key ] ) ) { $pure_setting_key = str_replace( 'elementor_', '', $setting_key ); $saved_general_settings[ $pure_setting_key ] = $_POST[ $setting_key ]; } } update_option( General_Settings_Manager::META_KEY, $saved_general_settings ); } } /** * @since 2.2.0 * @access private */ private function maybe_remove_all_admin_notices() { $elementor_pages = [ 'elementor-getting-started', 'elementor_custom_fonts', 'elementor_custom_icons', 'elementor-license', 'popup_templates', 'theme_templates', ]; if ( empty( $_GET['page'] ) || ! in_array( $_GET['page'], $elementor_pages, true ) ) { return; } remove_all_actions( 'admin_notices' ); } /** * Settings page constructor. * * Initializing Elementor "Settings" page. * * @since 1.0.0 * @access public */ public function __construct() { parent::__construct(); add_action( 'admin_init', [ $this, 'on_admin_init' ] ); add_action( 'admin_menu', [ $this, 'register_admin_menu' ], 20 ); add_action( 'admin_menu', [ $this, 'admin_menu_change_name' ], 200 ); add_action( 'admin_menu', [ $this, 'register_pro_menu' ], self::MENU_PRIORITY_GO_PRO ); add_action( 'admin_menu', [ $this, 'register_knowledge_base_menu' ], 501 ); // Clear CSS Meta after change print method. add_action( 'add_option_elementor_css_print_method', [ $this, 'update_css_print_method' ] ); add_action( 'update_option_elementor_css_print_method', [ $this, 'update_css_print_method' ] ); add_filter( 'custom_menu_order', '__return_true' ); add_filter( 'menu_order', [ $this, 'menu_order' ] ); foreach ( Responsive::get_editable_breakpoints() as $breakpoint_key => $breakpoint ) { foreach ( [ 'add', 'update' ] as $action ) { add_action( "{$action}_option_elementor_viewport_{$breakpoint_key}", [ 'Elementor\Core\Responsive\Responsive', 'compile_stylesheet_templates' ] ); } } } } settings-page.php000066600000021163152141474540010045 0ustar00ensure_tabs(); return $this->tabs; } /** * Add tab. * * Register a new tab to a settings page. * * @since 1.5.0 * @access public * * @param string $tab_id Tab ID. * @param array $tab_args Optional. Tab arguments. Default is an empty array. */ final public function add_tab( $tab_id, array $tab_args = [] ) { $this->ensure_tabs(); if ( isset( $this->tabs[ $tab_id ] ) ) { // Don't override an existing tab return; } if ( ! isset( $tab_args['sections'] ) ) { $tab_args['sections'] = []; } $this->tabs[ $tab_id ] = $tab_args; } /** * Add section. * * Register a new section to a tab. * * @since 1.5.0 * @access public * * @param string $tab_id Tab ID. * @param string $section_id Section ID. * @param array $section_args Optional. Section arguments. Default is an * empty array. */ final public function add_section( $tab_id, $section_id, array $section_args = [] ) { $this->ensure_tabs(); if ( ! isset( $this->tabs[ $tab_id ] ) ) { // If the requested tab doesn't exists, use the first tab $tab_id = key( $this->tabs ); } if ( isset( $this->tabs[ $tab_id ]['sections'][ $section_id ] ) ) { // Don't override an existing section return; } if ( ! isset( $section_args['fields'] ) ) { $section_args['fields'] = []; } $this->tabs[ $tab_id ]['sections'][ $section_id ] = $section_args; } /** * Add field. * * Register a new field to a section. * * @since 1.5.0 * @access public * * @param string $tab_id Tab ID. * @param string $section_id Section ID. * @param string $field_id Field ID. * @param array $field_args Field arguments. */ final public function add_field( $tab_id, $section_id, $field_id, array $field_args ) { $this->ensure_tabs(); if ( ! isset( $this->tabs[ $tab_id ] ) ) { // If the requested tab doesn't exists, use the first tab $tab_id = key( $this->tabs ); } if ( ! isset( $this->tabs[ $tab_id ]['sections'][ $section_id ] ) ) { // If the requested section doesn't exists, use the first section $section_id = key( $this->tabs[ $tab_id ]['sections'] ); } if ( isset( $this->tabs[ $tab_id ]['sections'][ $section_id ]['fields'][ $field_id ] ) ) { // Don't override an existing field return; } $this->tabs[ $tab_id ]['sections'][ $section_id ]['fields'][ $field_id ] = $field_args; } /** * Add fields. * * Register multiple fields to a section. * * @since 1.5.0 * @access public * * @param string $tab_id Tab ID. * @param string $section_id Section ID. * @param array $fields { * An array of fields. * * @type string $field_id Field ID. * @type array $field_args Field arguments. * } */ final public function add_fields( $tab_id, $section_id, array $fields ) { foreach ( $fields as $field_id => $field_args ) { $this->add_field( $tab_id, $section_id, $field_id, $field_args ); } } /** * Register settings fields. * * In each tab register his inner sections, and in each section register his * inner fields. * * @since 1.5.0 * @access public */ final public function register_settings_fields() { $controls_class_name = __NAMESPACE__ . '\Settings_Controls'; $tabs = $this->get_tabs(); foreach ( $tabs as $tab_id => $tab ) { foreach ( $tab['sections'] as $section_id => $section ) { $full_section_id = 'elementor_' . $section_id . '_section'; $label = isset( $section['label'] ) ? $section['label'] : ''; $section_callback = isset( $section['callback'] ) ? $section['callback'] : '__return_empty_string'; add_settings_section( $full_section_id, $label, $section_callback, static::PAGE_ID ); foreach ( $section['fields'] as $field_id => $field ) { $full_field_id = ! empty( $field['full_field_id'] ) ? $field['full_field_id'] : 'elementor_' . $field_id; $field['field_args']['id'] = $full_field_id; $field_classes = [ $full_field_id ]; if ( ! empty( $field['class'] ) ) { $field_classes[] = $field['field_args']['class']; } $field['field_args']['class'] = implode( ' ', $field_classes ); add_settings_field( $full_field_id, isset( $field['label'] ) ? $field['label'] : '', [ $controls_class_name, 'render' ], static::PAGE_ID, $full_section_id, $field['field_args'] ); $setting_args = []; if ( ! empty( $field['setting_args'] ) ) { $setting_args = $field['setting_args']; } register_setting( static::PAGE_ID, $full_field_id, $setting_args ); } } } } /** * Display settings page. * * Output the content for the settings page. * * @since 1.5.0 * @access public */ public function display_settings_page() { $this->register_settings_fields(); $tabs = $this->get_tabs(); ?>

get_page_title(); ?>

$tab ) { if ( empty( $tab['sections'] ) ) { continue; } $active_class = ''; if ( 'general' === $tab_id ) { $active_class = ' elementor-active'; } echo "
"; foreach ( $tab['sections'] as $section_id => $section ) { $full_section_id = 'elementor_' . $section_id . '_section'; if ( ! empty( $section['label'] ) ) { echo "

{$section['label']}

"; } if ( ! empty( $section['callback'] ) ) { $section['callback'](); } echo ''; do_settings_fields( static::PAGE_ID, $full_section_id ); echo '
'; } echo '
'; } submit_button(); ?>
tabs ) { $this->tabs = $this->create_tabs(); $page_id = static::PAGE_ID; /** * After create settings. * * Fires after the settings are created in Elementor admin page. * * The dynamic portion of the hook name, `$page_id`, refers to the current page ID. * * @since 1.0.0 * * @param Settings_Page $this The settings page. */ do_action( "elementor/admin/after_create_settings/{$page_id}", $this ); } } } tools.php000066600000024355152141474540006441 0ustar00files_manager->clear_cache(); wp_send_json_success(); } /** * Replace URLs. * * Sends an ajax request to replace old URLs to new URLs. This method also * updates all the Elementor data. * * Fired by `wp_ajax_elementor_replace_url` action. * * @since 1.1.0 * @access public */ public function ajax_elementor_replace_url() { check_ajax_referer( 'elementor_replace_url', '_nonce' ); $from = ! empty( $_POST['from'] ) ? $_POST['from'] : ''; $to = ! empty( $_POST['to'] ) ? $_POST['to'] : ''; try { $results = Utils::replace_urls( $from, $to ); wp_send_json_success( $results ); } catch ( \Exception $e ) { wp_send_json_error( $e->getMessage() ); } } /** * Elementor version rollback. * * Rollback to previous Elementor version. * * Fired by `admin_post_elementor_rollback` action. * * @since 1.5.0 * @access public */ public function post_elementor_rollback() { check_admin_referer( 'elementor_rollback' ); $rollback_versions = $this->get_rollback_versions(); if ( empty( $_GET['version'] ) || ! in_array( $_GET['version'], $rollback_versions ) ) { wp_die( __( 'Error occurred, The version selected is invalid. Try selecting different version.', 'elementor' ) ); } $plugin_slug = basename( ELEMENTOR__FILE__, '.php' ); $rollback = new Rollback( [ 'version' => $_GET['version'], 'plugin_name' => ELEMENTOR_PLUGIN_BASE, 'plugin_slug' => $plugin_slug, 'package_url' => sprintf( 'https://downloads.wordpress.org/plugin/%s.%s.zip', $plugin_slug, $_GET['version'] ), ] ); $rollback->run(); wp_die( '', __( 'Rollback to Previous Version', 'elementor' ), [ 'response' => 200, ] ); } /** * Tools page constructor. * * Initializing Elementor "Tools" page. * * @since 1.0.0 * @access public */ public function __construct() { parent::__construct(); add_action( 'admin_menu', [ $this, 'register_admin_menu' ], 205 ); if ( ! empty( $_POST ) ) { add_action( 'wp_ajax_elementor_clear_cache', [ $this, 'ajax_elementor_clear_cache' ] ); add_action( 'wp_ajax_elementor_replace_url', [ $this, 'ajax_elementor_replace_url' ] ); } add_action( 'admin_post_elementor_rollback', [ $this, 'post_elementor_rollback' ] ); } private function get_rollback_versions() { $rollback_versions = get_transient( 'elementor_rollback_versions_' . ELEMENTOR_VERSION ); if ( false === $rollback_versions ) { $max_versions = 30; require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; $plugin_information = plugins_api( 'plugin_information', [ 'slug' => 'elementor', ] ); if ( empty( $plugin_information->versions ) || ! is_array( $plugin_information->versions ) ) { return []; } krsort( $plugin_information->versions ); $rollback_versions = []; $current_index = 0; foreach ( $plugin_information->versions as $version => $download_link ) { if ( $max_versions <= $current_index ) { break; } if ( preg_match( '/(trunk|beta|rc)/i', strtolower( $version ) ) ) { continue; } if ( version_compare( $version, ELEMENTOR_VERSION, '>=' ) ) { continue; } $current_index++; $rollback_versions[] = $version; } set_transient( 'elementor_rollback_versions_' . ELEMENTOR_VERSION, $rollback_versions, WEEK_IN_SECONDS ); } return $rollback_versions; } /** * Create tabs. * * Return the tools page tabs, sections and fields. * * @since 1.5.0 * @access protected * * @return array An array with the page tabs, sections and fields. */ protected function create_tabs() { $rollback_html = ''; return [ 'general' => [ 'label' => __( 'General', 'elementor' ), 'sections' => [ 'tools' => [ 'fields' => [ 'clear_cache' => [ 'label' => __( 'Regenerate CSS', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( '', wp_create_nonce( 'elementor_clear_cache' ), __( 'Regenerate Files', 'elementor' ) ), 'desc' => __( 'Styles set in Elementor are saved in CSS files in the uploads folder. Recreate those files, according to the most recent settings.', 'elementor' ), ], ], 'reset_api_data' => [ 'label' => __( 'Sync Library', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( '', wp_create_nonce( 'elementor_reset_library' ), __( 'Sync Library', 'elementor' ) ), 'desc' => __( 'Elementor Library automatically updates on a daily basis. You can also manually update it by clicking on the sync button.', 'elementor' ), ], ], ], ], ], ], 'replace_url' => [ 'label' => __( 'Replace URL', 'elementor' ), 'sections' => [ 'replace_url' => [ 'callback' => function() { $intro_text = sprintf( /* translators: %s: Codex URL */ __( 'Important: It is strongly recommended that you backup your database before using Replace URL.', 'elementor' ), 'https://codex.wordpress.org/WordPress_Backups' ); $intro_text = '
' . $intro_text . '
'; echo '

' . esc_html__( 'Replace URL', 'elementor' ) . '

'; echo $intro_text; }, 'fields' => [ 'replace_url' => [ 'label' => __( 'Update Site Address (URL)', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( '', wp_create_nonce( 'elementor_replace_url' ), __( 'Replace URL', 'elementor' ) ), 'desc' => __( 'Enter your old and new URLs for your WordPress installation, to update all Elementor data (Relevant for domain transfers or move to \'HTTPS\').', 'elementor' ), ], ], ], ], ], ], 'versions' => [ 'label' => __( 'Version Control', 'elementor' ), 'sections' => [ 'rollback' => [ 'label' => __( 'Rollback to Previous Version', 'elementor' ), 'callback' => function() { $intro_text = sprintf( /* translators: %s: Elementor version */ __( 'Experiencing an issue with Elementor version %s? Rollback to a previous version before the issue appeared.', 'elementor' ), ELEMENTOR_VERSION ); $intro_text = '

' . $intro_text . '

'; echo $intro_text; }, 'fields' => [ 'rollback' => [ 'label' => __( 'Rollback Version', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( $rollback_html . '%s', wp_nonce_url( admin_url( 'admin-post.php?action=elementor_rollback&version=VERSION' ), 'elementor_rollback' ), __( 'Reinstall', 'elementor' ) ), 'desc' => '' . __( 'Warning: Please backup your database before making the rollback.', 'elementor' ) . '', ], ], ], ], 'beta' => [ 'label' => __( 'Become a Beta Tester', 'elementor' ), 'callback' => function() { $intro_text = __( 'Turn-on Beta Tester, to get notified when a new beta version of Elementor or Elementor Pro is available. The Beta version will not install automatically. You always have the option to ignore it.', 'elementor' ); $intro_text = '

' . $intro_text . '

'; $newsletter_opt_in_text = sprintf( __( 'Click here to join our first-to-know email updates.', 'elementor' ), '#' ); echo $intro_text; echo $newsletter_opt_in_text; }, 'fields' => [ 'beta' => [ 'label' => __( 'Beta Tester', 'elementor' ), 'field_args' => [ 'type' => 'select', 'default' => 'no', 'options' => [ 'no' => __( 'Disable', 'elementor' ), 'yes' => __( 'Enable', 'elementor' ), ], 'desc' => '' . __( 'Please Note: We do not recommend updating to a beta version on production sites.', 'elementor' ) . '', ], ], ], ], ], ], ]; } /** * Get tools page title. * * Retrieve the title for the tools page. * * @since 1.5.0 * @access protected * * @return string Tools page title. */ protected function get_page_title() { return __( 'Tools', 'elementor' ); } }