Completed
Push — develop ( a52dc0...a8f9d1 )
by Dieter
05:20
created

Base   D

Complexity

Total Complexity 96

Size/Duplication

Total Lines 924
Duplicated Lines 18.18 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 13
Bugs 3 Features 5
Metric Value
wmc 96
c 13
b 3
f 5
lcom 1
cbo 5
dl 168
loc 924
rs 4.4444

42 Methods

Rating   Name   Duplication   Size   Complexity  
A analyzeResponse() 0 14 3
A analyzeSecurityAuthenticateResponse() 0 4 1
A analyzeSecuritySignOutResponse() 0 4 1
A analyzeCommandCrypticResponse() 0 10 1
B analyzeAirSellFromRecommendationResponse() 0 27 4
B analyzeAirFlightInfoResponse() 0 30 6
B analyzeAirRetrieveSeatMapResponse() 50 65 7
A analyzePnrRetrieveResponse() 0 4 1
A analyzePnrAddMultiElementsResponse() 0 4 1
A analyzePnrCancelResponse() 0 4 1
A analyzePnrReply() 28 57 4
A analyzePnrRetrieveAndDisplayResponse() 0 4 1
A analyzePnrDisplayHistoryResponse() 9 23 2
A analyzeQueueRemoveItemResponse() 0 4 1
A analyzeQueueMoveItemResponse() 0 4 1
A analyzeQueuePlacePNRResponse() 0 4 1
A analyzeQueueListResponse() 0 4 1
A analyzeGenericQueueResponse() 0 19 2
B analyzeFarePricePNRWithBookingClassResponse() 0 30 3
B analyzeFareMasterPricerTravelBoardSearchResponse() 0 28 3
A analyzeFareConvertCurrencyResponse() 0 4 1
A analyzeFareCheckRulesResponse() 0 4 1
A analyzeFareInformativePricingWithoutPNRResponse() 0 4 1
A analyzeDocIssuanceIssueTicketResponse() 0 4 1
B analyzeTicketCreateTSTFromPricingResponse() 27 27 3
A analyzeOfferConfirmCarOfferResponse() 0 4 1
B analyzeOfferConfirmHotelOfferResponse() 0 25 3
A analyzeOfferConfirmAirOfferResponse() 0 4 1
A analyzeOfferVerifyOfferResponse() 0 4 1
B analyzeGenericOfferResponse() 0 32 5
B analyzeMiniRuleGetFromPricingRecResponse() 0 28 5
A analyzeInfoEncodeDecodeCityResponse() 0 4 1
A analyzePriceXplorerExtremeSearchResponse() 0 4 1
B analyzeSimpleResponseErrorCodeAndMessage() 27 27 3
B analyzeSimpleResponseErrorCodeAndMessageStatusCode() 27 27 3
B getErrorTextFromQueueErrorCode() 0 24 3
A loadDomDocument() 0 11 2
D makeStatusFromErrorQualifier() 0 28 9
A makeDomXpath() 0 12 1
A makeMessageFromMessagesNodeList() 0 12 1
A makeResultForException() 0 8 1
A makeMessageFromException() 0 15 3

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 Base 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 Base, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * amadeus-ws-client
4
 *
5
 * Copyright 2015 Amadeus Benelux NV
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 * http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 *
19
 * @package Amadeus
20
 * @license https://opensource.org/licenses/Apache-2.0 Apache 2.0
21
 */
22
23
namespace Amadeus\Client\ResponseHandler;
24
25
use Amadeus\Client\Exception;
26
use Amadeus\Client\ResponseHandler\Air\RetrieveSeatMap;
27
use Amadeus\Client\Result;
28
use Amadeus\Client\Session\Handler\SendResult;
29
30
/**
31
 * Default Response Handler
32
 *
33
 * @package Amadeus\Client\ResponseHandler
34
 * @author Dieter Devlieghere <[email protected]>
35
 */
