1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace UON; |
4
|
|
|
|
5
|
|
|
use GuzzleHttp\Exception\GuzzleException; |
6
|
|
|
use UON\Interfaces\ConfigInterface; |
7
|
|
|
use UON\Interfaces\ClientInterface; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* @author Paul Rock <[email protected]> |
11
|
|
|
* @link http://drteam.rocks |
12
|
|
|
* @license MIT |
13
|
|
|
* @package UON |
14
|
|
|
*/ |
15
|
|
|
class Client implements ClientInterface |
16
|
|
|
{ |
17
|
|
|
/** |
18
|
|
|
* Initial state of some variables |
19
|
|
|
*/ |
20
|
|
|
protected $_client; |
21
|
|
|
protected $_config; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Default server parameters |
25
|
|
|
*/ |
26
|
|
|
protected $host = 'api.u-on.ru'; |
27
|
|
|
protected $port = '443'; |
28
|
|
|
protected $path = '/'; |
29
|
|
|
protected $useSSL = true; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* User initial values |
33
|
|
|
* |
34
|
|
|
* @var string |
35
|
|
|
*/ |
36
|
|
|
protected $token; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Default format of output |
40
|
|
|
* |
41
|
|
|
* @var string |
42
|
|
|
*/ |
43
|
|
|
protected $format = 'json'; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Count of tries |
47
|
|
|
* |
48
|
|
|
* @var int |
49
|
|
|
*/ |
50
|
|
|
private $tries = self::TRIES; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Waiting time per each try |
54
|
|
|
* |
55
|
|
|
* @var int |
56
|
|
|
*/ |
57
|
|
|
private $seconds = self::SECONDS; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Timeout of every try |
61
|
|
|
* |
62
|
|
|
* @var float |
63
|
|
|
*/ |
64
|
|
|
private $maxRequestTimeout = self::MAX_REQUEST_TIMEOUT; |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Client constructor. |
68
|
|
|
* |
69
|
|
|
* @param Config $config User defined configuration |
70
|
|
|
*/ |
71
|
2 |
|
public function __construct(Config $config) |
72
|
|
|
{ |
73
|
|
|
// Extract toke from config |
74
|
2 |
|
$this->token = $config->get('token'); |
|
|
|
|
75
|
|
|
|
76
|
|
|
// Count of tries |
77
|
2 |
|
if ($config->get('tries') !== false) { |
78
|
|
|
$this->tries = $config->get('tries'); |
|
|
|
|
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
// Waiting time |
82
|
2 |
|
if ($config->get('seconds') !== false) { |
83
|
|
|
$this->seconds = $config->get('seconds'); |
|
|
|
|
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
// Max request timeout per try |
87
|
2 |
|
if ($config->get('maxRequestTimeout') !== false) { |
88
|
|
|
$this->maxRequestTimeout = $config->get('maxRequestTimeout'); |
|
|
|
|
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
// Save config into local variable |
92
|
2 |
|
$this->_config = $config; |
93
|
|
|
|
94
|
|
|
// Store the client object |
95
|
2 |
|
$this->_client = new \GuzzleHttp\Client($config->getParameters(true)); |
96
|
2 |
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Request executor with timeout and repeat tries |
100
|
|
|
* |
101
|
|
|
* @param string $type Request method |
102
|
|
|
* @param string $url endpoint url |
103
|
|
|
* @param array $params List of parameters |
104
|
|
|
* @return bool|\Psr\Http\Message\ResponseInterface |
105
|
|
|
* @throws \GuzzleHttp\Exception\GuzzleException |
106
|
|
|
*/ |
107
|
61 |
|
public function repeatRequest($type, $url, $params) |
108
|
|
|
{ |
109
|
61 |
|
for ($i = 0; $i < $this->tries; $i++) { |
110
|
|
|
|
111
|
|
|
// Execute the request to server |
112
|
61 |
|
$result = \in_array($type, self::ALLOWED_METHODS, false) |
113
|
61 |
|
? $this->_client->request($type, $url, ['timeout' => $this->maxRequestTimeout, 'form_params' => $params]) |
114
|
61 |
|
: null; |
115
|
|
|
|
116
|
|
|
// Check the code status |
117
|
61 |
|
$code = $result->getStatusCode(); |
|
|
|
|
118
|
|
|
|
119
|
|
|
// If code is not 405 (but 200 foe example) then exit from loop |
120
|
61 |
|
if ($code === 200 || $code === 500) { |
121
|
60 |
|
return $result; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
// Waiting in seconds |
125
|
1 |
|
sleep($this->seconds); |
126
|
1 |
|
} |
127
|
|
|
|
128
|
|
|
// Return false if loop is done but no answer from server |
129
|
1 |
|
return false; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Make the request and analyze the result |
134
|
|
|
* |
135
|
|
|
* @param string $type Request method |
136
|
|
|
* @param string $endpoint Api request endpoint |
137
|
|
|
* @param array $params List of parameters |
138
|
|
|
* @param bool $raw Return data in raw format |
139
|
|
|
* @return mixed|false Array with data or error, or False when something went fully wrong |
140
|
|
|
*/ |
141
|
61 |
|
public function doRequest($type, $endpoint, array $params = [], $raw = false) |
142
|
|
|
{ |
143
|
|
|
// Create the base URL |
144
|
61 |
|
$base = $this->useSSL ? 'https' : 'http'; |
145
|
|
|
|
146
|
|
|
// Generate the URL for request |
147
|
61 |
|
$url = $base . '://' . $this->host . ':' . $this->port . $this->path . $this->token . $endpoint . '.' . $this->format; |
148
|
|
|
|
149
|
|
|
try { |
150
|
|
|
// Execute the request to server |
151
|
61 |
|
$result = $this->repeatRequest($type, $url, $params); |
152
|
|
|
|
153
|
|
|
// Return result |
154
|
|
|
return |
155
|
61 |
|
($result === false) |
|
|
|
|
156
|
61 |
|
? false |
157
|
1 |
|
: [ |
158
|
60 |
|
'code' => $result->getStatusCode(), |
159
|
60 |
|
'reason' => $result->getReasonPhrase(), |
160
|
60 |
|
'message' => $raw ? (string) $result->getBody() : json_decode($result->getBody()) |
161
|
61 |
|
]; |
162
|
|
|
|
163
|
|
|
} catch (GuzzleException $e) { |
164
|
|
|
echo $e->getMessage() . "\n"; |
165
|
|
|
echo $e->getTrace(); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
return false; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
} |
172
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.