Completed
Pull Request — master (#89)
by
unknown
05:12 queued 26s
created

Tracking::setRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
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
     * @var string
46
     */
47
    private $shipperNumber;
48
49
    /**
50
     * @var string
51
     */
52
    private $beginDate;
53
54
    /**
55
     * @var string
56
     */
57
    private $endDate;
58
59
    /**
60
     * @param string|null $accessKey UPS License Access Key
61
     * @param string|null $userId UPS User ID
62
     * @param string|null $password UPS User Password
63
     * @param bool $useIntegration Determine if we should use production or CIE URLs.
64
     * @param RequestInterface|null $request
65
     * @param LoggerInterface|null $logger PSR3 compatible logger (optional)
66
     */
67 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...
68
    {
69 6
        if (null !== $request) {
70
            $this->setRequest($request);
71
        }
72 6
        parent::__construct($accessKey, $userId, $password, $useIntegration, $logger);
73 6
    }
74
75
    /**
76
     * Get package tracking information.
77
     *
78
     * @param string $trackingNumber The package's tracking number.
79
     * @param string $requestOption Optional processing. For Mail Innovations the only valid options are Last Activity and All activity.
80
     *
81
     * @throws Exception
82
     *
83
     * @return stdClass
84
     */
85 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...
86
    {
87 5
        $this->trackingNumber = $trackingNumber;
88 5
        $this->requestOption = $requestOption;
89
90 5
        $access = $this->createAccess();
91 5
        $request = $this->createRequest();
92
93 5
        $this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
94 5
        $response = $this->response->getResponse();
95
96 5
        if (null === $response) {
97 2
            throw new Exception('Failure (0): Unknown error', 0);
98
        }
99
100 3
        if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
101
            throw new Exception(
102
                "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
103
                (int)$response->Response->Error->ErrorCode
104
            );
105
        } else {
106 3
            return $this->formatResponse($response);
107
        }
108
    }
109
110
    /**
111
     * Get package tracking information.
112
     *
113
     * @param string $referenceNumber Reference numbers can be a purchase order number, job number, etc. Reference number can be added when creating a shipment.
114
     * @param string $requestOption
115
     *
116
     * @throws Exception
117
     *
118
     * @return stdClass
119
     */
120 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...
121
    {
122 1
        $this->referenceNumber = $referenceNumber;
123 1
        $this->requestOption = $requestOption;
124
125 1
        $access = $this->createAccess();
126 1
        $request = $this->createRequest();
127
128 1
        $this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
129 1
        $response = $this->response->getResponse();
130
131 1
        if (null === $response) {
132 1
            throw new Exception('Failure (0): Unknown error', 0);
133
        }
134
135
        if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
136
            throw new Exception(
137
                "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
138
                (int)$response->Response->Error->ErrorCode
139
            );
140
        } else {
141
            return $this->formatResponse($response);
142
        }
143
    }
144
145
    /**
146
     * Set shipper number
147
     *
148
     * @param string $shipperNumber
149
     *
150
     */
151
    public function setShipperNumber($shipperNumber)
152
    {
153
        $this->shipperNumber = $shipperNumber;
154
    }
155
156
    /**
157
     * Set begin date
158
     *
159
     * @param string $beginDate
160
     *
161
     */
162
    public function setBeginDate($beginDate)
163
    {
164
        $this->beginDate = $beginDate;
165
    }
166
167
    /**
168
     * Set end date
169
     *
170
     * @param string $endDate
171
     *
172
     */
173
    public function setEndDate($endDate)
174
    {
175
        $this->endDate = $endDate;
176
    }
177
178
    /**
179
     * Check if tracking number is for mail innovations.
180
     *
181
     * @return bool
182
     */
183 6
    private function isMailInnovations()
