* @license https://opensource.org/licenses/MIT MIT License * @link http://www.retailcrm.ru/docs/Developers/ApiVersion5 */ namespace RetailCrm\Http; use RetailCrm\Exception\CurlException; use RetailCrm\Exception\InvalidJsonException; use RetailCrm\Exception\LimitException; use RetailCrm\Response\ApiResponse; /** * PHP version 5.4 * * HTTP client * * @category RetailCrm * @package RetailCrm * @author RetailCrm * @license https://opensource.org/licenses/MIT MIT License * @link http://www.retailcrm.ru/docs/Developers/ApiVersion5 */ class Client { const METHOD_GET = 'GET'; const METHOD_POST = 'POST'; protected $url; protected $defaultParameters; /** * Client constructor. * * @param string $url api url * @param array $defaultParameters array of parameters * * @throws \InvalidArgumentException */ public function __construct($url, array $defaultParameters = []) { if (false === stripos($url, 'https://')) { throw new \InvalidArgumentException( 'API schema requires HTTPS protocol' ); } $this->url = $url; $this->defaultParameters = $defaultParameters; } /** * Make HTTP request * * @param string $path request url * @param string $method (default: 'GET') * @param array $parameters (default: array()) * @param bool $fullPath (default: false) * * @SuppressWarnings(PHPMD.ExcessiveParameterList) * * @throws \InvalidArgumentException * @throws CurlException * @throws InvalidJsonException * * @return ApiResponse */ public function makeRequest( $path, $method, array $parameters = [], $fullPath = false ) { $allowedMethods = [self::METHOD_GET, self::METHOD_POST]; if (!in_array($method, $allowedMethods, false)) { throw new \InvalidArgumentException( sprintf( 'Method "%s" is not valid. Allowed methods are %s', $method, implode(', ', $allowedMethods) ) ); } $parameters = array_merge($this->defaultParameters, $parameters); $url = $fullPath ? $path : $this->url . $path; if (self::METHOD_GET === $method && count($parameters)) { $url .= '?' . http_build_query($parameters, '', '&'); } $curlHandler = curl_init(); curl_setopt($curlHandler, CURLOPT_URL, $url); curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curlHandler, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curlHandler, CURLOPT_FAILONERROR, false); curl_setopt($curlHandler, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curlHandler, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curlHandler, CURLOPT_TIMEOUT, 30); curl_setopt($curlHandler, CURLOPT_CONNECTTIMEOUT, 30); if (self::METHOD_POST === $method) { curl_setopt($curlHandler, CURLOPT_POST, true); curl_setopt($curlHandler, CURLOPT_POSTFIELDS, $parameters); } $responseBody = curl_exec($curlHandler); $statusCode = curl_getinfo($curlHandler, CURLINFO_HTTP_CODE); if ($statusCode == 503) { throw new LimitException("Service temporary unavalable"); } $errno = curl_errno($curlHandler); $error = curl_error($curlHandler); curl_close($curlHandler); if ($errno) { throw new CurlException($error, $errno); } return new ApiResponse($statusCode, $responseBody); } }