Hey everyone! I need help with a WordPress query issue that’s been driving me crazy for weeks.
I’m working on a directory site using custom post types. The site has a search feature where users can look for businesses by location, and results get sorted by how close they are. But I also have premium listings that should appear first, even if they’re not the closest match.
Right now I have this code that handles the location sorting:
static function modify_query_clauses( $clauses, $query_obj ) {
extract(get_location_parameters());
global $wpdb;
$location_query = $query_obj->get( 'custom_geo_query' );
if ( !$location_query )
return $clauses;
extract( $location_query, EXTR_SKIP );
$radius_calc = 'mi' == $measurement ? 3959 : 6371;
$clauses['join'] .= $wpdb->prepare( " INNER JOIN (
SELECT post_id, ( %d * acos( cos( radians(%f) ) * cos( radians(latitude) ) * cos( radians(longitude) - radians(%f) ) + sin( radians(%f) ) * sin( radians(latitude) ) ) ) AS proximity FROM $wpdb->custom_locations
) as proximity_data ON ($wpdb->posts.ID = proximity_data.post_id)
", $radius_calc, $latitude, $longitude, $latitude );
$clauses['where'] .= $wpdb->prepare( " AND proximity < %f", (float) $search_radius );
if ( 'proximity' == $query_obj->get( 'orderby' ) ) {
$clauses['orderby'] = 'proximity ' . ( 'DESC' == strtoupper( $query_obj->get( 'order' ) ) ? 'DESC' : 'ASC' );
}
return $clauses;
}
And I have another piece that handles premium sorting:
function modify_search_query( $query_obj ) {
global $theme_settings, $wpdb;
$query_obj->set( 'search_term', trim( get_query_var( 'search_term' ) ) );
$query_obj->set( 's', get_query_var( 'search_term' ) );
$query_obj->set( 'post_type', BUSINESS_POST_TYPE );
$query_obj->set( 'posts_per_page', $theme_settings->results_per_page );
if ( '' == $query_obj->get( 'order' ) )
$query_obj->set( 'order', 'asc' );
$sort_method = $query_obj->get( 'orderby' );
switch ( $sort_method ) {
case 'premium':
default:
$query_obj->set( 'meta_key', PREMIUM_LISTING_KEY );
$query_obj->set( 'orderby', 'meta_value_num' );
$query_obj->set( 'order', 'desc' );
break;
case 'proximity':
break;
}
}
I can’t figure out how to combine both sorting methods so premium listings show up first within the distance results. I tried setting multiple meta keys and orderby arrays but nothing works. Anyone have ideas on how to make this work together?