/** * Uses Google Maps API to parse flat address */ static function parse($str, $returnAccuracy = false) { //CLEANUP $str = preg_replace('/[\\n\\r]/', ' ', $str); $key = sfConfig::get('sf_google_maps_key'); $url = 'http://maps.google.com/maps/geo?q=' . urlencode($str) . '&output=xml&key=' . $key; //echo $url . "\n"; $c = new sfWebBrowser(); try { if (!$c->get($url)->responseIsError()) { $c->setResponseText(iconv('ISO-8859-1', 'UTF-8', $c->getResponseText())); $xml = $c->getResponseXml(); //var_dump($xml); $structured = $xml->Response->Placemark->AddressDetails; $accuracy = (int) $structured['Accuracy']; } else { return null; } } catch (Exception $e) { // Adapter error (eg. Host not found) throw $e; } //accuracy of 4+ means we have at least a town (UNLESS THE TOWN DOESN'T "OFFICIALLY" EXIST) if ($accuracy > 3) { $address = new Address(); //COUNTRY (USA only for now) $address->country_id = 1; //STATE (for some reason trickery needs to be done to get state to work right) $stateName = null; if (isset($structured->Country->AdministrativeArea->AdministrativeAreaName)) { $stateName = (array) $structured->Country->AdministrativeArea->AdministrativeAreaName; $stateName = isset($stateName[0]) ? $stateName[0] : $stateName; } else { $possible_state = $structured->Country->CountryNameCode; if ($possible_state != 'US') { $stateName = $possible_state; } } if (!$stateName) { return null; } if (!($state = AddressStateTable::retrieveByText($stateName))) { return null; } $address->state_id = $state->id; //COUNTY (this may not exist) $countyName = $structured->Country->AdministrativeArea->SubAdministrativeArea->SubAdministrativeAreaName; $address->county = LsString::emptyToNull((string) $countyName); if ($countyName) { $cityName = $structured->Country->AdministrativeArea->SubAdministrativeArea->Locality->LocalityName; } else { $cityName = $structured->Country->AdministrativeArea->Locality->LocalityName; } //CITY (this may not exist!) $address->city = (string) $cityName; //accuracy of 5+ means we have postal code if ($accuracy > 4) { if ($cityName && $countyName) { $base = $structured->Country->AdministrativeArea->SubAdministrativeArea->Locality; if (isset($base->DependentLocality)) { $base = $base->DependentLocality; } } else { if ($cityName && !$countyName) { $base = $structured->Country->AdministrativeArea->Locality; } else { if (!$cityName && $countyName) { $base = $structured->Country->AdministrativeArea->SubAdministrativeArea; } else { $base = $structured->Country->AdministrativeArea; } } } //POSTAL CODE (for some reason trickery needs to be done to get postal code to work right) if ($postalCode = (array) $base->PostalCode->PostalCodeNumber) { $postalCode = $postalCode[0]; $address->postal = (string) $postalCode; } //accuracy of 8 means we have exact match //echo $accuracy . "\n"; if ($accuracy > 5) { //STREET (unit info is lost) //echo "street1 info found \n"; $street1 = $base->Thoroughfare->ThoroughfareName; $address->street1 = (string) $street1; } } //COORDINATES // Parse the coordinate string $coords = $c->getResponseXml()->Response->Placemark->Point->coordinates; list($lon, $lat, $alt) = explode(",", $coords); $address->longitude = $lon; $address->latitude = $lat; if ($returnAccuracy) { return array('address' => $address, 'accuracy' => $accuracy); } else { return $address; } } else { return null; } }
public function removeFields($fields) { $diff = array_diff($this->getFieldsArray(), (array) $fields); sort($diff); return $this->fields = LsString::emptyToNull(implode(',', $diff)); }