Add package tracking API
parent
f8e6983d23
commit
31a6243408
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
$trackinginfo;
|
||||
|
||||
try {
|
||||
if (!empty($VARS["carrier"])) {
|
||||
$trackinginfo = Tracking::track($VARS["code"], $VARS["carrier"]);
|
||||
} else {
|
||||
$trackinginfo = Tracking::track($VARS["code"]);
|
||||
}
|
||||
} catch (TrackingException $ex) {
|
||||
sendJsonResp($ex->getMessage(), "ERROR");
|
||||
}
|
||||
|
||||
if (is_null($trackinginfo)) {
|
||||
sendJsonResp("Could not find any results for that tracking code.", "ERROR");
|
||||
}
|
||||
exitWithJson($trackinginfo->toObject());
|
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
class Carriers {
|
||||
|
||||
const CARRIER_REGEXES = [
|
||||
[
|
||||
"carrier" => "ups_mi_datamatrix",
|
||||
"pattern" => "/^([^\\t]*\\t[^\\t]*){13}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "fedex_pdf417",
|
||||
"pattern" => "/.*\\x1D.*\\x1D.*\\x1D.*/" // look for the GS (group seperator) multiple times
|
||||
],
|
||||
[
|
||||
"carrier" => "helena_express",
|
||||
"pattern" => "/^[HLN|HEX][0-9]+$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "helena_express",
|
||||
"pattern" => "/^406[0-9]{6}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "usps",
|
||||
"pattern" => "/^[0-9]{20,40}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "usps",
|
||||
"pattern" => "/^82[0-9]{8}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "usps",
|
||||
"pattern" => "/^E\D{1}\d{9}\D{2}$|^9\d{15,21}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "usps",
|
||||
"pattern" => "/^91[0-9]+$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "usps",
|
||||
"pattern" => "/^[A-Z]{2}[0-9]{9}[A-Z]{2}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "usps",
|
||||
"pattern" => "/^420[0-9]{5}[0-9]+$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "ups",
|
||||
"pattern" => "/\b(1Z ?[0-9A-Z]{3} ?[0-9A-Z]{3} ?[0-9A-Z]{2} ?[0-9A-Z]{4} ?[0-9A-Z]{3} ?[0-9A-Z]|[\dT]\d\d\d ?\d\d\d\d ?\d\d\d)\b/"
|
||||
],
|
||||
[
|
||||
"carrier" => "ups",
|
||||
"pattern" => "/^[KJ]{1}[0-9]{10}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "fedex",
|
||||
"pattern" => "/(\b96\d{20}\b)|(\b\d{15}\b)|(\b\d{12}\b)/"
|
||||
],
|
||||
[
|
||||
"carrier" => "fedex",
|
||||
"pattern" => "/\b((98\d\d\d\d\d?\d\d\d\d|98\d\d) ?\d\d\d\d ?\d\d\d\d( ?\d\d\d)?)\b/"
|
||||
],
|
||||
[
|
||||
"carrier" => "fedex",
|
||||
"pattern" => "/^[0-9]{15}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_express",
|
||||
"pattern" => "/^[0-9]{10}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_express",
|
||||
"pattern" => "/^J?JD[0-9]{13,18}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_ecommerce",
|
||||
"pattern" => "/^[LR][A-Z][0-9]{9}DE$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_ecommerce",
|
||||
"pattern" => "/^CNAOG[0-9]{10}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_ecommerce",
|
||||
"pattern" => "/^SGKEN[0-9]{10}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_ecommerce",
|
||||
"pattern" => "/^SGAGS[0-9]{6}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_ecommerce",
|
||||
"pattern" => "/^[0-9]{16}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_ecommerce",
|
||||
"pattern" => "/^[0-9]{22}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_ecommerce",
|
||||
"pattern" => "/^GM[0-9]{16,18}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "dhl_ecommerce",
|
||||
"pattern" => "/^A[A-Z0-9]000[0-9]{15}$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "lasership",
|
||||
"pattern" => "/^LX[0-9]+$/"
|
||||
],
|
||||
[
|
||||
"carrier" => "lasership",
|
||||
"pattern" => "/^1LS[0-9]+$/"
|
||||
],
|
||||
];
|
||||
|
||||
const CARRIERS = [
|
||||
"usps" => [
|
||||
"code" => "usps",
|
||||
"name" => "USPS"
|
||||
],
|
||||
"ups" => [
|
||||
"code" => "ups",
|
||||
"name" => "UPS"
|
||||
],
|
||||
"ups_mi_datamatrix" => [
|
||||
"code" => "usps",
|
||||
"name" => "USPS"
|
||||
],
|
||||
"fedex" => [
|
||||
"code" => "fedex",
|
||||
"name" => "FedEx"
|
||||
],
|
||||
"fedex_pdf417" => [
|
||||
"code" => "fedex",
|
||||
"name" => "FedEx"
|
||||
],
|
||||
"dhl_express" => [
|
||||
"code" => "dhl_express",
|
||||
"name" => "DHL Express"
|
||||
],
|
||||
"dhl_ecommerce" => [
|
||||
"code" => "dhl_ecommerce",
|
||||
"name" => "DHL eCommerce"
|
||||
],
|
||||
"lasership" => [
|
||||
"code" => "lasership",
|
||||
"name" => "LaserShip"
|
||||
],
|
||||
"helena_express" => [
|
||||
"code" => "helena_express",
|
||||
"name" => "Helena Express"
|
||||
]
|
||||
];
|
||||
|
||||
public static function getCarrierName(string $carrier): string {
|
||||
// scan by internal ID
|
||||
foreach (Carriers::CARRIERS as $id => $info) {
|
||||
if ($id == $carrier) {
|
||||
return $info["name"];
|
||||
}
|
||||
}
|
||||
// scan by code
|
||||
foreach (Carriers::CARRIERS as $id => $info) {
|
||||
if (strtolower($info["code"]) == strtolower($carrier)) {
|
||||
return $info["name"];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static function getCarrierCode(string $carrier): string {
|
||||
// scan by internal ID
|
||||
foreach (Carriers::CARRIERS as $id => $info) {
|
||||
if ($id == $carrier) {
|
||||
return $info["code"];
|
||||
}
|
||||
}
|
||||
// scan by name
|
||||
foreach (Carriers::CARRIERS as $id => $info) {
|
||||
if (strtolower($info["name"]) == strtolower($carrier)) {
|
||||
return $info["code"];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
class Location {
|
||||
|
||||
public $number = "";
|
||||
public $streetname = "";
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string Number and street name.
|
||||
*/
|
||||
public $street = "";
|
||||
public $unit = "";
|
||||
public $city = "";
|
||||
public $state = "";
|
||||
public $zip = "";
|
||||
public $country = "";
|
||||
public $latitude = false;
|
||||
public $longitude = false;
|
||||
|
||||
public function hasAddress(): bool {
|
||||
return ($number . $streetname . $street . $city . $state . $zip . $country != "");
|
||||
}
|
||||
|
||||
public function hasCoordinates(): bool {
|
||||
return ($latitude !== false && $longitude !== false);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class Service {
|
||||
public $id = "";
|
||||
public $name = "";
|
||||
|
||||
public function __construct($id, $name) {
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class Tracking {
|
||||
|
||||
/**
|
||||
*
|
||||
* @global type $SETTINGS
|
||||
* @param string $code
|
||||
* @return \TrackingInfo
|
||||
* @throws TrackingException
|
||||
*/
|
||||
public static function track(string $code, string $carrier = ""): TrackingInfo {
|
||||
|
||||
$barcode = new TrackingBarcode($code);
|
||||
if (!empty($carrier)) {
|
||||
$carriercode = Carriers::getCarrierCode($carrier);
|
||||
} else {
|
||||
$carriercode = $barcode->getCarrier();
|
||||
}
|
||||
|
||||
switch ($carriercode) {
|
||||
case "ups_mi_datamatrix":
|
||||
return Tracking_UPS_MailInnovations_DataMatrix::track($code);
|
||||
case "fedex_pdf417":
|
||||
return Tracking_FedEx_PDF417::track($code);
|
||||
case "helena_express":
|
||||
return Tracking_HelenaExpress::track($barcode->getSanitized());
|
||||
case "usps":
|
||||
return Tracking_USPS::track($barcode->getSanitized());
|
||||
case "ups":
|
||||
return Tracking_UPS::track($barcode->getSanitized());
|
||||
default:
|
||||
return Tracking_Shippo::track($barcode->getSanitized());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
class TrackingBarcode {
|
||||
|
||||
private $code = "";
|
||||
|
||||
public function __construct(string $code) {
|
||||
$this->code = $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim and clean up the code so it's all caps and only A-Z and 0-9.
|
||||
* Does not change the actual barcode represented by this object.
|
||||
* @param string $code
|
||||
* @return string the sanitized code
|
||||
*/
|
||||
public function getSanitized(): string {
|
||||
$code = strtoupper($this->code);
|
||||
$code = trim($code);
|
||||
$code = preg_replace("/[^0-9A-Z]/", "", $code);
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess the carrier for the tracking code.
|
||||
* @return string An ID string representing the carrier. Some codes that
|
||||
* require extra processing before use will return a non-standard ID, use
|
||||
* Carriers::getCarrierName()/getCarrierCode() to resolve a standard ID code.
|
||||
*/
|
||||
public function getCarrier(): string {
|
||||
$carrier = "";
|
||||
foreach (Carriers::CARRIER_REGEXES as $p) {
|
||||
if (preg_match($p["pattern"], strtoupper($this->code))) {
|
||||
$carrier = $p["carrier"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($carrier == "") {
|
||||
// check again but strip out anything extra this time
|
||||
// makes it work with codes containing nonprintable stuff like the GS (group separator, %1D) char
|
||||
foreach (Carriers::CARRIER_REGEXES as $p) {
|
||||
if (preg_match($p["pattern"], $this->getSanitized())) {
|
||||
$carrier = $p["carrier"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($carrier == "") {
|
||||
throw new TrackingException("Unrecognized tracking code.");
|
||||
}
|
||||
}
|
||||
return $carrier;
|
||||
}
|
||||
|
||||
public function getCode(): string {
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
class TrackingEntry {
|
||||
|
||||
private $status = TrackingStatus::TRACKING_STATUS_UNKNOWN;
|
||||
private $details = "";
|
||||
private $datetime = "";
|
||||
private $location = null;
|
||||
private $iscontainerscan = false;
|
||||
|
||||
public function __construct(int $status, string $details, string $datetime, $location = null, bool $iscontainerscan = false) {
|
||||
$this->status = $status;
|
||||
$this->details = $details;
|
||||
$this->datetime = date("Y-m-d\TH:i:s", strtotime($datetime));
|
||||
$this->location = $location;
|
||||
$this->iscontainerscan = $iscontainerscan;
|
||||
}
|
||||
|
||||
public function toString(): string {
|
||||
return $this->details;
|
||||
}
|
||||
|
||||
public function getTimestamp(): int {
|
||||
return strtotime($this->datetime);
|
||||
}
|
||||
|
||||
public function getDateTime(string $format = "Y-m-d\TH:i:s"): string {
|
||||
return date($format, strtotime($this->datetime));
|
||||
}
|
||||
|
||||
public function getLocation() {
|
||||
return $this->location;
|
||||
}
|
||||
|
||||
public function setLocation(Location $location) {
|
||||
$this->location = $location;
|
||||
}
|
||||
|
||||
public function getStatus() {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function isContainerScan() {
|
||||
return $this->iscontainerscan;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class TrackingException extends Exception {
|
||||
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
class TrackingInfo {
|
||||
|
||||
private $code = null;
|
||||
private $carrier = null;
|
||||
private $service = null;
|
||||
private $history = [];
|
||||
private $from = null;
|
||||
private $to = null;
|
||||
private $current_status = null;
|
||||
|
||||
public function __construct($code = null, $carrier = null, $to = null, $from = null, $current_status = null, $history = null) {
|
||||
$this->code = $code;
|
||||
$this->carrier = $carrier;
|
||||
$this->to = $to;
|
||||
$this->from = $from;
|
||||
$this->current_status = $current_status;
|
||||
$this->history = $history;
|
||||
}
|
||||
|
||||
public function setCode(string $code) {
|
||||
$this->code = $code;
|
||||
}
|
||||
|
||||
public function getCode(): string {
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function setCarrier(string $carrierid) {
|
||||
$this->carrier = $carrierid;
|
||||
}
|
||||
|
||||
public function getCarrier() {
|
||||
return $this->carrier;
|
||||
}
|
||||
|
||||
public function setService(Service $service) {
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
public function getService() {
|
||||
return $this->service;
|
||||
}
|
||||
|
||||
public function setTo(Location $to) {
|
||||
$this->to = $to;
|
||||
}
|
||||
|
||||
public function getTo() {
|
||||
return $this->to;
|
||||
}
|
||||
|
||||
public function setFrom(Location $from) {
|
||||
$this->from = $from;
|
||||
}
|
||||
|
||||
public function getFrom() {
|
||||
return $this->from;
|
||||
}
|
||||
|
||||
public function setCurrentStatus(TrackingEntry $status) {
|
||||
$this->current_status = $status;
|
||||
}
|
||||
|
||||
public function getCurrentStatus() {
|
||||
return $this->current_status;
|
||||
}
|
||||
|
||||
public function getHistory() {
|
||||
return $this->history;
|
||||
}
|
||||
|
||||
public function appendHistoryEntry(TrackingEntry $history) {
|
||||
$this->history[] = $history;
|
||||
}
|
||||
|
||||
public function toObject() {
|
||||
$output = [
|
||||
"status" => "OK",
|
||||
"code" => $this->getCode(),
|
||||
"carrier" => [
|
||||
"code" => Carriers::getCarrierCode($this->getCarrier()),
|
||||
"name" => Carriers::getCarrierName($this->getCarrier())
|
||||
],
|
||||
"service" => [
|
||||
"id" => $this->service->id,
|
||||
"name" => $this->service->name
|
||||
],
|
||||
"addresses" => [
|
||||
"from" => [
|
||||
"street" => "",
|
||||
"city" => "Unknown",
|
||||
"state" => "",
|
||||
"zip" => "",
|
||||
"country" => ""
|
||||
],
|
||||
"to" => [
|
||||
"street" => "",
|
||||
"city" => "Unknown",
|
||||
"state" => "",
|
||||
"zip" => "",
|
||||
"country" => ""
|
||||
]
|
||||
],
|
||||
"current" => [
|
||||
"status" => "UNKNOWN",
|
||||
"details" => "No tracking information found.",
|
||||
"date" => time(),
|
||||
"location" => [
|
||||
"street" => "",
|
||||
"city" => "",
|
||||
"state" => "",
|
||||
"zip" => "",
|
||||
"country" => ""
|
||||
]
|
||||
],
|
||||
"history" => [
|
||||
]
|
||||
];
|
||||
|
||||
if (!is_null($this->getCurrentStatus())) {
|
||||
$output["current"] = [
|
||||
"status" => TrackingStatus::statusToString($this->getCurrentStatus()->getStatus()),
|
||||
"details" => $this->getCurrentStatus()->toString(),
|
||||
"datetime" => $this->getCurrentStatus()->getDateTime(),
|
||||
"timestamp" => $this->getCurrentStatus()->getTimestamp(),
|
||||
"containerscan" => $this->getCurrentStatus()->isContainerScan(),
|
||||
"location" => [
|
||||
"street" => "",
|
||||
"city" => "Unknown",
|
||||
"state" => "",
|
||||
"zip" => "",
|
||||
"country" => ""
|
||||
]
|
||||
];
|
||||
|
||||
if (!empty($this->getCurrentStatus()->getLocation())) {
|
||||
$output["current"]["location"] = [
|
||||
"street" => $this->getCurrentStatus()->getLocation()->street,
|
||||
"city" => $this->getCurrentStatus()->getLocation()->city,
|
||||
"state" => $this->getCurrentStatus()->getLocation()->state,
|
||||
"zip" => $this->getCurrentStatus()->getLocation()->zip,
|
||||
"country" => $this->getCurrentStatus()->getLocation()->country
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_null($this->getFrom())) {
|
||||
$output["addresses"]["from"] = [
|
||||
"street" => $this->getFrom()->street,
|
||||
"city" => $this->getFrom()->city,
|
||||
"state" => $this->getFrom()->state,
|
||||
"zip" => $this->getFrom()->zip,
|
||||
"country" => $this->getFrom()->country
|
||||
];
|
||||
}
|
||||
|
||||
if (!is_null($this->getTo())) {
|
||||
$output["addresses"]["to"] = [
|
||||
"street" => $this->getTo()->street,
|
||||
"city" => $this->getTo()->city,
|
||||
"state" => $this->getTo()->state,
|
||||
"zip" => $this->getTo()->zip,
|
||||
"country" => $this->getTo()->country
|
||||
];
|
||||
}
|
||||
|
||||
if (!is_null($this->getHistory())) {
|
||||
foreach ($this->getHistory() as $history) {
|
||||
$output["history"][] = [
|
||||
"status" => TrackingStatus::statusToString($history->getStatus()),
|
||||
"details" => $history->toString(),
|
||||
"datetime" => $history->getDateTime(),
|
||||
"timestamp" => $history->getTimestamp(),
|
||||
"containerscan" => $history->isContainerScan(),
|
||||
"location" => [
|
||||
"street" => $history->getLocation()->street,
|
||||
"city" => $history->getLocation()->city,
|
||||
"state" => $history->getLocation()->state,
|
||||
"zip" => $history->getLocation()->zip,
|
||||
"country" => $history->getLocation()->country
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
class TrackingStatus {
|
||||
|
||||
public const TRACKING_STATUS_UNKNOWN = 0;
|
||||
public const TRACKING_STATUS_PRE_TRANSIT = 1;
|
||||
public const TRACKING_STATUS_TRANSIT = 2;
|
||||
public const TRACKING_STATUS_DELIVERED = 3;
|
||||
public const TRACKING_STATUS_RETURNED = 4;
|
||||
public const TRACKING_STATUS_FAILURE = 5;
|
||||
|
||||
/**
|
||||
* Convert a status string API response to a constant integer.
|
||||
* @param string $status
|
||||
* @return int
|
||||
*/
|
||||
public static function stringToStatus(string $status): int {
|
||||
$status = strtoupper($status);
|
||||
switch ($status) {
|
||||
case "PRE_TRANSIT":
|
||||
return TrackingStatus::TRACKING_STATUS_PRE_TRANSIT;
|
||||
case "TRANSIT":
|
||||
case "IN_TRANSIT":
|
||||
case "ACCEPTED":
|
||||
return TrackingStatus::TRACKING_STATUS_TRANSIT;
|
||||
case "DELIVERED":
|
||||
return TrackingStatus::TRACKING_STATUS_DELIVERED;
|
||||
case "RETURNED":
|
||||
return TrackingStatus::TRACKING_STATUS_RETURNED;
|
||||
case "FAILURE":
|
||||
case "DELIVERY ATTEMPT":
|
||||
case "ALERT":
|
||||
return TrackingStatus::TRACKING_STATUS_FAILURE;
|
||||
default:
|
||||
return TrackingStatus::TRACKING_STATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a status constant to a string.
|
||||
* @param int $status
|
||||
* @return string
|
||||
*/
|
||||
public static function statusToString(int $status): string {
|
||||
switch ($status) {
|
||||
case TrackingStatus::TRACKING_STATUS_PRE_TRANSIT:
|
||||
return "PRE_TRANSIT";
|
||||
case TrackingStatus::TRACKING_STATUS_TRANSIT:
|
||||
return "TRANSIT";
|
||||
case TrackingStatus::TRACKING_STATUS_DELIVERED:
|
||||
return "DELIVERED";
|
||||
case TrackingStatus::TRACKING_STATUS_RETURNED:
|
||||
return "RETURNED";
|
||||
case TrackingStatus::TRACKING_STATUS_FAILURE:
|
||||
return "FAILURE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false if a two-char USPS API scan event is probably a physical scan of the actual item
|
||||
* @param string $eventcode
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isUSPSEventCodeContainerScan(string $eventcode) {
|
||||
switch ($eventcode) {
|
||||
case "A1":
|
||||
case "AE":
|
||||
case "DE":
|
||||
case "E1":
|
||||
case "L1":
|
||||
case "MA":
|
||||
case "MR":
|
||||
case "NT":
|
||||
case "OA":
|
||||
case "OD":
|
||||
case "OF":
|
||||
case "OX":
|
||||
case "PC":
|
||||
case "RB":
|
||||
case "SF":
|
||||
case "T1":
|
||||
case "TM":
|
||||
case "TX":
|
||||
case "U1":
|
||||
case "UA":
|
||||
case "VF":
|
||||
case "VR":
|
||||
case "WX":
|
||||
case "GX":
|
||||
case "80":
|
||||
case "89":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function USPSEventCodeToStatus(string $eventcode) {
|
||||
switch ($eventcode) {
|
||||
case "GC":
|
||||
case "GX":
|
||||
case "MA":
|
||||
case "89":
|
||||
return TrackingStatus::TRACKING_STATUS_PRE_TRANSIT;
|
||||
case "03":
|
||||
case "06":
|
||||
case "07":
|
||||
case "08":
|
||||
case "10":
|
||||
case "12":
|
||||
case "PA":
|
||||
case "14":
|
||||
case "15":
|
||||
case "16":
|
||||
case "17":
|
||||
case "19":
|
||||
case "30": // no access
|
||||
case "34":
|
||||
case "35":
|
||||
case "36":
|
||||
case "38":
|
||||
case "39":
|
||||
case "40":
|
||||
case "42":
|
||||
case "45":
|
||||
case "52":
|
||||
case "58":
|
||||
case "59":
|
||||
case "70":
|
||||
case "71":
|
||||
case "72":
|
||||
case "73":
|
||||
case "74":
|
||||
case "80":
|
||||
case "81":
|
||||
case "82":
|
||||
case "83":
|
||||
case "A1":
|
||||
case "AD":
|
||||
case "AE":
|
||||
case "AR":
|
||||
case "AX":
|
||||
case "B1":
|
||||
case "B5":
|
||||
case "BB":
|
||||
case "DD":
|
||||
case "DE":
|
||||
case "DX":
|
||||
case "E1":
|
||||
case "EF":
|
||||
case "L1":
|
||||
case "MR":
|
||||
case "NT": // generic filler messages to fill tracking gaps
|
||||
case "NP":
|
||||
case "C0":
|
||||
case "U1":
|
||||
case "OA":
|
||||
case "OD":
|
||||
case "OF":
|
||||
case "PC":
|
||||
case "RB":
|
||||
case "RC":
|
||||
case "SF":
|
||||
case "T1":
|
||||
case "TM":
|
||||
case "UA":
|
||||
case "VF":
|
||||
case "VR":
|
||||
case "WX":
|
||||
return TrackingStatus::TRACKING_STATUS_TRANSIT;
|
||||
case "01":
|
||||
case "13":
|
||||
case "17":
|
||||
case "41":
|
||||
case "43":
|
||||
case "60":
|
||||
case "61":
|
||||
case "62":
|
||||
case "63":
|
||||
case "84":
|
||||
case "85":
|
||||
case "86":
|
||||
case "87":
|
||||
case "LD": // letter estimated to be delivered today
|
||||
return TrackingStatus::TRACKING_STATUS_DELIVERED;
|
||||
case "04":
|
||||
case "05":
|
||||
case "09":
|
||||
case "21":
|
||||
case "22":
|
||||
case "23":
|
||||
case "24":
|
||||
case "25":
|
||||
case "26":
|
||||
case "27":
|
||||
case "28":
|
||||
case "29":
|
||||
return TrackingStatus::TRACKING_STATUS_RETURNED;
|
||||
case "02":
|
||||
case "53":
|
||||
case "54":
|
||||
case "55":
|
||||
case "56":
|
||||
case "57":
|
||||
case "64":
|
||||
case "04":
|
||||
case "05":
|
||||
case "11":
|
||||
case "16":
|
||||
case "31":
|
||||
case "32":
|
||||
case "33":
|
||||
case "44":
|
||||
case "51":
|
||||
case "LX": // LOOP bin
|
||||
case "OX":
|
||||
case "TX":
|
||||
return TrackingStatus::TRACKING_STATUS_FAILURE;
|
||||
default:
|
||||
return TrackingStatus::TRACKING_STATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static function UPSEventTypeToStatus(string $eventcode) {
|
||||
switch ($eventcode) {
|
||||
case "M":
|
||||
case "MV":
|
||||
return TrackingStatus::TRACKING_STATUS_PRE_TRANSIT;
|
||||
case "I":
|
||||
case "P":
|
||||
case "O":
|
||||
case "W":
|
||||
case "DO":
|
||||
case "DD":
|
||||
return TrackingStatus::TRACKING_STATUS_TRANSIT;
|
||||
case "D":
|
||||
return TrackingStatus::TRACKING_STATUS_DELIVERED;
|
||||
case "RS":
|
||||
return TrackingStatus::TRACKING_STATUS_RETURNED;
|
||||
case "X":
|
||||
return TrackingStatus::TRACKING_STATUS_FAILURE;
|
||||
case "NA":
|
||||
default:
|
||||
return TrackingStatus::TRACKING_STATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
class Tracking_FedEx_PDF417 {
|
||||
|
||||
/**
|
||||
*
|
||||
* @global type $SETTINGS
|
||||
* @param string $code
|
||||
* @return \TrackingInfo
|
||||
* @throws TrackingException
|
||||
*/
|
||||
public static function track(string $code): TrackingInfo {
|
||||
$codeparts = preg_split("/(\\x1D|\\x1E)/", $code);
|
||||
|
||||
$realcode = $codeparts[5];
|
||||
|
||||
$info = Tracking::track($realcode, "fedex");
|
||||
|
||||
// Set detailed destination address from code data
|
||||
$to = $info->getTo();
|
||||
if (is_null($to)) {
|
||||
$to = new Location();
|
||||
}
|
||||
$to->street = $codeparts[13];
|
||||
$to->city = $codeparts[14];
|
||||
$to->state = $codeparts[15];
|
||||
$to->country = (new League\ISO3166\ISO3166)->numeric($codeparts[3])['alpha2'];
|
||||
$info->setTo($to);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
class Tracking_HelenaExpress {
|
||||
|
||||
/**
|
||||
*
|
||||
* @global type $SETTINGS
|
||||
* @param string $code
|
||||
* @return \TrackingInfo
|
||||
* @throws TrackingException
|
||||
*/
|
||||
public static function track(string $code): TrackingInfo {
|
||||
global $SETTINGS;
|
||||
|
||||
$barcode = new TrackingBarcode($code);
|
||||
|
||||
|
||||
try {
|
||||
$status = json_decode(file_get_contents("https://helena.express/tracker/api.php?code=" . $barcode->getCode()));
|
||||
} catch (Exception $ex) {
|
||||
throw new TrackingException("There was a server problem. This code cannot be tracked right now.");
|
||||
}
|
||||
|
||||
if (empty($status->events) && empty($status->info->carrier)) {
|
||||
throw new TrackingException("Unknown tracking code (best guess: " . Carriers::getCarrierName($barcode->getCarrier()) . ").");
|
||||
}
|
||||
|
||||
$info = new TrackingInfo();
|
||||
|
||||
$info->setCode($barcode->getCode());
|
||||
$info->setCarrier($status->info->carrier);
|
||||
|
||||
if (!empty($status->events)) {
|
||||
$current_status = new TrackingEntry(
|
||||
TrackingStatus::stringToStatus($status->events[0]->eventtype),
|
||||
$status->events[0]->text,
|
||||
$status->events[0]->timestring
|
||||
);
|
||||
|
||||
$info->setCurrentStatus($current_status);
|
||||
}
|
||||
|
||||
|
||||
foreach ($status->events as $event) {
|
||||
$info->appendHistoryEntry(new TrackingEntry(TrackingStatus::stringToStatus($event->eventtype), $event->text, $event->timestring));
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
class Tracking_Shippo {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $code
|
||||
* @return \TrackingInfo
|
||||
* @throws TrackingException
|
||||
*/
|
||||
public static function track(string $code, string $carrier = ""): TrackingInfo {
|
||||
$barcode = new TrackingBarcode($code);
|
||||
|
||||
Shippo::setApiKey(env("shippo_key"));
|
||||
|
||||
try {
|
||||
$status = Shippo_Track::get_status([
|
||||
"id" => $code,
|
||||
"carrier" => empty($carrier) ? Carriers::getCarrierCode($barcode->getCarrier()) : $carrier
|
||||
]);
|
||||
} catch (Exception $ex) {
|
||||
throw new TrackingException("There was a server problem. This code cannot be tracked right now.");
|
||||
}
|
||||
|
||||
if (empty($status->tracking_status) && empty($status->address_to) && empty($status->address_from)) {
|
||||
throw new TrackingException("Unknown tracking code (best guess: " . Carriers::getCarrierName($barcode->getCarrier()) . ").");
|
||||
}
|
||||
|
||||
$info = new TrackingInfo();
|
||||
|
||||
$info->setCode($barcode->getCode());
|
||||
$info->setCarrier($barcode->getCarrier());
|
||||
$info->setService(new Service($status->servicelevel->token, $status->servicelevel->name));
|
||||
|
||||
if (!empty($status->tracking_status)) {
|
||||
$current_status = new TrackingEntry(
|
||||
TrackingStatus::stringToStatus($status->tracking_status->status),
|
||||
$status->tracking_status->status_details,
|
||||
$status->tracking_status->status_date
|
||||
);
|
||||
|
||||
if (!empty($status->tracking_status->location)) {
|
||||
$current_location = new Location();
|
||||
$current_location->city = $status->tracking_status->location->city;
|
||||
$current_location->state = $status->tracking_status->location->state;
|
||||
$current_location->zip = $status->tracking_status->location->zip;
|
||||
$current_location->country = $status->tracking_status->location->country;
|
||||
$current_status->setLocation($current_location);
|
||||
}
|
||||
|
||||
$info->setCurrentStatus($current_status);
|
||||
}
|
||||
|
||||
if (!empty($status->address_from)) {
|
||||
$from = new Location();
|
||||
$from->city = empty($status->address_from->city) ? "" : $status->address_from->city;
|
||||
$from->state = empty($status->address_from->state) ? "" : $status->address_from->state;
|
||||
$from->zip = empty($status->address_from->zip) ? "" : $status->address_from->zip;
|
||||
$from->country = empty($status->address_from->country) ? "" : $status->address_from->country;
|
||||
|
||||
$info->setFrom($from);
|
||||
}
|
||||
|
||||
if (!empty($status->address_to)) {
|
||||
$to = new Location();
|
||||
$to->city = empty($status->address_to->city) ? "" : $status->address_to->city;
|
||||
$to->state = empty($status->address_to->state) ? "" : $status->address_to->state;
|
||||
$to->zip = empty($status->address_to->zip) ? "" : $status->address_to->zip;
|
||||
$to->country = empty($status->address_to->country) ? "" : $status->address_to->country;
|
||||
|
||||
$info->setTo($to);
|
||||
}
|
||||
|
||||
foreach ($status->tracking_history as $history) {
|
||||
$location = new Location();
|
||||
$location->city = $history->location["city"];
|
||||
$location->state = $history->location["state"];
|
||||
$location->zip = $history->location["zip"];
|
||||
$location->country = $history->location["country"];
|
||||
$info->appendHistoryEntry(new TrackingEntry(TrackingStatus::stringToStatus($history->status), $history->status_details, $history->status_date, $location));
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
class Tracking_UPS {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $code
|
||||
* @return \TrackingInfo
|
||||
* @throws TrackingException
|
||||
*/
|
||||
public static function track(string $code, string $carrier = ""): TrackingInfo {
|
||||
$barcode = new TrackingBarcode($code);
|
||||
|
||||
try {
|
||||
$trackrequest = [
|
||||
"Security" => [
|
||||
"UsernameToken" => [
|
||||
"Username" => env("ups_user_account"),
|
||||
"Password" => env("ups_password")
|
||||
],
|
||||
"UPSServiceAccessToken" => [
|
||||
"AccessLicenseNumber" => env("ups_access_key")
|
||||
]
|
||||
],
|
||||
"TrackRequest" => [
|
||||
"Request" => [
|
||||
"RequestAction" => "Track",
|
||||
"RequestOption" => "activity"
|
||||
],
|
||||
"InquiryNumber" => $code
|
||||
]
|
||||
];
|
||||
$headers = [
|
||||
'Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept',
|
||||
'Access-Control-Allow-Methods: POST',
|
||||
'Access-Control-Allow-Origin: *',
|
||||
'Content-Type: application/json'
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
//curl_setopt($ch, CURLOPT_URL, "https://wwwcie.ups.com/rest/Track"); // TEST
|
||||
curl_setopt($ch, CURLOPT_URL, "https://onlinetools.ups.com/rest/Track"); // PROD
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($trackrequest));
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// CHECK TO SEE IF WE GOT AN ERROR
|
||||
// IF SO, FORMAT IT LIKE THIS ::28::Operation timed out afterseconds
|
||||
if ((curl_errno($ch)) && (curl_errno($ch) != 0)) {
|
||||
throw new TrackingException(curl_error($ch));
|
||||
}
|
||||
|
||||
$result = json_decode($response, true);
|
||||
|
||||
if (!empty($result["response"])) {
|
||||
// Should have trackResponse instead...
|
||||
if (!empty($result["response"]["errors"][0]["message"])) {
|
||||
throw new TrackingException($result["response"]["errors"][0]["message"]);
|
||||
}
|
||||
throw new TrackingException("The UPS tracking system is having problems. Try again later.");
|
||||
}
|
||||
if (!empty($result["Fault"])) {
|
||||
// Should have trackResponse instead...
|
||||
if (!empty($result["Fault"]["detail"]["Errors"]["ErrorDetail"]["PrimaryErrorCode"]["Description"])) {
|
||||
throw new TrackingException($result["Fault"]["detail"]["Errors"]["ErrorDetail"]["PrimaryErrorCode"]["Description"]);
|
||||
}
|
||||
throw new TrackingException("The UPS tracking system is having problems. Try again later.");
|
||||
}
|
||||
|
||||
if (!empty($result["TrackResponse"]["Shipment"]) && !empty($result["TrackResponse"]["Shipment"])) {
|
||||
$trackinfo = $result["TrackResponse"]["Shipment"];
|
||||
} else {
|
||||
throw new TrackingException("No tracking details found.");
|
||||
}
|
||||
//exitWithJson($trackinfo);
|
||||
} catch (TrackingException $ex) {
|
||||
throw $ex;
|
||||
} catch (Exception $ex) {
|
||||
throw new TrackingException("There was a server problem. This code cannot be tracked right now.");
|
||||
}
|
||||
|
||||
$info = new TrackingInfo();
|
||||
|
||||
$info->setCode($trackinfo["Package"]["TrackingNumber"]);
|
||||
|
||||
$info->setCarrier("ups");
|
||||
$info->setService(new Service($trackinfo["Service"]["Code"], $trackinfo["Service"]["Description"]));
|
||||
|
||||
if (count($trackinfo["Package"]["Activity"]) > 0) {
|
||||
$current = $trackinfo["Package"]["Activity"][0];
|
||||
$current_status = new TrackingEntry(
|
||||
TrackingStatus::UPSEventTypeToStatus($current["Status"]["Type"]),
|
||||
$current["Status"]["Description"] ?? "Unknown",
|
||||
DateTime::createFromFormat('Ymd His', "$current[Date] $current[Time]")->format("c")
|
||||
);
|
||||
|
||||
$current_location = new Location();
|
||||
$current_location->city = $current["ActivityLocation"]["Address"]["City"] ?? "";
|
||||
$current_location->state = $current["ActivityLocation"]["Address"]["StateProvinceCode"] ?? "";
|
||||
$current_location->zip = $current["ActivityLocation"]["Address"]["PostalCode"] ?? "";
|
||||
$current_location->country = $current["ActivityLocation"]["Address"]["CountryCode"] ?? "";
|
||||
$current_status->setLocation($current_location);
|
||||
|
||||
$info->setCurrentStatus($current_status);
|
||||
}
|
||||
|
||||
foreach ($trackinfo["ShipmentAddress"] as $address) {
|
||||
switch ($address["Type"]["Code"]) {
|
||||
case "02": // ShipTo Address
|
||||
$to = new Location();
|
||||
$to->city = $address["Address"]["City"] ?? "";
|
||||
$to->state = $address["Address"]["StateProvinceCode"] ?? "";
|
||||
$to->zip = $address["Address"]["PostalCode"] ?? "";
|
||||
$to->country = $address["Address"]["CountryCode"] ?? "";
|
||||
$info->setTo($to);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// $from = new Location();
|
||||
// $from->city = (string) $trackinfo->OriginCity ?? "";
|
||||
// $from->state = (string) $trackinfo->OriginState ?? "";
|
||||
// $from->zip = (string) $trackinfo->OriginZip ?? "";
|
||||
// $from->country = (string) $trackinfo->OriginCountryCode ?? "";
|
||||
//
|
||||
// $info->setFrom($from);
|
||||
|
||||
foreach ($trackinfo["Package"]["Activity"] as $history) {
|
||||
$location = new Location();
|
||||
$location->city = $history["ActivityLocation"]["Address"]["City"] ?? "";
|
||||
$location->state = $history["ActivityLocation"]["Address"]["StateProvinceCode"] ?? "";
|
||||
$location->zip = $history["ActivityLocation"]["Address"]["PostalCode"] ?? "";
|
||||
$location->country = $history["ActivityLocation"]["Address"]["CountryCode"] ?? "";
|
||||
$info->appendHistoryEntry(new TrackingEntry(
|
||||
TrackingStatus::UPSEventTypeToStatus($history["Status"]["Type"]),
|
||||
$history["Status"]["Description"] ?? "Unknown",
|
||||
DateTime::createFromFormat('Ymd His', "$history[Date] $history[Time]")->format("c"),
|
||||
$location
|
||||
));
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
class Tracking_UPS_MailInnovations_DataMatrix {
|
||||
|
||||
/**
|
||||
*
|
||||
* @global type $SETTINGS
|
||||
* @param string $code
|
||||
* @return \TrackingInfo
|
||||
* @throws TrackingException
|
||||
*/
|
||||
public static function track(string $code): TrackingInfo {
|
||||
$codeparts = explode("\t", $code);
|
||||
|
||||
$info = new TrackingInfo();
|
||||
|
||||
if (empty($codeparts[13])) {
|
||||
$from = new Location();
|
||||
$from->city = "Unknown";
|
||||
|
||||
$to = new Location();
|
||||
$to->street = implode(" ", [$codeparts[4], $codeparts[5]]);
|
||||
$to->city = $codeparts[6];
|
||||
$to->state = $codeparts[7];
|
||||
$to->zip = $codeparts[8];
|
||||
$to->country = (new League\ISO3166\ISO3166)->numeric($codeparts[9])['alpha2'];
|
||||
|
||||
$info->setCode($to->zip);
|
||||
$info->setTo($to);
|
||||
$info->setFrom($from);
|
||||
$info->setCarrier("usps");
|
||||
$info->setService(new Service("", "UPS Mail Innovations"));
|
||||
$info->setCurrentStatus(new TrackingEntry(TrackingStatus::TRACKING_STATUS_UNKNOWN, "Item is an untracked flat or international mailpiece.", time(), new Location()));
|
||||
} else {
|
||||
$realcode = $codeparts[13];
|
||||
|
||||
$info = Tracking::track($realcode);
|
||||
|
||||
// Set detailed destination address from code data
|
||||
$to = $info->getTo();
|
||||
if (is_null($to)) {
|
||||
$to = new Location();
|
||||
}
|
||||
$to->street = implode(" ", [$codeparts[4], $codeparts[5]]);
|
||||
$to->city = $codeparts[6];
|
||||
$to->state = $codeparts[7];
|
||||
$to->zip = $codeparts[8];
|
||||
$to->country = (new League\ISO3166\ISO3166)->numeric($codeparts[9])['alpha2'];
|
||||
$info->setTo($to);
|
||||
|
||||
$info->setService(new Service("", "UPS Mail Innovations"));
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
class Tracking_USPS {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $code
|
||||
* @return \TrackingInfo
|
||||
* @throws TrackingException
|
||||
*/
|
||||
public static function track(string $code, string $carrier = ""): TrackingInfo {
|
||||
$barcode = new TrackingBarcode($code);
|
||||
|
||||
try {
|
||||
$track = new \SimpleXMLElement("<TrackFieldRequest></TrackFieldRequest>");
|
||||
$track->addAttribute('USERID', env("usps_user_id"));
|
||||
$track->addChild('Revision', '1');
|
||||
$track->addChild('ClientIp', $_SERVER['REMOTE_ADDR']);
|
||||
$track->addChild('SourceId', env("usps_source_id", "selfhosted-opensource-default-value.netsyms.net"));
|
||||
$pack = $track->addChild('TrackID');
|
||||
$pack->addAttribute('ID', $barcode->getSanitized());
|
||||
$url = 'https://secure.shippingapis.com/ShippingApi.dll?API=TrackV2&XML=' . $track->asXML();
|
||||
$xml = simplexml_load_file($url);
|
||||
|
||||
if ($xml->getName() == "Error") {
|
||||
if (!empty($xml->Description)) {
|
||||
throw new TrackingException("The USPS tracking system is having problems: \"" . trim($xml->Description) . "\"");
|
||||
}
|
||||
throw new TrackingException("The USPS tracking system is having problems. Try again later.");
|
||||
}
|
||||
|
||||
if (!empty($xml->TrackInfo)) {
|
||||
$trackinfo = $xml->TrackInfo;
|
||||
}
|
||||
if (!empty($xml->TrackInfo->Error)) {
|
||||
throw new TrackingException((string) $xml->TrackInfo->Error->Description);
|
||||
}
|
||||
} catch (TrackingException $ex) {
|
||||
throw $ex;
|
||||
} catch (Exception $ex) {
|
||||
throw new TrackingException("There was a server problem. This code cannot be tracked right now.");
|
||||
}
|
||||
|
||||
$info = new TrackingInfo();
|
||||
|
||||
try {
|
||||
$info->setCode($trackinfo->attributes()["ID"]);
|
||||
} catch (Exception $ex) {
|
||||
throw new TrackingException("The USPS tracking system returned an invalid response. Try again later.");
|
||||
}
|
||||
|
||||
$info->setCarrier("usps");
|
||||
$info->setService(new Service((string) $trackinfo->ClassofMailCode, (string) $trackinfo->Class));
|
||||
|
||||
$current_status = new TrackingEntry(
|
||||
TrackingStatus::USPSEventCodeToStatus($trackinfo->TrackSummary->EventCode),
|
||||
$trackinfo->StatusSummary ?? "Unknown",
|
||||
$trackinfo->TrackSummary["EventDate"] . " " . $trackinfo->TrackSummary["EventTime"],
|
||||
null,
|
||||
TrackingStatus::isUSPSEventCodeContainerScan($trackinfo->TrackSummary->EventCode)
|
||||
);
|
||||
|
||||
$current_location = new Location();
|
||||
$current_location->city = (string) $trackinfo->TrackSummary->EventCity ?? "";
|
||||
$current_location->state = (string) $trackinfo->TrackSummary->EventState ?? "";
|
||||
$current_location->zip = (string) $trackinfo->TrackSummary->EventZIPCode ?? "";
|
||||
$current_location->country = (string) $trackinfo->TrackSummary->EventCountry ?? "";
|
||||
$current_status->setLocation($current_location);
|
||||
|
||||
$info->setCurrentStatus($current_status);
|
||||
|
||||
$from = new Location();
|
||||
$from->city = (string) $trackinfo->OriginCity ?? "";
|
||||
$from->state = (string) $trackinfo->OriginState ?? "";
|
||||
$from->zip = (string) $trackinfo->OriginZip ?? "";
|
||||
$from->country = (string) $trackinfo->OriginCountryCode ?? "";
|
||||
|
||||
$info->setFrom($from);
|
||||
|
||||
$to = new Location();
|
||||
$to->city = (string) $trackinfo->DestinationCity ?? "";
|
||||
$to->state = (string) $trackinfo->DestinationState ?? "";
|
||||
$to->zip = (string) $trackinfo->DestinationZip ?? "";
|
||||
$to->country = (string) $trackinfo->DestinationCountryCode ?? "";
|
||||
|
||||
$info->setTo($to);
|
||||
|
||||
foreach ($trackinfo->TrackDetail as $history) {
|
||||
$location = new Location();
|
||||
$location->city = (string) $history->EventCity ?? "";
|
||||
$location->state = (string) $history->EventState ?? "";
|
||||
$location->zip = (string) $history->EventZIPCode ?? "";
|
||||
$location->country = (string) $history->EventCountry ?? "";
|
||||
$info->appendHistoryEntry(new TrackingEntry(
|
||||
TrackingStatus::USPSEventCodeToStatus((string) $history->EventCode),
|
||||
((string) $history->Event),
|
||||
$history->EventDate . " " . $history->EventTime,
|
||||
$location,
|
||||
TrackingStatus::isUSPSEventCodeContainerScan((string) $history->EventCode)));
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue