The problem:
If you create some new posts with integrated google map using ACF, there is no way to make WP_Query to search posts within some latitude and longitude range.
Problem is that data saved by ACF is like this example:
Array ( [address] => Leicester, United Kingdom [lat] => 52.6368778 [lng] => -1.1397591999999577 )
Since entire data is saved as a single post meta value it is impossible to do search between two values.
Second problem I came up to is, if I save data manually into two post meta fields eg: lat_field, lng_field, you cannot get correct posts with WP Query.
The reason for this I believe is because postmeta table value field is of type ‘Longtext’.
Even if I try to do query as ‘Decimal’ field, it still returns wrong results.
The solution
Because of this, I came up with solution by creating custom table where I store lat/lng in correct database column type.
Following steps are required to make this possible:
- Create custom database table, with 3 columns: post_id, lat, lng
- Create helper functions to easily insert/update/delete data in custom table
- Update data in custom table on every post save or edit
- Make custom SQL query to retrieve posts
- Display posts in standard WP Loop
Let’s get to work
First of all, initial setup is to have Advanced Custom Fields plugin, and create new ‘Google map’ field for your post type you wish to geo locate.
1. Create new database table
/** * Create Database table for geodata */ global $my_db_version; $my_db_version = '1.1'; function my_install() { global $wpdb; global $my_db_version; $table_name = $wpdb->prefix . 'my_geodata'; /* * We'll set the default character set and collation for this table. * If we don't do this, some characters could end up being converted * to just ?'s when saved in our table. */ $charset_collate = ''; if ( ! empty( $wpdb->charset ) ) { $charset_collate = "DEFAULT CHARACTER SET {$wpdb->charset}"; } if ( ! empty( $wpdb->collate ) ) { $charset_collate .= " COLLATE {$wpdb->collate}"; } $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, post_id BIGINT NULL UNIQUE, lat DECIMAL(9,6) NULL, lng DECIMAL(9,6) NULL, UNIQUE KEY id (id) ) $charset_collate;"; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); dbDelta( $sql ); add_option( 'my_db_version', $my_db_version ); } function my_geodata_update_db_check() { global $my_db_version; if ( get_site_option( 'my_db_version' ) != $my_db_version ) { my_install(); } } add_action( 'init', 'my_geodata_update_db_check' );
2. Helper functions
These are helper functions that will make it easy to insert/update/delete data into custom database table we created above
/** * Insert geodata into table */ function insert_geodata( $data ) { global $wpdb; $table_name = $wpdb->prefix . 'my_geodata'; //Check date validity if( !is_float($data['lat']) || !is_float($data['lng']) || !is_int($data['post_id']) ) return 0; $wpdb->insert( $table_name, array( 'post_id' => $data['post_id'], 'lat' => $data['lat'], 'lng' => $data['lng'], ), array( '%d', '%f', '%f' ) ); } /** * Checks if entry for post_id exists */ function check_geodata($post_id) { global $wpdb; $table_name = $wpdb->prefix . 'my_geodata'; //Check date validity if( !is_int($post_id) ) return 0; $sql = "SELECT * FROM $table_name WHERE post_id = $post_id"; $geodata = $wpdb->get_row($sql); if($geodata) { return true; } } /** * Delete entry for post_id */ function delete_geodata($post_id) { global $wpdb; $table_name = $wpdb->prefix . 'my_geodata'; //Check date validity if( !is_int($post_id) ) return 0; $delete = $wpdb->delete( $table_name, array( 'post_id' => $post_id ) ); return $delete; } /** * Update existing */ function update_geodata($data) { global $wpdb; $table_name = $wpdb->prefix . 'my_geodata'; //Check date validity if( !is_float($data['lat']) || !is_float($data['lng']) || !is_int($data['post_id']) ) return 0; $wpdb->update( $table_name, array( 'lat' => $data['lat'], 'lng' => $data['lng'], ), array( 'post_id' => $data['post_id'], ), array( '%f', '%f' ) ); } /** * Insert or update current post geodata */ function add_geodata( $data ) { global $wpdb; //Check date validity if( !is_float($data['lat']) || !is_float($data['lng']) || !is_int($data['post_id']) ) return 0; /** * Check if geodata exists and update if exists else insert */ if( check_geodata( $data['post_id'] ) ) { update_geodata( $data ); } else { insert_geodata( $data ); } }
3. Update data in custom table on every post save or edit
To update data in custom table I have decided to create custom function.
This is standard WP Query that will get all posts, then loop trough and save required data into custom table.
To make this little bit more optimised I will use WP Transient and run check every one hour.
Transient will also be deleted on every post edit/save so it will update data every time you edit or create new post.
I have decided to do it like this because to access post meta created by ACF you need to use field ID instead of field name you selected.
/** * Loop trough all clinics and update geodata in custom table */ function update_post_geodata() { $args = array( 'posts_per_page' => -1, 'post_type' => 'post', ); $posts = get_posts( $args ); if($posts): foreach($posts as $item): $tables = get_field('tables', $item->ID); $address = get_field('address', $item->ID); /** * Update Lat/Lng for every clinic */ $id = (int) $item->ID; $lat = (float) $address['lat']; $lng = (float) $address['lng']; if( $address ): $data = array( 'post_id' => $id, 'lat' => $lat, 'lng' => $lng ); add_geodata( $data ); endif; endforeach; endif; }
Create Transient
As mentioned above, I have created Transient that runs every hour and executes our function for updating data in custom table.
Also, I delete this transient on every post edit/save, so first refresh of page after that will again execute function.
/** * Transient for locations * Run update post geodata every hour */ if ( false === ( $update_geodata = get_transient( 'locations_update_geodata' ) ) ) { update_post_geodata(); set_transient( 'locations_update_geodata', $update_geodata, 1 * HOUR_IN_SECONDS ); } // Create a simple function to delete our transient function delete_transient() { delete_transient( 'locations_update_geodata' ); } // Add the function to the edit/save post hook so it runs when posts are edited add_action( 'save_post', 'delete_transient' ); add_action( 'edit_post', 'delete_transient' );
Find your lat/lng radius
Next thing we will need is to calculate radius from desired location.
To use that I have found helpful function on stackoverflow (where eles?).
function bar_get_nearby( $lat, $lng, $limit = 50, $distance = 50, $unit = 'mi' ) { // radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius' if( $unit == 'km' ) { $radius = 6371.009; } elseif ( $unit == 'mi' ) { $radius = 3958.761; } // latitude boundaries $maxLat = ( float ) $lat + rad2deg( $distance / $radius ); $minLat = ( float ) $lat - rad2deg( $distance / $radius ); // longitude boundaries (longitude gets smaller when latitude increases) $maxLng = ( ( float ) $lng + rad2deg( $distance / $radius) ) / cos( deg2rad( ( float ) $lat ) ); $minLng = ( ( float ) $lng - rad2deg( $distance / $radius) ) / cos( deg2rad( ( float ) $lat ) ); $max_min_values = array( 'max_latitude' => $maxLat, 'min_latitude' => $minLat, 'max_longitude' => $maxLng, 'min_longitude' => $minLng ); return $max_min_values; }
This function will return min/max values for latitude and longitude, and these are the values in between we will do search.
Custom SQL Query
This code goes into page template file, where we want to display our results.
Comments are inline, be sure to check them.
global $wpdb, $paged, $max_num_pages; /** * Get current paged value, for pagination */ if ( get_query_var('paged') ) { $paged = get_query_var('paged'); } else if ( get_query_var('page') ) { $paged = get_query_var('page'); } else { $paged = 1; } /* * Get option from settings, how many posts per page to display */ $post_per_page = get_option( 'posts_per_page' ); /* * Calculate offset for pagination */ $offset = ($paged - 1)*$post_per_page; /* * Define variables */ $sort = 'ASC'; // Sort posts $range = 10; // Range within x miles, default is 10 $search_lat = false; // Latitude $search_lng = false; // Longitude $table_name = $wpdb->prefix . 'my_geodata';
Simple SQL query
Create simple sql query that will retrieve all posts, and then if latitude and longitude are set expand the query to search within range.
Simple query will return all results if no latitude/longitude is specified.
Comments on code are inline.
/* * Construct basic SQL query * Query will return all posts sorted by post title */ $sql_query = "SELECT SQL_CALC_FOUND_ROWS * FROM $wpdb->posts"; $sql_join = " INNER JOIN $table_name AS geo ON ($wpdb->posts.ID = geo.post_id)"; $sql_where = " WHERE ($wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type = 'post')"; $sql_group = " GROUP BY {$wpdb->posts}.ID"; $sql_order = " ORDER BY $wpdb->posts.post_title $sort"; $sql_limit = " LIMIT $offset, $post_per_page"; /* * If latitude and longitude are defined expand the SQL query */ if( $search_lat && $search_lng ) { /* * Calculate range * Function will return minimum and maximum latitude and longitude */ $minmax = bar_get_nearby( $search_lat, $search_lng, 0, $range ); /* * Update SQL query */ $sql_where .= " AND ( ( (geo.lat BETWEEN '$minmax[min_latitude]' AND '$minmax[max_latitude]') AND (geo.lng BETWEEN '$minmax[min_longitude]' AND '$minmax[max_longitude]') ) OR ( terms.term_taxonomy_id = '$search_id') OR ( parent.parent = '$search_id') )"; } /* * Construct SQL query and get results */ $sql = $sql_query . $sql_join . $sql_where . $sql_group . $sql_order . $sql_limit; $query = $wpdb->get_results($sql, OBJECT);
Standard WP loop
After query is run, we can do standard WP loop, loop trough posts and display them on page
/* * Calculate pagination */ $sql_posts_total = $wpdb->get_var( "SELECT FOUND_ROWS();" ); $max_num_pages = ceil($sql_posts_total / $post_per_page); if ( $query ): /** * Loop trough posts */ global $post; foreach ($query as $post): setup_postdata($post); the_title(); the_excerpt(); echo '<hr>'; endforeach; /** * No results */ else: ?> <h2>No Posts Found</h2> <?php endif; wp_reset_postdata(); ?>
Conclusion
That’s all folks, you have done it.
I have cut down the markup and tried to make it as less code as possible but again to keep all relevant things in place.
Hope you find this post helpful, if you have any questions, well you know what comments are used for…
Thanks, it works.
Cheers
I highly appreciate this, just saved me days of programming and figuring out how ACF fully works internally. Thank you.
Glad you found it helpful.
Cheers
Hi! This looks like something I could really use! However my setting is slightly different. I’ve stored long and lat values with ACF without the google maps field. The thing I need is that when a user searches for a ZIP code or city, posts get listed within a certain range. Is this possible with this script? If so, could you help me to steer me into the right direction?
I’d really appreciate your help!
Hi Bart,
You should check geocoding.
First you need to translate Address or ZIP into lat/lng and then search within that radius.
Cheers
Hi!Sorry for my bad English! I think that this tutorial is soo good and soo clear. But i don’t understand a “little” thing: where i must copy the code that you write in this tutorial (which file = function.php ?).
Thanks
Sir Plz provide me a zip file for this code
Brilliant! Will this work I don’t use ACF?
Thanks. Well it depends on your setup and how you store lat/long values.
Just thought I would share a quick note – the function that Bobz pulled from Stackoverflow is actually a little off and won’t calculate the radius correctly. It’s noted a couple responses under the link to Stackoverflow that Bobz posted, but the correct function is:
function bar_get_nearby( $lat, $lng, $limit = 50, $distance = 50, $unit = ‘mi’ ) {
// radius of earth; @note: the earth is not perfectly spherical, but this is considered the ‘mean radius’
if( $unit == ‘km’ ) { $radius = 6371.009; }
elseif ( $unit == ‘mi’ ) { $radius = 3958.761; }
// latitude boundaries
$maxLat = ( float ) $lat + rad2deg( $distance / $radius );
$minLat = ( float ) $lat – rad2deg( $distance / $radius );
// longitude boundaries (longitude gets smaller when latitude increases)
$maxLng = ( float ) $lng + rad2deg( $distance / $radius) / cos( deg2rad( ( float ) $lat ) );
$minLng = ( float ) $lng – rad2deg( $distance / $radius) / cos( deg2rad( ( float ) $lat ) );
$max_min_values = array(
‘max_latitude’ => $maxLat,
‘min_latitude’ => $minLat,
‘max_longitude’ => $maxLng,
‘min_longitude’ => $minLng
);
return $max_min_values;
}
GREAT, AWESOME post Bobz, saved me hours if not days as well. THANK YOU!
Thanks, I will check the function you posted and update my post.
Glad you found it helpful.
Hello Bobz,
thanks a lot for your work, seems to be exactly what i am looking for. But unfortunately i dont know where to put this code in. How can i use this code to create a new database table for example? Could you send me the whole package as a zip file?
Best regards,
Uwe
Just save everything in a file and include it in functions.php
Hi Bobz,
Once again, thanks for all the great work with this.
Quick question – have you ever come across the need to return the results ordered by closest location. I’ve been trying to figure out a way to accomplish this and been a bit stuck.
Hi, I’m sorry but I haven’t got this situation.
Maybe something like this:
A: https://developers.google.com/maps/documentation/distancematrix/#DistanceMatrixResponses
B: http://www.geocodezip.com/v3_GoogleEx_place-search.html
Eg:
1. Get results from db lat/lng
2. Query Google Maps API to calculate distance
I just used this and updated the line where $sql_query and $sql_order variables are defined with the code below
$sql_query = “SELECT SQL_CALC_FOUND_ROWS *, 3956 * 2 * ASIN(SQRT(POWER(SIN(($search_lat – abs(geo.lat)) * pi()/180 / 2),2) + COS($search_lat * pi()/180 ) * COS( abs(geo.lat) * pi()/180) * POWER(SIN(($search_lng – geo.lng) * pi()/180 / 2), 2) )) as distance FROM $wpdb->posts”;
$sql_order = ” ORDER BY distance, $wpdb->posts.post_title $sort”;
Thanks for share Andres
Hello,
I get a:
Cannot redeclare delete_transient() (previously declared in /var/www/vhosts/xxx/wp-includes/option.php:547) in /var/www/vhosts/xxxt/wp-content/themes/aust/inc/maps.php on line 219
Is tehre any adivce on this?
Thanks!
P.
Check maps.php on line 219.
You have declared same function twice.
No, just pasted yout script ?
Errors don’t lie.
Rename the function then in maps.php on line 219. to something else then delete_transient
You are right! But I don’t understand why there is nobody here with the same error, because In options.php (which is a WP core file) since WP 2.8 a function with the name “delete_transient” exists. Perhaps a PHP version issue ?
I agree, strange thing.
This is why prefixing functions is always best practice. Shame on me!
This saved me days of research and work. Thank you! Would you consider accepting donations?
Glad you found it helpful, be sure to check comments below posts too, there is one update regarding radius function.
Hello, these set of functions work great. I’m running into an issue where I try and place all of this inside of functions.php, so I can retreive the users geolocation, then send that latitude and longitude using WordPress ajax method and it seems to be failing inside of functions.php at the line: $query = $wpdb->get_results($sql, OBJECT);
I know you included it on the page with the functions.php returning the $sql- that works just fine for me. However when the user on my page clicks a button which gets their geolocation, sends that value via ajax it seems that get_results is returning an empty object. Thanks for any help that you might provide in advance.
David
Try adding
global $wpdb
in place before you make sql query.Cheers
Hey Bobz, thanks for the reply! It’s not the case- I’ve declared the global variable, even flushed it, but it doesn’t seem to fix the problem. In your example you use the function get_results() in the template- this shouldn’t be a problem inside of functions.php where wpdb can just as easily be accessed.
Where I think this might be failing is the sql- I pass the search_lat and search_lng via WordPress ajax method, and I think something about the sql script fails in get_results. Also, you have a varialble in that sql script called search_id- I wanted to omit that line about the OR ( terms.term_taxonomy_id = ‘$search_id’) OR ( parent.parent = ‘$search_id’) and wonder if that would help at all.
Thanks,
David
Hi David, it would be best if you print_r your $sql and then run the query alone to see what you get.
Thing is i’m looking up the ‘posts’ in the same category.
Check the comment by CN below to see some update about function.
Thanks for pointing me in the right direction Bobz. Here’s my snippet- I ran this in my template page and its returning a blank page minus the header. Im pretty sure something in this script is breaking. I have modified a the post_type and I’ve added lat and longitude for a search where I know it should return at least one result. Does anything look funky to you in this sql script? Thanks again.
get_results($sql, OBJECT);
print “”;
print_r($query);
print “”;
?>
Sorry, here’s a link to show this snippet: http://codepad.org/tZGE9aM2
Ok Im getting somewhere, I got it to print out an error, it says: WordPress database error: [Unknown column ‘terms.term_taxonomy_id’ in ‘where clause’]. I don’t have a table named terms. I do have a table, with my prefix of course called dev_term_taxonomy, and inside it I have a column called term_taxomomy_id. Inside of my terms table I also have no such column of term_taxonomy_id. I’m still unsure what this part of the script is doing and why it’s necessary. I’d really appreciate your advisement.
David
Hi David,
Looks like a mine mistake in the example provided, you shoud use $wpdb->terms.term_taxonomy_id.
It is getting posts for a specific term only, so if you are looking for example for taxonomy ‘Shops’ and term ‘Sportware’, meaning you want to get only shops that sell sport clothing.
If you don’t need this kind of filtering and you want to get all posts within coordinates you can ommit the taxonomy filtering part.
And a note, you should alwasy have debug mode off and you should always print_r what you get as result and you should always test your sql in some sql app.
After you get desired result in sql app, then it’s easy to turn that into working function.
And regarding the error you sent, take care of your quotes and double quotes in sql by escaping where needed.
BR
Vlado
Hi Bobz,
Thank you for posting this, it’s saved me a lot of time having to come up with this myself. I’m just having one small problem where the filtering doesn’t seem to be working if I pass a Lat & Lng into the define variables section. I have it pulling back all the posts from my custom post type (which is cinemas), I just need it to filter so that I can use a search function to dynamically update those fields at the next stage.
/*
* Define variables
*/
$sort = ‘ASC’; // Sort posts
$range = 300; // Range within x miles, default is 10
$search_lat = 55.958154; // Latitude
$search_lng = -3.188905; // Longitude
$table_name = $wpdb->prefix . ‘my_geodata’;
Hi Jason,
It’s been a long time from the post, but as far I remember, if I save lat/lng into postmeta table, then the search doesn’t work. I have spent some time testing that and it turned out it’s because of data type, and I was not able to make it work with CAST.
This is why I decided to create custom table for storing lat/lng values with proper data types for both columns.
Secondly, to populate that column I hooked into ‘save_post’ / ‘edit_post’ so I can create/update data in custom table every time post is created or edited.
Basically this is what’s going on in my article.
Secondly regarding your issue, it’s difficult for me to say what might be wrong.
I would recommend to test your query in some sql app (like sequel / phpmyadmin ) and find the correct syntax for your case.
hope it helps
BR
Vlado
I’d like to post a full bit of code that’s working flawlessly on a few websites i manage. Some websites use Types plugin and other use ACF.
In Types i set up 2 fields for Lat and Lng, and of course is far more easy, but you know clients are not aware how to extract Lat and Lng from google maps when doing data entry, so i worked a bit and came up with ACF alternative, which on one side is easier to use, especially when adding a map to the Custom Fields, on the other side is harder to extract those values.
Anyway by googling all around i came up with this code, taking pieces of it here and there. It definitely works, all you have to change is the Custom post type in the args (mine was ‘apartment’), and some other values for the html part for pop up window. Please have a look. Cheers
//Array of JSON objects.
var markers = [ -1,
‘post_type’ => ‘apartment’,
‘orderby’ => ‘rand’
);
// query
$the_query = new WP_Query( $args );
if( $the_query->have_posts() ):
$myarray = array();
while( $the_query->have_posts() ) : $the_query->the_post();
global $post;
$location = get_post_meta($post->ID, ‘posizione_mappa’, true); //this will extract the map position array, change posizione_mappa to your ACF gmaps field name
$mylat = $location[‘lat’]; //this wil fetch for previous array only Latitude value
$mylng = $location[‘lng’]; //this wil fetch for previous array only Longitude value
$mytitle = get_post_meta ($post->ID, ‘citta’, true); //change citta to your field name
$myaddress = get_post_meta($post->ID, ‘wpcf-tipologia’, true); //change wpcf-tipologia to your field name
$post_thumbnail_id = get_post_thumbnail_id($recent[‘ID’]);
$post_thumbnail_url = wp_get_attachment_image_src($post_thumbnail_id, ‘medium’ );
$post_map_image = ”;
if ( has_post_thumbnail() ) {
$thumb_id = get_post_thumbnail_id();
$thumb_url_array = wp_get_attachment_image_src($thumb_id, ‘homepage-tiles’, true);
$thumb_url = $thumb_url_array[0];
}
$data_for_infowindow = ‘‘.$mytitle.’‘.$post_map_image.’‘.$myaddress.”;
$new_element = ‘{“title”: ”.get_post_meta($post->ID, ‘wpcf-titoloslider’, true).”,
“lat”: ”.$mylat.”,
“lng”: ”.$mylng.”,
“description”: ”.$data_for_infowindow.”}’;
array_push($myarray, $new_element);
endwhile;
echo implode(“,”,$myarray);
endif;
wp_reset_query();
?>
]; //here ends the JSON part
window.onload = function () {
LoadMap();
}
function LoadMap() {
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 17, // The initial zoom level when your map loads (0-20)
minZoom: 6, // Minimum zoom level allowed (0-20)
maxZoom: 20, // Maximum soom level allowed (0-20)
zoomControl:true, // Set to true if using zoomControlOptions below, or false to remove all zoom controls.
zoomControlOptions: {
style:google.maps.ZoomControlStyle.DEFAULT // Change to SMALL to force just the + and – buttons.
},
mapTypeId: google.maps.MapTypeId.ROADMAP, // Set the type of Map
scrollwheel: false, // Disable Mouse Scroll zooming (Essential for responsive sites!)
// All of the below are set to true by default, so simply remove if set to true:
panControl:false, // Set to false to disable
mapTypeControl:false, // Disable Map/Satellite switch
scaleControl:false, // Set to false to hide scale
streetViewControl:false, // Set to disable to hide street view
overviewMapControl:false, // Set to false to remove overview control
rotateControl:false // Set to false to disable rotate control
};
var infoWindow = new google.maps.InfoWindow();
var latlngbounds = new google.maps.LatLngBounds();
var map = new google.maps.Map(document.getElementById(“dvMap”), mapOptions);
for (var i = 0; i < markers.length; i++) {
var data = markers[i]
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title
});
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent("” + data.description + “”);
infoWindow.open(map, marker);
});
})(marker, data);
latlngbounds.extend(marker.position);
}
var bounds = new google.maps.LatLngBounds();
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
}
i noticed that a large amount of code has been cut out, how can i still post it in full version?
thanks
Hi, would you mind using pastebin or similar for sharing large portion of code please.
I did not understood your first comment well, you have some question regarding post, or you share some example solution?
Hi thanks very much!
I had to change two lines in the bar_get_nearby function to make it work for me.
$maxLng = ( float ) $lng + rad2deg( $distance / $radius) / cos( deg2rad( ( float ) $lat ) );
$minLng = ( float ) $lng – rad2deg( $distance / $radius) / cos( deg2rad( ( float ) $lat ) );
Good hint, otherwise calculation is wrong.
Thanks Bobz! Exactly what I’ve been searching for!
Henry
Cheers, glad I could help.
Thanks, you code is very usseful. You save many hours in my life.
Glad I can help.
Thank you so much! I tried this in 2017 and it still works. I had to do just a few adjustments.
Greetings from Brazil
Good to hear Rômulo.
Cheers
Rômulo, can you tell me what adjustments you have make?
This solution looks brilliant and is something I definitely need. Im just having some problems with it. I am getting this error on the page:
WordPress database error: [Table ‘fadc.wp_my_geodata’ doesn’t exist]
SELECT SQL_CALC_FOUND_ROWS * FROM wp_posts INNER JOIN wp_my_geodata AS geo ON (wp_posts.ID = geo.post_id) WHERE (wp_posts.post_status = ‘publish’ AND wp_posts.post_type = ‘post’) GROUP BY wp_posts.ID ORDER BY wp_posts.post_title ASC LIMIT 0, 10
And in my browser console it is giving me a “Uncaught SyntaxError: Unexpected indentifier” which it says is on line 4 which is this: global $my_db_version;
Any help would be appreciated. Thank you!
Still works in Feb 2018! However, first of all, a very big thanks for compiling this so thoroughly! It has been a very, very, very amazing help!
For those not sure where to add the code -> functions.php
Adjustments I had to make:
1. For “3. Update data in custom table on every post save or edit” -> change ‘posts’ to your post type
2. For “Create Transient” -> Rename the delete_transient function (and the actions), otherwise, it will throw a fatal error because this function has been declared already.
3. For “Simple SQL Query” -> Change AND $wpdb->posts.post_type = ‘post’)”; to your post type
4. Also for the “Simple SQL Query” section, remove the following from the ‘where’ clause when lat/lng has been set:
“OR ( terms.term_taxonomy_id = ‘$search_id’) OR ( parent.parent = ‘$search_id’)”
5. Change the radius calculation within the bar_get_nearby function for the longitude as following:
$maxLng = ( float ) $lng + rad2deg( $distance / $radius) / cos( deg2rad( ( float ) $lat ) );
$minLng = ( float ) $lng – rad2deg( $distance / $radius) / cos( deg2rad( ( float ) $lat ) );
Apart from that, it works perfectly fine! Thanks again.
I think the longitude calculations are wrong.
Here’s the corrected code:
Hi, thank you for your post!
I have a question
How I can join this new table to postmeta table, becouse I have a custom search, and three parameters by search – custom category taxonomy, custom tag taxonomy and ACF google map field
And I search by WP_query, and at this moment I dont have my new parameters from new table at WP_query
This my table http://prntscr.com/k8rhpj
And this http://prntscr.com/k8ri02 – postmeta table
Thank you!
2023 – Can’t quite get this to work.
I get as far as creating the DB table, but cannot get the data to pass through.