Skip to content

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

Open
faisalahammad wants to merge 2 commits 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 2 commits into
10up:developfrom
faisalahammad:fix/3602-did-you-mean-valid-query

Conversation

@faisalahammad

@faisalahammad faisalahammad commented Jun 21, 2026

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.

Closes #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:

$suppress_when_results_exist = apply_filters( 'ep_suggestion_suppress_when_results_exist', true, $query );

if ( $suppress_when_results_exist && $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.

A new ep_suggestion_suppress_when_results_exist filter (default true) was added per review feedback, so sites that want the suggestion to still show up alongside results can opt back in with one line, instead of the fix being all-or-nothing.

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.

How to test the Change

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.

Test 4: Restore suggestion via filter

  1. Add add_filter( 'ep_suggestion_suppress_when_results_exist', '__return_false' ); to a must-use plugin.
  2. Repeat Test 1.
    Result: "Did you mean: shift?" now shows again alongside the "shirt" results.

Unit tests

Tests added/updated in tests/php/features/TestDidYouMean.php:

  • testGetSuggestionNotShownWhenResultsExist
  • testGetSuggestionNotShownWhenTopSuggestionMatchesOriginalTerm
  • testGetSuggestionNotShownWhenTopSuggestionMatchesOriginalTermCaseInsensitive
  • testGetSuggestionSuppressWhenResultsExistFilter

Run with:

vendor/bin/phpunit --filter TestDidYouMean

All 21 tests pass. Full composer run test-single-site suite also run (944 tests) with no regressions (1 pre-existing unrelated failure in TestInstantResults on WP 7.0, not touched by this PR).

Changelog Entry

Fixed - "Did You Mean" no longer suggests a term when the current search already has results or when the suggestion matches the original term (case-insensitive), preventing confusing suggestions and redirect loops. A new ep_suggestion_suppress_when_results_exist filter allows restoring the previous behavior.

Credits

Props @faisalahammad

Checklist:

…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
Comment thread includes/classes/Feature/DidYouMean/DidYouMean.php Outdated
- Add ep_suggestion_suppress_when_results_exist filter (default true)
- Add test for filter opt-out behavior

Addresses review feedback from burhandodhy.

Refs 10up#4330

@faisalahammad faisalahammad left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated per feedback. Added ep_suggestion_suppress_when_results_exist filter (default true) so sites can restore the old behavior with one line. Test added: testGetSuggestionSuppressWhenResultsExistFilter.

Tests: 21/21 TestDidYouMean pass. Full suite 944 tests, no regressions.
Lint: clean.
CodeRabbit: 0 findings.

@faisalahammad

Copy link
Copy Markdown
Author

@burhandodhy addressed your feedback, ready for another look.

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

2 participants