AbstractRequest   B
last analyzed

Complexity

Total Complexity 44

Size/Duplication

Total Lines 432
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 44
lcom 3
cbo 6
dl 0
loc 432
ccs 130
cts 130
cp 1
rs 8.8798
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A getEndpoint() 0 4 2
A getIntegrationKey() 0 4 1
A setIntegrationKey() 0 4 1
A getBoletoDueDate() 0 6 2
A getDocumentNumber() 0 4 1
A setDocumentNumber() 0 5 1
A getPersonType() 0 4 2
A setPersonType() 0 4 1
A getCompanyName() 0 4 1
A setCompanyName() 0 4 1
A getSplit() 0 4 2
A setSplit() 0 4 1
A getNote() 0 4 1
A setNote() 0 4 1
A getHttpMethod() 0 4 1
A createResponse() 0 4 1
A getHeaders() 0 4 1
A getDefaultParameters() 0 7 1
A getAddressData() 0 16 3
A getSplitData() 0 5 2
A getInstallments() 0 4 2
A setInstallments() 0 4 1
A sendData() 0 13 1
A getCustomerData() 0 21 2
A getCardData() 0 22 4
A getBoletoData() 0 8 1
A setBoletoDueDate() 0 11 2
A getPaymentData() 0 35 4

How to fix   Complexity   

Complex Class

Complex classes like AbstractRequest 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 AbstractRequest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Omnipay\Ebanx\Message;
4
5
use Omnipay\Common\Message\AbstractRequest as BaseAbstractRequest;
6
use Omnipay\Common\Exception\InvalidRequestException;
7
8
/**
9
 * Abstract Request
10
 */
