Completed
Branch refactor (d45ac9)
by Pol
18:06 queued 07:07
created

RandomOrgAPI::validateResponse()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 40
Code Lines 27

Duplication

Lines 8
Ratio 20 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 8
loc 40
rs 6.7272
ccs 0
cts 22
cp 0
cc 7
eloc 27
nc 7
nop 1
crap 56
1
<?php
2
3
namespace drupol\Yaroc;
4
5
use drupol\Yaroc\Plugin\MethodPluginInterface;
6
use Http\Client\HttpClient;
7
use Psr\Http\Message\ResponseInterface;
8
9
/**
10
 * Class RandomOrgAPI.
11
 */
12
class RandomOrgAPI implements RandomOrgAPIInterface
13
{
14
    /**
15
     * The default Random.org endpoint template.
16
     *
17
     * @var string;
18
     */
19
    private $endpoint = 'https://api.random.org/json-rpc/1/invoke';
20
21
    /**
22
     * The configuration.
23
     *
24
     * @var array
25
     */
26
    private $configuration;
27
28
    /**
29
     * The HTTP client.
30
     *
31
     * @var \Http\Client\HttpClient
32
     */
33
    private $httpClient;
34
35
    /**
36
     * RandomOrgAPI constructor.
37
     *
38
     * @param array $configuration
39
     */
40 5
    public function __construct(array $configuration = [])
41
    {
42 5
        $this->configuration = $configuration;
43 5
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 2
    public function withApiKey(string $apikey)
49
    {
50 2
        $clone = clone $this;
51
52 2
        return $clone->setApiKey($apikey);
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 1
    public function withEndPoint(string $endpoint)
59
    {
60 1
        $clone = clone $this;
61
62 1
        return $clone->setEndPoint($endpoint);
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 1
    public function withHttpClient(HttpClient $client)
69
    {
70 1
        $clone = clone $this;
71
72 1
        return $clone->setHttpClient($client);
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78 1
    public function getEndPoint()
79
    {
80 1
        return $this->endpoint;
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86 1
    public function getApiKey()
87
    {
88 1
        $configuration = $this->getConfiguration();
89
90 1
        $configuration += ['apiKey' => ''];
91
92 1
        return $configuration['apiKey'];
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function call(MethodPluginInterface $methodPlugin)
99
    {
100
        return $this->validateResponse($methodPlugin
101
            ->withEndPoint($this->getEndPoint())
102
            ->withApiKey($this->getApiKey())->call());
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function get(MethodPluginInterface $methodPlugin)
109
    {
110
        return json_decode(
111
            (string) $this
0 ignored issues
show
Bug introduced by
The method getBody does only exist in Psr\Http\Message\ResponseInterface, but not in Exception.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
112
                ->call($methodPlugin)
113
                ->getBody()
114
                ->getContents(),
115
            true
116
        );
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122
    public function getData(MethodPluginInterface $methodPlugin)
123
    {
124
        $data = $this->get($methodPlugin);
125
126
        if (!isset($data['result'])) {
127
            return false;
128
        }
129
130
        if (isset($data['result']['random']) && isset($data['result']['random']['data'])) {
131
            return $data['result']['random']['data'];
132
        }
133
134
        return false;
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140 2
    public function getConfiguration()
141
    {
142 2
        return $this->configuration;
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148 1
    public function getHttpClient()
149
    {
150 1
        return $this->httpClient;
151
    }
152
153
    /**
154
     * @param string $apikey
155
     *
156
     * @return $this
157
     */
158 2
    private function setApiKey(string $apikey)
159
    {
160 2
        $configuration = $this->getConfiguration();
161 2
        $configuration['apiKey'] = $apikey;
162
163 2
        return $this->setConfiguration($configuration);
164
    }
165
166
    /**
167
     * @param string $endpoint
168
     *
169
     * @return $this
170
     */
171 1
    private function setEndPoint(string $endpoint)
172
    {
173 1
        $this->endpoint = $endpoint;
174
175 1
        return $this;
176
    }
177
178
    /**
179
     * Validate the response.
180
     *
181
     * @param \Psr\Http\Message\ResponseInterface $response
182
     *
183
     * @return \Exception|ResponseInterface
184
     */
185
    private function validateResponse(ResponseInterface $response)
186
    {
187
        if (200 == $response->getStatusCode()) {
188
            $body = json_decode((string) $response->getBody()->getContents(), true);
189
190
            if (isset($body['error']['code'])) {
191
                switch ($body['error']['code']) {
192 View Code Duplication
                    case -32600:
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...
193
                        throw new \InvalidArgumentException(
194
                            'Invalid Request: ' . $body['error']['message'],
195
                            $body['error']['code']
196
                        );
197
                    case -32601:
198
                        throw new \BadFunctionCallException(
199
                            'Procedure not found: ' . $body['error']['message'],
200
                            $body['error']['code']
201
                        );
202 View Code Duplication
                    case -32602:
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...
203
                        throw new \InvalidArgumentException(
204
                            'Invalid arguments: ' . $body['error']['message'],
205
                            $body['error']['code']
206
                        );
207 View Code Duplication
                    case -32603:
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...
208
                        throw new \RuntimeException(
209
                            'Internal Error: ' . $body['error']['message'],
210
                            $body['error']['code']
211
                        );
212 View Code Duplication
                    default:
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...
213
                        throw new \RuntimeException(
214
                            'Invalid request/response: ' . $body['error']['message'],
215
                            $body['error']['code']
216
                        );
217
                }
218
            }
219
        }
220
221
        $response->getBody()->rewind();
222
223
        return $response;
224
    }
225
226
    /**
227
     * @param $configuration
228
     *
229
     * @return $this
230
     */
231 2
    private function setConfiguration($configuration)
232
    {
233 2
        $this->configuration = $configuration;
234
235 2
        return $this;
236
    }
237
238
    /**
239
     * Set the HTTP client.
240
     *
241
     * @param \Http\Client\HttpClient $client
242
     *
243
     * @return \drupol\Yaroc\RandomOrgAPI
244
     */
245 1
    private function setHttpClient(HttpClient $client)
246
    {
247 1
        $this->httpClient = $client;
248
249 1
        return $this;
250
    }
251
}
252