WebservicePurchaseResponse::__construct()   C
last analyzed

Complexity

Conditions 12
Paths 32

Size

Total Lines 63
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 12.0167

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 41
c 1
b 0
f 0
nc 32
nop 2
dl 0
loc 63
ccs 39
cts 41
cp 0.9512
crap 12.0167
rs 6.9666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Omnipay\Redsys\Message;
4
5
use AvaiBookSports\Component\RedsysMessages\Exception\CatalogNotFoundException;
6
use AvaiBookSports\Component\RedsysMessages\Factory;
7
use AvaiBookSports\Component\RedsysMessages\Loader\CatalogLoader;
8
use Omnipay\Common\Exception\InvalidResponseException;
9
use Omnipay\Common\Message\RequestInterface;
10
11
/**
12
 * Redsys Purchase Response.
13
 */
14
class WebservicePurchaseResponse extends AbstractResponse
15
{
16
    /** @var string */
17
    protected $returnSignature;
18
19
    /** @var bool */
20
    protected $usingUpcaseResponse = false;
21
22
    /** @var CatalogInterface */
0 ignored issues
show
Bug introduced by
The type Omnipay\Redsys\Message\CatalogInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
    protected $redsysMessages;
24
25
    /**
26
     * Constructor.
27
     *
28
     * @param RequestInterface $request the initiating request
29
     * @param mixed            $data
30
     *
31
     * @throws InvalidResponseException If resopnse format is incorrect, data is missing, or signature does not match
32
     */
33
    public function __construct(RequestInterface $request, $data)
34 13
    {
35
        parent::__construct($request, $data);
36 13
37
        try {
38
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage(array_key_exists('language', $this->request->getParameters()) ? $this->request->getParameters()['language'] : 'en');
0 ignored issues
show
Documentation Bug introduced by
It seems like new AvaiBookSports\Compo...s()['language'] : 'en') of type AvaiBookSports\Component...ssages\CatalogInterface is incompatible with the declared type Omnipay\Redsys\Message\CatalogInterface of property $redsysMessages.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
39 13
        } catch (CatalogNotFoundException $e) {
40 13
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage('en');
41
        }
42
43
        $security = new Security();
44 13
45
        if (!isset($data['CODIGO'])) {
46 13
            throw new InvalidResponseException('Invalid response from payment gateway (no data)');
47 1
        }
48
49
        if (!isset($data['OPERACION'])) {
50 12
            if ('0' == $data['CODIGO']) {
51 3
                throw new InvalidResponseException('Invalid response from payment gateway (no data)');
52 1
            } else {
53
                if (null === $this->getMessage()) {
54 2
                    throw new InvalidResponseException('Invalid response from payment gateway: "'.$this->getCode().'"');
55 2
                } else {
56
                    throw new InvalidResponseException('Invalid response from payment gateway: "'.$this->getCode().': '.$this->getMessage().'"');
57
                }
58
            }
59
        }
60
61
        if (isset($data['OPERACION']['DS_ORDER'])) {
62 9
            $this->usingUpcaseResponse = true;
63 1
        }
64 1
65
        $order = $this->GetKey('Ds_Order');
66 9
        if (null === $order) {
67 9
            throw new InvalidResponseException();
68 1
        }
69
70
        $signature_keys = [
71
            'Ds_Amount',
72 8
            'Ds_Order',
73 8
            'Ds_MerchantCode',
74 8
            'Ds_Currency',
75 8
            'Ds_Response',
76 8
            'Ds_TransactionType',
77 8
            'Ds_SecurePayment',
78 8
        ];
79 8
        $signature_data = '';
80 8
        foreach ($signature_keys as $key) {
81 8
            $value = $this->getKey($key);
82 8
            if (null === $value) {
83 8
                throw new InvalidResponseException('Invalid response from payment gateway (missing data)');
84 1
            }
85
            $signature_data .= $value;
86 8
        }
87 8
88
        $this->returnSignature = $security->createSignature(
89 7
            $signature_data,
90 7
            $order,
91 7
            $this->request->getHmacKey()
0 ignored issues
show
Bug introduced by
The method getHmacKey() does not exist on Omnipay\Common\Message\RequestInterface. It seems like you code against a sub-type of Omnipay\Common\Message\RequestInterface such as Omnipay\Redsys\Message\AbstractRequest. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

91
            $this->request->/** @scrutinizer ignore-call */ 
92
                            getHmacKey()
Loading history...
92 7
        );
93 7
94
        if ($this->returnSignature != $this->GetKey('Ds_Signature')) {
95 7
            throw new InvalidResponseException('Invalid response from payment gateway (signature mismatch)');
96 1
        }
97
    }
98 6
99
    public function isSuccessful()
100 6
    {
101
        $response_code = $this->getKey('Ds_Response');
102 6
103
        // check for field existence as well as value
104
        return isset($this->data['CODIGO'])
105 6
            && '0' == $this->data['CODIGO']
106 6
            && null !== $response_code
107 6
            && is_numeric($response_code)
108 6
            && 0 <= $response_code
109 6
            && 100 > $response_code;
110 6
    }
111
112
    /**
113
     * Helper method to get a specific response parameter if available.
114
     *
115
     * @param string $key The key to look up
116
     *
117
     * @return mixed|null
118
     */
119
    protected function getKey($key)
120 11
    {
121
        if ($this->usingUpcaseResponse) {
122 11
            $key = strtoupper($key);
123 1
        }
124 1
125
        return isset($this->data['OPERACION'][$key]) ? $this->data['OPERACION'][$key] : null;
126 11
    }
127
128
    /**
129
     * Get the authorisation code if available.
130
     *
131
     * @return string|null
132
     */
133
    public function getTransactionReference()
134 3
    {
135
        return $this->getAuthorisationCode();
136 3
    }
137
138
    /**
139
     * Get the merchant message if available.
140
     *
141
     * @return string|null A response message from the payment gateway
142
     */
143
    public function getMessage()
144 2
    {
145
        $message = $this->redsysMessages->getDsResponseMessage($this->getCode());
146 2
147
        if (null === $message) {
148 2
            $message = $this->redsysMessages->getErrorMessage($this->getCode());
149 2
        }
150 2
151
        return $message;
152 2
    }
153
154
    /**
155
     * Get the merchant response code if available.
156
     *
157
     * @return string|null
158
     */
159
    public function getCode()
160 8
    {
161
        $code = $this->getKey('Ds_Response');
162 8
163
        if (null === $code) {
164 8
            $code = $this->data['CODIGO'];
165 2
        }
166 2
167
        return $code;
168 8
    }
169
170
    /**
171
     * Get the merchant data if available.
172
     *
173
     * @return string|null
174
     */
175
    public function getMerchantData()
176 1
    {
177
        return $this->getKey('Ds_MerchantData');
178 1
    }
179
180
    /**
181
     * Get the card country if available.
182
     *
183
     * @return string|null ISO 3166-1 (3-digit numeric) format, if supplied
184
     */
185
    public function getCardCountry()
186 1
    {
187
        return $this->getKey('Ds_Card_Country');
188 1
    }
189
}
190