Passed
Push — master ( 60f89c...3e6fc7 )
by Jacques
02:01
created

Client   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 307
Duplicated Lines 36.48 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 82.18%

Importance

Changes 9
Bugs 1 Features 0
Metric Value
wmc 23
c 9
b 1
f 0
lcom 1
cbo 6
dl 112
loc 307
ccs 83
cts 101
cp 0.8218
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 23 1
A setBearerToken() 0 4 1
A setPassword() 0 4 1
A setUsername() 0 4 1
A auth() 23 23 3
A authDelete() 23 23 3
A authFlush() 23 23 3
A authToken() 23 23 3
A ping() 0 18 3
A clientError() 10 10 1
A parseError() 10 11 1
B bearerOrBasic() 0 32 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * SmartCall Restful API (v3) HTTP Client.
4
 *
5
 * PLEASE NOTE: The interface is very fluid while the intial integration
6
 * is taking place.  It will be refactored in the near future.
7
 *
8
 * @author    Jacques Marneweck <[email protected]>
9
 * @copyright 2017-2018 Jacques Marneweck.  All rights strictly reserved.
10
 * @license   MIT
11
 */
12
13
namespace Jacques\Smartcall\HttpClient;
14
15
use Jacques\Smartcall\HttpClient\Traits\SmartLoad;
16
use Jacques\Smartcall\HttpClient\Traits\SmartRica;
17
18
class Client extends \GuzzleHttp\Client
19
{
20
    use SmartLoad;
21
    use SmartRica;
22
23
    /**
24
     * @const string Version number
25
     */
26
    const VERSION = '0.0.1';
27
28
    /**
29
     * Defaults to expecting that Apache Tomcat runs on port 8080 on localhost
30
     * (127.0.0.1).
31
     *
32
     * @var array
33
     */
34
    protected $options = [
35
        'scheme'   => 'https',
36
        'hostname' => 'localhost',
37
        'port'     => '8080',
38
        'token'    => null,
39
        'username' => null,
40
        'password' => null,
41
    ];
42
43
    /**
44
     * @param array $options
45
     */
46 22
    public function __construct($options = [])
47
    {
48
        /*
49
         * Allow on instantiation to overwrite the defaults
50
         */
51 22
        $this->options = array_merge(
52 22
            $this->options,
53 22
            $options
54
        );
55
        $config = [
56 22
            'base_uri' => sprintf(
57 22
                '%s://%s:%s/',
58 22
                $this->options['scheme'],
59 22
                $this->options['hostname'],
60 22
                $this->options['port']
61
            ),
62
            'verify'  => false,
63
            'headers' => [
64 22
                'User-Agent' => 'SmartcallRestfulAPIClient-PHP/'.self::VERSION.' '.\GuzzleHttp\default_user_agent(),
65
            ],
66
        ];
67 22
        parent::__construct($config);
68 22
    }
69
70
    /**
71
     * Set the bearer token.
72
     *
73
     * @param string $token Bearer Token from Auth request
74
     */
75 11
    public function setBearerToken($token)
76
    {
77 11
        $this->options['token'] = $token;
78 11
    }
79
80
    /**
81
     * Set the password for basic authentication.
82
     *
83
     * @param string $password Password for use with basic authentication
84
     */
85 1
    public function setPassword($password)
86
    {
87 1
        $this->options['password'] = $password;
88 1
    }
89
90
    /**
91
     * Set the username for basic authentication.
92
     *
93
     * @param string $username Username for use with basic authentication
94
     */
95 1
    public function setUsername($username)
96
    {
97 1
        $this->options['username'] = $username;
98 1
    }
99
100
    /**
101
     * Authenticate and get Bearer token from SmartCall.
102
     *
103
     * @throws Exception
104
     *
105
     * @return array
106
     */
107 3 View Code Duplication
    public function auth()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
108
    {
109
        try {
110 3
            $response = $this->post(
111 3
                '/webservice/auth',
112
                [
113
                    'headers' => [
114 3
                        'Authorization' => $this->bearerOrBasic(),
115
                    ],
116
                ]
117
            );
118
119
            return [
120 1
                'status'    => 'ok',
121 1
                'http_code' => $response->getStatusCode(),
122 1
                'body'      => (string) $response->getBody(),
123
            ];
124 2
        } catch (\GuzzleHttp\Exception\ClientException $e) {
125 2
            return $this->clientError($e);
126
        } catch (\GuzzleHttp\Exception\ServerException $e) {
127
            return $this->parseError($e);
128
        }
129
    }
130
131
    /**
132
     * Authenticate and invalidates all the user allocated tokens.
133
     *
134
     * @throws Exception
135
     *
136
     * @return array
137
     */
138 2 View Code Duplication
    public function authDelete()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
139
    {
140
        try {
141 2
            $response = $this->delete(
142 2
                '/webservice/auth',
143
                [
144
                    'headers' => [
145 2
                        'Authorization' => $this->bearerOrBasic(),
146
                    ],
147
                ]
148
            );
149
150
            return [
151 1
                'status'    => 'ok',
152 1
                'http_code' => $response->getStatusCode(),
153 1
                'body'      => (string) $response->getBody(),
154
            ];
155 1
        } catch (\GuzzleHttp\Exception\ClientException $e) {
156 1
            return $this->clientError($e);
157
        } catch (\GuzzleHttp\Exception\ServerException $e) {
158
            return $this->parseError($e);
159
        }
160
    }
161
162
    /**
163
     * Authenticate and invalidates all the user allocated tokens.
164
     *
165
     * @throws Exception
166
     *
167
     * @return array
168
     */
169 3 View Code Duplication
    public function authFlush()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
170
    {
171
        try {
172 3
            $response = $this->delete(
173 3
                '/webservice/auth/token',
174
                [
175
                    'headers' => [
176 3
                        'Authorization' => $this->bearerOrBasic(),
177
                    ],
178
                ]
179
            );
180
181
            return [
182 2
                'status'    => 'ok',
183 2
                'http_code' => $response->getStatusCode(),
184 2
                'body'      => (string) $response->getBody(),
185
            ];
186 1
        } catch (\GuzzleHttp\Exception\ClientException $e) {
187 1
            return $this->clientError($e);
188
        } catch (\GuzzleHttp\Exception\ServerException $e) {
189
            return $this->parseError($e);
190
        }
191
    }
192
193
    /**
194
     * Authenticate and gets the number of available session tokens.
195
     *
196
     * @throws Exception
197
     *
198
     * @return array
199
     */
200 3 View Code Duplication
    public function authToken()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
201
    {
202
        try {
203 3
            $response = $this->get(
204 3
                '/webservice/auth/token',
205
                [
206
                    'headers' => [
207 3
                        'Authorization' => $this->bearerOrBasic(),
208
                    ],
209
                ]
210
            );
211
212
            return [
213 1
                'status'    => 'ok',
214 1
                'http_code' => $response->getStatusCode(),
215 1
                'body'      => (string) $response->getBody(),
216
            ];
217 2
        } catch (\GuzzleHttp\Exception\ClientException $e) {
218 2
            return $this->clientError($e);
219
        } catch (\GuzzleHttp\Exception\ServerException $e) {
220
            return $this->parseError($e);
221
        }
222
    }
223
224
    /**
225
     * Test SmartCall is responding.
226
     *
227
     * @throws Exception
228
     *
229
     * @return array
230
     */
231 1
    public function ping()
232
    {
233
        try {
234 1
            $response = $this->get(
235 1
                '/webservice/test/ping'
236
            );
237
238
            return [
239 1
                'status'    => 'ok',
240 1
                'http_code' => $response->getStatusCode(),
241 1
                'body'      => (string) $response->getBody(),
242
            ];
243
        } catch (\GuzzleHttp\Exception\ClientException $e) {
244
            return $this->clientError($e);
245
        } catch (\GuzzleHttp\Exception\ServerException $e) {
246
            return $this->parseError($e);
247
        }
248
    }
249
250
    /**
251
     * Parse the java exception that we receive from Smartcall's Tomcat's.
252
     *
253
     * @param \GuzzleHttp\Exception\ClientException $exception
254
     *
255
     * @return array
256
     */
257 9 View Code Duplication
    private function clientError(\GuzzleHttp\Exception\ClientException $exception)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
258
    {
259 9
        $body = (string) $exception->getResponse()->getBody();
260
261
        return [
262 9
            'status'    => 'error',
263 9
            'http_code' => $exception->getResponse()->getStatusCode(),
264 9
            'body'      => json_decode($body),
265
        ];
266
    }
267
268
    /**
269
     * Parse the java exception that we receive from Smartcall's Tomcat's.
270
     *
271
     * @param \GuzzleHttp\Exception\ServerException $exception
272
     *
273
     * @return array
274
     */
275 View Code Duplication
    private function parseError(\GuzzleHttp\Exception\ServerException $exception)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
276
    {
277
        $body = (string) $exception->getResponse()->getBody();
278
        preg_match('!<p><b>type</b> Exception report</p><p><b>message</b> <u>(.*[^</u>])</u></p><p><b>description</b>!', $body, $matches);
279
280
        return [
281
            'status'    => 'error',
282
            'http_code' => $exception->getResponse()->getStatusCode(),
283
            'body'      => $matches['1'],
284
        ];
285
    }
286
287
    /**
288
     * Use basic authentication header content if bearer token  is not set.
289
     *
290
     * @return string
291
     */
292 17
    private function bearerOrBasic()
293
    {
294
        /**
295
         * Get the function calling this method.
296
         */
297 17
        $caller = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2)[1]['function'];
298
299
        if (
300 17
            !in_array(
301 17
                $caller,
302
                [
303 17
                    'auth',
304
                ]
305
            )
306
        ) {
307 14
            return sprintf(
308 14
                'Bearer %s',
309 14
                $this->options['token']
310
            );
311
        }
312
313 3
        return sprintf(
314 3
            'Basic %s',
315 3
            base64_encode(
316 3
                sprintf(
317 3
                    '%s:%s',
318 3
                    $this->options['username'],
319 3
                    $this->options['password']
320
                )
321
            )
322
        );
323
    }
324
}
325