Completed
Pull Request — master (#115)
by
unknown
03:23
created

Tracking::createRequest()   C

Complexity

Conditions 8
Paths 128

Size

Total Lines 47
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 8.9115

Importance

Changes 7
Bugs 1 Features 2
Metric Value
c 7
b 1
f 2
dl 0
loc 47
ccs 25
cts 33
cp 0.7576
rs 5
cc 8
eloc 26
nc 128
nop 0
crap 8.9115
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
use DateTime;
11
12
/**
13
 * Tracking API Wrapper.
14
 */
15
class Tracking extends Ups
16
{
17
    const ENDPOINT = '/Track';
18
19
    /**
20
     * @var RequestInterface
21
     */
22
    private $request;
23
24
    /**
25
     * @var ResponseInterface
26
     *                        // todo make private
27
     */
28
    public $response;
29
30
    /**
31
     * @var string
32
     */
33
    private $trackingNumber;
34
35
    /**
36
     * @var string
37
     */
38
    private $referenceNumber;
39
40
    /**
41
     * @var string
42
     */
43
    private $requestOption;
44
45
    /**
46
     * @var string
47
     */
48
    private $shipperNumber;
49
50
    /**
51
     * @var \DateTime
52
     */
53
    private $beginDate;
54
55
    /**
56
     * @var \DateTime
57
     */
58
    private $endDate;
59
60
    /**
61
     * @param string|null $accessKey UPS License Access Key
62
     * @param string|null $userId UPS User ID
63
     * @param string|null $password UPS User Password
64
     * @param bool $useIntegration Determine if we should use production or CIE URLs.
65
     * @param RequestInterface|null $request
66
     * @param LoggerInterface|null $logger PSR3 compatible logger (optional)
67
     */
68 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...
69
    {
70 6
        if (null !== $request) {
71
            $this->setRequest($request);
72
        }
73 6
        parent::__construct($accessKey, $userId, $password, $useIntegration, $logger);
74 6
    }
75
76
    /**
77
     * Get package tracking information.
78
     *
79
     * @param string $trackingNumber The package's tracking number.
80
     * @param string $requestOption Optional processing. For Mail Innovations the only valid options are Last Activity and All activity.
81
     *
82
     * @throws Exception
83
     *
84
     * @return stdClass
85
     */
86 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...
87
    {
88 5
        $this->trackingNumber = $trackingNumber;
89 5
        $this->requestOption = $requestOption;
90
91 5
        $access = $this->createAccess();
92 5
        $request = $this->createRequest();
93
94 5
        $this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
95 5
        $response = $this->response->getResponse();
96
97 5
        if (null === $response) {
98 2
            throw new Exception('Failure (0): Unknown error', 0);
99
        }
100
101 3
        if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
102
            throw new Exception(
103
                "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
104
                (int)$response->Response->Error->ErrorCode
105
            );
106
        } else {
107 3
            return $this->formatResponse($response);
108
        }
109
    }
110
111
    /**
112
     * Get package tracking information.
113
     *
114
     * @param string $referenceNumber Reference numbers can be a purchase order number, job number, etc. Reference number can be added when creating a shipment.
115
     * @param string $requestOption
116
     *
117
     * @throws Exception
118
     *
119
     * @return stdClass
120
     */
121 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...
122
    {
123 1
        $this->referenceNumber = $referenceNumber;
124 1
        $this->requestOption = $requestOption;
125
126 1
        $access = $this->createAccess();
127 1
        $request = $this->createRequest();
128
129 1
        $this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
130 1
        $response = $this->response->getResponse();
131
132 1
        if (null === $response) {
133 1
            throw new Exception('Failure (0): Unknown error', 0);
134
        }
135
136
        if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
137
            throw new Exception(
138
                "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
139
                (int)$response->Response->Error->ErrorCode
140
            );
141
        } else {
142
            return $this->formatResponse($response);
143
        }
144
    }
145
146
    /**
147
     * Set shipper number
148
     *
149
     * @param string $shipperNumber
150
     *
151
     */
152
    public function setShipperNumber($shipperNumber)
153
    {
154
        $this->shipperNumber = $shipperNumber;
155
    }
156
157
    /**
158
     * Set begin date
159
     *
160
     * @param string $beginDate
161
     *
162
     */
163
    public function setBeginDate(DateTime $beginDate)
164
    {
165
        $this->beginDate = $beginDate;
166
    }
167
168
    /**
169
     * Set end date
170
     *
171
     * @param string $endDate
172
     *
173
     */
174
    public function setEndDate(DateTime $endDate)
175
    {
176
        $this->endDate = $endDate;
177
    }
178
179
    /**
180
     * Check if tracking number is for mail innovations.
181
     *
182
     * @return bool
183
     */
184 6
    private function isMailInnovations()
