SeventeenTracker   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 10
lcom 1
cbo 9
dl 0
loc 97
rs 10
c 2
b 0
f 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 2
A track() 0 10 2
A createRequest() 0 19 1
A sendRequest() 0 4 1
B buildShipment() 0 32 4
1
<?php
2
/**
3
 * Slince shipment tracker library
4
 * @author Tao <[email protected]>
5
 */
6
namespace Slince\ShipmentTracking\SeventeenTrack;
7
8
use Carbon\Carbon;
9
use GuzzleHttp\Psr7\Request;
10
use Psr\Http\Message\RequestInterface;
11
use Psr\Http\Message\ResponseInterface;
12
use Slince\ShipmentTracking\Foundation\Exception\TrackException;
13
use Slince\ShipmentTracking\Foundation\HttpAwareTracker;
14
use Slince\ShipmentTracking\Foundation\ShipmentEvent;
15
use GuzzleHttp\Client as HttpClient;
16
17
class SeventeenTracker extends HttpAwareTracker
18
{
19
    const TRACK_ENDPOINT = 'http://www.17track.net/restapi/handlertrack.ashx';
20
21
    const REFERER = 'http://www.17track.net/zh-cn/track?nums={trackingNumber}';
22
23
    public function __construct(HttpClient $httpClient = null)
24
    {
25
        $httpClient && $this->setHttpClient($httpClient);
26
    }
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function track($trackingNumber)
32
    {
33
        $request = static::createRequest($trackingNumber);
34
        $response = $this->sendRequest($request);
35
        $json = \GuzzleHttp\json_decode($response->getBody(), true);
36
        if ($json['ret'] != 1) {
37
            throw new TrackException($json['msg']);
38
        }
39
        return static::buildShipment($json);
40
    }
41
42
    /**
43
     * @param string $trackingNumber
44
     * @return Request
45
     */
46
    protected static function createRequest($trackingNumber)
47
    {
48
        $parameterKey = [
49
            'guid' => '',
50
            'data' => [
51
                [
52
                    'num' => $trackingNumber
53
                ]
54
            ]
55
        ];
56
        return new Request('POST', static::TRACK_ENDPOINT, [
57
                'Referer' => str_replace('{trackingNumber}', $trackingNumber, static::REFERER),
58
                'X-Requested-With' => 'XMLHttpRequest',
59
                'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
60
                'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'
61
            ],
62
            \GuzzleHttp\json_encode($parameterKey)
63
        );
64
    }
65
66
    /**
67
     * @param RequestInterface $request
68
     * @param array $options
69
     * @return ResponseInterface
70
     * @codeCoverageIgnore
71
     */
72
    protected function sendRequest(RequestInterface $request, $options = [])
73
    {
74
        return $this->getHttpClient()->send($request, $options);
75
    }
76
77
    /**
78
     * @param array $json
79
     * @return Shipment
80
     */
81
    protected static function buildShipment($json)
82
    {
83
        if (empty($json['dat'][0]['track'])) {
84
            throw new TrackException('Bad response');
85
        }
86
        $track = $json['dat'][0]['track'];
87
        $shipment = new Shipment();
88
        //源国家的跟踪轨迹
89
        $originEvents = array_map(function($item){
90
            return ShipmentEvent::fromArray([
91
                'description' => $item['z'],
92
                'location' => $item['d'] ?:  $item['c'],
93
                'date' => Carbon::parse($item['a'])
94
            ]);
95
        }, array_reverse($track['z1']));
96
        $shipment->setOriginEvents($originEvents);
97
        //目标国家跟踪轨迹
98
        $destinationEvents = array_map(function($item){
99
            return ShipmentEvent::fromArray([
100
                'description' => $item['z'],
101
                'location' => $item['d'] ?:  $item['c'],
102
                'date' => Carbon::parse($item['a'])
103
            ]);
104
        }, array_reverse($track['z2']));
105
        $shipment->setDestinationEvents($destinationEvents);
106
        $shipment->setEvents(array_merge($shipment->getOriginEvents(), $shipment->getDestinationEvents()));
107
        //状态
108
        $shipment->setStatus($track['e'])
109
            ->setIsDelivered($shipment->getStatus() === Shipment::STATUS_DELIVERED);
110
        //发货国家与目的国家暂时不得而知
111
        return $shipment;
112
    }
113
}