244 lines
8.9 KiB
PHP
244 lines
8.9 KiB
PHP
<?php
|
||
|
||
class ScooterApi extends Api
|
||
{
|
||
public $apiName = 'scooter';
|
||
|
||
public function indexAction()
|
||
{
|
||
$messge = 'Data not found';
|
||
return $this->response(
|
||
array(
|
||
'error' => $message
|
||
), 404);
|
||
}
|
||
|
||
/**
|
||
* Method GET
|
||
* Get single record (by id)
|
||
* http://DOMAIN/geocode/1
|
||
* @return string
|
||
*/
|
||
public function viewAction()
|
||
{
|
||
//id must be the first parameter after /geocode/x
|
||
$id = array_shift($this->requestUri);
|
||
|
||
if($id && (int)$id>0){
|
||
$db = new Db();
|
||
$address = Geocode::getAddressById($db->getConnect(), (int)$id);
|
||
if(is_array($address) && count($address)>0){
|
||
return $this->response($address, 200);
|
||
}
|
||
}
|
||
return $this->response(
|
||
array(
|
||
'error'=> 'Data not found'
|
||
), 404);
|
||
}
|
||
|
||
public function createAction()
|
||
{
|
||
$message = "Failed to run scooter directions";
|
||
$addresses = $this->requestParams["addresses"] ?? array();
|
||
$options = $this->requestParams["options"] ?? array();
|
||
try {
|
||
throw new Exception("We are sorry but scooters are not yet launched in your country. Please check back again soon!");
|
||
if ($addresses==NULL || !is_array($addresses) || count($addresses)<1 || !isset($addresses[0]["address"])) {
|
||
throw new Exception("Invalid input");
|
||
}
|
||
$db = new Db();
|
||
$result = [];
|
||
$input = [];
|
||
foreach ($addresses as $item) {
|
||
if (isset($item["type"]) && $item["type"]>0 && $item["type"]<3) {
|
||
$input[$item["type"]] = $item;
|
||
}
|
||
}
|
||
if (isset($input[1]) && isset($input[2]) &&
|
||
isset($input[1]["address"]) && isset($input[2]["address"])) {
|
||
|
||
list($result, $err) = self::scooter($db, $input);
|
||
|
||
if (!is_array($result) || count($result)<1) {
|
||
throw new Exception($err!=''? $err : 'No scooter option available');
|
||
}
|
||
} else {
|
||
throw new Exception("Invalid address");
|
||
}
|
||
if ((isset($options["travel_time"]) && $options["travel_time"]) ||
|
||
(isset($options["quote"]) && $options["quote"]) ||
|
||
(isset($options["route_overlay"]) && $options["route_overlay"])) {
|
||
$options = self::options($db, $input, $result, $options);
|
||
}
|
||
return $this->response(
|
||
array(
|
||
'data'=>$result,
|
||
'options'=>$options), 200);
|
||
} catch (Exception $e) {
|
||
error_log(json_encode($e));
|
||
$message = $e->getMessage();
|
||
}
|
||
return $this->response(
|
||
array(
|
||
"error" => $message
|
||
), 500);
|
||
}
|
||
|
||
public function updateAction()
|
||
{
|
||
return $this->response(
|
||
array(
|
||
"error" => "Update error"
|
||
), 400);
|
||
}
|
||
|
||
public function deleteAction() {
|
||
return $this->response(
|
||
array(
|
||
"error" => "Delete error"
|
||
), 500);
|
||
}
|
||
|
||
public function scooter($db, $input) {
|
||
global $savvyext;
|
||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||
$oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
|
||
// Call scooter service
|
||
$gps1 = $input[1]["coordinates"];
|
||
$gps2 = $input[2]["coordinates"];
|
||
$data = http_build_query(
|
||
array(
|
||
'gps' => sprintf("%s,%s,%s,%s",$gps1["lat"],$gps1["lng"],$gps2["lat"],$gps2["lng"]),
|
||
'from' => $input[1]["address"],
|
||
'to' => $input[2]["address"]
|
||
)
|
||
);
|
||
$url = $oauth2_url."scooter?" . $data;
|
||
//error_log($url);
|
||
$opts = array(
|
||
'http' => array(
|
||
'method' => "GET",
|
||
'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);
|
||
$scooter = json_decode($body,true);
|
||
if (is_array($scooter) && is_array($scooter["data"]) && !isset($scooter["error"])) {
|
||
// Cache the result in DB
|
||
//$scooter["data"]["id"] = Scooter::save($db->getConnect(), $scooter["data"]);
|
||
return array($scooter["data"], NULL);
|
||
} else if (is_array($scooter) && isset($scooter["error"])) {
|
||
$body = $scooter["error"];
|
||
}
|
||
return array(NULL, "Scooter service call error: ".$body);
|
||
}
|
||
|
||
public function options($db, $input, $result, $options) {
|
||
if (isset($options["travel_time"]) && $options["travel_time"]) {
|
||
$travel_time = 0;
|
||
foreach ($result as $step) {
|
||
$travel_time += $step["duration"];
|
||
}
|
||
$options["travel_time"] = (int)$travel_time;
|
||
}
|
||
if (isset($options["quote"]) && $options["quote"] &&
|
||
is_array($result) && count($result)>1 &&
|
||
isset($result[1]["duration"]) && $result[1]["duration"]>0) {
|
||
|
||
$scooter_time = $result[1]["duration"]; // 2nd entry is the scooter step
|
||
list($res,$err) = self::quote($db, $scooter_time, 'SG');
|
||
if ($err!=NULL) {
|
||
$options["error"] = $err;
|
||
} else {
|
||
$options["quote"] = $res;
|
||
}
|
||
}
|
||
if (isset($options["route_overlay"]) && $options["route_overlay"]) {
|
||
$options = self::directions($db, $input, $result, $options);
|
||
}
|
||
return $options;
|
||
}
|
||
|
||
public function quote($db, $seconds, $country='SG') {
|
||
global $scooterAuthToken, $savvyext;
|
||
// Check local DB cache
|
||
/* list ($res, $err) = Scooter::checkScooterQuote($db->getConnect(), $minutes, $country);
|
||
if (is_array($res) && isset($res[0]["quote"])) {
|
||
return array($res, NULL);
|
||
} */
|
||
// Call scooter quote service
|
||
$data = http_build_query(
|
||
array(
|
||
'minutes' => (int)($seconds/60),
|
||
'country' => $country
|
||
)
|
||
);
|
||
$url = $savvyext->cfgReadChar('microservices.catalog') . "/api/v1/price-quote/?" . $data;
|
||
$opts = array(
|
||
'http' => array(
|
||
'method' => "GET",
|
||
'header' =>
|
||
"Content-Type: application/x-www-form-urlencoded\r\n" .
|
||
"Accept: application/json\r\n" .
|
||
"Authorization: Server-Token ${scooterAuthToken}\r\n",
|
||
),
|
||
"ssl" => array(
|
||
"verify_peer"=>false,
|
||
"verify_peer_name"=>false,
|
||
)
|
||
);
|
||
$context = stream_context_create($opts);
|
||
$body = file_get_contents($url, false, $context);
|
||
$scooter = json_decode($body,true);
|
||
if (is_array($scooter) && count($scooter)>0 && isset($scooter[0]["quote"])) {
|
||
// Cache the result in DB
|
||
//$scooter["data"]["id"] = Scooter::saveQuote($db->getConnect(), $scooter);
|
||
return array($scooter, NULL);
|
||
} else if (is_array($scooter) && isset($scooter["error"])) {
|
||
$body = $scooter["error"];
|
||
}
|
||
return array(NULL, "Scooter quote service call error: ".$body);
|
||
}
|
||
|
||
public function directions($db, $input, $result, $options) {
|
||
// Walking with waypoints or 3 routes
|
||
$mode='walking';
|
||
$waypoints=[
|
||
$result[1]["data"]["location_start_lat"], $result[1]["data"]["location_start_lng"],
|
||
$result[1]["data"]["location_end_lat"], $result[1]["data"]["location_end_lng"]
|
||
];
|
||
$fromLat = $input[1]["coordinates"]["lat"];
|
||
$fromLng = $input[1]["coordinates"]["lng"];
|
||
$toLat = $input[2]["coordinates"]["lat"];
|
||
$toLng = $input[2]["coordinates"]["lng"];
|
||
list($res, $err) = GeocodeApi::route(
|
||
$db, $fromLat, $fromLng, $toLat, $toLng, $mode, $waypoints);
|
||
if ($err!=NULL || !is_array($res) || !isset($res["routes"]) || count($res["routes"])<1) {
|
||
$options['error'] = $err!=NULL ? $err : 'No available routes';
|
||
return $options;
|
||
}
|
||
$options["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'];
|
||
}
|
||
$options["route_overlay"][] = $r;
|
||
}
|
||
// ["route_overlay"]
|
||
return $options;
|
||
}
|
||
}
|