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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 timepre_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!