36
class Base implements ResponseHandlerInterface
37
{
38
    /**
39
     * Default namespace prefix we'll be using for xpath queries
40
     *
41
     * Why not "m"? It's as good as any other letter.
42
     */
43
    const XMLNS_PREFIX = "m";
44
45
    /**
46
     * Analyze the response from the server and throw an exception when an error has been detected.
47
     *
48
     * @param SendResult $sendResult The Send Result from the Session Handler
49
     * @param string $messageName The message that was called
50
     *
51
     * @throws Exception
52
     * @throws \RuntimeException
53
     * @return Result
54
     */
55
    public function analyzeResponse($sendResult, $messageName)
56
    {
57
        $methodName = 'analyze' . str_replace('_', '', ucfirst($messageName)) . 'Response';
58
59
        if (!empty($sendResult->exception)) {
60
            return $this->makeResultForException($sendResult);
61
        } elseif (method_exists($this, $methodName)) {
62
            return $this->$methodName(
63
                $sendResult
64
            );
65
        } else {
66
            return new Result($sendResult, Result::STATUS_UNKNOWN);
67
        }
68
    }
69
70
    /**
71
     * Analysing a Security_Authenticate
72
     *
73
     * @param SendResult $response Security_Authenticate result
74
     * @return Result
75
     */
76
    protected function analyzeSecurityAuthenticateResponse($response)
77
    {
78
        return $this->analyzeSimpleResponseErrorCodeAndMessage($response);
79
    }
80
81
    /**
82
     * Analysing a Security_Authenticate
83
     *
84
     * @param SendResult $response Security_Authenticate result
85
     * @return Result
86
     */
87
    protected function analyzeSecuritySignOutResponse($response)
88
    {
89
        return $this->analyzeSimpleResponseErrorCodeAndMessage($response);
90
    }
91
92
    /**
93
     * Unknown response for Command_Cryptic because you need to analyse the cryptic response yourself
94
     *
95
     * @param SendResult $response
96
     * @return Result
97
     */
98
    protected function analyzeCommandCrypticResponse($response)
99
    {
100
        $ccResult = new Result($response, Result::STATUS_UNKNOWN);
101
        $ccResult->messages[] = new Result\NotOk(
102
            0,
103
            "Response handling not supported for cryptic entries"
104
        );
105
106
        return $ccResult;
107
    }
108
109
    protected function analyzeAirSellFromRecommendationResponse($response)
110
    {
111
        $analyzeResponse = new Result($response);
112
113
        $errMsgMap = [
114
            "288" => "UNABLE TO SATISFY, NEED CONFIRMED FLIGHT STATUS",
115
            "390" => "UNABLE TO REFORMAT"
116
        ];
117
118
        $domXpath = $this->makeDomXpath($response->responseXml);
119
120
        $codeNode = $domXpath->query("//m:errorSegment/m:errorDetails/m:errorCode")->item(0);
121
        if ($codeNode instanceof \DOMNode) {
122
            $analyzeResponse->status = Result::STATUS_ERROR;
123
124
            $categoryNode = $domXpath->query("//m:errorSegment/m:errorDetails/m:errorCategory")->item(0);
125
            if ($categoryNode instanceof \DOMNode) {
126
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($categoryNode->nodeValue);
127
            }
128
129
            $message = (array_key_exists($codeNode->nodeValue, $errMsgMap)) ? $errMsgMap[$codeNode->nodeValue] : 'UNKNOWN ERROR';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 129 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
130
131
            $analyzeResponse->messages [] = new Result\NotOk($codeNode->nodeValue, $message);
132
        }
133
134
        return $analyzeResponse;
135
    }
136
137
    /**
138
     * @param SendResult $response
139
     * @return Result
140
     */
141
    protected function analyzeAirFlightInfoResponse($response)
142
    {
143
        $analyzeResponse = new Result($response);
144
145
        $code = null;
146
        $message = null;
147
148
        $domXpath = $this->makeDomXpath($response->responseXml);
149
150
        $categoryNodes = $domXpath->query('//m:responseError/m:errorInfo/m:errorDetails/m:errorCategory');
151
        if ($categoryNodes->length > 0) {
152
            $analyzeResponse->status = $this->makeStatusFromErrorQualifier($categoryNodes->item(0)->nodeValue);
153
        }
154
155
        $codeNodes = $domXpath->query('//m:responseError/m:errorInfo/m:errorDetails/m:errorCode');
156
        if ($codeNodes->length > 0) {
157
            $code = $codeNodes->item(0)->nodeValue;
158
        }
159
160
        $messageNodes = $domXpath->query('//m:responseError/m:interactiveFreeText/m:freeText');
161
        if ($messageNodes->length > 0) {
162
            $message = $this->makeMessageFromMessagesNodeList($messageNodes);
163
        }
164
165
        if (!is_null($message) && !is_null($code)) {
166
            $analyzeResponse->messages[] = new Result\NotOk($code, $message);
167
        }
168
169
        return $analyzeResponse;
170
    }
171
172
    /**
173
     * @param SendResult $response
174
     * @return Result
175
     */
176
    protected function analyzeAirRetrieveSeatMapResponse($response)
177
    {
178
        $analyzeResponse = new Result($response);
179
180
        $code = null;
0 ignored issues
show
Unused Code introduced by
$code is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
181
        $message = null;
0 ignored issues
show
Unused Code introduced by
$message is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
182
183
        $domXpath = $this->makeDomXpath($response->responseXml);
184
185
        $errorCodeNode = $domXpath->query('//m:errorInformation/m:errorDetails/m:code');
186 View Code Duplication
        if ($errorCodeNode->length > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
187
            $analyzeResponse->status = Result::STATUS_ERROR;
188
189
            $errCode = $errorCodeNode->item(0)->nodeValue;
190
            $level = null;
191
            $errDesc = null;
0 ignored issues
show
Unused Code introduced by
$errDesc is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
192
193
            $errorLevelNode = $domXpath->query('//m:errorInformation/m:errorDetails/m:processingLevel');
194
            if ($errorLevelNode->length > 0) {
195
                $level = RetrieveSeatMap::decodeProcessingLevel($errorLevelNode->item(0)->nodeValue);
196
            }
197
198
            $errorDescNode = $domXpath->query('//m:errorInformation/m:errorDetails/m:description');
199
            if ($errorDescNode->length > 0) {
200
                $errDesc = $errorDescNode->item(0)->nodeValue;
201
            } else {
202
                $errDesc = RetrieveSeatMap::findMessage($errCode);
203
            }
204
205
            $analyzeResponse->messages[] = new Result\NotOk(
206
                $errCode,
207
                $errDesc,
208
                $level
209
            );
210
        }
211
212
        $codeNode = $domXpath->query('//m:warningInformation/m:warningDetails/m:number');
213 View Code Duplication
        if ($codeNode->length > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
214
            $analyzeResponse->status = Result::STATUS_WARN;
215
216
            $warnCode = $codeNode->item(0)->nodeValue;
217
            $level = null;
218
            $warnDesc = null;
0 ignored issues
show
Unused Code introduced by
$warnDesc is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
219
220
            $levelNode = $domXpath->query('//m:warningInformation/m:warningDetails/m:processingLevel');
221
            if ($levelNode->length > 0) {
222
                $level = RetrieveSeatMap::decodeProcessingLevel($levelNode->item(0)->nodeValue);
223
            }
224
225
            $descNode = $domXpath->query('//m:warningInformation/m:warningDetails/m:description');
226
            if ($descNode->length > 0) {
227
                $warnDesc = $descNode->item(0)->nodeValue;
228
            } else {
229
                $warnDesc = RetrieveSeatMap::findMessage($warnCode);
230
            }
231
232
            $analyzeResponse->messages[] = new Result\NotOk(
233
                $warnCode,
234
                $warnDesc,
235
                $level
236
            );
237
        }
238
239
        return $analyzeResponse;
240
    }
241
242
    /**
243
     * Analysing a PNR_Retrieve response
244
     *
245
     * @param SendResult $response PNR_Retrieve result
246
     * @return Result
247
     */
248
    protected function analyzePnrRetrieveResponse($response)
249
    {
250
        return $this->analyzePnrReply($response);
251
    }
252
253
    /**
254
     * @param SendResult $response PNR_AddMultiElements result
255
     * @return Result
256
     */
257
    protected function analyzePnrAddMultiElementsResponse($response)
258
    {
259
        return $this->analyzePnrReply($response);
260
    }
261
262
    /**
263
     * @param SendResult $response PNR_Cancel result
264
     * @return Result
265
     */
266
    protected function analyzePnrCancelResponse($response)
267
    {
268
        return $this->analyzePnrReply($response);
269
    }
270
271
    /**
272
     * Analysing a PNR_Reply
273
     *
274
     * @param SendResult $response PNR_Retrieve result
275
     * @return Result
276
     */
277
    protected function analyzePnrReply($response)
278
    {
279
        $analyzeResponse = new Result($response);
280
281
        $domXpath = $this->makeDomXpath($response->responseXml);
282
283
        //General Errors:
284
        $queryAllErrorCodes = "//m:generalErrorInfo//m:errorOrWarningCodeDetails/m:errorDetails/m:errorCode";
285
        $queryAllErrorMsg = "//m:generalErrorInfo/m:errorWarningDescription/m:freeText";
286
287
        $errorCodeNodeList = $domXpath->query($queryAllErrorCodes);
288
289 View Code Duplication
        if ($errorCodeNodeList->length > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
290
            $analyzeResponse->status = Result::STATUS_ERROR;
291
292
            $code = $errorCodeNodeList->item(0)->nodeValue;
293
            $errorTextNodeList = $domXpath->query($queryAllErrorMsg);
294
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);
295
296
            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'general');
297
        }
