[Resolved] How to with Gabey D: Adding Location Filtering
-
Hello all,
I’ve seen some posts asking for this and never saw a full, complete guide on it so figure I’ll try again at making a contribution to the community. The below code is working for me with one caveat (that hopefully I’ll fix and post the solution to here).
So first off, we need a unified way of assessing location. The least sensitive yet least prone to error that I’ve found is zip code. Before I get ahead of myself though, here are the steps.
0. Make sure you have ‘geo_lat’ and ‘geo_meta’ keys set up. These are needed for the below code to work.
1. Get Zip Code
2. Get longitude and latitude from Zip Code using google geocoding API
3. Store lat and long (everytime a user updates zip code it updates these values)
4. Query database and order results by the distance from current userso here it is, all of this code is in functions.php:
add_action( 'bp_members_directory_order_options', 'mycred_pro_add_sorting_options' ); function mycred_pro_add_sorting_options() { ?> <option value="points-asc">Distance: Closest to me</option> <option value="points-desc">Distance: Farthest from me</option> <?php } add_action( 'bp_pre_user_query', 'mycred_pro_pre_user_query' ); function mycred_pro_pre_user_query( $BP_User_Query ) { // Only run this if one of our custom options is selected if ( in_array( $BP_User_Query->query_vars['type'], array( 'points-asc', 'points-desc' ) ) ) { global $wpdb, $scope; // Adjust SELECT $BP_User_Query->uid_clauses['select'] = " select distinct um.user_id, um.meta_value as latitude, um2.meta_value as longitude from wp_usermeta as um left join wp_usermeta as um2 on um.user_id=um2.user_id and um2.meta_key = 'geo_long' "; // Adjust WHERE $BP_User_Query->uid_clauses['where'] = "WHERE um.meta_key='geo_lat'"; //Additional Custom WHERE //You don't really need this part, I'm using it to make sure that my custom sort tabs don't stop working $ids_to_include = explode("=", $scope); $ids_to_include = explode(",",$ids_to_include[1]); $ids_string = ""; $id_count = 0; foreach($ids_to_include as $id){ if($id == ""){ continue; }else{ if($id_count == 0) $ids_string .= " AND (um.user_id = ".$id; else $ids_string .= " OR um.user_id = ".$id; $id_count++; } } if($ids_string != "") $ids_string .= ")"; $BP_User_Query->uid_clauses['where'] .= $ids_string; // Adjust ORDER BY $BP_User_Query->uid_clauses['orderby'] = "ORDER BY (((acos(sin((".get_user_meta(get_current_user_id(), "geo_lat",true)."*pi()/180)) * sin((latitude*pi()/180))+cos((".get_user_meta(get_current_user_id(), "geo_lat",true)."*pi()/180)) * cos((latitude*pi()/180)) * cos(((".get_user_meta(get_current_user_id(), "geo_long",true)."- longitude)*pi()/180))))*180/pi())*60*1.1515)"; // Adjust ORDER $BP_User_Query->uid_clauses['order'] = ( $BP_User_Query->query_vars['type'] == 'points-asc' ) ? 'ASC' : 'DESC'; echo '<script>console.log("'.$BP_User_Query->uid_clauses['where'].'");</script>'; } } function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'Mi') { $theta = $longitude1 - $longitude2; $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta))); $distance = acos($distance); $distance = rad2deg($distance); $distance = $distance * 60 * 1.1515; switch($unit) { case 'Mi': break; case 'Km' : $distance = $distance * 1.609344; } return (round($distance,2)); } function set_lat_long( $field_id, $value ){ global $bp; if($field_id == 36){ $url = "http://maps.googleapis.com/maps/api/geocode/json?address=".$value."&sensor=false"; $response = wp_remote_get($url); $geodata = json_decode($response['body'], true); $lat = $geodata["results"][0]["geometry"]["location"]["lat"]; $long = $geodata["results"][0]["geometry"]["location"]["lng"]; update_user_meta($bp->displayed_user->id, "geo_lat", $lat); update_user_meta($bp->displayed_user->id, "geo_long", $long); } } add_action( 'xprofile_profile_field_data_updated', 'set_lat_long', 1, 2 );
Hopefully I didnt forget anything. Feel free to edit it as you will, let me know if it doesn’t work – I may have forgotten to include one of the functions needed to make this work.
Also, as you can see the code that adds the filters to the drop down is from the MyCred author, Gabriel Merovingi so credit goes to him for that. I also found the data calculation somewhere online through google, don’t remember the exact author unfortunately 🙁
Enjoy!
If you figure out how to get the count (“Showing x out of y members”) let me know
- The topic ‘[Resolved] How to with Gabey D: Adding Location Filtering’ is closed to new replies.