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; } }