Files
dev-chiefworks 47f4fad75c Added Other AP
2022-04-26 11:30:34 -04:00

431 lines
14 KiB
PHP

<?php
use GuzzleHttp\Client;
use GuzzleHttp\Psr7;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException;
class Autocab {
const TIMEOUT = 60;
const DEBUG = false;
const SSL_VERIFY = false;
const REASON_NOT_REQUIRED = "NotRequired";
const REASON_PRICE_CHANGED = "PriceChanged";
private $httpClient;
private $agentId;
private $agentPassword;
private $currency;
private $vendorId;
private $templatesDir;
private $config = [];
private $templates = [];
public function __construct($config) {
if (empty($config)) {
throw new Exception("Configuration is not provided");
}
$this->setConfig($config);
if (!isset($config["baseUrl"]) || empty($config["baseUrl"])) {
throw new Exception("The API URL is not specified");
}
$this->httpClient = new Client(['base_uri' => $config["baseUrl"]]);
}
public function setConfig($config) {
global $savvyext;
$this->config = $config;
$this->agentId = $config["agentId"] ;
$this->agentPassword = $config["agentPassword"];
$this->currency = $config["currency"];
$this->templatesDir = $config["templatesDir"];
$this->loadTemplates($config);
}
public function loadTemplates($config) {
if ( !array_key_exists('templatesDir', $config) || empty($config["templatesDir"])) {
throw new Exception("The templates dir is not specified");
}
$files = scandir($this->templatesDir);
if ($files) {
foreach ($files as $templateFile) {
$template = file_get_contents($this->templatesDir."/".$templateFile);
if ($template) {
$this->templates[$templateFile] = $template;
}
}
}
if (count($this->templates) == 0) {
throw new Exception("Any one template is not initialized");
}
}
public function getTemplate($name, $oldRootTag=NULL, $newRootTag=NULL) {
if (!isset($this->templates[$name])) {
return false;
}
$template = $this->templates[$name];
if (isset($oldRootTag) && isset($newRootTag)) {
$template = str_replace($oldRootTag, $newRootTag, $template);
}
$xmlElement = new SimpleXMLElement($template);
$xmlElement->Agent->attributes()->Id = $this->config["agentId"];
$xmlElement->Agent->Password = $this->config["agentPassword"];
return $xmlElement;
}
public function getHeaders($extraHeaders = []) {
$headers = [
'content-type' => 'text/xml',
];
return array_merge($headers,$extraHeaders);
}
public function getAvailability($source, $destination) {
if (!isset($this->templates['autocab_agent_bid_request.xml'])) {
throw new Exception("Bid request template is not initialized");
}
$uri = '/api/agent';
$xmlElement = $this->getTemplate('autocab_agent_bid_request.xml');
$xmlElement->Agent->Time = gmdate("Y-m-d\TH:i:s.v\Z");
$xmlElement->BidParameters->Journey->From->Data = $source["address"];
$xmlElement->BidParameters->Journey->From->Coordinate->Latitude = $source["latitude"];
$xmlElement->BidParameters->Journey->From->Coordinate->Longitude = $source["longitude"];
$xmlElement->BidParameters->Journey->To->Data = $destination["address"];
$xmlElement->BidParameters->Journey->To->Coordinate->Latitude = $destination["latitude"];
$xmlElement->BidParameters->Journey->To->Coordinate->Longitude = $destination["longitude"];
$xml = $xmlElement->asXML();
$result = $this->genericPost($uri, $xml);
if ($result["error"]) {
return $result;
}
if ($result["code"] != 200) {
var_dump($result["data"]);
}
$xmlResponse = new SimpleXMLElement($result["data"]);
$error = self::processError($xmlResponse);
if($error) {
return ["error"=>1, "data" => $error, "request"=>$xmlElement];
}
$costs = [];
foreach ($xmlResponse->Offers->Offer as $offer) {
$item = self::processBidOffer($offer);
array_push($costs, $item);
}
return array("error"=>0, "data"=>$costs, "raw_data"=>$xmlResponse, "request"=>$xmlElement);
}
public function getBookingAvailability($source, $destination, $vendor) {
if (!isset($this->templates['autocab_agent_booking_availability_request.xml'])) {
throw new Exception("Booking Availability request template is not initialized");
}
$uri = '/api/agent';
$xmlElement = $this->getTemplate('autocab_agent_booking_availability_request.xml');
$xmlElement->Vendor->attributes()->Id = $vendor;
$xmlElement->Agent->Time = gmdate("Y-m-d\TH:i:s.v\Z");
$xmlElement->BookingParameters->Journey->From->Data = $source["address"] ?? "No Address";
$xmlElement->BookingParameters->Journey->From->Coordinate->Latitude = $source["latitude"];
$xmlElement->BookingParameters->Journey->From->Coordinate->Longitude = $source["longitude"];
$xmlElement->BookingParameters->Journey->To->Data = $destination["address"] ?? "No Address";
$xmlElement->BookingParameters->Journey->To->Coordinate->Latitude = $destination["latitude"];
$xmlElement->BookingParameters->Journey->To->Coordinate->Longitude = $destination["longitude"];
$xml = $xmlElement->asXML();
$result = $this->genericPost($uri, $xml);
if ($result["error"]) {
return $result;
}
if ($result["code"] != 200) {
var_dump($result["data"]);
}
$xmlResponse = new SimpleXMLElement($result["data"]);
$error = self::processError($xmlResponse);
if($error) {
return ["error"=>1, "data" => $error, "request"=>$xmlElement];
}
$cost = null;
if(isset($xmlResponse->Pricing)) {
$cost = [
'currency' => (string)$xmlResponse->Pricing->Currency,
'availability_ref' => (string)$xmlResponse->AvailabilityReference,
'display_name' => (string)$xmlResponse->VendorDetails->Name,
'high_estimate' => (int)$xmlResponse->Pricing->Price,
'low_estimate' => (int)$xmlResponse->Pricing->Price,
'distance_estimate' => (int) $xmlResponse->EstimatedJourney->Distance,
'duration_estimate' => (int) $xmlResponse->EstimatedJourney->Duration * 60,
'vendor_id' => (string) $xmlResponse->Vendor->attributes()->Id,
];
}
return ["error"=>0, "data"=>$cost, "raw_data"=>$xmlResponse, "request"=>$xmlElement];
}
public function cancelAvailability($availabilityRef, $vendor, $reason = self::REASON_NOT_REQUIRED) {
if (!isset($this->templates['autocab_agent_booking_not_authorized_request.xml'])) {
throw new Exception("BookingNotAuthorizedRequest template is not initialized");
}
if (!isset($availabilityRef)) {
throw new Exception("Invalid availability reference");
}
$uri = '/api/agent';
$xmlElement = $this->getTemplate('autocab_agent_booking_not_authorized_request.xml');
$xmlElement->Vendor->attributes()->Id = $vendor;
$xmlElement->Agent->Time = gmdate("Y-m-d\TH:i:s.v\Z");
$xmlElement->AvailabilityReference = $availabilityRef;
$xmlElement->Reason = $reason;
$xml = $xmlElement->asXML();
$result = $this->genericPost($uri, $xml);
if ($result["error"]) {
return $result;
}
if ($result["code"] != 200) {
var_dump($result["data"]);
}
$xmlResponse = new SimpleXMLElement($result["data"]);
$error = self::processError($xmlResponse);
if($error) {
return ["error"=>1, "data" => $error, "request"=>$xmlElement];
}
return ["error"=>0, "data"=>[], "raw_data"=>$xmlResponse, "request"=>$xmlElement];
}
public function booking($availabilityRef, $passengers=[], $vendor) {
if (!isset($this->templates['autocab_agent_booking_athorization_request.xml'])) {
throw new Exception("BookingAuthorization template is not initialized");
}
if (!isset($availabilityRef)) {
throw new Exception("Invalid availability reference");
}
if (!is_array($passengers) || count($passengers) < 1
|| !array_key_exists("name", $passengers[0]) || empty($passengers[0]["name"])
) {
throw new Exception("Invalid passengers information");
}
$uri = '/api/agent';
$xmlElement = $this->getTemplate('autocab_agent_booking_athorization_request.xml');
$xmlElement->Vendor->attributes()->Id = $vendor;
$xmlElement->Agent->Time = gmdate("Y-m-d\TH:i:s.v\Z");
$xmlElement->AvailabilityReference = $availabilityRef;
foreach ($passengers as $key => $passenger) {
$xmlPassenger = $xmlElement->Passengers->addChild("PassengerDetails");
$isLead = ($key === array_keys($passengers)[0]) ? "true" : "false";
$xmlPassenger->addAttribute("IsLead", "$isLead");
$xmlPassenger->addChild("Name", $passenger["name"]);
if (array_key_exists("phone", $passenger) && isset($passenger["phone"])) {
$xmlPassenger->addChild( "TelephoneNumber", $passenger["phone"] );
}
if (array_key_exists("email", $passenger) && isset($passenger["email"])) {
$xmlPassenger->addChild("EmailAddress", $passenger["email"]);
}
}
$xml = $xmlElement->asXML();
$result = $this->genericPost($uri, $xml);
if ($result["error"]) {
return $result;
}
if ($result["code"] != 200) {
var_dump($result["data"]);
}
$xmlResponse = new SimpleXMLElement($result["data"]);
$error = self::processError($xmlResponse);
if($error) {
return ["error"=>1, "data" => $error];
}
$resp = [];
if(isset($xmlResponse->AuthorizationReference)) {
$resp = [
'authorization_ref' => (string)$xmlResponse->AuthorizationReference,
'booking_ref' => (string)$xmlResponse->BookingReference,
];
}
return ["error"=>0, "data"=>$resp, "raw_data"=>$xmlResponse, "request"=>$xmlElement];
}
public function bookingStatus($authorizationRef, $vendor) {
if (!isset($this->templates['autocab_agent_booking_status_request.xml'])) {
throw new Exception("BookingStatusRequest template is not initialized");
}
if (!isset($authorizationRef)) {
throw new Exception("Invalid authorization reference");
}
$uri = '/api/agent';
$xmlElement = $this->getTemplate('autocab_agent_booking_status_request.xml');
$xmlElement->Vendor->attributes()->Id = $vendor;
$xmlElement->Agent->Time = gmdate("Y-m-d\TH:i:s.v\Z");
$xmlElement->AuthorizationReference = $authorizationRef;
$xml = $xmlElement->asXML();
$result = $this->genericPost($uri, $xml);
if ($result["error"]) {
return $result;
}
if ($result["code"] != 200) {
var_dump($result["data"]);
}
$xmlResponse = new SimpleXMLElement($result["data"]);
$error = self::processError($xmlResponse);
if($error) {
return ["error"=>1, "data" => $error, "request"=>$xmlElement];
}
$resp = [
'booking_ref' => (string)$xmlResponse->BookingReference,
'status' => (string)$xmlResponse->Status,
'cancellation_reason' => (string)$xmlResponse->CancellationReason
];
return ["error"=>0, "data"=>$resp, "raw_data"=>$xmlResponse, "request"=>$xmlElement];
}
public function bookingCancellation($authorizationRef, $vendor) {
if (!isset($this->templates['autocab_agent_booking_cancellation_request.xml'])) {
throw new Exception("BookingCancellationRequest template is not initialized");
}
if (!isset($authorizationRef)) {
throw new Exception("Invalid authorization reference");
}
$uri = '/api/agent';
$xmlElement = $this->getTemplate('autocab_agent_booking_cancellation_request.xml');
$xmlElement->Vendor->attributes()->Id = $vendor;
$xmlElement->Agent->Time = gmdate("Y-m-d\TH:i:s.v\Z");
$xmlElement->AuthorizationReference = $authorizationRef;
$xml = $xmlElement->asXML();
$result = $this->genericPost($uri, $xml);
if ($result["error"]) {
return $result;
}
if ($result["code"] != 200) {
var_dump($result["data"]);
}
$xmlResponse = new SimpleXMLElement($result["data"]);
$error = self::processError($xmlResponse);
if($error) {
return ["error"=>1, "data" => $error, "code" => 500, "request"=>$xmlElement];
}
$resp = [];
return ["error"=>0, "data"=>$resp, "code" => 200, "raw_data"=>$xmlResponse, "request"=>$xmlElement];
}
private function genericPost($uri, $xml, $extraHeaders=[]) {
$code = 0;
$data = [];
$error = 0;
try {
$json = json_encode($data);
$length = strlen($json);
$response = $this->httpClient->request('POST', $uri, [
'decode_content' => true,
'connect_timeout' => SELF::TIMEOUT,
'debug' => SELF::DEBUG,
'verify' => SELF::SSL_VERIFY,
'headers' => $this->getHeaders(),
'body' => $xml
]);
$code = $response->getStatusCode();
$data = $response->getBody();
} catch (RequestException $e) {
if (SELF::DEBUG) {
echo Psr7\str($e->getRequest());
if ($e->hasResponse()) {
echo Psr7\str($e->getResponse());
}
}
if ($e->hasResponse()) {
$code = (int) $e->getResponse()->getStatusCode();
}
$data = ["error" => "exception", "error_description" => $e->getMessage()];
$error = 1;
} catch (ClientException $e) {
if (SELF::DEBUG) {
echo Psr7\str($e->getRequest());
echo Psr7\str($e->getResponse());
}
$code = (int)$e->getResponse()->getStatusCode();
$data = ["error" => "exception", "error_description" => $e->getMessage()];
$error = 1;
} catch (Exception $e) {
if (SELF::DEBUG) {
echo Psr7\str($e->getRequest());
echo Psr7\str($e->getResponse());
}
$code = (int)$e->getResponse()->getStatusCode();
$data = ["error" => "exception", "error_description" => $e->getMessage()];
$error = 1;
}
return ["error" => $error, "data" => $data, "code" => $code];
}
public static function processError($xmlResponse) {
if ((string)$xmlResponse->Result->Success == "true") {
return false;
}
return ["error"=>"API error", "error_description" => (string) $xmlResponse->Result->FailureReason, "error_code" => (string) $xmlResponse->Result->FailureCode];
}
public static function processBidOffer($offer) {
$item = [
'currency' => (string)$offer->Pricing->Currency,
'transport_product' => (string)$offer['Reference'],
'display_name' => (string)$offer->VendorDetails->Name,
'high_estimate' => (int)$offer->Pricing->Price,
'low_estimate' => (int)$offer->Pricing->Price,
'distance_estimate' => (int) $offer->EstimatedJourney->Distance,
'duration_estimate' => (int) $offer->EstimatedJourney->Duration * 60,
];
return $item;
}
}