3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * Class that uses google geocoder
21 class CRM_Utils_Geocode_Google
{
24 * Server to retrieve the lat/long
28 static protected $_server = 'maps.googleapis.com';
35 static protected $_uri = '/maps/api/geocode/xml?sensor=false&address=';
38 * Function that takes an address object and gets the latitude / longitude for this
39 * address. Note that at a later stage, we could make this function also clean up
40 * the address into a more valid format
42 * @param array $values
43 * @param bool $stateName
46 * true if we modified the address, false otherwise
48 public static function format(&$values, $stateName = FALSE) {
49 // we need a valid country, else we ignore
50 if (empty($values['country'])) {
54 $config = CRM_Core_Config
::singleton();
58 if (!empty($values['street_address'])) {
59 $add = urlencode(str_replace('', '+', $values['street_address']));
63 $city = $values['city'] ??
NULL;
65 $add .= '+' . urlencode(str_replace('', '+', $city));
69 if (!empty($values['state_province']) ||
(!empty($values['state_province_id']) && $values['state_province_id'] != 'null')) {
70 if (!empty($values['state_province_id'])) {
71 $stateProvince = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_StateProvince', $values['state_province_id']);
75 $stateProvince = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_StateProvince',
76 $values['state_province'],
82 $stateProvince = $values['state_province'];
86 // dont add state twice if replicated in city (happens in NZ and other countries, CRM-2632)
87 if ($stateProvince != $city) {
88 $add .= '+' . urlencode(str_replace('', '+', $stateProvince));
93 if (!empty($values['postal_code'])) {
94 $add .= '+' . urlencode(str_replace('', '+', $values['postal_code']));
98 if (!empty($values['country'])) {
99 $add .= '+' . urlencode(str_replace('', '+', $values['country']));
102 if (!empty($config->geoAPIKey
)) {
103 $add .= '&key=' . urlencode($config->geoAPIKey
);
106 $query = 'https://' . self
::$_server . self
::$_uri . $add;
108 $client = new GuzzleHttp\
Client();
109 $request = $client->request('GET', $query, ['timeout' => \Civi
::settings()->get('http_timeout')]);
110 $string = $request->getBody();
112 libxml_use_internal_errors(TRUE);
113 $xml = @simplexml_load_string
($string);
114 CRM_Utils_Hook
::geocoderFormat('Google', $values, $xml);
115 if ($xml === FALSE) {
116 // account blocked maybe?
117 CRM_Core_Error
::debug_var('Geocoding failed. Message from Google:', $string);
121 if (isset($xml->status
)) {
122 if ($xml->status
== 'OK' &&
123 is_a($xml->result
->geometry
->location
,
127 $ret = $xml->result
->geometry
->location
->children();
128 if ($ret->lat
&& $ret->lng
) {
129 $values['geo_code_1'] = (float) $ret->lat
;
130 $values['geo_code_2'] = (float) $ret->lng
;
134 elseif ($xml->status
== 'ZERO_RESULTS') {
135 // reset the geo code values if we did not get any good values
136 $values['geo_code_1'] = $values['geo_code_2'] = 'null';
140 CRM_Core_Error
::debug_var("Geocoding failed. Message from Google: ({$xml->status})", (string ) $xml->error_message
);
141 $values['geo_code_1'] = $values['geo_code_2'] = 'null';
142 $values['geo_code_error'] = $xml->status
;