Added Other AP
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
|
||||
RewriteEngine On
|
||||
RewriteBase /SAVVY/advice/
|
||||
#RewriteBase /
|
||||
|
||||
#Checks to
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.*)$ index.php?/$1 [L]
|
||||
|
||||
</IfModule>
|
||||
|
||||
<IfModule !mod_rewrite.c>
|
||||
# If we don't have mod_rewrite installed, all 404's
|
||||
# can be sent to index.php, and everything works as normal.
|
||||
# Submitted by: ElliotHaughin
|
||||
|
||||
ErrorDocument 404 /index.php
|
||||
|
||||
</IfModule>
|
||||
|
||||
#Header add Access-Control-Allow-Origin "*"
|
||||
#Header add Access-Control-Expose-Headers "Access-Control-Allow-Origin"
|
||||
#Header add Access-Control-Allow-Headers "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With"
|
||||
#Header add Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
|
||||
#Header add Content-type "application/json"
|
||||
@@ -0,0 +1,347 @@
|
||||
<?php
|
||||
|
||||
class Destinations {
|
||||
|
||||
const TIME_DELTA = 180; // min (3 hrs)
|
||||
const TIME_LIMIT = 1262322000; // 2010-01-01
|
||||
const DEFAULT_COUNTRY = 'SG';
|
||||
const DEFAULT_OPTIONS = 5;
|
||||
const CITY_CURVATURE = 1.25;
|
||||
const CITY_SPEED = 0.667; // km/min (0.0667 = 40 km/h)
|
||||
const MIN_ACTIVITY_DISTANCE = 0.05; // 50m
|
||||
const MAX_ACTIVITY_DISTANCE = 50.0; // 50km
|
||||
|
||||
const ACTIVITY_RADIUS = 100000; // 100km
|
||||
|
||||
public static function byActivity($db, $gpsdb, $member_id, $lat, $lng, $radius, $time, $time_delta=Destinations::TIME_DELTA, $country=Destinations::DEFAULT_COUNTRY) {
|
||||
syslog(LOG_WARNING,"Activity::getActivity(\$db, \$gpsdb, $member_id, $lat, $lng, $radius, $time, $time_delta, $country)");
|
||||
$all_time_days = Destinations::getAllTimeDays();
|
||||
$res = [];
|
||||
|
||||
list($res1, $err1) = Destinations::activityByRangeAndTimeAndRadius(
|
||||
$gpsdb, $db, $member_id, $all_time_days, $lat, $lng, $radius, 'start', $time, $time_delta);
|
||||
if ($res1 && count($res1)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res1));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
syslog(LOG_WARNING,$err1);
|
||||
|
||||
list($res2, $err2) = Destinations::activityByRangeAndTimeAndRadius(
|
||||
$gpsdb, $db, $member_id, $all_time_days, $lat, $lng, $radius, 'end', $time, $time_delta);
|
||||
if ($res2 && count($res2)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res2));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
syslog(LOG_WARNING,$err2);
|
||||
|
||||
list($res3, $err3) = Destinations::activityByRangeAndRadius(
|
||||
$gpsdb, $db, $member_id, $all_time_days, $lat, $lng, $radius, 'start');
|
||||
if ($res3 && count($res3)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res3));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
syslog(LOG_WARNING,$err3);
|
||||
|
||||
list($res4, $err4) = Destinations::activityByRangeAndRadius(
|
||||
$gpsdb, $db, $member_id, $all_time_days, $lat, $lng, $radius, 'end');
|
||||
if ($res4 && count($res4)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res4));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
syslog(LOG_WARNING,$err4);
|
||||
|
||||
if ($country=='SG') {
|
||||
// For US it may produce the results too far apart
|
||||
list($res1, $err1) = Destinations::activityByRangeAndTime($db, $member_id, 7, $time, $time_delta, $country);
|
||||
if ($res1 && count($res1)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res1));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
list($res2, $err2) = Destinations::activityByRangeAndTime($db, $member_id, 30, $time, $time_delta, $country);
|
||||
if ($res2 && count($res2)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res2));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
list($res3, $err3) = Destinations::activityByRangeAndTime($db, $member_id, $all_time_days, $time, $time_delta, $country);
|
||||
if ($res3 && count($res3)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res3));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
list($res4, $err4) = Destinations::activityByRange($db, $member_id, 7, $country);
|
||||
if ($res4 && count($res4)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res4));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
list($res5, $err5) = Destinations::activityByRange($db, $member_id, 30, $country);
|
||||
if ($res5 && count($res5)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res5));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
list($res6, $err6) = Destinations::activityByRange($db, $member_id, $all_time_days, $country);
|
||||
if ($res6 && count($res6)>0) {
|
||||
$res = Destinations::uniqueTrips(array_merge($res,$res6));
|
||||
if (count($res)>=Destinations::DEFAULT_OPTIONS) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
}
|
||||
}
|
||||
//*/
|
||||
if ($res && count($res)>0) {
|
||||
return [$res, NULL];
|
||||
}
|
||||
return [NULL, "We could not find any recent activity in this area"];
|
||||
}
|
||||
|
||||
public static function getAddressActivity($db, $address, $member_id, $time, $time_delta=Destinations::TIME_DELTA) {
|
||||
// TODO: radius search
|
||||
|
||||
}
|
||||
/*
|
||||
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) |
|
||||
city_id | integer |
|
||||
*/
|
||||
|
||||
public static function activityByRange($db, $member_id, $days, $country=Destinations::DEFAULT_COUNTRY) {
|
||||
$db_time = strtotime($time);
|
||||
$db_days = date("w",$db_time) + (int)$days;
|
||||
$db_country = pg_escape_string($country);
|
||||
$q = "SELECT b.*, 60*date_part('hour', b.travel_date)+date_part('minute',b.travel_date) AS dm ";
|
||||
/////// Start Locations ///////
|
||||
$q.= ", c.address AS location_start_address, c.latitude AS location_start_lat, c.longitude AS location_start_lng";
|
||||
$q.= ", c.timezone AS location_start_timezone, c.postal AS location_start_postal, c.country AS location_start_country";
|
||||
$q.= ", c.description AS location_start_description, c.city_id AS location_start_city_id, c.geometry AS location_start_geometry ";
|
||||
$q.= ", d.address AS location_end_address, d.latitude AS location_end_lat, d.longitude AS location_end_lng";
|
||||
$q.= ", d.timezone AS location_end_timezone, d.postal AS location_end_postal, d.country AS location_end_country";
|
||||
$q.= ", d.description AS location_end_description, d.city_id AS location_end_city_id, d.geometry AS location_end_geometry ";
|
||||
/////// End Locations ///////
|
||||
$q.= " FROM trackedemail_item a, parsedemail_item b ";
|
||||
$q.= " LEFT JOIN address c ON (c.id=b.location_start_id) ";
|
||||
$q.= " LEFT JOIN address d ON (d.id=b.location_end_id) ";
|
||||
$q.= " WHERE a.id=b.trackedemail_item_id AND a.member_id=".((int)$member_id);
|
||||
$q.= " AND b.dup_id IS NULL AND b.travel_date_end > (now() - interval '${db_days} days') ";
|
||||
$q.= " AND (c.country='${db_country}' OR d.country='${db_country}') ";
|
||||
$q.= " ORDER BY b.travel_date DESC LIMIT ".Destinations::DEFAULT_OPTIONS;
|
||||
syslog(LOG_WARNING,$q);
|
||||
$r = pg_query($db, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$result = [];
|
||||
while ($f=pg_fetch_assoc($r)) {
|
||||
$f["location_start_address"] = html_entity_decode ($f["location_start_address"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
||||
$f["location_end_address"] = html_entity_decode ($f["location_end_address"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
||||
$result[] = $f;
|
||||
}
|
||||
return [$result, NULL];
|
||||
}
|
||||
return [NULL,pg_last_error()];
|
||||
}
|
||||
|
||||
public static function activityByRangeAndRadius($gpsdb, $db, $member_id, $days, $lat, $lng, $radius, $what) {
|
||||
syslog(LOG_WARNING,"Activity::activityByRangeAndRadius(\$gpsdb, \$db, $member_id, $days, $lat, $lng, $radius, $what)");
|
||||
$limit_lat = (float)$lat;
|
||||
$limit_lng = (float)$lng;
|
||||
$limit_rad = $radius;
|
||||
$db_days = (int)$days;
|
||||
$q = "SELECT b.*, 60*date_part('hour', b.travel_date)+date_part('minute',b.travel_date) AS dm ";
|
||||
/////// Start Locations ///////
|
||||
$q.= ", c.address AS location_start_address, c.latitude AS location_start_lat, c.longitude AS location_start_lng";
|
||||
$q.= ", c.timezone AS location_start_timezone, c.postal AS location_start_postal, c.country AS location_start_country";
|
||||
$q.= ", c.description AS location_start_description, c.city_id AS location_start_city_id, c.geometry AS location_start_geometry ";
|
||||
$q.= ", d.address AS location_end_address, d.latitude AS location_end_lat, d.longitude AS location_end_lng";
|
||||
$q.= ", d.timezone AS location_end_timezone, d.postal AS location_end_postal, d.country AS location_end_country";
|
||||
$q.= ", d.description AS location_end_description, d.city_id AS location_end_city_id, d.geometry AS location_end_geometry ";
|
||||
/////// End Locations ///////
|
||||
$q.= " FROM trackedemail_item a, parsedemail_item b ";
|
||||
$q.= " LEFT JOIN address c ON (c.id=b.location_start_id) ";
|
||||
$q.= " LEFT JOIN address d ON (d.id=b.location_end_id) ";
|
||||
$q.= " WHERE a.id=b.trackedemail_item_id AND a.member_id=".((int)$member_id);
|
||||
$q.= " AND b.dup_id IS NULL AND b.travel_date_end > (now() - interval '${db_days} days') ";
|
||||
//$q.= " AND (b.location_start_id IN (%d,%d) OR b.location_end_id IN (%d,%d)) ";
|
||||
$q.= " AND (";
|
||||
$q.= "ST_DWithin(c.geometry,ST_SetSRID(ST_MakePoint(${limit_lng},${limit_lat}),4326)::geography,${limit_rad})";
|
||||
$q.= " OR ";
|
||||
$q.= "ST_DWithin(d.geometry,ST_SetSRID(ST_MakePoint(${limit_lng},${limit_lat}),4326)::geography,${limit_rad})";
|
||||
$q.= ") ORDER BY b.travel_date DESC LIMIT ".Destinations::DEFAULT_OPTIONS;
|
||||
syslog(LOG_WARNING,$q);
|
||||
$r = pg_query($db, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$cache_from = [];
|
||||
$cache_to = [];
|
||||
$result = [];
|
||||
while ($f = pg_fetch_assoc($r)) {
|
||||
if (array_key_exists($f["location_start_geometry"],$cache_from) && $f["location_end_geometry"]==$cache_from[$f["location_start_geometry"]]) {
|
||||
continue; // We have similar trip in result set - let's skip it
|
||||
}
|
||||
if (array_key_exists($f["location_end_geometry"],$cache_to) && $f["location_start_geometry"]==$cache_to[$f["location_end_geometry"]]) {
|
||||
continue; // We have similar trip in result set - let's skip it
|
||||
}
|
||||
$f["location_start_address"] = html_entity_decode ($f["location_start_address"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
||||
$f["location_end_address"] = html_entity_decode ($f["location_end_address"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
||||
$result[] = $f;
|
||||
$cache_from[$f["location_start_geometry"]] = $f["location_end_geometry"];
|
||||
$cache_to[$f["location_end_geometry"]] = $f["location_start_geometry"];
|
||||
}
|
||||
unset($cache_from); // clear
|
||||
unset($cache_to); // clear
|
||||
return [$result, NULL];
|
||||
}
|
||||
return [NULL,pg_last_error()];
|
||||
}
|
||||
|
||||
public static function activityByRangeAndTimeAndRadius($gpsdb, $db, $member_id, $days, $lat, $lng, $radius, $what, $time, $time_delta=Destinations::TIME_DELTA) {
|
||||
syslog(LOG_WARNING,"Activity::activityByRangeAndTimeAndRadius(\$gpsdb, \$db, $member_id, $days, $lat, $lng, $radius, $what, $time, $time_delta)");
|
||||
$limit_lat = (float)$lat;
|
||||
$limit_lng = (float)$lng;
|
||||
$limit_rad = $radius;
|
||||
$db_time = strtotime($time);
|
||||
$db_days = date("w",$db_time) + (int)$days;
|
||||
$db_time_delta = (int)$time_delta;
|
||||
syslog(LOG_WARNING,"${db_time}=".date("Y-m-d H:i",$db_time));
|
||||
// Ranges
|
||||
$dh = 60*date("G",$db_time)+date("i",$db_time);
|
||||
$d1 = $dh - $db_time_delta;
|
||||
$d2 = $dh + $db_time_delta;
|
||||
syslog(LOG_WARNING,"${d1} <= x <= ${d2}");
|
||||
$q = "SELECT e.* FROM (SELECT b.*, 60*date_part('hour', b.travel_date)+date_part('minute',b.travel_date) AS dm ";
|
||||
/////// Start Locations ///////
|
||||
$q.= ", c.address AS location_start_address, c.latitude AS location_start_lat, c.longitude AS location_start_lng";
|
||||
$q.= ", c.timezone AS location_start_timezone, c.postal AS location_start_postal, c.country AS location_start_country";
|
||||
$q.= ", c.description AS location_start_description, c.city_id AS location_start_city_id, c.geometry AS location_start_geometry ";
|
||||
$q.= ", d.address AS location_end_address, d.latitude AS location_end_lat, d.longitude AS location_end_lng";
|
||||
$q.= ", d.timezone AS location_end_timezone, d.postal AS location_end_postal, d.country AS location_end_country";
|
||||
$q.= ", d.description AS location_end_description, d.city_id AS location_end_city_id, d.geometry AS location_end_geometry ";
|
||||
/////// End Locations ///////
|
||||
$q.= " FROM trackedemail_item a, parsedemail_item b ";
|
||||
$q.= " LEFT JOIN address c ON (c.id=b.location_start_id) ";
|
||||
$q.= " LEFT JOIN address d ON (d.id=b.location_end_id) ";
|
||||
$q.= " WHERE a.id=b.trackedemail_item_id AND a.member_id=".((int)$member_id);
|
||||
$q.= " AND b.dup_id IS NULL AND b.travel_date_end > (now() - interval '${db_days} days') ";
|
||||
$q.= " AND (";
|
||||
$q.= "ST_DWithin(c.geometry,ST_SetSRID(ST_MakePoint(${limit_lng},${limit_lat}),4326)::geography,${limit_rad})";
|
||||
$q.= " OR ";
|
||||
$q.= "ST_DWithin(d.geometry,ST_SetSRID(ST_MakePoint(${limit_lng},${limit_lat}),4326)::geography,${limit_rad})";
|
||||
$q.= ")) AS e ";
|
||||
$q.= " WHERE e.dm>=${d1} AND e.dm<=${d2} ";
|
||||
$q.= " ORDER BY e.travel_date DESC LIMIT ".Destinations::DEFAULT_OPTIONS;
|
||||
syslog(LOG_WARNING,$q);
|
||||
$r = pg_query($db, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
syslog(LOG_WARNING,"parsedemail_item(s) to process: ".pg_num_rows($r));
|
||||
$cache_from = [];
|
||||
$cache_to = [];
|
||||
$result = [];
|
||||
while ($f=pg_fetch_assoc($r)) {
|
||||
if (array_key_exists($f["location_start_geometry"],$cache_from) && $f["location_end_geometry"]==$cache_from[$f["location_start_geometry"]]) {
|
||||
continue; // We have similar trip in result set - let's skip it
|
||||
}
|
||||
if (array_key_exists($f["location_end_geometry"],$cache_to) && $f["location_start_geometry"]==$cache_to[$f["location_end_geometry"]]) {
|
||||
continue; // We have similar trip in result set - let's skip it
|
||||
}
|
||||
$f["location_start_address"] = html_entity_decode ($f["location_start_address"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
||||
$f["location_end_address"] = html_entity_decode ($f["location_end_address"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
||||
$result[] = $f;
|
||||
}
|
||||
unset($cache_from); // clear
|
||||
unset($cache_to); // clear
|
||||
return [$result, NULL];
|
||||
}
|
||||
return [NULL,pg_last_error()];
|
||||
}
|
||||
|
||||
public static function activityByRangeAndTime($db, $member_id, $days, $time, $time_delta=Destinations::TIME_DELTA, $country=Destinations::DEFAULT_COUNTRY) {
|
||||
syslog(LOG_WARNING,"Activity::activityByRangeAndTime(\$db, $member_id, $days, $time, $time_delta");
|
||||
$db_time = strtotime($time);
|
||||
$db_days = date("w",$db_time) + (int)$days;
|
||||
$db_time_delta = (int)$time_delta;
|
||||
$db_country = pg_escape_string($country);
|
||||
syslog(LOG_WARNING,"${db_time}=".date("Y-m-d H:i",$db_time));
|
||||
// Ranges
|
||||
$dh = 60*date("G",$db_time)+date("i",$db_time);
|
||||
$d1 = $dh - $db_time_delta;
|
||||
$d2 = $dh + $db_time_delta;
|
||||
syslog(LOG_WARNING,"${d1} <= x <= ${d2}");
|
||||
$q = "SELECT e.* FROM (SELECT b.*, 60*date_part('hour', b.travel_date)+date_part('minute',b.travel_date) AS dm ";
|
||||
/////// Start Locations ///////
|
||||
$q.= ", c.address AS location_start_address, c.latitude AS location_start_lat, c.longitude AS location_start_lng";
|
||||
$q.= ", c.timezone AS location_start_timezone, c.postal AS location_start_postal, c.country AS location_start_country";
|
||||
$q.= ", c.description AS location_start_description, c.city_id AS location_start_city_id, c.geometry AS location_start_geometry ";
|
||||
$q.= ", d.address AS location_end_address, d.latitude AS location_end_lat, d.longitude AS location_end_lng";
|
||||
$q.= ", d.timezone AS location_end_timezone, d.postal AS location_end_postal, d.country AS location_end_country";
|
||||
$q.= ", d.description AS location_end_description, d.city_id AS location_end_city_id, d.geometry AS location_end_geometry ";
|
||||
/////// End Locations ///////
|
||||
$q.= " FROM trackedemail_item a, parsedemail_item b ";
|
||||
$q.= " LEFT JOIN address c ON (c.id=b.location_start_id) ";
|
||||
$q.= " LEFT JOIN address d ON (d.id=b.location_end_id) ";
|
||||
$q.= " WHERE a.id=b.trackedemail_item_id AND a.member_id=".((int)$member_id);
|
||||
$q.= " AND (c.country='${db_country}' OR d.country='${db_country}') ";
|
||||
$q.= " AND b.dup_id IS NULL AND b.travel_date_end > (now() - interval '${db_days} days')) AS e ";
|
||||
$q.= " WHERE e.dm>=${d1} AND e.dm<=${d2} ";
|
||||
$q.= " ORDER BY e.travel_date DESC LIMIT ".Destinations::DEFAULT_OPTIONS;
|
||||
syslog(LOG_WARNING,$q);
|
||||
$r = pg_query($db, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$result = [];
|
||||
while ($f=pg_fetch_assoc($r)) {
|
||||
$f["location_start_address"] = html_entity_decode ($f["location_start_address"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
||||
$f["location_end_address"] = html_entity_decode ($f["location_end_address"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
||||
$result[] = $f;
|
||||
}
|
||||
return [$result, NULL];
|
||||
}
|
||||
return [NULL,pg_last_error()];
|
||||
}
|
||||
|
||||
protected static function getAllTimeDays() {
|
||||
$datediff = time() - Destinations::TIME_LIMIT;
|
||||
return round($datediff / (60 * 60 * 24));
|
||||
}
|
||||
|
||||
protected static function uniqueTrips($res) {
|
||||
$cache = [];
|
||||
$result = [];
|
||||
foreach ($res as $trip) {
|
||||
$key1ids = $trip["location_start_id"]."_".$trip["location_end_id"];
|
||||
$key1gps = $trip["location_start_lat"]."_".$trip["location_start_lng"]."_".$trip["location_end_lat"]."_".$trip["location_end_lng"];
|
||||
$key2ids = $trip["location_end_id"]."_".$trip["location_start_id"];
|
||||
$key2gps = $trip["location_end_lat"]."_".$trip["location_end_lng"]."_".$trip["location_start_lat"]."_".$trip["location_start_lng"];
|
||||
if (array_key_exists($key1ids, $cache) || array_key_exists($key2ids, $cache)) {
|
||||
continue;
|
||||
}
|
||||
if (array_key_exists($key1gps, $cache) || array_key_exists($key2gps, $cache)) {
|
||||
continue;
|
||||
}
|
||||
$cache[$key1ids] = $key2ids;
|
||||
$cache[$key1gps] = $key2gps;
|
||||
$result[] = $trip;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
// vi:ts=2
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
class DestinationsApi extends Api
|
||||
{
|
||||
public $apiName = 'destinations';
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
return $this->response(
|
||||
array(
|
||||
'error' => 'Data not found'
|
||||
), 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method GET
|
||||
* Get single record (by id)
|
||||
* http://DOMAIN/destinations/1
|
||||
* @return string
|
||||
*/
|
||||
public function viewAction()
|
||||
{
|
||||
return $this->response(
|
||||
array(
|
||||
'error'=> 'Data not found'
|
||||
), 404);
|
||||
}
|
||||
|
||||
public function createAction()
|
||||
{
|
||||
syslog(LOG_WARNING,'DestinationsApi::createAction()');
|
||||
$message = 'We could not find any recent activity in this area';
|
||||
$code = 404;
|
||||
$time = $this->requestParams['time'] ?? '';
|
||||
$location = $this->requestParams['location'] ?? [];
|
||||
$country = $this->requestParams['country'] ?? '';
|
||||
$member_id = $this->requestParams['member_id'] ?? 0;
|
||||
try {
|
||||
$db = new Db();
|
||||
|
||||
$country = Geocode::getCountryByGPS($db->getConnect(), $location, $country, Destinations::DEFAULT_COUNTRY);
|
||||
syslog(LOG_WARNING,'country='.$country);
|
||||
|
||||
$country = Geocode::mockGPSCountry($db->getConnect(), $member_id, $country, 'default');
|
||||
|
||||
$gps_country_code = $country; // Guessed
|
||||
|
||||
if ($country!='US' && $country!='SG') {
|
||||
throw new RuntimeException('Trips has not yet launched in your country. You can still track your travel activity and access exclusive deals. Start exploring!',500);
|
||||
}
|
||||
if ($member_id<1) {
|
||||
throw new RuntimeException('Invalid member ID',500);
|
||||
}
|
||||
if ($time=='' || strtotime($time)<Destinations::TIME_LIMIT) {
|
||||
throw new RuntimeException('Invalid time',500);
|
||||
}
|
||||
$address = NULL;
|
||||
$street_address = "";
|
||||
syslog(LOG_WARNING, "location => " . json_encode($location));
|
||||
|
||||
if (is_array($location) && isset($location["lat"]) && isset($location["lng"])) {
|
||||
// DEBUG
|
||||
list($location["lat"],$location["lng"]) = Geocode::mockGPSLocation(
|
||||
$db->getConnect(), $member_id, $location["lat"], $location["lng"], 'default');
|
||||
|
||||
syslog(LOG_WARNING,"lat=".$location["lat"].",lng=".$location["lng"]);
|
||||
list($street_address,$err) = GeocodeApi::reverseGeocode($db, $location["lat"], $location["lng"]);
|
||||
if ($street_address=="") {
|
||||
list($address,$err) = GeofenceApi::getAnchor($db, $location["lat"], $location["lng"]);
|
||||
if (is_array($address) && array_key_exists("address",$address) && $address["address"]!="") {
|
||||
$street_address = $address["address"];
|
||||
}
|
||||
}
|
||||
if ($street_address=="") {
|
||||
syslog(LOG_WARNING,'Reverse geocoder failed for ('.$location["lat"].', '.$location["lng"].')');
|
||||
throw new RuntimeException($err?"Geocoder failed: $err":'Cannot geocode your GPS location',500);
|
||||
}
|
||||
syslog(LOG_WARNING,"street_address=".json_encode($street_address));
|
||||
if (!is_array($address) || !array_key_exists("address",$address) || $address["address"]=="") {
|
||||
list($address,$err) = Geocode::checkLatLngByAddress($db->getConnect(), $street_address, $country);
|
||||
}
|
||||
if (!is_array($address) || !isset($address["address"])) {
|
||||
syslog(LOG_WARNING,'Geocoder failed for "'.$street_address.'"');
|
||||
throw new RuntimeException($err?"Geocoder failed: $err":'Cannot get address for your GPS location '.$street_address,500);
|
||||
}
|
||||
// Adjust GPS coordinates if any
|
||||
if (array_key_exists("latitude", $address) && $address["latitude"]!=null &&
|
||||
array_key_exists("longitude",$address) && $address["longitude"]!=null &&
|
||||
$address["latitude"]!=0 && $address["longitude"]!=0) {
|
||||
$location["lat"] = $address["latitude"];
|
||||
$location["lng"] = $address["longitude"];
|
||||
$address["lat"] = $address["latitude"];
|
||||
$address["lng"] = $address["longitude"];
|
||||
} else if (array_key_exists("lat",$address) && $address["lat"]!=null &&
|
||||
array_key_exists("lng",$address) && $address["lng"]!=null &&
|
||||
$address["lat"]!=0 && $address["lng"]!=0) {
|
||||
$location["lat"] = $address["lat"];
|
||||
$location["lng"] = $address["lng"];
|
||||
$address["latitude"] = $address["lat"];
|
||||
$address["longitude"] = $address["lng"];
|
||||
}
|
||||
list($location,$address) = DestinationsApi::adjustAddressLocationGPS($location,$address);
|
||||
if (is_array($address) && array_key_exists("country",$address)) {
|
||||
$gps_country_code = $address["country"]; // Geocoded
|
||||
}
|
||||
}
|
||||
|
||||
// Step 0. Check if we are in the service area
|
||||
/* GeocodeApi::checkWithinTheServiceArea($country,[
|
||||
[
|
||||
"type"=>1,
|
||||
"geocode" => [
|
||||
"lat" => $location["lat"],
|
||||
"lng" => $location["lng"]
|
||||
]
|
||||
]
|
||||
]); //*/
|
||||
syslog(LOG_WARNING, "location => " . json_encode($location));
|
||||
|
||||
// Step 1. Get activities
|
||||
list($res,$err) = Destinations::byActivity(
|
||||
$db->getConnect(), $db->getConnectGPS(), $member_id,
|
||||
$location["lat"], $location["lng"], Destinations::ACTIVITY_RADIUS,
|
||||
$time, Destinations::TIME_DELTA, $country);
|
||||
if (!$res || count($res)<1) {
|
||||
if ($err!="") {
|
||||
throw new RuntimeException($err, 500);
|
||||
}
|
||||
throw new RuntimeException($message, 404);
|
||||
}
|
||||
syslog(LOG_WARNING,'Recent activity has '.count($res).' trips!');
|
||||
//DestinationsApi::debugTrips($res,'0');
|
||||
return $this->response(
|
||||
array(
|
||||
"trips" => $res,
|
||||
"address" => $address,
|
||||
"country" => $country,
|
||||
"gps_country_code" => $gps_country_code,
|
||||
"street_address" => html_entity_decode($street_address)
|
||||
), 200);
|
||||
} catch (RuntimeException $e) {
|
||||
$message = $e->getMessage();
|
||||
$code = $e->getCode();
|
||||
syslog(LOG_WARNING,$message);
|
||||
}
|
||||
return $this->response(
|
||||
array(
|
||||
"error" => $message
|
||||
), $code);
|
||||
}
|
||||
|
||||
private static function adjustAddressLocationGPS($location,$address) {
|
||||
syslog(LOG_WARNING,'DestinationsApi::adjustAddressLocationGPS($location,$address)');
|
||||
if (array_key_exists("latitude", $address) && $address["latitude"]!=null &&
|
||||
array_key_exists("longitude",$address) && $address["longitude"]!=null &&
|
||||
$address["latitude"]!=0 && $address["longitude"]!=0) {
|
||||
$location["lat"] = $address["latitude"];
|
||||
$location["lng"] = $address["longitude"];
|
||||
$address["lat"] = $address["latitude"];
|
||||
$address["lng"] = $address["longitude"];
|
||||
} else if (array_key_exists("lat",$address) && $address["lat"]!=null &&
|
||||
array_key_exists("lng",$address) && $address["lng"]!=null &&
|
||||
$address["lat"]!=0 && $address["lng"]!=0) {
|
||||
$location["lat"] = $address["lat"];
|
||||
$location["lng"] = $address["lng"];
|
||||
$address["latitude"] = $address["lat"];
|
||||
$address["longitude"] = $address["lng"];
|
||||
}
|
||||
//syslog(LOG_WARNING,json_encode($address));
|
||||
//syslog(LOG_WARNING,"location => " . json_encode($location));
|
||||
return [$location,$address];
|
||||
}
|
||||
|
||||
public static function debugTrips($trips,$what='0') {
|
||||
return; /*
|
||||
foreach ($trips as $trip) {
|
||||
$leg_fare = $trip['multimodal']['options']['leg_fare'];
|
||||
syslog(LOG_WARNING,'>>>>>>> '.$what.' >>>>>>> '.json_encode($leg_fare));
|
||||
}*/
|
||||
}
|
||||
|
||||
public function updateAction()
|
||||
{
|
||||
return $this->response(
|
||||
array(
|
||||
"error" => "Update error"
|
||||
), 400);
|
||||
}
|
||||
|
||||
public function deleteAction()
|
||||
{
|
||||
return $this->response(
|
||||
array(
|
||||
"error" => "Delete error"
|
||||
), 500);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
require_once('../../core/backend.php');
|
||||
require_once('../constants.php');
|
||||
|
||||
require_once('../common/vendor/autoload.php');
|
||||
require_once('../common/Api.php');
|
||||
require_once('../common/Db.php');
|
||||
require_once('../common/GoogleKMS.php');
|
||||
require_once('../common/Logger.php');
|
||||
require_once('../common/Utilities.php');
|
||||
|
||||
require_once('Destinations.php');
|
||||
require_once('DestinationsApi.php');
|
||||
|
||||
require_once('../trips/Address.php');
|
||||
require_once('../trips/Geocode.php');
|
||||
require_once('../trips/GeocodeApi.php');
|
||||
require_once('../trips/Geofence.php');
|
||||
require_once('../trips/GeofenceApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
|
||||
header("Access-Control-Allow-Headers: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, client_id");
|
||||
header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
|
||||
header('Content-type: application/json');
|
||||
|
||||
if ("OPTIONS" === $_SERVER['REQUEST_METHOD']) {
|
||||
exit();
|
||||
}
|
||||
|
||||
$headers = getallheaders();
|
||||
if ((!isset($headers["Authorization"]) || substr($headers["Authorization"],-strlen($httpAuthToken))!=$httpAuthToken) &&
|
||||
(!isset($headers["authorization"]) || substr($headers["authorization"],-strlen($httpAuthToken))!=$httpAuthToken)) {
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
header('Status: 401 Unauthorized');
|
||||
echo "{\"status\":\"Missing authorization\"}";
|
||||
exit();
|
||||
}
|
||||
|
||||
try {
|
||||
if (strpos($_SERVER['REQUEST_URI'],'/api/')===false) {
|
||||
throw new Exception("Invalid API request");
|
||||
}
|
||||
$requestUri = explode('/', trim($_SERVER['REQUEST_URI'],'/'));
|
||||
while (array_shift($requestUri) !== 'api') {
|
||||
};
|
||||
if ($requestUri[0]=='destinations') {
|
||||
$api = new DestinationsApi($requestUri);
|
||||
}
|
||||
else {
|
||||
echo json_encode(Array('error' => 'Invalid API request'));
|
||||
}
|
||||
echo $api->run();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo json_encode(Array('error' => $e->getMessage()));
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 665 B |
Binary file not shown.
|
After Width: | Height: | Size: 628 B |
@@ -0,0 +1,60 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="swagger-ui-bundle.js"> </script>
|
||||
<script src="swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "../swagger.php",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
require('../../../adminsavvy/vendor/autoload.php');
|
||||
$openapi = \OpenApi\scan('.');
|
||||
header('Content-Type: application/json');
|
||||
echo $openapi->toJson();
|
||||
?>
|
||||
Reference in New Issue
Block a user