first commit
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst;
|
||||
|
||||
use Exception;
|
||||
use Analyst\Contracts\HttpClientContract;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
class ApiRequestor implements RequestorContract
|
||||
{
|
||||
/**
|
||||
* Supported http client
|
||||
*
|
||||
* @var HttpClientContract
|
||||
*/
|
||||
protected $httpClient;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $clientId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $clientSecret;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $apiBase;
|
||||
|
||||
/**
|
||||
* Default headers to be sent
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaultHeaders = [
|
||||
'accept' => 'application/json',
|
||||
'content-type' => 'application/json'
|
||||
];
|
||||
|
||||
/**
|
||||
* Prioritized http clients
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $availableClients = [
|
||||
'Analyst\Http\WordPressHttpClient',
|
||||
'Analyst\Http\CurlHttpClient',
|
||||
'Analyst\Http\DummyHttpClient',
|
||||
];
|
||||
|
||||
/**
|
||||
* ApiRequestor constructor.
|
||||
* @param $id
|
||||
* @param $secret
|
||||
* @param $apiBase
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($id, $secret, $apiBase)
|
||||
{
|
||||
$this->clientId = $id;
|
||||
$this->clientSecret = $secret;
|
||||
|
||||
$this->setApiBase($apiBase);
|
||||
|
||||
$this->httpClient = $this->resolveHttpClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set api base url
|
||||
*
|
||||
* @param $url
|
||||
*/
|
||||
public function setApiBase($url)
|
||||
{
|
||||
$this->apiBase = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request
|
||||
*
|
||||
* @param $url
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($url, $headers = [])
|
||||
{
|
||||
return $this->request('GET', $url, null, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post request
|
||||
*
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($url, $body = [], $headers = [])
|
||||
{
|
||||
return $this->request('POST', $url, $body, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put request
|
||||
*
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function put($url, $body = [], $headers = [])
|
||||
{
|
||||
return $this->request('PUT', $url, $body, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete request
|
||||
*
|
||||
* @param $url
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($url, $headers = [])
|
||||
{
|
||||
return $this->request('DELETE', $url, null, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make request to api
|
||||
*
|
||||
* @param $method
|
||||
* @param $url
|
||||
* @param array $body
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
protected function request($method, $url, $body = [], $headers = [])
|
||||
{
|
||||
$fullUrl = $this->resolveFullUrl($url);
|
||||
|
||||
$date = date('r', time());
|
||||
|
||||
$headers['date'] = $date;
|
||||
$headers['signature'] = $this->resolveSignature($this->clientSecret, $method, $fullUrl, $body, $date);
|
||||
|
||||
// Lowercase header names
|
||||
$headers = $this->prepareHeaders(
|
||||
array_merge($headers, $this->defaultHeaders)
|
||||
);
|
||||
|
||||
$response = $this->httpClient->request($method, $fullUrl, $body, $headers);
|
||||
|
||||
// TODO: Check response code and take actions
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set one default header
|
||||
*
|
||||
* @param $header
|
||||
* @param $value
|
||||
*/
|
||||
public function setDefaultHeader($header, $value)
|
||||
{
|
||||
$this->defaultHeaders[
|
||||
$this->resolveValidHeaderName($header)
|
||||
] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves supported http client
|
||||
*
|
||||
* @return HttpClientContract
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function resolveHttpClient()
|
||||
{
|
||||
$clients = array_filter($this->availableClients, $this->guessClientSupportEnvironment());
|
||||
|
||||
if (!isset($clients[0])) {
|
||||
throw new Exception('There is no http client which this application can support');
|
||||
}
|
||||
|
||||
// Instantiate first supported http client
|
||||
return new $clients[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* This will filter out clients which is not supported
|
||||
* by the current environment
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function guessClientSupportEnvironment()
|
||||
{
|
||||
return function ($client) {
|
||||
return forward_static_call([$client, 'hasSupport']);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves valid header name
|
||||
*
|
||||
* @param $headerName
|
||||
* @return string
|
||||
*/
|
||||
private function resolveValidHeaderName($headerName)
|
||||
{
|
||||
return strtolower($headerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowercase header names
|
||||
*
|
||||
* @param $headers
|
||||
* @return array
|
||||
*/
|
||||
private function prepareHeaders($headers)
|
||||
{
|
||||
return array_change_key_case($headers, CASE_LOWER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign request
|
||||
*
|
||||
* @param $key
|
||||
* @param $method
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param $date
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
private function resolveSignature($key, $method, $url, $body, $date)
|
||||
{
|
||||
$string = implode('\n', [$method, $url, md5(json_encode($body)), $date]);
|
||||
|
||||
$contentSecret = hash_hmac('sha256', $string, $key);
|
||||
|
||||
return sprintf('%s:%s', $this->clientId, $contentSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose full url
|
||||
*
|
||||
* @param $url
|
||||
* @return string
|
||||
*/
|
||||
private function resolveFullUrl($url)
|
||||
{
|
||||
return sprintf('%s/%s', $this->apiBase, trim($url, '/'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user