$componentValue) { $whereComponents[$componentName] = urlencode("$componentName=\"$componentValue\""); } $add = 'q=' . urlencode('select * from geo.placefinder where '); $add .= implode(urlencode(' and '), $whereComponents); $add .= "&appid=" . urlencode($config->mapAPIKey); $query = 'http://' . self::$_server . self::$_uri . '?' . $add; require_once 'HTTP/Request.php'; $request = new HTTP_Request($query); $request->sendRequest(); $string = $request->getResponseBody(); // see CRM-11359 for why we suppress errors with @ $xml = @simplexml_load_string($string); if ($xml === FALSE) { // account blocked maybe? CRM_Core_Error::debug_var('Geocoding failed. Message from Yahoo:', $string); return FALSE; } if ($xml->getName() == 'error') { CRM_Core_Error::debug_var('query', $query); CRM_Core_Error::debug_log_message('Geocoding failed. Message from Yahoo: ' . (string) $xml->description); return FALSE; } if (is_a($xml->results->Result, 'SimpleXMLElement')) { $result = array(); $result = get_object_vars($xml->results->Result); foreach ($result as $key => $val) { if (is_scalar($val) && strlen($val) ) { $ret[(string) $key] = (string) $val; } } $values['geo_code_1'] = $ret['latitude']; $values['geo_code_2'] = $ret['longitude']; if (!empty($ret['postal'])) { $current_pc = CRM_Utils_Array::value('postal_code', $values); $skip_postal = FALSE; if ($current_pc) { $current_pc_suffix = CRM_Utils_Array::value('postal_code_suffix', $values); $current_pc_complete = $current_pc . $current_pc_suffix; $new_pc_complete = preg_replace("/[+-]/", '', $ret['postal']); // if a postal code was already entered, don't change it, except to make it more precise if (strpos($new_pc_complete, $current_pc_complete) !== 0) { // Don't bother anonymous users with the message - they can't change a form they just submitted anyway if (CRM_Utils_System::isUserLoggedIn()) { $msg = ts('The Yahoo Geocoding system returned a different postal code (%1) than the one you entered (%2). If you want the Yahoo value, please delete the current postal code and save again.', array( 1 => $ret['postal'], 2 => $current_pc_suffix ? "$current_pc-$current_pc_suffix" : $current_pc, )); CRM_Core_Session::setStatus($msg, ts('Postal Code Mismatch'), 'error'); } $skip_postal = TRUE; } } if (!$skip_postal) { $values['postal_code'] = $ret['postal']; /* the following logic to split the string was borrowed from CRM/Core/BAO/Address.php -- CRM_Core_BAO_Address::fixAddress. This is actually the function that calls the geocoding script to begin with, but the postal code business takes place before geocoding gets called. */ if (preg_match('/^(\d{4,5})[+-](\d{4})$/', $ret['postal'], $match ) ) { $values['postal_code'] = $match[1]; $values['postal_code_suffix'] = $match[2]; } } } return TRUE; } // reset the geo code values if we did not get any good values $values['geo_code_1'] = $values['geo_code_2'] = 'null'; return FALSE; } }