Skip to content

fix(did-you-mean): suppress suggestions for valid queries and matching terms#4330

Open
faisalahammad wants to merge 1 commit into
10up:developfrom
faisalahammad:fix/3602-did-you-mean-valid-query
Open

fix(did-you-mean): suppress suggestions for valid queries and matching terms#4330
faisalahammad wants to merge 1 commit into
10up:developfrom
faisalahammad:fix/3602-did-you-mean-valid-query

Conversation

@faisalahammad

Copy link
Copy Markdown

Summary

"Did You Mean" currently shows the top suggestion even when the current search term already returns results. This leads to confusing suggestions like "Did you mean: shift?" when searching for "shirt" with valid results. This fix suppresses the suggestion when the query has results, or when the suggestion matches the original term. It also applies the same guard to the redirect behavior to prevent a redirect loop.

Fixes #3602

Changes

includes/classes/Feature/DidYouMean/DidYouMean.php

get_suggestion() now returns false early in two cases:

Before:

$term = $this->get_suggested_term( $query );
if ( empty( $term ) ) {
    return false;
}

$html = sprintf( '<span class="ep-spell-suggestion">%s: <a href="%s">%s</a>?</span>', ... );

After:

if ( $query->found_posts > 0 ) {
    return false;
}

$term = $this->get_suggested_term( $query );
if ( empty( $term ) ) {
    return false;
}

$search_term = $query->query_vars['s'] ?? '';
if ( strtolower( $term ) === strtolower( $search_term ) ) {
    return false;
}

$html = sprintf( '<span class="ep-spell-suggestion">%s: <a href="%s">%s</a>?</span>', ... );

Why: This matches the existing behavior of get_alternatives_terms(), which already hides the alternative list when the query has results. The case-insensitive match guard prevents the feature from suggesting the same term the user already typed.

automatically_redirect_user() also skips redirecting if the suggested term equals the current search term:

After:

$term = $this->get_suggested_term( $wp_query );
if ( empty( $term ) ) {
    return;
}

$search_term = $wp_query->query_vars['s'] ?? '';
if ( strtolower( $term ) === strtolower( $search_term ) ) {
    return;
}

Why: Prevents an infinite redirect loop when the phrase suggester returns the same term as the original query.

Testing

Test 1: Valid query with results

  1. Create posts containing "shirt" and "shift".
  2. Sync the index.
  3. Search for "shirt".
    Result: results load and no "Did you mean: shift?" message appears.

Test 2: Typo with no results

  1. Search for "shirf".
    Result: "Did you mean: shirt?" appears because the query has no results.

Test 3: Same-term suggestion

  1. Mock or trigger a query where the top suggestion equals the original term (e.g., "shirt" → "shirt" or "Shirt").
    Result: no suggestion is displayed.

Unit tests

Two new tests added to tests/php/features/TestDidYouMean.php:

  • testGetSuggestionNotShownWhenResultsExist
  • testGetSuggestionNotShownWhenTopSuggestionMatchesOriginalTerm
  • testGetSuggestionNotShownWhenTopSuggestionMatchesOriginalTermCaseInsensitive

Run with:

vendor/bin/phpunit --filter TestDidYouMean

All 20 tests pass.

…hes 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 10up#3602
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: "Did You Mean" feature offers suggestions even if the current search term is more appropriate

1 participant