Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/wp-includes/class-wp-query.php
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,24 @@ protected function parse_search_terms( $terms ) {
continue;
}

/**
* Filters a search term after it has passed the length and stopwords checks.
*
* Can be used to normalize or remove a term. Returning an empty string
* will cause the term to be skipped. This is particularly useful for
* languages such as Arabic that require stripping diacritics, Hamza
* variants, or other decorative characters before meaningful comparison.
*
* @since 6.9.0
*
* @param string $term The search term.
*/
$term = apply_filters( 'wp_search_term', $term );

if ( ! $term ) {
continue;
}

$checked[] = $term;
}

Expand Down
31 changes: 31 additions & 0 deletions tests/phpunit/tests/query/search.php
Original file line number Diff line number Diff line change
Expand Up @@ -644,4 +644,35 @@ public function test_wp_query_removes_filter_wp_allow_query_attachment_by_filena
public function filter_posts_search( $sql ) {
return $sql . ' /* posts_search */';
}

/**
* @ticket 25585
*/
public function test_wp_search_term_filter_empty_string_removes_term() {
$callback = static function ( $term ) {
return 'foo' === $term ? '' : $term;
};

add_filter( 'wp_search_term', $callback );
$query = new WP_Query( array( 's' => 'foo bar' ) );
remove_filter( 'wp_search_term', $callback );

$this->assertSame( array( 'bar' ), $query->get( 'search_terms' ) );
}

/**
* @ticket 25585
*/
public function test_wp_search_term_filter_normalizes_arabic_characters() {
$callback = static function ( $term ) {
$term = str_replace( array( 'أ', 'إ', 'آ' ), 'ا', $term );
return str_replace( array( 'َ', 'ً', 'ُ', 'ٌ', 'ِ', 'ٍ', 'ْ', 'ّ' ), '', $term );
};

add_filter( 'wp_search_term', $callback );
$query = new WP_Query( array( 's' => 'أَنْتَ بَيْت' ) );
remove_filter( 'wp_search_term', $callback );

$this->assertSame( array( 'انت', 'بيت' ), $query->get( 'search_terms' ) );
}
}
Loading