Current File : /var/www/vinorea/modules/psxmarketingwithgoogle/classes/Http/HttpClient.php |
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\PsxMarketingWithGoogle\Http;
use RuntimeException;
class HttpClient
{
private $curl;
/** @var array<int|string,string> */
private $headers = [];
/** @var array<int|string,bool|int> */
private $options = [];
/** @var string */
private $baseUrl = '';
/**
* Constructor initializes cURL
*
* @param string $baseUrl Optional base URL for all requests
*
* @throws RuntimeException if cURL extension is not loaded
*/
public function __construct(string $baseUrl = '')
{
if (!extension_loaded('curl')) {
throw new RuntimeException('cURL extension is not loaded');
}
$this->baseUrl = rtrim($baseUrl, '/');
$this->curl = curl_init();
// Set default options
$this->setDefaultOptions();
}
/**
* Set default cURL options
*/
private function setDefaultOptions(): void
{
$this->options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
];
}
/**
* Set custom headers for the request
*
* @param array<int|string,string> $headers
*
* @return self
*/
public function setHeaders(array $headers): self
{
$this->headers = $headers;
return $this;
}
/**
* Add a single header
*
* @param string $name
* @param string $value
*
* @return self
*/
public function addHeader(string $name, string $value): self
{
$this->headers[] = "$name: $value";
return $this;
}
/**
* Set custom cURL options
*
* @param array<string,bool|int> $options
*
* @return self
*/
public function setOptions(array $options): self
{
$this->options = $options + $this->options;
return $this;
}
/**
* Execute HTTP request
*
* @param string $method HTTP method
* @param string $url URL endpoint
* @param array<string,string|bool|int>|string|null $data Request data
*
* @return Response
*
* @throws RuntimeException on cURL errors
*/
public function request(string $method, string $url, $data = null)
{
$url = $this->baseUrl . '/' . ltrim($url, '/');
$options = $this->options + [
CURLOPT_URL => $url,
CURLOPT_CUSTOMREQUEST => strtoupper($method),
CURLOPT_HEADER => true,
CURLOPT_HTTPHEADER => $this->headers,
];
if ($data !== null) {
if (is_array($data)) {
$data = http_build_query($data);
}
if ($method === 'GET') {
/* @phpstan-ignore-next-line */
$options[CURLOPT_URL] .= '?' . $data;
} else {
$options[CURLOPT_POSTFIELDS] = $data;
}
}
curl_setopt_array($this->curl, $options);
$response = curl_exec($this->curl);
if ($response === false) {
throw new \RuntimeException(sprintf('cURL error (%s): %s', curl_errno($this->curl), curl_error($this->curl)));
}
$headerSize = curl_getinfo($this->curl, CURLINFO_HEADER_SIZE);
$httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
// Split response into headers and body
$headerStr = substr((string) $response, 0, $headerSize);
$body = substr((string) $response, $headerSize);
$error = curl_error($this->curl);
// Parse headers
$headers = [];
foreach (explode("\r\n", $headerStr) as $line) {
if (preg_match('/^([^:]+):(.+)$/', $line, $matches)) {
$headers[trim($matches[1])] = trim($matches[2]);
}
}
return new Response(
$httpCode,
$body,
$headers,
$error
);
}
/**
* Convenience method for GET requests
*
* @param string $url
* @param array<string, string> $params Query parameters
*
* @return Response
*/
public function get(string $url, array $params = [])
{
return $this->request('GET', $url, $params);
}
/**
* Convenience method for POST requests
*
* @param string $url
* @param array<string, string>|string $data
*
* @return Response
*/
public function post(string $url, $data = [])
{
return $this->request('POST', $url, $data);
}
/**
* Convenience method for PUT requests
*
* @param string $url
* @param array<string, string>|string $data
*
* @return Response
*/
public function put(string $url, $data = [])
{
return $this->request('PUT', $url, $data);
}
/**
* Convenience method for DELETE requests
*
* @param string $url
* @param array<string, string> $params
*
* @return Response
*/
public function delete(string $url, array $params = [])
{
return $this->request('DELETE', $url, $params);
}
/**
* Destructor closes cURL connection
*/
public function __destruct()
{
if ($this->curl) {
curl_close($this->curl);
}
}
}