From 959de9eb622a0e6d14e863140ed0f44dc4cb8bb3 Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Sun, 21 Jun 2026 11:32:29 +0600 Subject: [PATCH 1/2] fix(did-you-mean): suppress suggestion when query has results or matches original term - Suppress suggestion in get_suggestion() if query found_posts > 0 - Suppress suggestion if top suggestion equals original search term (case-insensitive) - Apply same guard in automatically_redirect_user() to prevent redirect loops - Add unit tests for both new behaviors Fixes #3602 --- .../classes/Feature/DidYouMean/DidYouMean.php | 17 ++++ tests/php/features/TestDidYouMean.php | 82 +++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/includes/classes/Feature/DidYouMean/DidYouMean.php b/includes/classes/Feature/DidYouMean/DidYouMean.php index 8c084d990..aaa89831f 100644 --- a/includes/classes/Feature/DidYouMean/DidYouMean.php +++ b/includes/classes/Feature/DidYouMean/DidYouMean.php @@ -127,11 +127,22 @@ public function get_suggestion( $query = null ) { return false; } + // No need to suggest alternatives if the current query already returned results. + if ( $query->found_posts > 0 ) { + return false; + } + $term = $this->get_suggested_term( $query ); if ( empty( $term ) ) { return false; } + // No need to suggest the same term the user already typed. + $search_term = $query->query_vars['s'] ?? ''; + if ( strtolower( $term ) === strtolower( $search_term ) ) { + return false; + } + $html = sprintf( '%s: %s?', esc_html__( 'Did you mean', 'elasticpress' ), get_search_link( $term ), $term ); $html .= $this->get_alternatives_terms( $query ); @@ -296,6 +307,12 @@ public function automatically_redirect_user() { return; } + // Do not redirect to the same term the user already searched for. + $search_term = $wp_query->query_vars['s'] ?? ''; + if ( strtolower( $term ) === strtolower( $search_term ) ) { + return; + } + $url = get_search_link( $term ); $url = add_query_arg( [ diff --git a/tests/php/features/TestDidYouMean.php b/tests/php/features/TestDidYouMean.php index b1d3e7e64..f9425110b 100644 --- a/tests/php/features/TestDidYouMean.php +++ b/tests/php/features/TestDidYouMean.php @@ -116,6 +116,9 @@ public function testGetSearchSuggestionMethod() { $this->assertTrue( $query->elasticsearch_success ); + // Force no results so the suggestion is displayed. + $query->found_posts = 0; + $expected = sprintf( 'Did you mean: test?', get_search_link( 'test' ) ); $this->assertEquals( $expected, ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion( $query ) ); } @@ -143,6 +146,9 @@ public function testGetSearchSuggestionMethodReturnsSuggestionForMainQuery() { $query = $query->query( $args ); + // Force no results so the suggestion is displayed. + $wp_query->found_posts = 0; + $expected = sprintf( 'Did you mean: test?', get_search_link( 'test' ) ); $this->assertEquals( $expected, ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion() ); } @@ -180,6 +186,10 @@ function ( $html, $terms, $query ) use ( $expected_result ) { 's' => 'teet', ] ); + + // Force no results so the suggestion is displayed. + $query->found_posts = 0; + $this->assertEquals( $expected_result, ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion( $query ) ); } @@ -338,6 +348,9 @@ public function testEPSuggestionsAction() { $wp_the_query = $query; $wp_query = $query; + // Force no results so the suggestion is displayed. + $query->found_posts = 0; + ob_start(); do_action( 'ep_suggestions' ); $output = ob_get_clean(); @@ -371,6 +384,9 @@ public function testEPSuggestionsActionOtherThanMainQuery() { parse_str( 'ep_suggestion_original_term=Original Term', $_GET ); + // Force no results so the suggestion is displayed. + $query->found_posts = 0; + ob_start(); do_action( 'ep_suggestions', $query ); $output = ob_get_clean(); @@ -457,4 +473,70 @@ public function test_get_settings_schema() { $settings_keys ); } + + /** + * Tests that get_suggestion returns false when the current search term already has results. + */ + public function testGetSuggestionNotShownWhenResultsExist() { + $this->ep_factory->post->create( [ 'post_content' => 'Shirt product' ] ); + $this->ep_factory->post->create( [ 'post_content' => 'Shift product' ] ); + + ElasticPress\Elasticsearch::factory()->refresh_indices(); + + $query = new \WP_Query( + [ + 's' => 'shirt', + ] + ); + + $this->assertTrue( $query->elasticsearch_success ); + $this->assertGreaterThan( 0, $query->found_posts ); + $this->assertFalse( ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion( $query ) ); + } + + /** + * Tests that get_suggestion returns false when the top suggestion matches the original term. + */ + public function testGetSuggestionNotShownWhenTopSuggestionMatchesOriginalTerm() { + $query = new \WP_Query( + [ + 's' => 'shirt', + ] + ); + $query->found_posts = 0; + $query->suggested_terms = [ + 'options' => [ + [ + 'text' => 'shirt', + ], + ], + ]; + $query->query_vars['s'] = 'shirt'; + $query->elasticsearch_success = true; + + $this->assertFalse( ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion( $query ) ); + } + + /** + * Tests that get_suggestion returns false when the top suggestion matches the original term with different casing. + */ + public function testGetSuggestionNotShownWhenTopSuggestionMatchesOriginalTermCaseInsensitive() { + $query = new \WP_Query( + [ + 's' => 'shirt', + ] + ); + $query->found_posts = 0; + $query->suggested_terms = [ + 'options' => [ + [ + 'text' => 'Shirt', + ], + ], + ]; + $query->query_vars['s'] = 'shirt'; + $query->elasticsearch_success = true; + + $this->assertFalse( ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion( $query ) ); + } } From 7dfd03826adfb766e8f314288304e8c755b76b2d Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Tue, 7 Jul 2026 00:33:59 +0600 Subject: [PATCH 2/2] fix(did-you-mean): add filter to restore suggestion when results exist - Add ep_suggestion_suppress_when_results_exist filter (default true) - Add test for filter opt-out behavior Addresses review feedback from burhandodhy. Refs #4330 --- .../classes/Feature/DidYouMean/DidYouMean.php | 13 ++++++++- tests/php/features/TestDidYouMean.php | 29 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/includes/classes/Feature/DidYouMean/DidYouMean.php b/includes/classes/Feature/DidYouMean/DidYouMean.php index aaa89831f..052fdf639 100644 --- a/includes/classes/Feature/DidYouMean/DidYouMean.php +++ b/includes/classes/Feature/DidYouMean/DidYouMean.php @@ -127,8 +127,19 @@ public function get_suggestion( $query = null ) { return false; } + /** + * Filter whether to suppress the suggestion when the current query already returned results. + * + * @since 5.4.0 + * @hook ep_suggestion_suppress_when_results_exist + * @param {bool} $suppress Whether to suppress the suggestion. Default true. + * @param {WP_Query} $query The WP_Query object. + * @return {bool} New value + */ + $suppress_when_results_exist = apply_filters( 'ep_suggestion_suppress_when_results_exist', true, $query ); + // No need to suggest alternatives if the current query already returned results. - if ( $query->found_posts > 0 ) { + if ( $suppress_when_results_exist && $query->found_posts > 0 ) { return false; } diff --git a/tests/php/features/TestDidYouMean.php b/tests/php/features/TestDidYouMean.php index f9425110b..05af9ca75 100644 --- a/tests/php/features/TestDidYouMean.php +++ b/tests/php/features/TestDidYouMean.php @@ -494,6 +494,35 @@ public function testGetSuggestionNotShownWhenResultsExist() { $this->assertFalse( ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion( $query ) ); } + /** + * Tests that `ep_suggestion_suppress_when_results_exist` filter can restore the suggestion when results exist. + */ + public function testGetSuggestionSuppressWhenResultsExistFilter() { + $query = new \WP_Query( + [ + 's' => 'shirt', + ] + ); + $query->found_posts = 1; + $query->suggested_terms = [ + 'options' => [ + [ + 'text' => 'shift', + ], + ], + ]; + $query->query_vars['s'] = 'shirt'; + $query->elasticsearch_success = true; + + // Default behavior: suppressed because the query already has results. + $this->assertFalse( ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion( $query ) ); + + add_filter( 'ep_suggestion_suppress_when_results_exist', '__return_false' ); + + $expected = sprintf( 'Did you mean: shift?', get_search_link( 'shift' ) ); + $this->assertEquals( $expected, ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_suggestion( $query ) ); + } + /** * Tests that get_suggestion returns false when the top suggestion matches the original term. */