Files
dev-chiefworks 47f4fad75c Added Other AP
2022-04-26 11:30:34 -04:00

368 lines
15 KiB
PHP

<?php
class ActivityDirectApi extends Api
{
public $apiName = 'activitydirect';
public function indexAction()
{
return $this->response(
array(
'error' => 'Data not found'
), 404);
}
/**
* Method GET
* Get single record (by id)
* http://DOMAIN/trips/1
* @return string
*/
public function viewAction()
{
return $this->response(
array(
'error'=> 'Data not found'
), 404);
}
public function createAction()
{
syslog(LOG_WARNING,'ActivityDirectApi::createAction()');
$message = 'No recent activity found';
$code = 404;
$time = $this->requestParams['time'] ?? '';
$location = $this->requestParams['location'] ?? [];
$country = $this->requestParams['country'] ?? ActivityDirect::DEFAULT_COUNTRY;
$member_id = $this->requestParams['member_id'] ?? 0;
try {
syslog(LOG_WARNING,'country='.$country);
$db = new Db();
$country = Geocode::mockGPSCountry($db->getConnect(), $member_id, $country, 'default');
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)<ActivityDirect::TIME_LIMIT) {
throw new RuntimeException('Invalid time',500);
}
$address = NULL;
$street_address = "";
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=="") {
syslog(LOG_WARNING,'Reverse geocoder failed for ('.$location["lat"].', '.$location["lng"].')');
throw new RuntimeException($err?"Geocoder failed: $err":'Cannot geocode your GSP location',500);
}
syslog(LOG_WARNING,"street_address=".json_encode($street_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',500);
}
syslog(LOG_WARNING,json_encode($address));
}
// Step 1. Get activities
list($res,$err) = ActivityDirect::getActivity(
$db->getConnect(), $db->getConnectGPS(), $member_id,
$location["lat"], $location["lng"], ActivityDirect::ACTIVITY_RADIUS,
$time, ActivityDirect::TIME_DELTA, $country);
if (!$res || count($res)<1) {
if ($err!="") {
throw new RuntimeException($err, 500);
}
throw new RuntimeException('No recent activity found', 404);
}
syslog(LOG_WARNING,'Recent activity has '.count($res).' trips!');
//ActivityDirectApi::debugTrips($res,'0');
$destination_cache = [];
$result = [];
$i = 0;
foreach ($res as $trip) {
//ActivityDirectApi::debugTrips([$trip],'1');
$trip['mode'] = 'rideshare';
$trip['steps'] = [];
$advice = [
"trip"=>$trip,
"scooter"=>[],
"multimodal"=>[],
"rideshare"=>$trip,
"faster"=>NULL,
"cheaper"=>NULL
];
//ActivityDirectApi::debugTrips([$advice],'2');
if ($advice && count($advice)>0) {
$result[] = $advice;
$i++;
}
if ($i>=ActivityDirect::DEFAULT_OPTIONS) {
break;
}
}
//syslog(LOG_WARNING,json_encode($result));
//ActivityDirectApi::debugTrips($result,'3');
//$result = self::processQuotesTrips($db, $member_id, $country, $result);
//ActivityDirectApi::debugTrips($result,'4');
//$result = self::processGojekOption($db, $member_id, $country, $result);
//ActivityDirectApi::debugTrips($result,'5');
//syslog(LOG_WARNING,json_encode($result));
return $this->response(
array(
"trips" => $result,
"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);
}
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);
}
protected function checkCache($trip, $cache) {
syslog(LOG_WARNING,'ActivityDirectApi::checkCache()');
foreach ($cache as $item) {
if ($item["id"]>0 && $item["id"]==$trip["id"]) {
return [false, $cache];
}
if ($item["location_end_id"]==$trip["location_end_id"]) {
return [false, $cache];
}
}
$cache[] = $trip;
return [true, $cache];
}
public static function processGojekOption($db, $member_id, $country, $trips) {
syslog(LOG_WARNING,"ActivityDirectApi::processGojekOption(\$db, $member_id, $country, \$trips)");
//"trips"=>$trips;
if (!is_array($trips) && count($trips)<1) {
syslog(LOG_WARNING,"Invalid trips!");
return $trips; // No idea how to handle it
}
$trip = $trips[0];
if (!array_key_exists('trip',$trip) || !is_array($trip['trip']) || count($trip['trip'])<10) {
syslog(LOG_WARNING,"Invalid trip[0]!");
return $trips; // No idea how to handle it
}
$oldTrip = $trip['trip'];
$newTrip = [
'cheaper' => [],
'faster' => [],
'multimodal' => [],
'rideshare' => [],
'scooter' => [],
'trip' => $trip['trip']
];
$origin = Address::getAddressById($db->getConnect(), $oldTrip['location_start_id']);
$destination = Address::getAddressById($db->getConnect(), $oldTrip['location_end_id']);
list($res, $err) = GeocodeApi::route($db,
$origin['latitude'], $origin['longitude'],
$destination['latitude'], $destination['longitude'], 'driving'
);
if ($err!=NULL || !is_array($res) || !isset($res["routes"]) || count($res["routes"])<1) {
syslog(LOG_WARNING,'No available routes!');
syslog(LOG_WARNING,$err);
return $trips; // We cannot route driving!
}
$route_overlay = [];
$travel_time = PHP_INT_MAX;
$travel_distance = PHP_INT_MAX;
foreach ($res["routes"] as $route) {
$r = GeocodeApi::processRoute($route);
if ($travel_time>$r['duration']) {
$travel_time = $r['duration'];
$travel_distance = $r['distance'];
}
$route_overlay[] = $r;
}
$oldTrip["duration"] = $travel_time==PHP_INT_MAX ? NULL : $travel_time;
$oldTrip["distance"] = $travel_distance==PHP_INT_MAX ? NULL : $travel_distance;
/*
$result = [
'polyline' => array(),
'distance' => NULL,
'duration' => NULL,
'summary' => $route["summary"],
'overview_polyline' => $route["overview_polyline"],
'bounds' => $route["bounds"]
];
*/
//syslog(LOG_WARNING,json_encode($res));
$route = $res["routes"][0];
$route_leg = $route["legs"][0];
$route_leg_steps = $route_leg["steps"];
$overview_polyline = $route["overview_polyline"]["points"];
$leg_steps = [];
$distance = 0;
$duration = 0;
$location_start_lat = 0;
$location_start_lng = 0;
$location_end_lat = 0;
$location_end_lng = 0;
$polyline = [];
$i = 0; $j=1; $n = count($route_leg_steps);
for (; $i<$n; $i++) {
$step = $route_leg_steps[$i];
if ($step["travel_mode"] == "DRIVING") {
$location_start_lat = $step["start_location"]["lat"];
$location_start_lng = $step["start_location"]["lng"];
break;
}
$leg_steps[] = [
'distance' => $step["distance"]["value"],
'duration' => $step["duration"]["value"],
'html_instructions' => $step["html_instructions"],
'location_end_lat' => $step["end_location"]["lat"],
'location_end_lng' => $step["end_location"]["lng"],
'location_start_lat' => $step["start_location"]["lat"],
'location_start_lng' => $step["start_location"]["lng"],
'polyline' => $step["polyline"]["points"], /*"yz|Fm_nxRi@e@_@P",*/
'sid' => $j++,
'travel_mode' => $step["travel_mode"]
];
}
for (;$i<$n; $i++) {
$step = $route_leg_steps[$i];
if ($step["travel_mode"] != "DRIVING") {
break;
}
$distance += $step["distance"]["value"];
$duration += $step["duration"]["value"];
$location_end_lat = $step["end_location"]["lat"];
$location_end_lng = $step["end_location"]["lng"];
$polyline[] = $step["polyline"]["points"];
}
$leg_steps[] = [
'distance' => $distance,
'duration' => $duration,
'fare_quote' => null,
'fare_raw' => null,
'html_instructions' => "Take Gojek to ".$destination["address"],
'location_end_lat' => $location_end_lat,
'location_end_lng' => $location_end_lng,
'location_start_lat' => $location_start_lat,
'location_start_lng' => $location_start_lng,
'polyline' => MultiModal::processPolyline($polyline),
'quote_group_id' => null,
'sid' => $j++,
'travel_mode' => "GOJEK"
];
for (;$i<$n; $i++) {
$step = $route_leg_steps[$i];
$leg_steps[] = [
'distance' => $step["distance"]["value"],
'duration' => $step["duration"]["value"],
'html_instructions' => $step["html_instructions"],
'location_end_lat' => $step["end_location"]["lat"],
'location_end_lng' => $step["end_location"]["lng"],
'location_start_lat' => $step["start_location"]["lat"],
'location_start_lng' => $step["start_location"]["lng"],
'polyline' => $step["polyline"]["points"], /*"yz|Fm_nxRi@e@_@P",*/
'sid' => $j++,
'travel_mode' => $step["travel_mode"]
];
}
$rideshare = [
'cost' => 1,
'cost_raw' => 1,
'count' => 1,
'country' => $country,
'distance' => $oldTrip['distance'],
'dup_id' => null,
'duration' => $oldTrip['duration'],
'id' => $oldTrip['id'],
'location_end' => $destination['address'],
'location_end_id' => $oldTrip['location_end_id'],
'location_end_lat' => $destination['latitude'],
'location_end_lng' => $destination['longitude'],
'location_end_tz' => $destination['timezone'],
'location_start' => $origin['address'],
'location_start_id' => $oldTrip['location_start_id'],
'location_start_lat' => $origin['latitude'],
'location_start_lng' => $origin['longitude'],
'location_start_tz' => $origin['timezone'],
'member_id' => $member_id,
'options' => [],
'parsedemail_item_id' => null, /* $trip['id'] ??? */
'private' => 't',
'scheduled' => null,
'trackedemail_item_id' => null,
'transport_provider_id' => null,
'travel_date' => $oldTrip['travel_date'],
'travel_date_end' => $oldTrip['travel_date_end'],
'updated' => $oldTrip['updated']
];
$leg_id = rand(1,10000);
$leg_fare = 1;
// TODO!
$leg = [
'id' => $leg_id,
'arrival_time' => "1569311499",
'arrival_time_zone' => $destination['timezone'],
'arrival_timezone' => "Asia/Singapore",
'departure_time' => "1569310392",
'departure_time_zone' => $origin['timezone'],
'departure_timezone' => "Asia/Singapore",
'distance' => $oldTrip['distance'],
'duration' => $oldTrip['duration'],
'fare_raw' => 1,
'polyline' => $overview_polyline,
'quote' => 1,
'steps' => count($leg_steps),
];
$options = [
'gid' => $leg_id, /* ??? */
'leg_fare' => [$leg_id => $leg_fare],
'leg_steps' => [$leg_id => $leg_steps],
'legs' => [$leg],
'routes' => 1
];
$rideshare['options'] = $options;
$newTrip['rideshare'] = $rideshare;
if (count($trips)>2) {
array_shift($trips); // Remove the first element
}
$trips[] = $newTrip;
return $trips;
}
}