PluginProbe ʕ •ᴥ•ʔ
Backup Migration / 1.4.9
Backup Migration v1.4.9
2.1.6 2.1.5.2 trunk 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.6.1 1.4.7 1.4.8 1.4.9 1.4.9.1 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.5.1
backup-backup / analyst / src / ApiRequestor.php
backup-backup / analyst / src Last commit date
Account 11 months ago Cache 11 months ago Contracts 11 months ago Core 11 months ago Http 11 months ago Notices 11 months ago Analyst.php 11 months ago ApiRequestor.php 11 months ago ApiResponse.php 11 months ago Collector.php 11 months ago Mutator.php 11 months ago helpers.php 11 months ago
ApiRequestor.php
258 lines
1 <?php
2
3 namespace Analyst;
4
5 use Exception;
6 use Analyst\Contracts\HttpClientContract;
7 use Analyst\Contracts\RequestorContract;
8
9 class ApiRequestor implements RequestorContract
10 {
11 /**
12 * Supported http client
13 *
14 * @var HttpClientContract
15 */
16 protected $httpClient;
17
18 /**
19 * @var string
20 */
21 protected $clientId;
22
23 /**
24 * @var string
25 */
26 protected $clientSecret;
27
28 /**
29 * @var string
30 */
31 protected $apiBase;
32
33 /**
34 * Default headers to be sent
35 *
36 * @var array
37 */
38 protected $defaultHeaders = [
39 'accept' => 'application/json',
40 'content-type' => 'application/json'
41 ];
42
43 /**
44 * Prioritized http clients
45 *
46 * @var array
47 */
48 protected $availableClients = [
49 'Analyst\Http\WordPressHttpClient',
50 'Analyst\Http\CurlHttpClient',
51 'Analyst\Http\DummyHttpClient',
52 ];
53
54 /**
55 * ApiRequestor constructor.
56 * @param $id
57 * @param $secret
58 * @param $apiBase
59 * @throws \Exception
60 */
61 public function __construct($id, $secret, $apiBase)
62 {
63 $this->clientId = $id;
64 $this->clientSecret = $secret;
65
66 $this->setApiBase($apiBase);
67
68 $this->httpClient = $this->resolveHttpClient();
69 }
70
71 /**
72 * Set api base url
73 *
74 * @param $url
75 */
76 public function setApiBase($url)
77 {
78 $this->apiBase = $url;
79 }
80
81 /**
82 * Get request
83 *
84 * @param $url
85 * @param array $headers
86 * @return mixed
87 */
88 public function get($url, $headers = [])
89 {
90 return $this->request('GET', $url, null, $headers);
91 }
92
93 /**
94 * Post request
95 *
96 * @param $url
97 * @param $body
98 * @param array $headers
99 * @return mixed
100 */
101 public function post($url, $body = [], $headers = [])
102 {
103 return $this->request('POST', $url, $body, $headers);
104 }
105
106 /**
107 * Put request
108 *
109 * @param $url
110 * @param $body
111 * @param array $headers
112 * @return mixed
113 */
114 public function put($url, $body = [], $headers = [])
115 {
116 return $this->request('PUT', $url, $body, $headers);
117 }
118
119 /**
120 * Delete request
121 *
122 * @param $url
123 * @param array $headers
124 * @return mixed
125 */
126 public function delete($url, $headers = [])
127 {
128 return $this->request('DELETE', $url, null, $headers);
129 }
130
131 /**
132 * Make request to api
133 *
134 * @param $method
135 * @param $url
136 * @param array $body
137 * @param array $headers
138 * @return mixed
139 */
140 protected function request($method, $url, $body = [], $headers = [])
141 {
142 $fullUrl = $this->resolveFullUrl($url);
143
144 $date = date('r', time());
145
146 $headers['date'] = $date;
147 $headers['signature'] = $this->resolveSignature($this->clientSecret, $method, $fullUrl, $body, $date);
148
149 // Lowercase header names
150 $headers = $this->prepareHeaders(
151 array_merge($headers, $this->defaultHeaders)
152 );
153
154 $response = $this->httpClient->request($method, $fullUrl, $body, $headers);
155
156 // TODO: Check response code and take actions
157
158 return $response;
159 }
160
161 /**
162 * Set one default header
163 *
164 * @param $header
165 * @param $value
166 */
167 public function setDefaultHeader($header, $value)
168 {
169 $this->defaultHeaders[
170 $this->resolveValidHeaderName($header)
171 ] = $value;
172 }
173
174 /**
175 * Resolves supported http client
176 *
177 * @return HttpClientContract
178 * @throws Exception
179 */
180 protected function resolveHttpClient()
181 {
182 $clients = array_filter($this->availableClients, $this->guessClientSupportEnvironment());
183
184 if (!isset($clients[0])) {
185 throw new Exception('There is no http client which this application can support');
186 }
187
188 // Instantiate first supported http client
189 return new $clients[0];
190 }
191
192 /**
193 * This will filter out clients which is not supported
194 * by the current environment
195 *
196 * @return \Closure
197 */
198 protected function guessClientSupportEnvironment()
199 {
200 return function ($client) {
201 return forward_static_call([$client, 'hasSupport']);
202 };
203 }
204
205 /**
206 * Resolves valid header name
207 *
208 * @param $headerName
209 * @return string
210 */
211 private function resolveValidHeaderName($headerName)
212 {
213 return strtolower($headerName);
214 }
215
216 /**
217 * Lowercase header names
218 *
219 * @param $headers
220 * @return array
221 */
222 private function prepareHeaders($headers)
223 {
224 return array_change_key_case($headers, CASE_LOWER);
225 }
226
227 /**
228 * Sign request
229 *
230 * @param $key
231 * @param $method
232 * @param $url
233 * @param $body
234 * @param $date
235 *
236 * @return false|string
237 */
238 private function resolveSignature($key, $method, $url, $body, $date)
239 {
240 $string = implode('\n', [$method, $url, md5(json_encode($body)), $date]);
241
242 $contentSecret = hash_hmac('sha256', $string, $key);
243
244 return sprintf('%s:%s', $this->clientId, $contentSecret);
245 }
246
247 /**
248 * Compose full url
249 *
250 * @param $url
251 * @return string
252 */
253 private function resolveFullUrl($url)
254 {
255 return sprintf('%s/%s', $this->apiBase, trim($url, '/'));
256 }
257 }
258