298
299
        //Segment errors:
300
        $querySegmentErrorCodes = "//m:originDestinationDetails//m:errorInfo/m:errorOrWarningCodeDetails/m:errorDetails/m:errorCode";
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 133 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
301
        $querySegmentErrorMsg = "//m:originDestinationDetails//m:errorInfo/m:errorWarningDescription/m:freeText";
302
303
        $errorCodeNodeList = $domXpath->query($querySegmentErrorCodes);
304
305 View Code Duplication
        if ($errorCodeNodeList->length > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
306
            $analyzeResponse->status = Result::STATUS_ERROR;
307
308
            $code = $errorCodeNodeList->item(0)->nodeValue;
309
            $errorTextNodeList = $domXpath->query($querySegmentErrorMsg);
310
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);
311
312
            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'segment');
313
        }
314
315
        //Element errors:
316
        $queryElementErrorCodes = "//m:dataElementsIndiv/m:elementErrorInformation/m:errorOrWarningCodeDetails/m:errorDetails/m:errorCode";
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 139 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
317
        $queryElementErrorMsg = "//m:dataElementsIndiv//m:elementErrorInformation/m:errorWarningDescription/m:freeText";
318
319
        $errorCodeNodeList = $domXpath->query($queryElementErrorCodes);
320
321 View Code Duplication
        if ($errorCodeNodeList->length > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
322
            $analyzeResponse->status = Result::STATUS_ERROR;
323
324
            $code = $errorCodeNodeList->item(0)->nodeValue;
325
326
            $errorTextNodeList = $domXpath->query($queryElementErrorMsg);
327
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);
328
329
            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message), 'element');
