requestParams["member_id"] ?? null; $params = [ 'status' => $this->requestParams["status"] ?? null, 'active' => $this->requestParams["active"] ?? false, 'limit' => $this->requestParams["limit"] ?? 10, 'offset' => $this->requestParams["offset"] ?? 0, ]; $db = new Db(); $sessionId = null; $requestHeaders = getallheaders(); if ((empty($memberId) || $memberId <=0 ) && array_key_exists("x-session-id",$requestHeaders)) { $sessionId = $requestHeaders["x-session-id"]; list($member, $error) = Booking::getMemberBySessionId($db->getConnect(), $sessionId); if (isset($member)) { $memberId = $member['id']; } } if (isset($memberId)) { list($message,$code,$action,$data) = AutocabApi::memberBookingList($db, $memberId, $params); } else { list($message,$code,$action,$data) = AutocabApi::bookingList($db, $params); } if ($code==200) { $log = [ 'message' => $message, 'code' => $code, 'action' => $action, 'data' => $data ]; Logger::warning($log); if ($action=="response") { return $this->response($data, $code); } } return $this->response( array( "error" => $message ), $code ); } public function viewAction() { global $autocabApiConfig; $code = 400; $message = "Bad request"; $data = []; $action = array_shift($this->requestUri); if (is_numeric($action)) { $id = $action; $action = 'booking'; } else { $id = array_shift($this->requestUri); } $db = new Db(); $autocab = new Autocab($autocabApiConfig); switch($action) { case 'status': list($message,$code,$action,$data) = AutocabApi::bookingStatus($autocab, $db, $id); break; case 'member': $requestHeaders = getallheaders(); if ((empty($id) || $id <=0 ) && array_key_exists("x-session-id",$requestHeaders)) { $sessionId = $requestHeaders["x-session-id"]; list($member, $error) = Booking::getMemberBySessionId($db->getConnect(), $sessionId); if (isset($member)) { $id = $member['id']; } } if(!empty($id)) { list($message,$code,$action,$data) = AutocabApi::memberBookingList($db, $id); } break; case 'booking': list($message,$code,$action,$data) = AutocabApi::bookingInfo($db, $id); break; } if ($code==200) { $log = [ 'message' => $message, 'code' => $code, 'action' => $action, 'data' => $data ]; Logger::warning($log); if ($action=="response") { return $this->response($data, $code); } } return $this->response( array( "error" => $message ), $code); } public function createAction() { global $autocabApiConfig, $savvyext; $action = array_shift($this->requestUri); Logger::debug(['message' => 'AutocabApi::createAction()']); $code = 400; $message = "Bad request"; $data = []; $quoteId = $this->requestParams["quote_id"] ?? null; $bookingId = $this->requestParams["booking_id"] ?? null; $memberId = $this->requestParams["member_id"] ?? 0; $autocab = new Autocab($autocabApiConfig); $db = new Db(); if ($action == 'check' || $action =='booking') { $requestHeaders = getallheaders(); if ((empty($memberId) || $memberId <=0 ) && array_key_exists("x-session-id",$requestHeaders)) { $sessionId = $requestHeaders["x-session-id"]; list($member, $error) = Booking::getMemberBySessionId($db->getConnect(), $sessionId); if (isset($member)) { $memberId = $member['id']; } } if ((empty($memberId) || $memberId <=0 )) { $message = "Couldn't identify Member Id. The member_id or x-session-id is not specified"; return $this->response( array( "error" => $message ), $code ); } } switch($action) { case "check": if (isset($quoteId)) { list($message,$code,$action,$data) = AutocabApi::checkOffer($autocab, $db, $quoteId, $memberId, $bookingId); } break; case "booking": if(isset($bookingId)) { list($message,$code,$action,$data) = AutocabApi::booking($autocab, $db, $bookingId, $memberId); } break; case "events": list($message,$code,$action,$data) = AutocabApi::eventHandler($autocab, $db, $this->requestParams); break; default: if (isset($quoteId)) { list($message,$code,$action,$data) = AutocabApi::checkOffer($autocab, $db, $quoteId, $memberId, $bookingId); } else if(isset($bookingId)) { list($message,$code,$action,$data) = AutocabApi::booking($autocab, $db, $bookingId, $memberId); } } if ($code==200) { $log = [ 'message' => $message, 'code' => $code, 'action' => $action, 'data' => $data ]; Logger::warning($log); if ($action=="response") { return $this->response($data, $code); } } return $this->response( array( "error" => $message ), $code); } public function updateAction() { global $autocabApiConfig; $message = 'Update error'; $code = 400; $bookingId = $this->requestParams["booking_id"]; $vendorId = $this->requestParams["vendor_id"] ?? null; $availabilityRef = $this->requestParams["availability_ref"] ?? null; try { $db = new Db(); $autocab = new Autocab($autocabApiConfig); if(isset($bookingId)) { $booking = Booking::getById($db->getConnect(), $bookingId); if (count($booking) == 0) { throw new Exception( "Booking info not found for id = ${bookingId}", 400); } $details = json_decode($booking["details"], true); $vendorId = $details["vendor_id"]; $availabilityRef = $details["availability_ref"]; } else if (isset($availabilityRef)) { $booking = Booking::getByBookingRef($db->getConnect(), $bookingId); if (count($booking) == 0) { throw new Exception( "Booking info not found for booking ref = ${availabilityRef}", 400); } $bookingId = $booking["id"]; $details = json_decode($booking["details"], true); $vendorId = $details["vendor_id"]; $availabilityRef = $details["availability_ref"]; } else { throw new Exception("Required parameters booking_id or availability_ref is not provided", 400); } if (isset($availabilityRef)) { $resp = $autocab->cancelAvailability($availabilityRef, $vendorId); $error = $resp["error"]; $data = $resp["data"]; } else { throw new Exception("Invalid parameters set", 400); } if ($error != 0) { $message = $data["error"].": ".$data["error_description"].(isset($data["error_code"]) ? " Code:".$data["error_code"]:""); if (isset($bookingId)) { Booking::update($db->getConnect(), [ "id"=>$bookingId, "message" => $message, "completed" => "now()", "updated" => "now()", "status" => Booking::STATUS_ERROR, ]); } throw new Exception($message); } if (isset($bookingId)) { Booking::update( $db->getConnect(), [ "id" => $booking["id"], "completed" => "now()", "updated" => "now()", "status" => 3, "message" => "Canceled" ] ); } $rawData = $resp["raw_data"]; $request = $resp["request"]; AutocabAPI::storeDetails($db, $booking["id"], "cancel", $rawData, $booking["message"], $request); } catch (Exception $e) { $message = $e->getMessage(); $code = $e->getCode() != 0 ? $e->getCode() : 500; return $this->response( [ "error" => $message ], $code); } return $this->response([], 200); } public function deleteAction() { global $autocabApiConfig; $message = 'Delete error'; $code = 400; $bookingId = array_shift($this->requestUri); try { $db = new Db(); $autocab = new Autocab($autocabApiConfig); if(!isset($bookingId)) { throw new Exception("Required parameters booking_id is not provided", 400); } $booking = Booking::getById($db->getConnect(), $bookingId); if (count($booking) == 0) { throw new Exception( "Booking info not found for id = ${bookingId}", 400); } $details = json_decode($booking["details"], true); $vendorId = $details["vendor_id"]; $authorizationRef = $details["authorization_ref"]; if (!isset($authorizationRef)) { throw new Exception("Authorization Ref is not defined", 400); } $resp = $autocab->bookingCancellation($authorizationRef, $vendorId); $error = $resp["error"]; $data = $resp["data"]; if ($error != 0) { $message = $data["error"].": ".$data["error_description"].(isset($data["error_code"]) ? " Code:".$data["error_code"]:""); Booking::update($db->getConnect(), [ "id"=>$bookingId, "message" => $message, "updated" => "now()", "completed" => "now()", "status" => Booking::STATUS_ERROR, ]); throw new Exception($message); } list($booking) = Booking::update( $db->getConnect(), [ "id" => $booking["id"], "completed" => "now()", "updated" => "now()", "status" => Booking::STATUS_CANCELED, "message" => "Cancelled" ] ); $rawData = $resp["raw_data"]; $request = $resp["request"]; AutocabAPI::storeDetails($db, $booking["id"], "cancel", $rawData, $booking["message"], $request); } catch (Exception $e) { $message = $e->getMessage(); $code = $e->getCode() != 0 ? $e->getCode() : 500; return $this->response( [ "error" => $message ], $code); } return $this->response([], 200); } public static function booking($autocab, $db, $bookingId, $memberId) { $log = [ 'message' => 'AutocabApi::booking', 'bookingId' => $bookingId, 'member_id' =>$memberId ]; Logger::debug($log); $message = "Failed to book trip"; $code = 500; $action = ""; $data = []; try { $booking = Booking::getLastNotCompletedBookingForMember($db->getConnect(), $memberId); if (count($booking) > 0) { throw new Exception("The previous booking has not completed or not cancelled yet. Cancel the previous booking to make a new one.", 409); } if (!isset($bookingId)) { throw new Exception('Invalid Booking id'); } $booking = Booking::getById($db->getConnect(), $bookingId); if (count($booking) == 0) { throw new Exception( "Booking info not found for id = ${bookingId}", 400); } $details = json_decode($booking["details"], true); $vendorId = $details["vendor_id"]; $availabilityRef = $details["availability_ref"]; $memberInfo = []; $q = "SELECT * FROM members WHERE id = $memberId LIMIT 1"; $r = pg_query($db->getConnect(), $q); //syslog(LOG_WARNING,$q); if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) { $memberInfo["name"] = $f["firstname"]." ".$f["lastname"]; $memberInfo["email"] = $f["email"]; $memberInfo["email"] = $f["email"]; $memberInfo["phone"] = $f["phone"]; } $resp = $autocab->booking($availabilityRef,[$memberInfo], $vendorId); $error = $resp["error"]; $data = $resp["data"]; if ($error != 0) { $autocab->cancelAvailability($availabilityRef, $vendorId); $message = $data["error"].": ".$data["error_description"].(isset($data["error_code"]) ? "Code:".$data["error_code"]:""); Booking::update($db->getConnect(), [ "id"=>$bookingId, "member_id" => $memberId, "message" => $message, "completed" => "now()", "updated" => "now()", "status" => Booking::STATUS_ERROR ]); throw new Exception("Booking failed. " . $message); } $details["authorization_ref"] = $data["authorization_ref"]; $details["booking_ref"] = $data["booking_ref"]; list($booking) = Booking::update($db->getConnect(), [ "id"=>$bookingId, "provider_booking_ref" => $data["authorization_ref"], "member_id" => $memberId, "message" => "Booked", "updated" => "now()", "status" => Booking::STATUS_BOOKED, "details" => json_encode($details) ]); $rawData = $resp["raw_data"]; $request = $resp["request"]; AutocabAPI::storeDetails($db, $booking["id"], "booking", $rawData, $booking["message"], $request); if (isset($booking)) { $booking["details"] = $details; } return ["Trip booked",200,"response",$booking]; } catch (Exception $e) { Logger::warning(['message' => 'AutocabApi::createReal exception', 'exception' => json_encode($e)]); syslog(LOG_WARNING,json_encode($e)); $message = $e->getMessage(); } Logger::warning(['message' => $message]); return [$message,$code,$action,$data]; } public static function checkOffer($autocab, $db, $quoteId, $memberId, $bookingId ) { $log = [ 'message' => 'AutocabApi::checkOffer', 'quoteId' => $quoteId, ]; Logger::debug($log); $message = "Failed to check offer"; $code = 500; $action = ""; $data = []; try { $booking = Booking::getLastNotCompletedBookingForMember($db->getConnect(), $memberId); if (count($booking) > 0) { throw new Exception("The previous booking has not completed or not cancelled yet. Cancel the previous booking to make a new one.", 409); } $quote = Quotes::getById($db->getConnect(), (int)$quoteId); if(!is_array($quote) || count($quote) == 0 || !isset($quote["automation_id"])) { throw new Exception("No quote found for id =${quoteId}", 400); } list($quoteService, $err) = Quotes::checkQuote($quote["automation_id"]); if ($err) { throw new Exception($err, 500); } if ($quoteService == null || $quoteService["complete"] =="" || $quoteService["message"] !="android_automation_job_detail") { throw new Exception("The quote has not completed yet for id =${quoteId}", 400); } list($details,$err) = Quotes::getQuoteDetails($quoteService["id"]); if ($details==NULL) { throw new Exception("The quote has not completed yet for id =${quoteId}", 400); } $low_estimate = $quoteService['cost']; $quoteServiceDetail = null; foreach ($details as $item) { $c_low_estimate = sprintf( "%0.02f", 0.01 * $item["low_estimate"] ); if ($low_estimate==$c_low_estimate || $low_estimate>$c_low_estimate) { $quoteServiceDetail = $item; break; } } $vendorId = null; if (is_array($quoteServiceDetail)) { $realQuoteDetail = json_decode( $quoteServiceDetail["warning_message"], true ); if ( is_array( $realQuoteDetail ) && isset( $realQuoteDetail["vendor_id"] ) ) { $vendorId = $realQuoteDetail["vendor_id"]; } } $source = [ 'address' => $quoteService["location_start"], 'latitude' => $quoteService["location_start_lat"], 'longitude' => $quoteService["location_start_lng"] ]; $destination = [ 'address' => $quoteService["location_end"], 'latitude' => $quoteService["location_end_lat"], 'longitude' => $quoteService["location_end_lng"] ]; $resp = $autocab->getBookingAvailability($source, $destination, $vendorId); $data = $resp["data"]; if ($resp["error"] != 0) { $message = $data["error"].": ".$data["error_description"].(isset($data["error_code"]) ? "Code:".$data["error_code"]:""); throw new Exception($message); } $vendorId = $data["vendor_id"]; $quoteService["availability_ref"] = $availabilityRef = $data["availability_ref"]; $quoteService["cost"] = sprintf( "%0.02f", 0.01 * $data["low_estimate"]); $requestData = [ "quote_id" => $quoteId, "member_id" => $memberId, "provider_booking_ref" => $data["availability_ref"], "details" => json_encode(["vendor_id"=>$vendorId,"availability_ref" => $availabilityRef]), "status" => Booking::STATUS_INIT, "cost" => $data["low_estimate"] ]; if (isset($bookingId)) { $booking = Booking::getById($db->getConnect(), $bookingId); if (isset($booking) && $booking['member_id'] == $memberId && $booking['status'] == Booking::STATUS_INIT) { $requestData['id'] = $bookingId; list($booking,$err) = Booking::update($db->getConnect(), $requestData); } else { list($booking,$err) = Booking::create($db->getConnect(), $requestData); } } else { list($booking,$err) = Booking::create($db->getConnect(), $requestData); } $log = [ 'message' => 'viewReal Booking::create response', 'booking' => $booking ]; Logger::debug($log); if($booking == null || !is_array($booking)) { $autocab->cancelAvailability($availabilityRef, $vendorId); $message = "Failed to create booking record: ".$err; throw new Exception($message); } $rawData = $resp["raw_data"]; $request = $resp["request"]; AutocabAPI::storeDetails($db, $booking["id"], "checkOffer", $rawData, $booking["message"],$request); $date = [ "booking_id" => $booking["id"], "created" => $booking["created"], "availability_ref" => $availabilityRef, "vendor_id" => $vendorId, "quote_id" => $quoteService["id"], "location_start" => $quoteService["location_start"], "location_start_lat" => $quoteService["location_start_lat"], "location_start_lng" => $quoteService["location_start_lng"], "location_end" => $quoteService["location_end"], "location_end_lat" => $quoteService["location_end_lat"], "location_end_lng" => $quoteService["location_end_lng"], "cost_raw" => $quoteService["cost_raw"], "cost" => $quoteService["cost"] ]; return ["Offer checked",200,"response", $date]; } catch (Exception $e) { Logger::warning(['message' => 'AutocabApi::checkOffer exception', 'exception' => json_encode($e)]); syslog(LOG_WARNING,json_encode($e)); $message = $e->getMessage(); if ($e->getCode() > 0) { $code = $e->getCode(); } } return [$message,$code,$action,$data]; } public static function eventHandler($autocab, $db, $requestParams) { $log = [ 'message' => 'AutocabApi::eventHandler', 'requestParams' => $requestParams, ]; Logger::debug($log); $message = "Failed to handle event"; $code = 200; $action = ""; $data = []; try { if (!isset($requestParams) || empty($requestParams['methodName']) || empty($requestParams['payload'])) { throw new Exception("Bad request parameters ", 400); } $eventName = $requestParams['methodName']; /* if (!in_array(strtolower($eventName), array_map('strtolower',['AgentVehicleArrivedEventRequest','AgentBookingCancelledEventRequest', 'AgentPassengerOnBoardEventRequest']))) { throw new Exception("Unsupported event", 404); } */ $payload = $requestParams['payload']; $inXml = new SimpleXMLElement( AutocabApi::decompress($payload)); $bookingRef = (string)$inXml->BookingReference; $authRef = (string)$inXml->AuthorizationReference; $vendorId = (string)$inXml->Vendor->attributes()->Id; $vendorRef = (string)$inXml->Vendor->Reference; $xmlElement = NULL; $shortMessage = NULL; $dbCode = NULL; $dbData = NULL; $notifyUser = false; $storeDetails = true; switch ($eventName) { case 'AgentVehicleArrivedEventRequest': $xmlElement = $autocab->getTemplate('autocab_agent_vehicle_arrived_response.xml'); list($shortMessage, $message, $dbCode, $dbData) = AutocabApi::vehicleArrivedEventHandler($inXml); $notifyUser = true; break; case 'AgentBookingCancelledEventRequest': case 'AgentNoFareEventRequest': // $xmlElement = $autocab->getTemplate('autocab_agent_booking_cancelled_response.xml'); $eventShortName = substr($eventName, 0, strrpos($eventName, 'Request')); $xmlElement = $autocab->getTemplate('autocab_response.xml', 'AgentEvent', $eventShortName); list($shortMessage, $message, $dbCode, $dbData) = AutocabApi::bookingCancelledEventHandler($inXml); $notifyUser = ($dbCode == Booking::STATUS_VENDOR_CANCELED); $storeDetails = ($dbCode == Booking::STATUS_VENDOR_CANCELED); break; case 'AgentPassengerOnBoardEventRequest': $eventShortName = substr($eventName, 0, strrpos($eventName, 'Request')); $xmlElement = $autocab->getTemplate('autocab_response.xml', 'AgentEvent', $eventShortName); list($shortMessage, $message, $dbCode, $dbData) = AutocabApi::passengerOnBoardEventHandler($inXml); break; case 'AgentLocationUpdateEventRequest': $eventShortName = substr($eventName, 0, strrpos($eventName, 'Request')); $xmlElement = $autocab->getTemplate('autocab_response.xml', 'AgentEvent', $eventShortName); list($shortMessage, $message, $dbCode, $dbData) = AutocabApi::locationUpdateEventHandler($inXml); $storeDetails = false; break; case 'AgentBookingDispatchedEventRequest': $eventShortName = substr($eventName, 0, strrpos($eventName, 'Request')); $xmlElement = $autocab->getTemplate('autocab_response.xml', 'AgentEvent', $eventShortName); list($shortMessage, $message, $dbCode, $dbData) = AutocabApi::bookingDispatchedEventHandler($inXml); break; case 'AgentBookingCompletedEventRequest': $eventShortName = substr($eventName, 0, strrpos($eventName, 'Request')); $xmlElement = $autocab->getTemplate('autocab_response.xml', 'AgentEvent', $eventShortName); list($shortMessage, $message, $dbCode, $dbData) = AutocabApi::bookingCompletedEventHandler($inXml); break; default: $code = 404; } if ($code == 404) { throw new Exception("Unsupported event", 404); } if (!$xmlElement) { throw new Exception("Response template not found", 500); } $acknowledgementRef = Uuid::uuid4()->toString(); $xmlElement->Vendor->attributes()->Id = $vendorId; $xmlElement->Vendor->Time = gmdate("Y-m-d\TH:i:s.v\Z"); $xmlElement->Vendor->Reference = $vendorRef; $xmlElement->AcknowledgementReference = Uuid::uuid4()->toString(); unset($xmlElement->Agent->Password); $booking = Booking::getByBookingRef($db->getConnect(), $authRef); if (count($booking) == 0) { $xmlElement->Result->Success = "false"; $xmlElement->Result->FailureCode = 3; $xmlElement->Result->FailureReason = 'Booking not found.'; } else { $bookingId = $booking["id"]; $memberId = $booking["member_id"]; $details = json_decode($booking["details"], true); $details['acknowledgement_ref'] = $acknowledgementRef; if (isset($dbData)) { $details['details'] = $dbData; } if (isset($dbCode)) { $completed = ($dbCode == Booking::STATUS_COMPLETED || $dbCode == Booking::STATUS_CANCELED || $dbCode == Booking::STATUS_VENDOR_CANCELED || $dbCode == Booking::STATUS_ERROR) ? "now()" : null; $data = [ "id"=>$bookingId, "message" => $message, "updated" => "now()", "completed" => $completed, "status" => $dbCode, "details" => json_encode($details) ]; if (!isset($completed)) { unset($data["completed"]); } if (!isset($message)) { unset($data["message"]); } if (Booking::STATUS_LOCATION_UPDATE == $dbCode) { unset($data["status"]); } list($booking) = Booking::update($db->getConnect(), $data); } if ($storeDetails) { $rawData = $inXml; AutocabAPI::storeDetails($db, $bookingId, "event:${eventName}", $rawData, $booking["message"]); } if ($notifyUser) { $result = AutocabApi::postOneSignal($db->getConnect(), $memberId, $shortMessage, $dbData); $log = [ 'message' => 'AutocabApi::eventHandler', 'postOneSignalResult' => $result, ]; } Logger::debug($log); } $template = str_replace('', '', $xmlElement->asXML()); $data = [ 'payload'=> AutocabApi::compress($template) ]; return ["Event $eventName handled", 200,"response", $data]; } catch (Exception $e) { Logger::warning(['message' => 'AutocabApi::eventHandler exception', 'exception' => json_encode($e)]); syslog(LOG_WARNING,json_encode($e)); $message = $e->getMessage(); if ($e->getCode() > 0) { $code = $e->getCode(); } else { $code = 500; } } return [$message,$code,$action,$data]; } protected static function vehicleArrivedEventHandler($inXml) { $data = [ 'vehicle' => [ 'callsign' => (string)$inXml->Vehicle->Callsign, 'make' => (string)$inXml->Vehicle->Make, 'model' => (string)$inXml->Vehicle->Model, 'colour' => (string)$inXml->Vehicle->Colour, 'registration' => (string)$inXml->Vehicle->Registration, 'plateNumber' => (string)$inXml->Vehicle->PlateNumber, ], 'location' => [ 'time'=> (string)$inXml->Location->Time, 'localTime'=> (string)$inXml->Location->LocalTime, 'lat' => (float)$inXml->Location->Coordinate->Latitude, 'lng' => (float)$inXml->Location->Coordinate->Longitude, ] ]; $shortMessage = 'Vehicle Arrived'; $message = 'Vehicle arrived'; $code = Booking::STATUS_VEHICLE_ARRIVED; return [$shortMessage, $message, $code, $data]; } protected static function bookingCancelledEventHandler($inXml) { $data = [ 'cancellationReason' => (string)$inXml->CancellationReason, 'cancellationMsg' => (string)$inXml->CancellationMsg ]; if ((string)$inXml->CancellationReason == 'CancelledByAgent') { $message = 'Booking cancelled. Cancellation Reason: '.(string)$inXml->CancellationReason.' Cancellation Message: '.(string)$inXml->CancellationMsg; $shortMessage = 'Booking cancelled'; $code = Booking::STATUS_CANCELED; } else { $message = 'Booking cancelled by vendor. Cancellation Reason: '.(string)$inXml->CancellationReason.' Cancellation Message: '.(string)$inXml->CancellationMsg; $shortMessage = 'Booking cancelled by vendor'; $code = Booking::STATUS_VENDOR_CANCELED; } return [$shortMessage, $message, $code, $data]; } protected static function passengerOnBoardEventHandler($inXml) { $data = [ 'location' => [ 'time'=> (string)$inXml->Location->Time, 'localTime'=> (string)$inXml->Location->LocalTime, 'lat' => (float)$inXml->Location->Coordinate->Latitude, 'lng' => (float)$inXml->Location->Coordinate->Longitude, ] ]; $shortMessage = 'Passenger on board.'; $message = 'Passenger on board.'; $code = Booking::STATUS_IN_PROGRESS; return [$shortMessage, $message, $code, $data]; } protected static function locationUpdateEventHandler($inXml) { $data = [ 'vehicle' => [ 'callsign' => (string)$inXml->Vehicle->Callsign, 'make' => (string)$inXml->Vehicle->Make, 'model' => (string)$inXml->Vehicle->Model, 'colour' => (string)$inXml->Vehicle->Colour, 'registration' => (string)$inXml->Vehicle->Registration, 'plateNumber' => (string)$inXml->Vehicle->PlateNumber, ], 'location' => [ 'time'=> (string)$inXml->Location->Time, 'localTime'=> (string)$inXml->Location->LocalTime, 'lat' => (float)$inXml->Location->Coordinate->Latitude, 'lng' => (float)$inXml->Location->Coordinate->Longitude, ], 'eta' => (string)$inXml->Eta, 'localEta' => (string)$inXml->LocalEta, 'etaInSeconds' => (string)$inXml->EtaInSeconds, 'distance' => (string)$inXml->Distance, ]; $shortMessage = 'Location updated'; $message = null; $code = Booking::STATUS_LOCATION_UPDATE; return [$shortMessage, $message, $code, $data]; } protected static function bookingDispatchedEventHandler($inXml) { $data = [ 'vehicle' => [ 'callsign' => (string)$inXml->Vehicle->Callsign, 'make' => (string)$inXml->Vehicle->Make, 'model' => (string)$inXml->Vehicle->Model, 'colour' => (string)$inXml->Vehicle->Colour, 'registration' => (string)$inXml->Vehicle->Registration, 'plateNumber' => (string)$inXml->Vehicle->PlateNumber, ], 'driver' => [ 'callsign' => (string)$inXml->Driver->Callsign, 'firstName' => (string)$inXml->Driver->Make, 'lastName' => (string)$inXml->Driver->Model, 'phoneNumber' => (string)$inXml->Driver->MobileNumber, 'badgeId' => (string)$inXml->Driver->BadgeId ], 'location' => [ 'time'=> (string)$inXml->Location->Time, 'localTime'=> (string)$inXml->Location->LocalTime, 'lat' => (float)$inXml->Location->Coordinate->Latitude, 'lng' => (float)$inXml->Location->Coordinate->Longitude, ], 'eta' => (string)$inXml->Eta, 'localEta' => (string)$inXml->LocalEta, 'etaInSeconds' => (string)$inXml->EtaInSeconds ]; $shortMessage = 'Booking dispatched.'; $message = 'Booking dispatched.'; $code = Booking::STATUS_DISPATCHED; return [$shortMessage, $message, $code, $data]; } protected static function bookingCompletedEventHandler($inXml) { $data = [ 'location' => [ 'time'=> (string)$inXml->Location->Time, 'localTime'=> (string)$inXml->Location->LocalTime, 'lat' => (float)$inXml->Location->Coordinate->Latitude, 'lng' => (float)$inXml->Location->Coordinate->Longitude, ] ]; $shortMessage = 'Booking completed.'; $message = 'Booking completed.'; $code = Booking::STATUS_COMPLETED; return [$shortMessage, $message, $code, $data]; } protected static function storeDetails($db, $bookingId, $action, $rawData, $message=NULL, $request=NULL) { list($bookingDetails) = Booking::createDetails($db->getConnect(), [ "booking_id"=>$bookingId, "action" => $action, "details" => json_encode($rawData), "message" => $message, "request" => isset($request) ? json_encode($request) : $request ]); return $bookingDetails; } public static function bookingStatus($autocab, $db, $bookingId) { $log = [ 'message' => 'AutocabApi::bookingStatus', 'bookingId' => $bookingId, ]; Logger::debug($log); $message = "Failed to check booking status"; $code = 500; $action = ""; $data = []; try { if ( ! isset($bookingId ) || !is_numeric($bookingId) ) { throw new Exception( "Bad request. The booking id is not specified or not number. Booking id: ${bookingId}", 400 ); } $booking = Booking::getById($db->getConnect(), $bookingId); if (count($booking) == 0) { throw new Exception( "The booking info not found for id = ${$bookingId}", 404); } $details = json_decode($booking["details"], true); $vendorId = $details["vendor_id"]; $authorizationRef = $details["authorization_ref"]; if (!isset($authorizationRef)) { throw new Exception("The Authorization Ref is not defined", 400); } $resp = $autocab->bookingStatus($authorizationRef, $vendorId); $error = $resp["error"]; $data = $resp["data"]; if ($error != 0) { $message = $data["error"].": ".$data["error_description"].(isset($data["error_code"]) ? " Code:".$data["error_code"]:""); throw new Exception($message); } return ["Booking checked",200,"response", $data]; } catch (Exception $e) { Logger::warning(['message' => 'AutocabApi::bookingStatus exception', 'exception' => json_encode($e)]); syslog(LOG_WARNING,json_encode($e)); $message = $e->getMessage(); if ($e->getCode() > 0) { $code = $e->getCode(); } } return [$message,$code,$action,$data]; } public static function bookingInfo($db, $bookingId) { $log = [ 'message' => 'AutocabApi::bookingInfo', 'bookingId' => $bookingId, ]; Logger::debug($log); $message = "Failed to check booking status"; $code = 500; $action = ""; $data = []; try { if ( ! isset($bookingId ) || !is_numeric($bookingId) ) { throw new Exception( "Bad request. The booking id is not specified or not number. Booking id: ${bookingId}", 400 ); } $booking = Booking::getById($db->getConnect(), $bookingId); if (count($booking) == 0) { throw new Exception( "The booking info not found for id = ${bookingId}", 404); } $details = json_decode($booking["details"], true); $booking["details"] = $details; $bookingDetailsList = Booking::getDetailsByBookingId($db->getConnect(), $bookingId); if (count($bookingDetailsList) > 0) { for ($i = 0; $i < count($bookingDetailsList); $i++) { $d = json_decode($bookingDetailsList[$i]["details"], true); $bookingDetailsList[$i]["details"] = $d; } } $booking["bookingDetails"] = $bookingDetailsList; return ["Booking checked",200,"response", $booking]; } catch (Exception $e) { Logger::warning(['message' => 'AutocabApi::bookingInfo exception', 'exception' => json_encode($e)]); syslog(LOG_WARNING,json_encode($e)); $message = $e->getMessage(); if ($e->getCode() > 0) { $code = $e->getCode(); } } return [$message,$code,$action,$data]; } public static function memberBookingList($db, $memberId, $params = []) { $log = [ 'message' => 'AutocabApi::memberBookingList', 'bookingId' => $memberId, 'params' => $params, ]; Logger::debug($log); $message = "Failed to get member's booking list"; $code = 500; $action = ""; $data = []; try { if ( ! isset($memberId ) || !is_numeric($memberId) ) { throw new Exception( "Bad request. The member id is not specified or not number. Member id: ${$memberId}", 400 ); } $data = Booking::getByMemberId($db->getConnect(), $memberId, $params); return ["Member's booking list ",200,"response", $data]; } catch (Exception $e) { Logger::warning(['message' => 'AutocabApi::memberBookingList exception', 'exception' => json_encode($e)]); syslog(LOG_WARNING,json_encode($e)); $message = $e->getMessage(); if ($e->getCode() > 0) { $code = $e->getCode(); } } return [$message,$code,$action,$data]; } public static function bookingList($db, $params = []) { $log = [ 'message' => 'AutocabApi::bookingList', 'params' => $params, ]; Logger::debug($log); $message = "Failed to get booking list"; $code = 500; $action = ""; $data = []; try { $data = Booking::getAll($db->getConnect(), $params); return ["Booking list ",200,"response", $data]; } catch (Exception $e) { Logger::warning(['message' => 'AutocabApi::bookingList exception', 'exception' => json_encode($e)]); syslog(LOG_WARNING,json_encode($e)); $message = $e->getMessage(); if ($e->getCode() > 0) { $code = $e->getCode(); } } return [$message,$code,$action,$data]; } private static function decompress($str) { return gzinflate(base64_decode($str)); } private static function compress($str) { return base64_encode(gzdeflate($str, 9)); } private static function postOneSignal($db, $memberId, $message, $arrayData) { global $savvyext; $url = $savvyext->cfgReadChar('onesignal.url'); $app_id = $savvyext->cfgReadChar('onesignal.app_id'); $devices = []; // reset the data $q = "SELECT * FROM members_devices WHERE status =1 AND member_id=${memberId} "; $r1 = pg_query($db, $q); while ($f1 = pg_fetch_assoc($r1)) { if (!empty($f1["player_id"])) { $devices[] = $f1["player_id"]; } } $result = NULL; if (count($devices)) { $data = [ 'app_id' => $app_id, 'contents' => ['en' => $message], 'headings' => ['en' => 'Float Activities'], 'subtitle' => ['en' => 'Your account activities message from Float.'], 'content_available' => true, 'mutable_content' => true, 'include_player_ids' => $devices, 'data' => $arrayData ]; $opts = array( 'http' => array( 'method' => "POST", 'header' => "Content-Type: application/json; charset=utf-8\r\n" . "Accept: application/json\r\n", 'content' => json_encode($data) ) ); $context = stream_context_create($opts); $body = file_get_contents($url, false, $context); $result = json_decode($body, true); } return $result; } }