368 lines
15 KiB
PHP
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;
|
|
}
|
|
}
|