is_main_query() && $query->is_search ) { $query->set( 'paged', ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1 ); $query->set( 'posts_per_page', -1 ); } } add_action( 'pre_get_posts', __NAMESPACE__ . '\\pageSearch' ); /** * Sort WP_Post objects in reverse order (most recent first). * * @param string $key WP_Post object property used for sorting. 'post_date' is assumed. * * @return int */ function postSort( $key ) { return function ( $a, $b ) use ( $key ) { if ( $a->$key < $b->$key ) { return 1; } elseif ( $a->$key > $b->$key ) { return -1; } else { // If first comparison is equal, use title as secondary sort key. return strnatcasecmp( $a->post_title, $b->post_title ); } }; } /** * Remove duplicate posts in combined list from default and secondary queries. * * @param array $posts Array of WP_Post objects. * @param string $key Search key used to identify duplicate objects. Post ID is used. * * @return array */ function dedupe( $posts, $key ) { $unique_posts = array(); $ids = array(); foreach ( $posts as $post ) { if ( ! in_array( $post->$key, $ids, true ) ) { $ids[] = $post->$key; $unique_posts[] = $post; } } return $unique_posts; } /** * Posts_results filter hook callback. * * @param array $posts Array of WP_Post objects. * @param object $query WP_Query object from default search. * * @return array */ function searchResultFilter( $posts, $query ) { if ( \is_search() && $query->is_search() && ! \is_admin() ) { $args = array( 'post_type' => array( 'post', 'page' ), 'posts_per_page' => -1, 'tax_query' => array( 'relation' => 'OR', // Include both tags and categories. array( 'taxonomy' => 'post_tag', 'field' => 'name', 'terms' => $query->get( 's' ), ), array( 'taxonomy' => 'category', 'field' => 'name', 'terms' => $query->get( 's' ), ), ), ); // Remove callback to avoid infinite loop. remove_filter( 'posts_results', __NAMESPACE__ . '\\searchResultFilter', 10 ); $secondary_query = new \WP_Query( $args ); $tagged_posts = $secondary_query->get_posts(); // Combine default search results with secondary query. $all_posts = array_merge( $posts, $tagged_posts ); // Remove duplicate posts. $unique_posts = dedupe( $all_posts, 'ID' ); // Sort by reverse post_date order (most recent first). usort( $unique_posts, postSort( 'post_date' ) ); // Restore posts_results callback. add_filter( 'posts_results', __NAMESPACE__ . '\\searchResultFilter', 10, 2 ); return $unique_posts; } else { return $posts; } } add_filter( 'posts_results', __NAMESPACE__ . '\\searchResultFilter', 10, 2 );