Hi i understand that geo location search will show listings based on nearest first from the set radius. But to make the search more relevant i will need to have geo location search tweaked. For example a user search for a location it shows 100 results. I need these results to show newest listings first rather than nearest first. In this way i will show relevant results + fresh listings first rather than just showing results solely based on distance of location that might be months old.
Hi,
Thanks for your suggestion, we’ll consider adding this feature.
Please clarify whether you need sorting by date only or a combination of two criteria. Also, if you are familiar with coding, you can check this link where this order is specified: hivepress-geolocation/includes/components/class-geolocation.php at master · hivepress/hivepress-geolocation · GitHub
Thanks for your reply. I will look into it and if i find a solution will post it here for others that are looking for the same
a combination of radius based geolocation search + date sorting
This is the code you can use to sort listing by date after radius. Hope it helps
add_action( 'pre_get_posts', function( $query ) {
if (
! is_admin() &&
$query->is_main_query() &&
$query->is_search() &&
$query->get( 'post_type' ) === 'hp_listing' &&
isset( $_GET['location'], $_GET['latitude'], $_GET['longitude'] )
) {
add_filter( 'posts_orderby', 'custom_hp_hybrid_sort', 100, 2 );
}
});
function custom_hp_hybrid_sort( $orderby, $query ) {
global $wpdb;
$latitude = round( floatval( $_GET['latitude'] ), 6 );
$longitude = round( floatval( $_GET['longitude'] ), 6 );
if ( $latitude < -90 || $latitude > 90 || $longitude < -180 || $longitude > 180 ) {
return $orderby;
}
$aliases = [];
if ( isset( $query->meta_query ) && method_exists( $query->meta_query, 'get_clauses' ) ) {
foreach ( $query->meta_query->get_clauses() as $clause ) {
if ( isset( $clause['key'] ) && in_array( $clause['key'], [ 'hp_latitude', 'hp_longitude' ] ) ) {
$key = str_replace( 'hp_', '', $clause['key'] );
$aliases[ $key ] = $clause['alias'];
}
}
}
if ( count( $aliases ) < 2 ) {
return $orderby;
}
// Hybrid formula: distance squared * 0.6 + days_since_posted * 0.4
$orderby = $wpdb->prepare(
"((POW({$aliases['latitude']}.meta_value - %f, 2) + POW({$aliases['longitude']}.meta_value - %f, 2)) * 0.6) + (DATEDIFF(NOW(), {$wpdb->posts}.post_date) * 0.4) ASC",
$latitude,
$longitude
);
return $orderby;
}
Hi,
Thank you for your solution, it will be useful for our community.
Hi Andrii, how do i make this an option in the filter. So users can toggle between distance / newest first
Hi,
Please clarify, do you want to add a filter based on an attribute or based on some other data such as distance / newest first?
i want to have the code snippet given earlier as an option at filter form
I have figured it out. For those who wants to have an option for your users to sort newest listing first in the sorting drop down apart from distance sorting you can use this code
// 1. Add “Newest first” option to the HivePress sort dropdown
add_filter('hivepress/v1/forms/listing_sort', function($form) {
$form['fields']['_sort']['options']['hybrid'] = __('Newest first', 'hivepress');
return $form;
}, 1000);
// 2. Apply hybrid sort when "Newest first" is selected
add_action('pre_get_posts', function($query) {
if (
!is_admin() &&
$query->is_main_query() &&
$query->get('post_type') === 'hp_listing' &&
$query->is_search() &&
isset($_GET['_sort']) && $_GET['_sort'] === 'hybrid'
) {
if (isset($_GET['location'], $_GET['latitude'], $_GET['longitude'])) {
add_filter('posts_orderby', 'custom_hp_hybrid_sort', 100, 2);
}
}
});
// 3. Define hybrid distance + recency sorting logic
function custom_hp_hybrid_sort($orderby, $query) {
global $wpdb;
$latitude = round(floatval($_GET['latitude']), 6);
$longitude = round(floatval($_GET['longitude']), 6);
if ($latitude < -90 || $latitude > 90 || $longitude < -180 || $longitude > 180) {
return $orderby;
}
$aliases = [];
if (isset($query->meta_query) && method_exists($query->meta_query, 'get_clauses')) {
foreach ($query->meta_query->get_clauses() as $clause) {
if (isset($clause['key']) && in_array($clause['key'], ['hp_latitude', 'hp_longitude'])) {
$key = str_replace('hp_', '', $clause['key']);
$aliases[$key] = $clause['alias'];
}
}
}
if (count($aliases) < 2) {
return $orderby;
}
// Hybrid sorting formula: (distance squared * 0.9) + (days since posted * 0.1)
$orderby = $wpdb->prepare(
"((POW({$aliases['latitude']}.meta_value - %f, 2) +
POW({$aliases['longitude']}.meta_value - %f, 2)) * 0.9) +
(DATEDIFF(NOW(), {$wpdb->posts}.post_date) * 0.1) ASC",
$latitude,
$longitude
);
return $orderby;
}
Thank you for the solution!
This will be very helpful for our community.
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.