330
        }
331
332
        return $analyzeResponse;
333
    }
334
335
    /**
336
     * @param SendResult $response Pnr_RetrieveAndDisplay response
337
     * @return Result
338
     * @throws Exception
339
     */
340
    protected function analyzePnrRetrieveAndDisplayResponse($response)
341
    {
342
        return $this->analyzeSimpleResponseErrorCodeAndMessage($response);
343
    }
344
345
    /**
346
     * Analysing a PNR_DisplayHistoryReply
347
     *
348
     * @param SendResult $response PNR_DisplayHistoryReply result
349
     * @return Result
350
     * @throws Exception
351
     */
352
    protected function analyzePnrDisplayHistoryResponse($response)
353
    {
354
        $analyzeResponse = new Result($response);
355
356
        $domXpath = $this->makeDomXpath($response->responseXml);
357
358
        $queryAllErrorCodes = "//m:generalErrorGroup//m:errorNumber/m:errorDetails/m:errorCode";
359
        $queryAllErrorMsg = "//m:generalErrorGroup/m:genrealErrorText/m:freeText";
360
361
        $errorCodeNodeList = $domXpath->query($queryAllErrorCodes);
362
363 View Code Duplication
        if ($errorCodeNodeList->length > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
364
            $analyzeResponse->status = Result::STATUS_ERROR;
365
366
            $code = $errorCodeNodeList->item(0)->nodeValue;
367
            $errorTextNodeList = $domXpath->query($queryAllErrorMsg);
368
            $message = $this->makeMessageFromMessagesNodeList($errorTextNodeList);
369
370
            $analyzeResponse->messages[] = new Result\NotOk($code, trim($message));
371
        }
372
373
        return $analyzeResponse;
374
    }
375
376
    /**
377
     * @param SendResult $response Queue_RemoveItem response
378
     * @return Result
379
     * @throws Exception
380
     */
381
    protected function analyzeQueueRemoveItemResponse($response)
382
    {
383
        return $this->analyzeGenericQueueResponse($response);
384
    }
385
386
    /**
387
     * @param SendResult $response Queue_MoveItem response
388
     * @return Result
389
     * @throws Exception
390
     */
391
    protected function analyzeQueueMoveItemResponse($response)
392
    {
393
        return $this->analyzeGenericQueueResponse($response);
394
    }
395
396
    /**
397
     * @param SendResult $response Queue_PlacePNR response
398
     * @return Result
399
     * @throws Exception
400
     */
401
    protected function analyzeQueuePlacePNRResponse($response)
402
    {
403
        return $this->analyzeGenericQueueResponse($response);
404
    }
405
406
    /**
407
     * @param SendResult $response Queue_List result
408
     * @return Result
409
     * @throws Exception
410
     */
411
    protected function analyzeQueueListResponse($response)
412
    {
413
        return $this->analyzeGenericQueueResponse($response);
414
    }
415
416
    /**
417
     * Analyze a generic Queue response
418
     *
419
     * @param SendResult $response Queue_*Reply result
420
     * @return Result
421
     * @throws Exception
422
     */
423
    protected function analyzeGenericQueueResponse($response)
