FourPartyExpressTracker   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 7
dl 0
loc 82
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A track() 0 5 1
A sendRequest() 0 8 1
A parseBody() 0 17 4
A makeSign() 0 13 1
A generateUrl() 0 10 1
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
use GuzzleHttp\Client as HttpClient;
14
15
class FourPartyExpressTracker extends HttpAwareTracker
16
{
17
    protected $appKey;
18
19
    protected $appSecret;
20
21
    public function __construct($appKey, $appSecret, HttpClient $httpClient = null)
22
    {
23
        $this->appKey = $appKey;
24
        $this->appSecret = $appSecret;
25
        $httpClient && $this->setHttpClient($httpClient);
26
    }
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function track($trackingNumber)
32
    {
33
        $response = $this->sendRequest($trackingNumber);
34
        return static::parseBody($response->getBody());
35
    }
36
37
    protected function sendRequest($trackingNumber)
38
    {
39
        $requestUrl = static::generateUrl($this->appKey, $this->appSecret, $trackingNumber);
40
        return $this->getHttpClient()->post($requestUrl, [
41
            'headers' => ['Content-Type' => 'application/json'],
42
            'body' =>  sprintf('{ "deliveryOrderNo":"%s" }', $trackingNumber),
43
        ]);
44
    }
45
46
    protected static function parseBody($body)
47
    {
48
        $json = \GuzzleHttp\json_decode($body, true);
49
        if (empty($json['data']) || !$json['result']) {
50
            throw new TrackException(sprintf('Bad Response message: %s', $json['msg']));
51
        }
52
        $trackEvents = array_map(function($trackInfo){
53
            return ShipmentEvent::fromArray([
54
                'time' => Carbon::parse($trackInfo['occurDatetime']),
55
                'location' => isset($trackInfo['occurLocation']) ? $trackInfo['occurLocation'] : $trackInfo['businessLinkCode'],
56
                'description' => $trackInfo['trackingContent']
57
            ]);
58
        }, array_reverse($json['data']['trackingList']));
59
        $shipment = new Shipment($trackEvents);
60
        $shipment->setDestination($json['data']['destinationCountry']);
61
        return $shipment;
62
    }
63
64
    /**
65
     * 生成sign
66
     * @param string $appKey
67
     * @param string $appSecret
68
     * @param string $timestamp
69
     * @param string $trackingNumber
70
     * @return string
71
     */
72
    protected static function makeSign($appKey, $appSecret, $timestamp, $trackingNumber)
73
    {
74
        $signatureStringBuffer = [
75
            'app_key', $appKey,
76
            'format', 'json',
77
            'method', 'tr.order.tracking.get',
78
            'timestamp', $timestamp,
79
            'v', '1.0',
80
            sprintf('{ "deliveryOrderNo":"%s" }', $trackingNumber),
81
            $appSecret
82
        ];
83
        return strtoupper(md5(implode('', $signatureStringBuffer)));
84
    }
85
86
    protected static function generateUrl($appKey, $appSecret, $trackingNumber)
87
    {
88
        $timestamp =  Carbon::now()->format('Y-m-d H24:i:s');
89
        $sign = static::makeSign($appKey, $appSecret, $timestamp, $trackingNumber);
90
        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',
91
            $appKey,
92
            $timestamp,
93
            $sign
94
        );
95
    }
96
}