Completed
Push — master ( 96178f...e2662a )
by Taosikai
10:28
created

FourPartyExpressTracker::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
/**
3
 * Slince shipment tracker library
4
 * @author Tao <[email protected]>
5
 */
6
namespace Slince\ShipmentTracking\FourPartyExpress;
7
8
use Carbon\Carbon;
9
use Slince\ShipmentTracking\Foundation\Exception\TrackException;
10
use Slince\ShipmentTracking\Foundation\HttpAwareTracker;
11
use Slince\ShipmentTracking\Foundation\Shipment;
12
use Slince\ShipmentTracking\Foundation\ShipmentEvent;
13
14
class FourPartyExpressTracker extends HttpAwareTracker
15
{
16
    protected $appKey;
17
18
    protected $appSecret;
19
20
21
    public function __construct($appKey, $appSecret)
22
    {
23
        $this->appKey = $appKey;
24
        $this->appSecret = $appSecret;
25
    }
26
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public function track($trackingNumber)
31
    {
32
        $response = $this->sendRequest($trackingNumber);
33
        return static::parseBody($response->getBody());
34
    }
35
36
    protected function sendRequest($trackingNumber)
37
    {
38
        $requestUrl = static::generateUrl($this->appKey, $this->appSecret, $trackingNumber);
39
        return $this->getHttpClient()->post($requestUrl, [
40
            'headers' => ['Content-Type' => 'application/json'],
41
            'body' =>  sprintf('{ "deliveryOrderNo":"%s" }', $trackingNumber),
42
        ]);
43
    }
44
45
    protected static function parseBody($body)
46
    {
47
        $json = \GuzzleHttp\json_decode($body, true);
48
        if (empty($json['data']) || !$json['result']) {
49
            throw new TrackException(sprintf('Bad Response message: %s', $json['msg']));
50
        }
51
        $trackEvents = array_map(function($trackInfo){
52
            return ShipmentEvent::fromArray([
53
                'time' => Carbon::parse($trackInfo['occurDatetime']),
54
                'location' => isset($trackInfo['occurLocation']) ? $trackInfo['occurLocation'] : $trackInfo['businessLinkCode'],
55
                'description' => $trackInfo['trackingContent']
56
            ]);
57
        }, array_reverse($json['data']['trackingList']));
58
        $shipment = new Shipment($trackEvents);
59
        $shipment->setDestination($json['data']['destinationCountry']);
60
        return $shipment;
61
    }
62
63
    /**
64
     * 生成sign
65
     * @param string $appKey
66
     * @param string $appSecret
67
     * @param string $timestamp
68
     * @param string $trackingNumber
69
     * @return string
70
     */
71
    protected static function makeSign($appKey, $appSecret, $timestamp, $trackingNumber)
72
    {
73
        $signatureStringBuffer = [
74
            'app_key', $appKey,
75
            'format', 'json',
76
            'method', 'tr.order.tracking.get',
77
            'timestamp', $timestamp,
78
            'v', '1.0',
79
            sprintf('{ "deliveryOrderNo":"%s" }', $trackingNumber),
80
            $appSecret
81
        ];
82
        return strtoupper(md5(implode('', $signatureStringBuffer)));
83
    }
84
85
    protected static function generateUrl($appKey, $appSecret, $trackingNumber)
86
    {
87
        $timestamp =  Carbon::now()->format('Y-m-d H24:i:s');
88
        $sign = static::makeSign($appKey, $appSecret, $timestamp, $trackingNumber);
89
        return sprintf('http://open.4px.com/router/api/service?method=tr.order.tracking.get&v=1.0&app_key=%s&timestamp=%s&format=json&access_token=&sign=%s',
90
            $appKey,
91
            $timestamp,
92
            $sign
93
        );
94
    }
95
}