PluginProbe
Elementor Website Builder – more than just a page builder / 3.4.1
Elementor Website Builder – more than just a page builder v3.4.1
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 +94 -333 4.2.43.4.1 View file →
@@ -2,11 +2,10 @@
2 2 namespace Elementor;
3 3
4 4 use Elementor\Core\Base\Base_Object;
5 5 use Elementor\Core\DynamicTags\Manager;
6 +use Elementor\Core\Schemes\Manager as Schemes_Manager;
6 7 use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
7 -use Elementor\Core\Frontend\Performance;
8 -use Elementor\Utils;
9 8
10 9 if ( ! defined( 'ABSPATH' ) ) {
11 10 exit; // Exit if accessed directly.
12 11 }
@@ -91,22 +90,8 @@
91 90 */
92 91 private $config;
93 92
94 93 /**
95 - * The additional configuration.
96 - *
97 - * Holds additional configuration that has been set using `set_config` method.
98 - * The `config` property is not modified directly while using the method because
99 - * it's used to check whether the initial config already loaded (in `get_config`).
100 - * After the initial config loaded, the additional config is merged into it.
101 - *
102 - * @access private
103 - *
104 - * @var null|array
105 - */
106 - private $additional_config = [];
107 -
108 - /**
109 94 * Current section.
110 95 *
111 96 * Holds the current section while inserting a set of controls sections.
112 97 *
@@ -226,26 +211,12 @@
226 211 public function get_id_int() {
227 212 /** We ignore possible notices, in order to support elements created prior to v1.8.0 and might include
228 213 * non-base 16 characters as part of their ID.
229 214 */
230 - return @hexdec( (string) $this->id );
215 + return @hexdec( $this->id );
231 216 }
232 217
233 218 /**
234 - * Get widget number.
235 - *
236 - * Get the first three numbers of the element converted ID.
237 - *
238 - * @since 3.16
239 - * @access public
240 - *
241 - * @return string The widget number.
242 - */
243 - public function get_widget_number(): string {
244 - return substr( $this->get_id_int(), 0, 3 );
245 - }
246 -
247 - /**
248 219 * Get the type.
249 220 *
250 221 * Retrieve the type, e.g. 'stack', 'section', 'widget' etc.
251 222 *
@@ -311,26 +282,9 @@
311 282 *
312 283 * @return mixed Controls list.
313 284 */
314 285 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 );
286 + return self::get_items( $this->get_stack()['controls'], $control_id );
333 287 }
334 288
335 289 /**
336 290 * Get active controls.
@@ -349,10 +303,10 @@
349 303 * @param array $settings Optional. Controls settings. Default is null.
350 304 *
351 305 * @return array Active controls.
352 306 */
353 - public function get_active_controls( ?array $controls = null, ?array $settings = null ) {
354 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.0.0' );
307 + public function get_active_controls( array $controls = null, array $settings = null ) {
308 + // _deprecated_function( __METHOD__, '3.0.0' );
355 309
356 310 if ( ! $controls ) {
357 311 $controls = $this->get_controls();
358 312 }
@@ -364,9 +318,9 @@
364 318 $active_controls = array_reduce(
365 319 array_keys( $controls ), function( $active_controls, $control_key ) use ( $controls, $settings ) {
366 320 $control = $controls[ $control_key ];
367 321
368 - if ( $this->is_control_visible( $control, $settings, $controls ) ) {
322 + if ( $this->is_control_visible( $control, $settings ) ) {
369 323 $active_controls[ $control_key ] = $control;
370 324 }
371 325
372 326 return $active_controls;
@@ -439,58 +393,14 @@
439 393 }
440 394
441 395 unset( $options['position'] );
442 396
443 - if ( $this->current_popover ) {
444 - $args['popover'] = [];
445 -
446 - if ( ! $this->current_popover['initialized'] ) {
447 - $args['popover']['start'] = true;
448 -
449 - $this->current_popover['initialized'] = true;
450 - }
451 - }
452 -
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,
397 + if ( $this->current_popover && ! $this->current_popover['initialized'] ) {
398 + $args['popover'] = [
399 + 'start' => true,
462 400 ];
463 401
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 -
471 - unset(
472 - $args['label_block'],
473 - $args['label'],
474 - $args['title'],
475 - $args['tab'],
476 - $args['options'],
477 - $args['placeholder'],
478 - $args['separator'],
479 - $args['size_units'],
480 - $args['range'],
481 - $args['toggle'],
482 - $args['ai'],
483 - $args['classes'],
484 - $args['style_transfer'],
485 - $args['show_label'],
486 - $args['description'],
487 - $args['label_on'],
488 - $args['label_off'],
489 - $args['labels'],
490 - $args['handles'],
491 - $args['editor_available'],
492 - );
402 + $this->current_popover['initialized'] = true;
493 403 }
494 404
495 405 return Plugin::$instance->controls_manager->add_control_to_stack( $this, $id, $args, $options );
496 406 }
@@ -612,10 +522,10 @@
612 522
613 523 $position = array_merge( $default_position, $position );
614 524
615 525 if (
616 - ( 'control' === $position['type'] && in_array( $position['at'], [ 'start', 'end' ], true ) ) ||
617 - ( 'section' === $position['type'] && in_array( $position['at'], [ 'before', 'after' ], true ) )
526 + 'control' === $position['type'] && in_array( $position['at'], [ 'start', 'end' ], true ) ||
527 + 'section' === $position['type'] && in_array( $position['at'], [ 'before', 'after' ], true )
618 528 ) {
619 529 _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 530
621 531 return false;
@@ -637,13 +547,13 @@
637 547
638 548 $controls_keys = array_keys( $registered_controls );
639 549
640 550 while ( Controls_Manager::SECTION !== $registered_controls[ $controls_keys[ $target_section_index ] ]['type'] ) {
641 - --$target_section_index;
551 + $target_section_index--;
642 552 }
643 553
644 554 if ( 'section' === $position['type'] ) {
645 - ++$target_control_index;
555 + $target_control_index++;
646 556
647 557 if ( 'end' === $position['at'] ) {
648 558 while ( Controls_Manager::SECTION !== $registered_controls[ $controls_keys[ $target_control_index ] ]['type'] ) {
649 559 if ( ++$target_control_index >= count( $registered_controls ) ) {
@@ -655,9 +565,9 @@
655 565
656 566 $target_control = $registered_controls[ $controls_keys[ $target_control_index ] ];
657 567
658 568 if ( 'after' === $position['at'] ) {
659 - ++$target_control_index;
569 + $target_control_index++;
660 570 }
661 571
662 572 $section_id = $registered_controls[ $controls_keys[ $target_section_index ] ]['name'];
663 573
@@ -737,9 +647,9 @@
737 647
738 648 $controls_keys = array_keys( $registered_controls );
739 649
740 650 while ( true ) {
741 - ++$section_index;
651 + $section_index++;
742 652
743 653 if ( ! isset( $controls_keys[ $section_index ] ) ) {
744 654 break;
745 655 }
@@ -750,9 +660,9 @@
750 660 break;
751 661 }
752 662
753 663 $section_controls[ $control_key ] = $registered_controls[ $control_key ];
754 - }
664 + };
755 665
756 666 return $section_controls;
757 667 }
758 668
@@ -781,8 +691,30 @@
781 691 $group->add_controls( $this, $args, $options );
782 692 }
783 693
784 694 /**
695 + * Get scheme controls.
696 + *
697 + * Retrieve all the controls that use schemes.
698 + *
699 + * @since 1.4.0
700 + * @access public
701 + * @deprecated 3.0.0
702 + *
703 + * @return array Scheme controls.
704 + */
705 + final public function get_scheme_controls() {
706 + // _deprecated_function( __METHOD__, '3.0.0' );
707 + $enabled_schemes = Schemes_Manager::get_enabled_schemes();
708 +
709 + return array_filter(
710 + $this->get_controls(), function( $control ) use ( $enabled_schemes ) {
711 + return ( ! empty( $control['scheme'] ) && in_array( $control['scheme']['type'], $enabled_schemes ) );
712 + }
713 + );
714 + }
715 +
716 + /**
785 717 * Get style controls.
786 718 *
787 719 * Retrieve style controls for all active controls or, when requested, from
788 720 * a specific set of controls.
@@ -796,10 +728,10 @@
796 728 * @param array $settings Optional. Controls settings. Default is null.
797 729 *
798 730 * @return array Style controls.
799 731 */
800 - final public function get_style_controls( ?array $controls = null, ?array $settings = null ) {
801 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.0.0' );
732 + final public function get_style_controls( array $controls = null, array $settings = null ) {
733 + // _deprecated_function( __METHOD__, '3.0.0' );
802 734
803 735 $controls = $this->get_active_controls( $controls, $settings );
804 736
805 737 $style_controls = [];
@@ -869,12 +801,9 @@
869 801 $args['responsive'] = [];
870 802
871 803 $active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
872 804
873 - $devices = Plugin::$instance->breakpoints->get_active_devices_list( [
874 - 'reverse' => true,
875 - 'desktop_first' => true,
876 - ] );
805 + $devices = Plugin::$instance->breakpoints->get_active_devices_list( [ 'reverse' => true ] );
877 806
878 807 if ( isset( $args['devices'] ) ) {
879 808 $devices = array_intersect( $devices, $args['devices'] );
880 809
@@ -882,23 +811,13 @@
882 811
883 812 unset( $args['devices'] );
884 813 }
885 814
886 - $control_to_check = $args;
887 -
888 - if ( ! empty( $options['overwrite'] ) ) {
889 - $existing_control = Plugin::$instance->controls_manager->get_control_from_stack( $this->get_unique_name(), $id );
890 -
891 - if ( ! is_wp_error( $existing_control ) ) {
892 - $control_to_check = $existing_control;
893 - }
894 - }
895 -
896 815 $responsive_duplication_mode = Plugin::$instance->breakpoints->get_responsive_control_duplication_mode();
897 816 $additional_breakpoints_active = Plugin::$instance->experiments->is_feature_active( 'additional_custom_breakpoints' );
898 - $control_is_dynamic = ! empty( $control_to_check['dynamic']['active'] );
899 - $is_frontend_available = ! empty( $control_to_check['frontend_available'] );
900 - $has_prefix_class = ! empty( $control_to_check['prefix_class'] );
817 + $control_is_dynamic = ! empty( $args['dynamic']['active'] );
818 + $is_frontend_available = ! empty( $args['frontend_available'] );
819 + $has_prefix_class = ! empty( $args['prefix_class'] );
901 820
902 821 // If the new responsive controls experiment is active, create only one control - duplicates per device will
903 822 // be created in JS in the Editor.
904 823 if (
@@ -930,14 +849,9 @@
930 849 foreach ( $devices as $device_name ) {
931 850 $control_args = $args;
932 851
933 852 // Set parent using the name from previous iteration.
934 - if ( isset( $control_name ) ) {
935 - // If $control_name end with _widescreen use desktop name instead.
936 - $control_args['parent'] = '_widescreen' === substr( $control_name, -strlen( '_widescreen' ) ) ? $id : $control_name;
937 - } else {
938 - $control_args['parent'] = null;
939 - }
853 + $control_args['parent'] = isset( $control_name ) ? $control_name : null;
940 854
941 855 if ( isset( $control_args['device_args'] ) ) {
942 856 if ( ! empty( $control_args['device_args'][ $device_name ] ) ) {
943 857 $control_args = array_merge( $control_args, $control_args['device_args'][ $device_name ] );
@@ -979,11 +893,9 @@
979 893 $id_suffix = Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP === $device_name ? '' : '_' . $device_name;
980 894 $control_name = $id . $id_suffix;
981 895
982 896 // Set this control as child of previous iteration control.
983 - if ( ! empty( $control_args['parent'] ) ) {
984 - $this->update_control( $control_args['parent'], [ 'inheritors' => [ $control_name ] ] );
985 - }
897 + $this->update_control( $control_args['parent'], [ 'inheritors' => [ $control_name ] ] );
986 898
987 899 if ( ! empty( $options['overwrite'] ) ) {
988 900 $this->update_control( $control_name, $control_args, [
989 901 'recursive' => ! empty( $options['recursive'] ),
@@ -1025,9 +937,13 @@
1025 937 *
1026 938 * @param string $id Responsive control ID.
1027 939 */
1028 940 final public function remove_responsive_control( $id ) {
1029 - $devices = Plugin::$instance->breakpoints->get_active_devices_list( [ 'reverse' => true ] );
941 + $devices = [
942 + Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP,
943 + Breakpoints_Manager::BREAKPOINT_KEY_TABLET,
944 + Breakpoints_Manager::BREAKPOINT_KEY_MOBILE,
945 + ];
1030 946
1031 947 foreach ( $devices as $device_name ) {
1032 948 $id_suffix = Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP === $device_name ? '' : '_' . $device_name;
1033 949
@@ -1060,10 +976,10 @@
1060 976 * @return array|null The config.
1061 977 */
1062 978 final public function get_config() {
1063 979 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.
980 + // TODO: This is for backwards compatibility starting from 2.9.0
981 + // This if statement should be removed when the method is hard-deprecated
1066 982 if ( $this->has_own_method( '_get_initial_config', self::class ) ) {
1067 983 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_get_initial_config', '2.9.0', __CLASS__ . '::get_initial_config()' );
1068 984
1069 985 $this->config = $this->_get_initial_config();
@@ -1069,16 +985,8 @@
1069 985 $this->config = $this->_get_initial_config();
1070 986 } else {
1071 987 $this->config = $this->get_initial_config();
1072 988 }
1073 -
1074 - foreach ( $this->additional_config as $key => $value ) {
1075 - if ( isset( $this->config[ $key ] ) ) {
1076 - $this->config[ $key ] = wp_parse_args( $value, $this->config[ $key ] );
1077 - } else {
1078 - $this->config[ $key ] = $value;
1079 - }
1080 - }
1081 989 }
1082 990
1083 991 return $this->config;
1084 992 }
@@ -1083,26 +991,8 @@
1083 991 return $this->config;
1084 992 }
1085 993
1086 994 /**
1087 - * Set a config property.
1088 - *
1089 - * Set a specific property of the config list for this controls-stack.
1090 - *
1091 - * @param string $key
1092 - * @param string $value
1093 - * @since 3.5.0
1094 - * @access public
1095 - */
1096 - public function set_config( $key, $value ) {
1097 - if ( isset( $this->additional_config[ $key ] ) ) {
1098 - $this->additional_config[ $key ] = wp_parse_args( $value, $this->additional_config[ $key ] );
1099 - } else {
1100 - $this->additional_config[ $key ] = $value;
1101 - }
1102 - }
1103 -
1104 - /**
1105 995 * Get frontend settings keys.
1106 996 *
1107 997 * Retrieve settings keys for all frontend controls.
1108 998 *
@@ -1166,11 +1056,8 @@
1166 1056 return self::get_items( $this->data, $item );
1167 1057 }
1168 1058
1169 1059 /**
1170 - * @param null $setting
1171 - * @param null $settings
1172 - * @return array|mixed|null
1173 1060 * @since 2.0.14
1174 1061 * @access public
1175 1062 */
1176 1063 public function get_parsed_dynamic_settings( $setting = null, $settings = null ) {
@@ -1184,28 +1071,21 @@
1184 1071
1185 1072 return self::get_items( $this->parsed_dynamic_settings, $setting );
1186 1073 }
1187 1074
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 1075 /**
1196 1076 * Get active settings.
1197 1077 *
1198 1078 * Retrieve the settings from all the active controls.
1199 1079 *
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.
1080 + * @since 1.4.0
1204 1081 * @since 2.1.0 Added the `controls` and the `settings` parameters.
1205 1082 * @access public
1206 1083 *
1207 - * @since 1.4.0
1084 + * @param array $controls Optional. An array of controls. Default is null.
1085 + * @param array $settings Optional. Controls settings. Default is null.
1086 + *
1087 + * @return array Active settings.
1208 1088 */
1209 1089 public function get_active_settings( $settings = null, $controls = null ) {
1210 1090 $is_first_request = ! $settings && ! $this->active_settings;
1211 1091
@@ -1220,10 +1100,8 @@
1220 1100 }
1221 1101
1222 1102 $active_settings = [];
1223 1103
1224 - $controls_objs = Plugin::$instance->controls_manager->get_controls();
1225 -
1226 1104 foreach ( $settings as $setting_key => $setting ) {
1227 1105 if ( ! isset( $controls[ $setting_key ] ) ) {
1228 1106 $active_settings[ $setting_key ] = $setting;
1229 1107
@@ -1231,10 +1109,10 @@
1231 1109 }
1232 1110
1233 1111 $control = $controls[ $setting_key ];
1234 1112
1235 - if ( $this->is_control_visible( $control, $settings, $controls ) ) {
1236 - $control_obj = $controls_objs[ $control['type'] ] ?? null;
1113 + if ( $this->is_control_visible( $control, $settings ) ) {
1114 + $control_obj = Plugin::$instance->controls_manager->get_control( $control['type'] );
1237 1115
1238 1116 if ( $control_obj instanceof Control_Repeater ) {
1239 1117 foreach ( $setting as & $item ) {
1240 1118 $item = $this->get_active_settings( $item, $control['fields'] );
@@ -1301,13 +1179,11 @@
1301 1179 if ( null === $controls ) {
1302 1180 $controls = $this->get_controls();
1303 1181 }
1304 1182
1305 - $controls_objs = Plugin::$instance->controls_manager->get_controls();
1306 -
1307 1183 foreach ( $controls as $control ) {
1308 1184 $control_name = $control['name'];
1309 - $control_obj = $controls_objs[ $control['type'] ] ?? null;
1185 + $control_obj = Plugin::$instance->controls_manager->get_control( $control['type'] );
1310 1186
1311 1187 if ( ! $control_obj instanceof Base_Data_Control ) {
1312 1188 continue;
1313 1189 }
@@ -1417,33 +1293,21 @@
1417 1293 );
1418 1294 }
1419 1295
1420 1296 /**
1421 - * Get Responsive Control Device Suffix
1422 - *
1423 - * @deprecated 3.7.6 Use `Elementor\Controls_Manager::get_responsive_control_device_suffix()` instead.
1424 - * @param array $control
1425 - * @return string $device suffix
1426 - */
1427 - protected function get_responsive_control_device_suffix( $control ) {
1428 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.7.6', 'Elementor\Controls_Manager::get_responsive_control_device_suffix()' );
1429 -
1430 - return Controls_Manager::get_responsive_control_device_suffix( $control );
1431 - }
1432 -
1433 - /**
1434 1297 * Whether the control is visible or not.
1435 1298 *
1436 1299 * Used to determine whether the control is visible or not.
1437 1300 *
1301 + * @since 1.4.0
1302 + * @access public
1303 + *
1438 1304 * @param array $control The control.
1439 - * @param null $values Optional. Condition values. Default is null.
1440 - * @param null $controls
1305 + * @param array $values Optional. Condition values. Default is null.
1306 + *
1441 1307 * @return bool Whether the control is visible.
1442 - * @since 1.4.0
1443 - * @access public
1444 1308 */
1445 - public function is_control_visible( $control, $values = null, $controls = null ) {
1309 + public function is_control_visible( $control, $values = null ) {
1446 1310 if ( null === $values ) {
1447 1311 $values = $this->get_settings();
1448 1312 }
1449 1313
@@ -1454,37 +1318,21 @@
1454 1318 if ( empty( $control['condition'] ) ) {
1455 1319 return true;
1456 1320 }
1457 1321
1458 - if ( ! $controls ) {
1459 - $controls = $this->get_controls();
1460 - }
1461 -
1462 1322 foreach ( $control['condition'] as $condition_key => $condition_value ) {
1463 1323 preg_match( '/([a-z_\-0-9]+)(?:\[([a-z_]+)])?(!?)$/i', $condition_key, $condition_key_parts );
1464 1324
1465 1325 $pure_condition_key = $condition_key_parts[1];
1466 1326 $condition_sub_key = $condition_key_parts[2];
1467 - $is_negative_condition = (bool) $condition_key_parts[3];
1327 + $is_negative_condition = ! ! $condition_key_parts[3];
1468 1328
1469 1329 if ( ! isset( $values[ $pure_condition_key ] ) || null === $values[ $pure_condition_key ] ) {
1470 1330 return false;
1471 1331 }
1472 1332
1473 - $are_control_and_condition_responsive = isset( $control['responsive'] ) && ! empty( $controls[ $pure_condition_key ]['responsive'] );
1474 - $condition_name_to_check = $pure_condition_key;
1333 + $instance_value = $values[ $pure_condition_key ];
1475 1334
1476 - if ( $are_control_and_condition_responsive ) {
1477 - $device_suffix = Controls_Manager::get_responsive_control_device_suffix( $control );
1478 -
1479 - $condition_name_to_check = $pure_condition_key . $device_suffix;
1480 -
1481 - // If the control is not desktop, and a conditioning control for the corresponding device exists, use it.
1482 - $instance_value = $values[ $pure_condition_key . $device_suffix ] ?? $values[ $pure_condition_key ];
1483 - } else {
1484 - $instance_value = $values[ $pure_condition_key ];
1485 - }
1486 -
1487 1335 if ( $condition_sub_key && is_array( $instance_value ) ) {
1488 1336 if ( ! isset( $instance_value[ $condition_sub_key ] ) ) {
1489 1337 return false;
1490 1338 }
@@ -1491,32 +1339,8 @@
1491 1339
1492 1340 $instance_value = $instance_value[ $condition_sub_key ];
1493 1341 }
1494 1342
1495 - if ( ! $instance_value ) {
1496 - $parent = isset( $controls[ $condition_name_to_check ]['parent'] ) ? $controls[ $condition_name_to_check ]['parent'] : false;
1497 -
1498 - while ( $parent ) {
1499 - $instance_value = $values[ $parent ];
1500 -
1501 - if ( $instance_value ) {
1502 - if ( ! is_array( $instance_value ) ) {
1503 - break;
1504 - }
1505 -
1506 - if ( $condition_sub_key && isset( $instance_value[ $condition_sub_key ] ) ) {
1507 - $instance_value = $instance_value[ $condition_sub_key ];
1508 -
1509 - if ( '' !== $instance_value ) {
1510 - break;
1511 - }
1512 - }
1513 - }
1514 -
1515 - $parent = isset( $controls[ $parent ]['parent'] ) ? $controls[ $parent ]['parent'] : false;
1516 - }
1517 - }
1518 -
1519 1343 /**
1520 1344 * If the $condition_value is a non empty array - check if the $condition_value contains the $instance_value,
1521 1345 * If the $instance_value is a non empty array - check if the $instance_value contains the $condition_value
1522 1346 * otherwise check if they are equal. ( and give the ability to check if the value is an empty array )
@@ -1528,12 +1352,9 @@
1528 1352 } else {
1529 1353 $is_contains = $instance_value === $condition_value;
1530 1354 }
1531 1355
1532 - if (
1533 - ( $is_negative_condition && $is_contains ) ||
1534 - ( ! $is_negative_condition && ! $is_contains )
1535 - ) {
1356 + if ( $is_negative_condition && $is_contains || ! $is_negative_condition && ! $is_contains ) {
1536 1357 return false;
1537 1358 }
1538 1359 }
1539 1360
@@ -1555,9 +1376,9 @@
1555 1376 * @param string $section_id Section ID.
1556 1377 * @param array $args Section arguments Optional.
1557 1378 */
1558 1379 public function start_controls_section( $section_id, array $args = [] ) {
1559 - $stack_name = $this->get_name();
1380 + $section_name = $this->get_name();
1560 1381
1561 1382 /**
1562 1383 * Before section start.
1563 1384 *
@@ -1575,9 +1396,9 @@
1575 1396 * Before section start.
1576 1397 *
1577 1398 * Fires before Elementor section starts in the editor panel.
1578 1399 *
1579 - * The dynamic portions of the hook name, `$stack_name` and `$section_id`, refers to the stack name and section ID, respectively.
1400 + * The dynamic portions of the hook name, `$section_name` and `$section_id`, refers to the section name and section ID, respectively.
1580 1401 *
1581 1402 * @since 1.4.0
1582 1403 *
1583 1404 * @param Controls_Stack $this The control.
@@ -1582,14 +1403,10 @@
1582 1403 *
1583 1404 * @param Controls_Stack $this The control.
1584 1405 * @param array $args Section arguments.
1585 1406 */
1586 - do_action( "elementor/element/{$stack_name}/{$section_id}/before_section_start", $this, $args );
1407 + do_action( "elementor/element/{$section_name}/{$section_id}/before_section_start", $this, $args );
1587 1408
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 1409 $args['type'] = Controls_Manager::SECTION;
1593 1410
1594 1411 $this->add_control( $section_id, $args );
1595 1412
@@ -1620,9 +1437,9 @@
1620 1437 * After section start.
1621 1438 *
1622 1439 * Fires after Elementor section starts in the editor panel.
1623 1440 *
1624 - * The dynamic portions of the hook name, `$stack_name` and `$section_id`, refers to the stack name and section ID, respectively.
1441 + * The dynamic portions of the hook name, `$section_name` and `$section_id`, refers to the section name and section ID, respectively.
1625 1442 *
1626 1443 * @since 1.4.0
1627 1444 *
1628 1445 * @param Controls_Stack $this The control.
@@ -1627,13 +1444,9 @@
1627 1444 *
1628 1445 * @param Controls_Stack $this The control.
1629 1446 * @param array $args Section arguments.
1630 1447 */
1631 - 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 - }
1448 + do_action( "elementor/element/{$section_name}/{$section_id}/after_section_start", $this, $args );
1636 1449 }
1637 1450
1638 1451 /**
1639 1452 * End controls section.
@@ -1682,12 +1495,8 @@
1682 1495 * @param array $args Section arguments.
1683 1496 */
1684 1497 do_action( "elementor/element/{$stack_name}/{$section_id}/before_section_end", $this, $args );
1685 1498
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 1499 $this->current_section = null;
1691 1500
1692 1501 /**
1693 1502 * After section end.
@@ -1706,9 +1515,9 @@
1706 1515 * After section end.
1707 1516 *
1708 1517 * Fires after Elementor section ends in the editor panel.
1709 1518 *
1710 - * The dynamic portions of the hook name, `$stack_name` and `$section_id`, refers to the stack name and section ID, respectively.
1519 + * The dynamic portions of the hook name, `$stack_name` and `$section_id`, refers to the section name and section ID, respectively.
1711 1520 *
1712 1521 * @since 1.4.0
1713 1522 *
1714 1523 * @param Controls_Stack $this The control.
@@ -1714,40 +1523,11 @@
1714 1523 * @param Controls_Stack $this The control.
1715 1524 * @param array $args Section arguments.
1716 1525 */
1717 1526 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 1527 }
1723 1528
1724 1529 /**
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 1530 * Start controls tabs.
1751 1531 *
1752 1532 * Used to add a new set of tabs inside a section. You should use this
1753 1533 * method before adding new individual tabs using `start_controls_tab()`.
@@ -2020,10 +1800,10 @@
2020 1800 *
2021 1801 * @since 2.7.0
2022 1802 * @access public
2023 1803 *
2024 - * @param string $element The HTML element.
2025 - * @param string $key Optional. Attribute key. Default is null.
1804 + * @param string $element The HTML element.
1805 + * @param string $key Optional. Attribute key. Default is null.
2026 1806 * @param array|string $values Optional. Attribute value/s. Default is null.
2027 1807 */
2028 1808 public function remove_render_attribute( $element, $key = null, $values = null ) {
2029 1809 if ( $key && ! isset( $this->render_attributes[ $element ][ $key ] ) ) {
@@ -2080,9 +1860,9 @@
2080 1860 *
2081 1861 * @param array|string $element The element.
2082 1862 */
2083 1863 public function print_render_attribute_string( $element ) {
2084 - Utils::print_unescaped_internal_string( $this->get_render_attribute_string( $element ) );
1864 + echo $this->get_render_attribute_string( $element ); // XSS ok.
2085 1865 }
2086 1866
2087 1867 /**
2088 1868 * Print element template.
@@ -2095,9 +1875,9 @@
2095 1875 public function print_template() {
2096 1876 ob_start();
2097 1877
2098 1878 // TODO: This is for backwards compatibility starting from 2.9.0
2099 - // This `if` statement should be removed when the method is removed.
1879 + // This `if` statement should be removed when the method is removed
2100 1880 if ( $this->has_own_method( '_content_template', self::class ) ) {
2101 1881 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_content_template', '2.9.0', __CLASS__ . '::content_template()' );
2102 1882
2103 1883 $this->_content_template();
@@ -2133,23 +1913,8 @@
2133 1913 <?php
2134 1914 }
2135 1915
2136 1916 /**
2137 - * On import update dynamic content (e.g. post and term IDs).
2138 - *
2139 - * @since 3.8.0
2140 - *
2141 - * @param array $config The config of the passed element.
2142 - * @param array $data The data that requires updating/replacement when imported.
2143 - * @param array|null $controls The available controls.
2144 - *
2145 - * @return array Element data.
2146 - */
2147 - public static function on_import_update_dynamic_content( array $config, array $data, $controls = null ): array {
2148 - return $config;
2149 - }
2150 -
2151 - /**
2152 1917 * Start injection.
2153 1918 *
2154 1919 * Used to inject controls and sections to a specific position in the stack.
2155 1920 *
@@ -2224,12 +1989,12 @@
2224 1989 * `start_controls_tab()`.
2225 1990 *
2226 1991 * @since 1.4.0
2227 1992 * @access protected
2228 - * @deprecated 3.1.0 Use `register_controls()` method instead.
1993 + * @deprecated 3.1.0 Use `Controls_Stack::register_controls()` instead
2229 1994 */
2230 1995 protected function _register_controls() {
2231 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0', 'register_controls()' );
1996 + Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0', __CLASS__ . '::register_controls()' );
2232 1997
2233 1998 $this->register_controls();
2234 1999 }
2235 2000
@@ -2272,12 +2037,10 @@
2272 2037 */
2273 2038 protected function get_init_settings() {
2274 2039 $settings = $this->get_data( 'settings' );
2275 2040
2276 - $controls_objs = Plugin::$instance->controls_manager->get_controls();
2277 -
2278 2041 foreach ( $this->get_controls() as $control ) {
2279 - $control_obj = $controls_objs[ $control['type'] ] ?? null;
2042 + $control_obj = Plugin::$instance->controls_manager->get_control( $control['type'] );
2280 2043
2281 2044 if ( ! $control_obj instanceof Base_Data_Control ) {
2282 2045 continue;
2283 2046 }
@@ -2313,15 +2076,15 @@
2313 2076 * Retrieve the current element initial configuration - controls list and
2314 2077 * the tabs assigned to the control.
2315 2078 *
2316 2079 * @since 1.4.0
2317 - * @deprecated 2.9.0 Use `get_initial_config()` method instead.
2080 + * @deprecated 2.9.0 use `get_initial_config()` instead
2318 2081 * @access protected
2319 2082 *
2320 2083 * @return array The initial config.
2321 2084 */
2322 2085 protected function _get_initial_config() {
2323 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '2.9.0', 'get_initial_config()' );
2086 + Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '2.9.0', __CLASS__ . '::get_initial_config()' );
2324 2087
2325 2088 return $this->get_initial_config();
2326 2089 }
2327 2090
@@ -2392,9 +2155,9 @@
2392 2155 *
2393 2156 * @param string $template_content Template content.
2394 2157 */
2395 2158 protected function print_template_content( $template_content ) {
2396 - Utils::print_unescaped_internal_string( $template_content );
2159 + echo $template_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2397 2160 }
2398 2161
2399 2162 /**
2400 2163 * Render element output in the editor.
@@ -2411,13 +2174,13 @@
2411 2174 *
2412 2175 * Used to generate the live preview, using a Backbone JavaScript template.
2413 2176 *
2414 2177 * @since 2.0.0
2415 - * @deprecated 2.9.0 Use `content_template()` method instead.
2178 + * @deprecated 2.9.0 use `content_template()` instead
2416 2179 * @access protected
2417 2180 */
2418 2181 protected function _content_template() {
2419 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '2.9.0', 'content_template()' );
2182 + Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '2.9.0', __CLASS__ . '::content_template()' );
2420 2183
2421 2184 $this->content_template();
2422 2185 }
2423 2186
@@ -2432,9 +2195,9 @@
2432 2195 protected function init_controls() {
2433 2196 Plugin::$instance->controls_manager->open_stack( $this );
2434 2197
2435 2198 // TODO: This is for backwards compatibility starting from 2.9.0
2436 - // This `if` statement should be removed when the method is removed.
2199 + // This `if` statement should be removed when the method is removed
2437 2200 if ( $this->has_own_method( '_register_controls', self::class ) ) {
2438 2201 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_register_controls', '3.1.0', __CLASS__ . '::register_controls()' );
2439 2202
2440 2203 $this->_register_controls();
@@ -2470,11 +2233,9 @@
2470 2233 if ( null !== $target_tab ) {
2471 2234 $args = array_replace_recursive( $target_tab, $args );
2472 2235 }
2473 2236 } 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 - }
2237 + 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 2238 }
2478 2239
2479 2240 return $args;
2480 2241 }
@@ -2500,15 +2261,15 @@
2500 2261 *
2501 2262 * Set the raw data, the ID and the parsed settings.
2502 2263 *
2503 2264 * @since 1.4.0
2504 - * @deprecated 2.9.0 Use `init()` method instead.
2265 + * @deprecated 2.9.0 use `init()` instead
2505 2266 * @access protected
2506 2267 *
2507 2268 * @param array $data Initial data.
2508 2269 */
2509 2270 protected function _init( $data ) {
2510 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '2.9.0', 'init()' );
2271 + Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '2.9.0', __CLASS__ . '::init()' );
2511 2272
2512 2273 $this->init( $data );
2513 2274 }
2514 2275
@@ -2579,9 +2340,9 @@
2579 2340 */
2580 2341 public function __construct( array $data = [] ) {
2581 2342 if ( $data ) {
2582 2343 // TODO: This is for backwards compatibility starting from 2.9.0
2583 - // This if statement should be removed when the method is hard-deprecated.
2344 + // This if statement should be removed when the method is hard-deprecated
2584 2345 if ( $this->has_own_method( '_init', self::class ) ) {
2585 2346 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_init', '2.9.0', __CLASS__ . '::init()' );
2586 2347
2587 2348 $this->_init( $data );