From 245e40f38498a599f1cfc16ca8e27690915f8f17 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Tue, 23 Feb 2016 20:13:22 +0000 Subject: [PATCH] Query: Search should match `post_excerpt` in addition to title and content. When ordering search results, exact matches in the post excerpt are weighted above those in post content, but below those in the post title. Props swissspidy, sebastian.pisula. FIxes #35762. git-svn-id: https://develop.svn.wordpress.org/trunk@36647 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/query.php | 9 ++-- tests/phpunit/tests/query/search.php | 75 ++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/query.php b/src/wp-includes/query.php index 99df782336..4b3e1e41f7 100644 --- a/src/wp-includes/query.php +++ b/src/wp-includes/query.php @@ -2156,7 +2156,7 @@ class WP_Query { } $like = $n . $wpdb->esc_like( $term ) . $n; - $search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like ); + $search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_excerpt $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like, $like ); $searchand = ' AND '; } @@ -2280,13 +2280,14 @@ class WP_Query { $search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 '; } - // sentence match in 'post_content' + // Sentence match in 'post_content' and 'post_excerpt'. if ( $like ) { - $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_content LIKE %s THEN 4 ", $like ); + $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_excerpt LIKE %s THEN 4 ", $like ); + $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_content LIKE %s THEN 5 ", $like ); } if ( $search_orderby ) { - $search_orderby = '(CASE ' . $search_orderby . 'ELSE 5 END)'; + $search_orderby = '(CASE ' . $search_orderby . 'ELSE 6 END)'; } } else { // single word or sentence search diff --git a/tests/phpunit/tests/query/search.php b/tests/phpunit/tests/query/search.php index 859cd98172..35f734b9c0 100644 --- a/tests/phpunit/tests/query/search.php +++ b/tests/phpunit/tests/query/search.php @@ -178,6 +178,81 @@ class Tests_Query_Search extends WP_UnitTestCase { $this->assertNotContains( 'posts_search', $q->request ); } + /** + * @ticket 35762 + */ + public function test_search_post_excerpt() { + $p1 = self::factory()->post->create( array( + 'post_status' => 'publish', + 'post_content' => 'This post has foo but also bar', + ) ); + $p2 = self::factory()->post->create( array( + 'post_status' => 'publish', + 'post_content' => '', + 'post_excerpt' => 'This post has bar and baz', + ) ); + $p3 = self::factory()->post->create( array( + 'post_status' => 'publish', + 'post_content' => '', + 'post_excerpt' => 'This post has only foo', + ) ); + + $q = new WP_Query( array( + 's' => 'foo', + 'fields' => 'ids', + ) ); + + $this->assertEqualSets( array( $p1, $p3 ), $q->posts ); + + $q = new WP_Query( array( + 's' => 'bar', + 'fields' => 'ids', + ) ); + + $this->assertEqualSets( array( $p1, $p2 ), $q->posts ); + + $q = new WP_Query( array( + 's' => 'baz', + 'fields' => 'ids', + ) ); + + $this->assertEqualSets( array( $p2 ), $q->posts ); + } + + /** + * @ticket 35762 + */ + public function test_search_order_title_before_excerpt_and_content() { + $p1 = self::factory()->post->create( array( + 'post_status' => 'publish', + 'post_title' => 'This post has foo', + 'post_content' => '', + 'post_excerpt' => '', + ) ); + + $p2 = self::factory()->post->create( array( + 'post_status' => 'publish', + 'post_title' => '', + 'post_content' => 'This post has foo', + 'post_excerpt' => '', + ) ); + + $p3 = self::factory()->post->create( array( + 'post_status' => 'publish', + 'post_title' => '', + 'post_content' => '', + 'post_excerpt' => 'This post has foo', + ) ); + + $q = new WP_Query( array( + 's' => 'this post has foo', + 'fields' => 'ids', + 'orderby' => false, + ) ); + + $this->assertSame( array( $p1, $p3, $p2 ), $q->posts ); + } + public function filter_posts_search( $sql ) { return $sql . ' /* posts_search */'; }