424
    {
425
        $analysisResponse = new Result($response);
426
427
        $domDoc = $this->loadDomDocument($response->responseXml);
428
429
        $errorCodeNode = $domDoc->getElementsByTagName("errorCode")->item(0);
430
431
        if (!is_null($errorCodeNode)) {
432
            $analysisResponse->status = Result::STATUS_WARN;
433
434
            $errorCode = $errorCodeNode->nodeValue;
435
            $errorMessage = $this->getErrorTextFromQueueErrorCode($errorCode);
436
437
            $analysisResponse->messages[] = new Result\NotOk($errorCode, $errorMessage);
438
        }
439
440
        return $analysisResponse;
441
    }
442
443
444
    /**
445
     *
446
     * <Fare_PricePNRWithBookingClassReply xmlns="http://xml.amadeus.com/TPCBRR_13_2_1A">
447
     * <applicationError>
448
     * <errorOrWarningCodeDetails>
449
     * <errorDetails>
450
     * <errorCode>00477</errorCode>
451
     * <errorCategory>EC</errorCategory>
452
     * <errorCodeOwner>1A</errorCodeOwner>
453
     * </errorDetails>
454
     * </errorOrWarningCodeDetails>
455
     * <errorWarningDescription>
456
     * <freeText>INVALID FORMAT</freeText>
457
     * </errorWarningDescription>
458
     * </applicationError>
459
     * </Fare_PricePNRWithBookingClassReply>
460
     *
461
     * @param SendResult $response Fare_PricePNRWithBookingClass result
462
     * @return Result
463
     * @throws Exception
464
     */
465
    protected function analyzeFarePricePNRWithBookingClassResponse($response)
466
    {
467
        $analyzeResponse = new Result($response);
468
469
        $domXpath = $this->makeDomXpath($response->responseXml);
470
471
        $queryErrorCode = "//m:applicationError//m:errorOrWarningCodeDetails/m:errorDetails/m:errorCode";
472
        $queryErrorCategory = "//m:applicationError//m:errorOrWarningCodeDetails/m:errorDetails/m:errorCategory";
473
        $queryErrorMsg = "//m:applicationError/m:errorWarningDescription/m:freeText";
474
475
        $errorCodeNodeList = $domXpath->query($queryErrorCode);
476
477
        if ($errorCodeNodeList->length > 0) {
478
            $analyzeResponse->status = Result::STATUS_ERROR;
479
480
            $errorCatNode = $domXpath->query($queryErrorCategory)->item(0);
481
            if ($errorCatNode instanceof \DOMNode) {
482
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($errorCatNode->nodeValue);
483
            }
484
485
            $analyzeResponse->messages[] = new Result\NotOk(
486
                $errorCodeNodeList->item(0)->nodeValue,
487
                $this->makeMessageFromMessagesNodeList(
488
                    $domXpath->query($queryErrorMsg)
489
                )
490
            );
491
        }
492
493
        return $analyzeResponse;
494
    }
495
496
    protected function analyzeFareMasterPricerTravelBoardSearchResponse($response)
497
    {
498
        $analyzeResponse = new Result($response);
499
500
        $domXpath = $this->makeDomXpath($response->responseXml);
501
502
        $queryErrCode = "//m:applicationError//m:applicationErrorDetail/m:error";
503
        $queryErrMsg = "//m:errorMessageText/m:description";
504
505
        $codeNode = $domXpath->query($queryErrCode)->item(0);
506
507
        if ($codeNode instanceof \DOMNode) {
508
            $analyzeResponse->status = Result::STATUS_ERROR;
509
510
            $errMsg = '';
511
            $errMsgNode = $domXpath->query($queryErrMsg)->item(0);
512
            if ($errMsgNode instanceof \DOMNode) {
513
                $errMsg = $errMsgNode->nodeValue;
514
            }
515
516
            $analyzeResponse->messages[] = new Result\NotOk(
517
                $codeNode->nodeValue,
518
                $errMsg
519
            );
520
        }
521
522
        return $analyzeResponse;
523
    }
524
525
    /**
526
     * @param SendResult $response
527
     * @return Result
528
     */
529
    protected function analyzeFareConvertCurrencyResponse($response)
530
    {
531
        return $this->analyzeSimpleResponseErrorCodeAndMessage($response);
532
    }
533
534
    /**
535
     * @param SendResult $response
536
     * @return Result
537
     */
538
    protected function analyzeFareCheckRulesResponse($response)
539
    {
540
        return $this->analyzeSimpleResponseErrorCodeAndMessage($response);
541
    }
542
543
    /**
544
     * @param SendResult $response
545
     * @return Result
546
     */
547
    protected function analyzeFareInformativePricingWithoutPNRResponse($response)
548
    {
549
        return $this->analyzeSimpleResponseErrorCodeAndMessage($response);
550
    }
551
552
553
    /**
554
     * @param SendResult $response
555
     * @return Result
556
     */
