1
+ <?php
2
+ /**
3
+ * Sorts unpaginated search results more intutiviely.
4
+ *
5
+ * If the search terms exactly match an item's title, that item is first. Then, general
6
+ * matches occur on the title, excerpt, and content fields, sorted in that order.
7
+ */
8
+
9
+ add_filter ( 'the_posts ' , function ( $ posts , $ query ) {
10
+ if ( ! $ query ->is_main_query () || ! $ query ->is_search () )
11
+ return $ posts ;
12
+
13
+ $ priorities = array_fill ( 0 , 4 , array () );
14
+
15
+ $ search_terms = $ query ->query_vars ['search_terms ' ];
16
+ $ search_terms = array_map ( 'strtolower ' , $ search_terms );
17
+ foreach ( $ posts as $ post ) {
18
+ if ( strtolower ( $ post ->post_title ) === implode ( ' ' , $ search_terms ) ) {
19
+ // Perfect title match: Priority 0.
20
+ $ priorities [0 ][] = $ post ;
21
+ continue ;
22
+ }
23
+
24
+ foreach ( array ( 1 => 'post_title ' , 2 => 'post_excerpt ' ) as $ priority => $ field ) {
25
+ foreach ( $ search_terms as $ search_term ) {
26
+ // A search term is not present in the field, so move to the next field.
27
+ if ( false === stripos ( $ post ->$ field , $ search_term ) )
28
+ continue 2 ;
29
+ }
30
+
31
+ // Found all matching terms in this field, so add it to the respective priority.
32
+ $ priorities [ $ priority ][] = $ post ;
33
+ continue 2 ;
34
+ }
35
+
36
+ // No matches in a priority field, so assume the post got here via the content.
37
+ $ priorities [3 ][] = $ post ;
38
+ }
39
+
40
+ return array_merge ( $ priorities [0 ], $ priorities [1 ], $ priorities [2 ], $ priorities [3 ] );
41
+ }, 10 , 2 );
0 commit comments