431 lines
14 KiB
PHP
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;
|
|
}
|
|
|
|
} |