/**
  * Add missing location fields, and update country and admin codes with
  * authoritative Geonames values.
  *
  * @since 1.3
  *
  * @param array $location The location to geocode, modified.
  * @param string $language Optional ISO language code.
  * @return bool Success.
  */
 private static function reverse_geocode_location(&$location, $language = '')
 {
     global $geo_mashup_options;
     // Coordinates are required
     if (self::are_any_location_fields_empty($location, array('lat', 'lng'))) {
         return false;
     }
     // Don't bother unless there are missing geocodable fields
     $geocodable_fields = array('country_code', 'admin_code', 'address', 'locality_name', 'postal_code');
     $have_empties = self::are_any_location_fields_empty($location, $geocodable_fields);
     if (!$have_empties) {
         return false;
     }
     $status = false;
     if (!class_exists('GeoMashupHttpGeocoder')) {
         include_once path_join(GEO_MASHUP_DIR_PATH, 'geo-mashup-geocoders.php');
     }
     $geonames_geocoder = new GeoMashupGeonamesGeocoder();
     $geonames_results = $geonames_geocoder->reverse_geocode($location['lat'], $location['lng']);
     if (is_wp_error($geonames_results) or empty($geonames_results)) {
         self::$geocode_error = $geonames_results;
     } else {
         if (!empty($geonames_results[0]->admin_code)) {
             $location['admin_code'] = $geonames_results[0]->admin_code;
         }
         if (!empty($geonames_results[0]->country_code)) {
             $location['country_code'] = $geonames_results[0]->country_code;
         }
         self::fill_empty_location_fields($location, (array) $geonames_results[0]);
         $status = true;
     }
     $have_empties = self::are_any_location_fields_empty($location, $geocodable_fields);
     if ($have_empties) {
         // Choose a geocoding service based on the default API in use
         if ('google' == substr($geo_mashup_options->get('overall', 'map_api'), 0, 6)) {
             $next_geocoder = new GeoMashupGoogleGeocoder();
         } else {
             if ('openlayers' == $geo_mashup_options->get('overall', 'map_api')) {
                 $next_geocoder = new GeoMashupNominatimGeocoder();
             }
         }
         $next_results = $next_geocoder->reverse_geocode($location['lat'], $location['lng']);
         if (is_wp_error($next_results) or empty($next_results)) {
             self::$geocode_error = $next_results;
         } else {
             self::fill_empty_location_fields($location, (array) $next_results[0]);
         }
         $status = true;
     }
     return $status;
 }
 /**
  * Try to fill in coordinates and other fields of a location from a textual
  * location search.
  *
  * Multiple geocoding services may be used. Google services are only used
  * if the default map provider is Google.
  * 
  * @since 1.3
  *
  * @param mixed $query The search string.
  * @param array $location The location array to geocode, modified.
  * @param string $language 
  * @return bool Whether a lookup succeeded.
  */
 public static function geocode($query, &$location, $language = '')
 {
     global $geo_mashup_options;
     if (empty($location)) {
         $location = self::blank_location();
     } else {
         if (!is_array($location) and !is_object($location)) {
             return false;
         }
     }
     $status = false;
     if (!class_exists('GeoMashupHttpGeocoder')) {
         include_once path_join(GEO_MASHUP_DIR_PATH, 'geo-mashup-geocoders.php');
     }
     // Try GeoCoding services (google, nominatim, geonames) until one gives an answer
     $results = array();
     if ('google' == substr($geo_mashup_options->get('overall', 'map_api'), 0, 6)) {
         // Only try the google service if a google API is selected as the default
         $google_geocoder = new GeoMashupGoogleGeocoder(array('language' => $language));
         $results = $google_geocoder->geocode($query);
     }
     if (is_wp_error($results) or empty($results)) {
         self::$geocode_error = $results;
         $nominatim_geocoder = new GeoMashupNominatimGeocoder(array('language' => $language));
         $results = $nominatim_geocoder->geocode($query);
     }
     if (is_wp_error($results) or empty($results)) {
         self::$geocode_error = $results;
         $geonames_geocoder = new GeoMashupGeonamesGeocoder(array('language' => $language));
         $results = $geonames_geocoder->geocode($query);
     }
     if (is_wp_error($results) or empty($results)) {
         self::$geocode_error = $results;
     } else {
         self::fill_empty_location_fields($location, $results[0]);
         $status = true;
     }
     return $status;
 }