<?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