557
    protected function analyzeDocIssuanceIssueTicketResponse($response)
558
    {
559
        return $this->analyzeSimpleResponseErrorCodeAndMessageStatusCode($response);
560
    }
561
562 View Code Duplication
    protected function analyzeTicketCreateTSTFromPricingResponse($response)
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...
563
    {
564
        $analyzeResponse = new Result($response);
565
566
        $domDoc = $this->loadDomDocument($response->responseXml);
567
568
        $errorCodeNode = $domDoc->getElementsByTagName("applicationErrorCode")->item(0);
569
570
        if (!is_null($errorCodeNode)) {
571
            $analyzeResponse->status = Result::STATUS_ERROR;
572
573
            $errorCatNode = $domDoc->getElementsByTagName("codeListQualifier")->item(0);
574
            if ($errorCatNode instanceof \DOMNode) {
575
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($errorCatNode->nodeValue);
576
            }
577
578
            $errorCode = $errorCodeNode->nodeValue;
579
            $errorTextNodeList = $domDoc->getElementsByTagName("errorFreeText");
580
581
            $analyzeResponse->messages[] = new Result\NotOk(
582
                $errorCode,
583
                $this->makeMessageFromMessagesNodeList($errorTextNodeList)
584
            );
585
        }
586
587
        return $analyzeResponse;
588
    }
589
590
    /**
591
     * @param SendResult $response
592
     * @return Result
593
     */
594
    protected function analyzeOfferConfirmCarOfferResponse($response)
595
    {
596
        return $this->analyzeGenericOfferResponse($response);
597
    }
598
599
    /**
600
     * @param SendResult $response
601
     * @return Result
602
     */
603
    protected function analyzeOfferConfirmHotelOfferResponse($response)
604
    {
605
        $analyzeResponse = new Result($response);
606
607
        $domXpath = $this->makeDomXpath($response->responseXml);
608
609
        $codeNode = $domXpath->query("//m:errorDetails/m:errorCode")->item(0);
610
        if ($codeNode instanceof \DOMNode) {
611
            $analyzeResponse->status = Result::STATUS_ERROR;
612
613
            $categoryNode = $domXpath->query("//m:errorDetails/m:errorCategory")->item(0);
614
            if ($categoryNode instanceof \DOMNode) {
615
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($categoryNode->nodeValue);
616
            }
617
618
            $msgNode = $domXpath->query('//m:errorDescription/m:freeText')->item(0);
619
620
            $analyzeResponse->messages[] = new Result\NotOk(
621
                $codeNode->nodeValue,
622
                trim($msgNode->nodeValue)
623
            );
624
        }
625
626
        return $analyzeResponse;
627
    }
628
629
    /**
630
     * @param SendResult $response
631
     * @return Result
632
     */
633
    protected function analyzeOfferConfirmAirOfferResponse($response)
634
    {
635
        return $this->analyzeGenericOfferResponse($response);
636
    }
637
638
    /**
639
     * @param SendResult $response
640
     * @return Result
641
     */
642
    protected function analyzeOfferVerifyOfferResponse($response)
643
    {
644
        return $this->analyzeGenericOfferResponse($response);
645
    }
646
647
    /**
648
     * @param SendResult $response
649
     * @return Result
650
     */
651
    protected function analyzeGenericOfferResponse($response)
652
    {
653
        $analyzeResponse = new Result($response);
654
655
        $domXpath = $this->makeDomXpath($response->responseXml);
656
657
        $msgNode = $domXpath->query('//m:errorsDescription/m:errorWarningDescription/m:freeText')->item(0);
658
659
        if ($msgNode instanceof \DOMNode) {
660
            if (trim($msgNode->nodeValue) === "OFFER CONFIRMED SUCCESSFULLY" || trim($msgNode->nodeValue) === "OFFER VERIFIED SUCCESSFULLY" ) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 143 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
661
                $analyzeResponse->messages[] = new Result\NotOk(
662
                    0,
663
                    trim($msgNode->nodeValue)
664
                );
665
                return $analyzeResponse;
666
            }
667
668
            $categoryNode = $domXpath->query('//m:errorDetails/m:errorCategory')->item(0);
669
            if ($categoryNode instanceof \DOMNode) {
670
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($categoryNode->nodeValue);
671
            }
672
673
            $codeNode = $domXpath->query('//m:errorDetails/m:errorCode')->item(0);
674
675
            $analyzeResponse->messages[] = new Result\NotOk(
676
                $codeNode->nodeValue,
677
                trim($msgNode->nodeValue)
678
            );
679
        }
680
681
        return $analyzeResponse;
682
    }
683
684
    protected function analyzeMiniRuleGetFromPricingRecResponse($response)
