PluginProbe
Elementor Website Builder – more than just a page builder / trunk
Elementor Website Builder – more than just a page builder vtrunk
4.3.3 4.3.2 4.3.1 4.3.0 4.3.0-beta3 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 All 456 releases
← All changes | core/experiments/manager.php +46 -5 4.3.2 → trunk View file →
@@ -89,8 +89,10 @@
89 89 }
90 90
91 91 $this->features[ $options['name'] ] = $experimental_data;
92 92
93 + $this->resolve_registered_dependants( $options['name'], $experimental_data );
94 +
93 95 if ( $experimental_data['mutable'] && is_admin() ) {
94 96 $feature_option_key = $this->get_feature_option_key( $options['name'] );
95 97
96 98 $on_state_change_callback = function( $old_state, $new_state ) use ( $experimental_data, $feature_option_key ) {
@@ -251,9 +253,9 @@
251 253 * @access public
252 254 *
253 255 * @param string $feature_name Experiment feature name.
254 256 * @param bool $check_dependencies When true, also require dependency experiments to be active.
255 - * Missing or hidden dependencies are treated as active for compatibility.
257 + * Missing dependencies always fail closed. Hidden dependencies are treated as satisfied.
256 258 *
257 259 * @return bool
258 260 */
259 261 public function is_feature_active( $feature_name, $check_dependencies = false ) {
@@ -262,17 +264,33 @@
262 264 if ( ! $feature || self::STATE_ACTIVE !== $this->get_feature_actual_state( $feature ) ) {
263 265 return false;
264 266 }
265 267
266 - if ( $check_dependencies && isset( $feature['dependencies'] ) && is_array( $feature['dependencies'] ) ) {
268 + if ( isset( $feature['dependencies'] ) && is_array( $feature['dependencies'] ) ) {
267 269 foreach ( $feature['dependencies'] as $dependency ) {
268 - if ( $dependency instanceof Non_Existing_Dependency ) {
270 + $dependent_feature = $this->get_features( $dependency->get_name() );
271 +
272 + // A dependency that Core still does not ship can never be verified as active.
273 + // Non existing dependencies are re-resolved first to cover later registrations.
274 + if ( $dependency instanceof Non_Existing_Dependency && ! $dependent_feature ) {
275 + return false;
276 + }
277 +
278 + if ( ! $dependent_feature ) {
279 + // A Core experiment dependency that no longer resolves fails closed.
280 + // Class dependencies are not experiment names and stay exempt.
281 + if ( $dependency instanceof Wrap_Core_Dependency ) {
282 + return false;
283 + }
284 +
269 285 continue;
270 286 }
271 287
272 - $dependent_feature = $this->get_features( $dependency->get_name() );
288 + if ( ! $check_dependencies ) {
289 + continue;
290 + }
273 291
274 - if ( $this->is_removed_or_hidden_dependency( $dependent_feature ) ) {
292 + if ( ! empty( $dependent_feature[ static::TYPE_HIDDEN ] ) ) {
275 293 continue;
276 294 }
277 295
278 296 $feature_state = self::STATE_ACTIVE === $this->get_feature_actual_state( $dependent_feature );
@@ -1018,8 +1036,31 @@
1018 1036 return true;
1019 1037 }
1020 1038
1021 1039 return ! empty( $dependency_feature[ static::TYPE_HIDDEN ] );
1040 + }
1041 +
1042 + /**
1043 + * Re-resolve non existing dependency placeholders of dependants that were
1044 + * registered before this feature existed.
1045 + *
1046 + * @param string $feature_name Newly registered feature name.
1047 + * @param array $feature_data Newly registered feature data.
1048 + */
1049 + private function resolve_registered_dependants( string $feature_name, array $feature_data ): void {
1050 + foreach ( $this->features as $name => $registered_feature ) {
1051 + if ( $name === $feature_name || empty( $registered_feature['dependencies'] ) || ! is_array( $registered_feature['dependencies'] ) ) {
1052 + continue;
1053 + }
1054 +
1055 + foreach ( $registered_feature['dependencies'] as $key => $dependency ) {
1056 + if ( ! ( $dependency instanceof Non_Existing_Dependency ) || $dependency->get_name() !== $feature_name ) {
1057 + continue;
1058 + }
1059 +
1060 + $this->features[ $name ]['dependencies'][ $key ] = $this->create_dependency_class( $feature_name, $feature_data );
1061 + }
1062 + }
1022 1063 }
1023 1064
1024 1065 private function warn_removed_or_hidden_dependency( string $message ): void {
1025 1066 if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {