Файловый менеджер - Редактировать - /var/www/xthruster/html/wp-content/uploads/flags/settings.tar
Назад
tools.php 0000644 00000036021 14720521203 0006413 0 ustar 00 <?php namespace Elementor; use Elementor\Core\Admin\Menu\Admin_Menu_Manager; use Elementor\Core\Admin\Menu\Main as MainMenu; use Elementor\Core\Kits\Manager; use Elementor\Includes\Settings\AdminMenuItems\Tools_Menu_Item; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor "Tools" page in WordPress Dashboard. * * Elementor settings page handler class responsible for creating and displaying * Elementor "Tools" page in WordPress dashboard. * * @since 1.0.0 */ class Tools extends Settings_Page { const CAPABILITY = 'manage_options'; /** * Settings page ID for Elementor tools. */ const PAGE_ID = 'elementor-tools'; private function register_admin_menu( MainMenu $menu ) { $menu->add_submenu( [ 'page_title' => esc_html__( 'Tools', 'elementor' ), 'menu_title' => esc_html__( 'Tools', 'elementor' ), 'menu_slug' => self::PAGE_ID, 'function' => [ $this, 'display_settings_page' ], 'index' => 50, ] ); } /** * Clear cache. * * Delete post meta containing the post CSS file data. And delete the actual * CSS files from the upload directory. * * Fired by `wp_ajax_elementor_clear_cache` action. * * @since 1.0.0 * @access public */ public function ajax_elementor_clear_cache() { check_ajax_referer( 'elementor_clear_cache', '_nonce' ); if ( ! current_user_can( static::CAPABILITY ) ) { wp_send_json_error( 'Permission denied' ); } Plugin::$instance->files_manager->clear_cache(); wp_send_json_success(); } /** * Recreate kit. * * Recreate default kit (only when default kit does not exist). * * Fired by `wp_ajax_elementor_recreate_kit` action. * * @since 1.0.0 * @access public */ public function ajax_elementor_recreate_kit() { check_ajax_referer( 'elementor_recreate_kit', '_nonce' ); if ( ! current_user_can( static::CAPABILITY ) ) { wp_send_json_error( 'Permission denied' ); } $kit = Plugin::$instance->kits_manager->get_active_kit(); if ( $kit->get_id() ) { wp_send_json_error( [ 'message' => esc_html__( 'There\'s already an active kit.', 'elementor' ) ], 400 ); } $created_default_kit = Plugin::$instance->kits_manager->create_default(); if ( ! $created_default_kit ) { wp_send_json_error( [ 'message' => esc_html__( 'An error occurred while trying to create a kit.', 'elementor' ) ], 500 ); } update_option( Manager::OPTION_ACTIVE, $created_default_kit ); wp_send_json_success( esc_html__( 'New kit have been created successfully', 'elementor' ) ); } /** * 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' ); if ( ! current_user_can( static::CAPABILITY ) ) { wp_send_json_error( 'Permission denied' ); } $from = Utils::get_super_global_value( $_POST, 'from' ) ?? ''; $to = Utils::get_super_global_value( $_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' ); if ( ! static::can_user_rollback_versions() ) { wp_die( esc_html__( 'Not allowed to rollback versions', 'elementor' ) ); } $rollback_versions = $this->get_rollback_versions(); $version = Utils::get_super_global_value( $_GET, 'version' ); if ( empty( $version ) || ! in_array( $version, $rollback_versions, true ) ) { wp_die( esc_html__( 'An error occurred, the selected version is invalid. Try selecting different version.', 'elementor' ) ); } /** * Filter to allow override the rollback process. * Should return an instance of `Rollback` class. * * @since 3.16.0 * * @param Rollback|null $rollback The rollback instance. * @param string $version The version to roll back to. */ $rollback = apply_filters( 'elementor/settings/rollback', null, $version ); if ( ! ( $rollback instanceof Rollback ) ) { $plugin_slug = basename( ELEMENTOR__FILE__, '.php' ); $rollback = new Rollback( [ 'version' => $version, 'plugin_name' => ELEMENTOR_PLUGIN_BASE, 'plugin_slug' => $plugin_slug, 'package_url' => sprintf( 'https://downloads.wordpress.org/plugin/%s.%s.zip', $plugin_slug, $version ), ] ); } $rollback->run(); wp_die( '', esc_html__( '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( 'elementor/admin/menu/register', function( Admin_Menu_Manager $admin_menu ) { $admin_menu->register( static::PAGE_ID, new Tools_Menu_Item( $this ) ); }, Settings::ADMIN_MENU_PRIORITY + 20 ); 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( 'wp_ajax_elementor_recreate_kit', [ $this, 'ajax_elementor_recreate_kit' ] ); 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; $versions = apply_filters( 'elementor/settings/rollback/versions', [] ); if ( empty( $versions ) ) { 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 []; } uksort( $plugin_information->versions, 'version_compare' ); $versions = array_keys( array_reverse( $plugin_information->versions ) ); } $rollback_versions = []; $current_index = 0; foreach ( $versions as $version ) { if ( $max_versions <= $current_index ) { break; } $lowercase_version = strtolower( $version ); $is_valid_rollback_version = ! preg_match( '/(trunk|beta|rc|dev)/i', $lowercase_version ); /** * Is rollback version is valid. * * Filters the check whether the rollback version is valid. * * @param bool $is_valid_rollback_version Whether the rollback version is valid. */ $is_valid_rollback_version = apply_filters( 'elementor/settings/tools/rollback/is_valid_rollback_version', $is_valid_rollback_version, $lowercase_version ); if ( ! $is_valid_rollback_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 = '<select class="elementor-rollback-select">'; foreach ( $this->get_rollback_versions() as $version ) { $rollback_html .= "<option value='{$version}'>$version</option>"; } $rollback_html .= '</select>'; $tabs = [ 'general' => [ 'label' => esc_html__( 'General', 'elementor' ), 'sections' => [ 'tools' => [ 'fields' => [ 'clear_cache' => [ 'label' => esc_html__( 'Regenerate CSS & Data', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( '<button data-nonce="%s" class="button elementor-button-spinner" id="elementor-clear-cache-button">%s</button>', wp_create_nonce( 'elementor_clear_cache' ), esc_html__( 'Regenerate Files & Data', 'elementor' ) ), 'desc' => esc_html__( 'Styles set in Elementor are saved in CSS files in the uploads folder and in the site’s database. Recreate those files and settings, according to the most recent settings.', 'elementor' ), ], ], 'reset_api_data' => [ 'label' => esc_html__( 'Sync Library', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( '<button data-nonce="%s" class="button elementor-button-spinner" id="elementor-library-sync-button">%s</button>', wp_create_nonce( 'elementor_reset_library' ), esc_html__( 'Sync Library', 'elementor' ) ), 'desc' => esc_html__( 'Elementor Library automatically updates on a daily basis. You can also manually update it by clicking on the sync button.', 'elementor' ), ], ], ], ], ], ], 'replace_url' => [ 'label' => esc_html__( 'Replace URL', 'elementor' ), 'sections' => [ 'replace_url' => [ 'callback' => function() { echo '<h2>' . esc_html__( 'Replace URL', 'elementor' ) . '</h2>'; echo sprintf( '<p><strong>%1$s</strong> %2$s</p>', esc_html__( 'Important:', 'elementor' ), sprintf( /* translators: 1: Link open tag, 2: Link close tag. */ esc_html__( 'It is strongly recommended to %1$sbackup the database%2$s before using replacing URLs.', 'elementor' ), '<a href="https://go.elementor.com/wordpress-backups/" target="_blank">', '</a>' ) ); }, 'fields' => [ 'replace_url' => [ 'label' => esc_html__( 'Update Site Address (URL)', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( '<input type="text" name="from" placeholder="https://old.example.com" class="large-text"><input type="text" name="to" placeholder="https://new.example.com" class="large-text"><button data-nonce="%s" class="button elementor-button-spinner" id="elementor-replace-url-button">%s</button>', wp_create_nonce( 'elementor_replace_url' ), esc_html__( 'Replace URL', 'elementor' ) ), 'desc' => esc_html__( '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' => [ 'show_if' => static::can_user_rollback_versions(), 'label' => esc_html__( 'Version Control', 'elementor' ), 'sections' => [ 'rollback' => [ 'label' => esc_html__( 'Rollback to Previous Version', 'elementor' ), 'callback' => function() { $intro_text = sprintf( /* translators: %s: Elementor version. */ esc_html__( 'Experiencing an issue with Elementor version %s? Rollback to a previous version before the issue appeared.', 'elementor' ), ELEMENTOR_VERSION ); $intro_text = '<p>' . $intro_text . '</p>'; Utils::print_unescaped_internal_string( $intro_text ); }, 'fields' => [ 'rollback' => [ 'label' => esc_html__( 'Rollback Version', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( $rollback_html . '<a data-placeholder-text="%1$s v{VERSION}" href="#" data-placeholder-url="%2$s" class="button elementor-button-spinner elementor-rollback-button">%1$s</a>', esc_html__( 'Reinstall', 'elementor' ), wp_nonce_url( admin_url( 'admin-post.php?action=elementor_rollback&version=VERSION' ), 'elementor_rollback' ) ), 'desc' => '<span style="color: red;">' . esc_html__( 'Warning: Please backup your database before making the rollback.', 'elementor' ) . '</span>', ], ], ], ], 'beta' => [ 'show_if' => $this->display_beta_tester(), 'label' => esc_html__( 'Become a Beta Tester', 'elementor' ), 'callback' => function() { echo '<p>' . esc_html__( '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' ) . '</p>'; echo '<p>' . sprintf( /* translators: 1: Link open tag, 2: Link close tag. */ esc_html__( '%1$sClick here%2$s %3$sto join our first-to-know email updates.%4$s', 'elementor' ), '<a id="beta-tester-first-to-know" class="elementor-become-a-beta-tester" href="#">', '</a>', '<span class="elementor-become-a-beta-tester">', '</span>', ) . '</p>'; }, 'fields' => [ 'beta' => [ 'label' => esc_html__( 'Beta Tester', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => 'no', 'options' => [ 'no' => esc_html__( 'Disable', 'elementor' ), 'yes' => esc_html__( 'Enable', 'elementor' ), ], 'desc' => '<span style="color: red;">' . esc_html__( 'Please Note: We do not recommend updating to a beta version on production sites.', 'elementor' ) . '</span>', ], ], ], ], ], ], ]; if ( ! Plugin::$instance->kits_manager->get_active_kit()->get_id() ) { $tabs['general']['sections']['tools']['fields']['recreate_kit'] = [ 'label' => esc_html__( 'Recreate Kit', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( '<button data-nonce="%s" class="button elementor-button-spinner" id="elementor-recreate-kit-button">%s</button>', wp_create_nonce( 'elementor_recreate_kit' ), esc_html__( 'Recreate Kit', 'elementor' ) ), 'desc' => esc_html__( 'It seems like your site doesn\'t have any active Kit. The active Kit includes all of your Site Settings. By recreating your Kit you will able to start edit your Site Settings again.', 'elementor' ), ], ]; } return $tabs; } /** * 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 esc_html__( 'Tools', 'elementor' ); } /** * Check if the current user can access the version control tab and rollback versions. * * @return bool */ public static function can_user_rollback_versions() { return current_user_can( 'activate_plugins' ) && current_user_can( 'update_plugins' ); } /** * Check if the beta tester should be displayed. * * @since 3.19.0 * * @return bool */ public function display_beta_tester(): bool { $display_beta_tester = true; /** * Filter to allow override the display of the beta tester. * * @param bool $display_beta_tester Whether to display the beta tester. * * @since 3.19.0 * * return bool */ return apply_filters( 'elementor/admin/show_beta_tester', $display_beta_tester ); } } controls.php 0000644 00000016107 14720521203 0007121 0 ustar 00 <?php namespace Elementor; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor settings controls. * * Elementor settings controls handler class responsible for creating the final * HTML for various input field types used in Elementor settings pages. * * @since 1.0.0 */ class Settings_Controls { /** * Render settings control. * * Generates the final HTML on the frontend for any given field based on * the field type (text, select, checkbox, raw HTML, etc.). * * @since 1.0.0 * @access public * @static * * @param array $field Optional. Field data. Default is an empty array. */ public static function render( $field = [] ) { if ( empty( $field ) || empty( $field['id'] ) ) { return; } $defaults = [ 'type' => '', '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'; } ?> <input type="<?php echo esc_attr( $field['type'] ); ?>" id="<?php echo esc_attr( $field['id'] ); ?>" name="<?php echo esc_attr( $field['id'] ); ?>" value="<?php echo esc_attr( get_option( $field['id'], $field['std'] ) ); ?>" <?php Utils::print_html_attributes( $field['attributes'] ); ?>/> <?php if ( ! empty( $field['sub_desc'] ) ) : echo wp_kses_post( $field['sub_desc'] ); endif; ?> <?php if ( ! empty( $field['desc'] ) ) : ?> <p class="description"><?php echo wp_kses_post( $field['desc'] ); ?></p> <?php endif; } /** * Render checkbox control. * * Generates the final HTML for checkbox controls. * * @since 2.0.0 * @access private * @static * * @param array $field Field data. */ private static function checkbox( array $field ) { ?> <label> <input type="<?php echo esc_attr( $field['type'] ); ?>" id="<?php echo esc_attr( $field['id'] ); ?>" name="<?php echo esc_attr( $field['id'] ); ?>" value="<?php echo esc_attr( $field['value'] ); ?>"<?php checked( $field['value'], get_option( $field['id'], $field['std'] ) ); ?> /> <?php if ( ! empty( $field['sub_desc'] ) ) : echo wp_kses_post( $field['sub_desc'] ); endif; ?> </label> <?php if ( ! empty( $field['desc'] ) ) : ?> <p class="description"><?php echo wp_kses_post( $field['desc'] ); ?></p> <?php endif; } /** * Render checkbox list control. * * Generates the final HTML for checkbox list controls. * * @since 2.0.0 * @access private * @static * * @param array $field Field data. */ private static function checkbox_list( array $field ) { $old_value = get_option( $field['id'], $field['std'] ); if ( ! is_array( $old_value ) ) { $old_value = []; } foreach ( $field['options'] as $option_key => $option_value ) : ?> <label> <input type="checkbox" name="<?php echo esc_attr( $field['id'] ); ?>[]" value="<?php echo esc_attr( $option_key ); ?>"<?php checked( in_array( $option_key, $old_value ), true ); ?> /> <?php echo wp_kses_post( $option_value ); ?> </label><br /> <?php endforeach; ?> <?php if ( ! empty( $field['desc'] ) ) : ?> <p class="description"><?php echo wp_kses_post( $field['desc'] ); ?></p> <?php endif; } /** * Render select control. * * Generates the final HTML for select controls. * * @since 2.0.0 * @access private * @static * * @param array $field Field data. */ private static function select( array $field ) { $old_value = get_option( $field['id'], $field['std'] ); ?> <select name="<?php echo esc_attr( $field['id'] ); ?>"> <?php if ( ! empty( $field['show_select'] ) ) : ?> <option value="">— <?php echo esc_html__( 'Select', 'elementor' ); ?> —</option> <?php endif; ?> <?php foreach ( $field['options'] as $value => $label ) : ?> <option value="<?php echo esc_attr( $value ); ?>"<?php esc_attr( selected( $value, $old_value ) ); ?>><?php echo esc_html( $label ); ?></option> <?php endforeach; ?> </select> <?php if ( ! empty( $field['desc'] ) ) : ?> <p class="description"><?php echo wp_kses_post( $field['desc'] ); ?></p> <?php endif; } /** * Render checkbox list control for CPT. * * Generates the final HTML for checkbox list controls populated with Custom Post Types. * * @since 2.0.0 * @access private * @static * * @param array $field Field data. */ private static function checkbox_list_cpt( array $field ) { $defaults = [ 'exclude' => [], ]; $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' => esc_html__( '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; } ?> <div id="<?php echo esc_attr( $field['id'] ); ?>"> <?php // PHPCS - This is a Raw HTML control, it is not escaped on purpose. ?> <div><?php echo $field['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div> <?php if ( ! empty( $field['sub_desc'] ) ) : echo wp_kses_post( $field['sub_desc'] ); endif; ?> <?php if ( ! empty( $field['desc'] ) ) : ?> <p class="description"><?php echo wp_kses_post( $field['desc'] ); ?></p> <?php endif; ?> </div> <?php } } settings.php 0000644 00000042345 14720521203 0007121 0 ustar 00 <?php namespace Elementor; use Elementor\Core\Admin\Menu\Admin_Menu_Manager; use Elementor\Core\Settings\Manager as SettingsManager; use Elementor\Includes\Settings\AdminMenuItems\Admin_Menu_Item; use Elementor\Includes\Settings\AdminMenuItems\Get_Help_Menu_Item; use Elementor\Includes\Settings\AdminMenuItems\Getting_Started_Menu_Item; use Elementor\Modules\Promotions\Module as Promotions_Module; use Elementor\TemplateLibrary\Source_Local; use Elementor\Modules\Home\Module as Home_Module; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor "Settings" page in WordPress Dashboard. * * Elementor settings page handler class responsible for creating and displaying * Elementor "Settings" page in WordPress dashboard. * * @since 1.0.0 */ class Settings extends Settings_Page { /** * Settings page ID for Elementor settings. */ const PAGE_ID = 'elementor'; /** * Upgrade menu priority. */ const MENU_PRIORITY_GO_PRO = 502; /** * Settings page field for update time. */ const UPDATE_TIME_FIELD = '_elementor_settings_update_time'; /** * Settings page general tab slug. */ const TAB_GENERAL = 'general'; /** * Settings page style tab slug. */ const TAB_STYLE = 'style'; /** * Settings page integrations tab slug. */ const TAB_INTEGRATIONS = 'integrations'; /** * Settings page advanced tab slug. */ const TAB_ADVANCED = 'advanced'; /** * Settings page performance tab slug. */ const TAB_PERFORMANCE = 'performance'; const ADMIN_MENU_PRIORITY = 10; public Home_Module $home_module; /** * Register admin menu. * * Add new Elementor Settings admin menu. * * Fired by `admin_menu` action. * * @since 1.0.0 * @access public */ public function register_admin_menu() { global $menu; $menu[] = [ '', 'read', 'separator-elementor', '', 'wp-menu-separator elementor' ]; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited if ( ! current_user_can( 'manage_options' ) ) { return; } add_menu_page( esc_html__( 'Elementor', 'elementor' ), esc_html__( 'Elementor', 'elementor' ), 'manage_options', self::PAGE_ID, [ $this, $this->home_module->is_experiment_active() ? 'display_home_screen' : 'display_settings_page', ], '', '58.5' ); if ( $this->home_module->is_experiment_active() ) { add_action( 'elementor/admin/menu/register', function( Admin_Menu_Manager $admin_menu ) { $admin_menu->register( 'elementor-settings', new Admin_Menu_Item( $this ) ); }, 0 ); } } public function display_home_screen() { echo '<div id="e-home-screen"></div>'; } /** * Reorder the Elementor menu items in admin. * Based on WC. * * @since 2.4.0 * * @param array $menu_order Menu order. * @return array */ public function menu_order( $menu_order ) { // Initialize our custom order array. $elementor_menu_order = []; // Get the index of our custom separator. $elementor_separator = array_search( 'separator-elementor', $menu_order, true ); // Get index of library menu. $elementor_library = array_search( Source_Local::ADMIN_MENU_SLUG, $menu_order, true ); // Loop through menu order and do some rearranging. foreach ( $menu_order as $index => $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 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 private */ private function register_knowledge_base_menu( Admin_Menu_Manager $admin_menu ) { $admin_menu->register( 'elementor-getting-started', new Getting_Started_Menu_Item() ); $admin_menu->register( 'go_knowledge_base_site', new Get_Help_Menu_Item() ); } /** * 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_knowledge_base_site' === $_GET['page'] ) { wp_redirect( Get_Help_Menu_Item::URL ); die; } } /** * On admin init. * * Preform actions on WordPress admin initialization. * * Fired by `admin_init` action. * * @since 2.0.0 * @access public */ public function on_admin_init() { $this->handle_external_redirects(); $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() { $menu_name = $this->home_module->is_experiment_active() ? esc_html__( 'Home', 'elementor' ) : esc_html__( 'Settings', 'elementor' ); Utils::change_submenu_first_item_label( 'elementor', $menu_name ); } /** * 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 * @deprecated 3.0.0 Use `Plugin::$instance->files_manager->clear_cache()` method instead. */ 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'; return [ self::TAB_GENERAL => [ 'label' => esc_html__( 'General', 'elementor' ), 'sections' => [ 'general' => [ 'label' => esc_html__( 'General', 'elementor' ), 'callback' => function() { printf( '<p>%s</p><br><hr><br>', esc_html__( 'Tailor how Elementor enhances your site, from post types to other functions.', 'elementor' ) ); }, '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' => esc_html__( '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' => esc_html__( 'Disable Default Colors', 'elementor' ), 'field_args' => [ 'type' => 'checkbox', 'value' => 'yes', 'sub_desc' => esc_html__( 'Checking this box will disable Elementor\'s Default Colors, and make Elementor inherit the colors from your theme.', 'elementor' ), ], ], 'disable_typography_schemes' => [ 'label' => esc_html__( 'Disable Default Fonts', 'elementor' ), 'field_args' => [ 'type' => 'checkbox', 'value' => 'yes', 'sub_desc' => esc_html__( 'Checking this box will disable Elementor\'s Default Fonts, and make Elementor inherit the fonts from your theme.', 'elementor' ), ], ], ], ], 'usage' => [ 'label' => esc_html__( 'Improve Elementor', 'elementor' ), 'fields' => $this->get_usage_fields(), ], ], ], self::TAB_INTEGRATIONS => [ 'label' => esc_html__( 'Integrations', 'elementor' ), 'sections' => [ 'google_maps' => [ 'label' => esc_html__( 'Google Maps Embed API', 'elementor' ), 'callback' => function() { printf( /* translators: 1: Link open tag, 2: Link close tag */ esc_html__( 'Google Maps Embed API is a free service by Google that allows embedding Google Maps in your site. For more details, visit Google Maps\' %1$sUsing API Keys%2$s page.', 'elementor' ), '<a target="_blank" href="https://developers.google.com/maps/documentation/embed/get-api-key">', '</a>' ); }, 'fields' => [ 'google_maps_api_key' => [ 'label' => esc_html__( 'API Key', 'elementor' ), 'field_args' => [ 'class' => 'elementor_google_maps_api_key', 'type' => 'text', ], ], ], ], ], ], self::TAB_ADVANCED => [ 'label' => esc_html__( 'Advanced', 'elementor' ), 'sections' => [ 'advanced' => [ 'label' => esc_html__( 'Advanced', 'elementor' ), 'callback' => function() { printf( '<p>%s</p><br><hr><br>', esc_html__( 'Personalize the way Elementor works on your website by choosing the advanced features and how they operate.', 'elementor' ) ); }, 'fields' => [ 'editor_break_lines' => [ 'label' => esc_html__( 'Switch Editor Loader Method', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => '', 'options' => [ '' => esc_html__( 'Disable', 'elementor' ), '1' => esc_html__( 'Enable', 'elementor' ), ], 'desc' => esc_html__( 'For troubleshooting server configuration conflicts.', 'elementor' ), ], ], 'unfiltered_files_upload' => [ 'label' => esc_html__( 'Enable Unfiltered File Uploads', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => '', 'options' => [ '' => esc_html__( 'Disable', 'elementor' ), '1' => esc_html__( 'Enable', 'elementor' ), ], 'desc' => esc_html__( 'Please note! Allowing uploads of any files (SVG & JSON included) is a potential security risk.', 'elementor' ) . '<br>' . esc_html__( 'Elementor will try to sanitize the unfiltered files, removing potential malicious code and scripts.', 'elementor' ) . '<br>' . esc_html__( 'We recommend you only enable this feature if you understand the security risks involved.', 'elementor' ), ], ], 'google_font' => [ 'label' => esc_html__( 'Google Fonts', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => '1', 'options' => [ '1' => esc_html__( 'Enable', 'elementor' ), '0' => esc_html__( 'Disable', 'elementor' ), ], 'desc' => sprintf( esc_html__( 'Disable this option if you want to prevent Google Fonts from being loaded. This setting is recommended when loading fonts from a different source (plugin, theme or %1$scustom fonts%2$s).', 'elementor' ), '<a href="' . admin_url( 'admin.php?page=elementor_custom_fonts' ) . '">', '</a>' ), ], ], 'font_display' => [ 'label' => esc_html__( 'Google Fonts Load', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => 'auto', 'options' => [ 'auto' => esc_html__( 'Default', 'elementor' ), 'block' => esc_html__( 'Blocking', 'elementor' ), 'swap' => esc_html__( 'Swap', 'elementor' ), 'fallback' => esc_html__( 'Fallback', 'elementor' ), 'optional' => esc_html__( 'Optional', 'elementor' ), ], 'desc' => esc_html__( 'Font-display property defines how font files are loaded and displayed by the browser.', 'elementor' ) . '<br>' . esc_html__( 'Set the way Google Fonts are being loaded by selecting the font-display property (Default: Auto).', 'elementor' ), ], ], ], ], ], ], self::TAB_PERFORMANCE => [ 'label' => esc_html__( 'Performance', 'elementor' ), 'sections' => [ 'performance' => [ 'label' => esc_html__( 'Performance', 'elementor' ), 'callback' => function() { printf( '<p>%s</p><br><hr><br>', esc_html__( 'Improve loading times on your site by selecting the optimization tools that best fit your requirements.', 'elementor' ) ); }, 'fields' => [ 'css_print_method' => [ 'label' => esc_html__( 'CSS Print Method', 'elementor' ), 'field_args' => [ 'class' => 'elementor_css_print_method', 'type' => 'select', 'std' => 'external', 'options' => [ 'external' => esc_html__( 'External File', 'elementor' ), 'internal' => esc_html__( 'Internal Embedding', 'elementor' ), ], 'desc' => sprintf( /* translators: %s: <head> tag. */ esc_html__( 'Internal Embedding places all CSS in the %s which works great for troubleshooting, while External File uses external CSS file for better performance (recommended).', 'elementor' ), '<code><head></code>', ), ], ], 'optimized_image_loading' => [ 'label' => esc_html__( 'Optimized Image Loading', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => '1', 'options' => [ '1' => esc_html__( 'Enable', 'elementor' ), '0' => esc_html__( 'Disable', 'elementor' ), ], 'desc' => sprintf( /* translators: 1: fetchpriority attribute, 2: lazy loading attribute. */ esc_html__( 'Improve performance by applying %1$s on LCP image and %2$s on images below the fold.', 'elementor' ), '<code>fetchpriority="high"</code>', '<code>loading="lazy"</code>' ), ], ], 'optimized_gutenberg_loading' => [ 'label' => esc_html__( 'Optimized Gutenberg Loading', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => '1', 'options' => [ '1' => esc_html__( 'Enable', 'elementor' ), '0' => esc_html__( 'Disable', 'elementor' ), ], 'desc' => esc_html__( 'Reduce unnecessary render-blocking loads by dequeuing unused Gutenberg block editor scripts and styles.', 'elementor' ), ], ], 'lazy_load_background_images' => [ 'label' => esc_html__( 'Lazy Load Background Images', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => '1', 'options' => [ '1' => esc_html__( 'Enable', 'elementor' ), '0' => esc_html__( 'Disable', 'elementor' ), ], 'desc' => esc_html__( 'Improve initial page load performance by lazy loading all background images except the first one.', '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 esc_html__( 'Elementor', 'elementor' ); } /** * @since 2.2.0 * @access private */ private function maybe_remove_all_admin_notices() { $elementor_pages = [ 'elementor-getting-started', 'elementor-system-info', 'e-form-submissions', 'elementor_custom_fonts', 'elementor_custom_icons', 'elementor-license', 'elementor_custom_code', 'popup_templates', 'elementor-apps', ]; if ( empty( $_GET['page'] ) || ! in_array( $_GET['page'], $elementor_pages, true ) ) { return; } remove_all_actions( 'admin_notices' ); } public function add_generator_tag_settings( $settings ) { $css_print_method = get_option( 'elementor_css_print_method', 'external' ); $settings[] = 'css_print_method-' . $css_print_method; $google_font = Fonts::is_google_fonts_enabled() ? 'enabled' : 'disabled'; $settings[] = 'google_font-' . $google_font; $font_display = Fonts::get_font_display_setting(); $settings[] = 'font_display-' . $font_display; return $settings; } /** * Settings page constructor. * * Initializing Elementor "Settings" page. * * @since 1.0.0 * @access public */ public function __construct() { parent::__construct(); $this->home_module = new Home_Module(); add_action( 'admin_init', [ $this, 'on_admin_init' ] ); add_filter( 'elementor/generator_tag/settings', [ $this, 'add_generator_tag_settings' ] ); add_action( 'admin_menu', [ $this, 'register_admin_menu' ], 20 ); add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu ) { $this->register_knowledge_base_menu( $admin_menu ); }, Promotions_Module::ADMIN_MENU_PRIORITY - 1 ); add_action( 'admin_menu', [ $this, 'admin_menu_change_name' ], 200 ); add_filter( 'custom_menu_order', '__return_true' ); add_filter( 'menu_order', [ $this, 'menu_order' ] ); $clear_cache_callback = [ Plugin::$instance->files_manager, 'clear_cache' ]; // Clear CSS Meta after change css related methods. $css_settings = [ 'elementor_disable_color_schemes', 'elementor_disable_typography_schemes', 'elementor_css_print_method', ]; foreach ( $css_settings as $option_name ) { add_action( "add_option_{$option_name}", $clear_cache_callback ); add_action( "update_option_{$option_name}", $clear_cache_callback ); } } } validations.php 0000644 00000003177 14720521203 0007576 0 ustar 00 <?php namespace Elementor; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor settings validations. * * Elementor settings validations handler class is responsible for validating settings * fields. * * @since 1.0.0 */ class Settings_Validations { /** * Validate HTML field. * * Sanitize content for allowed HTML tags and remove backslashes before quotes. * * @since 1.0.0 * @access public * @static * * @param string $input Input field. * * @return string Input field. */ public static function html( $input ) { return stripslashes( wp_filter_post_kses( addslashes( $input ) ) ); } /** * Validate checkbox list. * * Make sure that an empty checkbox list field will return an array. * * @since 1.0.0 * @access public * @static * * @param mixed $input Input field. * * @return mixed Input field. */ public static function checkbox_list( $input ) { if ( empty( $input ) ) { $input = []; } return $input; } /** * Current Time * * Used to return current time * * @since 2.5.0 * @access public * @static * * @param mixed $input Input field. * * @return int */ public static function current_time( $input ) { return time(); } /** * Clear cache. * * Delete post meta containing the post CSS file data. And delete the actual * CSS files from the upload directory. * * @since 1.4.8 * @access public * @static * * @param mixed $input Input field. * * @return mixed Input field. */ public static function clear_cache( $input ) { Plugin::$instance->files_manager->clear_cache(); return $input; } } admin-menu-items/tools-menu-item.php 0000644 00000001527 14720521203 0013465 0 ustar 00 <?php namespace Elementor\Includes\Settings\AdminMenuItems; use Elementor\Core\Admin\Menu\Interfaces\Admin_Menu_Item_With_Page; use Elementor\Settings; use Elementor\Tools; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Tools_Menu_Item implements Admin_Menu_Item_With_Page { private $tools_page; public function __construct( Tools $tools_page ) { $this->tools_page = $tools_page; } public function is_visible() { return true; } public function get_parent_slug() { return Settings::PAGE_ID; } public function get_label() { return esc_html__( 'Tools', 'elementor' ); } public function get_page_title() { return esc_html__( 'Tools', 'elementor' ); } public function get_capability() { return Tools::CAPABILITY; } public function render() { $this->tools_page->display_settings_page(); } } admin-menu-items/get-help-menu-item.php 0000644 00000001377 14720521203 0014035 0 ustar 00 <?php namespace Elementor\Includes\Settings\AdminMenuItems; use Elementor\Core\Admin\Menu\Interfaces\Admin_Menu_Item_With_Page; use Elementor\Settings; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Get_Help_Menu_Item implements Admin_Menu_Item_With_Page { const URL = 'https://go.elementor.com/docs-admin-menu/'; public function is_visible() { return true; } public function get_parent_slug() { return Settings::PAGE_ID; } public function get_label() { return esc_html__( 'Get Help', 'elementor' ); } public function get_page_title() { return ''; } public function get_capability() { return 'manage_options'; } public function render() { // Redirects from the settings page on `admin_init`. die; } } admin-menu-items/admin-menu-item.php 0000644 00000002044 14720521203 0013410 0 ustar 00 <?php namespace Elementor\Includes\Settings\AdminMenuItems; use Elementor\Core\Admin\Menu\Interfaces\Admin_Menu_Item_With_Page; use Elementor\Settings; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Admin_Menu_Item implements Admin_Menu_Item_With_Page { private $settings_page; public function __construct( Settings $settings_page ) { $this->settings_page = $settings_page; } public function is_visible() { return true; } public function get_parent_slug() { return $this->settings_page->home_module->is_experiment_active() ? 'elementor' : null; } public function get_label() { return $this->settings_page->home_module->is_experiment_active() ? esc_html__( 'Settings', 'elementor' ) : esc_html__( 'Elementor', 'elementor' ); } public function get_page_title() { return $this->get_label(); } public function get_position() { return '58.5'; } public function get_capability() { return 'manage_options'; } public function render() { $this->settings_page->display_settings_page(); } } admin-menu-items/getting-started-menu-item.php 0000644 00000006312 14720521203 0015427 0 ustar 00 <?php namespace Elementor\Includes\Settings\AdminMenuItems; use Elementor\Core\Admin\Menu\Interfaces\Admin_Menu_Item_With_Page; use Elementor\Plugin; use Elementor\Settings; use Elementor\User; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Getting_Started_Menu_Item implements Admin_Menu_Item_With_Page { public function is_visible() { return ! Plugin::instance()->experiments->is_feature_active( 'home_screen' ); } public function get_parent_slug() { return Settings::PAGE_ID; } public function get_label() { return esc_html__( 'Getting Started', 'elementor' ); } public function get_page_title() { return esc_html__( 'Getting Started', 'elementor' ); } public function get_capability() { return 'manage_options'; } public function render() { if ( User::is_current_user_can_edit_post_type( 'page' ) ) { $create_new_label = esc_html__( 'Create Your First Page', 'elementor' ); $create_new_cpt = 'page'; } elseif ( User::is_current_user_can_edit_post_type( 'post' ) ) { $create_new_label = esc_html__( 'Create Your First Post', 'elementor' ); $create_new_cpt = 'post'; } ?> <div class="wrap"> <div class="e-getting-started"> <div class="e-getting-started__box postbox"> <div class="e-getting-started__header"> <div class="e-getting-started__title"> <div class="e-logo-wrapper"> <i class="eicon-elementor"></i> </div> <?php echo esc_html__( 'Getting Started', 'elementor' ); ?> </div> <a class="e-getting-started__skip" href="<?php echo esc_url( admin_url() ); ?>"> <i class="eicon-close" aria-hidden="true" title="<?php esc_attr_e( 'Skip', 'elementor' ); ?>"></i> <span class="elementor-screen-only"><?php echo esc_html__( 'Skip', 'elementor' ); ?></span> </a> </div> <div class="e-getting-started__content"> <div class="e-getting-started__content--narrow"> <h2><?php echo esc_html__( 'Welcome to Elementor', 'elementor' ); ?></h2> <p><?php echo esc_html__( 'Get introduced to Elementor by watching our "Getting Started" video series. It will guide you through the steps needed to create your website. Then click to create your first page.', 'elementor' ); ?></p> </div> <div class="e-getting-started__video"> <iframe width="620" height="350" src="https://www.youtube-nocookie.com/embed/videoseries?si=XX1RveLtiTcLKmvC&list=PLZyp9H25CboFLsiad-zQOs-o-pGiv0a54;index=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div> <div class="e-getting-started__actions e-getting-started__content--narrow"> <?php if ( ! empty( $create_new_cpt ) ) : ?> <a href="<?php echo esc_url( Plugin::$instance->documents->get_create_new_post_url( $create_new_cpt ) ); ?>" class="button button-primary button-hero"><?php echo esc_html( $create_new_label ); ?></a> <?php endif; ?> <a href="https://go.elementor.com/wp-dash-getting-started-container/" target="_blank" class="button button-secondary button-hero"><?php echo esc_html__( 'Watch the Full Guide', 'elementor' ); ?></a> </div> </div> </div> </div> </div><!-- /.wrap --> <?php } } settings-page.php 0000644 00000026346 14720521203 0010036 0 ustar 00 <?php namespace Elementor; use Elementor\Plugin; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor settings page. * * An abstract class that provides the needed properties and methods to handle * WordPress dashboard settings pages in inheriting classes. * * @since 1.0.0 * @abstract */ abstract class Settings_Page { /** * Settings page ID. */ const PAGE_ID = ''; /** * Tabs. * * Holds the settings page tabs, sections and fields. * * @access private * * @var array */ private $tabs; /** * Create tabs. * * Return the settings page tabs, sections and fields. * * @since 1.5.0 * @access protected * @abstract */ abstract protected function create_tabs(); /** * Get settings page title. * * Retrieve the title for the settings page. * * @since 1.5.0 * @access protected * @abstract */ abstract protected function get_page_title(); /** * Get settings page URL. * * Retrieve the URL of the settings page. * * @since 1.5.0 * @access public * @static * * @return string Settings page URL. */ final public static function get_url() { return admin_url( 'admin.php?page=' . static::PAGE_ID ); } /** * Get settings tab URL. * * Retrieve the URL of a specific tab in the settings page. * * @since 3.23.0 * @access public * @static * * @param string $tab_id The ID of the settings tab. * * @return string Settings tab URL. */ final public static function get_settings_tab_url( $tab_id ): string { $settings_page_id = Plugin::$instance->experiments->is_feature_active( 'home_screen' ) ? 'elementor-settings' : 'elementor'; return admin_url( "admin.php?page=$settings_page_id#tab-$tab_id" ); } /** * Settings page constructor. * * Initializing Elementor settings page. * * @since 1.5.0 * @access public */ public function __construct() { // PHPCS - The user data is not used. if ( ! empty( $_POST['option_page'] ) && static::PAGE_ID === $_POST['option_page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing add_action( 'admin_init', [ $this, 'register_settings_fields' ] ); } } /** * Get tabs. * * Retrieve the settings page tabs, sections and fields. * * @since 1.5.0 * @access public * * @return array Settings page tabs, sections and fields. */ final public function get_tabs() { $this->ensure_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 ); if ( ! isset( $field['render'] ) ) { $field['render'] = [ $controls_class_name, 'render' ]; } add_settings_field( $full_field_id, isset( $field['label'] ) ? $field['label'] : '', $field['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(); ?> <div class="wrap"> <h1 class="wp-heading-inline"><?php echo esc_html( $this->get_page_title() ); ?></h1> <div id="elementor-settings-tabs-wrapper" class="nav-tab-wrapper"> <?php foreach ( $tabs as $tab_id => $tab ) { if ( ! $this->should_render_tab( $tab ) ) { continue; } $active_class = ''; if ( 'general' === $tab_id ) { $active_class = ' nav-tab-active'; } $sanitized_tab_id = esc_attr( $tab_id ); $sanitized_tab_label = esc_html( $tab['label'] ); // PHPCS - Escaped the relevant strings above. echo "<a id='elementor-settings-tab-{$sanitized_tab_id}' class='nav-tab{$active_class}' href='#tab-{$sanitized_tab_id}'>{$sanitized_tab_label}</a>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } ?> </div> <form id="elementor-settings-form" method="post" action="options.php"> <?php settings_fields( static::PAGE_ID ); foreach ( $tabs as $tab_id => $tab ) { if ( ! $this->should_render_tab( $tab ) ) { continue; } $active_class = ''; if ( 'general' === $tab_id ) { $active_class = ' elementor-active'; } $sanitized_tab_id = esc_attr( $tab_id ); // PHPCS - $active_class is a non-dynamic string and $sanitized_tab_id is escaped above. echo "<div id='tab-{$sanitized_tab_id}' class='elementor-settings-form-page{$active_class}'>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped foreach ( $tab['sections'] as $section_id => $section ) { if ( ! $this->should_render_section( $section ) ) { continue; } $full_section_id = 'elementor_' . $section_id . '_section'; if ( ! empty( $section['label'] ) ) { echo '<h2>' . esc_html( $section['label'] ) . '</h2>'; } if ( ! empty( $section['callback'] ) ) { $section['callback'](); } echo '<table class="form-table">'; do_settings_fields( static::PAGE_ID, $full_section_id ); echo '</table>'; } echo '</div>'; } submit_button(); ?> </form> </div><!-- /.wrap --> <?php } public function get_usage_fields() { return [ 'allow_tracking' => [ 'label' => esc_html__( 'Usage Data Sharing', 'elementor' ), 'field_args' => [ 'type' => 'checkbox', 'value' => 'yes', 'default' => '', 'sub_desc' => sprintf( '%1$s <a href="https://go.elementor.com/usage-data-tracking/" target="_blank">%2$s</a>', esc_html__( 'Become a super contributor by opting in to share non-sensitive plugin data and to receive periodic email updates from us.', 'elementor' ), esc_html__( 'Learn more', 'elementor' ) ), ], 'setting_args' => [ __NAMESPACE__ . '\Tracker', 'check_for_settings_optin' ], ], ]; } /** * Ensure tabs. * * Make sure the settings page has tabs before inserting any new sections or * fields. * * @since 1.5.0 * @access private */ private function ensure_tabs() { if ( null === $this->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 ); } } /** * Should it render the settings tab * * @param $tab * * @return bool */ private function should_render_tab( $tab ) { // BC - When 'show_if' prop is not exists, it actually should render the tab. return ! empty( $tab['sections'] ) && ( ! isset( $tab['show_if'] ) || $tab['show_if'] ); } /** * Should it render the settings section * * @param $section * * Since 3.19.0 * * @return bool */ private function should_render_section( $section ) { // BC - When 'show_if' prop is not exists, it actually should render the section. return ! isset( $section['show_if'] ) || $section['show_if']; } } emails-settings.twig 0000644 00000006114 14721500727 0010557 0 ustar 00 {% set completed_frequency_dropdown %} <select name="notification[completed_frequency]"{{ settings.completed_frequency.disabled }}> {% for option in settings.completed_frequency.options %} <option value="{{ option.value }}"{{ option.checked }}>{{ option.label }}</option> {% endfor %} </select> {% endset %} {% set overdue_offset_input %} <input name="notification[overdue_offset]" value="{{ settings.overdue_offset.value }}" size="1"{{ settings.overdue_offset.disabled }}> {% endset %} <div class="wpml-section" id="translation-notifications-translator"> <div class="wpml-section-header"> <h4>{{ strings.section_title_translator }}</h4> </div> <div class="wpml-section-content"> <ul> <li> <input name="notification[new-job]" type="checkbox" id="wpml_tm_notify_new_job" data-child="notification[include_xliff]" value="{{ settings.new_job.value }}"{{ settings.new_job.checked }}> <label for="wpml_tm_notify_new_job">{{ strings.label_new_job }}</label> <ul> <li> <input type="checkbox" name="notification[include_xliff]" id="wpml_tm_notify_include_xliff" value="{{ settings.include_xliff.value }}" {{ settings.include_xliff.checked }}{{ settings.include_xliff.disabled }}> <label for="icl_include_xliff">{{ strings.label_include_xliff }}</label> </li> </ul> </li> <li> <input name="notification[resigned]" type="checkbox" id="wpml_tm_notify_job_resigned" value="{{ settings.resigned.value }}"{{ settings.resigned.checked }}> <label for="wpml_tm_notify_job_resigned">{{ strings.label_resigned_job }}</label> </li> </ul> </div> </div> <div class="wpml-section" id="translation-notifications-manager"> <div class="wpml-section-header"> <h4>{{ strings.section_title_manager }}</h4> </div> <div class="wpml-section-content"> <ul> <li> <input name="notification[completed]" type="checkbox" id="wpml_tm_notify_completed" data-child="notification[completed_frequency]" value="{{ settings.completed.value }}"{{ settings.completed.checked }}> <label for="wpml_tm_notify_completed"> {{ strings.label_completed_job|format(completed_frequency_dropdown)|raw }} </label> </li> <li> <input name="notification[overdue]" type="checkbox" id="wpml_tm_notify_job_overdue" data-child="notification[overdue_offset]" value="{{ settings.overdue.value }}"{{ settings.overdue.checked }}> <label for="wpml_tm_notify_job_overdue"> {{ strings.label_overdue_job|format(overdue_offset_input)|raw }} </label> </li> </ul> </div> </div>