Today I’ve written a short tutorial to show you how to leverage pods framework pre-save filter in order to automatically get address coordinates using Google geocoding functionalities.
Prerequisites:
- Google geocoding API documentation
- My previous tutorial about actions and filters
As I stated in previous post – most of my tutorials code will be hosted on GitHub to allow me (and hopefully you too) to update all of the code snippets in more efficient manner. At the same time I would like to paste the code here too for all non-github users and not to force you to jump between sites. I will try to keep both versions the same but please head to my GitHub repository for the newest version of the snippet.
How to use it?
- Add two fields to your pod – one for the address and second one for automatically generated coordinates.
- Go to my GitHub repository or copy code from down below.
- Put the code into your theme’s functions.php file or to your custom UI plugin.
- Replace %%podname%%, %%address_field_name_here%%, %%coordinates_field_name_here%% with the proper values (your pod name, name of your address field, name of your coordinates field).
- And that should be it.
I have few address fields in my pod, what now?
If you keep address separated in your pod then you can still use the code with just slight modification:
//concatenate all of your address fields into one
//please remember about cleaning those values first using trim() and / or other string functions.
$address = $pieces['fields']['street']['value'] . ' ' . $pieces['fields']['city']['value'] . ' ' . $pieces['fields']['state']['value'] . ' ' . $pieces['fields']['country']['value'];
$address = urlencode( strtolower( trim($address)));
Please remember about removing the if statement in such case (the one checking if the address field exists). Also it would be good to sanitize user input to be sure that our request url is nice and clean
Why there are two filters in the code?
If you take a closer look into the code you will see that I’ve used two filters in there. The first one is responsible for our core functionality and calls nice lady from Google to get coordinates from her ;). The second one is just small function which uses a little bit dirty code to make coordinates field disabled – so the user will not be able to modify the values.
Full filter code
/**
* Simple geocode snippet to use as pre save filter
* Author: Kamil Grzegorczyk
* Version: 1.0
* Author URI: http://api.lowgravity.pl
*
* TODO: add JS functionality to display map frame and drop marker using mouse, display current coordinates on map
*
* !!!README!!!
* Remember to exchange:
* %%podname%%, %%address_field_name_here%%, %%coordinates_field_name_here%%
* with correct names of your pods and its fields
*
* If you would like to use multiple address fields then just please concatenate them into one address string. The rest of the process stays the same.
*
*/
add_filter('pods_api_pre_save_pod_item_%%podname%%','lowgravity_geo_pre_save',10,2);
add_filter('pods_form_ui_field_text', 'lowgravity_disable_coordinates_field', 10, 6);
function lowgravity_geo_pre_save($pieces, $is_new) {
$address_field_name = '%%address_field_name_here%%';
$coordinates_field_name = '%%coordinates_field_name_here%%';
//checking if our address field exists
if(isset($pieces['fields'][$address_field_name])) {
//parsing data
$address = urlencode( strtolower( trim($pieces['fields'][$address_field_name]['value'])));
} else {// otherwise do nothing
return $pieces;
}
//preparing url
$geourl = "http://maps.google.com/maps/api/geocode/json?address=". $address ."&sensor=false";
//get the geocoded info from Google
$geoinfo = wp_remote_get($geourl);
//default value for coordinates field
$coordinates = 'Unable to automatically detect coordinates';
//if the response is OK
if( "OK" == $geoinfo['response']['message'] ) {
$json_obj = json_decode($geoinfo['body']);
$coordinates = $json_obj->results[0]->geometry->location->lat . ',' . $json_obj->results[0]->geometry->location->lng;
}
$pieces['fields'][$coordinates_field_name]['value'] = $coordinates;
//returning data
return $pieces;
}
function lowgravity_disable_coordinates_field($output, $name, $value, $options, $pod, $id) {
//as this filter is assigned to each text field we need to filter the ones we need
if( strstr( $name, '%%coordinates_field_name_here%%' )) {
$output = '<em>This field will be autogenerated from your address</em>' . str_replace('<input', '<input disabled=disabled', $output);
return $output;
}
return $output;
}