Completed
Push — master ( 3f0652...6ef7a8 )
by Taosikai
10:39
created

USPSTracker::getUserId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * Slince shipment tracker library
4
 * @author Tao <[email protected]>
5
 */
6
namespace Slince\ShipmentTracking\USPS;
7
8
use function GuzzleHttp\Promise\promise_for;
9
use Slince\ShipmentTracking\Foundation\Exception\TrackException;
10
use Slince\ShipmentTracking\Foundation\HttpAwareTracker;
11
use GuzzleHttp\Client as HttpClient;
12
use Slince\ShipmentTracking\Foundation\Shipment;
13
use Slince\ShipmentTracking\Utility;
14
15
class USPSTracker extends HttpAwareTracker
16
{
17
    const TRACKING_ENDPOINT  = 'http://production.shippingapis.com/ShippingAPI.dll';
18
19
    /**
20
     * @var string
21
     */
22
    protected $userId;
23
24
    /**
25
     * You can get your userID from the following url
26
     * {@link https://www.usps.com/business/web-tools-apis/welcome.htm}
27
     */
28
    public function __construct($userId, HttpClient $httpClient = null)
29
    {
30
        $this->userId = $userId;
31
        $httpClient && $this->setHttpClient($httpClient);
32
    }
33
34
    /**
35
     * @return string
36
     */
37
    public function getUserId()
38
    {
39
        return $this->userId;
40
    }
41
42
    /**
43
     * @param string $userId
44
     * @return USPSTracker
45
     */
46
    public function setUserId($userId)
47
    {
48
        $this->userId = $userId;
49
        return $this;
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function track($trackingNumber)
56
    {
57
        try {
58
            $body = $this->request($trackingNumber);
59
            $array = Utility::parseXml($body);
60
        } catch (\Exception $exception) {
61
            throw new TrackException($exception->getMessage());
62
        }
63
        if (!isset($array['TrackInfo'])) {
64
            throw new TrackException($array['Description']);
65
        }
66
        if (isset($array['TrackInfo']['Error'])) {
67
            throw new TrackException($array['TrackInfo']['Error']['Description']);
68
        }
69
        $shipment = static::buildShipment($array);
70
        return $shipment;
71
    }
72
73
    protected function request($trackingNumber)
74
    {
75
        return $this->getHttpClient()->get(static::TRACKING_ENDPOINT, [
76
            'query' => [
77
                'API' => 'TrackV2',
78
                'XML' => static::buildXml($this->userId, $trackingNumber)
79
            ]
80
        ])->getBody();
81
    }
82
83
    /**
84
     * @param string $userId
85
     * @param string $trackID
86
     * @return string
87
     */
88
    protected static function buildXml($userId, $trackID)
89
    {
90
        $xmlTemplate = <<<XML
91
<?xml version="1.0" encoding="UTF-8" ?>
92
<TrackFieldRequest USERID="%s">
93
  <ClientIp>111.0.0.1</ClientIp>
94
  <TrackID ID="%s"></TrackID>
95
</TrackFieldRequest>
96
XML;
97
        return sprintf($xmlTemplate, $userId, $trackID);
98
    }
99
100
    /**
101
     * @param array $array
102
     * @return Shipment
103
     */
104
    protected static function buildShipment($array)
105
    {
106
        $events = array_map(function($eventData){
107
            $time = empty($eventData['EventTime']) ? '' : $eventData['EventTime'];
108
            $day = empty($eventData['EventDate']) ? '' : $eventData['EventDate'];
109
            $country = empty($eventData['EventCountry']) ? '' : $eventData['EventCountry'];
110
            $state = empty($eventData['EventState']) ? '' : $eventData['EventState'];
111
            $city = empty($eventData['EventCity']) ? '' : $eventData['EventCity'];
112
            return ShipmentEvent::fromArray([
113
                'date' => "{$day} {$time}",
114
                'location' => "{$city} {$state} {$country}",
115
                'description' => $eventData['Event'],
116
                'time' => $time,
117
                'day' => $day,
118
                'city' => $city,
119
                'state' => $state,
120
                'country' => $country
121
            ]);
122
        }, array_reverse($array['TrackInfo']['TrackDetail']));
123
        $shipment = new Shipment($events);
124
        if (isset($array['TrackInfo']['TrackSummary']['DeliveryAttributeCode'])) {
125
            $shipment->setIsDelivered($array['TrackInfo']['TrackSummary']['DeliveryAttributeCode'] == '01');
126
        }
127
        if ($firstEvent = reset($events)) {
128
            $shipment->setDeliveredAt($firstEvent->getDate());
129
        }
130
        return $shipment;
131
    }
132
}