<?php
/** @noinspection MagicMethodsValidityInspection */
namespace Paynetics\HttpRequest;
use JsonException;
use Paynetics\Exception\ApiException;
use Paynetics\Helper\RequestMethods;
use Paynetics\Helper\SerializationTrait;
use Paynetics\Helper\URLParser;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\RequestOptions;
use Paynetics\Cache\RedisCacheRequest;
use Paynetics\HttpRequest\Headers\HeadersBag;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* Class AbstractHttpRequest
* @package Paynetics\HttpRequest
*
* @property HeadersBag headers
*/
abstract class AbstractHttpRequest implements HttpRequestInterface
{
use SerializationTrait;
/**
* .env file variable with url to destination
*/
protected const SERVICE = '';
/**
* @var Client
*/
protected $client;
/**
* @var HeadersBag
*/
protected $_headers;
/**
* @var RedisCacheRequest
*/
protected $cache;
/**
* RequestService constructor.
* @param ClientInterface $client
* @param RedisCacheRequest $cache
*/
public function __construct(ClientInterface $client, RedisCacheRequest $cache)
{
$this->client = $client;
$this->_headers = new HeadersBag();
$this->cache = $cache;
}
/**
* @param string $uri
* @param array $params
* @param array $query
* @param array $options
*
* @param bool $async
* @return mixed|ResponseInterface
*
* @throws ApiException
* @throws GuzzleException
* @throws JsonException
*/
public function get(string $uri, array $params = [], array $query = [], array $options = [], bool $async = false)
{
$options[RequestOptions::QUERY] = $query;
return $this->request(RequestMethods::GET, $uri, $params, null, true, $options, $async);
}
/**
* @param string $uri
* @param null $data
* @param array $params
* @param bool $json
* @param array $options
*
* @param bool $async
* @return mixed|ResponseInterface
*
* @throws ApiException
* @throws GuzzleException
*/
public function post(string $uri, $data = null, array $params = [], bool $json = true, array $options = [], bool $async = false)
{
return $this->request(RequestMethods::POST, $uri, $params, $data, $json, $options, $async);
}
/**
* @param string $uri
* @param null $data
* @param array $params
* @param bool $json
* @param array $options
*
* @param bool $async
* @return mixed|ResponseInterface
*
* @throws ApiException
* @throws GuzzleException
*/
public function put(string $uri, $data = null, array $params = [], bool $json = true, array $options = [], bool $async = false)
{
return $this->request(RequestMethods::PUT, $uri, $params, $data, $json, $options, $async);
}
/**
* @param string $uri
* @param null $data
* @param array $params
* @param bool $json
* @param array $options
*
* @param bool $async
* @return mixed|ResponseInterface
*
* @throws ApiException
* @throws GuzzleException
*/
public function patch(string $uri, $data = null, array $params = [], bool $json = true, array $options = [], bool $async = false)
{
return $this->request(RequestMethods::PATCH, $uri, $params, $data, $json, $options, $async);
}
/**
* @param string $uri
* @param null $data
* @param array $params
* @param array $options
*
* @param bool $async
* @return mixed|ResponseInterface
*
* @throws ApiException
* @throws GuzzleException
*/
public function delete(string $uri, $data = null, array $params = [], array $options = [], bool $async = false)
{
return $this->request(RequestMethods::DELETE, $uri, $params, $data, true, $options, $async);
}
/**
* @param string $method
* @param string $uri
* @param array $params
* @param $data
* @param bool $json
* @param array $options
*
* @param bool $async
* @return mixed|ResponseInterface
*
* @throws ApiException
* @throws GuzzleException
* @throws JsonException
*/
public function request(string $method, string $uri, array $params, $data, bool $json = true, array $options = [], bool $async = false)
{
if ($json) {
if ($data && !is_string($data)) {
$data = $this->serialize($data);
}
if (is_array($data)) {
$data = json_encode($data, JSON_THROW_ON_ERROR, 512);
}
$data = [RequestOptions::BODY => $data];
} else {
$data = [RequestOptions::FORM_PARAMS => $data];
}
$this->preRequest($options);
$options = array_merge($data, [RequestOptions::HEADERS => $this->_headers->all()], $options);
if (!$async) {
$response = $this->client->request($method, URLParser::parse($uri, static::SERVICE, $params), $options);
$this->_headers->flush();
return $this->handle($response);
}
$this->_headers->flush();
return $this->client->requestAsync($method, URLParser::parse($uri, static::SERVICE, $params), $options)->then();
}
/**
* Pre Request Hook
* @param $options
*/
public function preRequest(array &$options): void
{
}
/**
* @param ResponseInterface $response
*
* @return HttpException|void
*
* @throws ApiException
*/
abstract protected function handle(ResponseInterface $response);
}