setRequest($request); } parent::__construct($accessKey, $userId, $password, $useIntegration, $logger); } /** * Get package tracking information. * * @param string $trackingNumber The package's tracking number. * @param string $requestOption Optional processing. For Mail Innovations the only valid options are Last Activity and All activity. * * @throws Exception * * @return stdClass */ public function track($trackingNumber, $requestOption = 'activity') { $this->trackingNumber = $trackingNumber; $this->requestOption = $requestOption; return $this->getFormattedResponse(); } /** * Get package tracking information. * * @param string $referenceNumber Reference numbers can be a purchase order number, job number, etc. Reference number can be added when creating a shipment. * @param string $requestOption * * @throws Exception * * @return stdClass */ public function trackByReference($referenceNumber, $requestOption = 'activity') { $this->referenceNumber = $referenceNumber; $this->requestOption = $requestOption; return $this->getFormattedResponse(); } /** * Set shipper number * * @param string $shipperNumber * */ public function setShipperNumber($shipperNumber) { $this->shipperNumber = $shipperNumber; } /** * Set begin date * * @param DateTime $beginDate * */ public function setBeginDate(DateTime $beginDate) { $this->beginDate = $beginDate; } /** * Set end date * * @param DateTime $endDate * */ public function setEndDate(DateTime $endDate) { $this->endDate = $endDate; } /** * @return stdClass * @throws Exception */ private function getFormattedResponse() { $this->response = $this->getRequest()->request( $this->createAccess(), $this->createRequest(), $this->compileEndpointUrl(self::ENDPOINT) ); $response = $this->response->getResponse(); if (null === $response) { throw new Exception('Failure (0): Unknown error', 0); } if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) { throw new Exception( "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}", (int)$response->Response->Error->ErrorCode ); } return $this->formatResponse($response); } /** * Check if tracking number is for mail innovations. * * @return bool */ private function isMailInnovations() { $patterns = [ // UPS Mail Innovations tracking numbers '/^MI\d{6}\d{1,22}$/',// MI 000000 00000000+ // USPS - Certified Mail '/^94071\d{17}$/', // 9407 1000 0000 0000 0000 00 '/^7\d{19}$/', // 7000 0000 0000 0000 0000 // USPS - Collect on Delivery '/^93033\d{17}$/', // 9303 3000 0000 0000 0000 00 '/^M\d{9}$/', // M000 0000 00 // USPS - Global Express Guaranteed '/^82\d{10}$/', // 82 000 000 00 // USPS - Priority Mail Express International '/^EC\d{9}US$/', // EC 000 000 000 US // USPS Innovations Expedited '/^927\d{23}$/', // 9270 8900 8900 8900 8900 8900 00 // USPS - Priority Mail Express '/^927\d{19}$/', // 9270 1000 0000 0000 0000 00 '/^EA\d{9}US$/', // EA 000 000 000 US // USPS - Priority Mail International '/^CP\d{9}US$/', // CP 000 000 000 US // USPS - Priority Mail '/^92055\d{17}$/', // 9205 5000 0000 0000 0000 00 '/^14\d{18}$/', // 1400 0000 0000 0000 0000 // USPS - Registered Mail '/^92088\d{17}$/', // 9208 8000 0000 0000 0000 00 '/^RA\d{9}US$/', // RA 000 000 000 US // USPS - Signature Confirmation '/^9202\d{16}US$/', // 9202 1000 0000 0000 0000 00 '/^23\d{16}US$/', // 2300 0000 0000 0000 0000 // USPS - Tracking '/^94\d{20}$/', // 9400 1000 0000 0000 0000 00 '/^03\d{18}$/' // 0300 0000 0000 0000 0000 ]; foreach ($patterns as $pattern) { if (preg_match($pattern, $this->trackingNumber)) { return true; } } return false; } /** * Create the Tracking request. * * @return string */ private function createRequest() { $xml = new DOMDocument(); $xml->formatOutput = true; $trackRequest = $xml->appendChild($xml->createElement('TrackRequest')); $trackRequest->setAttribute('xml:lang', 'en-US'); $request = $trackRequest->appendChild($xml->createElement('Request')); $node = $xml->importNode($this->createTransactionNode(), true); $request->appendChild($node); $request->appendChild($xml->createElement('RequestAction', 'Track')); if (null !== $this->requestOption) { $request->appendChild($xml->createElement('RequestOption', $this->requestOption)); } if (null !== $this->trackingNumber) { $trackRequest->appendChild($xml->createElement('TrackingNumber', $this->trackingNumber)); } if ($this->isMailInnovations()) { $trackRequest->appendChild($xml->createElement('IncludeMailInnovationIndicator')); } if (null !== $this->referenceNumber) { $trackRequest->appendChild($xml->createElement('ReferenceNumber'))->appendChild($xml->createElement('Value', $this->referenceNumber)); } if (null !== $this->shipperNumber) { $trackRequest->appendChild($xml->createElement('ShipperNumber', $this->shipperNumber)); } if (null !== $this->beginDate || null !== $this->endDate) { $DateRange = $xml->createElement('PickupDateRange'); if (null !== $this->beginDate) { $beginDate = $this->beginDate->format('Ymd'); $DateRange->appendChild($xml->createElement('BeginDate', $beginDate)); } if (null !== $this->endDate) { $endDate = $this->endDate->format('Ymd'); $DateRange->appendChild($xml->createElement('EndDate', $endDate)); } $trackRequest->appendChild($DateRange); } return $xml->saveXML(); } /** * Format the response. * * @param SimpleXMLElement $response * * @return stdClass */ private function formatResponse(SimpleXMLElement $response) { if ($this->allowMultipleShipments) { $response = $this->convertXmlObject($response); if (!is_array($response->Shipment)) { $response->Shipment = [$response->Shipment]; } return $response; } return $this->convertXmlObject($response->Shipment); } /** * @return RequestInterface */ public function getRequest() { if (null === $this->request) { $this->request = new Request($this->logger); } return $this->request; } /** * @param RequestInterface $request * * @return $this */ public function setRequest(RequestInterface $request) { $this->request = $request; return $this; } /** * @return ResponseInterface */ public function getResponse() { return $this->response; } /** * @param ResponseInterface $response * * @return $this */ public function setResponse(ResponseInterface $response) { $this->response = $response; return $this; } /** * @param bool $value * @return $this */ public function allowMultipleShipments($value = true) { $this->allowMultipleShipments = $value ? true : false; return $this; } }