184
    {
185
        $patterns = [
186
187
            // UPS Mail Innovations tracking numbers
188 6
            '/^MI\d{6}\d{1,22}$/',// MI 000000 00000000+
189
190
            // USPS - Certified Mail
191 6
            '/^94071\d{17}$/',    // 9407 1000 0000 0000 0000 00
192 6
            '/^7\d{19}$/',        // 7000 0000 0000 0000 0000
193
194
            // USPS - Collect on Delivery
195 6
            '/^93033\d{17}$/',    // 9303 3000 0000 0000 0000 00
196 6
            '/^M\d{9}$/',         // M000 0000 00
197
198
            // USPS - Global Express Guaranteed
199 6
            '/^82\d{10}$/',       // 82 000 000 00
200
201
            // USPS - Priority Mail Express International
202 6
            '/^EC\d{9}US$/',      // EC 000 000 000 US
203
204
            // USPS - Priority Mail Express
205 6
            '/^927\d{19}$/',      // 9270 1000 0000 0000 0000 00
206 6
            '/^EA\d{9}US$/',      // EA 000 000 000 US
207
208
            // USPS - Priority Mail International
209 6
            '/^CP\d{9}US$/',      // CP 000 000 000 US
210
211
            // USPS - Priority Mail
212 6
            '/^92055\d{17}$/',    // 9205 5000 0000 0000 0000 00
213 6
            '/^14\d{18}$/',       // 1400 0000 0000 0000 0000
214
215
            // USPS - Registered Mail
216 6
            '/^92088\d{17}$/',    // 9208 8000 0000 0000 0000 00
217 6
            '/^RA\d{9}US$/',      // RA 000 000 000 US
218
219
            // USPS - Signature Confirmation
220 6
            '/^9202\d{16}US$/',   // 9202 1000 0000 0000 0000 00
221 6
            '/^23\d{16}US$/',     // 2300 0000 0000 0000 0000
222
223
            // USPS - Tracking
224 6
            '/^94\d{20}$/',       // 9400 1000 0000 0000 0000 00
225
            '/^03\d{18}$/'        // 0300 0000 0000 0000 0000
226 6
        ];
227
228 6
        foreach ($patterns as $pattern) {
229 6
            if (preg_match($pattern, $this->trackingNumber)) {
230 1
                return true;
231
            }
232 6
        }
233
234 5
        return false;
235
    }
236
237
    /**
238
     * Create the Tracking request.
239
     *
240
     * @return string
241
     */
242 6
    private function createRequest()
243
    {
244 6
        $xml = new DOMDocument();
245 6
        $xml->formatOutput = true;
246
247 6
        $trackRequest = $xml->appendChild($xml->createElement('TrackRequest'));
248 6
        $trackRequest->setAttribute('xml:lang', 'en-US');
249
250 6
        $request = $trackRequest->appendChild($xml->createElement('Request'));
251
252 6
        $node = $xml->importNode($this->createTransactionNode(), true);
253 6
        $request->appendChild($node);
254
255 6
        $request->appendChild($xml->createElement('RequestAction', 'Track'));
256
257 6
        if (null !== $this->requestOption) {
258 6
            $request->appendChild($xml->createElement('RequestOption', $this->requestOption));
259 6
        }
260
261 6
        if (null !== $this->trackingNumber) {
262 5
            $trackRequest->appendChild($xml->createElement('TrackingNumber', $this->trackingNumber));
263 5
        }
264
265 6
        if ($this->isMailInnovations()) {
266 1
            $trackRequest->appendChild($xml->createElement('IncludeMailInnovationIndicator'));
267 1
        }
268
269 6
        if (null !== $this->referenceNumber) {
270 1
            $trackRequest->appendChild($xml->createElement('ReferenceNumber'))->appendChild($xml->createElement('Value', $this->referenceNumber));
271 1
        }
272
273 6
        if (null !== $this->shipperNumber) {
274
            $trackRequest->appendChild($xml->createElement('ShipperNumber', $this->shipperNumber));
275
        }
276
277 6
        if (null !== $this->beginDate) {
278
            $trackRequest->appendChild($xml->createElement('BeginDate', $this->beginDate));
279
        }
280
281 6
        if (null !== $this->endDate) {
282
            $trackRequest->appendChild($xml->createElement('EndDate', $this->endDate));
283
        }
284
285 6
        return $xml->saveXML();
286
    }
287
288
    /**
289
     * Format the response.
290
     *
291
     * @param SimpleXMLElement $response
292
     *
293
     * @return stdClass
294
     */
295 3
    private function formatResponse(SimpleXMLElement $response)
296
    {
297 3
        return $this->convertXmlObject($response->Shipment);
298
    }
299
300
    /**
301
     * @return RequestInterface
302
     */
303 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...
304
    {
305 6
        if (null === $this->request) {
306
            $this->request = new Request($this->logger);
307
        }
308
309 6
        return $this->request;
310
    }
311
312
    /**
313
     * @param RequestInterface $request
314
     *
315
     * @return $this
316
     */
317 6
    public function setRequest(RequestInterface $request)
318
    {
319 6
        $this->request = $request;
320
321 6
        return $this;
322
    }
323
324
    /**
325
     * @return ResponseInterface
326
     */
327 2
    public function getResponse()
328
    {
329 2
        return $this->response;
330
    }
331
332
    /**
333
     * @param ResponseInterface $response
334
     *
335
     * @return $this
336
     */
337
    public function setResponse(ResponseInterface $response)
338
    {
339
        $this->response = $response;
340
341
        return $this;
342
    }
343
}
344