return FALSE;
}
- $config = CRM_Core_Config::singleton();
-
$add = '';
if (!empty($values['street_address'])) {
$add .= '+' . urlencode(str_replace('', '+', $values['country']));
}
+ $coord = self::makeRequest($add);
+
+ $values['geo_code_1'] = $coord['geo_code_1'] ?? 'null';
+ $values['geo_code_2'] = $coord['geo_code_2'] ?? 'null';
+
+ if (isset($coord['geo_code_error'])) {
+ $values['geo_code_error'] = $coord['geo_code_error'];
+ }
+
+ return isset($coord['geo_code_1'], $coord['geo_code_2']);
+ }
+
+ /**
+ * @param string $address
+ * Plain text address
+ * @return array
+ * @throws \GuzzleHttp\Exception\GuzzleException
+ */
+ public static function getCoordinates($address) {
+ return self::makeRequest(urlencode($address));
+ }
+
+ /**
+ * @param string $add
+ * Url-encoded address
+ * @return array
+ * @throws \GuzzleHttp\Exception\GuzzleException
+ */
+ private static function makeRequest($add) {
+
+ $config = CRM_Core_Config::singleton();
if (!empty($config->geoAPIKey)) {
$add .= '&key=' . urlencode($config->geoAPIKey);
}
if ($xml === FALSE) {
// account blocked maybe?
CRM_Core_Error::debug_var('Geocoding failed. Message from Google:', $string);
- return FALSE;
+ return ['geo_code_error' => $string];
}
if (isset($xml->status)) {
) {
$ret = $xml->result->geometry->location->children();
if ($ret->lat && $ret->lng) {
- $values['geo_code_1'] = (float) $ret->lat;
- $values['geo_code_2'] = (float) $ret->lng;
- return TRUE;
+ return [
+ 'geo_code_1' => (float) $ret->lat,
+ 'geo_code_2' => (float) $ret->lng,
+ ];
}
}
elseif ($xml->status == 'ZERO_RESULTS') {
// reset the geo code values if we did not get any good values
- $values['geo_code_1'] = $values['geo_code_2'] = 'null';
- return FALSE;
+ return [];
}
else {
CRM_Core_Error::debug_var("Geocoding failed. Message from Google: ({$xml->status})", (string ) $xml->error_message);
- $values['geo_code_1'] = $values['geo_code_2'] = 'null';
- $values['geo_code_error'] = $xml->status;
- return FALSE;
+ return ['geo_code_error' => $xml->status];
}
}
+ return [];
}
}
--- /dev/null
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Action\Address;
+
+use Civi\Api4\Generic\Result;
+
+/**
+ * Converts an address string to lat/long coordinates.
+ *
+ * @method $this setAddress(string $address)
+ * @method string getAddress()
+ */
+class GetCoordinates extends \Civi\Api4\Generic\AbstractAction {
+
+ /**
+ * Address string to convert to lat/long
+ *
+ * @var string
+ * @required
+ */
+ protected $address;
+
+ public function _run(Result $result) {
+ $coord = \CRM_Utils_Geocode_Google::getCoordinates($this->address);
+ if (isset($coord['geo_code_1'], $coord['geo_code_2'])) {
+ $result[] = $coord;
+ }
+ elseif (!empty($coord['geo_code_error'])) {
+ throw new \API_Exception('Geocoding failed. ' . $coord['geo_code_error']);
+ }
+ }
+
+}
namespace Civi\Api4\Service\Spec\Provider;
+use Civi\Api4\Address;
use Civi\Api4\Query\Api4SelectQuery;
use Civi\Api4\Service\Spec\FieldSpec;
use Civi\Api4\Service\Spec\RequestSpec;
$distance = $distance * 1000.00;
}
+ if (!isset($value['geo_code_1'], $value['geo_code_2'])) {
+ $value = Address::getCoordinates(FALSE)
+ ->setAddress($value['address'])
+ ->execute()->first();
+ }
+
if (
isset($value['geo_code_1']) && is_numeric($value['geo_code_1']) &&
isset($value['geo_code_2']) && is_numeric($value['geo_code_2'])
explode('.', $fieldAlias)[0]
);
}
- // Todo: If address string given without lat/long, convert it.
return '(0)';
}