1
0
mirror of synced 2024-11-25 23:06:07 +03:00
api-client-php/lib/RetailCrm/Http/Client.php

259 lines
6.9 KiB
PHP
Raw Normal View History

<?php
/**
* PHP version 5.4
*
* HTTP client
*
* @category RetailCrm
* @package RetailCrm
*/
namespace RetailCrm\Http;
use Psr\Log\LoggerInterface;
use RetailCrm\Exception\CurlException;
2016-03-12 01:54:33 +03:00
use RetailCrm\Exception\InvalidJsonException;
use RetailCrm\Exception\LimitException;
2020-12-29 12:18:32 +03:00
use RetailCrm\Exception\NotFoundException;
use RetailCrm\Response\ApiResponse;
/**
* PHP version 5.4
2016-03-09 02:31:29 +03:00
*
* HTTP client
2016-03-09 02:31:29 +03:00
*
* @category RetailCrm
* @package RetailCrm
*/
class Client
{
const METHOD_GET = 'GET';
const METHOD_POST = 'POST';
protected $url;
protected $defaultParameters;
2020-08-21 10:24:55 +03:00
protected $options;
/**
* @var LoggerInterface|null $logger
*/
protected $logger;
2016-03-09 02:31:29 +03:00
/**
* Client constructor.
*
* @param string $url api url
* @param array $defaultParameters array of parameters
2019-08-30 14:10:52 +03:00
* @param bool $debug debug mode
2016-03-12 01:54:33 +03:00
*
* @throws \InvalidArgumentException
2016-03-09 02:31:29 +03:00
*/
2019-08-30 14:10:52 +03:00
public function __construct($url, array $defaultParameters = [], $debug = false)
{
2019-08-30 14:10:52 +03:00
if (false === stripos($url, 'https://') && false === $debug) {
2016-03-09 02:31:29 +03:00
throw new \InvalidArgumentException(
'API schema requires HTTPS protocol'
);
}
$this->url = $url;
$this->defaultParameters = $defaultParameters;
2020-08-21 10:24:55 +03:00
$this->options = new RequestOptions();
}
/**
* Make HTTP request
*
2016-03-09 02:31:29 +03:00
* @param string $path request url
* @param string $method (default: 'GET')
* @param array $parameters (default: array())
2018-01-10 11:35:57 +03:00
* @param bool $fullPath (default: false)
2016-03-09 02:31:29 +03:00
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*
2016-03-12 01:54:33 +03:00
* @throws \InvalidArgumentException
* @throws CurlException
* @throws InvalidJsonException
*
* @return ApiResponse
*/
2020-02-11 10:57:17 +03:00
public function makeRawRequest(
2015-05-08 18:03:05 +03:00
$path,
$method,
array $parameters = [],
$fullPath = false
2015-05-08 18:03:05 +03:00
) {
$allowedMethods = [self::METHOD_GET, self::METHOD_POST];
2016-03-12 01:54:33 +03:00
if (!in_array($method, $allowedMethods, false)) {
2016-03-09 02:31:29 +03:00
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;
2015-05-08 18:03:05 +03:00
2016-03-12 01:54:33 +03:00
if (self::METHOD_GET === $method && count($parameters)) {
2016-01-09 15:23:50 +03:00
$url .= '?' . http_build_query($parameters, '', '&');
}
2019-08-30 14:10:52 +03:00
if (self::METHOD_POST === $method && '/files/upload' == $path) {
$url .= '?apiKey=' . $parameters['apiKey'];
}
2016-03-12 01:54:33 +03:00
$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);
2020-08-21 10:24:55 +03:00
curl_setopt($curlHandler, CURLOPT_TIMEOUT, $this->options->getClientTimeout());
curl_setopt($curlHandler, CURLOPT_CONNECTTIMEOUT, $this->options->getClientTimeout());
if ($this->options->getHeaders()) {
curl_setopt($curlHandler, CURLOPT_HTTPHEADER, $this->options->getHttpHeaders());
}
$this->logRequest($url, $method, $parameters);
if (self::METHOD_POST === $method) {
2016-03-12 01:54:33 +03:00
curl_setopt($curlHandler, CURLOPT_POST, true);
2019-08-30 14:10:52 +03:00
if ('/files/upload' == $path) {
2020-02-11 10:57:17 +03:00
curl_setopt($curlHandler, CURLOPT_POSTFIELDS, file_get_contents($parameters['file']));
2019-08-30 14:10:52 +03:00
} else {
curl_setopt($curlHandler, CURLOPT_POSTFIELDS, $parameters);
}
}
2020-12-29 14:28:36 +03:00
list($statusCode, $responseBody) = $this->checkResponse($curlHandler, $method);
2015-05-08 18:03:05 +03:00
return new ApiResponse($statusCode, $responseBody);
}
2020-02-11 10:57:17 +03:00
/**
* Make HTTP request and deserialize JSON body (throws exception otherwise)
*
* @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
) {
return $this->makeRawRequest($path, $method, $parameters, $fullPath)->asJsonResponse();
}
2020-08-21 10:24:55 +03:00
/**
* Set request options
*
* @param RequestOptions $options
*/
public function setOptions(RequestOptions $options)
{
$this->options = $options;
}
2020-12-29 12:18:32 +03:00
/**
* Set logger
*
* @param LoggerInterface|null $logger
*/
public function setLogger($logger = null)
{
$this->logger = $logger;
}
2020-12-29 12:18:32 +03:00
/**
* @param $curlHandler
* @param $method
*
2020-12-29 14:28:36 +03:00
* @return array
2020-12-29 12:18:32 +03:00
*/
private function checkResponse($curlHandler, $method)
{
2020-12-29 14:28:36 +03:00
$responseBody = curl_exec($curlHandler);
2020-12-29 12:18:32 +03:00
$statusCode = curl_getinfo($curlHandler, CURLINFO_HTTP_CODE);
$contentType = curl_getinfo($curlHandler, CURLINFO_CONTENT_TYPE);
$this->logResponse($responseBody, $statusCode);
2020-12-29 12:18:32 +03:00
if (503 === $statusCode) {
throw new LimitException("Service temporary unavailable");
}
if (
2020-12-29 14:28:36 +03:00
(404 === $statusCode && false !== stripos($responseBody, 'Account does not exist'))
2020-12-29 12:18:32 +03:00
|| ('GET' !== $method && 405 === $statusCode && false !== stripos($contentType, 'text/html'))
) {
throw new NotFoundException("Account does not exist");
}
$errno = curl_errno($curlHandler);
$error = curl_error($curlHandler);
curl_close($curlHandler);
if ($errno) {
throw new CurlException($error, $errno);
}
2020-12-29 14:28:36 +03:00
return [$statusCode, $responseBody];
2020-12-29 12:18:32 +03:00
}
/**
* @param string $url
* @param string $method
* @param array $params
*/
private function logRequest($url, $method, $params)
{
if (null === $this->logger) {
return;
}
$message = 'Send request: ' . $method . ' ' . $url;
if (!empty($params)) {
$message .= ' with params: ' . json_encode($params);
}
$this->logger->info($message);
}
/**
* @param string $responseBody
* @param int $statusCode
*/
private function logResponse($responseBody, $statusCode)
{
if (null === $this->logger) {
return;
}
$message = 'Response with code ' . $statusCode . ' received with body: ' . $responseBody;
$this->logger->info($message);
}
}