Файловый менеджер - Редактировать - /var/www/xthruster/html/wp-content/uploads/flags/managers.tar
Назад
controls.php 0000644 00000100670 14720521210 0007116 0 ustar 00 <?php namespace Elementor; use Elementor\Core\Frontend\Performance; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor controls manager. * * Elementor controls manager handler class is responsible for registering and * initializing all the supported controls, both regular controls and the group * controls. * * @since 1.0.0 */ class Controls_Manager { /** * Content tab. */ const TAB_CONTENT = 'content'; /** * Style tab. */ const TAB_STYLE = 'style'; /** * Advanced tab. */ const TAB_ADVANCED = 'advanced'; /** * Responsive tab. */ const TAB_RESPONSIVE = 'responsive'; /** * Layout tab. */ const TAB_LAYOUT = 'layout'; /** * Settings tab. */ const TAB_SETTINGS = 'settings'; /** * Text control. */ const TEXT = 'text'; /** * Number control. */ const NUMBER = 'number'; /** * Textarea control. */ const TEXTAREA = 'textarea'; /** * Select control. */ const SELECT = 'select'; /** * Switcher control. */ const SWITCHER = 'switcher'; /** * Button control. */ const BUTTON = 'button'; /** * Hidden control. */ const HIDDEN = 'hidden'; /** * Heading control. */ const HEADING = 'heading'; /** * Raw HTML control. */ const RAW_HTML = 'raw_html'; /** * Notice control. */ const NOTICE = 'notice'; /** * Deprecated Notice control. */ const DEPRECATED_NOTICE = 'deprecated_notice'; /** * Alert control. */ const ALERT = 'alert'; /** * Popover Toggle control. */ const POPOVER_TOGGLE = 'popover_toggle'; /** * Section control. */ const SECTION = 'section'; /** * Tab control. */ const TAB = 'tab'; /** * Tabs control. */ const TABS = 'tabs'; /** * Divider control. */ const DIVIDER = 'divider'; /** * Color control. */ const COLOR = 'color'; /** * Media control. */ const MEDIA = 'media'; /** * Slider control. */ const SLIDER = 'slider'; /** * Dimensions control. */ const DIMENSIONS = 'dimensions'; /** * Choose control. */ const CHOOSE = 'choose'; /** * WYSIWYG control. */ const WYSIWYG = 'wysiwyg'; /** * Code control. */ const CODE = 'code'; /** * Font control. */ const FONT = 'font'; /** * Image dimensions control. */ const IMAGE_DIMENSIONS = 'image_dimensions'; /** * WordPress widget control. */ const WP_WIDGET = 'wp_widget'; /** * URL control. */ const URL = 'url'; /** * Repeater control. */ const REPEATER = 'repeater'; /** * Icon control. */ const ICON = 'icon'; /** * Icons control. */ const ICONS = 'icons'; /** * Gallery control. */ const GALLERY = 'gallery'; /** * Structure control. */ const STRUCTURE = 'structure'; /** * Select2 control. */ const SELECT2 = 'select2'; /** * Date/Time control. */ const DATE_TIME = 'date_time'; /** * Box shadow control. */ const BOX_SHADOW = 'box_shadow'; /** * Text shadow control. */ const TEXT_SHADOW = 'text_shadow'; /** * Entrance animation control. */ const ANIMATION = 'animation'; /** * Hover animation control. */ const HOVER_ANIMATION = 'hover_animation'; /** * Exit animation control. */ const EXIT_ANIMATION = 'exit_animation'; /** * Gaps control. */ const GAPS = 'gaps'; /** * Controls. * * Holds the list of all the controls. Default is `null`. * * @since 1.0.0 * @access private * * @var Base_Control[] */ private $controls = null; /** * Control groups. * * Holds the list of all the control groups. Default is an empty array. * * @since 1.0.0 * @access private * * @var Group_Control_Base[] */ private $control_groups = []; /** * Control stacks. * * Holds the list of all the control stacks. Default is an empty array. * * @since 1.0.0 * @access private * * @var array */ private $stacks = []; /** * Tabs. * * Holds the list of all the tabs. * * @since 1.0.0 * @access private * @static * * @var array */ private static $tabs; /** * Has stacks cache been cleared. * * Boolean flag used to determine whether the controls manager stack cache has been cleared once during the current runtime. * * @since 3.13.0 * @access private * @static * * @var array */ private $has_stacks_cache_been_cleared = false; /** * Init tabs. * * Initialize control tabs. * * @since 1.6.0 * @access private * @static */ private static function init_tabs() { self::$tabs = [ self::TAB_CONTENT => esc_html__( 'Content', 'elementor' ), self::TAB_STYLE => esc_html__( 'Style', 'elementor' ), self::TAB_ADVANCED => esc_html__( 'Advanced', 'elementor' ), self::TAB_RESPONSIVE => esc_html__( 'Responsive', 'elementor' ), self::TAB_LAYOUT => esc_html__( 'Layout', 'elementor' ), self::TAB_SETTINGS => esc_html__( 'Settings', 'elementor' ), ]; } /** * Get tabs. * * Retrieve the tabs of the current control. * * @since 1.6.0 * @access public * @static * * @return array Control tabs. */ public static function get_tabs() { if ( ! self::$tabs ) { self::init_tabs(); } return self::$tabs; } /** * Add tab. * * This method adds a new tab to the current control. * * @since 1.6.0 * @access public * @static * * @param string $tab_name Tab name. * @param string $tab_label Tab label. */ public static function add_tab( $tab_name, $tab_label = '' ) { if ( ! self::$tabs ) { self::init_tabs(); } if ( isset( self::$tabs[ $tab_name ] ) ) { return; } self::$tabs[ $tab_name ] = $tab_label; } public static function get_groups_names() { // Group name must use "-" instead of "_" return [ 'background', 'border', 'typography', 'image-size', 'box-shadow', 'css-filter', 'text-shadow', 'flex-container', 'grid-container', 'flex-item', 'text-stroke', ]; } public static function get_controls_names() { return [ self::TEXT, self::NUMBER, self::TEXTAREA, self::SELECT, self::SWITCHER, self::BUTTON, self::HIDDEN, self::HEADING, self::RAW_HTML, self::POPOVER_TOGGLE, self::SECTION, self::TAB, self::TABS, self::DIVIDER, self::DEPRECATED_NOTICE, self::ALERT, self::NOTICE, self::COLOR, self::MEDIA, self::SLIDER, self::DIMENSIONS, self::CHOOSE, self::WYSIWYG, self::CODE, self::FONT, self::IMAGE_DIMENSIONS, self::GAPS, self::WP_WIDGET, self::URL, self::REPEATER, self::ICON, self::ICONS, self::GALLERY, self::STRUCTURE, self::SELECT2, self::DATE_TIME, self::BOX_SHADOW, self::TEXT_SHADOW, self::ANIMATION, self::HOVER_ANIMATION, self::EXIT_ANIMATION, ]; } /** * Register controls. * * This method creates a list of all the supported controls by requiring the * control files and initializing each one of them. * * The list of supported controls includes the regular controls and the group * controls. * * External developers can register new controls by hooking to the * `elementor/controls/controls_registered` action. * * @since 3.1.0 * @access private */ private function register_controls() { $this->controls = []; foreach ( self::get_controls_names() as $control_id ) { $control_class_id = str_replace( ' ', '_', ucwords( str_replace( '_', ' ', $control_id ) ) ); $class_name = __NAMESPACE__ . '\Control_' . $control_class_id; $this->register( new $class_name() ); } // Group Controls foreach ( self::get_groups_names() as $group_name ) { $group_class_id = str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $group_name ) ) ); $class_name = __NAMESPACE__ . '\Group_Control_' . $group_class_id; $this->control_groups[ $group_name ] = new $class_name(); } /** * After controls registered. * * Fires after Elementor controls are registered. * * @since 1.0.0 * @deprecated 3.5.0 Use `elementor/controls/register` hook instead. * * @param Controls_Manager $this The controls manager. */ // TODO: Uncomment when Pro uses the new hook. //Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->do_deprecated_action( // 'elementor/controls/controls_registered', // [ $this ], // '3.5.0', // 'elementor/controls/register' //); do_action( 'elementor/controls/controls_registered', $this ); /** * After controls registered. * * Fires after Elementor controls are registered. * * @since 3.5.0 * * @param Controls_Manager $this The controls manager. */ do_action( 'elementor/controls/register', $this ); } /** * Register control. * * This method adds a new control to the controls list. It adds any given * control to any given control instance. * * @since 1.0.0 * @access public * @deprecated 3.5.0 Use `register()` method instead. * * @param string $control_id Control ID. * @param Base_Control $control_instance Control instance, usually the * current instance. */ public function register_control( $control_id, Base_Control $control_instance ) { // TODO: Uncomment when Pro uses the new hook. //Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( // __METHOD__, // '3.5.0', // 'register()' //); $this->register( $control_instance, $control_id ); } /** * Register control. * * This method adds a new control to the controls list. It adds any given * control to any given control instance. * * @since 3.5.0 * @access public * * @param Base_Control $control_instance Control instance, usually the current instance. * @param string $control_id Control ID. Deprecated parameter. * * @return void */ public function register( Base_Control $control_instance, $control_id = null ) { // TODO: For BC. Remove in the future. if ( $control_id ) { Plugin::instance()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_argument( '$control_id', '3.5.0' ); } else { $control_id = $control_instance->get_type(); } $this->controls[ $control_id ] = $control_instance; } /** * Unregister control. * * This method removes control from the controls list. * * @since 1.0.0 * @access public * @deprecated 3.5.0 Use `unregister()` method instead. * * @param string $control_id Control ID. * * @return bool True if the control was removed, False otherwise. */ public function unregister_control( $control_id ) { Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'unregister()' ); return $this->unregister( $control_id ); } /** * Unregister control. * * This method removes control from the controls list. * * @since 3.5.0 * @access public * * @param string $control_id Control ID. * * @return bool Whether the controls has been unregistered. */ public function unregister( $control_id ) { if ( ! isset( $this->controls[ $control_id ] ) ) { return false; } unset( $this->controls[ $control_id ] ); return true; } /** * Get controls. * * Retrieve the controls list from the current instance. * * @since 1.0.0 * @access public * * @return Base_Control[] Controls list. */ public function get_controls() { if ( null === $this->controls ) { $this->register_controls(); } return $this->controls; } /** * Get control. * * Retrieve a specific control from the current controls instance. * * @since 1.0.0 * @access public * * @param string $control_id Control ID. * * @return bool|Base_Control Control instance, or False otherwise. */ public function get_control( $control_id ) { $controls = $this->get_controls(); return isset( $controls[ $control_id ] ) ? $controls[ $control_id ] : false; } /** * Get controls data. * * Retrieve all the registered controls and all the data for each control. * * @since 1.0.0 * @access public * * @return array { * Control data. * * @type array $name Control data. * } */ public function get_controls_data() { $controls_data = []; foreach ( $this->get_controls() as $name => $control ) { $controls_data[ $name ] = $control->get_settings(); } return $controls_data; } /** * Render controls. * * Generate the final HTML for all the registered controls using the element * template. * * @since 1.0.0 * @access public */ public function render_controls() { foreach ( $this->get_controls() as $control ) { $control->print_template(); } } /** * Get control groups. * * Retrieve a specific group for a given ID, or a list of all the control * groups. * * If the given group ID is wrong, it will return `null`. When the ID valid, * it will return the group control instance. When no ID was given, it will * return all the control groups. * * @since 1.0.10 * @access public * * @param string $id Optional. Group ID. Default is null. * * @return null|Group_Control_Base|Group_Control_Base[] */ public function get_control_groups( $id = null ) { if ( $id ) { return isset( $this->control_groups[ $id ] ) ? $this->control_groups[ $id ] : null; } return $this->control_groups; } /** * Add group control. * * This method adds a new group control to the control groups list. It adds * any given group control to any given group control instance. * * @since 1.0.0 * @access public * * @param string $id Group control ID. * @param Group_Control_Base $instance Group control instance, usually the * current instance. * * @return Group_Control_Base Group control instance. */ public function add_group_control( $id, $instance ) { $this->control_groups[ $id ] = $instance; return $instance; } /** * Enqueue control scripts and styles. * * Used to register and enqueue custom scripts and styles used by the control. * * @since 1.0.0 * @access public */ public function enqueue_control_scripts() { foreach ( $this->get_controls() as $control ) { $control->enqueue(); } } /** * Open new stack. * * This method adds a new stack to the control stacks list. It adds any * given stack to the current control instance. * * @since 1.0.0 * @access public * * @param Controls_Stack $controls_stack Controls stack. */ public function open_stack( Controls_Stack $controls_stack ) { $stack_id = $controls_stack->get_unique_name(); $this->stacks[ $stack_id ] = [ 'tabs' => [], 'controls' => [], 'style_controls' => [], 'responsive_control_duplication_mode' => Plugin::$instance->breakpoints->get_responsive_control_duplication_mode(), ]; } /** * Remove existing stack from the stacks cache * * Removes the stack of a passed instance from the Controls Manager's stacks cache. * * @param Controls_Stack $controls_stack * @return void */ public function delete_stack( Controls_Stack $controls_stack ) { $stack_id = $controls_stack->get_unique_name(); unset( $this->stacks[ $stack_id ] ); } /** * Add control to stack. * * This method adds a new control to the stack. * * @since 1.0.0 * @access public * * @param Controls_Stack $element Element stack. * @param string $control_id Control ID. * @param array $control_data Control data. * @param array $options Optional. Control additional options. * Default is an empty array. * * @return bool True if control added, False otherwise. */ public function add_control_to_stack( Controls_Stack $element, $control_id, $control_data, $options = [] ) { $default_options = [ 'overwrite' => false, 'index' => null, ]; $control_type = 'controls'; if ( Performance::is_optimized_control_loading_feature_enabled() && Performance::should_optimize_controls() && $this->is_style_control( $control_data ) ) { $control_type = 'style_controls'; } $options = array_merge( $default_options, $options ); $default_args = [ 'type' => self::TEXT, 'tab' => self::TAB_CONTENT, ]; $control_data['name'] = $control_id; $control_data = array_merge( $default_args, $control_data ); $control_type_instance = $this->get_control( $control_data['type'] ); if ( ! $control_type_instance ) { _doing_it_wrong( sprintf( '%1$s::%2$s', __CLASS__, __FUNCTION__ ), sprintf( 'Control type "%s" not found.', esc_html( $control_data['type'] ) ), '1.0.0' ); return false; } if ( $control_type_instance instanceof Has_Validation ) { try { $control_type_instance->validate( $control_data ); } catch ( \Exception $e ) { _doing_it_wrong( sprintf( '%1$s::%2$s', __CLASS__, __FUNCTION__ ), esc_html( $e->getMessage() ), '3.23.0' ); return false; } } if ( $control_type_instance instanceof Base_Data_Control ) { $control_default_value = $control_type_instance->get_default_value(); if ( is_array( $control_default_value ) ) { $control_data['default'] = isset( $control_data['default'] ) ? array_merge( $control_default_value, $control_data['default'] ) : $control_default_value; } else { $control_data['default'] = isset( $control_data['default'] ) ? $control_data['default'] : $control_default_value; } } $stack_id = $element->get_unique_name(); if ( ! $options['overwrite'] && isset( $this->stacks[ $stack_id ][ $control_type ][ $control_id ] ) ) { _doing_it_wrong( sprintf( '%1$s::%2$s', __CLASS__, __FUNCTION__ ), sprintf( 'Cannot redeclare control with same name "%s".', esc_html( $control_id ) ), '1.0.0' ); return false; } $tabs = self::get_tabs(); if ( ! isset( $tabs[ $control_data['tab'] ] ) ) { $control_data['tab'] = $default_args['tab']; } $this->stacks[ $stack_id ]['tabs'][ $control_data['tab'] ] = $tabs[ $control_data['tab'] ]; $this->stacks[ $stack_id ][ $control_type ][ $control_id ] = $control_data; if ( null !== $options['index'] ) { $controls = $this->stacks[ $stack_id ][ $control_type ]; $controls_keys = array_keys( $controls ); array_splice( $controls_keys, $options['index'], 0, $control_id ); $this->stacks[ $stack_id ][ $control_type ] = array_merge( array_flip( $controls_keys ), $controls ); } return true; } /** * Remove control from stack. * * This method removes a control a the stack. * * @since 1.0.0 * @access public * * @param string $stack_id Stack ID. * @param array|string $control_id The ID of the control to remove. * * @return bool|\WP_Error True if the stack was removed, False otherwise. */ public function remove_control_from_stack( $stack_id, $control_id ) { if ( is_array( $control_id ) ) { foreach ( $control_id as $id ) { $this->remove_control_from_stack( $stack_id, $id ); } return true; } if ( empty( $this->stacks[ $stack_id ]['controls'][ $control_id ] ) ) { return new \WP_Error( 'Cannot remove not-exists control.' ); } unset( $this->stacks[ $stack_id ]['controls'][ $control_id ] ); return true; } /** * Has Stacks Cache Been Cleared. * @since 3.13.0 * @access public * @return bool True if the CSS requires to clear the controls stack cache, False otherwise. */ public function has_stacks_cache_been_cleared() { return $this->has_stacks_cache_been_cleared; } /** * Clear stack. * This method clears the stack. * @since 3.13.0 * @access public */ public function clear_stack_cache() { $this->stacks = []; $this->has_stacks_cache_been_cleared = true; } /** * Get control from stack. * * Retrieve a specific control for a given a specific stack. * * If the given control does not exist in the stack, or the stack does not * exist, it will return `WP_Error`. Otherwise, it will retrieve the control * from the stack. * * @since 1.1.0 * @access public * * @param string $stack_id Stack ID. * @param string $control_id Control ID. * * @return array|\WP_Error The control, or an error. */ public function get_control_from_stack( $stack_id, $control_id ) { $stack_data = $this->get_stacks( $stack_id ); if ( ! empty( $stack_data['controls'][ $control_id ] ) ) { return $stack_data['controls'][ $control_id ]; } if ( ! empty( $stack_data['style_controls'][ $control_id ] ) ) { return $stack_data['style_controls'][ $control_id ]; } return new \WP_Error( 'Cannot get a not-exists control.' ); } /** * Update control in stack. * * This method updates the control data for a given stack. * * @since 1.1.0 * @access public * * @param Controls_Stack $element Element stack. * @param string $control_id Control ID. * @param array $control_data Control data. * @param array $options Optional. Control additional options. * Default is an empty array. * * @return bool True if control updated, False otherwise. */ public function update_control_in_stack( Controls_Stack $element, $control_id, $control_data, array $options = [] ) { $old_control_data = $this->get_control_from_stack( $element->get_unique_name(), $control_id ); if ( is_wp_error( $old_control_data ) ) { return false; } if ( ! empty( $options['recursive'] ) ) { $control_data = array_replace_recursive( $old_control_data, $control_data ); } else { $control_data = array_merge( $old_control_data, $control_data ); } return $this->add_control_to_stack( $element, $control_id, $control_data, [ 'overwrite' => true, ] ); } /** * Get stacks. * * Retrieve a specific stack for the list of stacks. * * If the given stack is wrong, it will return `null`. When the stack valid, * it will return the the specific stack. When no stack was given, it will * return all the stacks. * * @since 1.7.1 * @access public * * @param string $stack_id Optional. stack ID. Default is null. * * @return null|array A list of stacks. */ public function get_stacks( $stack_id = null ) { if ( $stack_id ) { if ( isset( $this->stacks[ $stack_id ] ) ) { return $this->stacks[ $stack_id ]; } return null; } return $this->stacks; } /** * Get element stack. * * Retrieve a specific stack for the list of stacks from the current instance. * * @since 1.0.0 * @access public * * @param Controls_Stack $controls_stack Controls stack. * * @return null|array Stack data if it exists, `null` otherwise. */ public function get_element_stack( Controls_Stack $controls_stack ) { $stack_id = $controls_stack->get_unique_name(); if ( ! isset( $this->stacks[ $stack_id ] ) ) { return null; } if ( $this->should_clean_stack( $this->stacks[ $stack_id ] ) ) { $this->delete_stack( $controls_stack ); return null; } return $this->stacks[ $stack_id ]; } /** * Add custom CSS controls. * * This method adds a new control for the "Custom CSS" feature. The free * version of elementor uses this method to display an upgrade message to * Elementor Pro. * * @since 1.0.0 * @access public * * @param Controls_Stack $controls_stack . * @param string $tab * @param array $additional_messages * */ public function add_custom_css_controls( Controls_Stack $controls_stack, $tab = self::TAB_ADVANCED, $additional_messages = [] ) { $controls_stack->start_controls_section( 'section_custom_css_pro', [ 'label' => esc_html__( 'Custom CSS', 'elementor' ), 'tab' => $tab, ] ); $messages = [ esc_html__( 'Custom CSS lets you add CSS code to any widget, and see it render live right in the editor.', 'elementor' ), ]; if ( $additional_messages ) { $messages = array_merge( $messages, $additional_messages ); } $controls_stack->add_control( 'custom_css_pro', [ 'type' => self::RAW_HTML, 'raw' => $this->get_teaser_template( [ 'title' => esc_html__( 'Meet Our Custom CSS', 'elementor' ), 'messages' => $messages, 'link' => 'https://go.elementor.com/go-pro-custom-css/', ] ), ] ); $controls_stack->end_controls_section(); } /** * Add Page Transitions controls. * * This method adds a new control for the "Page Transitions" feature. The Core * version of elementor uses this method to display an upgrade message to * Elementor Pro. * * @param Controls_Stack $controls_stack . * @param string $tab * @param array $additional_messages * * @return void */ public function add_page_transitions_controls( Controls_Stack $controls_stack, $tab = self::TAB_ADVANCED, $additional_messages = [] ) { $controls_stack->start_controls_section( 'section_page_transitions_teaser', [ 'label' => esc_html__( 'Page Transitions', 'elementor' ), 'tab' => $tab, ] ); $messages = [ esc_html__( 'Page Transitions let you style entrance and exit animations between pages as well as display loader until your page assets load.', 'elementor' ), ]; if ( $additional_messages ) { $messages = array_merge( $messages, $additional_messages ); } $controls_stack->add_control( 'page_transitions_teaser', [ 'type' => self::RAW_HTML, 'raw' => $this->get_teaser_template( [ 'title' => esc_html__( 'Meet Page Transitions', 'elementor' ), 'messages' => $messages, 'link' => 'https://go.elementor.com/go-pro-page-transitions/', ] ), ] ); $controls_stack->end_controls_section(); } public function get_teaser_template( $texts ) { ob_start(); ?> <div class="elementor-nerd-box"> <img class="elementor-nerd-box-icon" src="<?php echo esc_url( ELEMENTOR_ASSETS_URL . 'images/go-pro.svg' ); ?>" loading="lazy" alt="<?php echo esc_attr__( 'Upgrade', 'elementor' ); ?>" /> <div class="elementor-nerd-box-title"><?php Utils::print_unescaped_internal_string( $texts['title'] ); ?></div> <?php foreach ( $texts['messages'] as $message ) { ?> <div class="elementor-nerd-box-message"><?php Utils::print_unescaped_internal_string( $message ); ?></div> <?php } // Show the upgrade button only if the user doesn't have Pro. if ( $texts['link'] && ! Utils::has_pro() ) { ?> <a class="elementor-button go-pro" href="<?php echo esc_url( ( $texts['link'] ) ); ?>" target="_blank"> <?php echo esc_html__( 'Upgrade Now', 'elementor' ); ?> </a> <?php } ?> </div> <?php return ob_get_clean(); } /** * Get Responsive Control Device Suffix * * @param array $control * @return string $device suffix */ public static function get_responsive_control_device_suffix( array $control ): string { if ( ! empty( $control['responsive']['max'] ) ) { $query_device = $control['responsive']['max']; } elseif ( ! empty( $control['responsive']['min'] ) ) { $query_device = $control['responsive']['min']; } else { return ''; } return 'desktop' === $query_device ? '' : '_' . $query_device; } /** * Add custom attributes controls. * * This method adds a new control for the "Custom Attributes" feature. The free * version of elementor uses this method to display an upgrade message to * Elementor Pro. * * @since 2.8.3 * @access public * * @param Controls_Stack $controls_stack. */ public function add_custom_attributes_controls( Controls_Stack $controls_stack, string $tab = self::TAB_ADVANCED ) { $controls_stack->start_controls_section( 'section_custom_attributes_pro', [ 'label' => esc_html__( 'Attributes', 'elementor' ), 'tab' => $tab, ] ); $controls_stack->add_control( 'custom_attributes_pro', [ 'type' => self::RAW_HTML, 'raw' => $this->get_teaser_template( [ 'title' => esc_html__( 'Meet Our Attributes', 'elementor' ), 'messages' => [ esc_html__( 'Attributes lets you add custom HTML attributes to any element.', 'elementor' ), ], 'link' => 'https://go.elementor.com/go-pro-custom-attributes/', ] ), ] ); $controls_stack->end_controls_section(); } /** * Check if a stack should be cleaned by the current responsive control duplication mode. * * @param $stack * @return bool */ private function should_clean_stack( $stack ): bool { if ( ! isset( $stack['responsive_control_duplication_mode'] ) ) { return false; } $stack_duplication_mode = $stack['responsive_control_duplication_mode']; // This array provides a convenient way to map human-readable mode names to numeric values for comparison. // If the current stack's mode is greater than or equal to the current mode, then we shouldn't clean the stack. $modes = [ 'off' => 1, 'dynamic' => 2, 'on' => 3, ]; if ( ! isset( $modes[ $stack_duplication_mode ] ) ) { return false; } $current_duplication_mode = Plugin::$instance->breakpoints->get_responsive_control_duplication_mode(); if ( $modes[ $stack_duplication_mode ] >= $modes[ $current_duplication_mode ] ) { return false; } return true; } public function add_display_conditions_controls( Controls_Stack $controls_stack ) { if ( Utils::has_pro() ) { return; } ob_start(); ?> <div class="e-control-display-conditions-promotion__wrapper"> <div class="e-control-display-conditions-promotion__description"> <span class="e-control-display-conditions-promotion__text"> <?php echo esc_html__( 'Display Conditions', 'elementor' ); ?> </span> <span class="e-control-display-conditions-promotion__lock-wrapper"> <i class="eicon-lock e-control-display-conditions-promotion"></i> </span> </div> <i class="eicon-flow e-control-display-conditions-promotion"></i> </div> <?php $control_template = ob_get_clean(); $controls_stack->add_control( 'display_conditions_pro', [ 'type' => self::RAW_HTML, 'separator' => 'before', 'raw' => $control_template, ] ); } public function add_motion_effects_promotion_control( Controls_Stack $controls_stack ) { if ( Utils::has_pro() ) { return; } $controls_stack->add_control( 'scrolling_effects_pro', [ 'type' => self::RAW_HTML, 'separator' => 'before', 'raw' => $this->promotion_switcher_control( esc_html__( 'Scrolling Effects', 'elementor' ), 'scrolling-effects' ), ] ); $controls_stack->add_control( 'mouse_effects_pro', [ 'type' => self::RAW_HTML, 'separator' => 'before', 'raw' => $this->promotion_switcher_control( esc_html__( 'Mouse Effects', 'elementor' ), 'mouse-effects' ), ] ); $controls_stack->add_control( 'sticky_pro', [ 'type' => self::RAW_HTML, 'separator' => 'before', 'raw' => $this->promotion_select_control( esc_html__( 'Sticky', 'elementor' ), 'sticky-effects' ), ] ); $controls_stack->add_control( 'motion_effects_promotion_divider', [ 'type' => self::DIVIDER, ] ); } private function promotion_switcher_control( $title, $id ): string { return '<div class="elementor-control-type-switcher elementor-label-inline e-control-motion-effects-promotion__wrapper"> <div class="elementor-control-content"> <div class="elementor-control-field"> <label> ' . $title . ' </label> <span class="e-control-motion-effects-promotion__lock-wrapper"> <i class="eicon-lock"></i> </span> <div class="elementor-control-input-wrapper"> <label class="elementor-switch elementor-control-unit-2 e-control-' . $id . '-promotion"> <input type="checkbox" class="elementor-switch-input" disabled> <span class="elementor-switch-label" data-off="Off"></span> <span class="elementor-switch-handle"></span> </label> </div> </div> </div> </div>'; } private function promotion_select_control( $title, $id ): string { return '<div class="elementor-control-type-select elementor-label-inline e-control-motion-effects-promotion__wrapper"> <div class="elementor-control-content"> <div class="elementor-control-field "> <label for="sticky-motion-effect-pro"> ' . $title . ' </label> <span class="e-control-motion-effects-promotion__lock-wrapper"> <i class="eicon-lock"></i> </span> <div class="elementor-control-input-wrapper elementor-control-unit-5 e-control-' . $id . '-promotion"> <div class="select-promotion elementor-control-unit-5">None</div> </div> </div> </div> </div>'; } private function is_style_control( $control_data ): bool { $frontend_available = $control_data['frontend_available'] ?? false; if ( $frontend_available ) { return false; } if ( ! empty( $control_data['control_type'] ) && 'content' === $control_data['control_type'] ) { return false; } if ( ! empty( $control_data['prefix_class'] ) ) { return false; } $render_type = $control_data['render_type'] ?? ''; if ( 'template' === $render_type ) { return false; } if ( 'ui' === $render_type ) { return true; } if ( ! empty( $control_data['selectors'] ) ) { return true; } return false; } } image.php 0000644 00000012203 14720521210 0006327 0 ustar 00 <?php namespace Elementor; use Elementor\Core\Editor\Editor; use Elementor\Core\Utils\Collection; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor images manager. * * Elementor images manager handler class is responsible for retrieving image * details. * * @since 1.0.0 */ class Images_Manager { /** * Get images details. * * Retrieve details for all the images. * * Fired by `wp_ajax_elementor_get_images_details` action. * * @since 1.0.0 * @access public */ public function get_images_details() { if ( ! current_user_can( Editor::EDITING_CAPABILITY ) ) { wp_send_json_error( 'Permission denied' ); } // PHPCS - Already validated by wp_ajax. $items = Utils::get_super_global_value( $_POST, 'items' ) ?? []; // phpcs:ignore WordPress.Security.NonceVerification.Missing $urls = []; foreach ( $items as $item ) { $urls[ $item['id'] ] = $this->get_details( $item['id'], $item['size'], $item['is_first_time'] ); } wp_send_json_success( $urls ); } /** * Get image details. * * Retrieve single image details. * * Fired by `wp_ajax_elementor_get_image_details` action. * * @since 1.0.0 * @access public * * @param string $id Image attachment ID. * @param string|array $size Image size. Accepts any valid image * size, or an array of width and height * values in pixels (in that order). * @param string $is_first_time Set 'true' string to force reloading * all image sizes. * * @return array URLs with different image sizes. */ public function get_details( $id, $size, $is_first_time ) { if ( ! class_exists( 'Group_Control_Image_Size' ) ) { require_once ELEMENTOR_PATH . '/includes/controls/groups/image-size.php'; } if ( 'true' === $is_first_time ) { $sizes = get_intermediate_image_sizes(); $sizes[] = 'full'; } else { $sizes = []; } $sizes[] = $size; $urls = []; foreach ( $sizes as $size ) { if ( 0 === strpos( $size, 'custom_' ) ) { preg_match( '/custom_(\d*)x(\d*)/', $size, $matches ); $matches[1] = (int) $matches[1]; $matches[2] = (int) $matches[2]; $instance = [ 'image_size' => 'custom', 'image_custom_dimension' => [ 'width' => $matches[1], 'height' => $matches[2], ], ]; $url = Group_Control_Image_Size::get_attachment_image_src( $id, 'image', $instance ); $thumbs_path = BFITHUMB_UPLOAD_DIR . '/' . basename( $url ); $image_meta = wp_get_attachment_metadata( $id ); // Attach custom image to original. $image_meta['sizes'][ 'elementor_' . $size ] = [ 'file' => $thumbs_path, 'width' => $matches[1], 'height' => $matches[2], 'mime-type' => get_post_mime_type( $id ), ]; wp_update_attachment_metadata( $id, $image_meta ); $urls[ $size ] = $url; } else { $urls[ $size ] = wp_get_attachment_image_src( $id, $size )[0]; } } return $urls; } /** * Get Light-Box Image Attributes * * Used to retrieve an array of image attributes to be used for displaying an image in Elementor's Light Box module. * * @param int $id The ID of the image * * @return array An array of image attributes including `title` and `description`. * @since 2.9.0 * @access public */ public function get_lightbox_image_attributes( $id ) { $attributes = []; $kit = Plugin::$instance->kits_manager->get_active_kit(); $lightbox_title_src = $kit->get_settings( 'lightbox_title_src' ); $lightbox_description_src = $kit->get_settings( 'lightbox_description_src' ); $attachment = get_post( $id ); if ( $attachment ) { $image_data = [ 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), 'caption' => $attachment->post_excerpt, 'description' => $attachment->post_content, 'title' => $attachment->post_title, ]; if ( $lightbox_title_src && $image_data[ $lightbox_title_src ] ) { $attributes['title'] = $image_data[ $lightbox_title_src ]; } if ( $lightbox_description_src && $image_data[ $lightbox_description_src ] ) { $attributes['description'] = $image_data[ $lightbox_description_src ]; } } return $attributes; } private function delete_custom_images( $post_id ) { $image_meta = wp_get_attachment_metadata( $post_id ); if ( ! empty( $image_meta ) && ! empty( $image_meta['sizes'] ) ) { ( new Collection( $image_meta['sizes'] ) ) ->filter( function ( $value, $key ) { return ( 0 === strpos( $key, 'elementor_custom_' ) ); } ) ->pluck( 'file' ) ->each( function ( $path ) { $base_dir = wp_get_upload_dir()['basedir']; wp_delete_file( $base_dir . '/' . $path ); } ); } } /** * Images manager constructor. * * Initializing Elementor images manager. * * @since 1.0.0 * @access public */ public function __construct() { add_action( 'wp_ajax_elementor_get_images_details', [ $this, 'get_images_details' ] ); // Delete elementor thumbnail files on deleting its main image. add_action( 'delete_attachment', function ( $post_id ) { $this->delete_custom_images( $post_id ); } ); } } skins.php 0000644 00000004506 14720521210 0006403 0 ustar 00 <?php namespace Elementor; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor skins manager. * * Elementor skins manager handler class is responsible for registering and * initializing all the supported skins. * * @since 1.0.0 */ class Skins_Manager { /** * Registered Skins. * * Holds the list of all the registered skins for all the widgets. * * @since 1.0.0 * @access private * * @var array Registered skins. */ private $_skins = []; /** * Add new skin. * * Register a single new skin for a widget. * * @since 1.0.0 * @access public * * @param Widget_Base $widget Elementor widget. * @param Skin_Base $skin Elementor skin. * * @return true True if skin added. */ public function add_skin( Widget_Base $widget, Skin_Base $skin ) { $widget_name = $widget->get_name(); if ( ! isset( $this->_skins[ $widget_name ] ) ) { $this->_skins[ $widget_name ] = []; } $this->_skins[ $widget_name ][ $skin->get_id() ] = $skin; return true; } /** * Remove a skin. * * Unregister an existing skin from a widget. * * @since 1.0.0 * @access public * * @param Widget_Base $widget Elementor widget. * @param string $skin_id Elementor skin ID. * * @return true|\WP_Error True if skin removed, `WP_Error` otherwise. */ public function remove_skin( Widget_Base $widget, $skin_id ) { $widget_name = $widget->get_name(); if ( ! isset( $this->_skins[ $widget_name ][ $skin_id ] ) ) { return new \WP_Error( 'Cannot remove not-exists skin.' ); } unset( $this->_skins[ $widget_name ][ $skin_id ] ); return true; } /** * Get skins. * * Retrieve all the skins assigned for a specific widget. * * @since 1.0.0 * @access public * * @param Widget_Base $widget Elementor widget. * * @return false|array Skins if the widget has skins, False otherwise. */ public function get_skins( Widget_Base $widget ) { $widget_name = $widget->get_name(); if ( ! isset( $this->_skins[ $widget_name ] ) ) { return false; } return $this->_skins[ $widget_name ]; } /** * Skins manager constructor. * * Initializing Elementor skins manager by requiring the skin base class. * * @since 1.0.0 * @access public */ public function __construct() { require ELEMENTOR_PATH . 'includes/base/skin-base.php'; } } elements.php 0000644 00000020733 14720521210 0007070 0 ustar 00 <?php namespace Elementor; use Elementor\Includes\Elements\Container; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor elements manager. * * Elementor elements manager handler class is responsible for registering and * initializing all the supported elements. * * @since 1.0.0 */ class Elements_Manager { /** * Element types. * * Holds the list of all the element types. * * @access private * * @var Element_Base[] */ private $_element_types; /** * Element categories. * * Holds the list of all the element categories. * * @access private * * @var */ private $categories; /** * Elements constructor. * * Initializing Elementor elements manager. * * @since 1.0.0 * @access public */ public function __construct() { $this->require_files(); } /** * Create element instance. * * This method creates a new element instance for any given element. * * @since 1.0.0 * @access public * * @param array $element_data Element data. * @param array $element_args Optional. Element arguments. Default is * an empty array. * @param Element_Base $element_type Optional. Element type. Default is null. * * @return Element_Base|null Element instance if element created, or null * otherwise. */ public function create_element_instance( array $element_data, array $element_args = [], Element_Base $element_type = null ) { if ( null === $element_type ) { if ( 'widget' === $element_data['elType'] ) { $element_type = Plugin::$instance->widgets_manager->get_widget_types( $element_data['widgetType'] ); } else { $element_type = $this->get_element_types( $element_data['elType'] ); } } if ( ! $element_type ) { return null; } $args = array_merge( $element_type->get_default_args(), $element_args ); $element_class = $element_type->get_class_name(); try { $element = new $element_class( $element_data, $args ); } catch ( \Exception $e ) { return null; } return $element; } /** * Get element categories. * * Retrieve the list of categories the element belongs to. * * @since 1.0.0 * @access public * * @return array Element categories. */ public function get_categories() { if ( null === $this->categories ) { $this->init_categories(); } return $this->categories; } /** * Add element category. * * Register new category for the element. * * @since 1.7.12 * @access public * * @param string $category_name Category name. * @param array $category_properties Category properties. */ public function add_category( $category_name, $category_properties ) { if ( null === $this->categories ) { $this->get_categories(); } if ( ! isset( $this->categories[ $category_name ] ) ) { $this->categories[ $category_name ] = $category_properties; } } /** * Register element type. * * Add new type to the list of registered types. * * @since 1.0.0 * @access public * * @param Element_Base $element Element instance. * * @return bool Whether the element type was registered. */ public function register_element_type( Element_Base $element ) { $this->_element_types[ $element->get_name() ] = $element; return true; } /** * Unregister element type. * * Remove element type from the list of registered types. * * @since 1.0.0 * @access public * * @param string $name Element name. * * @return bool Whether the element type was unregister, or not. */ public function unregister_element_type( $name ) { if ( ! isset( $this->_element_types[ $name ] ) ) { return false; } unset( $this->_element_types[ $name ] ); return true; } /** * Get element types. * * Retrieve the list of all the element types, or if a specific element name * was provided retrieve his element types. * * @since 1.0.0 * @access public * * @param string $element_name Optional. Element name. Default is null. * * @return null|Element_Base|Element_Base[] Element types, or a list of all the element * types, or null if element does not exist. */ public function get_element_types( $element_name = null ) { if ( is_null( $this->_element_types ) ) { $this->init_elements(); } if ( null !== $element_name ) { return isset( $this->_element_types[ $element_name ] ) ? $this->_element_types[ $element_name ] : null; } return $this->_element_types; } /** * Get element types config. * * Retrieve the config of all the element types. * * @since 1.0.0 * @access public * * @return array Element types config. */ public function get_element_types_config() { $config = []; foreach ( $this->get_element_types() as $element ) { $config[ $element->get_name() ] = $element->get_config(); } return $config; } /** * Render elements content. * * Used to generate the elements templates on the editor. * * @since 1.0.0 * @access public */ public function render_elements_content() { foreach ( $this->get_element_types() as $element_type ) { $element_type->print_template(); } } /** * Init elements. * * Initialize Elementor elements by registering the supported elements. * Elementor supports by default `section` element and `column` element. * * @since 2.0.0 * @access private */ private function init_elements() { $this->_element_types = []; foreach ( [ 'section', 'column' ] as $element_name ) { $class_name = __NAMESPACE__ . '\Element_' . $element_name; $this->register_element_type( new $class_name() ); } $experiments_manager = Plugin::$instance->experiments; if ( $experiments_manager->is_feature_active( 'container' ) ) { $this->register_element_type( new Container() ); } /** * After elements registered. * * Fires after Elementor elements are registered. * * @since 1.0.0 */ do_action( 'elementor/elements/elements_registered', $this ); } /** * Init categories. * * Initialize the element categories. * * @since 1.7.12 * @access private */ private function init_categories() { $this->categories = [ 'layout' => [ 'title' => esc_html__( 'Layout', 'elementor' ), 'hideIfEmpty' => true, ], 'basic' => [ 'title' => esc_html__( 'Basic', 'elementor' ), 'icon' => 'eicon-font', ], 'pro-elements' => [ 'title' => esc_html__( 'Pro', 'elementor' ), 'promotion' => [ 'url' => esc_url( 'https://go.elementor.com/go-pro-section-pro-widget-panel/' ), ], ], 'general' => [ 'title' => esc_html__( 'General', 'elementor' ), 'icon' => 'eicon-font', ], 'link-in-bio' => [ 'title' => esc_html__( 'Link In Bio', 'elementor' ), 'hideIfEmpty' => true, ], 'theme-elements' => [ 'title' => esc_html__( 'Site', 'elementor' ), 'active' => false, 'promotion' => [ 'url' => esc_url( 'https://go.elementor.com/go-pro-section-site-widget-panel/' ), ], ], 'woocommerce-elements' => [ 'title' => esc_html__( 'WooCommerce', 'elementor' ), 'active' => false, 'promotion' => [ 'url' => esc_url( 'https://go.elementor.com/go-pro-section-woocommerce-widget-panel/' ), ], ], ]; // Not using the `add_category` because it doesn't allow 3rd party to inject a category on top the others. $this->categories = array_merge_recursive( [ 'favorites' => [ 'title' => esc_html__( 'Favorites', 'elementor' ), 'icon' => 'eicon-heart', 'sort' => 'a-z', 'hideIfEmpty' => false, ], ], $this->categories ); /** * When categories are registered. * * Fires after basic categories are registered, before WordPress * category have been registered. * * This is where categories registered by external developers are * added. * * @since 2.0.0 * * @param Elements_Manager $this Elements manager instance. */ do_action( 'elementor/elements/categories_registered', $this ); $this->categories['wordpress'] = [ 'title' => esc_html__( 'WordPress', 'elementor' ), 'icon' => 'eicon-wordpress', 'active' => false, ]; } /** * Require files. * * Require Elementor element base class and column, section and repeater * elements. * * @since 1.0.0 * @access private */ private function require_files() { require_once ELEMENTOR_PATH . 'includes/base/element-base.php'; require ELEMENTOR_PATH . 'includes/elements/column.php'; require ELEMENTOR_PATH . 'includes/elements/section.php'; require ELEMENTOR_PATH . 'includes/elements/repeater.php'; } } icons.php 0000644 00000043555 14720521210 0006376 0 ustar 00 <?php namespace Elementor; use Elementor\Core\Files\File_Types\Svg; use Elementor\Core\Page_Assets\Data_Managers\Font_Icon_Svg\Manager as Font_Icon_Svg_Data_Manager; use Elementor\Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor icons manager. * * Elementor icons manager handler class * * @since 2.4.0 */ class Icons_Manager { const NEEDS_UPDATE_OPTION = 'icon_manager_needs_update'; const FONT_ICON_SVG_CLASS_NAME = 'e-font-icon-svg'; const LOAD_FA4_SHIM_OPTION_KEY = 'elementor_load_fa4_shim'; const ELEMENTOR_ICONS_VERSION = '5.32.0'; /** * Tabs. * * Holds the list of all the tabs. * * @access private * @static * @since 2.4.0 * @var array */ private static $tabs; private static $data_manager; private static function get_needs_upgrade_option() { return get_option( 'elementor_' . self::NEEDS_UPDATE_OPTION, null ); } /** * @param $icon * @param $attributes * @param $tag * @return bool|mixed|string */ public static function try_get_icon_html( $icon, $attributes = [], $tag = 'i' ) { if ( empty( $icon['library'] ) ) { return ''; } return static::get_icon_html( $icon, $attributes, $tag ); } /** * @param array $icon * @param array $attributes * @param $tag * @return bool|mixed|string */ private static function get_icon_html( array $icon, array $attributes, $tag ) { /** * When the library value is svg it means that it's a SVG media attachment uploaded by the user. * Otherwise, it's the name of the font family that the icon belongs to. */ if ( 'svg' === $icon['library'] ) { $output = self::render_uploaded_svg_icon( $icon['value'] ); } else { $output = self::render_font_icon( $icon, $attributes, $tag ); } return $output; } /** * register styles * * Used to register all icon types stylesheets so they could be enqueued later by widgets */ public function register_styles() { $config = self::get_icon_manager_tabs_config(); $shared_styles = []; foreach ( $config as $type => $icon_type ) { if ( ! isset( $icon_type['url'] ) ) { continue; } $dependencies = []; if ( ! empty( $icon_type['enqueue'] ) ) { foreach ( (array) $icon_type['enqueue'] as $font_css_url ) { if ( ! in_array( $font_css_url, array_keys( $shared_styles ), true ) ) { $style_handle = 'elementor-icons-shared-' . count( $shared_styles ); wp_register_style( $style_handle, $font_css_url, [], $icon_type['ver'] ); $shared_styles[ $font_css_url ] = $style_handle; } $dependencies[] = $shared_styles[ $font_css_url ]; } } wp_register_style( 'elementor-icons-' . $icon_type['name'], $icon_type['url'], $dependencies, $icon_type['ver'] ); } } /** * Init Tabs * * Initiate Icon Manager Tabs. * * @access private * @static * @since 2.4.0 */ private static function init_tabs() { $initial_tabs = [ 'fa-regular' => [ 'name' => 'fa-regular', 'label' => esc_html__( 'Font Awesome - Regular', 'elementor' ), 'url' => self::get_fa_asset_url( 'regular' ), 'enqueue' => [ self::get_fa_asset_url( 'fontawesome' ) ], 'prefix' => 'fa-', 'displayPrefix' => 'far', 'labelIcon' => 'fab fa-font-awesome-alt', 'ver' => '5.15.3', 'fetchJson' => self::get_fa_asset_url( 'regular', 'js', false ), 'native' => true, ], 'fa-solid' => [ 'name' => 'fa-solid', 'label' => esc_html__( 'Font Awesome - Solid', 'elementor' ), 'url' => self::get_fa_asset_url( 'solid' ), 'enqueue' => [ self::get_fa_asset_url( 'fontawesome' ) ], 'prefix' => 'fa-', 'displayPrefix' => 'fas', 'labelIcon' => 'fab fa-font-awesome', 'ver' => '5.15.3', 'fetchJson' => self::get_fa_asset_url( 'solid', 'js', false ), 'native' => true, ], 'fa-brands' => [ 'name' => 'fa-brands', 'label' => esc_html__( 'Font Awesome - Brands', 'elementor' ), 'url' => self::get_fa_asset_url( 'brands' ), 'enqueue' => [ self::get_fa_asset_url( 'fontawesome' ) ], 'prefix' => 'fa-', 'displayPrefix' => 'fab', 'labelIcon' => 'fab fa-font-awesome-flag', 'ver' => '5.15.3', 'fetchJson' => self::get_fa_asset_url( 'brands', 'js', false ), 'native' => true, ], ]; /** * Initial icon manager tabs. * * Filters the list of initial icon manager tabs. * * @param array $icon_manager_tabs Initial icon manager tabs. */ $initial_tabs = apply_filters( 'elementor/icons_manager/native', $initial_tabs ); self::$tabs = $initial_tabs; } /** * Get Icon Manager Tabs * @return array */ public static function get_icon_manager_tabs() { if ( self::is_font_icon_inline_svg() && ! Plugin::$instance->editor->is_edit_mode() && ! Plugin::$instance->preview->is_preview_mode() ) { self::$tabs = []; } elseif ( ! self::$tabs ) { self::init_tabs(); } $additional_tabs = []; /** * Additional icon manager tabs. * * Filters additional icon manager tabs. * * @param array $additional_tabs Additional icon manager tabs. Default is an empty array. */ $additional_tabs = apply_filters( 'elementor/icons_manager/additional_tabs', $additional_tabs ); return array_replace( self::$tabs, $additional_tabs ); } public static function enqueue_shim() { //phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter wp_enqueue_script( 'font-awesome-4-shim', self::get_fa_asset_url( 'v4-shims', 'js' ), [], ELEMENTOR_VERSION ); // Make sure that the CSS in the 'all' file does not override FA Pro's CSS if ( ! wp_script_is( 'font-awesome-pro' ) ) { wp_enqueue_style( 'font-awesome-5-all', self::get_fa_asset_url( 'all' ), [], ELEMENTOR_VERSION ); } wp_enqueue_style( 'font-awesome-4-shim', self::get_fa_asset_url( 'v4-shims' ), [], ELEMENTOR_VERSION ); } private static function get_fa_asset_url( $filename, $ext_type = 'css', $add_suffix = true ) { static $is_test_mode = null; if ( null === $is_test_mode ) { $is_test_mode = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG || defined( 'ELEMENTOR_TESTS' ) && ELEMENTOR_TESTS; } $url = ELEMENTOR_ASSETS_URL . 'lib/font-awesome/' . $ext_type . '/' . $filename; if ( ! $is_test_mode && $add_suffix ) { $url .= '.min'; } return $url . '.' . $ext_type; } public static function get_icon_manager_tabs_config() { $tabs = [ 'all' => [ 'name' => 'all', 'label' => esc_html__( 'All Icons', 'elementor' ), 'labelIcon' => 'eicon-filter', 'native' => true, ], ]; return array_values( array_merge( $tabs, self::get_icon_manager_tabs() ) ); } /** * is_font_awesome_inline * * @return bool */ private static function is_font_icon_inline_svg() { return Plugin::$instance->experiments->is_feature_active( 'e_font_icon_svg' ); } /** * @deprecated 3.8.0 */ public static function render_svg_symbols() {} public static function get_icon_svg_data( $icon ) { return self::$data_manager->get_font_icon_svg_data( $icon ); } /** * Get font awesome svg. * @param $icon array [ 'value' => string, 'library' => string ] * * @return bool|mixed|string */ public static function get_font_icon_svg( $icon, $attributes = [] ) { // Load the SVG from the database. $icon_data = self::get_icon_svg_data( $icon ); if ( ! $icon_data['path'] ) { return ''; } if ( ! empty( $attributes['class'] ) && ! is_array( $attributes['class'] ) ) { $attributes['class'] = [ $attributes['class'] ]; } $attributes['class'][] = self::FONT_ICON_SVG_CLASS_NAME; $attributes['class'][] = 'e-' . $icon_data['key']; $attributes['viewBox'] = '0 0 ' . $icon_data['width'] . ' ' . $icon_data['height']; $attributes['xmlns'] = 'http://www.w3.org/2000/svg'; return ( '<svg ' . Utils::render_html_attributes( $attributes ) . '>' . '<path d="' . esc_attr( $icon_data['path'] ) . '"></path>' . '</svg>' ); } public static function render_uploaded_svg_icon( $value ) { if ( ! isset( $value['id'] ) ) { return ''; } return Svg::get_inline_svg( $value['id'] ); } public static function render_font_icon( $icon, $attributes = [], $tag = 'i' ) { $icon_types = self::get_icon_manager_tabs(); if ( isset( $icon_types[ $icon['library'] ]['render_callback'] ) && is_callable( $icon_types[ $icon['library'] ]['render_callback'] ) ) { return call_user_func_array( $icon_types[ $icon['library'] ]['render_callback'], [ $icon, $attributes, $tag ] ); } $content = ''; $font_icon_svg_family = self::is_font_icon_inline_svg() ? Font_Icon_Svg_Data_Manager::get_font_family( $icon['library'] ) : ''; if ( $font_icon_svg_family ) { $icon['font_family'] = $font_icon_svg_family; $content = self::get_font_icon_svg( $icon, $attributes ); if ( $content ) { return $content; } } if ( ! $content ) { if ( empty( $attributes['class'] ) ) { $attributes['class'] = $icon['value']; } else { if ( is_array( $attributes['class'] ) ) { $attributes['class'][] = $icon['value']; } else { $attributes['class'] .= ' ' . $icon['value']; } } } return '<' . $tag . ' ' . Utils::render_html_attributes( $attributes ) . '>' . $content . '</' . $tag . '>'; } /** * Render Icon * * Used to render Icon for \Elementor\Controls_Manager::ICONS * @param array $icon Icon Type, Icon value * @param array $attributes Icon HTML Attributes * @param string $tag Icon HTML tag, defaults to <i> * * @return mixed|string */ public static function render_icon( $icon, $attributes = [], $tag = 'i' ) { if ( empty( $icon['library'] ) ) { return false; } $output = static::get_icon_html( $icon, $attributes, $tag ); Utils::print_unescaped_internal_string( $output ); return true; } /** * Font Awesome 4 to font Awesome 5 Value Migration * * used to convert string value of Icon control to array value of Icons control * ex: 'fa fa-star' => [ 'value' => 'fas fa-star', 'library' => 'fa-solid' ] * * @param $value * * @return array */ public static function fa4_to_fa5_value_migration( $value ) { static $migration_dictionary = false; if ( '' === $value ) { return [ 'value' => '', 'library' => '', ]; } if ( false === $migration_dictionary ) { $migration_dictionary = json_decode( Utils::file_get_contents( ELEMENTOR_ASSETS_PATH . 'lib/font-awesome/migration/mapping.js' ), true ); } if ( isset( $migration_dictionary[ $value ] ) ) { return $migration_dictionary[ $value ]; } return [ 'value' => 'fas ' . str_replace( 'fa ', '', $value ), 'library' => 'fa-solid', ]; } /** * on_import_migration * @param array $element settings array * @param string $old_control old control id * @param string $new_control new control id * @param bool $remove_old boolean whether to remove old control or not * * @return array */ public static function on_import_migration( array $element, $old_control = '', $new_control = '', $remove_old = false ) { if ( ! isset( $element['settings'][ $old_control ] ) || isset( $element['settings'][ $new_control ] ) ) { return $element; } // Case when old value is saved as empty string $new_value = [ 'value' => '', 'library' => '', ]; // Case when old value needs migration if ( ! empty( $element['settings'][ $old_control ] ) && ! self::is_migration_allowed() ) { $new_value = self::fa4_to_fa5_value_migration( $element['settings'][ $old_control ] ); } $element['settings'][ $new_control ] = $new_value; //remove old value if ( $remove_old ) { unset( $element['settings'][ $old_control ] ); } return $element; } /** * is_migration_allowed * @return bool */ public static function is_migration_allowed() { static $migration_allowed = false; if ( false === $migration_allowed ) { $migration_allowed = null === self::get_needs_upgrade_option(); /** * Is icon migration allowed. * * Filters whether the icons migration allowed. * * @param bool $migration_allowed Is icon migration is allowed. */ $migration_allowed = apply_filters( 'elementor/icons_manager/migration_allowed', $migration_allowed ); } return $migration_allowed; } /** * Register_Admin Settings * * adds Font Awesome migration / update admin settings * @param Settings $settings */ public function register_admin_settings( Settings $settings ) { $settings->add_field( Settings::TAB_ADVANCED, Settings::TAB_ADVANCED, 'load_fa4_shim', [ 'label' => esc_html__( 'Load Font Awesome 4 Support', 'elementor' ), 'field_args' => [ 'type' => 'select', 'std' => '', 'options' => [ '' => esc_html__( 'No', 'elementor' ), 'yes' => esc_html__( 'Yes', 'elementor' ), ], 'desc' => esc_html__( 'Font Awesome 4 support script (shim.js) is a script that makes sure all previously selected Font Awesome 4 icons are displayed correctly while using Font Awesome 5 library.', 'elementor' ), ], ] ); } public function register_admin_tools_settings( Tools $settings ) { $settings->add_tab( 'fontawesome4_migration', [ 'label' => esc_html__( 'Font Awesome Upgrade', 'elementor' ) ] ); $settings->add_section( 'fontawesome4_migration', 'fontawesome4_migration', [ 'callback' => function() { echo '<h2>' . esc_html__( 'Font Awesome Upgrade', 'elementor' ) . '</h2>'; echo '<p>' . // PHPCS - Plain Text esc_html__( 'Access 1,500+ amazing Font Awesome 5 icons and enjoy faster performance and design flexibility.', 'elementor' ) . '<br>' . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped esc_html__( 'By upgrading, whenever you edit a page containing a Font Awesome 4 icon, Elementor will convert it to the new Font Awesome 5 icon.', 'elementor' ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped '</p><p><strong>' . esc_html__( 'Please note that the upgrade process may cause some of the previously used Font Awesome 4 icons to look a bit different due to minor design changes made by Font Awesome.', 'elementor' ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped '</strong></p><p>' . esc_html__( 'The upgrade process includes a database update', 'elementor' ) . ' - ' . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped esc_html__( 'We highly recommend backing up your database before performing this upgrade.', 'elementor' ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped '</p>' . esc_html__( 'This action is not reversible and cannot be undone by rolling back to previous versions.', 'elementor' ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped '</p>'; }, 'fields' => [ [ 'label' => esc_html__( 'Font Awesome Upgrade', 'elementor' ), 'field_args' => [ 'type' => 'raw_html', 'html' => sprintf( '<span data-action="%s" data-_nonce="%s" data-redirect-url="%s" class="button" id="elementor_upgrade_fa_button">%s</span>', self::NEEDS_UPDATE_OPTION . '_upgrade', wp_create_nonce( self::NEEDS_UPDATE_OPTION ), esc_url( $this->get_upgrade_redirect_url() ), esc_html__( 'Upgrade To Font Awesome 5', 'elementor' ) ), ], ], ], ] ); } /** * Get redirect URL when upgrading font awesome. * * @return string */ public function get_upgrade_redirect_url() { if ( ! wp_verify_nonce( Utils::get_super_global_value( $_GET, '_wpnonce' ), 'tools-page-from-editor' ) ) { return ''; } $document_id = ! empty( $_GET['redirect_to_document'] ) ? absint( $_GET['redirect_to_document'] ) : null; if ( ! $document_id ) { return ''; } $document = Plugin::$instance->documents->get( $document_id ); if ( ! $document ) { return ''; } return $document->get_edit_url(); } /** * Ajax Upgrade to FontAwesome 5 */ public function ajax_upgrade_to_fa5() { check_ajax_referer( self::NEEDS_UPDATE_OPTION, '_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'Permission denied' ); } delete_option( 'elementor_' . self::NEEDS_UPDATE_OPTION ); wp_send_json_success( [ 'message' => esc_html__( 'Hurray! The upgrade process to Font Awesome 5 was completed successfully.', 'elementor' ) ] ); } /** * Add Update Needed Flag * @param array $settings * * @return array; */ public function add_update_needed_flag( $settings ) { $settings['icons_update_needed'] = true; return $settings; } public function enqueue_fontawesome_css() { if ( ! self::is_migration_allowed() ) { wp_enqueue_style( 'font-awesome' ); } else { $current_filter = current_filter(); $load_shim = get_option( self::LOAD_FA4_SHIM_OPTION_KEY, false ); if ( 'elementor/editor/after_enqueue_styles' === $current_filter ) { self::enqueue_shim(); } elseif ( 'yes' === $load_shim ) { self::enqueue_shim(); } } } /** * @deprecated 3.1.0 */ public function add_admin_strings() { Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0' ); return []; } /** * Icons Manager constructor */ public function __construct() { if ( is_admin() ) { // @todo: remove once we deprecate fa4 add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_settings' ], 100 ); } if ( self::is_font_icon_inline_svg() ) { self::$data_manager = new Font_Icon_Svg_Data_Manager(); } add_action( 'elementor/frontend/after_enqueue_styles', [ $this, 'enqueue_fontawesome_css' ] ); add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] ); if ( ! self::is_migration_allowed() ) { add_filter( 'elementor/editor/localize_settings', [ $this, 'add_update_needed_flag' ] ); add_action( 'elementor/admin/after_create_settings/' . Tools::PAGE_ID, [ $this, 'register_admin_tools_settings' ], 100 ); if ( ! empty( $_POST ) ) { // phpcs:ignore -- nonce validation done in callback add_action( 'wp_ajax_' . self::NEEDS_UPDATE_OPTION . '_upgrade', [ $this, 'ajax_upgrade_to_fa5' ] ); } } } } wordpress-widgets.php 0000644 00000005326 14720521210 0010751 0 ustar 00 <?php namespace Elementor; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor WordPress widgets manager. * * Elementor WordPress widgets manager handler class is responsible for * registering and initializing all the supported controls, both regular * controls and the group controls. * * @since 1.5.0 */ class WordPress_Widgets_Manager { /** * WordPress widgets manager constructor. * * Initializing the WordPress widgets manager in Elementor editor. * * @since 1.5.0 * @access public */ public function __construct() { if ( version_compare( get_bloginfo( 'version' ), '4.8', '<' ) ) { return; } add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'before_enqueue_scripts' ] ); add_action( 'elementor/editor/footer', [ $this, 'footer' ] ); } /** * Before enqueue scripts. * * Prints custom scripts required to run WordPress widgets in Elementor * editor. * * Fired by `elementor/editor/before_enqueue_scripts` action. * * @since 1.5.0 * @access public */ public function before_enqueue_scripts() { global $wp_scripts; $suffix = Utils::is_script_debug() ? '' : '.min'; // TODO: after WP >= 4.9 - it's no needed, Keep for Backward compatibility. $wp_scripts->add( 'media-widgets', "/wp-admin/js/widgets/media-widgets$suffix.js", array( 'jquery', 'media-models', 'media-views' ) ); $wp_scripts->add_inline_script( 'media-widgets', 'wp.mediaWidgets.init();', 'after' ); $wp_scripts->add( 'media-audio-widget', "/wp-admin/js/widgets/media-audio-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) ); $wp_scripts->add( 'media-image-widget', "/wp-admin/js/widgets/media-image-widget$suffix.js", array( 'media-widgets' ) ); $wp_scripts->add( 'media-video-widget', "/wp-admin/js/widgets/media-video-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) ); $wp_scripts->add( 'text-widgets', "/wp-admin/js/widgets/text-widgets$suffix.js", array( 'jquery', 'editor', 'wp-util' ) ); $wp_scripts->add_inline_script( 'text-widgets', 'wp.textWidgets.init();', 'after' ); wp_enqueue_style( 'widgets' ); wp_enqueue_style( 'media-views' ); // End TODO. // Don't enqueue `code-editor` for WP Custom HTML widget. wp_get_current_user()->syntax_highlighting = 'false'; /** This action is documented in wp-admin/admin-header.php */ do_action( 'admin_print_scripts-widgets.php' ); } /** * WordPress widgets footer. * * Prints WordPress widgets scripts in Elementor editor footer. * * Fired by `elementor/editor/footer` action. * * @since 1.5.0 * @access public */ public function footer() { /** This action is documented in wp-admin/admin-footer.php */ do_action( 'admin_footer-widgets.php' ); } } widgets.php 0000644 00000040641 14720521210 0006722 0 ustar 00 <?php namespace Elementor; use Elementor\Core\Common\Modules\Ajax\Module as Ajax; use Elementor\Core\Utils\Collection; use Elementor\Core\Utils\Exceptions; use Elementor\Core\Utils\Force_Locale; use Elementor\Modules\NestedAccordion\Widgets\Nested_Accordion; use Elementor\Modules\NestedElements\Module as NestedElementsModule; use Elementor\Modules\NestedTabs\Widgets\NestedTabs; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor widgets manager. * * Elementor widgets manager handler class is responsible for registering and * initializing all the supported Elementor widgets. * * @since 1.0.0 */ class Widgets_Manager { /** * Widget types. * * Holds the list of all the widget types. * * @since 1.0.0 * @access private * * @var Widget_Base[] */ private $_widget_types = null; /** * Promoted widget types. * * Holds the list of all the Promoted widget types. * * @since 3.15.0 * @access private * * @var Widget_Base[] * * @return array */ private array $promoted_widgets = [ NestedElementsModule::EXPERIMENT_NAME => [ NestedTabs::class, Nested_Accordion::class, ], ]; /** * Init widgets. * * Initialize Elementor widgets manager. Include all the widgets files * and register each Elementor and WordPress widget. * * @since 2.0.0 * @access private */ private function init_widgets() { $build_widgets_filename = [ 'common', 'inner-section', 'heading', 'image', 'text-editor', 'video', 'button', 'divider', 'spacer', 'image-box', 'google-maps', 'icon', 'icon-box', 'star-rating', 'image-carousel', 'image-gallery', 'icon-list', 'counter', 'progress', 'testimonial', 'tabs', 'accordion', 'toggle', 'social-icons', 'alert', 'audio', 'shortcode', 'html', 'menu-anchor', 'sidebar', 'read-more', 'rating', 'share-buttons', ]; $this->_widget_types = []; $this->register_promoted_widgets(); foreach ( $build_widgets_filename as $widget_filename ) { include ELEMENTOR_PATH . 'includes/widgets/' . $widget_filename . '.php'; $class_name = str_replace( '-', '_', $widget_filename ); $class_name = __NAMESPACE__ . '\Widget_' . $class_name; $this->register( new $class_name() ); } $this->register_wp_widgets(); /** * After widgets registered. * * Fires after Elementor widgets are registered. * * @since 1.0.0 * @deprecated 3.5.0 Use `elementor/widgets/register` hook instead. * * @param Widgets_Manager $this The widgets manager. */ Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->do_deprecated_action( 'elementor/widgets/widgets_registered', [ $this ], '3.5.0', 'elementor/widgets/register' ); /** * After widgets registered. * * Fires after Elementor widgets are registered. * * @since 3.5.0 * * @param Widgets_Manager $this The widgets manager. */ do_action( 'elementor/widgets/register', $this ); } /** * Register WordPress widgets. * * Add native WordPress widget to the list of registered widget types. * * Exclude the widgets that are in Elementor widgets black list. Theme and * plugin authors can filter the black list. * * @since 2.0.0 * @access private */ private function register_wp_widgets() { global $wp_widget_factory; // Allow themes/plugins to filter out their widgets. $black_list = []; /** * Elementor widgets black list. * * Filters the widgets black list that won't be displayed in the panel. * * @since 1.0.0 * * @param array $black_list A black list of widgets. Default is an empty array. */ $black_list = apply_filters( 'elementor/widgets/black_list', $black_list ); foreach ( $wp_widget_factory->widgets as $widget_class => $widget_obj ) { if ( in_array( $widget_class, $black_list ) ) { continue; } $elementor_widget_class = __NAMESPACE__ . '\Widget_WordPress'; $this->register( new $elementor_widget_class( [], [ 'widget_name' => $widget_class, ] ) ); } } /** * Require files. * * Require Elementor widget base class. * * @since 2.0.0 * @access private */ private function require_files() { require ELEMENTOR_PATH . 'includes/base/widget-base.php'; } private function pluck_default_controls( $controls ) { return ( new Collection( $controls ) ) ->reduce( function ( $controls_defaults, $control, $control_key ) { if ( ! empty( $control['default'] ) ) { $controls_defaults[ $control_key ]['default'] = $control['default']; } return $controls_defaults; }, [] ); } /** * Register widget type. * * Add a new widget type to the list of registered widget types. * * @since 1.0.0 * @access public * @deprecated 3.5.0 Use `register()` method instead. * * @param Widget_Base $widget Elementor widget. * * @return true True if the widget was registered. */ public function register_widget_type( Widget_Base $widget ) { Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'register()' ); return $this->register( $widget ); } /** * Register a new widget type. * * @param \Elementor\Widget_Base $widget_instance Elementor Widget. * * @return bool True if the widget was registered. * @since 3.5.0 * @access public */ public function register( Widget_Base $widget_instance ) { if ( is_null( $this->_widget_types ) ) { $this->init_widgets(); } /** * Should widget be registered. * * @since 3.18.0 * * @param bool $should_register Should widget be registered. Default is `true`. * @param \Elementor\Widget_Base $widget_instance Widget instance. */ $should_register = apply_filters( 'elementor/widgets/is_widget_enabled', true, $widget_instance ); if ( ! $should_register ) { return false; } $this->_widget_types[ $widget_instance->get_name() ] = $widget_instance; return true; } /** Register promoted widgets * * Since we cannot allow widgets to place themselves is a specific * location on our widgets panel we need to use a hard coded solution for this. * * @return void */ private function register_promoted_widgets() { foreach ( $this->promoted_widgets as $experiment_name => $classes ) { $this->register_promoted_active_widgets( $experiment_name, $classes ); } } /** * Unregister widget type. * * Removes widget type from the list of registered widget types. * * @since 1.0.0 * @access public * @deprecated 3.5.0 Use `unregister()` method instead. * * @param string $name Widget name. * * @return true True if the widget was unregistered, False otherwise. */ public function unregister_widget_type( $name ) { Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'unregister()' ); return $this->unregister( $name ); } /** * Unregister widget type. * * Removes widget type from the list of registered widget types. * * @since 3.5.0 * @access public * * @param string $name Widget name. * * @return boolean Whether the widget was unregistered. */ public function unregister( $name ) { if ( ! isset( $this->_widget_types[ $name ] ) ) { return false; } unset( $this->_widget_types[ $name ] ); return true; } /** * Get widget types. * * Retrieve the registered widget types list. * * @since 1.0.0 * @access public * * @param string $widget_name Optional. Widget name. Default is null. * * @return Widget_Base|Widget_Base[]|null Registered widget types. */ public function get_widget_types( $widget_name = null ) { if ( is_null( $this->_widget_types ) ) { $this->init_widgets(); } if ( null !== $widget_name ) { return isset( $this->_widget_types[ $widget_name ] ) ? $this->_widget_types[ $widget_name ] : null; } return $this->_widget_types; } /** * Get widget types config. * * Retrieve all the registered widgets with config for each widgets. * * @since 1.0.0 * @access public * * @return array Registered widget types with each widget config. */ public function get_widget_types_config() { $config = []; foreach ( $this->get_widget_types() as $widget_key => $widget ) { $config[ $widget_key ] = $widget->get_config(); } return $config; } /** * @throws \Exception */ public function ajax_get_widget_types_controls_config( array $data ) { Plugin::$instance->documents->check_permissions( $data['editor_post_id'] ); wp_raise_memory_limit( 'admin' ); $config = []; foreach ( $this->get_widget_types() as $widget_key => $widget ) { if ( isset( $data['exclude'][ $widget_key ] ) ) { continue; } $config[ $widget_key ] = [ 'controls' => $widget->get_stack( false )['controls'], 'tabs_controls' => $widget->get_tabs_controls(), ]; } return $config; } public function ajax_get_widgets_default_value_translations( array $data = [] ) { $locale = empty( $data['locale'] ) ? get_locale() : $data['locale']; $force_locale = new Force_Locale( $locale ); $force_locale->force(); $controls = ( new Collection( $this->get_widget_types() ) ) ->map( function ( Widget_Base $widget ) { $controls = $widget->get_stack( false )['controls']; return [ 'controls' => $this->pluck_default_controls( $controls ), ]; } ) ->filter( function ( $widget ) { return ! empty( $widget['controls'] ); } ) ->all(); $force_locale->restore(); return $controls; } /** * Ajax render widget. * * Ajax handler for Elementor render_widget. * * Fired by `wp_ajax_elementor_render_widget` action. * * @since 1.0.0 * @access public * * @throws \Exception If current user don't have permissions to edit the post. * * @param array $request Ajax request. * * @return array { * Rendered widget. * * @type string $render The rendered HTML. * } */ public function ajax_render_widget( $request ) { $document = Plugin::$instance->documents->get_with_permissions( $request['editor_post_id'] ); // Override the global $post for the render. query_posts( [ 'p' => $request['editor_post_id'], 'post_type' => 'any', ] ); $editor = Plugin::$instance->editor; $is_edit_mode = $editor->is_edit_mode(); $editor->set_edit_mode( true ); Plugin::$instance->documents->switch_to_document( $document ); $render_html = $document->render_element( $request['data'] ); $editor->set_edit_mode( $is_edit_mode ); return [ 'render' => $render_html, ]; } /** * Ajax get WordPress widget form. * * Ajax handler for Elementor editor get_wp_widget_form. * * Fired by `wp_ajax_elementor_editor_get_wp_widget_form` action. * * @since 1.0.0 * @access public * * @param array $request Ajax request. * * @return bool|string Rendered widget form. * @throws \Exception */ public function ajax_get_wp_widget_form( $request ) { Plugin::$instance->documents->check_permissions( $request['editor_post_id'] ); if ( empty( $request['widget_type'] ) ) { return false; } if ( empty( $request['data'] ) ) { $request['data'] = []; } $element_data = [ 'id' => $request['id'], 'elType' => 'widget', 'widgetType' => $request['widget_type'], 'settings' => $request['data'], ]; /** * @var $widget_obj Widget_WordPress */ $widget_obj = Plugin::$instance->elements_manager->create_element_instance( $element_data ); if ( ! $widget_obj ) { return false; } return $widget_obj->get_form(); } /** * Render widgets content. * * Used to generate the widget templates on the editor using Underscore JS * template, for all the registered widget types. * * @since 1.0.0 * @access public */ public function render_widgets_content() { foreach ( $this->get_widget_types() as $widget ) { $widget->print_template(); } } /** * Get widgets frontend settings keys. * * Retrieve frontend controls settings keys for all the registered widget * types. * * @since 1.3.0 * @access public * * @return array Registered widget types with settings keys for each widget. */ public function get_widgets_frontend_settings_keys() { $keys = []; foreach ( $this->get_widget_types() as $widget_type_name => $widget_type ) { $widget_type_keys = $widget_type->get_frontend_settings_keys(); if ( $widget_type_keys ) { $keys[ $widget_type_name ] = $widget_type_keys; } } return $keys; } /** * Widgets with styles. * * This method returns the list of all the widgets in the `/includes/` * folder that have styles. * * @since 3.24.0 * @access public * * @return array The names of the widgets that have styles. */ public function widgets_with_styles(): array { return [ 'counter', 'divider', 'google_maps', 'heading', 'image', 'image-carousel', 'menu-anchor', 'rating', 'social-icons', 'spacer', 'testimonial', 'text-editor', 'video', ]; } /** * Widgets with responsive styles. * * This method returns the list of all the widgets in the `/includes/` * folder that have responsive styles. * * @since 3.24.0 * @access public * * @return array The names of the widgets that have responsive styles. */ public function widgets_with_responsive_styles(): array { return [ 'accordion', 'alert', 'icon-box', 'icon-list', 'image-box', 'image-gallery', 'progress', 'star-rating', 'tabs', 'toggle', ]; } /** * Enqueue widgets scripts. * * Enqueue all the scripts defined as a dependency for each widget. * * @since 1.3.0 * @access public */ public function enqueue_widgets_scripts() { foreach ( $this->get_widget_types() as $widget ) { $widget->enqueue_scripts(); } } /** * Enqueue widgets styles * * Enqueue all the styles defined as a dependency for each widget * * @access public */ public function enqueue_widgets_styles() { foreach ( $this->get_widget_types() as $widget ) { $widget->enqueue_styles(); } } /** * Retrieve inline editing configuration. * * Returns general inline editing configurations like toolbar types etc. * * @access public * @since 1.8.0 * * @return array { * Inline editing configuration. * * @type array $toolbar { * Toolbar types and the actions each toolbar includes. * Note: Wysiwyg controls uses the advanced toolbar, textarea controls * uses the basic toolbar and text controls has no toolbar. * * @type array $basic Basic actions included in the edit tool. * @type array $advanced Advanced actions included in the edit tool. * } * } */ public function get_inline_editing_config() { $basic_tools = [ 'bold', 'underline', 'italic', ]; $advanced_tools = array_merge( $basic_tools, [ 'createlink', 'unlink', 'h1' => [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'blockquote', 'pre', ], 'list' => [ 'insertOrderedList', 'insertUnorderedList', ], ] ); return [ 'toolbar' => [ 'basic' => $basic_tools, 'advanced' => $advanced_tools, ], ]; } /** * Widgets manager constructor. * * Initializing Elementor widgets manager. * * @since 1.0.0 * @access public */ public function __construct() { $this->require_files(); add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); } /** * Register ajax actions. * * Add new actions to handle data after an ajax requests returned. * * @since 2.0.0 * @access public * * @param Ajax $ajax_manager */ public function register_ajax_actions( Ajax $ajax_manager ) { $ajax_manager->register_ajax_action( 'render_widget', [ $this, 'ajax_render_widget' ] ); $ajax_manager->register_ajax_action( 'editor_get_wp_widget_form', [ $this, 'ajax_get_wp_widget_form' ] ); $ajax_manager->register_ajax_action( 'get_widgets_config', [ $this, 'ajax_get_widget_types_controls_config' ] ); $ajax_manager->register_ajax_action( 'get_widgets_default_value_translations', function ( array $data ) { return $this->ajax_get_widgets_default_value_translations( $data ); } ); } /** * @param $experiment_name * @param $classes * @return void */ public function register_promoted_active_widgets( string $experiment_name, array $classes ) : void { if ( ! Plugin::$instance->experiments->is_feature_active( $experiment_name ) || empty( $classes ) ) { return; } foreach ( $classes as $class_name ) { $this->register( new $class_name() ); } } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.3-4ubuntu2.24 | Генерация страницы: 0.41 |
proxy
|
phpinfo
|
Настройка