Last active
September 5, 2024 01:51
-
-
Save tammyhart/138971bb9d1f97c30090 to your computer and use it in GitHub Desktop.
Traverse WordPress Search Results
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
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
TBH, it's been so long since I originally wrote this, I'm not sure where I got that method from. All I can say is that it does return the correct posts. you can unwrap it from the transient settings and print it out to see for yourself.