Skip to main content
commenting the code
Source Link
mrwweb
  • 10.3k
  • 5
  • 40
  • 75
//* function wc_add_latlong()
 * take address from post, geocode it, and save as a custom meta field
 * @parameter $post_id, id of the post being saved, passed by save_post hook
 * @returns nothing
 **************************************/
function wc_add_latlong( $post_id ) {
    // get the address from ACF field
    $address = urlencode( get_field( 'wc_map_address', $post_id ) );
    // Check to see if the post type is right, it's not a revision, and there is an address to geocode
    if( get_post_type( $post_id ) == 'wc_biz' && !wp_is_post_revision( $post_id ) && $address ) {
        // call the geocoder class below
        $coords = geocoder::getLocation( $address );
        // split latLngObject with a comma and space
        $lat_long_string = $coords['lat'] . ', ' . $coords['lng'];
        // either add that value as a new post meta field OR update the existing one
        add_post_meta( $post_id, '_wc_lat_long', $lat_long_string, true ) || update_post_meta( $post_id, '_wc_lat_long', $lat_long_string );
    }
}
// This runs on the save_post hook
add_action( 'save_post', 'wc_add_latlong', 11 );

// Thank you Sergiy!
// http://erlycoder.com/45/php-server-side-geocoding-with-google-maps-api-v3
// a class to get the lat and long of an address _server-side_
class geocoder{
    // The base URL for a non-sensor json Google Geocode API request
    static private $url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=";

    static public function getLocation($address){
        // append URL-friendly address to base URL
        $url = self::$url.urlencode($address);
            // request the Geocode JSON object from Google
        $resp_json = wp_remote_get($url);
            // decode the body of the response
        $resp = json_decode( wp_remote_retrieve_body($resp_json), true );
            // make sure the remove_get was successful and it geocoded the address
        if( !is_wp_error( $resp_json ) && $resp['status']='OK' ) {
                // success! return the lat and long
            return $resp['results'][0]['geometry']['location'];
        }else{
                // we failed, return false
            return false;
        }
    }
}

UPDATE: I've commented all the code so you can understand what's going on. You'll have to adapt it from there.

// take address, geocode it, and save as a custom meta field
function wc_add_latlong( $post_id ) {
    $address = urlencode( get_field( 'wc_map_address', $post_id ) );
    if( get_post_type( $post_id ) == 'wc_biz' && !wp_is_post_revision( $post_id ) && $address ) {
        
        $coords = geocoder::getLocation( $address );
        $lat_long_string = $coords['lat'] . ', ' . $coords['lng'];
        add_post_meta( $post_id, '_wc_lat_long', $lat_long_string, true ) || update_post_meta( $post_id, '_wc_lat_long', $lat_long_string );
    }
}
add_action( 'save_post', 'wc_add_latlong', 11 );

// Thank you Sergiy!
// http://erlycoder.com/45/php-server-side-geocoding-with-google-maps-api-v3
// a class to get the lat and long of an address _server-side_
class geocoder{
    static private $url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=";

    static public function getLocation($address){
        $url = self::$url.urlencode($address);
       
        $resp_json = wp_remote_get($url);
        $resp = json_decode( wp_remote_retrieve_body($resp_json), true );

        if( !is_wp_error( $resp_json ) && $resp['status']='OK' ) {
            return $resp['results'][0]['geometry']['location'];
        }else{
            return false;
        }
    }
}
/* function wc_add_latlong()
 * take address from post, geocode it, and save as a custom meta field
 * @parameter $post_id, id of the post being saved, passed by save_post hook
 * @returns nothing
 **************************************/
