Make WordPress Core

Opened 6 weeks ago

Last modified 5 weeks ago

#65130 new enhancement

Plugin search (term) in wp-admin lacks normalization, causing fragile keyword matching

Reported by: 369work's profile 369work Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Plugins Keywords:
Focuses: administration Cc:

Description (last modified by sabernhardt)

Problem

The plugin search box in wp-admin (Plugins > Add New) produces unreliable results when searching by keyword (term). A user searching for "WP Multibyte Patch" gets very different results depending on minor variations in their query:

Query Result
multibyte Found
multi byte Not found
multi Not found
multi patch Not found

The root cause is that the search term is passed to the WordPress.org Plugin API with no normalization whatsoever.

Root cause (confirmed in source)

In wp-admin/includes/class-wp-plugin-install-list-table.php, the prepare_items() method handles the search tab as follows:

// Line 161-169
$type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
$term = isset( $_REQUEST['s'] )    ? wp_unslash( $_REQUEST['s'] )    : '';

switch ( $type ) {
    case 'tag':
        $args['tag'] = sanitize_title_with_dashes( $term ); // sanitized
        break;
    case 'term':
        $args['search'] = $term; // ← NO processing at all
        break;
    case 'author':
        $args['author'] = $term; // no processing
        break;
}

Note the inconsistency: the tag type applies sanitize_title_with_dashes(), which strips spaces and normalizes the string, while term (keyword search) receives NO processing. This asymmetry appears unintentional.

The raw $args is then passed directly to plugins_api( 'query_plugins', $args ), which forwards the search string as-is to https://api.wordpress.org/plugins/info/1.2/.

Proposed fix

The fix is a single line change in class-wp-plugin-install-list-table.php:

// Before (line 169):
$args['search'] = $term;

// After:
$args['search'] = preg_replace( '/\s+/', '', $term );

This strips whitespace between words before sending the query to the API, so "multi byte" becomes "multibyte" — matching the plugin slug and name as indexed by WordPress.org.

A more robust approach could also apply sanitize_text_field() for consistency with the tag type, and potentially send a secondary query with the original term to merge results.

Files affected

  • wp-admin/includes/class-wp-plugin-install-list-table.php — line 169 (primary fix)
  • wp-admin/includes/plugin-install.phpplugins_api() (no change needed; normalization should happen before this call)

Note on server-side improvements

Deeper fuzzy search improvements (stemming, partial matching, relevance ranking) would require changes on the Meta/Plugin Directory side (api.wordpress.org). This ticket focuses solely on the low-risk, one-line client-side normalization that can ship independently.

Attachments (1)

65130.diff (664 bytes) - added by yusufmudagal 5 weeks ago.
Patch to normalize plugin keyword search terms by stripping spaces/hyphens before sending the query to the WordPress.org Plugin API.

Download all attachments as: .zip

Change History (5)

@yusufmudagal
5 weeks ago

Patch to normalize plugin keyword search terms by stripping spaces/hyphens before sending the query to the WordPress.org Plugin API.

#1 @369work
5 weeks ago

  • Keywords has-patch added; needs-patch removed

A patch has been attached by @yusufmudagal. Updating keyword to has-patch.

#2 @369work
5 weeks ago

Tested the patch on a local WordPress trunk installation.

Results:

  • "multibyte" → WP Multibyte Patch found ✅
  • "multi byte" → WP Multibyte Patch found ✅
  • "multi-byte" → WP Multibyte Patch found ✅
  • "multi" → Too many results (5000+) to confirm, but no regression observed
  • "multi patch" → Not found ❌ (expected, as the API does not support multi-token matching)

The patch works as intended for the core use case (space/hyphen normalization).
The "multi patch" case would require server-side improvements, which is out of scope for this ticket as noted in the description.

#3 @sabernhardt
5 weeks ago

  • Component changed from Administration to Plugins
  • Description modified (diff)
  • Focuses administration added
  • Keywords has-patch removed
  • Version trunk deleted

65130.diff would introduce a new problem with some queries that work correctly now. If someone enters multiple words of the plugin name, the edited keyword search query could yield zero results.

  • "wp multibyte patch"
  • "wp multibyte"
  • "multibyte patch"

I expect that keyword search queries for other plugins' names would have similar problems with the patch.

In the case of WP Multibyte Patch, the plugin has more than one million installations. Many people successfully find it (possibly because more people would search for it in Japanese than in English).

#4 @369work
5 weeks ago

Thank you for the review.
You're right — stripping all spaces unconditionally breaks multi-word queries that already work (e.g. "wp multibyte patch"). That was a mistake in the proposed fix.
Instead, I'd propose keeping the original $term for the first query, and only retrying with spaces/hyphens removed if the result is empty. This avoids breaking existing queries while still recovering zero-result cases caused by unintentional spacing.

"wp multibyte patch" → first query succeeds ✅
"multi byte" → fallback strips spaces → "multibyte" ✅

That said, partial queries like "wp multi" or "multibyte-pa" can't be fixed this way — that would require prefix/partial matching on the api.wordpress.org side.
If this direction seems reasonable, would it be worth pursuing a revised patch using the fallback approach?

Note: See TracTickets for help on using tickets.