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