1
|
|
|
<?php declare(strict_types=1); |
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-2019 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
|
61 |
|
public function __construct($options = []) |
47
|
|
|
{ |
48
|
|
|
/* |
49
|
|
|
* Allow on instantiation to overwrite the defaults |
50
|
|
|
*/ |
51
|
61 |
|
$this->options = array_merge( |
52
|
61 |
|
$this->options, |
53
|
61 |
|
$options |
54
|
|
|
); |
55
|
|
|
$config = [ |
56
|
61 |
|
'base_uri' => sprintf( |
57
|
61 |
|
'%s://%s:%s/', |
58
|
61 |
|
$this->options['scheme'], |
59
|
61 |
|
$this->options['hostname'], |
60
|
61 |
|
$this->options['port'] |
61
|
|
|
), |
62
|
|
|
'verify' => false, |
63
|
|
|
'headers' => [ |
64
|
61 |
|
'User-Agent' => 'SmartcallRestfulAPIClient-PHP/'.self::VERSION.' '.\GuzzleHttp\default_user_agent(), |
65
|
|
|
], |
66
|
|
|
]; |
67
|
61 |
|
parent::__construct($config); |
68
|
61 |
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Set the bearer token. |
72
|
|
|
* |
73
|
|
|
* @param string $token Bearer Token from Auth request |
74
|
|
|
* |
75
|
|
|
* @return void |
76
|
|
|
*/ |
77
|
45 |
|
public function setBearerToken($token): void |
78
|
|
|
{ |
79
|
45 |
|
$this->options['token'] = $token; |
80
|
45 |
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Set the password for basic authentication. |
84
|
|
|
* |
85
|
|
|
* @param string $password Password for use with basic authentication |
86
|
|
|
* |
87
|
|
|
* @return void |
88
|
|
|
*/ |
89
|
5 |
|
public function setPassword($password): void |
90
|
|
|
{ |
91
|
5 |
|
$this->options['password'] = $password; |
92
|
5 |
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Set the username for basic authentication. |
96
|
|
|
* |
97
|
|
|
* @param string $username Username for use with basic authentication |
98
|
|
|
* |
99
|
|
|
* @return void |
100
|
|
|
*/ |
101
|
5 |
|
public function setUsername($username): void |
102
|
|
|
{ |
103
|
5 |
|
$this->options['username'] = $username; |
104
|
5 |
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Authenticate and get Bearer token from SmartCall. |
108
|
|
|
* |
109
|
|
|
* @throws Exception |
110
|
|
|
* |
111
|
|
|
* @return array |
112
|
|
|
*/ |
113
|
4 |
View Code Duplication |
public function auth() |
|
|
|
|
114
|
|
|
{ |
115
|
|
|
try { |
116
|
4 |
|
$response = $this->post( |
117
|
4 |
|
'/webservice/auth', |
118
|
|
|
[ |
119
|
|
|
'headers' => [ |
120
|
4 |
|
'Authorization' => $this->bearerOrBasic(), |
121
|
|
|
], |
122
|
|
|
] |
123
|
|
|
); |
124
|
|
|
|
125
|
|
|
return [ |
126
|
1 |
|
'status' => 'ok', |
127
|
1 |
|
'http_code' => $response->getStatusCode(), |
128
|
1 |
|
'body' => (string) $response->getBody(), |
129
|
|
|
]; |
130
|
3 |
|
} catch (\GuzzleHttp\Exception\ClientException $e) { |
131
|
3 |
|
return $this->clientError($e); |
132
|
|
|
} catch (\GuzzleHttp\Exception\ServerException $e) { |
133
|
|
|
return $this->parseError($e); |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Authenticate and invalidates all the user allocated tokens. |
139
|
|
|
* |
140
|
|
|
* @throws Exception |
141
|
|
|
* |
142
|
|
|
* @return array |
143
|
|
|
*/ |
144
|
2 |
View Code Duplication |
public function authDelete() |
|
|
|
|
145
|
|
|
{ |
146
|
|
|
try { |
147
|
2 |
|
$response = $this->delete( |
148
|
2 |
|
'/webservice/auth', |
149
|
|
|
[ |
150
|
|
|
'headers' => [ |
151
|
2 |
|
'Authorization' => $this->bearerOrBasic(), |
152
|
|
|
], |
153
|
|
|
] |
154
|
|
|
); |
155
|
|
|
|
156
|
|
|
return [ |
157
|
1 |
|
'status' => 'ok', |
158
|
1 |
|
'http_code' => $response->getStatusCode(), |
159
|
1 |
|
'body' => (string) $response->getBody(), |
160
|
|
|
]; |
161
|
1 |
|
} catch (\GuzzleHttp\Exception\ClientException $e) { |
162
|
1 |
|
return $this->clientError($e); |
163
|
|
|
} catch (\GuzzleHttp\Exception\ServerException $e) { |
164
|
|
|
return $this->parseError($e); |
165
|
|
|
} |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Authenticate and invalidates all the user allocated tokens. |
170
|
|
|
* |
171
|
|
|
* @throws Exception |
172
|
|
|
* |
173
|
|
|
* @return array |
174
|
|
|
*/ |
175
|
3 |
View Code Duplication |
public function authFlush() |
|
|
|
|
176
|
|
|
{ |
177
|
|
|
try { |
178
|
3 |
|
$response = $this->delete( |
179
|
3 |
|
'/webservice/auth/token', |
180
|
|
|
[ |
181
|
|
|
'headers' => [ |
182
|
3 |
|
'Authorization' => $this->bearerOrBasic(), |
183
|
|
|
], |
184
|
|
|
] |
185
|
|
|
); |
186
|
|
|
|
187
|
|
|
return [ |
188
|
2 |
|
'status' => 'ok', |
189
|
2 |
|
'http_code' => $response->getStatusCode(), |
190
|
2 |
|
'body' => (string) $response->getBody(), |
191
|
|
|
]; |
192
|
1 |
|
} catch (\GuzzleHttp\Exception\ClientException $e) { |
193
|
1 |
|
return $this->clientError($e); |
194
|
|
|
} catch (\GuzzleHttp\Exception\ServerException $e) { |
195
|
|
|
return $this->parseError($e); |
196
|
|
|
} |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* Authenticate and gets the number of available session tokens. |
201
|
|
|
* |
202
|
|
|
* @throws Exception |
203
|
|
|
* |
204
|
|
|
* @return array |
205
|
|
|
*/ |
206
|
3 |
View Code Duplication |
public function authToken() |
|
|
|
|
207
|
|
|
{ |
208
|
|
|
try { |
209
|
3 |
|
$response = $this->get( |
210
|
3 |
|
'/webservice/auth/token', |
211
|
|
|
[ |
212
|
|
|
'headers' => [ |
213
|
3 |
|
'Authorization' => $this->bearerOrBasic(), |
214
|
|
|
], |
215
|
|
|
] |
216
|
|
|
); |
217
|
|
|
|
218
|
|
|
return [ |
219
|
1 |
|
'status' => 'ok', |
220
|
1 |
|
'http_code' => $response->getStatusCode(), |
221
|
1 |
|
'body' => (string) $response->getBody(), |
222
|
|
|
]; |
223
|
2 |
|
} catch (\GuzzleHttp\Exception\ClientException $e) { |
224
|
2 |
|
return $this->clientError($e); |
225
|
|
|
} catch (\GuzzleHttp\Exception\ServerException $e) { |
226
|
|
|
return $this->parseError($e); |
227
|
|
|
} |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* Gets the current connection status to the various mobile networks. |
232
|
|
|
* |
233
|
|
|
* @throws Exception |
234
|
|
|
* |
235
|
|
|
* @return array |
236
|
|
|
*/ |
237
|
3 |
View Code Duplication |
public function health() |
|
|
|
|
238
|
|
|
{ |
239
|
|
|
try { |
240
|
3 |
|
$response = $this->get( |
241
|
3 |
|
'/webservice/utilities/health', |
242
|
|
|
[ |
243
|
|
|
'headers' => [ |
244
|
3 |
|
'Authorization' => $this->bearerOrBasic(), |
245
|
|
|
], |
246
|
|
|
] |
247
|
|
|
); |
248
|
|
|
|
249
|
|
|
return [ |
250
|
1 |
|
'status' => 'ok', |
251
|
1 |
|
'http_code' => $response->getStatusCode(), |
252
|
1 |
|
'body' => (string) $response->getBody(), |
253
|
|
|
]; |
254
|
2 |
|
} catch (\GuzzleHttp\Exception\ClientException $e) { |
255
|
2 |
|
return $this->clientError($e); |
256
|
|
|
} catch (\GuzzleHttp\Exception\ServerException $e) { |
257
|
|
|
return $this->parseError($e); |
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Gets the mobile network on which the SIM is connected. |
263
|
|
|
* |
264
|
|
|
* @param string $msisdn |
265
|
|
|
* |
266
|
|
|
* @throws Exception |
267
|
|
|
* |
268
|
|
|
* @return array |
269
|
|
|
*/ |
270
|
4 |
View Code Duplication |
public function simnetwork($msisdn) |
|
|
|
|
271
|
|
|
{ |
272
|
|
|
try { |
273
|
4 |
|
$response = $this->get( |
274
|
4 |
|
sprintf( |
275
|
4 |
|
'/webservice/utilities/simnetwork/%d', |
276
|
4 |
|
$msisdn |
277
|
|
|
), |
278
|
|
|
[ |
279
|
|
|
'headers' => [ |
280
|
4 |
|
'Authorization' => $this->bearerOrBasic(), |
281
|
|
|
], |
282
|
|
|
] |
283
|
|
|
); |
284
|
|
|
|
285
|
|
|
return [ |
286
|
2 |
|
'status' => 'ok', |
287
|
2 |
|
'http_code' => $response->getStatusCode(), |
288
|
2 |
|
'body' => (string) $response->getBody(), |
289
|
|
|
]; |
290
|
2 |
|
} catch (\GuzzleHttp\Exception\ClientException $e) { |
291
|
2 |
|
return $this->clientError($e); |
292
|
|
|
} catch (\GuzzleHttp\Exception\ServerException $e) { |
293
|
|
|
return $this->parseError($e); |
294
|
|
|
} |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* Test SmartCall is responding. |
299
|
|
|
* |
300
|
|
|
* @throws Exception |
301
|
|
|
* |
302
|
|
|
* @return array |
303
|
|
|
*/ |
304
|
1 |
|
public function ping() |
305
|
|
|
{ |
306
|
|
|
try { |
307
|
1 |
|
$response = $this->get( |
308
|
1 |
|
'/webservice/test/ping' |
309
|
|
|
); |
310
|
|
|
|
311
|
|
|
return [ |
312
|
1 |
|
'status' => 'ok', |
313
|
1 |
|
'http_code' => $response->getStatusCode(), |
314
|
1 |
|
'body' => (string) $response->getBody(), |
315
|
|
|
]; |
316
|
|
|
} catch (\GuzzleHttp\Exception\ClientException $e) { |
317
|
|
|
return $this->clientError($e); |
318
|
|
|
} catch (\GuzzleHttp\Exception\ServerException $e) { |
319
|
|
|
return $this->parseError($e); |
320
|
|
|
} |
321
|
|
|
} |
322
|
|
|
|
323
|
|
|
/** |
324
|
|
|
* Parse the java exception that we receive from Smartcall's Tomcat's. |
325
|
|
|
* |
326
|
|
|
* @param \GuzzleHttp\Exception\ClientException $exception |
327
|
|
|
* |
328
|
|
|
* @return array |
329
|
|
|
*/ |
330
|
29 |
View Code Duplication |
private function clientError(\GuzzleHttp\Exception\ClientException $exception): array |
|
|
|
|
331
|
|
|
{ |
332
|
29 |
|
$body = (string) $exception->getResponse()->getBody(); |
333
|
|
|
|
334
|
|
|
return [ |
335
|
29 |
|
'status' => 'error', |
336
|
29 |
|
'http_code' => $exception->getResponse()->getStatusCode(), |
337
|
29 |
|
'body' => json_decode($body), |
338
|
|
|
]; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* Parse the java exception that we receive from Smartcall's Tomcat's. |
343
|
|
|
* |
344
|
|
|
* @param \GuzzleHttp\Exception\ServerException $exception |
345
|
|
|
* |
346
|
|
|
* @return array |
347
|
|
|
*/ |
348
|
|
View Code Duplication |
private function parseError(\GuzzleHttp\Exception\ServerException $exception): array |
|
|
|
|
349
|
|
|
{ |
350
|
|
|
$body = (string) $exception->getResponse()->getBody(); |
351
|
|
|
preg_match('/<p><b>(JBWEB\d{6}): type<\/b> (JBWEB\d{6}): Exception report<\/p><p><b>(JBWEB\d{6}): message<\/b> <u>(.*[^<\/u>])<\/u><\/p><p><b>(JBWEB\d{6}): description<\/b> <u>(.+[^<\/u>])<\/u><\/p>/ims', $body, $matches); |
352
|
|
|
|
353
|
|
|
return [ |
354
|
|
|
'status' => 'error', |
355
|
|
|
'http_code' => $exception->getResponse()->getStatusCode(), |
356
|
|
|
'body' => $matches['6'], |
357
|
|
|
]; |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
/** |
361
|
|
|
* Use basic authentication header content if bearer token is not set. |
362
|
|
|
* |
363
|
|
|
* @return string |
364
|
|
|
*/ |
365
|
56 |
|
private function bearerOrBasic(): string |
366
|
|
|
{ |
367
|
|
|
/** |
368
|
|
|
* Get the function calling this method. |
369
|
|
|
*/ |
370
|
56 |
|
$caller = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2)[1]['function']; |
371
|
|
|
|
372
|
|
|
if ( |
373
|
56 |
|
!in_array( |
374
|
56 |
|
$caller, |
375
|
|
|
[ |
376
|
56 |
|
'auth', |
377
|
|
|
] |
378
|
|
|
) |
379
|
|
|
) { |
380
|
52 |
|
return sprintf( |
381
|
52 |
|
'Bearer %s', |
382
|
52 |
|
$this->options['token'] |
383
|
|
|
); |
384
|
|
|
} |
385
|
|
|
|
386
|
4 |
|
return sprintf( |
387
|
4 |
|
'Basic %s', |
388
|
4 |
|
base64_encode( |
389
|
4 |
|
sprintf( |
390
|
4 |
|
'%s:%s', |
391
|
4 |
|
$this->options['username'], |
392
|
4 |
|
$this->options['password'] |
393
|
|
|
) |
394
|
|
|
) |
395
|
|
|
); |
396
|
|
|
} |
397
|
|
|
} |
398
|
|
|
|
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.