Passed
Branch feature/ECO-965-refactoring (c9cdee)
by Andrey
06:34 queued 01:51
created

AbstractResponseParserConverter::isSuccess()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Apache OSL-2
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerEco\Zed\AmazonPay\Business\Api\Converter;
9
10
use ArrayObject;
11
use Generated\Shared\Transfer\AddressTransfer;
12
use Generated\Shared\Transfer\AmazonpayResponseConstraintTransfer;
13
use Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer;
14
use Generated\Shared\Transfer\AmazonpayResponseTransfer;
15
use PayWithAmazon\ResponseInterface;
16
use SprykerEco\Shared\AmazonPay\AmazonPayConfig;
17
18
abstract class AbstractResponseParserConverter extends AbstractConverter implements ResponseParserConverterInterface
19
{
20
    const STATUS_CODE_SUCCESS = 200;
21
    const ORDER_REFERENCE_DETAILS = 'OrderReferenceDetails';
22
    const CONSTRAINTS = 'Constraints';
23
    const DESCRIPTION = 'Description';
24
    const CONSTRAINT_ID = 'ConstraintID';
25
    const REQUEST_ID = 'RequestId';
26
    const ERROR = 'Error';
27
    const RESPONSE_METADATA = 'ResponseMetadata';
28
    const RESPONSE_STATUS = 'ResponseStatus';
29
    const MESSAGE = 'Message';
30
    const CODE = 'Code';
31
    const DESTINATION = 'Destination';
32
    const PHYSICAL_DESTINATION = 'PhysicalDestination';
33
    const NAME = 'Name';
34
    const CITY = 'City';
35
    const COUNTRY_CODE = 'CountryCode';
36
    const POSTAL_CODE = 'PostalCode';
37
    const ADDRESS_LINE_1 = 'AddressLine1';
38
    const ADDRESS_LINE_2 = 'AddressLine2';
39
    const ADDRESS_LINE_3 = 'AddressLine3';
40
    const DISTRICT = 'District';
41
    const STATE_OR_REGION = 'StateOrRegion';
42
    const PHONE = 'Phone';
43
44
    /**
45
     * @var string
46
     */
47
    protected $resultKeyName;
48
49
    /**
50
     * @return string
51
     */
52
    abstract protected function getResponseType();
53
54
    /**
55
     * @return \Generated\Shared\Transfer\AmazonpayResponseTransfer
56
     */
57
    protected function createTransferObject()
58
    {
59
        return new AmazonpayResponseTransfer();
60
    }
61
62
    /**
63
     * @param \Generated\Shared\Transfer\AmazonpayResponseTransfer $responseTransfer
64
     * @param array $response
65
     *
66
     * @return \Generated\Shared\Transfer\AmazonpayResponseTransfer
67
     */
68
    protected function setBody(AmazonpayResponseTransfer $responseTransfer, array $response)
69
    {
70
        return $responseTransfer;
71
    }
72
73
    /**
74
     * @param \Generated\Shared\Transfer\AmazonpayResponseTransfer $responseTransfer
75
     * @param array $response
76
     *
77
     * @return \Generated\Shared\Transfer\AmazonpayResponseTransfer
78
     */
79
    protected function mapResponseDataToTransfer(AmazonpayResponseTransfer $responseTransfer, array $response)
80
    {
81
        $responseTransfer->setResponseHeader($this->extractHeader($response));
82
83
        if ($responseTransfer->getResponseHeader()->getIsSuccess()) {
84
            return $this->setBody($responseTransfer, $response);
85
        }
86
87
        return $responseTransfer;
88
    }
89
90
    /**
91
     * @param \PayWithAmazon\ResponseInterface $responseParser
92
     *
93
     * @return \Generated\Shared\Transfer\AmazonpayResponseTransfer
94
     */
95
    public function convert(ResponseInterface $responseParser)
96
    {
97
        return $this->mapResponseDataToTransfer($this->createTransferObject(), $responseParser->toArray());
98
    }
99
100
    /**
101
     * @param array $response
102
     *
103
     * @return array
104
     */
105
    protected function extractMetadata(array $response)
106
    {
107
        return $response[static::RESPONSE_METADATA] ?? [];
108
    }
109
110
    /**
111
     * @param array $response
112
     *
113
     * @return int
114
     */
115
    protected function extractStatusCode(array $response)
116
    {
117
        return (int)$response[static::RESPONSE_STATUS];
118
    }
119
120
    /**
121
     * @param array $response
122
     *
123
     * @return \Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer
124
     */
125
    protected function extractHeader(array $response)
126
    {
127
        $header = new AmazonpayResponseHeaderTransfer();
128
        $header->setIsSuccess($this->isSuccess($response));
129
130
        $statusCode = $this->extractStatusCode($response);
131
        $header->setStatusCode($statusCode);
132
133
        $this->extractRequest($header, $response);
134
135
        $constraints = $this->extractConstraints($response);
136
        $header->setConstraints($constraints);
137
        $this->extractErrorFromConstraints($header);
138
139
        return $header;
140
    }
141
142
    /**
143
     * @return void
144
     */
145
    protected function extractRequest(AmazonpayResponseHeaderTransfer $header, array $response)
146
    {
147
        $metadata = $this->extractMetadata($response);
148
        if (isset($metadata[static::REQUEST_ID])) {
149
            $header->setRequestId($metadata[static::REQUEST_ID]);
150
151
            if (!empty($response[static::ERROR])) {
152
                $this->updateHeaderWithError($header, $response);
153
            }
154
        }
155
    }
156
157
    /**
158
     * @param \Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer $header
159
     * @param array $response
160
     *
161
     * @return void
162
     */
163
    protected function updateHeaderWithError(AmazonpayResponseHeaderTransfer $header, array $response)
164
    {
165
        $header->setErrorMessage($response[static::ERROR][static::MESSAGE]);
166
        $header->setErrorCode($response[static::ERROR][static::CODE]);
167
        $header->setRequestId($response[static::REQUEST_ID]);
168
    }
169
170
    /**
171
     * @param \Generated\Shared\Transfer\AmazonpayResponseHeaderTransfer $header
172
     *
173
     * @return void
174
     */
175
    protected function extractErrorFromConstraints(AmazonpayResponseHeaderTransfer $header)
176
    {
177
        if ($header->getConstraints()->count() === 0) {
178
            return;
179
        }
180
181
        $constraint = $header->getConstraints()[0];
182
        $header->setErrorMessage($this->buildErrorMessage($constraint));
183
    }
184
185
    /**
186
     * @param array $response
187
     *
188
     * @return bool
189
     */
190
    protected function isSuccess(array $response)
191
    {
192
        return
193
            $this->extractStatusCode($response) === static::STATUS_CODE_SUCCESS
194
            && $this->extractConstraints($response)->count() === 0;
195
    }
196
197
    /**
198
     * @param array $response
199
     *
200
     * @return array
201
     */
202
    protected function extractResult(array $response)
203
    {
204
        $responseType = $this->getResponseType();
205
206
        return $response[$responseType] ?? [];
207
    }
208
209
    /**
210
     * @param array $response
211
     *
212
     * @return \ArrayObject|\Generated\Shared\Transfer\AmazonpayResponseConstraintTransfer[]
213
     */
214
    protected function extractConstraints(array $response)
215
    {
216
        $result = $this->extractResult($response);
217
218
        if (empty($result[static::ORDER_REFERENCE_DETAILS][static::CONSTRAINTS])) {
219
            return new ArrayObject();
220
        }
221
222
        $constraints = $this->getConstraints($result);
223
224
        return $this->buildConstraintTransfers($constraints);
225
    }
226
227
    /**
228
     * @param array $constraints
229
     *
230
     * @return \ArrayObject|\Generated\Shared\Transfer\AmazonpayResponseConstraintTransfer[]
231
     */
232
    protected function buildConstraintTransfers(array $constraints)
233
    {
234
        $constraintTransfers = new ArrayObject();
235
236
        foreach ($constraints as $constraint) {
237
            if ($this->isValidConstraint($constraint)) {
238
                $constraintTransfers[] = $this->buildConstraintTransfer($constraint);
239
            }
240
        }
241
242
        return $constraintTransfers;
243
    }
244
245
    /**
246
     * @param array $constraint
247
     *
248
     * @return bool
249
     */
250
    protected function isValidConstraint(array $constraint)
251
    {
252
        return !empty($constraint[static::CONSTRAINT_ID]) && !empty($constraint[static::DESCRIPTION]);
253
    }
254
255
    /**
256
     * @param array $result
257
     *
258
     * @return array
259
     */
260
    protected function getConstraints(array $result)
261
    {
262
        if (count($result[static::ORDER_REFERENCE_DETAILS][static::CONSTRAINTS]) === 1) {
263
            return array_values($result[static::ORDER_REFERENCE_DETAILS][static::CONSTRAINTS]);
264
        }
265
266
        return $result[static::ORDER_REFERENCE_DETAILS][static::CONSTRAINTS];
267
    }
268
269
    /**
270
     * @param array $constraint
271
     *
272
     * @return \Generated\Shared\Transfer\AmazonpayResponseConstraintTransfer
273
     */
274
    protected function buildConstraintTransfer(array $constraint)
275
    {
276
        $constraintTransfer = new AmazonpayResponseConstraintTransfer();
277
        $constraintTransfer->setConstraintId($constraint[static::CONSTRAINT_ID]);
278
        $constraintTransfer->setConstraintDescription($constraint[static::DESCRIPTION]);
279
280
        return $constraintTransfer;
281
    }
282
283
    /**
284
     * @param array $response
285
     *
286
     * @return \Generated\Shared\Transfer\AddressTransfer
287
     */
288
    protected function extractShippingAddress(array $response)
289
    {
290
        $address = new AddressTransfer();
291
292
        if (!$this->isSuccess($response)) {
293
            return $address;
294
        }
295
296
        $aResponseAddress =
297
            $this->extractResult($response)[static::ORDER_REFERENCE_DETAILS][static::DESTINATION][static::PHYSICAL_DESTINATION] ?? null;
298
299
        if ($aResponseAddress !== null) {
300
            $address = $this->convertAddressToTransfer($aResponseAddress);
301
        }
302
303
        return $address;
304
    }
305
306
    /**
307
     * @param array $addressData
308
     *
309
     * @return \Generated\Shared\Transfer\AddressTransfer
310
     */
311
    protected function convertAddressToTransfer(array $addressData)
312
    {
313
        $address = new AddressTransfer();
314
315
        if (!empty($addressData[static::NAME])) {
316
            $address = $this->updateNameData($address, $addressData[static::NAME]);
317
        }
318
319
        $addressData = array_map([$this, 'getStringValue'], $addressData);
320
321
        $address->setCity($addressData[static::CITY] ?? null);
322
        $address->setIso2Code($addressData[static::COUNTRY_CODE] ?? null);
323
        $address->setZipCode($addressData[static::POSTAL_CODE] ?? null);
324
        $address->setAddress1($addressData[static::ADDRESS_LINE_1] ?? null);
325
        $address->setAddress2($addressData[static::ADDRESS_LINE_2] ?? null);
326
        $address->setAddress3($addressData[static::ADDRESS_LINE_3] ?? null);
327
        $address->setRegion($addressData[static::DISTRICT] ?? null);
328
        $address->setState($addressData[static::STATE_OR_REGION] ?? null);
329
        $address->setPhone($addressData[static::PHONE] ?? null);
330
331
        return $address;
332
    }
333
334
    /**
335
     * @param string|array $value
336
     *
337
     * @return string|null
338
     */
339
    protected function getStringValue($value)
340
    {
341
        return empty($value) ? null : (string)$value;
342
    }
343
344
    /**
345
     * @param $constraint
346
     *
347
     * @return string
348
     */
349
    protected function buildErrorMessage($constraint):string
350
    {
351
        return AmazonPayConfig::PREFIX_AMAZONPAY_PAYMENT_ERROR . $constraint->getConstraintId();
352
    }
353
}
354