2021-05-21 18:50:46 -06:00
|
|
|
<?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));
|
2021-10-09 16:34:16 -06:00
|
|
|
$info->setCarrierLogo("data:image/svg+xml;base64,PHN2ZyBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA2NTkuMDU1IDExMC4wMzYiIGhlaWdodD0iMTEwLjAzNiIgdmlld0JveD0iMCAwIDY1OS4wNTUgMTEwLjAzNiIgd2lkdGg9IjY1OS4wNTUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxnIGZpbGw9IiMwMDRjODIiPjxwYXRoIGQ9Im0yMy4zODIuNTU1aC44MjZsMS4zNzkuMjY5IDEuNjQ4LjI3NiA0LjQwMiAxLjEwMyA2LjA1IDEuMDk2IDMuMzA1LjgzIDMuNTc1LjgyNiAzLjg1LjU0OSAzLjg1MiAxLjEgNC4xMjcuNTQ4IDQuMTI1IDEuMTAyIDEzLjIwNSAyLjQ3NCA0LjEyOCAxLjEwMyA0LjQwMi44MjMgMy44NDguODI2IDQuMTI4LjgyNiAzLjg0Ny44MjQgMy44NTMuNTUzIDMuMzAxLjgyNiAzLjMwNS41NDcgMi43NTEuODI0IDIuNDczLjU1MyAyLjE5OS4yNzMgMS45MjcuMjc2IDEuMzc5LjI3Ny44MjUuMjczaC41NDZsMy41NzguODI1IDMuMzAzLjU1MiAyLjc1Mi44MjUgMi4xOTcuNTUgMi4yMDMuODI0IDEuNjUyLjU1MSAyLjE5NyAxLjEwMi44MjQuNTUyIDEuMzc5IDEuMzcxdi4yNzZsLjI3OC4yNzd2LjI2OWgxMS44MjNsMS4xMDQuMjc4aDEuMTAxbC44MjQuMjc3aC44MjRsLjgyNC4yNzYgMi4yMDQgMS4wOTUuMjczLjU1NSAxLjkyNiAzLjAyNS41NTIgMy41NzQtLjU1MiA0LjQwMi0xLjM3NSA0LjEyOS0xLjY1IDQuMTI0LTEuNjU1IDMuMzA0LTEuMzcxIDIuMi0uNTQ5LjgyNi0uNTUyLjI3Ni0xLjM3NS41NDctMS45MjYuODI1LTIuNzUgMS4xLTMuMDI5IDEuMDk4LTMuODQ3IDEuNjU2LTQuMTMxIDEuNjQ4LTQuNjc2IDEuNjQ4LTUuMjI4IDIuMjA1LTUuNSAxLjkyNi01LjQ5OSAyLjE5Ny0xMi4xMDUgNC45NTktNi4zMjkgMi40NzUtNi4zMjggMi4xOTgtNi4zMjYgMi43NDYtNi41OTkgMi40ODMtNi4zMjggMi4xOTctNi4wNTUgMi43NTQtNi4zMjUgMi4xOTgtNS43NzkgMi4xOTctMTEuMDA0IDQuNDA5LTQuOTUxIDEuOTE5LTQuNjc3IDEuNjU1LTQuMTI0IDEuNjQ4LTMuNTc1IDEuMzc3LTMuMDI5IDEuMzc3LTIuNDcyLjgyOC0xLjkyOC44MjctMS4xMDEuMjY0LS4yNzguMjc4aDE0Mi4yMjdsMjMuMTA1LTEwOS40ODZoLTE1NS40Mjh6Ii8+PHBhdGggZD0ibTEyOS44NDcgMzYuMDM5LS44MjkuMjc2LTUuNDk5IDEuMDk1aC0xLjM3N2wtMS4xMDIuMjc4aC0xLjA5NWwtMS42NTUuMjc3LS44MjQuMjc1LS41NS4yNzItLjI3OC41NTV2LjU0OGwuNTU1LjU0OWgxLjA5N2wxLjEwMi4yNzVoMi43NWwxLjY0OC0uMjc1aDEuNjVsMy44NTQtLjU0OWgxLjkyN2wyLjItLjI3OSAxLjkyMy0uMjY5IDEuNjU3LS4yNzYgMS45MjEtLjI3OWg3LjQyOWwuODIyLjI3OS41NTYuMjc2LjU0Ni44MjR2MS4wOTdsLS4yNzUgMS4xLS4yNzEgMS4zNzktLjU1NiAxLjY1LS44MjIgMS45MjgtLjU1IDEuOTI2LS4yNzcgMS4wOTcuNTUuNTUyLjU1My0uMjc5IDEuMTAyLTEuMS41NDYtLjgyNC44MjgtMS4zNzIuODI1LTEuNjUxLjgyNC0xLjkyNy44MjItMS42NS41NTMtMS42NTMuMjczLTEuMzczdi0xLjY1bC0uNTQ3LTEuMzc5LS44MjQtLjgyNS0xLjEwMS0uODIzLTEuMzc3LS41NTEtMS42NTEtLjI3NC0xLjkyMy0uMjc3aC0xMS41NTZsLS4yNzUuMjc3aC0uMjc2bC0uNTQ3LjI3NC0uNTU1IDEuMTAzLS41NDcuMjcxLS41NS41NTJ6Ii8+PHBhdGggZD0ibTE4LjE1NiAyNS4zMTMtMTguMTU2IDg0LjE3My44MjktLjI3OCAxLjY0OC0xLjA5MSAyLjc1Mi0xLjEwNyAzLjU3OC0xLjkyNiA0LjEyMi0xLjkyNiA0LjY4LTIuNDY4IDUuNTAyLTIuNDc2IDUuMjI2LTIuNzU0IDUuNTAxLTIuNDgzIDUuMjI3LTIuNzQ2IDUuMjI2LTIuNDc2IDQuOTQ5LTIuNDc1IDQuMTMtMi4yMDUgMy41NzUtMS42NDggMi43NTEtMS4zNzcgMS45MjYtLjgyIDIuNzUyLTEuMzc3IDIuNDc2LTEuMzc3IDMuMDI1LTEuMzc3IDMuMDI2LTEuNjQ4IDIuNzUtMS4zNzcgMy4zMDItMS4zNzcgMy4wMjYtMS42NDggMy4zLTEuMzcgMy4zMDQtMS42NjIgMTYuNTAzLTYuODcgNy40My0yLjQ3NiAxLjA5OS0uMjc3IDEuMDk3LS41NDcgMS4zOC0uMjc2IDQuOTQ4LTEuNjUgNS43NzgtMS42NTQgMS45MjctLjI3NiA1Ljc3NS0xLjY1IDMuMzA1LS41NDYgMS4wOTctLjI3Ni44MjQtLjI3OGguODI5bC44MjQtLjI3LjU1MS0uNTU0aC4yNzd2LS4yNzdsLS41NTUtMS4wOTUtLjgyNC0uMjc2LTEuMTAyLS4yNzloLTEuMDk3bC0xLjY0OC0uMjcxaC0xLjY1N2wtMS45MjMuMjcxLTMuMzAzLjI3OS0zLjU3Ni41NDUtMy44NDkuODI2LTQuMTI5LjgzMS00LjEyMiAxLjA5Ny00LjQwMyAxLjM3Ny00LjEyOSAxLjM3My00LjQgMS4zNzctNC4xMjQgMS42NTItNC4xMzEgMS4zNzItMy44NDkgMS4zNzgtMy41NzQgMS4zNzctMy4zMDUgMS42NDktMi43NSAxLjA5OC0yLjQ3NiAxLjEwNi0xLjkyNiAxLjA5OC0xMC40NTItMzIuNDY0aDY2LjU3NGwuMjcxLTEuMzcyLTEuMDk3LTEuMzc5LTEuNjUzLS44MjUtMi40NzYtLjgyNC0yLjc1Mi0uODI0LTcuMTUyLTEuMTAzLTExLjU1Mi0uODIxeiIvPjwvZz48cGF0aCBkPSJtNjU4LjM4NSA1Ny4yOTloLTQ2Ni4wOTNsLjY2OC03LjAwNGg0NjYuMDk1eiIgZmlsbD0iI2VhNDE1NiIvPjxwYXRoIGQ9Im0yMTMuNDcyIDQxLjgxNy0zLjU3NC0uMjc2LTMuNTc2LS44MjQtMi43NTItLjgyNi0yLjQ3Ni0xLjY1MS0xLjY0OC0xLjkyNS0xLjEwMi0yLjQ3OS0uMjc2LTIuNzQ3LjI3Ni0zLjMwNSAxLjM3Ny02LjA1IDEuMDk3LTUuNTAyIDEuMTAzLTQuNjguODIyLTMuODQ3LjU1Ny0zLjMwMy41NDgtMi40NzYuMjc2LTEuMzcyLjI2OS0uNTU0aDkuMDc5bC0uMjc1IDEuMS0uNTQ5IDIuNzUyLTEuMTAzIDQuMTI1LS44MjQgNC42NzYtMS4xMDIgNC42OC0xLjM3MiA2Ljg3NS0uMjc4LjgyNC0uMjczIDIuMjAzdjMuODUzbC41NTEgMS4zNzIgMS4wOTkgMS4xMDIgMS4zNzUuODI0IDEuOTI2LjU0OSAyLjIwMy4yNzYgMi40NzQtLjI3NiAxLjkyNi0uMjcxIDEuOTI3LS44MyAxLjM3My0xLjM3NSAxLjEwMy0xLjM3MiAxLjEwMi0xLjY1NyAxLjY1LT
|
2021-05-22 22:14:20 -06:00
|
|
|
$info->setCarrierAttributionText("Information provided by www.usps.com.");
|
2021-05-21 18:50:46 -06:00
|
|
|
|
|
|
|
$current_status = new TrackingEntry(
|
|
|
|
TrackingStatus::USPSEventCodeToStatus($trackinfo->TrackSummary->EventCode),
|
2021-05-21 19:26:03 -06:00
|
|
|
($trackinfo->StatusSummary ?? "Unknown") . (TrackingStatus::USPSEventCodeToStatus($trackinfo->TrackSummary->EventCode) == TrackingStatus::TRACKING_STATUS_UNKNOWN ? " " . $trackinfo->TrackSummary->EventCode : ""),
|
2021-05-21 18:50:46 -06:00
|
|
|
$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);
|
2021-06-19 17:27:22 -06:00
|
|
|
// USPS doesn't put the latest entry in the history
|
|
|
|
$info->appendHistoryEntry($current_status);
|
2021-05-21 18:50:46 -06:00
|
|
|
|
|
|
|
$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;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|