From 5a7d3930b126d50b8255a7d3af0813dbec2eae17 Mon Sep 17 00:00:00 2001 From: ArkaPrabhaChowdhury Date: Wed, 8 Jul 2026 19:09:02 +0530 Subject: [PATCH 1/2] Administration: Normalize texturized post search terms --- src/wp-includes/class-wp-query.php | 20 +++++++++++++++ tests/phpunit/tests/query/search.php | 37 ++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 2c9502035705c..31d1769405c1b 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -1440,6 +1440,26 @@ protected function parse_search( &$query_vars ) { if ( empty( $_GET['s'] ) && $this->is_main_query() ) { $query_vars['s'] = urldecode( $query_vars['s'] ); } + // Admin post titles are texturized before display, so copied smart quotes should still match stored titles. + $query_vars['s'] = strtr( + $query_vars['s'], + array( + "\u{00A0}" => ' ', + "\u{202F}" => ' ', + "\u{00AB}" => '"', + "\u{00BB}" => '"', + "\u{2018}" => "'", + "\u{2019}" => "'", + "\u{201A}" => "'", + "\u{201B}" => "'", + "\u{201C}" => '"', + "\u{201D}" => '"', + "\u{201E}" => '"', + "\u{201F}" => '"', + "\u{2039}" => "'", + "\u{203A}" => "'", + ) + ); // There are no line breaks in fields. $query_vars['s'] = str_replace( array( "\r", "\n" ), '', $query_vars['s'] ); $query_vars['search_terms_count'] = 1; diff --git a/tests/phpunit/tests/query/search.php b/tests/phpunit/tests/query/search.php index 7bfbdec31c87d..8da15f5d0fad5 100644 --- a/tests/phpunit/tests/query/search.php +++ b/tests/phpunit/tests/query/search.php @@ -32,6 +32,10 @@ private function get_search_results( $terms ) { return $this->q->query( $args ); } + private function get_texturized_search_term( $title ) { + return html_entity_decode( wptexturize( $title ), ENT_QUOTES, 'UTF-8' ); + } + public function test_search_order_title_relevance() { foreach ( range( 1, 7 ) as $i ) { self::factory()->post->create( @@ -52,6 +56,38 @@ public function test_search_order_title_relevance() { $this->assertSame( $post_id, reset( $posts )->ID ); } + /** + * @ticket 63209 + */ + public function test_search_should_match_texturized_double_quotes() { + $post_id = self::factory()->post->create( + array( + 'post_title' => '"New" a good post', + 'post_type' => $this->post_type, + ) + ); + + $posts = $this->get_search_results( $this->get_texturized_search_term( '"New" a good post' ) ); + + $this->assertSame( array( $post_id ), wp_list_pluck( $posts, 'ID' ) ); + } + + /** + * @ticket 63209 + */ + public function test_search_should_match_texturized_apostrophes() { + $post_id = self::factory()->post->create( + array( + 'post_title' => "Today's post", + 'post_type' => $this->post_type, + ) + ); + + $posts = $this->get_search_results( $this->get_texturized_search_term( "Today's post" ) ); + + $this->assertSame( array( $post_id ), wp_list_pluck( $posts, 'ID' ) ); + } + public function test_search_terms_query_var() { $terms = 'This is a search term'; $query = new WP_Query( array( 's' => 'This is a search term' ) ); @@ -645,3 +681,4 @@ public function filter_posts_search( $sql ) { return $sql . ' /* posts_search */'; } } + From d65e45fc6f1eb02a442df1dcc9cd0fc54a93126c Mon Sep 17 00:00:00 2001 From: ArkaPrabhaChowdhury Date: Wed, 8 Jul 2026 22:58:58 +0530 Subject: [PATCH 2/2] Tests: Remove extra blank line at end of search query test file --- tests/phpunit/tests/query/search.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/phpunit/tests/query/search.php b/tests/phpunit/tests/query/search.php index 8da15f5d0fad5..c909d9292cc9e 100644 --- a/tests/phpunit/tests/query/search.php +++ b/tests/phpunit/tests/query/search.php @@ -681,4 +681,3 @@ public function filter_posts_search( $sql ) { return $sql . ' /* posts_search */'; } } -