I think the only solution is to skip the sql pagination and handle it only via php.
My idea involves 2 functions, one hooked on pre_get_posts
, the second to filter the_posts
.
The first function does 2 things:
- unset the paged value for search, in this way all the posts are returned from the SQL query.
- save the queried
paged
value in global variable, in this way can be used in the second function that run later
Here the function:
function filter_my_search_query( $query ) {
if ( is_search() && $query->is_main_query() && ! is_admin() ) {
global $the_original_paged;
$the_original_paged = $query->get('paged') ? $query->get('paged') : 1;
$query->set('paged', NULL );
$query->set('nopaging', TRUE );
}
}
add_action('pre_get_posts', 'filter_my_search_query', 1);
Now the search query return all the posts, with no pagination, and the paged required is saved in the global variable $the_original_paged
.
So we can filter the_posts
merging the wanted additional posts, then get only the correct posts based on required page and posts per page setting, and finally reset the paged
and other $wp_query
properties to let pagination link works:
function add_posts_to_search_query( $posts ) {
global $wp_query, $the_original_paged;
if ( ! is_main_query() || is_admin() || ! is_search() || is_null($the_original_paged) )
return $posts;
// the wanted posts per page here setted on general settings
$perpage = get_option('posts_per_page');
remove_filter( 'the_posts', 'add_posts_to_search_query' );
$new = new WP_Query( 'year=2012&monthnum=12&day=12&nopaging=1' );
$merged = array_merge( $posts, $new->posts );
$wp_query->found_posts += $new->found_posts;
// getting the right posts based on current page and posts per page
$wp_query->posts = array_slice($merged, ( $perpage * ($the_original_paged-1) ), $perpage );
// set the paged and other wp_query properties to the right value, to make pagination work
$wp_query->set('paged', $the_original_paged);
$wp_query->post_count = count($wp_query->posts);
$wp_query->max_num_pages = ceil( $wp_query->found_posts / $perpage );
unset($the_original_paged); // clean up global variable
return $wp_query->posts;
}
add_filter('the_posts', 'add_posts_to_search_query');