__('Content'), self::TAB_STYLE => __('Style'), self::TAB_ADVANCED => __('Advanced'), self::TAB_RESPONSIVE => __('Responsive'), self::TAB_LAYOUT => __('Layout'), self::TAB_SETTINGS => __('Settings'), ]; } /** * Get tabs. * * Retrieve the tabs of the current control. * * @since 1.6.0 * @access public * @static * * @return array Control tabs. */ public static function getTabs() { if (!self::$tabs) { self::initTabs(); } 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 addTab($tab_name, $tab_label) { if (!self::$tabs) { self::initTabs(); } if (isset(self::$tabs[$tab_name])) { return; } self::$tabs[$tab_name] = $tab_label; } public static function getGroupsNames() { // Group name must use "-" instead of "_" return [ 'background', 'border', 'typography', 'image-size', 'box-shadow', 'css-filter', 'text-shadow', 'text-stroke', ]; } public static function getControlsNames() { 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::COLOR, self::MEDIA, self::SLIDER, self::DIMENSIONS, self::CHOOSE, self::WYSIWYG, self::CODE, self::FONT, // self::IMAGE_DIMENSIONS, // self::WP_WIDGET, self::URL, self::REPEATER, self::ICON, // self::GALLERY, self::STRUCTURE, self::SELECT2, self::DATE_TIME, self::BOX_SHADOW, self::TEXT_SHADOW, self::ANIMATION, self::HOVER_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 1.0.0 * @access private */ private function registerControls() { $this->controls = []; foreach (self::getControlsNames() as $control_id) { $control_class_id = str_replace(' ', '', ucwords(str_replace('_', ' ', $control_id))); $class_name = __NAMESPACE__ . '\Control' . $control_class_id; $this->registerControl($control_id, new $class_name()); } // Group Controls foreach (self::getGroupsNames() as $group_name) { $group_class_id = str_replace(' ', '', ucwords(str_replace('-', ' ', $group_name))); $class_name = __NAMESPACE__ . '\GroupControl' . $group_class_id; $this->control_groups[$group_name] = new $class_name(); } /** * After controls registered. * * Fires after Elementor controls are registered. * * @since 1.0.0 * * @param ControlsManager $this The controls manager. */ do_action('elementor/controls/controls_registered', $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 * * @param string $control_id Control ID. * @param BaseControl $control_instance Control instance, usually the * current instance. */ public function registerControl($control_id, BaseControl $control_instance) { $this->controls[$control_id] = $control_instance; } /** * Unregister control. * * This method removes control from the controls list. * * @since 1.0.0 * @access public * * @param string $control_id Control ID. * * @return bool True if the control was removed, False otherwise. */ public function unregisterControl($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 BaseControl[] Controls list. */ public function getControls() { if (null === $this->controls) { $this->registerControls(); } 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 getControl($control_id) { $controls = $this->getControls(); 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 getControlsData() { $controls_data = []; foreach ($this->getControls() as $name => $control) { $controls_data[$name] = $control->getSettings(); } 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 renderControls() { foreach ($this->getControls() as $control) { $control->printTemplate(); } } /** * 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 getControlGroups($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 GroupControlBase $instance Group control instance, usually the * current instance. * * @return GroupControlBase Group control instance. */ public function addGroupControl($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 enqueueControlScripts() { foreach ($this->getControls() 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 ControlsStack $controls_stack Controls stack. */ public function openStack(ControlsStack $controls_stack) { $stack_id = $controls_stack->getUniqueName(); $this->stacks[$stack_id] = [ 'tabs' => [], 'controls' => [], ]; } /** * Add control to stack. * * This method adds a new control to the stack. * * @since 1.0.0 * @access public * * @param ControlsStack $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 addControlToStack(ControlsStack $element, $control_id, $control_data, $options = []) { $default_options = [ 'overwrite' => false, 'index' => null, ]; $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->getControl($control_data['type']); if (!$control_type_instance) { _doing_it_wrong(sprintf('%1$s::%2$s', __CLASS__, __FUNCTION__), sprintf('Control type "%s" not found.', $control_data['type']), '1.0.0'); return false; } if ($control_type_instance instanceof BaseDataControl) { $control_default_value = $control_type_instance->getDefaultValue(); 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->getUniqueName(); if (!$options['overwrite'] && isset($this->stacks[$stack_id]['controls'][$control_id])) { _doing_it_wrong(sprintf('%1$s::%2$s', __CLASS__, __FUNCTION__), sprintf('Cannot redeclare control with same name "%s".', $control_id), '1.0.0'); return false; } $tabs = self::getTabs(); 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]['controls'][$control_id] = $control_data; if (null !== $options['index']) { $controls = $this->stacks[$stack_id]['controls']; $controls_keys = array_keys($controls); array_splice($controls_keys, $options['index'], 0, $control_id); $this->stacks[$stack_id]['controls'] = 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|WPError True if the stack was removed, False otherwise. */ public function removeControlFromStack($stack_id, $control_id) { if (is_array($control_id)) { foreach ($control_id as $id) { $this->removeControlFromStack($stack_id, $id); } return true; } if (empty($this->stacks[$stack_id]['controls'][$control_id])) { return new WPError('Cannot remove not-exists control.'); } unset($this->stacks[$stack_id]['controls'][$control_id]); return 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|WPError The control, or an error. */ public function getControlFromStack($stack_id, $control_id) { if (empty($this->stacks[$stack_id]['controls'][$control_id])) { return new WPError('Cannot get a not-exists control.'); } return $this->stacks[$stack_id]['controls'][$control_id]; } /** * Update control in stack. * * This method updates the control data for a given stack. * * @since 1.1.0 * @access public * * @param ControlsStack $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 updateControlInStack(ControlsStack $element, $control_id, $control_data, array $options = []) { $old_control_data = $this->getControlFromStack($element->getUniqueName(), $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->addControlToStack($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 getStacks($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 ControlsStack $controls_stack Controls stack. * * @return null|array Stack data if it exist, `null` otherwise. */ public function getElementStack(ControlsStack $controls_stack) { $stack_id = $controls_stack->getUniqueName(); if (!isset($this->stacks[$stack_id])) { return null; } return $this->stacks[$stack_id]; } /** * Add custom CSS controls. * * This method adds a new control for the "Custom CSS" feature. * * @since 1.0.0 * @access public * * @param ControlsStack $controls_stack. */ public function addCustomCssControls(ControlsStack $controls_stack) { $controls_stack->startControlsSection( 'section_custom_css', [ 'label' => __('Custom CSS'), 'tab' => self::TAB_ADVANCED, ] ); $controls_stack->addControl( 'custom_css_title', [ 'raw' => __('Add your own custom CSS here'), 'type' => ControlsManager::RAW_HTML, ] ); $controls_stack->addControl( 'custom_css', [ 'type' => ControlsManager::CODE, 'label' => __('Custom CSS'), 'language' => 'css', 'render_type' => 'ui', 'show_label' => false, 'description' => __('Use "selector" to target wrapper element. Examples:') . '
' . __(
                        "/* For main element */\nselector { color: red; }\n" .
                        "/* For child element */\nselector .child-element { margin: 10px; }\n" .
                        "/* Or use any custom selector */\n.my-class { text-align: center; }"
                    ) . '
', ] ); $controls_stack->endControlsSection(); } }