PHP File Manager
Editing File: Ups.php
<?php /* * Copyright (C) Wayne Purton-Smith - All Rights Reserved * Unauthorized copying of this file or removing this paragraph, via any medium is strictly prohibited * Proprietary and confidential * Written by Wayne Purton-Smith <waynepurtonsmith@hotmail.co.uk> February 2014 */ class Ups extends CI_Model { const UPS_TEST_URL = 'https://wwwcie.ups.com/ups.app/xml'; const UPS_PRODUCTION_URL = 'https://onlinetools.ups.com/ups.app/xml'; private $_username; private $_password; private $_access_key; private $_shipper_number; private $_env = 'test'; private $_related_order_id; private $_pickup_date; private $_arrival_date; private $_request_body; private $_response; private $warnings = array(); private $errors = array(); private $error; public $origin; public $destination; public $shipper = false; public $response; function __construct() { $this->_access_key = $this->config->item('ups_access_key'); $this->_shipper_number = $this->config->item('ups_shipper_number'); $this->_username = $this->config->item('ups_username'); $this->_password = $this->config->item('ups_password'); } private static $transit_rate_codes = array ( // Name R TiT array('UPS Worldwide Express', '07', '01'), array('UPS Worldwide Expedited', '08', '05'), array('UPS Standard', '11', '25'), array('UPS Standard', '11', '08'), array('UPS Worldwide Express Plus', '54', '21'), array('UPS Saver', '65', '28'), array('UPS Worldwide Express Freight', '96', '29'), array('UPS Express', '07', '24'), array('UPS Express', '07', '10'), array('UPS Express Plus', '54', '23'), array('UPS Express Saver', '86', '26') ); public function transitCodeToRateCode($code = '') { foreach(self::$transit_rate_codes as $code_row) { if($code_row[2] == $code) { return (object) array ( 'name' => $code_row[0], 'code' => $code_row[1] ); } } return false; } public function enviornment($env = 'test') { $this->_env = (in_array($env, array('test', 'production'))) ? $env : 'test'; return $this; } public function earliestPickupDate($date = NULL) { $tomorrow = strtotime('tomorrow 00:00:00'); if(!is_numeric($date)) { $date = strtotime($date . ' 00:00:00'); } if($date > 0) { if($date > $tomorrow) { return strtotime('-1 day', $date); } } return $tomorrow; } public function setAddress($type, $address_data = array()) { if(isset($type) && property_exists(__CLASS__, $type)) { $this->$type = array_merge(array ( 'company' => '', 'name' => '', 'full_name' => '', 'address' => array ( 'address_1' => '', 'address_2' => '', 'address_3' => '', 'town' => '', 'county' => '', 'postcode' => '', 'country_code' => '' ), 'phone' => '', 'fax' => '', 'residential' => false ), $address_data); } return $this; } public function setRelatedOrderId($order_id = NULL) { $this->_related_order_id = (($order_id = (int) $order_id) > 0) ? $order_id : NULL; return $this; } public function validateAddress($address_data = array()) { $request = array ( 'Request' => array ( 'RequestAction' => 'XAV', 'RequestOption' => '3', 'TransactionReference' => array ( 'CustomerContext' => '' ) ), 'MaximumListSize' => '3', 'AddressKeyFormat' => array ( 'ConsigneeName' => (isset($address_data['company']) && strlen($address_data['company'])) ? $address_data['company'] : ((isset($address_data['name'])) ? $address_data['name'] : ''), 'BuildingName' => (isset($address_data['company']) && strlen($address_data['company'])) ? $address_data['company'] : '', '#list' => array ( 'AddressLine' => (isset($address_data['address_1'])) ? $address_data['address_1'] : '', 'AddressLine' => (isset($address_data['address_2'])) ? $address_data['address_2'] : '', 'AddressLine' => (isset($address_data['address_3'])) ? $address_data['address_3'] : '' ), 'PoliticalDivision2' => (isset($address_data['town'])) ? $address_data['town'] : '', 'PoliticalDivision1' => (isset($address_data['county'])) ? $address_data['county'] : '', 'PostcodePrimaryLow' => (isset($address_data['postcode'])) ? $address_data['postcode'] : '', 'CountryCode' => (isset($address_data['country_code'])) ? $address_data['country_code'] : '' ) ); $request_data = $this->_wrapBaseXML('AddressValidationRequest', $this->_arrayToXML($request)); $this->sendRequest('/XAV', $request_data); $response = $this->getXMLResponseToJSON(); $this->response->actual = $response; $this->response->actualXML = $this->getResponse(); $this->response->sent = $this->getXMLRequestBody(); $this->response->sentXML = $this->getRequestBody(); //print_r($response); //print_r($this->getXMLRequestBody()); // TimeInTransit return $this->response; } public function timeInTransit($data = array()) { $data['shipper'] = (isset($data['shipper'])) ? $data['shipper'] : (($this->shipper) ? $this->shipper : $this->origin); $data['ship_to'] = (isset($data['ship_to'])) ? $data['ship_to'] : $this->destination; //print_r($data); $pick_up_date = (isset($data['pickup_date']) && ($pick_up_date = (int) $data['pickup_date']) > 0) ? $pick_up_date : strtotime('tomorrow'); $total_cost = (isset($data['total_cost'])) ? $data['total_cost'] : 0; $total_weight = 0; $total_items = 0; if(isset($data['items'])) { foreach($data['items'] as $item_info) { $total_weight += $item_info['weight']; $total_items += 1; } } $request = array ( 'Request' => array ( 'RequestAction' => 'TimeInTransit', 'TransactionReference' => array ( 'CustomerContext' => '' ) ), 'ShipmentWeight' => array ( 'UnitOfMeasurement' => array ( 'Code' => 'KGS' ), 'Weight' => $total_weight ), 'TransitFrom' => array ( 'AddressArtifactFormat' => $this->buildTransitAddress($data['shipper']['address']) ), 'TransitTo' => array ( 'AddressArtifactFormat' => $this->buildTransitAddress($data['ship_to']['address']) ), 'PickupType' => array ( 'Code' => '01' ), 'PickupDate' => date('Ymd', $pick_up_date), 'TotalPackagesInShipment' => $total_items, 'InvoiceLineTotal' => array ( 'MonetaryValue' => $total_cost, 'CurrencyCode' => 'GBP' ) ); $request_data = $this->_wrapBaseXML('TimeInTransitRequest', $this->_arrayToXML($request)); $this->sendRequest('/TimeInTransit', $request_data); $response = $this->getXMLResponseToJSON(); //predump($response); if($response->Response->ResponseStatusCode == '1') { $this->responseIsSuccess(); $this->response->disclaimer = flip_date($response->TransitResponse->Disclaimer); $this->response->pickupDate = flip_date($response->TransitResponse->PickupDate); $this->response->pickupDateTimestamp = strtotime($this->response->pickupDate); $services = array(); foreach($response->TransitResponse->ServiceSummary as $service_info) { $services[] = (object) array ( 'serviceType' => $service_info->Service->Code, 'serviceTypeLabel' => $service_info->Service->Description, 'guaranteed' => ($service_info->Guaranteed->Code == 'Y'), 'estimatedArrival' => (object) array ( 'businessDays' => (int) $service_info->EstimatedArrival->BusinessTransitDays, 'totalDays' => (int) $service_info->EstimatedArrival->TotalTransitDays, 'pickupDate' => flip_date($service_info->EstimatedArrival->PickupDate), 'pickupTime' => $service_info->EstimatedArrival->PickupTime, 'pickupTimestamp' => strtotime($service_info->EstimatedArrival->PickupDate . ' ' . $service_info->EstimatedArrival->PickupTime), 'pickupFormatted' => date('l, jS F - H:i', strtotime($service_info->EstimatedArrival->PickupDate . ' ' . $service_info->EstimatedArrival->PickupTime)), 'date' => flip_date($service_info->EstimatedArrival->Date), 'time' => $service_info->EstimatedArrival->Time, 'dateTimestamp' => strtotime($service_info->EstimatedArrival->Date . ' ' . $service_info->EstimatedArrival->Time), 'dateFormatted' => date('l, jS F - H:i', strtotime($service_info->EstimatedArrival->Date . ' ' . $service_info->EstimatedArrival->Time)) ), 'saturdayDelivery' => (isset($service_info->SaturdayDelivery)) ? ((int) $service_info->SaturdayDelivery === 1) : false, 'disclaimer' => (isset($service_info->SaturdayDeliveryDisclaimer)) ? nullify($service_info->SaturdayDeliveryDisclaimer) : NULL ); } $this->response->services = $services; } else { $this->responseIsError(); } $this->response->actual = $response; $this->response->actualXML = $this->getResponse(); $this->response->sent = $this->getXMLRequestBody(); $this->response->sentXML = $this->getRequestBody(); //print_r($response); //print_r($this->getXMLRequestBody()); // TimeInTransit return $this->response; } public function getShippingRates($data = array()) { $request = array ( 'Request' => array ( 'RequestAction' => 'Rate', 'RequestOption' => 'Rate', 'TransactionReference' => array ( 'CustomerContext' => '' ) ), 'PickupType' => array ( 'Code' => '01' ), 'Shipment' => $this->generateShipment($data) ); if(!($service_code = $this->transitCodeToRateCode($request['Shipment']['Service']['Code']))) { throw new Exception('The service code was not found'); } if(!$this->extractEstimatedTimes($data)) { throw new Exception('Malformed request'); } $request['Shipment']['Service']['Code'] = $service_code->code; $request['Shipment']['Service']['Description'] = $service_code->name; $request['Shipment']['PaymentInformation'] = $this->buildPaymentInformation(); $request_data = $this->_wrapBaseXML('RatingServiceSelectionRequest', $this->_arrayToXML($request)); //echo $request_data;exit; $this->sendRequest('/Rate', $request_data); $response = $this->getXMLResponseToJSON(); if($response->Response->ResponseStatusCode == '1') { $this->responseIsSuccess(); if(isset($response->RatedShipment->RatedShipmentWarning)) { foreach($response->RatedShipment->RatedShipmentWarning as $warning) { $this->response->warnings[] = (string) $warning; } } foreach($response->RatedShipment as $service_key => $service_info) { if(isset($service_info->MonetaryValue)) { $split_words = preg_split('/(?=[A-Z])/', $service_key); $info_key = lcfirst($service_key); $this->response->rateBreakdown->$info_key = (object) array ( 'label' => trim(implode(' ', $split_words)), 'amount' => (float) $service_info->MonetaryValue, 'currency' => (string) $service_info->CurrencyCode ); } } $this->response->guaranteedDays = (count((array) $response->RatedShipment->GuaranteedDaysToDelivery)) ? (int) $response->RatedShipment->GuaranteedDaysToDelivery : NULL; $this->response->scheduledDeliveryTime = (count((array) $response->RatedShipment->ScheduledDeliveryTime)) ? $response->RatedShipment->ScheduledDeliveryTime : NULL; if(count((array) $response->RatedShipment->GuaranteedDaysToDelivery)) { //$date = (time() + ($response->RatedShipment->GuaranteedDaysToDelivery * 86400)); } $this->response->rateTotal = $this->response->rateBreakdown->totalCharges; } else { $this->responseIsError(); } $this->response->actual = $response; $this->response->actualXML = $this->getResponse(); $this->response->sent = $this->getXMLRequestBody(); $this->response->sentXML = $this->getRequestBody(); return $this->response; } // Confirms the rate provided when searching for the rates // It will return a digest string to be passed to the accept function public function confirmShipment($data = array()) { $request = array ( 'Request' => array ( 'RequestAction' => 'ShipConfirm', 'RequestOption' => 'nonvalidate', 'TransactionReference' => array ( 'CustomerContext' => '' ) ), 'PickupType' => array ( 'Code' => '01' ), 'LabelSpecification' => $this->buildLabelSpecification(), 'Shipment' => $this->generateShipment($data) ); if(isset($data['service'])) { $request['Shipment']['Service']['Code'] = $data['service']; } if(!($service_code = $this->transitCodeToRateCode($request['Shipment']['Service']['Code']))) { throw new Exception('The service code was not found'); } if(!$this->extractEstimatedTimes($data)) { throw new Exception('Malformed request'); } $request['Shipment']['Service']['Code'] = $service_code->code; $request['Shipment']['Service']['Description'] = $service_code->name; if(isset($data['description']) && strlen(remove_whitespace($data['description']))) { $request['Shipment']['Description'] = $data['description']; } $request['Shipment']['PaymentInformation'] = $this->buildPaymentInformation(); $request_data = $this->_wrapBaseXML('ShipmentConfirmRequest', $this->_arrayToXML($request)); $this->sendRequest('/ShipConfirm', $request_data); $response = $this->getXMLResponse(); if((string) $response->Response->ResponseStatusCode === '1') { $this->responseIsSuccess(); $this->response->identificationNumber = trim((string) $response->ShipmentIdentificationNumber); $this->response->digestString = trim((string) $response->ShipmentDigest); } else { $this->responseIsError(); } //print_r($response);exit; $this->response->actual = $response; $this->response->actualXML = $this->getResponse(); $this->response->sent = $this->getXMLRequestBody(); $this->response->sentXML = $this->getRequestBody(); return $this->response; } // Sends the digest code and accepts the shipment public function acceptShipment($digest_string = '') { $request = array ( 'Request' => array ( 'RequestAction' => 'ShipAccept', 'TransactionReference' => array ( 'CustomerContext' => '' ) ), 'PickupType' => array ( 'Code' => '01' ), 'ShipmentDigest' => $digest_string ); $request_data = $this->_wrapBaseXML('ShipmentAcceptRequest', $this->_arrayToXML($request)); $this->sendRequest('/ShipAccept', $request_data); $response = $this->getXMLResponse(); if((string) $response->Response->ResponseStatusCode === '1') { $this->responseIsSuccess(); $this->response->trackingNumber = trim((string) $response->ShipmentResults->ShipmentIdentificationNumber); foreach($response->ShipmentResults->PackageResults as $package_info) { $package_tracking_number = trim((string) $package_info->TrackingNumber); $this->response->trackingNumbers[] = $package_tracking_number; $this->saveShippingZplLabel($package_tracking_number, (string) $package_info->LabelImage->GraphicImage, $package_tracking_number); /* if(($tracking_label_image = $this->saveShippingLabel($package_tracking_number, (string) $package_info->LabelImage->GraphicImage, $package_tracking_number))) { $label_info = getimagesize($tracking_label_image); $this->response->trackingLabels[] = (object) array ( 'file' => $tracking_label_image, 'file_v' => preg_replace('/\.gif$/', '_v.gif', $tracking_label_image), 'size' => (object) array ( 'width' => $label_info[0], 'height' => $label_info[1] ) ); } */ } $this->orders->changeOrderData($this->_related_order_id, array ( 'tracking_number' => $this->response->trackingNumber, 'courier_service' => 'UPS', 'courier_pickup_date' => $this->_pickup_date, 'courier_arrival_date' => $this->_arrival_date, )); $this->orders->changeDispatchmentStep($this->_related_order_id, DISPATCHMENT_PACKED); } else { $this->responseIsError(); } $this->response->actual = $response; $this->response->actualXML = $this->getResponse(); $this->response->sent = $this->getXMLRequestBody(); $this->response->sentXML = $this->getRequestBody(); return $this->response; } public function track($tracking_number = '', $latest = true) { $request = array ( 'Request' => array ( 'RequestAction' => 'Track', 'RequestOption' => ($latest) ? '0' : '1', 'TransactionReference' => array ( 'CustomerContext' => '' ) ), 'TrackingNumber' => $tracking_number ); $request_data = $this->_wrapBaseXML('TrackRequest', $this->_arrayToXML($request)); $this->sendRequest('/Track', $request_data); $response = $this->getXMLResponse(); print_r($this->getXMLResponse()); } private function extractEstimatedTimes($data = array()) { if(isset($data['actual_pickup_date'], $data['estimated_arrival_date'])) { $actual_pickup_date = (($actual_pickup_date = (int) $data['actual_pickup_date']) > 1) ? $actual_pickup_date : NULL; $estimated_arrival_date = (($estimated_arrival_date = (int) $data['estimated_arrival_date']) > 1) ? $estimated_arrival_date : NULL; if($actual_pickup_date && $estimated_arrival_date) { $this->_pickup_date = $actual_pickup_date; $this->_arrival_date = $estimated_arrival_date; return true; } } return false; } private function generateShipment($data = array()) { $data['shipper'] = (isset($data['shipper'])) ? $data['shipper'] : (($this->shipper) ? $this->shipper : $this->origin); $data['ship_to'] = (isset($data['ship_to'])) ? $data['ship_to'] : $this->destination; $data['packages'] = (isset($data['packages'])) ? $data['packages'] : array(); $data['currency'] = 'GBP'; $shipment = array ( 'Shipper' => array ( 'Name' => (isset($data['shipper']['name']) && strlen($data['shipper']['name'])) ? $data['shipper']['name'] : ((isset($data['shipper']['company'])) ? $data['shipper']['company'] : ''), 'AttentionName' => (isset($data['shipper']['full_name'])) ? $data['shipper']['full_name'] : '', 'PhoneNumber' => (isset($data['shipper']['phone'])) ? $data['shipper']['phone'] : '', 'EMailAddress' => (isset($data['shipper']['email'])) ? $data['shipper']['email'] : '', 'FaxNumber' => (isset($data['shipper']['fax'])) ? $data['shipper']['fax'] : '', 'ShipperNumber' => $this->_shipper_number, 'Address' => $this->buildAddress($data['shipper']['address']) ), 'ShipTo' => array ( 'CompanyName' => (isset($data['ship_to']['company']) && strlen($data['ship_to']['company'])) ? $data['ship_to']['company'] : ((isset($data['ship_to']['name'])) ? $data['ship_to']['name'] : ''), 'AttentionName' => (isset($data['ship_to']['full_name']) && strlen($data['ship_to']['full_name'])) ? $data['ship_to']['full_name'] : ((isset($data['ship_to']['name'])) ? $data['ship_to']['name'] : ''), 'PhoneNumber' => (isset($data['ship_to']['phone'])) ? $data['ship_to']['phone'] : '', 'EMailAddress' => (isset($data['ship_to']['email'])) ? $data['ship_to']['email'] : '', 'FaxNumber' => (isset($data['ship_to']['fax'])) ? $data['ship_to']['fax'] : '', 'Address' => $this->buildAddress($data['ship_to']['address']) ) ); if(isset($data['ship_from'])) { $shipment['ShipFrom'] = array ( 'AttentionName' => (isset($data['ship_from']['full_name'])) ? $data['ship_from']['full_name'] : '', 'CompanyName' => (isset($data['ship_from']['company'])) ? $data['ship_from']['company'] : '', 'PhoneNumber' => (isset($data['ship_from']['phone'])) ? $data['ship_from']['phone'] : '', 'Address' => $this->buildAddress($data['ship_from']['address']) ); } if(isset($data['service'])) { $shipment['Service'] = array ( 'Code' => $data['service'] ); } $shipment['#list'] = array(); foreach($data['items'] as $package_info) { $package = array ( 'Package' => array ( 'Description' => $package_info['name'], 'PackagingType' => array ( 'Code' => '02' ), 'PackageWeight' => array ( 'Weight' => $package_info['weight'], 'UnitOfMeasurement' => array ( 'Code' => 'KGS' ) ) ) ); if(isset($package_info['reference'])) { $package['Package']['ReferenceNumber']['Value'] = trim($package_info['reference']); } $shipment['#list'][] = $package; } $shipment['NumOfPieces'] = count($shipment['#list']); // Negotiated rates $shipment['RateInformation'] = array ( 'NegotiatedRatesIndicator' => true ); //print_r($shipment);exit; return $shipment; } private function buildAddress($data = array()) { $address = array ( 'AddressLine1' => (isset($data['address_1'])) ? $data['address_1'] : '', 'AddressLine2' => (isset($data['address_2'])) ? $data['address_2'] : '', 'AddressLine3' => (isset($data['address_3'])) ? $data['address_3'] : '', 'City' => (isset($data['town'])) ? $data['town'] : '', 'StateProvinceCode' => (isset($data['county'])) ? $data['county'] : '', 'PostalCode' => (isset($data['postcode'])) ? $data['postcode'] : '', 'CountryCode' => (isset($data['country_code'])) ? $data['country_code'] : '' ); if(isset($data['residential'])) { $address['ResidentialAddressIndicator'] = true; } return $address; } private function buildTransitAddress($data = array()) { $address = array ( 'PoliticalDivision2' => (isset($data['town'])) ? $data['town'] : '', 'PoliticalDivision1' => (isset($data['county'])) ? $data['county'] : '', 'PostcodePrimaryLow' => (isset($data['postcode'])) ? $data['postcode'] : '', 'CountryCode' => (isset($data['country_code'])) ? $data['country_code'] : '' ); return $address; } private function buildLabelSpecification() { // GIF label /* $label = array ( 'LabelPrintMethod' => array ( 'Code' => 'ZPL' ), 'HTTPUserAgent' => $this->agent->agent_string(), 'LabelImageFormat' => array ( 'Code' => 'GIF' ) ); */ // ZPL label $label = array ( 'LabelStockSize' => array ( 'Height' => 4, 'Width' => 6 ), 'LabelPrintMethod' => array ( 'Code' => 'ZPL', 'Description' => 'zpl file' ), 'HTTPUserAgent' => $this->agent->agent_string(), 'LabelImageFormat' => array ( 'Code' => 'GIF', 'Description' => 'gif' ) ); return $label; } private function buildPaymentInformation() { $payment = array ( 'Prepaid' => array ( 'BillShipper' => array ( 'AccountNumber' => $this->_shipper_number ) ) ); return $payment; } private function saveShippingZplLabel($tracking_number, $data_str = NULL, $file_name) { if(strlen(($tracking_number = trim($tracking_number))) && is_string($data_str) && ($decoded_zpl_contents = @base64_decode($data_str))) { $write_path = 'assets/uploads/print-commands'; if(is_really_writable($write_path)) { if(!$this->_related_order_id) { throw new Exception('Related Order ID must be set!'); } $write_path .= '/' . md5($this->_related_order_id); $full_file_path = $write_path . '/' . $file_name . '.txt'; if(!file_exists($write_path)) { if(!mkdir($write_path, 0755, true)) { throw new Exception('Failed to create directory'); } } $this->db->query($this->db->insert_string('shipment_tracking', array ( 'order_id' => $this->_related_order_id, 'courier_service' => 'UPS', 'tracking_number' => $tracking_number ))); if($this->db->affected_rows() === 1) { $attempts = 0; $max_attempts = 5; do { if($attempts === $max_attempts) { return false; } if(($save_file = file_put_contents($full_file_path, $decoded_zpl_contents))) { return $full_file_path; } $attempts++; } while($save_file === false); } } } return false; } private function saveShippingLabel($tracking_number, $data_str = NULL, $file_name) { if(strlen(($tracking_number = trim($tracking_number))) && is_string($data_str) && ($decoded_image = @base64_decode($data_str))) { $write_path = 'assets/uploads/labels'; if(is_really_writable($write_path)) { if(!$this->_related_order_id) { throw new Exception('Related Order ID must be set!'); } $write_path .= '/' . md5($this->_related_order_id); $full_image_path = $write_path . '/' . $file_name . '.gif'; if(!file_exists($write_path)) { if(!mkdir($write_path, 0755, true)) { throw new Exception('Failed to create directory'); } } $this->db->query($this->db->insert_string('shipment_tracking', array ( 'order_id' => $this->_related_order_id, 'courier_service' => 'UPS', 'tracking_number' => $tracking_number ))); if($this->db->affected_rows() === 1) { $attempts = 0; $max_attempts = 5; do { if($attempts === $max_attempts) { return false; } if(file_put_contents($full_image_path, $decoded_image)) { // Rotate the shipping label to make a vertical version $this->load->library('image_lib'); $this->image_lib->initialize(array ( 'source_image' => $full_image_path, 'new_image' => preg_replace('/\.gif$/', '_v.gif', $full_image_path), 'rotation_angle' => 270 )); if(!($label_rotate = $this->image_lib->rotate())) { throw new Exception($this->image_lib->display_errors()); } $this->image_lib->clear(); return $full_image_path; } $attempts++; } while($label_rotate === false); } } } return false; } public function cancelShipment($order_id = 0) { if(!(($order_id = (int) $order_id) > 0 && ($order_info = $this->orders->get($order_id)) && ($tracking_numbers = $this->orders->getOrderTrackingNumbers($order_id)))) { throw new Exception('Non-existent tracking number'); } $request = array ( 'Request' => array ( 'RequestAction' => '1', 'RequestOption' => '1', 'TransactionReference' => array ( 'CustomerContext' => '' ) ), 'ExpandedVoidShipment' => array() ); if(count($tracking_numbers) === 1) { $request['ExpandedVoidShipment']['ShipmentIdentificationNumber'] = $tracking_numbers[0]->tracking_number; } else { foreach($tracking_numbers as $i => $tracking_info) { $request['ExpandedVoidShipment']['#list'] = array ( 'TrackingNumber' => $tracking_info->tracking_number ); } } $request_data = $this->_wrapBaseXML('VoidShipmentRequest', $this->_arrayToXML($request)); $this->sendRequest('/Void', $request_data); $response = $this->getXMLResponseToJSON(); if($response->Response->ResponseStatusCode === '1') { $this->responseIsSuccess(); } else { $this->responseIsError(); } $this->response->actual = $response; $this->response->actualXML = $this->getResponse(); $this->response->sent = $this->getXMLRequestBody(); $this->response->sentXML = $this->getRequestBody(); preprint($this->response); return $this->response; } private function generateAccessXML() { return '<?xml version="1.0" encoding="UTF-8"?> <AccessRequest xml:lang="en-GB"> <AccessLicenseNumber>' . $this->_access_key . '</AccessLicenseNumber> <UserId>' . $this->_username . '</UserId> <Password>' . $this->_password . '</Password> </AccessRequest>'; } private function sendRequest($end_point = NULL, $data = array()) { $this->_response = NULL; $this->_request_body = $data; $this->_buildResponse(); $data = $this->generateAccessXML() . ' ' . $data; $ch = curl_init($this->makeUrl($end_point)); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CAINFO, APPPATH . 'third_party/cacert.pem'); //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $this->_response = curl_exec($ch); curl_close($ch); return $this; } public function getResponse() { return $this->_response; } public function getXMLResponse() { return $this->_decodeXML($this->getResponse()); } public function getXMLResponseToJSON() { return json_decode(json_encode($this->_decodeXML($this->getResponse()))); } public function getRequestBody() { return $this->_request_body; } public function getXMLRequestBody() { return $this->_decodeXML($this->getRequestBody()); } private function makeUrl($end_point = NULL) { $url = ($this->_env == 'test') ? self::UPS_TEST_URL : self::UPS_PRODUCTION_URL; $url .= '/' . ltrim($end_point, '/'); return $url; } private function _buildResponse() { $this->response = (object) array ( 'success' => false, 'errors' => array(), 'error' => NULL, 'warnings' => array() ); return $this; } private function responseIsError() { $response = $this->getXMLResponse(); $error = $response->Response->Error; $this->response->errors[] = 'Error: ' . ((string) $error->ErrorCode) . ' - ' . ((string) $error->ErrorDescription); $this->response->error = (object) array ( 'severity' => (string) $error->ErrorSeverity, 'code' => (string) $error->ErrorCode, 'description' => (string) $error->ErrorDescription ); } private function responseIsSuccess() { $this->response->success = true; } private function _wrapBaseXML($base_tag, $xml = '', $attributes = '') { $xml = preg_replace(array('/<\/?#list>/sm', '/<\/?[0-9]+>/sm'), '', $xml); return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <' . $base_tag . ' xml:lang="en-GB">' . $xml . '</' . $base_tag . '>'; } private function _arrayToXML($array, $xml = '') { foreach($array as $index => $value) { if(is_array($value)) { $xml .= $this->_tag($index, $this->_arrayToXML($value)); } else { $xml .= $this->_tag($index, ($value === true) ? $value : htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8', false)); } } return $xml; } private function _tag($index, $value) { $return = '<' . $this->_key($index) . '>' . ((string) $value) . '</' . $this->_key($index) . '>'; if($value === true) { $return = '<' . $this->_key($index) . ' />'; } return $return; } private function _key($str) { $reserved_words = array ( 'street' => 'AddressLine1', 'street_2' => 'AddressLine2', 'street_3' => 'AddressLine3', 'address_1' => 'AddressLine1', 'address_2' => 'AddressLine2', 'address_3' => 'AddressLine3', 'city' => 'City', 'town' => 'City', 'state' => 'StateProvinceCode', 'county' => 'StateProvinceCode', 'zip' => 'PostalCode', 'zipcode' => 'PostalCode', 'postal' => 'PostalCode', 'postcode' => 'PostalCode', 'country_code' => 'CountryCode', 'name' => 'Name', 'full_name' => 'AttentionName', 'attn' => 'AttentionName', 'attention' => 'AttentionName', 'company' => 'CompanyName', 'phone' => 'PhoneNumber', 'fax' => 'FaxNumber', ); if(isset($reserved_words[$str])) { $str = $reserved_words[$str]; } return str_replace(array('<', '>', '/>', ' '), '', ucwords(str_replace('_', ' ', $str))); } private function _decodeXML($xml = '') { if(is_string($xml)) { try { return new SimpleXMLElement((string) strstr($xml, '<?')); } catch (Exception $ex) { return $ex; } } return NULL; } }
Cancel