function wc_add_latlong( $post_id ) {
    // get the address from ACF field
    $address = get_field( 'wc_map_address', $post_id );
    // Check to see if the post type is right, it's not a revision, and there is an address to geocode
    if( get_post_type( $post_id ) == 'wc_biz' && !wp_is_post_revision( $post_id ) && $address ) {
        // call the geocoder class below
        $coords = geocoder::getLocation( $address );
        // split latLngObject with a comma and space
        $lat_long_string = $coords['lat'] . ', ' . $coords['lng'];
        // either add that value as a new post meta field OR update the existing one
        add_post_meta( $post_id, '_wc_lat_long', $lat_long_string, true ) || update_post_meta( $post_id, '_wc_lat_long', $lat_long_string );
    }
}
// This runs on the save_post hook
add_action( 'save_post', 'wc_add_latlong', 11 );

// Thank you Sergiy!
// http://erlycoder.com/45/php-server-side-geocoding-with-google-maps-api-v3
// a class to get the lat and long of an address _server-side_
class geocoder{
    // The base URL for a non-sensor json Google Geocode API request
    static private $url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=";

    static public function getLocation($address){
        // append URL-friendly address to base URL
        $url = self::$url.urlencode($address);
            // request the Geocode JSON object from Google
        $resp_json = wp_remote_get($url);
            // decode the body of the response
        $resp = json_decode( wp_remote_retrieve_body($resp_json), true );
            // make sure the remove_get was successful and it geocoded the address
        if( !is_wp_error( $resp_json ) && $resp['status']='OK' ) {
                // success! return the lat and long
            return $resp['results'][0]['geometry']['location'];
        }else{
                // we failed, return false
            return false;
        }
    }
}

UPDATE: I've commented all the code so you can understand what's going on. You'll have to adapt it from there.

Source Link
mrwweb
  • 10.3k
  • 5
  • 40
  • 75

I recently had almost the exact same use case:

  • On saving a custom post type, check for the existance of some meta data.
  • If it exists, geocode it using the Google Geocode API.
  • Save the result as a new meta field (this one hidden so the user can't screw it up).
  • Note: What I do with the data on the front end of the site is handled in a template file using javascript and the Google Maps API.

It looks like you're assembling multiple fields to get the address (I stored it in one) and you're saving the resulting format differently, but hopefully this serves as a good example that you can borrow from. As I always try to do, I used the WordPress API functions for querying and saving to the database. It's mores secure and future-proof.

Just as @OriginalEXE suggests, I used the save_post hook. I don't think you need publish_post:

save_post is an action triggered whenever a post or page is created or updated, which could be from an import, post/page edit form, xmlrpc, or post by email.

A few more notes:

  • Note the lower priority of the action. I found that leaving it as the default priority left it looking at the previously saved data (which is saved using Advanced Custom Fields which it looks like you're using).
  • The geocoding class was not mine and saved me a huge amount of time. I modified what Sergiy published to use the wp_remote_get() function that has better server support than either curl or file_get_contents. It uses the JSON (Google-recommended) request rather than XML.

I put this in a functionality plugin, but it would work the same in functions.php:

// take address, geocode it, and save as a custom meta field
function wc_add_latlong( $post_id ) {
    $address = urlencode( get_field( 'wc_map_address', $post_id ) );
    if( get_post_type( $post_id ) == 'wc_biz' && !wp_is_post_revision( $post_id ) && $address ) {
        
        $coords = geocoder::getLocation( $address );
        $lat_long_string = $coords['lat'] . ', ' . $coords['lng'];
        add_post_meta( $post_id, '_wc_lat_long', $lat_long_string, true ) || update_post_meta( $post_id, '_wc_lat_long', $lat_long_string );
    }
}
add_action( 'save_post', 'wc_add_latlong', 11 );

// Thank you Sergiy!
// http://erlycoder.com/45/php-server-side-geocoding-with-google-maps-api-v3
// a class to get the lat and long of an address _server-side_
class geocoder{
    static private $url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=";

    static public function getLocation($address){
        $url = self::$url.urlencode($address);
       
        $resp_json = wp_remote_get($url);
        $resp = json_decode( wp_remote_retrieve_body($resp_json), true );

        if( !is_wp_error( $resp_json ) && $resp['status']='OK' ) {
            return $resp['results'][0]['geometry']['location'];
        }else{
            return false;
        }
    }
}