2014-11-06 02:44:52 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace RetailCrm\Http;
|
|
|
|
|
|
|
|
use RetailCrm\Exception\CurlException;
|
|
|
|
use RetailCrm\Response\ApiResponse;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* HTTP client
|
|
|
|
*/
|
|
|
|
class Client
|
|
|
|
{
|
|
|
|
const METHOD_GET = 'GET';
|
|
|
|
const METHOD_POST = 'POST';
|
|
|
|
|
|
|
|
protected $url;
|
|
|
|
protected $defaultParameters;
|
2015-04-30 17:35:57 +03:00
|
|
|
protected $retry;
|
2014-11-06 02:44:52 +03:00
|
|
|
|
|
|
|
public function __construct($url, array $defaultParameters = array())
|
|
|
|
{
|
|
|
|
if (false === stripos($url, 'https://')) {
|
|
|
|
throw new \InvalidArgumentException('API schema requires HTTPS protocol');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->url = $url;
|
|
|
|
$this->defaultParameters = $defaultParameters;
|
2015-04-30 17:35:57 +03:00
|
|
|
$this->retry = 0;
|
2014-11-06 02:44:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Make HTTP request
|
|
|
|
*
|
2014-11-10 03:12:50 +03:00
|
|
|
* @param string $path
|
|
|
|
* @param string $method (default: 'GET')
|
|
|
|
* @param array $parameters (default: array())
|
|
|
|
* @param int $timeout
|
2015-04-30 17:35:57 +03:00
|
|
|
* @param bool $verify
|
2015-05-04 18:54:57 +03:00
|
|
|
* @param bool $debug
|
2014-11-06 02:44:52 +03:00
|
|
|
* @return ApiResponse
|
|
|
|
*/
|
2015-05-04 18:47:14 +03:00
|
|
|
public function makeRequest($path, $method, array $parameters = array(), $timeout = 30, $verify = false, $debug = false)
|
2014-11-06 02:44:52 +03:00
|
|
|
{
|
|
|
|
$allowedMethods = array(self::METHOD_GET, self::METHOD_POST);
|
|
|
|
if (!in_array($method, $allowedMethods)) {
|
|
|
|
throw new \InvalidArgumentException(sprintf(
|
|
|
|
'Method "%s" is not valid. Allowed methods are %s',
|
|
|
|
$method,
|
|
|
|
implode(', ', $allowedMethods)
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
$parameters = array_merge($this->defaultParameters, $parameters);
|
|
|
|
|
|
|
|
$path = $this->url . $path;
|
|
|
|
if (self::METHOD_GET === $method && sizeof($parameters)) {
|
|
|
|
$path .= '?' . http_build_query($parameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
$ch = curl_init();
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $path);
|
2015-05-04 18:56:30 +03:00
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, (int) $timeout);
|
|
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (int) $timeout);
|
2015-04-30 17:35:57 +03:00
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
2014-11-10 03:12:50 +03:00
|
|
|
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
2015-04-30 17:35:57 +03:00
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify);
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verify);
|
2014-11-06 02:44:52 +03:00
|
|
|
|
|
|
|
if (self::METHOD_POST === $method) {
|
|
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
|
|
|
|
}
|
|
|
|
|
2015-05-04 18:47:14 +03:00
|
|
|
$responseBody = $this->curlExec($ch, $debug);
|
2014-11-06 02:44:52 +03:00
|
|
|
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
$errno = curl_errno($ch);
|
|
|
|
$error = curl_error($ch);
|
|
|
|
curl_close($ch);
|
|
|
|
|
|
|
|
if ($errno) {
|
|
|
|
throw new CurlException($error, $errno);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new ApiResponse($statusCode, $responseBody);
|
|
|
|
}
|
2015-04-30 17:35:57 +03:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param resource $ch
|
2015-05-04 18:47:14 +03:00
|
|
|
* @param boolean $debug
|
2015-04-30 17:35:57 +03:00
|
|
|
* @return mixed
|
|
|
|
*/
|
2015-05-04 18:47:14 +03:00
|
|
|
private function curlExec($ch, $debug) {
|
2015-04-30 17:35:57 +03:00
|
|
|
$exec = curl_exec($ch);
|
|
|
|
|
|
|
|
if (curl_errno($ch) && in_array(curl_errno($ch), array(6, 7, 28, 34, 35)) && $this->retry < 3) {
|
|
|
|
$this->retry += 1;
|
2015-05-04 18:47:14 +03:00
|
|
|
|
|
|
|
if ($debug) {
|
|
|
|
error_log('CURL RETRY #' . $this->retry . PHP_EOL, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->curlExec($ch, $debug);
|
2015-04-30 17:35:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return $exec;
|
|
|
|
}
|
2014-11-10 03:12:50 +03:00
|
|
|
}
|