From 1b3ebf7d8f75e87ffea27a3c1b54934838543b41 Mon Sep 17 00:00:00 2001 From: LaurenSmillie Date: Tue, 12 Dec 2023 15:19:14 -0500 Subject: [PATCH 1/5] Adding new Geocoder.ca geocoder instance --- ProviderMetadata/8_GeocoderDotCa.mgd.php | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 ProviderMetadata/8_GeocoderDotCa.mgd.php diff --git a/ProviderMetadata/8_GeocoderDotCa.mgd.php b/ProviderMetadata/8_GeocoderDotCa.mgd.php new file mode 100644 index 0000000..96b41ea --- /dev/null +++ b/ProviderMetadata/8_GeocoderDotCa.mgd.php @@ -0,0 +1,25 @@ + 'geocoder_dot_ca', + 'entity' => 'Geocoder', + 'update' => 'never', + 'params' => [ + 'version' => 3, + 'name' => 'geocoder_dot_ca', + 'title' => 'Geocoder.ca', + 'class' => 'Geocoder.ca\Geocoder.ca', + 'api_key' => \Civi::settings()->get('geoAPIKey'), + 'url' => 'https://geocoder.ca', + 'is_active' => FALSE, + 'weight' => 8, + ], + 'help_text' => ts('api key required - sign up https://geocoder.ca/?register=1'), + 'user_editable_fields' => ['api_key', 'threshold_standdown'], + 'metadata' => [ + 'argument' => ['geocoder.api_key', 'pass_through' => TRUE], + 'required_config_fields' => ['api_key'], + 'is_enabled_on_install' => TRUE, + ], + ] +]; From bf2e22d1b66948da65645f912cd8c0066ec43dff Mon Sep 17 00:00:00 2001 From: LaurenSmillie Date: Tue, 12 Dec 2023 15:33:47 -0500 Subject: [PATCH 2/5] Updating managed file --- ProviderMetadata/8_GeocoderDotCa.mgd.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ProviderMetadata/8_GeocoderDotCa.mgd.php b/ProviderMetadata/8_GeocoderDotCa.mgd.php index 96b41ea..e374ab5 100644 --- a/ProviderMetadata/8_GeocoderDotCa.mgd.php +++ b/ProviderMetadata/8_GeocoderDotCa.mgd.php @@ -17,9 +17,9 @@ 'help_text' => ts('api key required - sign up https://geocoder.ca/?register=1'), 'user_editable_fields' => ['api_key', 'threshold_standdown'], 'metadata' => [ - 'argument' => ['geocoder.api_key', 'pass_through' => TRUE], + 'argument' => ['geocoder.api_key', 'geocoder.url'], 'required_config_fields' => ['api_key'], - 'is_enabled_on_install' => TRUE, + 'is_enabled_on_install' => FALSE, ], ] ]; From 7f1ab536c59a49db1f33d162e2776e4972a976cd Mon Sep 17 00:00:00 2001 From: Monish Deb Date: Tue, 9 Jan 2024 23:15:54 +0530 Subject: [PATCH 3/5] Add GecoderCa geocoder --- CRM/Utils/Geocode/GeocoderCa.php | 174 +++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 CRM/Utils/Geocode/GeocoderCa.php diff --git a/CRM/Utils/Geocode/GeocoderCa.php b/CRM/Utils/Geocode/GeocoderCa.php new file mode 100644 index 0000000..ca25493 --- /dev/null +++ b/CRM/Utils/Geocode/GeocoderCa.php @@ -0,0 +1,174 @@ +geoAPIKey)) { + $add .= '&geoit=XML&auth=' . urlencode($config->geoAPIKey); + } + + $query = 'https://' . self::$_server . $add; + + $client = new GuzzleHttp\Client(); + $request = $client->request('GET', $query, ['timeout' => \Civi::settings()->get('http_timeout')]); + $string = $request->getBody(); + + libxml_use_internal_errors(TRUE); + $xml = @simplexml_load_string($string); + $coords['request_xml'] = $xml; + if ($xml === FALSE) { + // account blocked maybe? + CRM_Core_Error::debug_var('Geocoding failed. Message from Geocoder.ca:', $string); + $coords['geo_code_error'] = $string; + } + + if (isset($xml->status)) { + if ($xml->status == 'OK' && + is_a($xml->result->geometry->location, + 'SimpleXMLElement' + ) + ) { + $ret = $xml->result->geometry->location->children(); + if ($ret->lat && $ret->lng) { + $coords['geo_code_1'] = (float) $ret->lat; + $coords['geo_code_2'] = (float) $ret->lng; + } + } + elseif ($xml->status != 'ZERO_RESULTS') { + // 'ZERO_RESULTS' is a valid status, in which case we'll change nothing in $ret; + // but if the status is anything else, we need to note the error. + CRM_Core_Error::debug_var("Geocoding failed. Message from Geocoder.ca: ({$xml->status})", (string ) $xml->error_message); + $coords['geo_code_error'] = $xml->status; + } + } + return $coords; + } + +} From 9da6386acf66e4def266d0082e5a2dd3f8aca786 Mon Sep 17 00:00:00 2001 From: Monish Deb Date: Fri, 19 Jan 2024 20:51:53 +0530 Subject: [PATCH 4/5] Fix parameters and format response to fetch coordinates or throw error message --- CRM/Utils/Geocode/GeocoderCa.php | 59 ++++++++++---------------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/CRM/Utils/Geocode/GeocoderCa.php b/CRM/Utils/Geocode/GeocoderCa.php index ca25493..c1cabba 100644 --- a/CRM/Utils/Geocode/GeocoderCa.php +++ b/CRM/Utils/Geocode/GeocoderCa.php @@ -44,18 +44,10 @@ public static function format(&$values, $stateName = FALSE) { return FALSE; } - $add = ''; + $add = []; - if (!empty($values['street_address'])) { - $add = urlencode(str_replace('', '+', $values['street_address'])); - $add .= ',+'; - } $city = $values['city'] ?? NULL; - if ($city) { - $add .= '+' . urlencode(str_replace('', '+', $city)); - $add .= ',+'; - } if (!empty($values['state_province']) || (!empty($values['state_province_id']) && $values['state_province_id'] != 'null')) { if (!empty($values['state_province_id'])) { @@ -76,19 +68,22 @@ public static function format(&$values, $stateName = FALSE) { // dont add state twice if replicated in city (happens in NZ and other countries, CRM-2632) if ($stateProvince != $city) { - $add .= '+' . urlencode(str_replace('', '+', $stateProvince)); - $add .= ',+'; + $add[] = 'state=' . urlencode(str_replace('', '+', $stateProvince)); } } - if (!empty($values['postal_code'])) { - $add .= '+' . urlencode(str_replace('', '+', $values['postal_code'])); - $add .= ',+'; + foreach ([ + 'country' => 'country', + 'city' => 'city', + 'postal' => 'postal_code', + 'staddress' => 'street_address', + ] as $key => $addressFieldName) { + if (!empty($values[$addressFieldName])) { + $add[] = $key . '=' . urlencode(str_replace('', '+', $values[$addressFieldName])); + } } - if (!empty($values['country'])) { - $add .= '+' . urlencode(str_replace('', '+', $values['country'])); - } + $add = implode('&', $add); $coord = self::makeRequest($add); @@ -134,8 +129,7 @@ private static function makeRequest($add) { $add .= '&geoit=XML&auth=' . urlencode($config->geoAPIKey); } - $query = 'https://' . self::$_server . $add; - + $query = 'https://' . self::$_server . '?' . $add; $client = new GuzzleHttp\Client(); $request = $client->request('GET', $query, ['timeout' => \Civi::settings()->get('http_timeout')]); $string = $request->getBody(); @@ -143,31 +137,16 @@ private static function makeRequest($add) { libxml_use_internal_errors(TRUE); $xml = @simplexml_load_string($string); $coords['request_xml'] = $xml; - if ($xml === FALSE) { - // account blocked maybe? + if (isset($xml->error)) { + $string = sprintf('Error %s: %s', $xml->error->code, $xml->error->description); CRM_Core_Error::debug_var('Geocoding failed. Message from Geocoder.ca:', $string); $coords['geo_code_error'] = $string; } - - if (isset($xml->status)) { - if ($xml->status == 'OK' && - is_a($xml->result->geometry->location, - 'SimpleXMLElement' - ) - ) { - $ret = $xml->result->geometry->location->children(); - if ($ret->lat && $ret->lng) { - $coords['geo_code_1'] = (float) $ret->lat; - $coords['geo_code_2'] = (float) $ret->lng; - } - } - elseif ($xml->status != 'ZERO_RESULTS') { - // 'ZERO_RESULTS' is a valid status, in which case we'll change nothing in $ret; - // but if the status is anything else, we need to note the error. - CRM_Core_Error::debug_var("Geocoding failed. Message from Geocoder.ca: ({$xml->status})", (string ) $xml->error_message); - $coords['geo_code_error'] = $xml->status; - } + if (isset($xml->latt) && isset($xml->longt)) { + $coords['geo_code_1'] = (float) $xml->latt; + $coords['geo_code_2'] = (float) $xml->longt; } + return $coords; } From 0256801d31bc3611905e2bc0de25d74181017b0c Mon Sep 17 00:00:00 2001 From: Monish Deb Date: Fri, 19 Jan 2024 22:05:40 +0530 Subject: [PATCH 5/5] Add geocoding provider - Geocoder.xyz --- CRM/Utils/Geocode/GeocoderCa.php | 3 +- CRM/Utils/Geocode/GeocoderXyz.php | 71 +++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 CRM/Utils/Geocode/GeocoderXyz.php diff --git a/CRM/Utils/Geocode/GeocoderCa.php b/CRM/Utils/Geocode/GeocoderCa.php index c1cabba..1360684 100644 --- a/CRM/Utils/Geocode/GeocoderCa.php +++ b/CRM/Utils/Geocode/GeocoderCa.php @@ -94,7 +94,8 @@ public static function format(&$values, $stateName = FALSE) { $values['geo_code_error'] = $coord['geo_code_error']; } - CRM_Utils_Hook::geocoderFormat('GeocoderCa', $values, $coord['request_xml']); + $geoCoder = array_pop(explode('_', __CLASS__)); + CRM_Utils_Hook::geocoderFormat($geoCoder, $values, $coord['request_xml']); return isset($coord['geo_code_1'], $coord['geo_code_2']); } diff --git a/CRM/Utils/Geocode/GeocoderXyz.php b/CRM/Utils/Geocode/GeocoderXyz.php new file mode 100644 index 0000000..46da6d7 --- /dev/null +++ b/CRM/Utils/Geocode/GeocoderXyz.php @@ -0,0 +1,71 @@ +geoAPIKey)) { + $add .= '&geoit=XML&auth=' . urlencode($config->geoAPIKey); + } + + $query = 'https://' . self::$_server . '?' . $add; + $client = new GuzzleHttp\Client(); + $request = $client->request('GET', $query, ['timeout' => \Civi::settings()->get('http_timeout')]); + $string = $request->getBody(); + + libxml_use_internal_errors(TRUE); + $xml = @simplexml_load_string($string); + $coords['request_xml'] = $xml; + if (isset($xml->error)) { + $string = sprintf('Error %s: %s', $xml->error->code, $xml->error->description); + CRM_Core_Error::debug_var('Geocoding failed. Message from Geocoder.xyz:', $string); + $coords['geo_code_error'] = $string; + } + if (isset($xml->latt) && isset($xml->longt)) { + $coords['geo_code_1'] = (float) $xml->latt; + $coords['geo_code_2'] = (float) $xml->longt; + } + + return $coords; + } + +}