Completed
Push — master ( 2b3b62...a74c29 )
by Taosikai
14:49
created

KuaiDi100Tracker::buildQueryParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 1
1
<?php
2
/**
3
 * Slince shipment tracker library
4
 * @author Tao <[email protected]>
5
 */
6
namespace Slince\ShipmentTracking\KuaiDi100;
7
8
use GuzzleHttp\Client as HttpClient;
9
use GuzzleHttp\Psr7\Request;
10
use GuzzleHttp\Exception\GuzzleException;
11
use Psr\Http\Message\RequestInterface;
12
use Slince\ShipmentTracking\Foundation\Exception\TrackException;
13
use Slince\ShipmentTracking\Foundation\HttpAwareTracker;
14
use Slince\ShipmentTracking\Foundation\Shipment;
15
use Slince\ShipmentTracking\Foundation\ShipmentEvent;
16
17
class KuaiDi100Tracker extends HttpAwareTracker
18
{
19
    /**
20
     * @var string
21
     */
22
    const TRACKING_ENDPOINT = 'http://api.kuaidi100.com/api';
23
24
    /**
25
     * @var string
26
     */
27
    protected $appKey;
28
29
    /**
30
     * @var string
31
     */
32
    protected $carrier;
33
34
    public function __construct($appKey, $carrier = null, HttpClient $httpClient = null)
35
    {
36
        $this->appKey = $appKey;
37
        $this->carrier = $carrier;
38
        $httpClient && $this->setHttpClient($httpClient);
39
    }
40
41
    /**
42
     * @param string $appKey
43
     */
44
    public function setAppKey($appKey)
45
    {
46
        $this->appKey = $appKey;
47
    }
48
49
    /**
50
     * @return string
51
     */
52
    public function getAppKey()
53
    {
54
        return $this->appKey;
55
    }
56
57
    /**
58
     * @return string
59
     */
60
    public function getCarrier()
61
    {
62
        return $this->carrier;
63
    }
64
65
    /**
66
     * @param string $carrier
67
     * @return KuaiDi100Tracker
68
     */
69
    public function setCarrier($carrier)
70
    {
71
        $this->carrier = $carrier;
72
        return $this;
73
    }
74
75
    /**
76
     * @param string $trackingNumber
77
     * @return array
78
     */
79
    protected function buildQueryParameters($trackingNumber)
80
    {
81
        return [
82
            'id' => $this->appKey,
83
            'com' => $this->carrier,
84
            'nu' => $trackingNumber,
85
            'show' => 0,
86
            'multi' => 1,
87
            'order' => 'asc',
88
        ];
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function track($trackingNumber)
95
    {
96
        $request = new Request('GET', static::TRACKING_ENDPOINT);
97
        $json = $this->sendRequest($request, [
98
            'query' => $this->buildQueryParameters($trackingNumber)
99
        ]);
100
        if ($json['status'] != 1) {
101
            throw new TrackException(sprintf('Bad response with status "%d"', $json['status']));
102
        }
103
        return static::buildShipment($json);
104
    }
105
106
    /**
107
     * @param RequestInterface $request
108
     * @param array $options
109
     * @return array
110
     * @codeCoverageIgnore
111
     */
112
    protected function sendRequest(RequestInterface $request, array $options = [])
113
    {
114
        try {
115
            $response = $this->getHttpClient()->send($request, $options);
116
            return \GuzzleHttp\json_decode((string)$response->getBody(), true);
117
        } catch (GuzzleException $exception) {
118
            throw new TrackException($exception->getMessage());
119
        }
120
    }
121
122
    /**
123
     * @param array $json
124
     * @return Shipment
125
     */
126
    protected static function buildShipment($json)
127
    {
128
        $events = array_map(function($item) {
129
            return ShipmentEvent::fromArray([
130
                'location' => $item['location'],
131
                'description' => $item['context'],
132
                'date' => $item['time'],
133
            ]);
134
        }, $json['data']);
135
        $shipment = new Shipment($events);
136
        $shipment->setIsDelivered($json['state'] == 3);
137
        if ($firstEvent = reset($events)) {
138
            $shipment->setDeliveredAt($firstEvent->getDate());
139
        }
140
        return $shipment;
141
    }
142
}