Added Other AP
This commit is contained in:
@@ -0,0 +1,828 @@
|
||||
<?php
|
||||
|
||||
class MultiModalApi extends Api
|
||||
{
|
||||
public $apiName = 'multimodal';
|
||||
const CACHE_TIMEOUT = 1800; // 30 minutes
|
||||
|
||||
public function indexAction() {
|
||||
syslog(LOG_WARNING,'MultiModalApi::indexAction()');
|
||||
// 16279
|
||||
$message = "Unexpected error";
|
||||
$leg_id = $this->requestParams["leg_id"] ?? 0;
|
||||
$country = $this->requestParams["country"] ?? 'SG';
|
||||
$member_id = $this->requestParams["member_id"] ?? 0;
|
||||
$advice_id = 0;
|
||||
try {
|
||||
if ($leg_id<1) {
|
||||
throw new Exception('Invalid trip leg ID');
|
||||
}
|
||||
$db = new Db();
|
||||
list ($leg, $err) = MultiModal::getLegById($db->getConnect(), (int)$leg_id);
|
||||
if (!$leg || !isset($leg['id']) || $leg['id']<1) {
|
||||
throw new Exception($err!=""?$err:'No trip leg found');
|
||||
}
|
||||
syslog(LOG_WARNING,'111111111');
|
||||
list ($advice, $err) = MultiModal::getLegAdviceGoogleById($db->getConnect(), (int)$leg['parsedemail_item_advice_google_id']);
|
||||
if ($advice && $advice['id']>0) {
|
||||
$advice_id = $advice['id'];
|
||||
} else {
|
||||
throw new Exception($err!=""?$err:'No google advice found');
|
||||
}
|
||||
// DEBUG
|
||||
$country = Geocode::mockGPSCountry($db->getConnect(), $member_id, $country, 'default');
|
||||
|
||||
list ($legs, $err) = MultiModal::getAdviceLegs($db->getConnect(), $advice_id);
|
||||
return MultiModalApi::processLegs($db, $legs, $advice_id, $country);
|
||||
} catch (Exception $e) {
|
||||
syslog(LOG_WARNING,json_encode($e));
|
||||
$message = $e->getMessage();
|
||||
}
|
||||
return $this->response(
|
||||
array(
|
||||
'error' => $message
|
||||
), 500);
|
||||
}
|
||||
|
||||
protected function processSteps($db, $leg, $ok) {
|
||||
list ($steps, $err) = MultiModal::getLegSteps($db->getConnect(), (int)$leg['id']);
|
||||
if ($steps || count($steps)>0) {
|
||||
$total = 0;
|
||||
$overview = [];
|
||||
foreach ($steps as $key=>$step) {
|
||||
$leg['step_fares'][$step['sid']] = NULL;
|
||||
// We support BUS, SUBWAY, TAXI only (and Singapore...)
|
||||
if ($step['travel_mode']=='TAXI' || $step['travel_mode']=='SCOOTER' ||
|
||||
($step['travel_mode']=='TRANSIT' && isset($step['vehicle']) &&
|
||||
($step['vehicle']='BUS' || $step['vehicle']=='SUBWAY'))) {
|
||||
if (isset($step['fare_raw']) && $step['fare_raw']!="") {
|
||||
// OK
|
||||
$total += (int)$step['fare_raw'];
|
||||
$leg['step_fares'][$step['sid']] = (int)$step['fare_raw'];
|
||||
} else {
|
||||
// Not OK
|
||||
$ok = false;
|
||||
error_log('No quote for step_id='.$step['sid'].' traveling by '.(isset($step['vehicle'])?$step['vehicle']:"NO VEHICLE"));
|
||||
}
|
||||
} else {
|
||||
error_log('Unsupported travel mode: '.$step['travel_mode']."/".(isset($step['vehicle'])?$step['vehicle']:"NO VEHICLE"));
|
||||
}
|
||||
if (array_key_exists("polyline",$step)) {
|
||||
$overview[] = $step["polyline"];
|
||||
}
|
||||
if (!array_key_exists('duration',$step) || $step['duration']<60) {
|
||||
$step['duration'] = 60;
|
||||
}
|
||||
$steps[$key] = $step;
|
||||
}
|
||||
if ($leg['fare_raw']!=$total && $total>0) {
|
||||
error_log('Leg #'.$leg['id'].' total ('.$leg['fare_raw'].') != calculated ('.$total.')');
|
||||
$leg['fare_raw'] = $total;
|
||||
}
|
||||
if (count($overview)>0) {
|
||||
require_once('../common/Polyline.php');
|
||||
$leg["polyline"] = MultiModal::processPolyline($overview);
|
||||
}
|
||||
} else {
|
||||
error_log('No steps found for leg #'.$leg['id']);
|
||||
}
|
||||
return [$leg, $ok, $steps];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method GET
|
||||
* Get single record (by id)
|
||||
* http://DOMAIN/multimodal/1
|
||||
* @return string
|
||||
*/
|
||||
public function viewAction() {
|
||||
//id must be the first parameter after /multimodal/x
|
||||
$id = array_shift($this->requestUri);
|
||||
|
||||
if($id && (int)$id>0){
|
||||
$db = new Db();
|
||||
$tripOptions = Trips::getOptionsById($db->getConnect(), (int)$id);
|
||||
if(is_array($tripOptions) && count($tripOptions)>0) {
|
||||
/*$tripOptions = ActivityApi::processQuotesTripMultimodalOptions(
|
||||
$db, $member_id, $country, $tripOptions);*/
|
||||
return $this->response(
|
||||
array(
|
||||
'id' => $id,
|
||||
'count' => count($tripOptions),
|
||||
'options' => $tripOptions
|
||||
), 200);
|
||||
}
|
||||
}
|
||||
return $this->response(
|
||||
array(
|
||||
'error'=> 'Data not found'
|
||||
), 404);
|
||||
}
|
||||
|
||||
public function createAction() {
|
||||
syslog(LOG_WARNING,'MultiModalApi::createAction()');
|
||||
$message = "Failed to run multi-modal router";
|
||||
$origin = $this->requestParams["origin"] ?? 0;
|
||||
$destination = $this->requestParams["destination"] ?? 0;
|
||||
$country = $this->requestParams["country"] ?? 'SG';
|
||||
$no_cache = $this->requestParams["no_cache"] ?? false;
|
||||
$member_id = $this->requestParams["member_id"] ?? 0;
|
||||
$cache_timeout = $this->requestParams["cache_timeout"] ?? MultiModalApi::CACHE_TIMEOUT;
|
||||
$distance = $this->requestParams["distance"] ?? 0;
|
||||
$duration = $this->requestParams["duration"] ?? 0;
|
||||
|
||||
try {
|
||||
$db = new Db();
|
||||
|
||||
// DEBUG
|
||||
$country = Geocode::mockGPSCountry($db->getConnect(), $member_id, $country, 'default');
|
||||
|
||||
// Check country
|
||||
if ($country!='SG' && $country!='US') {
|
||||
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);
|
||||
}
|
||||
// Check input
|
||||
$addrOrigin = Address::getAddressById($db->getConnect(), (int)$origin);
|
||||
$addrDestination = Address::getAddressById($db->getConnect(), (int)$destination);
|
||||
if ($addrOrigin==NULL || $addrDestination==NULL) {
|
||||
throw new Exception('Invalid origin and/or destination address');
|
||||
}
|
||||
|
||||
$checkOptions = [
|
||||
[
|
||||
"type"=>1,
|
||||
"geocode" => [
|
||||
"lat" => $addrOrigin["latitude"],
|
||||
"lng" => $addrOrigin["longitude"]
|
||||
]
|
||||
]
|
||||
];
|
||||
syslog(LOG_WARNING,'MultiModalApi: '.json_encode($checkOptions));
|
||||
$withinTheServiceArea = GeocodeApi::checkWithinTheServiceArea($country, $checkOptions, false);
|
||||
if ($withinTheServiceArea) {
|
||||
syslog(LOG_WARNING,'MultiModalApi: WITHIN SERVICE AREA!');
|
||||
$trip = MultiModalApi::multimodal(
|
||||
$db, $addrOrigin, $addrDestination, $country, $no_cache, $member_id, $cache_timeout, $distance, $duration
|
||||
);
|
||||
} else {
|
||||
// Trip format
|
||||
syslog(LOG_WARNING,'MultiModalApi: IS NOT WITHIN SERVICE AREA!');
|
||||
$trip = ActivityApi::createTrip($db, $country, $duration, $distance, $addrOrigin["id"], $addrDestination["id"]);
|
||||
}
|
||||
|
||||
/******* Start GOJEK ******/
|
||||
//$trip = MultiModalApi::processGojekOption($db, $member_id, $country, $trip);
|
||||
/******* End GOJEK ******/
|
||||
if ($country=='US') {
|
||||
$trip = MultiModalApi::processRidesharesOption($db, $member_id, $country, $trip);
|
||||
}
|
||||
|
||||
if ($trip && count($trip)) {
|
||||
$trip = MultiModalFilter::sortTrip($trip);
|
||||
return $this->response($trip, 200);
|
||||
} else {
|
||||
$message = "Failed to process multimodal trip";
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log(json_encode($e));
|
||||
$message = $e->getMessage();
|
||||
}
|
||||
return $this->response(
|
||||
array(
|
||||
"error" => $message
|
||||
), 500);
|
||||
}
|
||||
|
||||
public static function processGojekOption($db, $member_id, $country, $trip) {
|
||||
$trips = ActivityApi::processGojekOption($db, $member_id, $country, [
|
||||
[
|
||||
'trip' => $trip
|
||||
]
|
||||
]);
|
||||
$n = count($trips) - 1;
|
||||
if ($n>0 && array_key_exists('rideshare',$trips[$n]) && is_array($trips[$n]['rideshare']) && count($trips[$n]['rideshare'])>10) {
|
||||
$gojek = $trips[$n]['rideshare'];
|
||||
$options = $gojek['options'];
|
||||
$leg = $options['legs'][0];
|
||||
$leg_fare = $options['leg_fare'][$leg['id']];
|
||||
$leg_steps = $options['leg_steps'][$leg['id']];
|
||||
$trip['options']['legs'][] = $leg; // Append GOJEK
|
||||
$trip['options']['leg_fare'][$leg['id']] = $leg_fare;
|
||||
$trip['options']['leg_steps'][$leg['id']] = $leg_steps;
|
||||
$trip['options']['routes'] = count($trip['options']['legs']);
|
||||
}
|
||||
return $trip;
|
||||
}
|
||||
|
||||
public static function processRidesharesOption($db, $member_id, $country, $trip) {
|
||||
syslog(LOG_WARNING,"MultiModalApi::processRidesharesOption(\$db, $member_id, $country, \$trip)");
|
||||
$trips = ActivityApi::processRidesharesOption($db, $member_id, $country, [
|
||||
[
|
||||
'trip' => $trip
|
||||
]
|
||||
]);
|
||||
foreach ($trips as $item) {
|
||||
if (is_array($item) && array_key_exists('rideshare',$item) && is_array($item['rideshare']) && count($item['rideshare'])>10) {
|
||||
$rideshare = $item['rideshare'];
|
||||
$options = $rideshare['options'];
|
||||
$leg = $options['legs'][0];
|
||||
$leg_fare = $options['leg_fare'][$leg['id']];
|
||||
$leg_steps = $options['leg_steps'][$leg['id']];
|
||||
$trip['options']['legs'][] = $leg; // Append Rideshare
|
||||
$trip['options']['leg_fare'][$leg['id']] = $leg_fare;
|
||||
$trip['options']['leg_steps'][$leg['id']] = $leg_steps;
|
||||
$trip['options']['routes'] = count($trip['options']['legs']);
|
||||
} else {
|
||||
syslog(LOG_WARNING,"Invalid rideshare entry!");
|
||||
}
|
||||
}
|
||||
/*
|
||||
$n = count($trips) - 1;
|
||||
if ($n>0 && array_key_exists('rideshare',$trips[$n]) && is_array($trips[$n]['rideshare']) && count($trips[$n]['rideshare'])>10) {
|
||||
$rideshare = $trips[$n]['rideshare'];
|
||||
$options = $rideshare['options'];
|
||||
$leg = $options['legs'][0];
|
||||
$leg_fare = $options['leg_fare'][$leg['id']];
|
||||
$leg_steps = $options['leg_steps'][$leg['id']];
|
||||
$trip['options']['legs'][] = $leg; // Append Rideshare
|
||||
$trip['options']['leg_fare'][$leg['id']] = $leg_fare;
|
||||
$trip['options']['leg_steps'][$leg['id']] = $leg_steps;
|
||||
$trip['options']['routes'] = count($trip['options']['legs']);
|
||||
}*/
|
||||
return $trip;
|
||||
}
|
||||
|
||||
public function multimodal($db, $addrOrigin, $addrDestination, $country, $no_cache, $member_id, $cache_timeout, $distance, $duration) {
|
||||
error_log('MultiModalApi::multimodal()');
|
||||
$trip = NULL;
|
||||
try {
|
||||
// id,address,latitude,longitude,timezone,geocoding_date,postal
|
||||
// 3,'97 Meyer Road, Singapore', 1.2833754, 103.8607264, 1, 2019-05-18, 018956
|
||||
if (!$no_cache) { // we can force to skip the cache...
|
||||
$trip = Trips::getByCoordinates(
|
||||
$db->getConnect(),
|
||||
['lat' => $addrOrigin['latitude'], 'lng' => $addrOrigin['longitude']],
|
||||
['lat' => $addrDestination['latitude'], 'lng' => $addrDestination['longitude']],
|
||||
1
|
||||
);
|
||||
if ($trip && $trip["id"]>0 && MultiModalApi::checkCache($db, $trip, $cache_timeout)) {
|
||||
// Trip options
|
||||
$trip["member_id"] = $member_id; // Pass along
|
||||
$tripOptions = Trips::getOptionsById($db->getConnect(), $trip["id"]);
|
||||
if(is_array($tripOptions) && count($tripOptions)>0) {
|
||||
|
||||
ActivityApi::debugTrips([['multimodal'=>['options'=>$tripOptions]]],'11111');
|
||||
|
||||
$tripOptions = ActivityApi::processQuotesTripMultimodalOptions($db, $member_id, $country, $tripOptions);
|
||||
$trip = array_merge($trip, array(
|
||||
'count' => count($tripOptions),
|
||||
'options' => $tripOptions,
|
||||
'from_cache' => true
|
||||
));
|
||||
|
||||
ActivityApi::debugTrips([['multimodal'=>$trip]],'11112');
|
||||
|
||||
$trip['country'] = $country;
|
||||
$trip = MultiModalApi::processTrip($db, $trip, $country);
|
||||
|
||||
ActivityApi::debugTrips([['multimodal'=>$trip]],'11113');
|
||||
|
||||
|
||||
throw new Exception('OK');
|
||||
} else {
|
||||
// Will need new trip options!
|
||||
error_log('Trip parsedemail_item.id='.$trip["id"].' does not have options!');
|
||||
}
|
||||
} else if ($trip && $trip["id"]>0) {
|
||||
$trip = NULL; // cache miss - we will need a new trip!
|
||||
} // else trip was not found
|
||||
}
|
||||
// Create a new trip entry
|
||||
if ($trip==NULL || !isset($trip["id"])) {
|
||||
$data = [
|
||||
'travel_date' => MultiModal::getDate($country),
|
||||
'duration' => (int)$duration,
|
||||
'cost_raw' => NULL,
|
||||
'trackedemail_item_id' => NULL,
|
||||
'cost' => NULL,
|
||||
'distance' => $distance,
|
||||
'transport_provider_id' => NULL,
|
||||
'scheduled' => NULL,
|
||||
'travel_date_end' => MultiModal::getDate($country),
|
||||
'dup_id' => NULL,
|
||||
'location_start_id' => $addrOrigin['id'],
|
||||
'location_end_id' => $addrDestination['id'],
|
||||
'private' => 't' /* this is a private entry without the source e-mail */
|
||||
];
|
||||
list($id, $err) = Trips::create($db->getConnect(), $data);
|
||||
if ($id && $id>0) {
|
||||
$trip = Trips::getById($db->getConnect(), $id);
|
||||
}
|
||||
if ($trip==NULL || !isset($trip["id"])) {
|
||||
throw new Exception('Failed to create new trip record'.($err?": ${err}":""));
|
||||
}
|
||||
}
|
||||
// New directions
|
||||
$tripService = MultiModalApi::tripService($trip["id"], $country);
|
||||
//error_log(json_encode($tripService));
|
||||
if (is_array($tripService) && isset($tripService["travel_date"])) {
|
||||
$tripService["member_id"] = $member_id; // Pass along
|
||||
$tripService["country"] = $country;
|
||||
|
||||
$tripService = MultiModalFilter::byDuration($tripService);
|
||||
|
||||
ActivityApi::debugTrips([['multimodal'=>$tripService]],'11114');
|
||||
|
||||
$tripService = MultiModalApi::processTrip($db, $tripService, $country);
|
||||
|
||||
ActivityApi::debugTrips([['multimodal'=>$tripService]],'11115');
|
||||
|
||||
$tripOptions = $tripService["options"];
|
||||
|
||||
ActivityApi::debugTrips([['multimodal'=>$tripService]],'111');
|
||||
|
||||
$tripOptions = ActivityApi::processQuotesTripMultimodalOptions(
|
||||
$db, $member_id, $country, $tripOptions);
|
||||
$tripService["options"] = $tripOptions;
|
||||
$trip = $tripService;
|
||||
|
||||
ActivityApi::debugTrips([['multimodal'=>$trip]],'112');
|
||||
|
||||
$trip = MultiModalFilter::byCost($trip);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
}
|
||||
return $trip;
|
||||
}
|
||||
|
||||
protected function checkCache($db, $trip, $cache_timeout) {
|
||||
error_log('MultiModalApi::checkCache()');
|
||||
$advice = NULL;
|
||||
if (!is_array($trip) || $trip['id']<1) {
|
||||
error_log('No trip data to analyse => no cache!');
|
||||
return false;
|
||||
}
|
||||
list ($res, $err) = MultiModal::getLastGoogleAdviceByTrip($db->getConnect(),$trip['id']);
|
||||
error_log(json_encode($res));
|
||||
if ($res && $res['id']>0) {
|
||||
$advice = $res;
|
||||
} else {
|
||||
error_log('No parsedemail_item_advice_google record => no cache!');
|
||||
return false;
|
||||
}
|
||||
if ($advice['elapsed'] > $cache_timeout) {
|
||||
error_log('Cache expired! We will need a new advice!');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function checkTaxiQuote($db, $trip, $country) {
|
||||
syslog(LOG_WARNING,"MultiModalApi::checkTaxiQuote(\$db, \$trip, $country)");
|
||||
try {
|
||||
// Do we have trip options?
|
||||
if (!isset($trip['options']) || !is_array($trip['options']) || !isset($trip['options']['legs'])) {
|
||||
error_log('Trip parsedemail_item.id='.$trip['id'].' has no options!');
|
||||
return $trip;
|
||||
}
|
||||
// Do we have a member_id?
|
||||
$member_id = 0;
|
||||
if (isset($trip["member_id"])) {
|
||||
$member_id = $trip["member_id"];
|
||||
}
|
||||
// Do we have transport providers?
|
||||
$transport_providers = [];
|
||||
list ($result, $error) = Geocode::getTransportProvidersByCountry(
|
||||
$db->getConnect(), $trip["country"]);
|
||||
if ($result==NULL || count($result)<1) {
|
||||
syslog(LOG_WARNING,"Failed to get transport providers: ".$error);
|
||||
return $trip;
|
||||
}
|
||||
foreach ($result as $f) {
|
||||
if ($trip["country"]!='SG' || $f["transport_provider_id"]==4) { // ComfortDelGro
|
||||
$transport_providers[] = $f["transport_provider_id"];
|
||||
}
|
||||
}
|
||||
// Check leg steps for the taxi
|
||||
$n = count($trip['options']['legs']);
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$leg = $trip['options']['legs'][$i];
|
||||
$leg_id = $leg['id'];
|
||||
$leg_steps = $trip['options']['leg_steps'][$leg_id];
|
||||
$leg_fare = $trip['options']['leg_fare'][$leg_id];
|
||||
$m = count($leg_steps);
|
||||
$total = 0;
|
||||
for ($j=0; $j<$m; $j++) {
|
||||
$step = $leg_steps[$j];
|
||||
if ($step['travel_mode']=="TAXI") {
|
||||
// Reverse geocode
|
||||
list($origin, $err1) = GeocodeApi::reverseGeocode($db, $step["location_start_lat"], $step["location_start_lng"]);
|
||||
list($destination, $err2) = GeocodeApi::reverseGeocode($db, $step["location_end_lat"], $step["location_end_lng"]);
|
||||
if ($origin=='' || $destination=='') {
|
||||
syslog(LOG_WARNING,'MultiModalApi::checkTaxiQuote() Reverse geocoding failed! From "'.$origin.'"('.$step["location_start_lat"].','.$step["location_start_lng"].') to "'.$destination.'"('.$step["location_end_lat"].','.$step["location_end_lng"].')');
|
||||
continue;
|
||||
}
|
||||
syslog(LOG_WARNING,"origin='${origin}'");
|
||||
syslog(LOG_WARNING,"destination='${destination}");
|
||||
list($message,$code,$action,$data) = QuoteGroupApi::createReal(
|
||||
$db, $origin, $destination, $member_id, $transport_providers, $country
|
||||
);
|
||||
if (is_array($data) && isset($data["id"]) && $data["id"]>0) {
|
||||
syslog(LOG_WARNING,"QuoteGroup ID: ".$data["id"]);
|
||||
$quoteGroupId = $data["id"];
|
||||
// Check quote
|
||||
$step["quote_group_id"] = $quoteGroupId;
|
||||
sleep(3);
|
||||
list($message,$code,$action,$data) = QuoteGroupApi::viewReal($db, $quoteGroupId);
|
||||
if ($code==200 && isset($data["cost"]) && $data["cost"]>0) {
|
||||
// TODO: double-check!
|
||||
$step["fare_quote"] = ((int)(100*$data["cost"]));
|
||||
if (!array_key_exists('fare_raw',$step) || $step['fare_raw']<$step["fare_quote"]) {
|
||||
$step['fare_raw'] = $step["fare_quote"];
|
||||
}
|
||||
if ($leg_fare==NULL) $leg_fare = $step["fare_quote"];
|
||||
else $leg_fare += $step["fare_quote"];
|
||||
} else {
|
||||
syslog(LOG_WARNING,"ERROR: ".$message);
|
||||
}
|
||||
} else {
|
||||
syslog(LOG_WARNING,"ERROR: ".$message);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('fare_raw',$step) && $step['fare_raw']>0) {
|
||||
$total += $step['fare_raw'];
|
||||
}
|
||||
if (!array_key_exists('duration',$step) || $step['duration']<60) {
|
||||
$step['duration'] = 60;
|
||||
}
|
||||
$leg_steps[$j] = $step;
|
||||
}
|
||||
if (!array_key_exists('fare_raw',$leg) || $leg['fare_raw']<$leg_fare || $leg['fare_raw']<$total) {
|
||||
$leg['fare_raw'] = $leg_fare>$total ? $leg_fare : $total;
|
||||
}
|
||||
$trip['options']['leg_fare'][$leg_id] = $leg_fare>$total ? $leg_fare : $total;
|
||||
$trip['options']['leg_steps'][$leg_id] = $leg_steps;
|
||||
$trip['options']['legs'][$i] = $leg;
|
||||
}
|
||||
//*/
|
||||
} catch (Exception $e) {
|
||||
syslog(LOG_WARNING,'MultiModalApi::checkTaxiQuote() EXCEPTION: '.$e->getMessage());
|
||||
}
|
||||
return $trip;
|
||||
}
|
||||
|
||||
protected function processTrip($db, $trip, $country) {
|
||||
syslog(LOG_WARNING,'MultiModalApi::processTrip()');
|
||||
require_once('../common/Polyline.php');
|
||||
//error_log(json_encode($trip));
|
||||
|
||||
ActivityApi::debugTrips([['multimodal'=>$trip]],'1111');
|
||||
|
||||
if (array_key_exists('options',$trip) && is_array($trip['options']) && isset($trip['options']['legs'])) {
|
||||
if ($trip['options']['gid']<1) {
|
||||
// Save options...
|
||||
list($res, $err) = MultiModal::create($db->getConnect(), $trip);
|
||||
error_log($err);
|
||||
if ($res && $res['id']>0) {
|
||||
$trip = $res;
|
||||
// TODO: fix!
|
||||
//unset($trip['error']);
|
||||
} else {
|
||||
$message = $err!='' ? $err : 'Failed to save multi-modal option';
|
||||
error_log($message);
|
||||
$trip['error'] = $message;
|
||||
$trip['options']['routes'] = count($trip['options']['legs']);
|
||||
$trip = MultiModalApi::checkTaxiQuote($db, $trip, $country);
|
||||
return $trip;
|
||||
}
|
||||
} else {
|
||||
error_log('DB record for options already exists');
|
||||
}
|
||||
// Schedule quote
|
||||
$trip = MultiModalApi::checkTaxiQuote($db, $trip, $country);
|
||||
$n = count($trip['options']['legs']);
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$leg = $trip['options']['legs'][$i];
|
||||
$leg_id = $leg['id'];
|
||||
$leg_steps = $trip['options']['leg_steps'][$leg_id];
|
||||
$leg_fare = $trip['options']['leg_fare'][$leg_id];
|
||||
// We must schedule leg fare quote...
|
||||
$m = count($leg_steps);
|
||||
$overview = [];
|
||||
for ($j=0; $j<$m; $j++) {
|
||||
$step = $leg_steps[$j];
|
||||
//"travel_mode": "TRANSIT"
|
||||
//"vehicle": "BUS",
|
||||
//"line": "", <------------- WTF?
|
||||
if ($step['travel_mode']=="SCOOTER") {
|
||||
$polyline = [];
|
||||
// Get directions
|
||||
$input = [
|
||||
1 => [
|
||||
"coordinates" => [
|
||||
"lat" => $trip["location_start_lat"],
|
||||
"lng" => $trip["location_start_lng"]
|
||||
]
|
||||
],
|
||||
2 => [
|
||||
"coordinates" => [
|
||||
"lat" => $trip["location_end_lat"],
|
||||
"lng" => $trip["location_end_lng"]
|
||||
]
|
||||
]
|
||||
];
|
||||
$result = [
|
||||
1 => [
|
||||
"data" => [
|
||||
"location_start_lat" => $step["location_start_lat"],
|
||||
"location_start_lng" => $step["location_start_lng"],
|
||||
"location_end_lat" => $step["location_end_lat"],
|
||||
"location_end_lng" => $step["location_end_lng"]
|
||||
]
|
||||
]
|
||||
];
|
||||
$options = ScooterApi::directions($db, $input, $result, []);
|
||||
$step["route_overlay"] = isset($options["route_overlay"]) ? $options["route_overlay"][0] : [];
|
||||
$step["polyline"] = $options["route_overlay"][0]["polyline"];
|
||||
$polyline = $step["polyline"]; // TODO: merge with walking...
|
||||
// Get quote
|
||||
$scooter_time = $step['duration'];
|
||||
$country = 'SG'; // Singapore only!
|
||||
list($res,$err) = ScooterApi::quote($db, $scooter_time, $country);
|
||||
if ($res && count($res)>0) {
|
||||
$fare_raw = PHP_INT_MAX;
|
||||
foreach ($res as $quote) {
|
||||
if ($quote['pricing']['dropoff_anywhere']!=null) {
|
||||
$fare_raw = $quote['quote'] + $quote['pricing']['dropoff_anywhere'];
|
||||
break; // with this option we have Neuron only and that be it
|
||||
}
|
||||
if ($fare_raw > $quote['quote']) {
|
||||
$fare_raw = $quote['quote'];
|
||||
}
|
||||
}
|
||||
if ($fare_raw == PHP_INT_MAX) {
|
||||
$fare_raw = NULL; // we did not get any quote?
|
||||
} else {
|
||||
$fare_raw = (int)($fare_raw);
|
||||
}
|
||||
$trip['options']['leg_fare'][$leg_id] = $fare_raw;
|
||||
$leg['fare_raw'] = $fare_raw;
|
||||
$step['fare_raw'] = $fare_raw;
|
||||
}
|
||||
$leg['polyline'] = $polyline;
|
||||
$step['polyline'] = $polyline;
|
||||
}
|
||||
//error_log(json_encode($step));
|
||||
$leg_steps[$j] = $step;
|
||||
|
||||
// TODO: FIX!!!
|
||||
|
||||
if (array_key_exists("polyline",$step)) {
|
||||
$overview[] = $step["polyline"];
|
||||
}
|
||||
|
||||
}
|
||||
if (count($overview)>0) {
|
||||
$leg["polyline"] = MultiModal::processPolyline($overview);
|
||||
}
|
||||
//syslog(LOG_WARNING,'$leg["polyline"] = '.$leg["polyline"]);
|
||||
$trip['options']['leg_steps'][$leg_id] = $leg_steps;
|
||||
$trip['options']['legs'][$i] = $leg;
|
||||
}
|
||||
$trip['options']['routes'] = count($trip['options']['legs']);
|
||||
} else {
|
||||
syslog(LOG_WARNING,'Trip parsedemail_item.id='.$trip['id'].' has no options!');
|
||||
}
|
||||
return $trip;
|
||||
}
|
||||
|
||||
public function updateAction() {
|
||||
return $this->response(
|
||||
array(
|
||||
"error" => "Update error"
|
||||
), 400);
|
||||
}
|
||||
|
||||
public function deleteAction() {
|
||||
$res = 0;
|
||||
$message = "Delete error";
|
||||
$id = (int)array_shift($this->requestUri);
|
||||
if ($id>0) {
|
||||
$db = new Db();
|
||||
$res = MultiModal::delete($db->getConnect(), $id);
|
||||
if ($res>0) {
|
||||
return $this->response(array(
|
||||
'id' => $id,
|
||||
'result' => $res
|
||||
), 200);
|
||||
} else {
|
||||
$message = "Delete failed";
|
||||
}
|
||||
} else {
|
||||
$message = "Invalid error";
|
||||
}
|
||||
return $this->response(
|
||||
array(
|
||||
"error" => $message,
|
||||
"result" => $res
|
||||
), 500);
|
||||
}
|
||||
|
||||
public function tripService($id, $country) {
|
||||
global $savvyext;
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
|
||||
error_log("MultiModalApi::tripService($id)");
|
||||
if ($country!='SG' && $country!='US') {
|
||||
throw new Exception('Unsupported country: '.$country);
|
||||
}
|
||||
// curl -d 'id=8907' -X POST {$oauth2_url}trips/
|
||||
$postdata = http_build_query(
|
||||
array(
|
||||
'id'=> $id,
|
||||
'country' => $country
|
||||
)
|
||||
);
|
||||
$url = $oauth2_url."trips";
|
||||
$opts = array(
|
||||
'http' => array(
|
||||
'method' => "POST",
|
||||
'timeout' => 60, /* 1 minute */
|
||||
'header' =>
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n" .
|
||||
"Accept: application/json\r\n" .
|
||||
"Authorization: Server-Token ${httpAuthToken}\r\n",
|
||||
'content' => $postdata
|
||||
),
|
||||
"ssl" => array(
|
||||
"verify_peer"=>false,
|
||||
"verify_peer_name"=>false,
|
||||
)
|
||||
);
|
||||
$context = stream_context_create($opts);
|
||||
error_log("started trips service call");
|
||||
$t = time();
|
||||
$body = file_get_contents($url, false, $context);
|
||||
error_log("complete trips service call: ".(time()-$t)." seconds");
|
||||
file_put_contents('/home/savvy/FloatWeb/adminsavvy/DEBUG/trips'.time().'.json',$body);
|
||||
$trip = json_decode($body,true);
|
||||
return $trip;
|
||||
}
|
||||
|
||||
public function mytansportsgService($id) {
|
||||
global $savvyext;
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
|
||||
error_log("public function mytransportsgService($id)");
|
||||
// curl -d 'id=8907' -X POST $oauth2_url.'mytransportsg'/
|
||||
$postdata = http_build_query(
|
||||
array(
|
||||
'advice_id'=> $id
|
||||
)
|
||||
);
|
||||
$url = $oauth2_url."mytransportsg";
|
||||
$opts = array(
|
||||
'http' => array(
|
||||
'method' => "POST",
|
||||
'timeout' => 60, /* 1 minute */
|
||||
'header' =>
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n" .
|
||||
"Accept: application/json\r\n" .
|
||||
"Authorization: Server-Token ${httpAuthToken}\r\n",
|
||||
'content' => $postdata
|
||||
),
|
||||
"ssl" => array(
|
||||
"verify_peer"=>false,
|
||||
"verify_peer_name"=>false,
|
||||
)
|
||||
);
|
||||
$context = stream_context_create($opts);
|
||||
$body = file_get_contents($url, false, $context);
|
||||
$advice = json_decode($body,true);
|
||||
return $advice;
|
||||
}
|
||||
|
||||
public function mytansportsgServiceLeg($id) {
|
||||
global $savvyext;
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
|
||||
error_log("public function mytransportsgServiceLeg($id)");
|
||||
$url = $oauth2_url."mytransportsg/" . $id;
|
||||
$opts = array(
|
||||
'http' => array(
|
||||
'method' => "GET",
|
||||
'timeout' => 60, /* 1 minute */
|
||||
'header' =>
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n" .
|
||||
"Accept: application/json\r\n" .
|
||||
"Authorization: Server-Token ${httpAuthToken}\r\n",
|
||||
),
|
||||
"ssl" => array(
|
||||
"verify_peer"=>false,
|
||||
"verify_peer_name"=>false,
|
||||
)
|
||||
);
|
||||
$context = stream_context_create($opts);
|
||||
$body = file_get_contents($url, false, $context);
|
||||
$advice = json_decode($body,true);
|
||||
return $advice;
|
||||
}
|
||||
|
||||
public function bartService($db, $legs, $id) {
|
||||
$quotes = []; // We do not call the service as the data is presented after the initial call
|
||||
foreach ($legs as $leg_id=>$leg) {
|
||||
$total = 0;
|
||||
list ($res, $err) = MultiModal::getLegStepQuotes($db->getConnect(), $leg_id);
|
||||
if ($res && count($res)>0) {
|
||||
foreach ($res as $quote) {
|
||||
$total += ((int)$f["fare_raw"]);
|
||||
}
|
||||
}
|
||||
$quotes[$leg_id] = [
|
||||
"total" => $total,
|
||||
];
|
||||
}
|
||||
$result = [
|
||||
"code" => 0,
|
||||
"data" => $quotes
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function processLegs($db, $legs, $advice_id, $country) {
|
||||
syslog(LOG_WARNING,"MultiModalApi::processLegs(\$db, \$legs, $advice_id, $country)");
|
||||
$ok = true; // All the steps on all the legs have the quotes?
|
||||
$leg_steps = [];
|
||||
foreach ($legs as $leg_id=>$leg) {
|
||||
list ($leg, $ok, $steps) = MultiModalApi::processSteps($db, $leg, $ok);
|
||||
$legs[$leg_id] = $leg;
|
||||
$leg_steps[$leg_id] = $leg_steps;
|
||||
}
|
||||
if ($ok) {
|
||||
return $this->response($legs, 200);
|
||||
}
|
||||
// Get quote
|
||||
$options = [
|
||||
"legs" => $legs,
|
||||
"leg_steps" => $leg_steps
|
||||
];
|
||||
$options = ActivityApi::processQuotesTripMultimodalOptions(
|
||||
$db, 0, $country, $options); /* NOTE: $member_id = 0; */
|
||||
$legs = $options["legs"];
|
||||
/*
|
||||
if (is_array($result) && isset($result["code"]) && $result["code"]==0 && isset($result["data"])) {
|
||||
$data = $result["data"];
|
||||
error_log(json_encode($data));
|
||||
foreach ($data as $leg_id=>$quote) {
|
||||
$leg = $legs[$leg_id];
|
||||
if (isset($quote['total']) && $quote['total']>0) {
|
||||
$leg['fare_raw'] = $quote['total'];
|
||||
}
|
||||
$ok = true;
|
||||
list ($leg, $ok, $steps) = MultiModalApi::processSteps($db, $leg, $ok);
|
||||
if ($ok) {
|
||||
$legs[$leg_id] = $leg;
|
||||
} else {
|
||||
error_log('Failed to process steps for leg #'.$leg_id);
|
||||
}
|
||||
}
|
||||
return $this->response($legs, 200);
|
||||
}
|
||||
*/
|
||||
return $this->response($legs, 200);
|
||||
/*
|
||||
return $this->response(
|
||||
array(
|
||||
'error' => isset($result["error"])?$result["error"]:"MyTrasnport.sg service call failed"
|
||||
), 500);*/
|
||||
}
|
||||
|
||||
public static function getPolyline($id) {
|
||||
global $savvyext;
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
|
||||
$url = $oauth2_url."polyline/" . $id;
|
||||
$opts = array(
|
||||
'http' => array(
|
||||
'method' => "GET",
|
||||
'timeout' => 60, /* 1 minute */
|
||||
'header' =>
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n" .
|
||||
"Accept: application/json\r\n" .
|
||||
"Authorization: Server-Token ${httpAuthToken}\r\n",
|
||||
),
|
||||
"ssl" => array(
|
||||
"verify_peer"=>false,
|
||||
"verify_peer_name"=>false,
|
||||
)
|
||||
);
|
||||
$context = stream_context_create($opts);
|
||||
$body = file_get_contents($url, false, $context);
|
||||
$geocoded = json_decode($body,true);
|
||||
|
||||
//var_dump($http_response_header);
|
||||
//var_dump($body);
|
||||
return $geocoded;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user