/** * Get contacts by proximity. * * @param array $params * * @return array * @throws Exception */ function civicrm_api3_contact_proximity($params) { $latitude = CRM_Utils_Array::value('latitude', $params); $longitude = CRM_Utils_Array::value('longitude', $params); $distance = CRM_Utils_Array::value('distance', $params); $unit = CRM_Utils_Array::value('unit', $params); // check and ensure that lat/long and distance are floats if (!CRM_Utils_Rule::numeric($latitude) || !CRM_Utils_Rule::numeric($longitude) || !CRM_Utils_Rule::numeric($distance)) { throw new Exception(ts('Latitude, Longitude and Distance should exist and be numeric')); } if ($unit == "mile") { $conversionFactor = 1609.344; } else { $conversionFactor = 1000; } //Distance in meters $distance = $distance * $conversionFactor; $whereClause = CRM_Contact_BAO_ProximityQuery::where($latitude, $longitude, $distance); $query = "\nSELECT civicrm_contact.id as contact_id,\n civicrm_contact.display_name as display_name\nFROM civicrm_contact\nLEFT JOIN civicrm_address ON civicrm_contact.id = civicrm_address.contact_id\nWHERE {$whereClause}\n"; $dao = CRM_Core_DAO::executeQuery($query); $contacts = array(); while ($dao->fetch()) { $contacts[] = $dao->toArray(); } return civicrm_api3_create_success($contacts, $params, 'Contact', 'get_by_location', $dao); }
/** * @param bool $includeContactIDs * * @return string */ public function where($includeContactIDs = FALSE) { $params = array(); $clause = array(); $where = CRM_Contact_BAO_ProximityQuery::where($this->_latitude, $this->_longitude, $this->_distance, 'address'); if ($this->_tag) { $where .= "\nAND t.tag_id = {$this->_tag}\n"; } if ($this->_group) { $where .= "\nAND cgc.group_id = {$this->_group}\n "; } $where .= " AND contact_a.is_deleted != 1 "; return $this->whereClause($where, $params); }
/** * Helper method to filter Projects by location. * * @param array $params * <ol> * <li>string city - optional. Not used in this function, just passed along for geocoding.</li> * <li>mixed country - required if lat/lon not provided. Can be country_id or string.</li> * <li>float lat - required if country not provided</li> * <li>float lon - required if country not provided</li> * <li>string postal_code - optional. Not used in this function, just passed along for geocoding.</li> * <li>float radius - required</li> * <li>string street_address - optional. Not used in this function, just passed along for geocoding.</li> * <li>string unit - optional, defaults to meters unless 'mile' is specified</li> * </ol> * @return string * SQL fragment (partial where clause) * @throws Exception */ private static function buildProximityWhere(array $params) { $country = $lat = $lon = $radius = $unit = NULL; extract($params, EXTR_IF_EXISTS); // ensure that radius is a float if (!CRM_Utils_Rule::numeric($radius)) { throw new Exception(ts('Radius should exist and be numeric')); } if (!CRM_Utils_Rule::numeric($lat) || !CRM_Utils_Rule::numeric($lon)) { if (empty($country)) { throw new Exception(ts('Either Country or both Latitude and Longitude are required')); } // TODO: I think CRM_Utils_Geocode_*::format should be responsible for this if (CRM_Utils_Type::validate($country, 'Positive', FALSE)) { $country = civicrm_api3('Country', 'getvalue', array('id' => $country, 'return' => 'name')); } // TODO: support other geocoders $geocodeSuccess = CRM_Utils_Geocode_Google::format($params); if (!$geocodeSuccess) { // this is intentionally a string; a query like "SELECT * FROM foo WHERE FALSE" // will return an empty set, which is what we should do if the provided address // can't be geocoded return 'FALSE'; } // $params is passed to the geocoder by reference; on success, these values // will be available $lat = $params['geo_code_1']; $lon = $params['geo_code_2']; } $conversionFactor = $unit == "mile" ? 1609.344 : 1000; //radius in meters $radius = $radius * $conversionFactor; return CRM_Contact_BAO_ProximityQuery::where($lat, $lon, $radius); }
function where($includeContactIDs = false) { $params = array(); $clause = array(); require_once 'CRM/Contact/BAO/ProximityQuery.php'; $where = CRM_Contact_BAO_ProximityQuery::where($this->_latitude, $this->_longitude, $this->_distance, 'address'); if ($this->_tag) { $where .= "\nAND t.tag_id = {$this->_tag}\n"; } if ($this->_group) { $where .= "\nAND cgc.group_id = {$this->_group}\n "; } return $this->whereClause($where, $params); }