685
    {
686
        $analyzeResponse = new Result($response);
687
688
        $domXpath = $this->makeDomXpath($response->responseXml);
689
690
        $statusNode = $domXpath->query('//m:responseDetails/m:statusCode')->item(0);
691
        if ($statusNode instanceof \DOMNode) {
692
            $code = $statusNode->nodeValue;
693
694
            if ($code !== 'O') {
695
                $categoryNode = $domXpath->query('//m:errorOrWarningCodeDetails/m:errorDetails/m:errorCategory')->item(0);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
696
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($categoryNode->nodeValue);
697
698
                $codeNode = $domXpath->query('//m:errorOrWarningCodeDetails/m:errorDetails/m:errorCode')->item(0);
699
                $msgNode = $domXpath->query('//m:errorWarningDescription/m:freeText')->item(0);
700
701
                if ($codeNode instanceof \DOMNode && $msgNode instanceof \DOMNode) {
702
                    $analyzeResponse->messages[] = new Result\NotOk(
703
                        $codeNode->nodeValue,
704
                        $msgNode->nodeValue
705
                    );
706
                }
707
            }
708
        }
709
710
        return $analyzeResponse;
711
    }
712
713
    /**
714
     * @param SendResult $response
715
     * @return Result
716
     */
717
    protected function analyzeInfoEncodeDecodeCityResponse($response)
718
    {
719
        return $this->analyzeSimpleResponseErrorCodeAndMessage($response);
720
    }
721
722
    /**
723
     * @param SendResult $response
724
     * @return Result
725
     */
726
    protected function analyzePriceXplorerExtremeSearchResponse($response)
727
    {
728
        return $this->analyzeSimpleResponseErrorCodeAndMessage($response);
729
    }
730
731
    /**
732
     * @param SendResult $response WebService message Send Result
733
     * @return Result
734
     * @throws Exception
735
     */
736 View Code Duplication
    protected function analyzeSimpleResponseErrorCodeAndMessage($response)
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...
737
    {
738
        $analyzeResponse = new Result($response);
739
740
        $domDoc = $this->loadDomDocument($response->responseXml);
741
742
        $errorCodeNode = $domDoc->getElementsByTagName("errorCode")->item(0);
743
744
        if (!is_null($errorCodeNode)) {
745
            $errorCatNode = $domDoc->getElementsByTagName("errorCategory")->item(0);
746
            if ($errorCatNode instanceof \DOMNode) {
747
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($errorCatNode->nodeValue);
748
            } else {
749
                $analyzeResponse->status = Result::STATUS_ERROR;
750
            }
751
752
            $errorCode = $errorCodeNode->nodeValue;
753
            $errorTextNodeList = $domDoc->getElementsByTagName("freeText");
754
755
            $analyzeResponse->messages[] = new Result\NotOk(
756
                $errorCode,
757
                $this->makeMessageFromMessagesNodeList($errorTextNodeList)
758
            );
759
        }
760
761
        return $analyzeResponse;
762
    }
763
764
    /**
765
     * @param SendResult $response WebService message Send Result
766
     * @return Result
767
     * @throws Exception
768
     */
769 View Code Duplication
    protected function analyzeSimpleResponseErrorCodeAndMessageStatusCode($response)
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...
770
    {
771
        $analyzeResponse = new Result($response);
772
773
        $domDoc = $this->loadDomDocument($response->responseXml);
774
775
        $errorCodeNode = $domDoc->getElementsByTagName("errorCode")->item(0);
776
777
        if (!is_null($errorCodeNode)) {
778
            $analyzeResponse->status = Result::STATUS_ERROR;
779
780
            $errorCatNode = $domDoc->getElementsByTagName("statusCode")->item(0);
781
            if ($errorCatNode instanceof \DOMNode) {
782
                $analyzeResponse->status = $this->makeStatusFromErrorQualifier($errorCatNode->nodeValue);
783
            }
784
785
            $errorCode = $errorCodeNode->nodeValue;
786
            $errorTextNodeList = $domDoc->getElementsByTagName("freeText");
787
788
            $analyzeResponse->messages[] = new Result\NotOk(
789
                $errorCode,
790
                $this->makeMessageFromMessagesNodeList($errorTextNodeList)
791
            );
792
        }
793
794
        return $analyzeResponse;
795
    }
796
797
    /**
798
     * Returns the errortext from a Queue_*Reply errorcode
799
     *
800
     * This function is necessary because the core only responds
801
     * with errorcode but does not send an errortext.
802
     *
803
     * The errorcodes for all Queue_*Reply messages are the same.
804
     *
805
     * @link https://webservices.amadeus.com/extranet/viewArea.do?id=10
806
     * @param string $errorCode
807
     * @return string the errortext for this errorcode.
808
     */
