Support

Account

Home Forums Feature Requests Google Map & City Name

Solved

Google Map & City Name

  • Hello everyone,

    First, I would like to thank the ACF team for the wonderful plugin and add-ons ! I couldn’t have made my wordpress website without these tools.

    My question is about the Google Map field : I use it a lot, to create a map on which all the posts appear with data in Infowindow. It’s perfect for me to have the simple map field in the backoffice.

    Now, I would also like to give the opportunity to the visitors to chose a “list view” instead of a “map view”. To do this, I would like to order the posts by city name. I see 3 option to do this :
    – add a new field in the backoffice with a list of each city of the country (not a very good option)
    – add a function with reverse geocoding on the visitor side (the page already takes too long to load, i would like to avoid this)
    – add a function inside my field group, and do the reverse geocoding BEFORE the post is saved in the DB.

    I put my question in the “Feature Request” because I think it would be great to have the possibility to add a “PHP & JS Field” which would – in my case – get the Lat/Lng from the map, read it and add the city name in the db.

    There may be a way to do it in the meanwhile but I haven’t found it yet. Does anyone has an idea for this ?

    thanks a lot !

    Lucas

  • Okay, first, so you know, I don’t know anything about reverse geocoding, but it sounds like you do, so I’m hoping that my ignorance in this area doesn’t matter.

    Does this reverse geocoding need to be done with JavaScript or can it be done in PHP. I assume you’re connecting to the google API to do it? If this is possible you can create an acf/save_post action, http://www.advancedcustomfields.com/resources/acfsave_post/ and in that function get the saved map field, do the api call with PHP and then save the result into another field.

    Hopefully this is some help.

    ~JH

  • Hello John,

    thank you for your answer, I’ve gave it a try, but it didn’t work… I don’t really understand why. Am I supposed to insert the code in my theme’s functions.php ?

    Then do something like this …? :

    <?php
    
    function my_acf_save_post( $post_id ) {
        
        // bail early if no ACF data
        if( empty($_POST['acf']) ) {
            
            return;
            
        }
        
          
        // do things with the var, insert the data i am interested in
     
        $_POST['acf']['field_abc123'] = $my_array_with_data_i_want
    
        
    }
    
    // run before ACF saves the $_POST['acf'] data
    add_action('acf/save_post', 'my_acf_save_post', 1);
    
    ?>

    Is this the spirit ?
    If yes it doesn’t work, and I can’t figure out why…

  • Yes, that is the idea. It should be working as long as $_POST['acf']['field_abc123'] matches a field that ACF maintains and is associated with the post. field_abc123 needs to match the field key of the field where you want to save the data.

  • And do you have any idea why it wouldn’t work ?
    I’ve simplified as much as possible

    function my_acf_save_post( $post_id ) {
        
      
    	update_field( "field_5593bd8134102", "This is a test!", $post_id );
    }
    
    // run before ACF saves the $_POST['acf'] data
    add_action('acf/save_post', 'my_acf_save_post', 1);

    Then I got on a post, fill all the field, and publish the post but… “This is a test” never appears.
    This code is used in the theme’s functions.php

    Is there any previous step I may have missed ?

  • What happens if you do

    
    $_POST['acf']['field_5593bd8134102'] = 'This is a test!';
    

    also, is this a sub field of a repeater?

  • Thank you John, it eventually worked, here is my working code :

    
    <?php
    function reverse_geocoding($form_data) {
    	
    	
    	$latlng = $latlng = $_POST['fields']['field_123abcd-this-is-my-map-field']['lat'].','.$_POST['fields']['field_123abcd-this-is-my-map-field']['lng'];
    	
    	// set your API key here
    	$server_key = '*****';
    	
    	// format this string with the appropriate latitude longitude
    	$url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng='.$latlng.'&key='.$server_key.'&sensor=true&language=fr';
    	
    	// make the HTTP request
    	$data = @file_get_contents($url);
    	// parse the json response
    	
    	$jsondata = json_decode($data,true);
    	
    
    	if(is_array($jsondata )&& $jsondata ['status']=='OK') // this piece of code is looping through each component in ['address_components']
    	{
    		foreach ($jsondata['results'][0]['address_components'] as $comp) {
    			foreach ($comp['types'] as $currType){
    				// Here I get all the information I need and store it into vars
    				if($currType == 'administrative_area_level_2'){
    					$area_level_2 = $comp['long_name'];
    				}
    				if($currType == 'locality'){
    					$locality = $comp['long_name'];
    				}
    			}
    		}
    		
    	$coord = explode(",", $latlng);
    	
    	$loc_data = array('city' => $locality,
    					'area_level_2' => $area_level_2,
    					'lat' => $coord[0],
    					'lng' => $coord[1],
    					'zoom' => $zoom,
    					'address' => $form_data['field_556355e41efef']['address']);
    	}
    	
    	return $loc_data;
    	
    	
    }
    
    function acf_location_data( $post_id ) {
     
    		
    		$loc_data = reverse_geocoding($_POST['fields']); // I send all the
    
    		$_POST['fields']['field_123abcd-this-is-my-map-field'] = array(); // not sure if necessary, just to clean the data...
    		$_POST['fields']['field_123abcd-this-is-my-map-field'] = $loc_data; // insert all the data calculated in the funciton above
    		$_POST['fields']['field_456efgh-empty_hidden_field'] = $loc_data['area_level_2']; // here I insert just area_level_2 in order to filter / Order my SQL request later
    		
    }
    
    // run before ACF saves the $_POST['acf'] data
    add_action('acf/save_post', 'acf_location_data', 1);
    
    

    The update_field function wasn’t working, but step by step I’ve managed to do exactly want I was looking for. I hope this may be useful for someone out there.

    Thanks a lot John 🙂

    edit : it’s not very clean, but it works…. if I have time i will simplify it to give you a “generic” code 😉

  • Hi Lucas,

    Does this code just print the city in the front end in the posts with an address field? Or how would you call it? I’m looking for the same thing I think: to just extract the city from the google maps field. With your function above, how would I call it within a custom post type?

    Thanks!!!

  • I made here a shortcode to show the “city, country” from the coordinates

    You have to change the get_field(‘adresse’, $id) to your ACF field name.
    Here you need to write also the post id or you can just delete the beginning.
    I m not sure if you need a google api key … i tried it both with and without and it works…
    You can put that code in the functions.php of your theme

    It could be that you have to change on your server in the php.ini ( allow_url_fopen=0 ….. to …. allow_url_fopen=1 )… when you get an error like this “http:// wrapper is disabled in the server configuration by allow_url_fopen=0” …

    I m not sure… if this code is slowing a website also down. hm?

    // [location id=""]
    function location_shortcode( $atts ) {
    
    	extract( shortcode_atts(
    		array(
    			'id' => '',
    			), $atts )
    	);
    
    	if ( isset( $id ) && get_field('adresse', $id) ) {
    
    	$google_map = get_field('adresse', $id);
    
    $url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng='.$google_map['lat'].','.$google_map['lng'].'&sensor=true';
    $data = @file_get_contents($url);
    $jsondata = json_decode($data,true);
    if(is_array($jsondata) && $jsondata['status'] == "OK")
    {
    
    // city
    foreach ($jsondata["results"] as $result) {
        foreach ($result["address_components"] as $address) {
            if (in_array("locality", $address["types"])) {
                $city = $address["long_name"];
            }
        }
    }
    // country
    foreach ($jsondata["results"] as $result) {
        foreach ($result["address_components"] as $address) {
            if (in_array("country", $address["types"])) {
                $country = $address["long_name"];
            }
        }
    }
    
    }
    $seperator = ', ';
    
    $location = $city . $seperator . $country;
    
    return $location;
    
    }
    }
    add_shortcode( 'location', 'location_shortcode' );
  • Thank you for your shortcode, it works flawless!

    The reason i am writing you is to ask if you can extract the street address as well, along with the city and country.

    I would only need the street address and city.

    Please let me know if there is anyway to get that field.

    Thank you!

  • change “locality” or “country” to the things you need, check out: https://developers.google.com/maps/documentation/geocoding/intro for variables

    but … when you have a lot of streets and cities … i think the website is slowing massive down. i implemented this into my website first, but then i took it out again, cause i think it is slowing the website down a lot (if you have a lot of geo requests…)

    perhaps another solution? or am i wrong?

  • but perhaps, when you have a plugin, which converts automaticly in the backend all stored acf-maps-coordinates into name, street, country, city, etc … and safe those into the database. then you could send some get_field request from your database, without calling all the time again and again on on-the-fly the geo-coding thing.

    does somebody want to code such a plugin? 🙂

  • perhaps in combination with another plugin, which is writing to the database, like this? https://wordpress.org/plugins/contact-form-7-to-database-extension/

Viewing 13 posts - 1 through 13 (of 13 total)

You must be logged in to reply to this topic.