Merge pull request #15830 from eileenmcnaughton/dedupe4
[civicrm-core.git] / CRM / Utils / Geocode / Google.php
CommitLineData
6a488035
TO
1<?php
2/*
bc77d7c0
TO
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
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 +--------------------------------------------------------------------+
e70a7fc0 10 */
6a488035
TO
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
16 */
17
18/**
19 * Class that uses google geocoder
20 */
21class CRM_Utils_Geocode_Google {
22
23 /**
100fef9d 24 * Server to retrieve the lat/long
6a488035
TO
25 *
26 * @var string
6a488035
TO
27 */
28 static protected $_server = 'maps.googleapis.com';
29
30 /**
fe482240 31 * Uri of service.
6a488035
TO
32 *
33 * @var string
6a488035
TO
34 */
35 static protected $_uri = '/maps/api/geocode/xml?sensor=false&address=';
36
37 /**
100fef9d 38 * Function that takes an address object and gets the latitude / longitude for this
6a488035
TO
39 * address. Note that at a later stage, we could make this function also clean up
40 * the address into a more valid format
41 *
c490a46a 42 * @param array $values
77b97be7
EM
43 * @param bool $stateName
44 *
bed98343 45 * @return bool
a6c01b45 46 * true if we modified the address, false otherwise
6a488035 47 */
00be9182 48 public static function format(&$values, $stateName = FALSE) {
6a488035 49 // we need a valid country, else we ignore
a7488080 50 if (empty($values['country'])) {
6a488035
TO
51 return FALSE;
52 }
53
54 $config = CRM_Core_Config::singleton();
55
56 $add = '';
57
a7488080 58 if (!empty($values['street_address'])) {
6a488035
TO
59 $add = urlencode(str_replace('', '+', $values['street_address']));
60 $add .= ',+';
61 }
62
63 $city = CRM_Utils_Array::value('city', $values);
64 if ($city) {
65 $add .= '+' . urlencode(str_replace('', '+', $city));
66 $add .= ',+';
67 }
68
f731b3dd 69 if (!empty($values['state_province']) || (!empty($values['state_province_id']) && $values['state_province_id'] != 'null')) {
a7488080 70 if (!empty($values['state_province_id'])) {
6a488035
TO
71 $stateProvince = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_StateProvince', $values['state_province_id']);
72 }
73 else {
74 if (!$stateName) {
75 $stateProvince = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_StateProvince',
76 $values['state_province'],
77 'name',
78 'abbreviation'
79 );
80 }
81 else {
82 $stateProvince = $values['state_province'];
83 }
84 }
85
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));
89 $add .= ',+';
90 }
91 }
92
a7488080 93 if (!empty($values['postal_code'])) {
6a488035
TO
94 $add .= '+' . urlencode(str_replace('', '+', $values['postal_code']));
95 $add .= ',+';
96 }
97
a7488080 98 if (!empty($values['country'])) {
6a488035
TO
99 $add .= '+' . urlencode(str_replace('', '+', $values['country']));
100 }
101
6849336a
CB
102 if (!empty($config->geoAPIKey)) {
103 $add .= '&key=' . urlencode($config->geoAPIKey);
104 }
105
106 $query = 'https://' . self::$_server . self::$_uri . $add;
6a488035
TO
107
108 require_once 'HTTP/Request.php';
109 $request = new HTTP_Request($query);
110 $request->sendRequest();
111 $string = $request->getResponseBody();
112
113 libxml_use_internal_errors(TRUE);
114 $xml = @simplexml_load_string($string);
9862d91a 115 CRM_Utils_Hook::geocoderFormat('Google', $values, $xml);
6a488035
TO
116 if ($xml === FALSE) {
117 // account blocked maybe?
118 CRM_Core_Error::debug_var('Geocoding failed. Message from Google:', $string);
119 return FALSE;
120 }
121
122 if (isset($xml->status)) {
123 if ($xml->status == 'OK' &&
124 is_a($xml->result->geometry->location,
125 'SimpleXMLElement'
126 )
127 ) {
128 $ret = $xml->result->geometry->location->children();
129 if ($ret->lat && $ret->lng) {
e7292422
TO
130 $values['geo_code_1'] = (float) $ret->lat;
131 $values['geo_code_2'] = (float) $ret->lng;
6a488035
TO
132 return TRUE;
133 }
134 }
a61fce12
TL
135 elseif ($xml->status == 'ZERO_RESULTS') {
136 // reset the geo code values if we did not get any good values
137 $values['geo_code_1'] = $values['geo_code_2'] = 'null';
138 return FALSE;
139 }
140 else {
141 CRM_Core_Error::debug_var("Geocoding failed. Message from Google: ({$xml->status})", (string ) $xml->error_message);
79f1148d
DL
142 $values['geo_code_1'] = $values['geo_code_2'] = 'null';
143 $values['geo_code_error'] = $xml->status;
144 return FALSE;
6a488035
TO
145 }
146 }
6a488035 147 }
161af008 148
6a488035 149}