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