CurlClient   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 25
c 2
b 0
f 0
lcom 1
cbo 14
dl 0
loc 165
ccs 60
cts 60
cp 1
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A setConnectTimeout() 0 6 1
A setTimeout() 0 6 1
A setHostname() 0 13 1
B report() 0 21 5
A isValidMaxMindResponse() 0 12 4
C getMaxMindExceptionByCodeAndMessage() 0 26 11
1
<?php
2
3
/**
4
 * This file is part of Pachico\MaxMind\MinFraudChargeback. (https://github.com/pachico/maxmind-minfraud-chargeback)
5
 *
6
 * @link https://github.com/pachico/maxmind-minfraud-chargeback for the canonical source repository
7
 * @copyright Copyright (c) 2016-2017 Mariano F.co Benítez Mulet. (https://github.com/pachico/)
8
 * @license https://raw.githubusercontent.com/pachico/maxmind-minfraud-chargeback/master/LICENSE.md MIT
9
 */
10
11
namespace Pachico\MaxMind\MinFraudChargeback\Http;
12
13
use Pachico\MaxMind\MinFraudChargeback\Auth\Credential;
14
use Pachico\MaxMind\MinFraudChargeback\Chargeback;
15
use Pachico\MaxMind\MinFraudChargeback\Exception\ExceptionAbstract;
16
use Pachico\MaxMind\MinFraudChargeback\Exception;
17
use Curl\Curl;
18
use Webmozart\Assert\Assert;
19
use RuntimeException;
20
21
/**
22
 * This is the class that handles the business logic for the request to MaxMind
23
 */
24
class CurlClient implements ClientInterface
25
{
26
    /**
27
     * The URI for this service
28
     * The minfraud.maxmind.com hostname automatically picks the data center geographically
29
     * closest to you. In some cases, this data center may not be the one
30
     * that provides you with the best service. You can explicitly try the
31
     * following hostnames to see which one provides the best performance for you:
32
     * @see https://minfraud.maxmind.com/minfraud/chargeback.
33
     */
34
    const HOSTNAME_DEFAULT = 'https://minfraud.maxmind.com/minfraud/chargeback';
35
    const HOSTNAME_US_EAST = 'https://minfraud-us-east.maxmind.com/minfraud/chargeback';
36
    const HOSTNAME_US_WEST = 'https://minfraud-us-west.maxmind.com/minfraud/chargeback';
37
    const HOSTNAME_EU_WEST = 'https://minfraud-eu-west.maxmind.com/minfraud/chargeback';
38
39
    /**
40
     * @var Credential
41
     */
42
    private $credential;
43
    /**
44
     * @var Curl
45
     */
46
    private $curl;
47
    /**
48
     * @var string
49
     */
50
    private $hostname;
51
52
    /**
53
     * @param Credential $credential
54
     * @param Curl $curl
55
     */
56 24
    public function __construct(Credential $credential, Curl $curl = null)
57
    {
58 24
        $this->credential = $credential;
59
60 24
        $this->curl = $curl ? : new Curl();
61
62 24
        $this->hostname = static::HOSTNAME_DEFAULT;
63 24
    }
64
65
    /**
66
     * @param int $seconds
67
     *
68
     * @return CurlClient
69
     */
70 1
    public function setConnectTimeout($seconds)
71
    {
72 1
        $this->curl->setConnectTimeout($seconds);
73
74 1
        return $this;
75
    }
76
77
    /**
78
     * @param string $seconds
79
     *
80
     * @return CurlClient
81
     */
82 1
    public function setTimeout($seconds)
83
    {
84 1
        $this->curl->setTimeout($seconds);
85
86 1
        return $this;
87
    }
88
89
    /**
90
     * @param string $hostname
91
     *
92
     * @return CurlClient
93
     */
94 2
    public function setHostname($hostname)
95
    {
96 2
        Assert::oneOf($hostname, [
97 2
            static::HOSTNAME_DEFAULT,
98 2
            static::HOSTNAME_EU_WEST,
99 2
            static::HOSTNAME_US_EAST,
100
            static::HOSTNAME_US_WEST
101 2
        ]);
102
103 1
        $this->hostname = $hostname;
104
105 1
        return $this;
106
    }
107
108
    /**
109
     * @param Chargeback $chargeback
110
     *
111
     * @throws ExceptionAbstract
112
     * @throws RuntimeException
113
     *
114
     * @return bool
115
     */
116 3
    public function report(Chargeback $chargeback)
117
    {
118 3
        $this->curl->setBasicAuthentication(
119 3
            $this->credential->getUser(),
120 3
            $this->credential->getPassword()
121 3
        );
122
123 3
        $this->curl->setHeader('Content-Type', 'application/json');
124
125 3
        $this->curl->post($this->hostname, $chargeback->toArray());
126
127 3
        if ($this->curl->error && !$this->curl->response) {
128 1
            throw new RuntimeException($this->curl->errorMessage);
129
        }
130
131 2
        if ($this->curl->error && $this->isValidMaxMindResponse($this->curl->response)) {
132 1
            throw $this->getMaxMindExceptionByCodeAndMessage($this->curl->response->code, $this->curl->response->error);
133
        }
134
135 1
        return true;
136
    }
137
138
    /**
139
     * @param mixed $content
140
     *
141
     * @return boolean
142
     */
143 7
    protected function isValidMaxMindResponse($content)
144
    {
145 7
        if (!$content instanceof \stdClass) {
146 2
            return false;
147
        }
148
149 5
        if (!property_exists($content, 'code') || !property_exists($content, 'error')) {
150 3
            return false;
151
        }
152
153 2
        return true;
154
    }
155
156
    /**
157
     * @param string $code
158
     * @param string $message
159
     *
160
     * @return ExceptionAbstract
161
     */
162 12
    protected function getMaxMindExceptionByCodeAndMessage($code, $message)
163
    {
164
        switch ($code) {
165 12
            case ExceptionAbstract::AUTHORIZATION_INVALID:
166 2
                return new Exception\UnauthorizedException($message);
167 10
            case ExceptionAbstract::FRAUD_SCORE_INVALID:
168 1
                return new Exception\InvalidFraudScoreException($message);
169 9
            case ExceptionAbstract::IP_ADDRESS_INVALID:
170 9
            case ExceptionAbstract::IP_ADDRESS_RESERVED:
171 2
                return new Exception\InvalidIpException($message);
172 7
            case ExceptionAbstract::JSON_INVALID:
173 1
                return new Exception\InvalidJSONException($message);
174 6
            case ExceptionAbstract::LICENSE_KEY_REQUIRED:
175 1
                return new Exception\InvalidLicenceException($message);
176 5
            case ExceptionAbstract::MAXMIND_ID_INVALID:
177 1
                return new Exception\InvalidMaxMindIdException($message);
178 4
            case ExceptionAbstract::MINFRAUD_ID_INVALID:
179 1
                return new Exception\InvalidMinFraudIdException($message);
180 3
            case ExceptionAbstract::PARAMETER_UNKNOWN:
181 1
                return new Exception\UnknownParameterException($message);
182 2
            case ExceptionAbstract::USER_ID_REQUIRED:
183 1
                return new Exception\InvalidUserIdException($message);
184 1
            default:
185 1
                return new Exception\ServiceUnavailableException();
186 1
        }
187
    }
188
}
189