Completed
Pull Request — master (#82)
by Stefan
03:29
created

Tracking::setResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Ups;
4
5
use DOMDocument;
6
use Exception;
7
use Psr\Log\LoggerInterface;
8
use SimpleXMLElement;
9
use stdClass;
10
11
/**
12
 * Tracking API Wrapper.
13
 */
14
class Tracking extends Ups
15
{
16
    const ENDPOINT = '/Track';
17
18
    /**
19
     * @var RequestInterface
20
     */
21
    private $request;
22
23
    /**
24
     * @var ResponseInterface
25
     *                        // todo make private
26
     */
27
    public $response;
28
29
    /**
30
     * @var string
31
     */
32
    private $trackingNumber;
33
34
    /**
35
     * @var string
36
     */
37
    private $referenceNumber;
38
39
    /**
40
     * @var string
41
     */
42
    private $requestOption;
43
44
    /**
45
     * @param string|null $accessKey UPS License Access Key
46
     * @param string|null $userId UPS User ID
47
     * @param string|null $password UPS User Password
48
     * @param bool $useIntegration Determine if we should use production or CIE URLs.
49
     * @param RequestInterface $request
50
     * @param LoggerInterface PSR3 compatible logger (optional)
51
     */
52 6 View Code Duplication
    public function __construct($accessKey = null, $userId = null, $password = null, $useIntegration = false, RequestInterface $request = null, LoggerInterface $logger = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
53
    {
54 6
        if (null !== $request) {
55
            $this->setRequest($request);
56
        }
57 6
        parent::__construct($accessKey, $userId, $password, $useIntegration, $logger);
58 6
    }
59
60
    /**
61
     * Get package tracking information.
62
     *
63
     * @param string $trackingNumber The package's tracking number.
64
     * @param string $requestOption Optional processing. For Mail Innovations the only valid options are Last Activity and All activity.
65
     *
66
     * @throws Exception
67
     *
68
     * @return stdClass
69
     */
70 5 View Code Duplication
    public function track($trackingNumber, $requestOption = 'activity')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
    {
72 5
        $this->trackingNumber = $trackingNumber;
73 5
        $this->requestOption = $requestOption;
74
75 5
        $access = $this->createAccess();
76 5
        $request = $this->createRequest();
77
78 5
        $this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
79 5
        $response = $this->response->getResponse();
80
81 5
        if (null === $response) {
82 2
            throw new Exception('Failure (0): Unknown error', 0);
83
        }
84
85 3
        if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
86
            throw new Exception(
87
                "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
88
                (int)$response->Response->Error->ErrorCode
89
            );
90
        } else {
91 3
            return $this->formatResponse($response);
92
        }
93
    }
94
95
    /**
96
     * Get package tracking information.
97
     *
98
     * @param string $referenceNumber Reference numbers can be a purchase order number, job number, etc. Reference number can be added when creating a shipment.
99
     * @throws Exception
100
     *
101
     * @return stdClass
102
     */
103 1 View Code Duplication
    public function trackByReference($referenceNumber, $requestOption = 'activity')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
    {
105 1
        $this->referenceNumber = $referenceNumber;
106 1
        $this->requestOption = $requestOption;
107
108 1
        $access = $this->createAccess();
109 1
        $request = $this->createRequest();
110
111 1
        $this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
112 1
        $response = $this->response->getResponse();
113
114 1
        if (null === $response) {
115 1
            throw new Exception('Failure (0): Unknown error', 0);
116
        }
117
118
        if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
119
            throw new Exception(
120
                "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
121
                (int)$response->Response->Error->ErrorCode
122
            );
123
        } else {
124
            return $this->formatResponse($response);
125
        }
126
    }
127
128
    /**
129
     * Check if tracking number is for mail innovations.
130
     *
131
     * @return bool
132
     */
133 6
    private function isMailInnovations()
134
    {
135
        $patterns = [
136
137
            // UPS Mail Innovations tracking numbers
138 6
            '/^MI\d{6}\d{1,22}$/',// MI 000000 00000000+
139
140
            // USPS - Certified Mail
141 6
            '/^94071\d{17}$/',    // 9407 1000 0000 0000 0000 00
142 6
            '/^7\d{19}$/',        // 7000 0000 0000 0000 0000
143
144
            // USPS - Collect on Delivery
145 6
            '/^93033\d{17}$/',    // 9303 3000 0000 0000 0000 00
146 6
            '/^M\d{9}$/',         // M000 0000 00
147
148
            // USPS - Global Express Guaranteed
149 6
            '/^82\d{10}$/',       // 82 000 000 00
150
151
            // USPS - Priority Mail Express International
152 6
            '/^EC\d{9}US$/',      // EC 000 000 000 US
153
154
            // USPS - Priority Mail Express
155 6
            '/^927\d{19}$/',      // 9270 1000 0000 0000 0000 00
156 6
            '/^EA\d{9}US$/',      // EA 000 000 000 US
157
158
            // USPS - Priority Mail International
159 6
            '/^CP\d{9}US$/',      // CP 000 000 000 US
160
161
            // USPS - Priority Mail
162 6
            '/^92055\d{17}$/',    // 9205 5000 0000 0000 0000 00
163 6
            '/^14\d{18}$/',       // 1400 0000 0000 0000 0000
164
165
            // USPS - Registered Mail
166 6
            '/^92088\d{17}$/',    // 9208 8000 0000 0000 0000 00
167 6
            '/^RA\d{9}US$/',      // RA 000 000 000 US
168
169
            // USPS - Signature Confirmation
170 6
            '/^9202\d{16}US$/',   // 9202 1000 0000 0000 0000 00
171 6
            '/^23\d{16}US$/',     // 2300 0000 0000 0000 0000
172
173
            // USPS - Tracking
174 6
            '/^94\d{20}$/',       // 9400 1000 0000 0000 0000 00
175
            '/^03\d{18}$/'        // 0300 0000 0000 0000 0000
176 6
        ];
177
178 6
        foreach ($patterns as $pattern) {
179 6
            if (preg_match($pattern, $this->trackingNumber)) {
180 1
                return true;
181
            }
182 6
        }
183
184 5
        return false;
185
    }
186
187
    /**
188
     * Create the Tracking request.
189
     *
190
     * @return string
191
     */
192 6
    private function createRequest()
193
    {
194 6
        $xml = new DOMDocument();
195 6
        $xml->formatOutput = true;
196
197 6
        $trackRequest = $xml->appendChild($xml->createElement('TrackRequest'));
198 6
        $trackRequest->setAttribute('xml:lang', 'en-US');
199
200 6
        $request = $trackRequest->appendChild($xml->createElement('Request'));
201
202 6
        $node = $xml->importNode($this->createTransactionNode(), true);
203 6
        $request->appendChild($node);
204
205 6
        $request->appendChild($xml->createElement('RequestAction', 'Track'));
206
207 6
        if (null !== $this->requestOption) {
208 6
            $request->appendChild($xml->createElement('RequestOption', $this->requestOption));
209 6
        }
210
211 6
        if (null !== $this->trackingNumber) {
212 5
            $trackRequest->appendChild($xml->createElement('TrackingNumber', $this->trackingNumber));
213 5
        }
214
215 6
        if ($this->isMailInnovations()) {
216 1
            $trackRequest->appendChild($xml->createElement('IncludeMailInnovationIndicator'));
217 1
        }
218
219 6
        if (null !== $this->referenceNumber) {
220 1
            $trackRequest->appendChild($xml->createElement('ReferenceNumber'))->appendChild($xml->createElement('Value', $this->referenceNumber));
221 1
        }
222 6
        return $xml->saveXML();
223
    }
224
225
    /**
226
     * Format the response.
227
     *
228
     * @param SimpleXMLElement $response
229
     *
230
     * @return stdClass
231
     */
232 3
    private function formatResponse(SimpleXMLElement $response)
233
    {
234 3
        return $this->convertXmlObject($response->Shipment);
235
    }
236
237
    /**
238
     * @return RequestInterface
239
     */
240 6 View Code Duplication
    public function getRequest()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
241
    {
242 6
        if (null === $this->request) {
243
            $this->request = new Request($this->logger);
244
        }
245
246 6
        return $this->request;
247
    }
248
249
    /**
250
     * @param RequestInterface $request
251
     *
252
     * @return $this
253
     */
254 6
    public function setRequest(RequestInterface $request)
255
    {
256 6
        $this->request = $request;
257
258 6
        return $this;
259
    }
260
261
    /**
262
     * @return ResponseInterface
263
     */
264 2
    public function getResponse()
265
    {
266 2
        return $this->response;
267
    }
268
269
    /**
270
     * @param ResponseInterface $response
271
     *
272
     * @return $this
273
     */
274
    public function setResponse(ResponseInterface $response)
275
    {
276
        $this->response = $response;
277
278
        return $this;
279
    }
280
}
281