Completed
Push — master ( ba6641...734696 )
by Hamoud
27:01 queued 12:22
created

Smsa   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 513
Duplicated Lines 25.73 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 0
Metric Value
wmc 44
lcom 1
cbo 14
dl 132
loc 513
rs 8.3396
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 1
A cities() 16 16 2
A retailsIn() 16 16 2
A retails() 16 16 2
B track() 0 28 4
A trackByReference() 0 22 3
B status() 26 26 5
B cancel() 26 26 5
A createShipment() 0 20 3
A awbPDF() 0 18 2
A parseCityResult() 0 14 2
A parseRetailsResult() 0 21 3
A parseTrackResult() 0 19 2
A successResponse() 14 14 1
A failedRequest() 0 21 2
A failedResponse() 18 18 2
A shouldUseExceptions() 0 4 1
A throwRequestError() 0 11 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Smsa often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Smsa, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of Smsa WebService package.
5
 * (c) Hamoud Alhoqbani <[email protected]>
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Alhoqbani\SmsaWebService;
11
12
use Alhoqbani\SmsaWebService\Exceptions\FailedResponse;
13
use Alhoqbani\SmsaWebService\Exceptions\RequestError;
14
use Alhoqbani\SmsaWebService\Models\Shipment;
15
use Alhoqbani\SmsaWebService\Response\SMSAResponse;
16
use Alhoqbani\SmsaWebService\Soap\ClassMap;
17
use Alhoqbani\SmsaWebService\Soap\Service;
18
use Alhoqbani\SmsaWebService\Soap\Type\CancelShipment;
19
use Alhoqbani\SmsaWebService\Soap\Type\GetAllRetails;
20
use Alhoqbani\SmsaWebService\Soap\Type\GetPDF;
21
use Alhoqbani\SmsaWebService\Soap\Type\GetRTLCities;
22
use Alhoqbani\SmsaWebService\Soap\Type\GetRTLRetails;
23
use Alhoqbani\SmsaWebService\Soap\Type\GetStatus;
24
use Alhoqbani\SmsaWebService\Soap\Type\GetTrackingByRef;
25
use Alhoqbani\SmsaWebService\Soap\Type\GetTrackingwithRef;
26
use WsdlToPhp\PackageBase\AbstractSoapClientBase;
27
use WsdlToPhp\PackageBase\AbstractStructBase;
28
29
class Smsa
30
{
31
32
    /**
33
     * Weather to throw exceptions when there is a request error or a failed response from SMSA.
34
     *
35
     * @var bool
36
     */
37
    public $shouldUseExceptions = true;
38
39
    /**
40
     * @var \Alhoqbani\SmsaWebService\Soap\Service
41
     */
42
    protected $service;
43
44
    /**
45
     * @var string
46
     */
47
    private $passKey;
48
49
    /**
50
     * Create a new Smsa Instance
51
     *
52
     * @param string                 $passKey The pass key to the api provided by Smsa.
53
     * @param array|null             $options WSDL option to be passed to SoapClient.
54
     * @param AbstractSoapClientBase $service The service which provide SMSA api methods.
55
     */
56
    public function __construct(
57
        string $passKey = 'Testing0',
58
        array $options = [],
59
        AbstractSoapClientBase $service = null
60
    ) {
61
        $this->passKey = $passKey;
62
63
        $options = array_merge([
64
            AbstractSoapClientBase::WSDL_URL      => 'http://track.smsaexpress.com/SECOM/SMSAwebService.asmx?WSDL',
65
            AbstractSoapClientBase::WSDL_CLASSMAP => ClassMap::get(),
66
        ], $options);
67
68
        $this->service = $service ?? new Service($options);
0 ignored issues
show
Documentation Bug introduced by
$service ?? new \Alhoqba...\Soap\Service($options) is of type object<WsdlToPhp\Package...AbstractSoapClientBase>, but the property $service was declared to be of type object<Alhoqbani\SmsaWebService\Soap\Service>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
69
    }
70
71
    /**
72
     * Fetch all cities that has SMSAExpress locations
73
     *
74
     * @throws RequestError
75
     *
76
     * @return SMSAResponse with array of cities with their route code.
77
     */
78 View Code Duplication
    public function cities(): SMSAResponse
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...
79
    {
80
        $result = $this->service->getRTLCities(
81
            $payload = new GetRTLCities($this->passKey)
82
        );
83
84
        if (false === $result) {
85
            return $this->failedRequest('getRTLCities', $payload);
86
        }
87
88
        return $this->successResponse(
89
            'getRTLCities',
90
            $payload,
91
            $this->parseCityResult($result->getGetRTLCitiesResult()->getAny())
0 ignored issues
show
Bug introduced by
The method getGetRTLCitiesResult does only exist in Alhoqbani\SmsaWebService...pe\GetRTLCitiesResponse, but not in Alhoqbani\SmsaWebService...ype\StoShipmentResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
92
        );
93
    }
94
95
    /**
96
     * Fetch all retails in a particular city.
97
     * The city code is the three letters route code
98
     * For example: RUH, JED
99
     *
100
     * @param $cityCode
101
     *
102
     * @throws RequestError
103
     *
104
     * @return SMSAResponse with array of retails in given city.
105
     */
106 View Code Duplication
    public function retailsIn($cityCode): SMSAResponse
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...
107
    {
108
        $result = $this->service->getRTLRetails(
109
            $payload = new GetRTLRetails($cityCode, $this->passKey)
110
        );
111
112
        if (false === $result) {
113
            return $this->failedRequest('getRTLCities', $payload);
114
        }
115
116
        return $this->successResponse(
117
            'getRTLCities',
118
            $payload,
119
            $this->parseRetailsResult($result->getGetRTLRetailsResult()->getAny())
0 ignored issues
show
Bug introduced by
The method getGetRTLRetailsResult does only exist in Alhoqbani\SmsaWebService...e\GetRTLRetailsResponse, but not in Alhoqbani\SmsaWebService...ype\StoShipmentResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
120
        );
121
    }
122
123
    /**
124
     * Fetch all Smsa Express retails
125
     *
126
     * @throws RequestError
127
     *
128
     * @return SMSAResponse with list of all retails with details
129
     */
130 View Code Duplication
    public function retails(): SMSAResponse
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...
131
    {
132
        $result = $this->service->getAllRetails(
133
            $payload = new GetAllRetails($this->passKey)
134
        );
135
136
        if (false === $result) {
137
            return $this->failedRequest('getAllRetails', $payload);
138
        }
139
140
        return $this->successResponse(
141
            'getAllRetails',
142
            $payload,
143
            $this->parseRetailsResult($result->getGetAllRetailsResult()->getAny())
0 ignored issues
show
Bug introduced by
The method getGetAllRetailsResult does only exist in Alhoqbani\SmsaWebService...e\GetAllRetailsResponse, but not in Alhoqbani\SmsaWebService...ype\StoShipmentResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
144
        );
145
    }
146
147
    /**
148
     * Track a shipment by its awb
149
     *
150
     * @param $awb
151
     *
152
     * @throws \Alhoqbani\SmsaWebService\Exceptions\RequestError
153
     * @throws \Alhoqbani\SmsaWebService\Exceptions\FailedResponse
154
     *
155
     * @return SMSAResponse
156
     */
157
    public function track($awb): SMSAResponse
158
    {
159
        $result = $this->service->getTrackingwithRef(
160
            $payload = new GetTrackingwithRef($awb, $this->passKey)
161
        );
162
163
        if (false === $result) {
164
            return $this->failedRequest('GetTrackingwithRef', $payload);
165
        }
166
167
        $result = $result->getGetTrackingwithRefResult();
0 ignored issues
show
Bug introduced by
The method getGetTrackingwithRefResult does only exist in Alhoqbani\SmsaWebService...TrackingwithRefResponse, but not in Alhoqbani\SmsaWebService...ype\StoShipmentResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
168
169
        if (is_null($result)) {
170
            return $this->failedResponse('GetTrackingwithRef', $payload, 'The awb provided is not correct.');
171
        }
172
173
        $track = $this->parseTrackResult($result->getAny());
174
175
        if (empty($track)) {
176
            return $this->failedResponse('GetTrackingwithRef', $payload, 'No shipment with provided awb.');
177
        }
178
179
        return $this->successResponse(
180
            'GetTrackingwithRef',
181
            $payload,
182
            $track
183
        );
184
    }
185
186
    /**
187
     * Get the real-time tracking information of the shipment
188
     *
189
     * @param string $reference Customer reference number
190
     *
191
     * @todo This is not working
192
     *
193
     * @throws FailedResponse
194
     * @throws RequestError
195
     *
196
     * @return SMSAResponse
197
     */
198
    public function trackByReference(string $reference)
199
    {
200
        $result = $this->service->getTrackingByRef(
201
            $payload = new GetTrackingByRef($reference, $this->passKey)
202
        );
203
204
        if (false === $result) {
205
            return $this->failedRequest('GetTrackingwithRef', $payload);
206
        }
207
208
        $data = $result->getGetTrackingByRefResult();
0 ignored issues
show
Bug introduced by
The method getGetTrackingByRefResult does only exist in Alhoqbani\SmsaWebService...etTrackingByRefResponse, but not in Alhoqbani\SmsaWebService...ype\StoShipmentResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
209
210
        if (is_null($data)) {
211
            return $this->failedResponse('GetTrackingwithRef', $payload, 'Shipment was not found');
212
        }
213
214
        return $this->successResponse(
215
            'GetTrackingwithRef',
216
            $payload,
217
            $data->getAny()
218
        );
219
    }
220
221
    /**
222
     * @param $awb
223
     *
224
     * @throws FailedResponse
225
     * @throws RequestError
226
     *
227
     * @return SMSAResponse
228
     */
229 View Code Duplication
    public function status($awb): SMSAResponse
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...
230
    {
231
        $result = $this->service->getStatus(
232
            $payload = new GetStatus($awb, $this->passKey)
233
        );
234
235
        if (false === $result) {
236
            return $this->failedRequest('GetStatus', $payload);
237
        }
238
239
        $status = $result->getGetStatusResult();
0 ignored issues
show
Bug introduced by
The method getGetStatusResult does only exist in Alhoqbani\SmsaWebService...\Type\GetStatusResponse, but not in Alhoqbani\SmsaWebService...ype\StoShipmentResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
240
241
        if (empty($status) || is_null($status)) {
242
            return $this->failedResponse('GetStatus', $payload, 'No status, shipment was not found');
243
        }
244
245
        if (0 === strpos(mb_strtolower($status), 'failed')) {
246
            return $this->failedResponse('GetStatus', $payload, $status);
247
        }
248
249
        return $this->successResponse(
250
            'GetStatus',
251
            $payload,
252
            $status
253
        );
254
    }
255
256
    /**
257
     * Cancel a shipment by AWB
258
     *
259
     * @param $awb string
260
     * @param $reason string
261
     *
262
     * @throws FailedResponse
263
     * @throws RequestError
264
     *
265
     * @return SMSAResponse
266
     */
267 View Code Duplication
    public function cancel($awb, $reason): SMSAResponse
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...
268
    {
269
        $result = $this->service->cancelShipment(
270
            $payload = new CancelShipment($awb, $this->passKey, $reason)
271
        );
272
273
        if (false === $result) {
274
            return $this->failedRequest('CancelShipment', $payload);
275
        }
276
277
        $data = $result->getCancelShipmentResult();
0 ignored issues
show
Bug introduced by
The method getCancelShipmentResult does only exist in Alhoqbani\SmsaWebService...\CancelShipmentResponse, but not in Alhoqbani\SmsaWebService...ype\StoShipmentResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
278
279
        if (empty($data) || is_null($data)) {
280
            return $this->failedResponse('CancelShipment', $payload, 'Cannot Cancel, shipment was not found');
281
        }
282
283
        if (0 === strpos(mb_strtolower($data), 'failed')) {
284
            return $this->failedResponse('CancelShipment', $payload, $data);
285
        }
286
287
        return $this->successResponse(
288
            'CancelShipment',
289
            $payload,
290
            $data
291
        );
292
    }
293
294
    /**
295
     * Create a new shipment
296
     *
297
     * @param Shipment $shipment
298
     *
299
     * @throws FailedResponse
300
     * @throws RequestError
301
     *
302
     * @return SMSAResponse
303
     */
304
    public function createShipment(Shipment $shipment): SMSAResponse
305
    {
306
        $payload = $shipment->getTypeObject($this->passKey);
307
308
        $method = $shipment->getServiceMethod();
309
310
        $result = call_user_func([$this->service, $method], $payload);
311
312
        if (false === $result) {
313
            return $this->failedRequest($method, $payload);
314
        }
315
316
        $data = $result->{"get{$method}Result"}();
317
318
        if (0 === strpos(mb_strtolower($data), 'failed')) {
319
            return $this->failedResponse($method, $payload, $data);
320
        }
321
322
        return $this->successResponse($method, $payload, $data);
323
    }
324
325
    /**
326
     * Get AWB in PDF for printing
327
     * This method can be used to get the AWB Copy in PDF format for printing and labeling on shipment.
328
     *
329
     * @param $awb string
330
     *
331
     * @throws RequestError
332
     *
333
     * @return SMSAResponse
334
     */
335
    public function awbPDF(string $awb): SMSAResponse
336
    {
337
        $result = $this->service->getPDF(
338
            $payload = new GetPDF($awb, $passKey ?? $this->passKey)
339
        );
340
341
        if (false === $result) {
342
            return $this->failedRequest('GetPDF', $payload);
343
        }
344
345
        $data = $result->getGetPDFResult();
0 ignored issues
show
Bug introduced by
The method getGetPDFResult does only exist in Alhoqbani\SmsaWebService\Soap\Type\GetPDFResponse, but not in Alhoqbani\SmsaWebService...ype\StoShipmentResponse.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
346
347
        return $this->successResponse(
348
            'GetPDF',
349
            $payload,
350
            $data
351
        );
352
    }
353
354
    /**
355
     * Parse the cities xml response into array
356
     *
357
     * @param string $citiesResult
358
     *
359
     * @return array Array of cities with its names and route code
360
     */
361
    protected function parseCityResult(string $citiesResult): array
362
    {
363
        $xml = simplexml_load_string($citiesResult);
364
        $cities = [];
365
366
        foreach ($xml->NewDataSet[0]->RetailCities as $city) {
367
            $cities[] = [
368
                'name'      => (string) $city->rCity,
369
                'routeCode' => (string) $city->routCode,
370
            ];
371
        }
372
373
        return $cities;
374
    }
375
376
    /**
377
     * Parse retails xml response into an array
378
     *
379
     * @param string $retailsResult
380
     *
381
     * @return array array of retails with their details
382
     */
383
    private function parseRetailsResult(string $retailsResult): array
384
    {
385
        $xml = simplexml_load_string($retailsResult);
386
        $retails = [];
387
388
        if ($xml->count() > 0) {
389
            foreach ($xml->NewDataSet[0]->RetailsList as $retail) {
390
                $retails[] = [
391
                    'code'       => (string) $retail->rCode,
392
                    'route_code' => (string) $retail->routCode,
393
                    'city'       => (string) $retail->rCity,
394
                    'address_en' => (string) $retail->rAddrEng,
395
                    'address_ar' => (string) $retail->rAddrAr,
396
                    'gps_point'  => (string) $retail->rGPSPt,
397
                    'phone'      => (string) $retail->rPhone,
398
                ];
399
            }
400
        }
401
402
        return $retails;
403
    }
404
405
    /**
406
     * Parse a tracking xml response
407
     *
408
     * @param string $result
409
     *
410
     * @return array Details of the tracking
411
     */
412
    private function parseTrackResult(string $result): array
413
    {
414
        $xml = simplexml_load_string($result);
415
416
        if ($xml->count() > 0) {
417
            $track = $xml->NewDataSet[0]->Tracking;
418
419
            return [
420
                'awb'       => (string) $track->awbNo,
421
                'date'      => (string) $track->Date,
422
                'activity'  => (string) $track->Activity,
423
                'details'   => (string) $track->Details,
424
                'location'  => (string) $track->Location,
425
                'reference' => (string) $track->refNo,
426
            ];
427
        }
428
429
        return [];
430
    }
431
432
    /**
433
     * Return a successful response with the data.
434
     *
435
     * @param $type string The type/function of the SOAP Api used.
436
     * @param $payload AbstractStructBase The object that was sent to the SoapClient
437
     * @param $data mixed
438
     *
439
     * @return SMSAResponse
440
     */
441 View Code Duplication
    protected function successResponse($type, $payload, $data): SMSAResponse
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...
442
    {
443
        $response = new SMSAResponse(
444
            true,
445
            $data,
446
            null,
447
            $type,
448
            $payload,
449
            $this->service->getLastRequest(true),
450
            $this->service->getLastResponse(true)
451
        );
452
453
        return $response;
454
    }
455
456
    /**
457
     * Send a Response with failed request.
458
     *
459
     * @param $type string The type/function of the SOAP Api used.
460
     * @param $payload AbstractStructBase The object that was sent to the SoapClient
461
     *
462
     * @throws \Alhoqbani\SmsaWebService\Exceptions\RequestError
463
     *
464
     * @return SMSAResponse
465
     */
466
    protected function failedRequest($type, $payload)
467
    {
468
        $errors = $this->service->getLastError();
469
        $error = array_shift($errors);
470
471
        $response = new SMSAResponse(
472
            false,
473
            null,
474
            $error,
475
            $type,
476
            $payload,
477
            $this->service->getLastRequest(true),
478
            $this->service->getLastResponse(true)
479
        );
480
481
        if ($this->shouldUseExceptions()) {
482
            $this->throwRequestError($response);
483
        }
484
485
        return $response;
486
    }
487
488
    /**
489
     * Return a failed response. (Usually, wrong data was sent to SMSA Api)
490
     *
491
     * @param $type string The type/function of the SOAP Api used
492
     * @param $payload AbstractStructBase The object that was sent to the SoapClient
493
     * @param $error string The error message from SMSA.
494
     *
495
     * @throws FailedResponse
496
     *
497
     * @return SMSAResponse
498
     */
499 View Code Duplication
    protected function failedResponse($type, $payload, $error)
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...
500
    {
501
        $response = new SMSAResponse(
502
            false,
503
            null,
504
            $error,
505
            $type,
506
            $payload,
507
            $this->service->getLastRequest(true),
508
            $this->service->getLastResponse(true)
509
        );
510
511
        if ($this->shouldUseExceptions()) {
512
            throw new FailedResponse($response, $error);
513
        }
514
515
        return $response;
516
    }
517
518
    protected function shouldUseExceptions()
519
    {
520
        return $this->shouldUseExceptions;
521
    }
522
523
    /**
524
     * To handle response error from Smsa Soap server
525
     *
526
     * @param SMSAResponse $response
527
     *
528
     * @throws RequestError
529
     */
530
    protected function throwRequestError(SMSAResponse $response): void
531
    {
532
        $errors = $this->service->getLastError();
533
        $soapFault = array_shift($errors);
534
535
        if ($soapFault instanceof \SoapFault) {
536
            throw new RequestError($response, $soapFault->faultstring, $soapFault->getCode(), $soapFault);
0 ignored issues
show
Bug introduced by
The property faultstring does not seem to exist. Did you mean string?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
537
        }
538
539
        throw new RequestError($response, 'Smsa request failed with unknown error');
540
    }
541
}
542