PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.2
Elementor Website Builder – more than just a page builder v4.3.2
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 4.1.0-dev2 All 455 releases
← All changes | core/experiments/manager.php +75 -21 4.1.4 → 4.3.2 View file →
@@ -249,9 +249,11 @@
249 249 *
250 250 * @since 3.1.0
251 251 * @access public
252 252 *
253 - * @param string $feature_name
253 + * @param string $feature_name Experiment feature name.
254 + * @param bool $check_dependencies When true, also require dependency experiments to be active.
255 + * Missing or hidden dependencies are treated as active for compatibility.
254 256 *
255 257 * @return bool
256 258 */
257 259 public function is_feature_active( $feature_name, $check_dependencies = false ) {
@@ -262,9 +264,18 @@
262 264 }
263 265
264 266 if ( $check_dependencies && isset( $feature['dependencies'] ) && is_array( $feature['dependencies'] ) ) {
265 267 foreach ( $feature['dependencies'] as $dependency ) {
268 + if ( $dependency instanceof Non_Existing_Dependency ) {
269 + continue;
270 + }
271 +
266 272 $dependent_feature = $this->get_features( $dependency->get_name() );
273 +
274 + if ( $this->is_removed_or_hidden_dependency( $dependent_feature ) ) {
275 + continue;
276 + }
277 +
267 278 $feature_state = self::STATE_ACTIVE === $this->get_feature_actual_state( $dependent_feature );
268 279
269 280 if ( ! $feature_state ) {
270 281 return false;
@@ -342,15 +353,13 @@
342 353 $this->add_feature( [
343 354 'name' => 'container',
344 355 'title' => esc_html__( 'Container', 'elementor' ),
345 356 'description' => sprintf(
346 - /* translators: 1: Link opening tag, 2: Link closing tag, 3: Link opening tag, 4: Link closing tag, 5: Link opening tag, 6: Link closing tag */
347 - esc_html__( 'Create advanced layouts and responsive designs with %1$sFlexbox%2$s and %3$sGrid%4$s container elements. Give it a try using the %5$sContainer playground%6$s.', 'elementor' ),
357 + /* translators: 1: Link opening tag, 2: Link closing tag, 3: Link opening tag, 4: Link closing tag */
358 + esc_html__( 'Create advanced layouts and responsive designs with %1$sFlexbox%2$s and %3$sGrid%4$s container elements.', 'elementor' ),
348 359 '<a target="_blank" href="https://go.elementor.com/wp-dash-flex-container/">',
349 360 '</a>',
350 361 '<a target="_blank" href="https://go.elementor.com/wp-dash-grid-container/">',
351 - '</a>',
352 - '<a target="_blank" href="https://go.elementor.com/wp-dash-flex-container-playground/">',
353 362 '</a>'
354 363 ),
355 364 'release_status' => self::RELEASE_STATUS_STABLE,
356 365 'default' => self::STATE_INACTIVE,
@@ -380,14 +389,15 @@
380 389 ],
381 390 ] );
382 391
383 392 $this->add_feature( [
384 - 'name' => 'e_panel_promotions',
385 - 'title' => esc_html__( 'Panel Promotions', 'elementor' ),
386 - 'description' => esc_html__( 'Enable experimental rendering for targeted promotions within the elements panels.', 'elementor' ),
387 - 'release_status' => self::RELEASE_STATUS_DEV,
388 - 'default' => self::STATE_ACTIVE,
389 - 'type' => self::TYPE_HIDDEN,
393 + 'name' => 'e_optimized_css_files',
394 + 'title' => esc_html__( 'Optimized CSS Files', 'elementor' ),
395 + 'tag' => esc_html__( 'Performance', 'elementor' ),
396 + 'description' => esc_html__( 'Keeps external CSS files available and consistent for sites behind page caching or a CDN.', 'elementor' ),
397 + 'release_status' => self::RELEASE_STATUS_ALPHA,
398 + 'default' => self::STATE_INACTIVE,
399 + 'generator_tag' => true,
390 400 ] );
391 401 }
392 402
393 403 /**
@@ -780,20 +790,41 @@
780 790 }
781 791
782 792 // Validate if the current feature dependency is available.
783 793 foreach ( $feature['dependencies'] as $dependency ) {
794 + if ( $dependency instanceof Non_Existing_Dependency ) {
795 + $this->warn_removed_or_hidden_dependency(
796 + sprintf(
797 + 'The feature `%s` has a dependency `%s` that is not available in Core.',
798 + esc_html( $feature['name'] ),
799 + esc_html( $dependency->get_name() )
800 + )
801 + );
802 + continue;
803 + }
804 +
784 805 $dependency_feature = $this->get_features( $dependency->get_name() );
785 806
786 807 if ( ! $dependency_feature ) {
787 - $rollback( $feature_option_key, self::STATE_INACTIVE );
808 + $this->warn_removed_or_hidden_dependency(
809 + sprintf(
810 + 'The feature `%s` has a dependency `%s` that is not available in Core.',
811 + esc_html( $feature['name'] ),
812 + esc_html( $dependency->get_name() )
813 + )
814 + );
815 + continue;
816 + }
788 817
789 - throw new Exceptions\Dependency_Exception(
818 + if ( $this->is_removed_or_hidden_dependency( $dependency_feature ) ) {
819 + $this->warn_removed_or_hidden_dependency(
790 820 sprintf(
791 - 'The feature `%s` has a dependency `%s` that is not available.',
821 + 'The feature `%1$s` depends on hidden experiment `%2$s`.',
792 822 esc_html( $feature['name'] ),
793 - esc_html( $dependency->get_name() )
823 + esc_html( $dependency_feature['name'] )
794 824 )
795 825 );
826 + continue;
796 827 }
797 828
798 829 $dependency_state = $this->get_feature_actual_state( $dependency_feature );
799 830
@@ -946,10 +977,8 @@
946 977
947 978 /**
948 979 * @param array $experimental_data
949 980 * @return array
950 - *
951 - * @throws Exceptions\Dependency_Exception If the feature dependency is not initialized or depends on a hidden experiment.
952 981 */
953 982 private function initialize_feature_dependencies( array $experimental_data ): array {
954 983 foreach ( $experimental_data['dependencies'] as $key => $dependency ) {
955 984 $feature = $this->get_features( $dependency );
@@ -954,20 +983,28 @@
954 983 foreach ( $experimental_data['dependencies'] as $key => $dependency ) {
955 984 $feature = $this->get_features( $dependency );
956 985
957 986 if ( ! isset( $feature ) ) {
958 - // since we must validate the state of each dependency, we have to make sure that dependencies are initialized in the correct order, otherwise, error.
959 - throw new Exceptions\Dependency_Exception(
987 + $this->warn_removed_or_hidden_dependency(
960 988 sprintf(
961 - 'Feature %s cannot be initialized before dependency feature: %s.',
989 + 'Feature %1$s depends on experiment %2$s that is not registered in Core.',
962 990 esc_html( $experimental_data['name'] ),
963 991 esc_html( $dependency )
964 992 )
965 993 );
994 +
995 + $experimental_data['dependencies'][ $key ] = $this->create_dependency_class( $dependency, null );
996 + continue;
966 997 }
967 998
968 999 if ( ! empty( $feature[ static::TYPE_HIDDEN ] ) ) {
969 - throw new Exceptions\Dependency_Exception( 'Depending on a hidden experiment is not allowed.' );
1000 + $this->warn_removed_or_hidden_dependency(
1001 + sprintf(
1002 + 'Feature %1$s depends on hidden experiment %2$s.',
1003 + esc_html( $experimental_data['name'] ),
1004 + esc_html( $dependency )
1005 + )
1006 + );
970 1007 }
971 1008
972 1009 $experimental_data['dependencies'][ $key ] = $this->create_dependency_class( $dependency, $feature );
973 1010 $experimental_data = $this->set_feature_default_state_to_match_dependencies( $feature, $experimental_data );
@@ -973,8 +1010,25 @@
973 1010 $experimental_data = $this->set_feature_default_state_to_match_dependencies( $feature, $experimental_data );
974 1011 }
975 1012
976 1013 return $experimental_data;
1014 + }
1015 +
1016 + private function is_removed_or_hidden_dependency( $dependency_feature ): bool {
1017 + if ( ! $dependency_feature ) {
1018 + return true;
1019 + }
1020 +
1021 + return ! empty( $dependency_feature[ static::TYPE_HIDDEN ] );
1022 + }
1023 +
1024 + private function warn_removed_or_hidden_dependency( string $message ): void {
1025 + if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
1026 + return;
1027 + }
1028 +
1029 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Developer notice; message is escaped.
1030 + _doing_it_wrong( __METHOD__, esc_html( $message ), ELEMENTOR_VERSION );
977 1031 }
978 1032
979 1033 /**
980 1034 * @param array $feature