Completed
Push — master ( d0aa61...4c97cb )
by Taosikai
12:05
created

SeventeenTracker::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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