809
    protected function getErrorTextFromQueueErrorCode($errorCode)
810
    {
811
        $recognizedErrors = [
812
            '723' => "Invalid category",
813
            '911' => "Unable to process - system error",
814
            '913' => "Item/data not found or data not existing in processing host",
815
            '79D' => "Queue identifier has not been assigned for specified office identification",
816
            '91C' => "invalid record locator",
817
            '91F' => "Invalid queue number",
818
            '921' => "target not specified",
819
            '922' => "Targetted queue has wrong queue type",
820
            '926' => "Queue category empty",
821
            '928' => "Queue category not assigned",
822
            '92A' => "Queue category full",
823
        ];
824
825
        $errorMessage = (array_key_exists($errorCode, $recognizedErrors)) ? $recognizedErrors[$errorCode] : '';
826
827
        if ($errorMessage === '') {
828
            $errorMessage = "QUEUE ERROR '" . $errorCode . "' (Error message unavailable)";
829
        }
830
831
        return $errorMessage;
832
    }
833
834
    /**
835
     * @param string $response
836
     * @return \DOMDocument
837
     * @throws Exception when there's a problem loading the message
838
     */
839
    protected function loadDomDocument($response)
840
    {
841
        $domDoc = new \DOMDocument('1.0', 'UTF-8');
842
843
        $loadResult = $domDoc->loadXML($response);
844
        if ($loadResult === false) {
845
            throw new Exception('Could not load response message into DOMDocument');
846
        }
847
848
        return $domDoc;
849
    }
850
851
    /**
852
     * @param $qualifier
853
     * @return string Result::STATUS_*
854
     */
855
    protected function makeStatusFromErrorQualifier($qualifier)
856
    {
857
        $status = null;
0 ignored issues
show
Unused Code introduced by
$status is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
858
859
        switch ($qualifier) {
860
            case 'INF':
861
                $status = Result::STATUS_INFO;
862
                break;
863
            case 'WEC':
864
            case 'WZZ': //Mutually defined warning
865
            case 'W':
866
                $status = Result::STATUS_WARN;
867
                break;
868
            case 'EC':
869
            case 'X':
870
                $status = Result::STATUS_ERROR;
871
                break;
872
            case 'O':
873
                $status = Result::STATUS_OK;
874
                break;
875
            case 'ZZZ': //Mutually defined
876
            default:
877
                $status = Result::STATUS_UNKNOWN;
878
                break;
879
        }
880
881
        return $status;
882
    }
883
884
885
    /**
886
     * Make a Xpath-queryable object for an XML string
887
     *
888
     * registers TNS namespace with prefix self::XMLNS_PREFIX
889
     *
890
     * @param string $response
891
     * @return \DOMXPath
892
     * @throws Exception when there's a problem loading the message
893
     */
894
    protected function makeDomXpath($response)
895
    {
896
        $domDoc = $this->loadDomDocument($response);
897
        $domXpath = new \DOMXPath($domDoc);
898
899
        $domXpath->registerNamespace(
900
            self::XMLNS_PREFIX,
901
            $domDoc->documentElement->lookupNamespaceUri(null)
902
        );
903
904
        return $domXpath;
905
    }
906
907
    /**
908
     * Convert a DomNodeList of nodes containing a (potentially partial) error message into a string.
909
     *
910
     * @param \DOMNodeList $errorTextNodeList
911
     * @return string|null
912
     */
913
    protected function makeMessageFromMessagesNodeList($errorTextNodeList)
914
    {
915
        return implode(
916
            ' - ',
917
            array_map(
918
                function($item) {
919
                    return trim($item->nodeValue);
920
                },
921
                iterator_to_array($errorTextNodeList)
922
            )
923
        );
924
    }
925
926
    /**
927
     * @param SendResult $sendResult
928
     * @return Result
929
     */
930
    protected function makeResultForException($sendResult)
931
    {
932
        $result = new Result($sendResult, Result::STATUS_FATAL);
933
934
        $result->messages[] = $this->makeMessageFromException($sendResult->exception);
935
936
        return $result;
937
    }
938
939
    /**
940
     * @param \Exception $exception
941
     * @return Result\NotOk
942
     * @throws Exception
943
     */
944
    protected function makeMessageFromException(\Exception $exception)
945
    {
946
        $message = new Result\NotOk();
947
948
        if ($exception instanceof \SoapFault) {
949
            $info = explode('|', $exception->getMessage());
950
            $message->code = $info[0];
951
            if (count($info) === 3) {
952
                $message->level = $info[1];
953
                $message->text = $info[2];
954
            }
955
        }
956
957
        return $message;
958
    }
959
}
960