0 AND longitude<>0 AND geocoding_date IS NOT NULL AND postal IS NOT NULL "; $q .= "ORDER BY geocoding_date DESC LIMIT 1"; error_log($q); $r = pg_query($db, $q); if ($r && pg_num_rows($r) && $f = pg_fetch_assoc($r)) { return $f; } syslog(LOG_WARNING, 'Address::save($db, $result)'); $db_lat = floatval($result["lat"]); $db_lng = floatval($result["lng"]); $db_postal = pg_escape_string($result["postal"]); $db_plus_code = pg_escape_string($result["plus_code"]); $db_city = pg_escape_string($result["city"]); $db_country = pg_escape_string($result["country"]); $db_tz = Geocode::getTimezone($db, $result["timeZoneId"]); $db_city_lat = floatval($result["city_lat"]); $db_city_lng = floatval($result["city_lng"]); $city_id = Address::getCity($db, $db_city, $db_country,$db_city_lat, $db_city_lng); if (empty($city_id)) { $city_id = Address::insertCity($db, $db_city, $db_country, $db_city_lat, $db_city_lng); } if (empty($db_postal)) { $db_postal = Address::getClosestPostalCode($db_lat, $db_lng, $db_country); } $q = "INSERT INTO address (address,latitude,longitude,timezone,geocoding_date,postal,country,geometry, city_id, plus_code) VALUES ("; $q .= "'${db_address}',${db_lat},${db_lng}," . ($db_tz == null ? "NULL" : $db_tz) . ",now(),'${db_postal}','${db_country}',ST_SetSRID(ST_MakePoint(${db_lng},${db_lat}), 4326),'${city_id}','${db_plus_code}')"; $q .= " RETURNING id, address, latitude as lat, longitude as lng, postal, country, timezone, city_id, plus_code"; error_log($q); $r = pg_query($db, $q); if ($r && pg_num_rows($r) && $f = pg_fetch_assoc($r)) { if(!empty($db_address_input) && $db_plus_code!=$db_address_input){ Address::saveAliasAddress($db, $f['id'], $db_address_input); } return $f; } return null; } public function saveAliasAddress($db, $address_id, $address, $source='Google'){ $q = "SELECT id, address_id, name FROM address_alias WHERE lower(name)=lower('${address}') "; $q .= "ORDER BY geocoding_date DESC LIMIT 1"; error_log($q); $r = pg_query($db, $q); if ($r && pg_num_rows($r) && $f = pg_fetch_assoc($r)) { return $f; } $q = "INSERT INTO address_alias (address_id,name,geocoding_date,source) VALUES ("; $q .= "${address_id},'${address}', now() ,'${source}')"; $q .= " RETURNING address_id, name"; error_log($q); $r = pg_query($db, $q); if ($r && pg_num_rows($r) && $f = pg_fetch_assoc($r)) { return $f; } return null; } public function update($db, $condition, $data) { syslog(LOG_WARNING,'Address::update(): '.json_encode($data)); $q = "select column_name, data_type, character_maximum_length from INFORMATION_SCHEMA.COLUMNS where table_name = 'address'"; $r = pg_query($db, $q); while ($f = pg_fetch_assoc($r)) { $columns[$f['column_name']] = $f['data_type']; } if(count($data)<1) return null; $q = "UPDATE address SET id=id "; foreach ($data as $key => $val) { if ($key == "id") { continue; } if (array_key_exists($key, $data) && !in_array($columns[$key], ['character varying', 'date', 'timestamp with time zone', 'timestamp without time zone'])) { $q .= ", ${key} = " . ($val == "" ? "NULL" : $val); } else { $q .= ", ${key} = '" . pg_escape_string($val) . "'"; } } $q .= " WHERE " . $condition . ""; $r = pg_query($db, $q); if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) { return $f; } return array(NULL, pg_last_error($db)); } public function searchInView($db, $country, $address) { $db_country = pg_escape_string($country); // is not used for now... $db_address = pg_escape_string(html_entity_decode($address,ENT_QUOTES|ENT_HTML5,"UTF-8")); $words = preg_split("/[\s,]+/", $db_address); $tsquery = implode(':* & ', $words). ':* & '.$db_country; $q = "SELECT * FROM address_view a WHERE address_search @@ to_tsquery('simple', '${tsquery}') ORDER BY ts_rank(address_search,to_tsquery('simple', '${tsquery}')) desc LIMIT 10"; $r = pg_query($db, $q); $results = []; if ($r && pg_num_rows($r)) { while ($f = pg_fetch_assoc($r)) { $f["address"] = html_entity_decode($f["address"],ENT_QUOTES|ENT_HTML5,"UTF-8"); $results[] = $f; } if (count($results) > 9) { return $results; } } return $results; } public function search($db, $country, $address) { //syslog(LOG_WARNING,"Address::search(\$db, $country, $address)"); $db_country = pg_escape_string($country); // is not used for now... $db_address = pg_escape_string(html_entity_decode($address,ENT_QUOTES|ENT_HTML5,"UTF-8")); $q = "SELECT a.*, b.timezone AS \"timeZoneId\" FROM address a LEFT JOIN address_timezone b ON (b.id=a.timezone) "; $q .= " WHERE UPPER(a.address) ILIKE ('%${db_address}%') AND a.country='${db_country}' LIMIT 10"; //error_log($q); $r = pg_query($db, $q); $results = []; if ($r && pg_num_rows($r)) { while ($f = pg_fetch_assoc($r)) { $f["address"] = html_entity_decode($f["address"],ENT_QUOTES|ENT_HTML5,"UTF-8"); $results[] = $f; } if (count($results) > 9) { return $results; } } if ($country == 'SG') { $q = "SELECT id as singapore_buildings_id, address, latitude, longitude, 1 AS timezone, NOW() as geocoding_date, postal, 'SG' AS country, building AS description, 'Asia/Singapore' AS \"timeZoneId\" "; $q .= " FROM singapore_buildings WHERE UPPER(address) ILIKE ('%${db_address}%') LIMIT 10"; $r = pg_query($db, $q); if ($r && pg_num_rows($r)) { while ($f = pg_fetch_assoc($r)) { $f["address"] = html_entity_decode($f["address"],ENT_QUOTES|ENT_HTML5,"UTF-8"); $results[] = $f; } return $results; } } /* savvy=> \d singapore_buildings Table "public.singapore_buildings" Column | Type | Modifiers -----------+------------------------+------------------------------------------------------------------ id | integer | not null default nextval('singapore_buildings_id_seq'::regclass) address | character varying(150) | not null blk_no | character varying(10) | building | character varying(100) | latitude | numeric | longitude | numeric | postal | character varying(6) | not null road_name | character varying(40) | not null searchval | character varying(100) | not null x | numeric | y | numeric | Indexes: "singapore_buildings_pkey" PRIMARY KEY, btree (id) savvy=> \d address Table "public.address" Column | Type | Modifiers ----------------+------------------------+------------------------------------------------------ id | bigint | not null default nextval('address_id_seq'::regclass) address | character varying(200) | latitude | numeric | longitude | numeric | timezone | integer | geocoding_date | date | postal | character varying(40) | country | character varying(2) | default 'SG'::character varying geometry | geography(Point,4326) | description | character varying(100) | */ return $results; } public function recentTrips($db, $member_id, $country, $address) { $db_country = pg_escape_string($country); // is not used for now... $db_address = pg_escape_string(html_entity_decode($address,ENT_QUOTES|ENT_HTML5,"UTF-8")); $q = "SELECT a.location_start_id, a.location_end_id "; $q .= " FROM trackedemail_item b, parsedemail_item a "; $q .= " LEFT JOIN address c ON (c.id=a.location_start_id) LEFT JOIN address d ON (d.id=a.location_end_id) "; $q .= " WHERE b.id=a.trackedemail_item_id AND b.member_id=" . ((int) $member_id); $q .= " AND (c.country='${db_country}' OR d.country='${db_country}')"; $q .= " ORDER BY a.travel_date DESC LIMIT 10"; //error_log($q); $r = pg_query($db, $q); $results = []; $address = []; if ($r && pg_num_rows($r)) { while ($f = pg_fetch_assoc($r)) { if (!array_key_exists($f["location_start_id"], $address)) { $results[] = self::getAddressById($db, $f["location_start_id"]); $address[$f["location_start_id"]] = 1; } if (!array_key_exists($f["location_end_id"], $address)) { $results[] = self::getAddressById($db, $f["location_end_id"]); $address[$f["location_end_id"]] = 1; } } return $results; } return null; } public function favourites($db, $member_id, $country, $address) { // Not implemented return null; } public static function getTzById($db, $id) { syslog(LOG_WARNING, "Address::getTzById(\$db, $id)"); $q = "SELECT timezone FROM address_timezone WHERE id=" . ((int) $id); //syslog(LOG_WARNING,$q); $r = pg_query($db, $q); if ($r && pg_num_rows($r) && $f = pg_fetch_row($r)) { return $f[0]; } return 'America/Los_Angeles'; // 2 } public static function getTzByAddressId($db, $id) { syslog(LOG_WARNING, "Address::getTzByAddressId(\$db, $id)"); $q = "SELECT timezone FROM address_timezone WHERE id=(SELECT timezone FROM address WHERE id=" . ((int) $id) . ")"; //syslog(LOG_WARNING,"ActivityApi: ".$q); $r = pg_query($db, $q); if ($r && pg_num_rows($r) && $f = pg_fetch_row($r)) { //syslog(LOG_WARNING,"ActivityApi: ".$f[0]); return $f[0]; } else { //syslog(LOG_WARNING,"ActivityApi: ".pg_last_error()); } return 'America/Los_Angeles'; // 2 } public static function getCity($db, $city, $country_code, $latitude='', $longitude='') { $q = "SELECT id FROM geofence_area_city WHERE (LOWER(city) ILIKE '" . strtolower($city) . "' AND country='" . $country_code . "') OR (latitude = '${latitude}' AND longitude ='${longitude}') LIMIT 1"; $r = pg_query($db, $q); if ($r && pg_num_rows($r) && $f = pg_fetch_assoc($r)) { return $f['id']; } else { return null; } } public static function insertCity($db, $city, $country_code, $latitude, $longitude) { $i = "INSERT INTO geofence_area_city (city,country,latitude,longitude,location) VALUES ('${city}','${country_code}',${latitude},${longitude},ST_SetSRID(ST_MakePoint(${longitude},${latitude}), 4326)) RETURNING id"; $city_id=null; $r = pg_query($db, $i); if ($r && pg_num_rows($r) && $f = pg_fetch_row($r)) { $city_id = $f[0]; } return $city_id; } public function getClosestPostalCode($latitude, $longitude, $country, $distance = 50000) { $q = "SELECT postal, ST_DistanceSphere(geometry::geometry, ST_SetSRID(ST_MakePoint(" . $longitude . ", " . $latitude . "),4326)) AS distance FROM geoname_postal_code WHERE ST_DistanceSphere(geometry::geometry, ST_SetSRID(ST_MakePoint(" . $longitude . ", " . $latitude . "),4326)) BETWEEN 0 AND " . $distance . " AND country='" . $country . "' ORDER BY distance LIMIT 1;"; $r = pg_query($q); if ($r && pg_num_rows($r) && $f = pg_fetch_assoc($r)) { return $f['postal']; } return null; } } // vi:ts=2