185
    {
186
        $patterns = [
187
188
            // UPS Mail Innovations tracking numbers
189 6
            '/^MI\d{6}\d{1,22}$/',// MI 000000 00000000+
190
191
            // USPS - Certified Mail
192 6
            '/^94071\d{17}$/',    // 9407 1000 0000 0000 0000 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
193 6
            '/^7\d{19}$/',        // 7000 0000 0000 0000 0000
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
194
195
            // USPS - Collect on Delivery
196 6
            '/^93033\d{17}$/',    // 9303 3000 0000 0000 0000 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
197 6
            '/^M\d{9}$/',         // M000 0000 00
198
199
            // USPS - Global Express Guaranteed
200 6
            '/^82\d{10}$/',       // 82 000 000 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
201
202
            // USPS - Priority Mail Express International
203 6
            '/^EC\d{9}US$/',      // EC 000 000 000 US
204
205
            // USPS Innovations Expedited
206 6
            '/^927\d{23}$/',      // 9270 8900 8900 8900 8900 8900 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
207
            
208
            // USPS - Priority Mail Express
209 6
            '/^927\d{19}$/',      // 9270 1000 0000 0000 0000 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
210 6
            '/^EA\d{9}US$/',      // EA 000 000 000 US
211
212
            // USPS - Priority Mail International
213 6
            '/^CP\d{9}US$/',      // CP 000 000 000 US
214
215
            // USPS - Priority Mail
216 6
            '/^92055\d{17}$/',    // 9205 5000 0000 0000 0000 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
217 6
            '/^14\d{18}$/',       // 1400 0000 0000 0000 0000
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
218
219
            // USPS - Registered Mail
220 6
            '/^92088\d{17}$/',    // 9208 8000 0000 0000 0000 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
221 6
            '/^RA\d{9}US$/',      // RA 000 000 000 US
222
223
            // USPS - Signature Confirmation
224 6
            '/^9202\d{16}US$/',   // 9202 1000 0000 0000 0000 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
225 6
            '/^23\d{16}US$/',     // 2300 0000 0000 0000 0000
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
226
227
            // USPS - Tracking
228 6
            '/^94\d{20}$/',       // 9400 1000 0000 0000 0000 00
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
229
            '/^03\d{18}$/'        // 0300 0000 0000 0000 0000
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
230 6
        ];
231
232 6
        foreach ($patterns as $pattern) {
233 6
            if (preg_match($pattern, $this->trackingNumber)) {
234 1
                return true;
235
            }
236 6
        }
237
238 5
        return false;
239
    }
240
241
    /**
242
     * Create the Tracking request.
243
     *
244
     * @return string
245
     */
246 6
    private function createRequest()
247
    {
248 6
        $xml = new DOMDocument();
249 6
        $xml->formatOutput = true;
250
251 6
        $trackRequest = $xml->appendChild($xml->createElement('TrackRequest'));
252 6
        $trackRequest->setAttribute('xml:lang', 'en-US');
253
254 6
        $request = $trackRequest->appendChild($xml->createElement('Request'));
255
256 6
        $node = $xml->importNode($this->createTransactionNode(), true);
257 6
        $request->appendChild($node);
258
259 6
        $request->appendChild($xml->createElement('RequestAction', 'Track'));
260
261 6
        if (null !== $this->requestOption) {
262 6
            $request->appendChild($xml->createElement('RequestOption', $this->requestOption));
263 6
        }
264
265 6
        if (null !== $this->trackingNumber) {
266 5
            $trackRequest->appendChild($xml->createElement('TrackingNumber', $this->trackingNumber));
267 5
        }
268
269 6
        if ($this->isMailInnovations()) {
270 1
            $trackRequest->appendChild($xml->createElement('IncludeMailInnovationIndicator'));
271 1
        }
272
273 6
        if (null !== $this->referenceNumber) {
274 1
            $trackRequest->appendChild($xml->createElement('ReferenceNumber'))->appendChild($xml->createElement('Value', $this->referenceNumber));
275 1
        }
276
277 6
        if (null !== $this->shipperNumber) {
278
            $trackRequest->appendChild($xml->createElement('ShipperNumber', $this->shipperNumber));
279
        }
280
281 6
        if (null !== $this->beginDate) {
282
            $beginDate = $this->beginDate->format('Ymd');
283
            $trackRequest->appendChild($xml->createElement('BeginDate', $beginDate));
284
        }
285
286 6
        if (null !== $this->endDate) {
287
            $endDate = $this->endDate->format('Ymd');
288
            $trackRequest->appendChild($xml->createElement('EndDate', $endDate));
289
        }
290
291 6
        return $xml->saveXML();
292
    }
293
294
    /**
295
     * Format the response.
296
     *
297
     * @param SimpleXMLElement $response
298
     *
299
     * @return stdClass
300
     */
301 3
    private function formatResponse(SimpleXMLElement $response)
302
    {
303 3
        return $this->convertXmlObject($response->Shipment);
304
    }
305
306
    /**
307
     * @return RequestInterface
308
     */
309 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...
310
    {
311 6
        if (null === $this->request) {
312
            $this->request = new Request($this->logger);
313
        }
314
315 6
        return $this->request;
316
    }
317
318
    /**
319
     * @param RequestInterface $request
320
     *
321
     * @return $this
322
     */
323 6
    public function setRequest(RequestInterface $request)
324
    {
325 6
        $this->request = $request;
326
327 6
        return $this;
328
    }
329
330
    /**
331
     * @return ResponseInterface
332
     */
333 2
    public function getResponse()
334
    {
335 2
        return $this->response;
336
    }
337
338
    /**
339
     * @param ResponseInterface $response
340
     *
341
     * @return $this
342
     */
343
    public function setResponse(ResponseInterface $response)
344
    {
345
        $this->response = $response;
346
347
        return $this;
348
    }
349
}
350