<?php namespace Elementor; use Elementor\Core\Base\Base_Object; use Elementor\Core\DynamicTags\Manager; use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager; use Elementor\Core\Frontend\Performance; use Elementor\Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor controls stack. * * An abstract class that provides the needed properties and methods to * manage and handle controls in the editor panel to inheriting classes. * * @since 1.4.0 * @abstract */ abstract class Controls_Stack extends Base_Object { /** * Responsive 'desktop' device name. * * @deprecated 3.4.0 */ const RESPONSIVE_DESKTOP = 'desktop'; /** * Responsive 'tablet' device name. * * @deprecated 3.4.0 */ const RESPONSIVE_TABLET = 'tablet'; /** * Responsive 'mobile' device name. * * @deprecated 3.4.0 */ const RESPONSIVE_MOBILE = 'mobile'; /** * Generic ID. * * Holds the unique ID. * * @access private * * @var string */ private $id; private $active_settings; private $parsed_active_settings; /** * Parsed Dynamic Settings. * * @access private * * @var null|array */ private $parsed_dynamic_settings; /** * Raw Data. * * Holds all the raw data including the element type, the child elements, * the user data. * * @access private * * @var null|array */ private $data; /** * The configuration. * * Holds the configuration used to generate the Elementor editor. It includes * the element name, icon, categories, etc. * * @access private * * @var null|array */ private $config; /** * The additional configuration. * * Holds additional configuration that has been set using `set_config` method. * The `config` property is not modified directly while using the method because * it's used to check whether the initial config already loaded (in `get_config`). * After the initial config loaded, the additional config is merged into it. * * @access private * * @var null|array */ private $additional_config = []; /** * Current section. * * Holds the current section while inserting a set of controls sections. * * @access private * * @var null|array */ private $current_section; /** * Current tab. * * Holds the current tab while inserting a set of controls tabs. * * @access private * * @var null|array */ private $current_tab; /** * Current popover. * * Holds the current popover while inserting a set of controls. * * @access private * * @var null|array */ private $current_popover; /** * Injection point. * * Holds the injection point in the stack where the control will be inserted. * * @access private * * @var null|array */ private $injection_point; /** * Data sanitized. * * @access private * * @var bool */ private $settings_sanitized = false; /** * Element render attributes. * * Holds all the render attributes of the element. Used to store data like * the HTML class name and the class value, or HTML element ID name and value. * * @access private * * @var array */ private $render_attributes = []; /** * Get element name. * * Retrieve the element name. * * @since 1.4.0 * @access public * @abstract * * @return string The name. */ abstract public function get_name(); /** * Get unique name. * * Some classes need to use unique names, this method allows you to create * them. By default it retrieves the regular name. * * @since 1.6.0 * @access public * * @return string Unique name. */ public function get_unique_name() { return $this->get_name(); } /** * Get element ID. * * Retrieve the element generic ID. * * @since 1.4.0 * @access public * * @return string The ID. */ public function get_id() { return $this->id; } /** * Get element ID. * * Retrieve the element generic ID as integer. * * @since 1.8.0 * @access public * * @return string The converted ID. */ public function get_id_int() { /** We ignore possible notices, in order to support elements created prior to v1.8.0 and might include * non-base 16 characters as part of their ID. */ return @hexdec( $this->id ); } /** * Get widget number. * * Get the first three numbers of the element converted ID. * * @since 3.16 * @access public * * @return string The widget number. */ public function get_widget_number(): string { return substr( $this->get_id_int(), 0, 3 ); } /** * Get the type. * * Retrieve the type, e.g. 'stack', 'section', 'widget' etc. * * @since 1.4.0 * @access public * @static * * @return string The type. */ public static function get_type() { return 'stack'; } /** * @since 2.9.0 * @access public * * @return bool */ public function is_editable() { return true; } /** * Get current section. * * When inserting new controls, this method will retrieve the current section. * * @since 1.7.1 * @access public * * @return null|array Current section. */ public function get_current_section() { return $this->current_section; } /** * Get current tab. * * When inserting new controls, this method will retrieve the current tab. * * @since 1.7.1 * @access public * * @return null|array Current tab. */ public function get_current_tab() { return $this->current_tab; } /** * Get controls. * * Retrieve all the controls or, when requested, a specific control. * * @since 1.4.0 * @access public * * @param string $control_id The ID of the requested control. Optional field, * when set it will return a specific control. * Default is null. * * @return mixed Controls list. */ public function get_controls( $control_id = null ) { $stack = $this->get_stack(); if ( null !== $control_id ) { $control_data = self::get_items( $stack['controls'], $control_id ); if ( null === $control_data && ! empty( $stack['style_controls'] ) ) { $control_data = self::get_items( $stack['style_controls'], $control_id ); } return $control_data; } $controls = $stack['controls']; if ( Performance::is_use_style_controls() && ! empty( $stack['style_controls'] ) ) { $controls += $stack['style_controls']; } return self::get_items( $controls, $control_id ); } /** * Get active controls. * * Retrieve an array of active controls that meet the condition field. * * If specific controls was given as a parameter, retrieve active controls * from that list, otherwise check for all the controls available. * * @since 1.4.0 * @since 2.0.9 Added the `controls` and the `settings` parameters. * @access public * @deprecated 3.0.0 * * @param array $controls Optional. An array of controls. Default is null. * @param array $settings Optional. Controls settings. Default is null. * * @return array Active controls. */ public function get_active_controls( array $controls = null, array $settings = null ) { Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.0.0' ); if ( ! $controls ) { $controls = $this->get_controls(); } if ( ! $settings ) { $settings = $this->get_controls_settings(); } $active_controls = array_reduce( array_keys( $controls ), function( $active_controls, $control_key ) use ( $controls, $settings ) { $control = $controls[ $control_key ]; if ( $this->is_control_visible( $control, $settings, $controls ) ) { $active_controls[ $control_key ] = $control; } return $active_controls; }, [] ); return $active_controls; } /** * Get controls settings. * * Retrieve the settings for all the controls that represent them. * * @since 1.5.0 * @access public * * @return array Controls settings. */ public function get_controls_settings() { return array_intersect_key( $this->get_settings(), $this->get_controls() ); } /** * Add new control to stack. * * Register a single control to allow the user to set/update data. * * This