PluginProbe
Elementor Website Builder – more than just a page builder / 3.20.2
Elementor Website Builder – more than just a page builder v3.20.2
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 +50 -112 4.2.43.20.2 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,9 +430,9 @@
449 430 $this->current_popover['initialized'] = true;
450 431 }
451 432 }
452 433
453 - if ( Performance::should_optimize_controls() ) {
434 + if ( $this->should_optimize_controls() ) {
454 435 $ui_controls = [
455 436 Controls_Manager::RAW_HTML,
456 437 Controls_Manager::DIVIDER,
457 438 Controls_Manager::HEADING,
@@ -477,8 +458,9 @@
477 458 $args['placeholder'],
478 459 $args['separator'],
479 460 $args['size_units'],
480 461 $args['range'],
462 + $args['render_type'],
481 463 $args['toggle'],
482 464 $args['ai'],
483 465 $args['classes'],
484 466 $args['style_transfer'],
@@ -494,8 +476,21 @@
494 476
495 477 return Plugin::$instance->controls_manager->add_control_to_stack( $this, $id, $args, $options );
496 478 }
497 479
480 + private function should_optimize_controls() {
481 + static $is_frontend = null;
482 +
483 + if ( null === $is_frontend ) {
484 + $is_frontend = (
485 + ! is_admin()
486 + && ! Plugin::$instance->preview->is_preview_mode()
487 + );
488 + }
489 +
490 + return $is_frontend;
491 + }
492 +
498 493 /**
499 494 * Remove control from stack.
500 495 *
501 496 * Unregister an existing control and remove it from the stack.
@@ -612,10 +607,10 @@
612 607
613 608 $position = array_merge( $default_position, $position );
614 609
615 610 if (
616 - ( 'control' === $position['type'] && in_array( $position['at'], [ 'start', 'end' ], true ) ) ||
617 - ( 'section' === $position['type'] && in_array( $position['at'], [ 'before', 'after' ], true ) )
611 + 'control' === $position['type'] && in_array( $position['at'], [ 'start', 'end' ], true ) ||
612 + 'section' === $position['type'] && in_array( $position['at'], [ 'before', 'after' ], true )
618 613 ) {
619 614 _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 615
621 616 return false;
@@ -637,13 +632,13 @@
637 632
638 633 $controls_keys = array_keys( $registered_controls );
639 634
640 635 while ( Controls_Manager::SECTION !== $registered_controls[ $controls_keys[ $target_section_index ] ]['type'] ) {
641 - --$target_section_index;
636 + $target_section_index--;
642 637 }
643 638
644 639 if ( 'section' === $position['type'] ) {
645 - ++$target_control_index;
640 + $target_control_index++;
646 641
647 642 if ( 'end' === $position['at'] ) {
648 643 while ( Controls_Manager::SECTION !== $registered_controls[ $controls_keys[ $target_control_index ] ]['type'] ) {
649 644 if ( ++$target_control_index >= count( $registered_controls ) ) {
@@ -655,9 +650,9 @@
655 650
656 651 $target_control = $registered_controls[ $controls_keys[ $target_control_index ] ];
657 652
658 653 if ( 'after' === $position['at'] ) {
659 - ++$target_control_index;
654 + $target_control_index++;
660 655 }
661 656
662 657 $section_id = $registered_controls[ $controls_keys[ $target_section_index ] ]['name'];
663 658
@@ -737,9 +732,9 @@
737 732
738 733 $controls_keys = array_keys( $registered_controls );
739 734
740 735 while ( true ) {
741 - ++$section_index;
736 + $section_index++;
742 737
743 738 if ( ! isset( $controls_keys[ $section_index ] ) ) {
744 739 break;
745 740 }
@@ -750,9 +745,9 @@
750 745 break;
751 746 }
752 747
753 748 $section_controls[ $control_key ] = $registered_controls[ $control_key ];
754 - }
749 + };
755 750
756 751 return $section_controls;
757 752 }
758 753
@@ -796,9 +791,9 @@
796 791 * @param array $settings Optional. Controls settings. Default is null.
797 792 *
798 793 * @return array Style controls.
799 794 */
800 - final public function get_style_controls( ?array $controls = null, ?array $settings = null ) {
795 + final public function get_style_controls( array $controls = null, array $settings = null ) {
801 796 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.0.0' );
802 797
803 798 $controls = $this->get_active_controls( $controls, $settings );
804 799
@@ -931,9 +926,9 @@
931 926 $control_args = $args;
932 927
933 928 // Set parent using the name from previous iteration.
934 929 if ( isset( $control_name ) ) {
935 - // If $control_name end with _widescreen use desktop name instead.
930 + // If $control_name end with _widescreen use desktop name instead
936 931 $control_args['parent'] = '_widescreen' === substr( $control_name, -strlen( '_widescreen' ) ) ? $id : $control_name;
937 932 } else {
938 933 $control_args['parent'] = null;
939 934 }
@@ -1060,10 +1055,10 @@
1060 1055 * @return array|null The config.
1061 1056 */
1062 1057 final public function get_config() {
1063 1058 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.
1059 + // TODO: This is for backwards compatibility starting from 2.9.0
1060 + // This if statement should be removed when the method is hard-deprecated
1066 1061 if ( $this->has_own_method( '_get_initial_config', self::class ) ) {
1067 1062 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_get_initial_config', '2.9.0', __CLASS__ . '::get_initial_config()' );
1068 1063
1069 1064 $this->config = $this->_get_initial_config();
@@ -1087,10 +1082,8 @@
1087 1082 * Set a config property.
1088 1083 *
1089 1084 * Set a specific property of the config list for this controls-stack.
1090 1085 *
1091 - * @param string $key
1092 - * @param string $value
1093 1086 * @since 3.5.0
1094 1087 * @access public
1095 1088 */
1096 1089 public function set_config( $key, $value ) {
@@ -1166,11 +1159,8 @@
1166 1159 return self::get_items( $this->data, $item );
1167 1160 }
1168 1161
1169 1162 /**
1170 - * @param null $setting
1171 - * @param null $settings
1172 - * @return array|mixed|null
1173 1163 * @since 2.0.14
1174 1164 * @access public
1175 1165 */
1176 1166 public function get_parsed_dynamic_settings( $setting = null, $settings = null ) {
@@ -1184,28 +1174,21 @@
1184 1174
1185 1175 return self::get_items( $this->parsed_dynamic_settings, $setting );
1186 1176 }
1187 1177
1188 - public function reset_render_state(): void {
1189 - $this->active_settings = null;
1190 - $this->parsed_active_settings = null;
1191 - $this->parsed_dynamic_settings = null;
1192 - $this->render_attributes = [];
1193 - }
1194 -
1195 1178 /**
1196 1179 * Get active settings.
1197 1180 *
1198 1181 * Retrieve the settings from all the active controls.
1199 1182 *
1200 - * @param array|null $settings Optional. Controls settings. Default is null.
1201 - * @param array|null $controls Optional. An array of controls. Default is null.
1202 - *
1203 - * @return array Active settings.
1183 + * @since 1.4.0
1204 1184 * @since 2.1.0 Added the `controls` and the `settings` parameters.
1205 1185 * @access public
1206 1186 *
1207 - * @since 1.4.0
1187 + * @param array $controls Optional. An array of controls. Default is null.
1188 + * @param array $settings Optional. Controls settings. Default is null.
1189 + *
1190 + * @return array Active settings.
1208 1191 */
1209 1192 public function get_active_settings( $settings = null, $controls = null ) {
1210 1193 $is_first_request = ! $settings && ! $this->active_settings;
1211 1194
@@ -1434,14 +1417,15 @@
1434 1417 * Whether the control is visible or not.
1435 1418 *
1436 1419 * Used to determine whether the control is visible or not.
1437 1420 *
1421 + * @since 1.4.0
1422 + * @access public
1423 + *
1438 1424 * @param array $control The control.
1439 - * @param null $values Optional. Condition values. Default is null.
1440 - * @param null $controls
1425 + * @param array $values Optional. Condition values. Default is null.
1426 + *
1441 1427 * @return bool Whether the control is visible.
1442 - * @since 1.4.0
1443 - * @access public
1444 1428 */
1445 1429 public function is_control_visible( $control, $values = null, $controls = null ) {
1446 1430 if ( null === $values ) {
1447 1431 $values = $this->get_settings();
@@ -1463,9 +1447,9 @@
1463 1447 preg_match( '/([a-z_\-0-9]+)(?:\[([a-z_]+)])?(!?)$/i', $condition_key, $condition_key_parts );
1464 1448
1465 1449 $pure_condition_key = $condition_key_parts[1];
1466 1450 $condition_sub_key = $condition_key_parts[2];
1467 - $is_negative_condition = (bool) $condition_key_parts[3];
1451 + $is_negative_condition = ! ! $condition_key_parts[3];
1468 1452
1469 1453 if ( ! isset( $values[ $pure_condition_key ] ) || null === $values[ $pure_condition_key ] ) {
1470 1454 return false;
1471 1455 }
@@ -1528,12 +1512,9 @@
1528 1512 } else {
1529 1513 $is_contains = $instance_value === $condition_value;
1530 1514 }
1531 1515
1532 - if (
1533 - ( $is_negative_condition && $is_contains ) ||
1534 - ( ! $is_negative_condition && ! $is_contains )
1535 - ) {
1516 + if ( $is_negative_condition && $is_contains || ! $is_negative_condition && ! $is_contains ) {
1536 1517 return false;
1537 1518 }
1538 1519 }
1539 1520
@@ -1584,12 +1565,8 @@
1584 1565 * @param array $args Section arguments.
1585 1566 */
1586 1567 do_action( "elementor/element/{$stack_name}/{$section_id}/before_section_start", $this, $args );
1587 1568
1588 - if ( $this->should_manually_trigger_common_action( $stack_name ) ) {
1589 - do_action( "elementor/element/common/{$section_id}/before_section_start", $this, $args );
1590 - }
1591 -
1592 1569 $args['type'] = Controls_Manager::SECTION;
1593 1570
1594 1571 $this->add_control( $section_id, $args );
1595 1572
@@ -1628,12 +1605,8 @@
1628 1605 * @param Controls_Stack $this The control.
1629 1606 * @param array $args Section arguments.
1630 1607 */
1631 1608 do_action( "elementor/element/{$stack_name}/{$section_id}/after_section_start", $this, $args );
1632 -
1633 - if ( $this->should_manually_trigger_common_action( $stack_name ) ) {
1634 - do_action( "elementor/element/common/{$section_id}/after_section_start", $this, $args );
1635 - }
1636 1609 }
1637 1610
1638 1611 /**
1639 1612 * End controls section.
@@ -1682,12 +1655,8 @@
1682 1655 * @param array $args Section arguments.
1683 1656 */
1684 1657 do_action( "elementor/element/{$stack_name}/{$section_id}/before_section_end", $this, $args );
1685 1658
1686 - if ( $this->should_manually_trigger_common_action( $stack_name ) ) {
1687 - do_action( "elementor/element/common/{$section_id}/before_section_end", $this, $args );
1688 - }
1689 -
1690 1659 $this->current_section = null;
1691 1660
1692 1661 /**
1693 1662 * After section end.
@@ -1714,40 +1683,11 @@
1714 1683 * @param Controls_Stack $this The control.
1715 1684 * @param array $args Section arguments.
1716 1685 */
1717 1686 do_action( "elementor/element/{$stack_name}/{$section_id}/after_section_end", $this, $args );
1718 -
1719 - if ( $this->should_manually_trigger_common_action( $stack_name ) ) {
1720 - do_action( "elementor/element/common/{$section_id}/after_section_end", $this, $args );
1721 - }
1722 1687 }
1723 1688
1724 1689 /**
1725 - * Should manually trigger common action.
1726 - *
1727 - * With the Optimized Markup experiment, the Advanced Tab has been split to maintain backward compatibility:
1728 - * - 'common' refers to the existing Advanced Tab.
1729 - * - 'common-optimized' refers to the new Advanced Tab for optimized widgets.
1730 - *
1731 - * Third-party developers may have used hooks like 'elementor/element/common/_section_background/before_section_end'
1732 - * to add controls to the Advanced Tab. However, this hook will now only work on widgets that are not optimized.
1733 - *
1734 - * This method checks whether the 'elementor/element/common/...' hooks should be manually executed
1735 - * to prevent third parties from needing to add equivalent hooks for 'elementor/element/common-optimized/...'.
1736 - *
1737 - * @todo Remove this method and the manual execution of 'common' hooks when the feature is merged.
1738 - *
1739 - * @access private
1740 - *
1741 - * @param string $stack_name Stack name.
1742 - *
1743 - * @return bool
1744 - */
1745 - private function should_manually_trigger_common_action( $stack_name ): bool {
1746 - return 'common-optimized' === $stack_name && Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
1747 - }
1748 -
1749 - /**
1750 1690 * Start controls tabs.
1751 1691 *
1752 1692 * Used to add a new set of tabs inside a section. You should use this
1753 1693 * method before adding new individual tabs using `start_controls_tab()`.
@@ -2020,10 +1960,10 @@
2020 1960 *
2021 1961 * @since 2.7.0
2022 1962 * @access public
2023 1963 *
2024 - * @param string $element The HTML element.
2025 - * @param string $key Optional. Attribute key. Default is null.
1964 + * @param string $element The HTML element.
1965 + * @param string $key Optional. Attribute key. Default is null.
2026 1966 * @param array|string $values Optional. Attribute value/s. Default is null.
2027 1967 */
2028 1968 public function remove_render_attribute( $element, $key = null, $values = null ) {
2029 1969 if ( $key && ! isset( $this->render_attributes[ $element ][ $key ] ) ) {
@@ -2080,9 +2020,9 @@
2080 2020 *
2081 2021 * @param array|string $element The element.
2082 2022 */
2083 2023 public function print_render_attribute_string( $element ) {
2084 - Utils::print_unescaped_internal_string( $this->get_render_attribute_string( $element ) );
2024 + echo $this->get_render_attribute_string( $element ); // XSS ok.
2085 2025 }
2086 2026
2087 2027 /**
2088 2028 * Print element template.
@@ -2095,9 +2035,9 @@
2095 2035 public function print_template() {
2096 2036 ob_start();
2097 2037
2098 2038 // TODO: This is for backwards compatibility starting from 2.9.0
2099 - // This `if` statement should be removed when the method is removed.
2039 + // This `if` statement should be removed when the method is removed
2100 2040 if ( $this->has_own_method( '_content_template', self::class ) ) {
2101 2041 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_content_template', '2.9.0', __CLASS__ . '::content_template()' );
2102 2042
2103 2043 $this->_content_template();
@@ -2143,9 +2083,9 @@
2143 2083 * @param array|null $controls The available controls.
2144 2084 *
2145 2085 * @return array Element data.
2146 2086 */
2147 - public static function on_import_update_dynamic_content( array $config, array $data, $controls = null ): array {
2087 + public static function on_import_update_dynamic_content( array $config, array $data, $controls = null ) : array {
2148 2088 return $config;
2149 2089 }
2150 2090
2151 2091 /**
@@ -2392,9 +2332,9 @@
2392 2332 *
2393 2333 * @param string $template_content Template content.
2394 2334 */
2395 2335 protected function print_template_content( $template_content ) {
2396 - Utils::print_unescaped_internal_string( $template_content );
2336 + echo $template_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2397 2337 }
2398 2338
2399 2339 /**
2400 2340 * Render element output in the editor.
@@ -2432,9 +2372,9 @@
2432 2372 protected function init_controls() {
2433 2373 Plugin::$instance->controls_manager->open_stack( $this );
2434 2374
2435 2375 // TODO: This is for backwards compatibility starting from 2.9.0
2436 - // This `if` statement should be removed when the method is removed.
2376 + // This `if` statement should be removed when the method is removed
2437 2377 if ( $this->has_own_method( '_register_controls', self::class ) ) {
2438 2378 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_register_controls', '3.1.0', __CLASS__ . '::register_controls()' );
2439 2379
2440 2380 $this->_register_controls();
@@ -2470,11 +2410,9 @@
2470 2410 if ( null !== $target_tab ) {
2471 2411 $args = array_replace_recursive( $target_tab, $args );
2472 2412 }
2473 2413 } elseif ( empty( $args['section'] ) && ( ! $overwrite || is_wp_error( Plugin::$instance->controls_manager->get_control_from_stack( $this->get_unique_name(), $control_id ) ) ) ) {
2474 - if ( ! Performance::should_optimize_controls() ) {
2475 - 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
2476 - }
2414 + 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
2477 2415 }
2478 2416
2479 2417 return $args;
2480 2418 }
@@ -2579,9 +2517,9 @@
2579 2517 */
2580 2518 public function __construct( array $data = [] ) {
2581 2519 if ( $data ) {
2582 2520 // TODO: This is for backwards compatibility starting from 2.9.0
2583 - // This if statement should be removed when the method is hard-deprecated.
2521 + // This if statement should be removed when the method is hard-deprecated
2584 2522 if ( $this->has_own_method( '_init', self::class ) ) {
2585 2523 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_init', '2.9.0', __CLASS__ . '::init()' );
2586 2524
2587 2525 $this->_init( $data );