PluginProbe
Elementor Website Builder – more than just a page builder / 3.19.4
Elementor Website Builder – more than just a page builder v3.19.4
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
← All changes | includes/base/controls-stack.php +51 -130 4.1.23.19.4 View file →
@@ -3,10 +3,8 @@
3 3
4 4 use Elementor\Core\Base\Base_Object;
5 5 use Elementor\Core\DynamicTags\Manager;
6 6 use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
7 -use Elementor\Core\Frontend\Performance;
8 -use Elementor\Utils;
9 7
10 8 if ( ! defined( 'ABSPATH' ) ) {
11 9 exit; // Exit if accessed directly.
12 10 }
@@ -226,9 +224,9 @@
226 224 public function get_id_int() {
227 225 /** We ignore possible notices, in order to support elements created prior to v1.8.0 and might include
228 226 * non-base 16 characters as part of their ID.
229 227 */
230 - return @hexdec( (string) $this->id );
228 + return @hexdec( $this->id );
231 229 }
232 230
233 231 /**
234 232 * Get widget number.
@@ -311,26 +309,9 @@
311 309 *
312 310 * @return mixed Controls list.
313 311 */
314 312 public function get_controls( $control_id = null ) {
315 - $stack = $this->get_stack();
316 -
317 - if ( null !== $control_id ) {
318 - $control_data = self::get_items( $stack['controls'], $control_id );
319 - if ( null === $control_data && ! empty( $stack['style_controls'] ) ) {
320 - $control_data = self::get_items( $stack['style_controls'], $control_id );
321 - }
322 -
323 - return $control_data;
324 - }
325 -
326 - $controls = $stack['controls'];
327 -
328 - if ( Performance::is_use_style_controls() && ! empty( $stack['style_controls'] ) ) {
329 - $controls += $stack['style_controls'];
330 - }
331 -
332 - return self::get_items( $controls, $control_id );
313 + return self::get_items( $this->get_stack()['controls'], $control_id );
333 314 }
334 315
335 316 /**
336 317 * Get active controls.
@@ -349,9 +330,9 @@
349 330 * @param array $settings Optional. Controls settings. Default is null.
350 331 *
351 332 * @return array Active controls.
352 333 */
353 - public function get_active_controls( ?array $controls = null, ?array $settings = null ) {
334 + public function get_active_controls( array $controls = null, array $settings = null ) {
354 335 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.0.0' );
355 336
356 337 if ( ! $controls ) {
357 338 $controls = $this->get_controls();
@@ -449,47 +430,24 @@
449 430 $this->current_popover['initialized'] = true;
450 431 }
451 432 }
452 433
453 - if ( Performance::should_optimize_controls() ) {
454 - $ui_controls = [
455 - Controls_Manager::RAW_HTML,
456 - Controls_Manager::DIVIDER,
457 - Controls_Manager::HEADING,
458 - Controls_Manager::BUTTON,
459 - Controls_Manager::ALERT,
460 - Controls_Manager::NOTICE,
461 - Controls_Manager::DEPRECATED_NOTICE,
462 - ];
463 -
464 - if ( ! empty( $args['type'] ) && ! empty( $args['section'] ) && in_array( $args['type'], $ui_controls ) ) {
465 - $args = [
466 - 'type' => $args['type'],
467 - 'section' => $args['section'],
468 - ];
469 - }
470 -
434 + if ( $this->should_optimize_controls() ) {
471 435 unset(
472 436 $args['label_block'],
473 437 $args['label'],
474 - $args['title'],
475 438 $args['tab'],
476 439 $args['options'],
477 - $args['placeholder'],
478 440 $args['separator'],
479 441 $args['size_units'],
480 442 $args['range'],
443 + $args['render_type'],
481 444 $args['toggle'],
482 445 $args['ai'],
483 - $args['classes'],
484 - $args['style_transfer'],
485 - $args['show_label'],
486 - $args['description'],
487 446 $args['label_on'],
488 447 $args['label_off'],
489 448 $args['labels'],
490 - $args['handles'],
491 - $args['editor_available'],
449 + $args['handles']
492 450 );
493 451 }
494 452
495 453 return Plugin::$instance->controls_manager->add_control_to_stack( $this, $id, $args, $options );
@@ -494,8 +452,21 @@
494 452
495 453 return Plugin::$instance->controls_manager->add_control_to_stack( $this, $id, $args, $options );
496 454 }
497 455
456 + private function should_optimize_controls() {
457 + static $is_frontend = null;
458 +
459 + if ( null === $is_frontend ) {
460 + $is_frontend = (
461 + ! is_admin()
462 + && ! Plugin::$instance->preview->is_preview_mode()
463 + );
464 + }
465 +
466 + return $is_frontend;
467 + }
468 +
498 469 /**
499 470 * Remove control from stack.
500 471 *
501 472 * Unregister an existing control and remove it from the stack.
@@ -612,10 +583,10 @@
612 583
613 584 $position = array_merge( $default_position, $position );
614 585
615 586 if (
616 - ( 'control' === $position['type'] && in_array( $position['at'], [ 'start', 'end' ], true ) ) ||
617 - ( 'section' === $position['type'] && in_array( $position['at'], [ 'before', 'after' ], true ) )
587 + 'control' === $position['type'] && in_array( $position['at'], [ 'start', 'end' ], true ) ||
588 + 'section' === $position['type'] && in_array( $position['at'], [ 'before', 'after' ], true )
618 589 ) {
619 590 _doing_it_wrong( sprintf( '%s::%s', get_called_class(), __FUNCTION__ ), 'Invalid position arguments. Use `before` / `after` for control or `start` / `end` for section.', '1.7.0' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
620 591
621 592 return false;
@@ -637,13 +608,13 @@
637 608
638 609 $controls_keys = array_keys( $registered_controls );
639 610
640 611 while ( Controls_Manager::SECTION !== $registered_controls[ $controls_keys[ $target_section_index ] ]['type'] ) {
641 - --$target_section_index;
612 + $target_section_index--;
642 613 }
643 614
644 615 if ( 'section' === $position['type'] ) {
645 - ++$target_control_index;
616 + $target_control_index++;
646 617
647 618 if ( 'end' === $position['at'] ) {
648 619 while ( Controls_Manager::SECTION !== $registered_controls[ $controls_keys[ $target_control_index ] ]['type'] ) {
649 620 if ( ++$target_control_index >= count( $registered_controls ) ) {
@@ -655,9 +626,9 @@
655 626
656 627 $target_control = $registered_controls[ $controls_keys[ $target_control_index ] ];
657 628
658 629 if ( 'after' === $position['at'] ) {
659 - ++$target_control_index;
630 + $target_control_index++;
660 631 }
661 632
662 633 $section_id = $registered_controls[ $controls_keys[ $target_section_index ] ]['name'];
663 634
@@ -737,9 +708,9 @@
737 708
738 709 $controls_keys = array_keys( $registered_controls );
739 710
740 711 while ( true ) {
741 - ++$section_index;
712 + $section_index++;
742 713
743 714 if ( ! isset( $controls_keys[ $section_index ] ) ) {
744 715 break;
745 716 }
@@ -750,9 +721,9 @@
750 721 break;
751 722 }
752 723
753 724 $section_controls[ $control_key ] = $registered_controls[ $control_key ];
754 - }
725 + };
755 726
756 727 return $section_controls;
757 728 }
758 729
@@ -796,9 +767,9 @@
796 767 * @param array $settings Optional. Controls settings. Default is null.
797 768 *
798 769 * @return array Style controls.
799 770 */
800 - final public function get_style_controls( ?array $controls = null, ?array $settings = null ) {
771 + final public function get_style_controls( array $controls = null, array $settings = null ) {
801 772 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.0.0' );
802 773
803 774 $controls = $this->get_active_controls( $controls, $settings );
804 775
@@ -931,9 +902,9 @@
931 902 $control_args = $args;
932 903
933 904 // Set parent using the name from previous iteration.
934 905 if ( isset( $control_name ) ) {
935 - // If $control_name end with _widescreen use desktop name instead.
906 + // If $control_name end with _widescreen use desktop name instead
936 907 $control_args['parent'] = '_widescreen' === substr( $control_name, -strlen( '_widescreen' ) ) ? $id : $control_name;
937 908 } else {
938 909 $control_args['parent'] = null;
939 910 }
@@ -1060,10 +1031,10 @@
1060 1031 * @return array|null The config.
1061 1032 */
1062 1033 final public function get_config() {
1063 1034 if ( null === $this->config ) {
1064 - // TODO: This is for backwards compatibility starting from 2.9.0.
1065 - // This if statement should be removed when the method is hard-deprecated.
1035 + // TODO: This is for backwards compatibility starting from 2.9.0
1036 + // This if statement should be removed when the method is hard-deprecated
1066 1037 if ( $this->has_own_method( '_get_initial_config', self::class ) ) {
1067 1038 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_get_initial_config', '2.9.0', __CLASS__ . '::get_initial_config()' );
1068 1039
1069 1040 $this->config = $this->_get_initial_config();
@@ -1087,10 +1058,8 @@
1087 1058 * Set a config property.
1088 1059 *
1089 1060 * Set a specific property of the config list for this controls-stack.
1090 1061 *
1091 - * @param string $key
1092 - * @param string $value
1093 1062 * @since 3.5.0
1094 1063 * @access public
1095 1064 */
1096 1065 public function set_config( $key, $value ) {
@@ -1166,11 +1135,8 @@
1166 1135 return self::get_items( $this->data, $item );
1167 1136 }
1168 1137
1169 1138 /**
1170 - * @param null $setting
1171 - * @param null $settings
1172 - * @return array|mixed|null
1173 1139 * @since 2.0.14
1174 1140 * @access public
1175 1141 */
1176 1142 public function get_parsed_dynamic_settings( $setting = null, $settings = null ) {
@@ -1189,16 +1155,16 @@
1189 1155 * Get active settings.
1190 1156 *
1191 1157 * Retrieve the settings from all the active controls.
1192 1158 *
1193 - * @param array|null $settings Optional. Controls settings. Default is null.
1194 - * @param array|null $controls Optional. An array of controls. Default is null.
1195 - *
1196 - * @return array Active settings.
1159 + * @since 1.4.0
1197 1160 * @since 2.1.0 Added the `controls` and the `settings` parameters.
1198 1161 * @access public
1199 1162 *
1200 - * @since 1.4.0
1163 + * @param array $controls Optional. An array of controls. Default is null.
1164 + * @param array $settings Optional. Controls settings. Default is null.
1165 + *
1166 + * @return array Active settings.
1201 1167 */
1202 1168 public function get_active_settings( $settings = null, $controls = null ) {
1203 1169 $is_first_request = ! $settings && ! $this->active_settings;
1204 1170
@@ -1427,14 +1393,15 @@
1427 1393 * Whether the control is visible or not.
1428 1394 *
1429 1395 * Used to determine whether the control is visible or not.
1430 1396 *
1397 + * @since 1.4.0
1398 + * @access public
1399 + *
1431 1400 * @param array $control The control.
1432 - * @param null $values Optional. Condition values. Default is null.
1433 - * @param null $controls
1401 + * @param array $values Optional. Condition values. Default is null.
1402 + *
1434 1403 * @return bool Whether the control is visible.
1435 - * @since 1.4.0
1436 - * @access public
1437 1404 */
1438 1405 public function is_control_visible( $control, $values = null, $controls = null ) {
1439 1406 if ( null === $values ) {
1440 1407 $values = $this->get_settings();
@@ -1456,9 +1423,9 @@
1456 1423 preg_match( '/([a-z_\-0-9]+)(?:\[([a-z_]+)])?(!?)$/i', $condition_key, $condition_key_parts );
1457 1424
1458 1425 $pure_condition_key = $condition_key_parts[1];
1459 1426 $condition_sub_key = $condition_key_parts[2];
1460 - $is_negative_condition = (bool) $condition_key_parts[3];
1427 + $is_negative_condition = ! ! $condition_key_parts[3];
1461 1428
1462 1429 if ( ! isset( $values[ $pure_condition_key ] ) || null === $values[ $pure_condition_key ] ) {
1463 1430 return false;
1464 1431 }
@@ -1521,12 +1488,9 @@
1521 1488 } else {
1522 1489 $is_contains = $instance_value === $condition_value;
1523 1490 }
1524 1491
1525 - if (
1526 - ( $is_negative_condition && $is_contains ) ||
1527 - ( ! $is_negative_condition && ! $is_contains )
1528 - ) {
1492 + if ( $is_negative_condition && $is_contains || ! $is_negative_condition && ! $is_contains ) {
1529 1493 return false;
1530 1494 }
1531 1495 }
1532 1496
@@ -1577,12 +1541,8 @@
1577 1541 * @param array $args Section arguments.
1578 1542 */
1579 1543 do_action( "elementor/element/{$stack_name}/{$section_id}/before_section_start", $this, $args );
1580 1544
1581 - if ( $this->should_manually_trigger_common_action( $stack_name ) ) {
1582 - do_action( "elementor/element/common/{$section_id}/before_section_start", $this, $args );
1583 - }
1584 -
1585 1545 $args['type'] = Controls_Manager::SECTION;
1586 1546
1587 1547 $this->add_control( $section_id, $args );
1588 1548
@@ -1621,12 +1581,8 @@
1621 1581 * @param Controls_Stack $this The control.
1622 1582 * @param array $args Section arguments.
1623 1583 */
1624 1584 do_action( "elementor/element/{$stack_name}/{$section_id}/after_section_start", $this, $args );
1625 -
1626 - if ( $this->should_manually_trigger_common_action( $stack_name ) ) {
1627 - do_action( "elementor/element/common/{$section_id}/after_section_start", $this, $args );
1628 - }
1629 1585 }
1630 1586
1631 1587 /**
1632 1588 * End controls section.
@@ -1675,12 +1631,8 @@
1675 1631 * @param array $args Section arguments.
1676 1632 */
1677 1633 do_action( "elementor/element/{$stack_name}/{$section_id}/before_section_end", $this, $args );
1678 1634
1679 - if ( $this->should_manually_trigger_common_action( $stack_name ) ) {
1680 - do_action( "elementor/element/common/{$section_id}/before_section_end", $this, $args );
1681 - }
1682 -
1683 1635 $this->current_section = null;
1684 1636
1685 1637 /**
1686 1638 * After section end.
@@ -1707,40 +1659,11 @@
1707 1659 * @param Controls_Stack $this The control.
1708 1660 * @param array $args Section arguments.
1709 1661 */
1710 1662 do_action( "elementor/element/{$stack_name}/{$section_id}/after_section_end", $this, $args );
1711 -
1712 - if ( $this->should_manually_trigger_common_action( $stack_name ) ) {
1713 - do_action( "elementor/element/common/{$section_id}/after_section_end", $this, $args );
1714 - }
1715 1663 }
1716 1664
1717 1665 /**
1718 - * Should manually trigger common action.
1719 - *
1720 - * With the Optimized Markup experiment, the Advanced Tab has been split to maintain backward compatibility:
1721 - * - 'common' refers to the existing Advanced Tab.
1722 - * - 'common-optimized' refers to the new Advanced Tab for optimized widgets.
1723 - *
1724 - * Third-party developers may have used hooks like 'elementor/element/common/_section_background/before_section_end'
1725 - * to add controls to the Advanced Tab. However, this hook will now only work on widgets that are not optimized.
1726 - *
1727 - * This method checks whether the 'elementor/element/common/...' hooks should be manually executed
1728 - * to prevent third parties from needing to add equivalent hooks for 'elementor/element/common-optimized/...'.
1729 - *
1730 - * @todo Remove this method and the manual execution of 'common' hooks when the feature is merged.
1731 - *
1732 - * @access private
1733 - *
1734 - * @param string $stack_name Stack name.
1735 - *
1736 - * @return bool
1737 - */
1738 - private function should_manually_trigger_common_action( $stack_name ): bool {
1739 - return 'common-optimized' === $stack_name && Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
1740 - }
1741 -
1742 - /**
1743 1666 * Start controls tabs.
1744 1667 *
1745 1668 * Used to add a new set of tabs inside a section. You should use this
1746 1669 * method before adding new individual tabs using `start_controls_tab()`.
@@ -2013,10 +1936,10 @@
2013 1936 *
2014 1937 * @since 2.7.0
2015 1938 * @access public
2016 1939 *
2017 - * @param string $element The HTML element.
2018 - * @param string $key Optional. Attribute key. Default is null.
1940 + * @param string $element The HTML element.
1941 + * @param string $key Optional. Attribute key. Default is null.
2019 1942 * @param array|string $values Optional. Attribute value/s. Default is null.
2020 1943 */
2021 1944 public function remove_render_attribute( $element, $key = null, $values = null ) {
2022 1945 if ( $key && ! isset( $this->render_attributes[ $element ][ $key ] ) ) {
@@ -2073,9 +1996,9 @@
2073 1996 *
2074 1997 * @param array|string $element The element.
2075 1998 */
2076 1999 public function print_render_attribute_string( $element ) {
2077 - Utils::print_unescaped_internal_string( $this->get_render_attribute_string( $element ) );
2000 + echo $this->get_render_attribute_string( $element ); // XSS ok.
2078 2001 }
2079 2002
2080 2003 /**
2081 2004 * Print element template.
@@ -2088,9 +2011,9 @@
2088 2011 public function print_template() {
2089 2012 ob_start();
2090 2013
2091 2014 // TODO: This is for backwards compatibility starting from 2.9.0
2092 - // This `if` statement should be removed when the method is removed.
2015 + // This `if` statement should be removed when the method is removed
2093 2016 if ( $this->has_own_method( '_content_template', self::class ) ) {
2094 2017 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_content_template', '2.9.0', __CLASS__ . '::content_template()' );
2095 2018
2096 2019 $this->_content_template();
@@ -2136,9 +2059,9 @@
2136 2059 * @param array|null $controls The available controls.
2137 2060 *
2138 2061 * @return array Element data.
2139 2062 */
2140 - public static function on_import_update_dynamic_content( array $config, array $data, $controls = null ): array {
2063 + public static function on_import_update_dynamic_content( array $config, array $data, $controls = null ) : array {
2141 2064 return $config;
2142 2065 }
2143 2066
2144 2067 /**
@@ -2385,9 +2308,9 @@
2385 2308 *
2386 2309 * @param string $template_content Template content.
2387 2310 */
2388 2311 protected function print_template_content( $template_content ) {
2389 - Utils::print_unescaped_internal_string( $template_content );
2312 + echo $template_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2390 2313 }
2391 2314
2392 2315 /**
2393 2316 * Render element output in the editor.
@@ -2425,9 +2348,9 @@
2425 2348 protected function init_controls() {
2426 2349 Plugin::$instance->controls_manager->open_stack( $this );
2427 2350
2428 2351 // TODO: This is for backwards compatibility starting from 2.9.0
2429 - // This `if` statement should be removed when the method is removed.
2352 + // This `if` statement should be removed when the method is removed
2430 2353 if ( $this->has_own_method( '_register_controls', self::class ) ) {
2431 2354 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_register_controls', '3.1.0', __CLASS__ . '::register_controls()' );
2432 2355
2433 2356 $this->_register_controls();
@@ -2463,11 +2386,9 @@
2463 2386 if ( null !== $target_tab ) {
2464 2387 $args = array_replace_recursive( $target_tab, $args );
2465 2388 }
2466 2389 } elseif ( empty( $args['section'] ) && ( ! $overwrite || is_wp_error( Plugin::$instance->controls_manager->get_control_from_stack( $this->get_unique_name(), $control_id ) ) ) ) {
2467 - if ( ! Performance::should_optimize_controls() ) {
2468 - wp_die( sprintf( '%s::%s: Cannot add a control outside of a section (use `start_controls_section`).', get_called_class(), __FUNCTION__ ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2469 - }
2390 + wp_die( sprintf( '%s::%s: Cannot add a control outside of a section (use `start_controls_section`).', get_called_class(), __FUNCTION__ ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2470 2391 }
2471 2392
2472 2393 return $args;
2473 2394 }
@@ -2572,9 +2493,9 @@
2572 2493 */
2573 2494 public function __construct( array $data = [] ) {
2574 2495 if ( $data ) {
2575 2496 // TODO: This is for backwards compatibility starting from 2.9.0
2576 - // This if statement should be removed when the method is hard-deprecated.
2497 + // This if statement should be removed when the method is hard-deprecated
2577 2498 if ( $this->has_own_method( '_init', self::class ) ) {
2578 2499 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_init', '2.9.0', __CLASS__ . '::init()' );
2579 2500
2580 2501 $this->_init( $data );