11
abstract class AbstractRequest extends BaseAbstractRequest
12
{
13
    protected $liveEndpoint = 'https://api.ebanx.com.br/ws';
14
    protected $testEndpoint = 'https://staging.ebanx.com.br/ws';
15
16
    /**
17
     * Get the endpoint where the request should be made.
18
     *
19
     * @return string the URL of the endpoint
20
     */
21 51
    public function getEndpoint()
22
    {
23 51
        return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
24
    }
25
26
    /**
27
     * Get the gateway Integration Key.
28
     *
29
     * Authentication is by means of a single secret API key set as
30
     * the integrationKey parameter when creating the gateway object.
31
     *
32
     * @return string
33
     */
34 72
    public function getIntegrationKey()
35
    {
36 72
        return $this->getParameter('integration_key');
37
    }
38
39
    /**
40
     * Set Integration key
41
     *
42
     * @param  string $value
43
     * @return AbstractRequest provides a fluent interface.
44
     */
45 60
    public function setIntegrationKey($value)
46
    {
47 60
        return $this->setParameter('integration_key', $value);
48
    }
49
50
    /**
51
     * Get the boleto due date
52
     *
53
     * @return string boleto due date
54
     */
55 9
    public function getBoletoDueDate($format = 'd/m/Y')
56
    {
57 9
        $value = $this->getParameter('boletoDueDate');
58
59 9
        return $value ? $value->format($format) : null;
60
    }
61
62
    /**
63
     * Set the boleto due date
64
     *
65
     * @param  string $value defaults to atual date + 30 days
66
     * @return AbstractRequest
67
     */
68 9
    public function setBoletoDueDate($value)
69
    {
70 9
        if ($value) {
71 9
            $value = new \DateTime($value, new \DateTimeZone('UTC'));
72 9
            $value = new \DateTime($value->format('Y-m-d\T03:00:00'), new \DateTimeZone('UTC'));
73
        } else {
74 3
            $value = null;
75
        }
76
77 9
        return $this->setParameter('boletoDueDate', $value);
78
    }
79
80
    /**
81
     * Get Document number (CPF or CNPJ).
82
     *
83
     * @return string
84
     */
85 27
    public function getDocumentNumber()
86
    {
87 27
        return $this->getParameter('documentNumber');
88
    }
89
90
    /**
91
     * Set Document Number (CPF or CNPJ)
92
     *
93
     * Non-numeric characters are stripped out of the document number, so
94
     * it's safe to pass in strings such as "224.158.178-40" etc.
95
     *
96
     * @param  string $value Parameter value
97
     * @return AbstractRequest
98
     */
99 36
    public function setDocumentNumber($value)
100
    {
101
        // strip non-numeric characters
102 36
        return $this->setParameter('documentNumber', preg_replace('/\D/', '', $value));
103
    }
104
105
    /**
106
     * Get the type of person that is making the payment
107
     * This allow to a payment be made by a company
108
     *
109
     * @return string
110
     */
111 27
    public function getPersonType()
112
    {
113 27
        return $this->getParameter('personType') ?: 'personal';
114
    }
115
116
    /**
117
     * Set Person Type
118
     *
119
     * @param  string $value Person type value
120
     * @return AbstractRequest
121
     */
122 6
    public function setPersonType($value)
123
    {
124 6
        return $this->setParameter('personType', $value);
125
    }
126
127
    /**
128
     * Get the company name that is making the payment
129
     *
130
     * @return string
131
     */
132 6
    public function getCompanyName()
133
    {
134 6
        return $this->getParameter('companyName');
135
    }
136
137
    /**
138
     * Set Company Name
139
     *
140
     * @param  string $value Company name value
141
     * @return AbstractRequest
142
     */
143 6
    public function setCompanyName($value)
144
    {
145 6
        return $this->setParameter('companyName', $value);
146
    }
147
148
    /**
149
     * Get the split param
150
     *
151
     * @return array
152
     */
153 36
    public function getSplit()
154
    {
155 36
        return $this->getParameter('split') ?: [];
156
    }
157
158
    /**
159
     * Set Split
160
     *
161
     * @param  array $value Array containing the required fields to split the payment
162
     * @return AbstractRequest
163
     */
164 6
    public function setSplit($value = [])
165
    {
166 6
        return $this->setParameter('split', $value);
167
    }
168
169
    /**
170
     * A note about the payment.
171
     *
172
     * @return string
173
     */
174 24
    public function getNote()
175
    {
176 24
        return $this->getParameter('note');
177
    }
178
179
    /**
180
     * Set a note about the payment. The value of this parameter
181
     * will be shown along with payment details.
182
     *
183
     * @param  string $value Person type value
184
     * @return AbstractRequest
185
     */
186 6
    public function setNote($value)
187
    {
188 6
        return $this->setParameter('note', $value);
189
    }
190
191
    /**
192
     * Get HTTP Method.
193
     *
194
     * This is nearly always POST but can be over-ridden in sub classes.
195
     *
196
     * @return string the HTTP method
197
     */
198 12
    public function getHttpMethod()
199
    {
200 12
        return 'POST';
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206 12
    public function sendData($data)
207
    {
208 12
        $response = $this->httpClient->request(
209 12
            $this->getHttpMethod(),
210 12
            $this->getEndpoint(),
211 12
            $this->getHeaders(),
212 12
            json_encode($data)
213
        );
214
215 12
        $payload =  json_decode($response->getBody()->getContents(), true);
216
217 12
        return $this->createResponse($payload);
218
    }
219
220 12
    public function createResponse($data)
221
    {
222 12
        return $this->response = new Response($this, $data);
223
    }
224
225 12
    public function getHeaders()
226
    {
227 12
        return [];
228
    }
229
230
    /**
231
     * Get the base data.
232
     *
233
     * Because the Ebanx gateway requires a common of fields for every request
234
     * this function can be called to this common data in the format that the
235
     * API requires.
236
     *
237
     * @return array
238
     */
239 57
    public function getDefaultParameters()
240
    {
241 57
        $data                    = array();
242 57
        $data['integration_key'] = $this->getIntegrationKey();
243
244 57
        return $data;
245
    }
246
247
    /**
248
     * Get the customer data.
249
     *
250
     * Because the Ebanx gateway uses a common format for passing
251
     * customer data to the API, this function can be called to get the
252
     * data from the associated card object in the format that the
253
     * API requires.
254
     *
255
     * @return array
256
     */
257 24
    public function getCustomerData()
258
    {
259 24
        $this->validate('card', 'documentNumber');
260 24
        $card    = $this->getCard();
261
262 24
        $data                 = array();
263 24
        $data['name']         = $card->getName();
264 24
        $data['email']        = $card->getEmail();
265 24
        $data['document']     = $this->getDocumentNumber();
266 24
        $data['phone_number'] = $card->getPhone();
267
268 24
        $personType = $this->getPersonType();
269
        //If you need to create a payment for a company a couple of extra parameters are need.
270 24
        if ($personType == 'business') {
271 3
            $this->validate('companyName');
272 3
            $data['name']                = $this->getCompanyName();
273 3
            $data['person_type']         = $personType;
274 3
            $data['responsible']['name'] = $card->getName();
275
        }
276 24
        return $data;
277
    }
278
279
    /**
280
     * Get the card data.
281
     *
282
     * Because the Ebanx gateway uses a common format for passing
283
     * card data to the API, this function can be called to get the
284
     * data from the associated card object in the format that the
285
     * API requires.
286
     *
287
     * @return array
288
     */
289 21
    public function getCardData()
290
    {
291 21
        $card                = $this->getCard();
292 21
        $cardReference       = $this->getCardReference();
293 21
        $data                = array();
294 21
        $data['instalments'] = $this->getInstallments();
295
296
        // We try first for the card reference
297 21
        if ($cardReference) {
298 6
            $data['creditcard']['token']  = $cardReference;
299 15
        } elseif ($card) {
300 12
            $card->validate();
301 12
            $data['creditcard']['card_name']     = $card->getName();
302 12
            $data['creditcard']['card_number']   = $card->getNumber();
303 12
            $data['creditcard']['card_due_date'] = $card->getExpiryMonth() . '/' . $card->getExpiryYear();
304 12
            if ($card->getCvv()) {
305 12
                $data['creditcard']['card_cvv']  = $card->getCvv();
306
            }
307
        }
308
309 21
        return $data;
310
    }
311
    /**
312
     * Get the boleto data.
313
     *
314
     * Because the Ebanx gateway uses a common format for passing
315
     * boleto data to the API, this function can be called to get the
316
     * data from the associated request object in the format that the
317
     * API requires.
318
     *
319
     * @return array
320
     */
321 6
    public function getBoletoData()
322
    {
323 6
        $this->validate('boletoDueDate');
324
325 6
        $data                  = array();
326 6
        $data['due_date'] = $this->getBoletoDueDate();
327 6
        return $data;
328
    }
329
330
    /**
331
     * Get the address data.
332
     *
333
     * Because the Ebanx gateway uses a common format for passing
334
     * address data to the API, this function can be called to get the
335
     * data from the associated card object in the format that the
336
     * API requires.
337
     *
338
     * @return array
339
     */
340 27
    public function getAddressData()
341
    {
342 27
        $card    = $this->getCard();
343 27
        $address = array_map('trim', explode(',', $card->getAddress1()));
344
345 27
        $data                  = array();
346 27
        $data['address']       = $address[0];
347 27
        $data['street_number'] = isset($address[1]) ? $address[1] : '';
348 27
        $data['street_complement'] = isset($address[2]) ? $address[2] : '';
349 27
        $data['city']          = $card->getCity();
350 27
        $data['state']         = $card->getState();
351 27
        $data['country']       = $card->getCountry();
352 27
        $data['zipcode']       = $card->getPostcode();
353
354 27
        return $data;
355
    }
356
357
    /**
358
     * Get the split data.
359
     *
360
     * Because the Ebanx gateway uses a common format for passing
361
     * split payment data to the API, this function can be called to get the
362
     * data from the associated request in the format that the
363
     * API requires.
364
     *
365
     * @return array
366
     */
367 33
    public function getSplitData()
368
    {
369 33
        $split = $this->getSplit();
370 33
        return !empty($split) ? ['split' => $split] : [];
371
    }
372
373
    /**
374
     * Get the payment data.
375
     *
376
     * Because the Ebanx gateway uses a common format for passing
377
     * payment data to the API, this function can be called to get the
378
     * data from the associated card object in the format that the
379
     * API requires.
380
     *
381
     * @return array
382
     */
383 21
    public function getPaymentData($aditionalPaymentData = [])
384
    {
385 21
        $this->validate('transactionId', 'currency', 'amount', 'paymentMethod');
386
387 21
        $customerData = $this->getCustomerData();
388 21
        $addressData  = $this->getAddressData();
389 21
        $splitData    = $this->getSplitData();
390
391 21
        $paymentData                          = array();
392 21
        $paymentData['merchant_payment_code'] = $this->getTransactionId();
393 21
        $paymentData['currency_code']         = $this->getCurrency();
394 21
        $paymentData['amount_total']          = $this->getAmount();
395 21
        $paymentData['payment_type_code']     = $this->getPaymentMethod();
396
397 21
        if ($notifyUrl = $this->getNotifyUrl()) {
398 3
            $paymentData['notification_url']      = $notifyUrl;
399
        }
400 21
        if ($returnUrl = $this->getReturnUrl()) {
401 3
            $paymentData['redirect_url']      = $returnUrl;
402
        }
403
404 21
        if ($paymentNote = $this->getNote()) {
405 3
            $paymentData['note']      = $paymentNote;
406
        }
407
408 21
        $paymentData = array_merge(
409 21
            $customerData,
410 21
            $addressData,
411 21
            $paymentData,
412 21
            $splitData,
413 21
            $aditionalPaymentData
414
        );
415
416 21
        return ['payment' => $paymentData];
417
    }
418
419
    /**
420
     * Get installments.
421
     *
422
     * @return integer the number of installments
423
     */
424 24
    public function getInstallments()
425
    {
426 24
        return $this->getParameter('installments') ?: 1;
427
    }
428
429
    /**
430
     * Set Installments.
431
     *
432
     * The number must be between 1 and 12.
433
     * If the payment method is boleto defaults to 1.
434
     *
435
     * @param  integer $value
436
     * @return AuthorizeRequest provides a fluent interface.
437
     */
438 6
    public function setInstallments($value)
439
    {
440 6
        return $this->setParameter('installments', (int) $value);
441
    }
442
}
443