Skip to content

Instantly share code, notes, and snippets.

@tammyhart
Last active August 29, 2015 14:20
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tammyhart/138971bb9d1f97c30090 to your computer and use it in GitHub Desktop.
Save tammyhart/138971bb9d1f97c30090 to your computer and use it in GitHub Desktop.
Traverse WordPress Search Results
<?php
/**
* Return search array
*/
function loopconf_search_array( $search_hash ) {
// check for existence of unique transient
if ( false === ( $search_array = get_transient( 'loopconf_search_' . $search_hash ) ) ) {
global $wpdb;
$posts = $wpdb->get_results( $GLOBALS['wp_query']->request );
$search_array = array();
if ( false === empty( $posts ) ) {
foreach ( $posts as $post ) {
$search_array[] = $post->ID;
}
}
// save the transient for 10 minutes
set_transient( 'loopconf_search_' . $search_hash, $search_array, MINUTE_IN_SECONDS * 10 );
}
return $search_array;
}
/**
* Set session search_string
*/
function loopconf_set_search_string() {
global $wp_query;
$wp_session = WP_Session::get_instance();
// if we’re on a search page, save the search data
if ( !is_admin() && is_search() && isset( $wp_query->query_vars_hash ) ) {
$search_string = $wp_query->query['s'];
$search_hash = $wp_query->query_vars_hash;
$wp_session['search_string'] = $search_string;
$wp_session['search_hash'] = $search_hash;
$wp_session['search_array'] = loopconf_search_array( $search_hash );
}
// if we’re anywhere else, clear the search data
if ( !is_admin() && !is_search() && !is_single() && is_main_query() ) {
$wp_session['search_string'] =
$wp_session['search_hash'] =
$wp_session['search_array'] = null;
}
}
add_action( 'pre_get_posts', 'loopconf_set_search_string' );
/**
* Get the next or previous post in the array
*/
function loopconf_get_next_search_result( $next = true ) {
$wp_session = WP_Session::get_instance();
// make sure there’s a search saved in the session
if ( isset( $wp_session['search_array'] ) === false ) {
return false;
}
// set variables
$next_key = 0;
$search_array = $wp_session['search_array']->toArray();
$current_key = array_search( get_the_ID(), $search_array );
// get next or previous location in the array
if ( $next === true ) {
$next_key = $current_key + 1;
if ( isset( $search_array[$next_key] ) === false ) {
$next_key = 0;
}
} else {
$next_key = $current_key - 1;
if ( isset( $search_array[$next_key] ) === false ) {
end( $search_array );
$next_key = key( $search_array );
}
}
// return value from that location
return $search_array[$next_key];
}
?>
<?php
$prev_url = $next_url = false;
// get next and prev search results or just the links
if ( loopconf_get_next_search_result() ) {
$wp_session = WP_Session::get_instance();
$prev_url = get_permalink( loopconf_get_next_search_result() ); false ) );
$next_url = get_permalink( loopconf_get_next_search_result() );
} else {
$prev_url = get_previous_post();
$next_url = get_next_post();
}
?>
<div class="single-nav">
<a href="<?php echo esc_url( $prev_url ); ?>" class="prev">Previous</a>
<a href="<?php echo esc_url( $next_url ); ?>" class="next">Next</a>
</div>
@richardbuff
Copy link

So I've figured out what was confusing me. loopconf_search_array gets called for EVERY query on the search page. And since the SQL isn't created yet on the first call, if there's only one query on the page, it will fail. The second time pre_get_posts fires, which happens when there's at least 2 queries, everything will be set as expected. I was testing it with a version of 2015 that didn't have the menu configured, or any widgets in the sidebar, so it was failing for me. As soon as I added anything to the page that created another query, it worked fine and dandy. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment