ldc-arcadia-genesis-php-client/src/Lib/Psr7/RequestFactory.php
Jérémy Munsch 9c47b9cd66
refactor: rename namespace from ArcadiaGenesisPhpClient to ArcadiaApiPhpClient
This change updates the namespace across multiple files to reflect the new naming convention.
2026-09-11 16:55:12 +02:00

160 lines
4.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Uwil\ArcadiaApiPhpClient\Lib\Psr7;
use GuzzleHttp\Psr7\Request as Psr7Request;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Psr7\Utils as Psr7Utils;
use GuzzleHttp\Utils as GuzzleHttpUtils;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\UriInterface;
use Uwil\ArcadiaApiPhpClient\Lib\ApiConfig;
use Uwil\ArcadiaApiPhpClient\Lib\HttpMethod;
use Uwil\ArcadiaApiPhpClient\Utils\Utils;
final readonly class RequestFactory
{
public function __construct(
#[\SensitiveParameter]
private readonly ApiConfig $apiConfig
) {
}
/**
* @param array<array-key,mixed> $data
* @param array<string,string> $headersMap
*/
public function buildRequest(
HttpMethod $method,
UriInterface $uri,
array $data = [],
array $headersMap = [],
): RequestInterface {
$scheme = $uri->getScheme();
if ($scheme !== 'http' && $scheme !== 'https') {
throw new \InvalidArgumentException('Only http(s) is allowed');
}
foreach ($headersMap as $headerName => $value) {
if (! is_string($headerName)) {
throw new \InvalidArgumentException('Header must be a string');
}
if (! is_string($value)) {
throw new \InvalidArgumentException("Header value '{$headerName}' must be a string");
}
}
// ! Make sure parameters are on queries when HTTP GET
if ($method === HttpMethod::GET) {
$this->putAllParamsOnQuery($uri, $data);
} else {
$this->putAllParamInData($uri, $data);
}
$timestamp = Utils::getNow();
$request = new Psr7Request(
\strtoupper($method->value),
$uri,
$headersMap
);
// NOTE: Dont prodive body content on GET method.
$jsonEncodedData = $method !== HttpMethod::GET ? GuzzleHttpUtils::jsonEncode($data) : '';
$alteredUri = $this->transformUriInOrderToMatchLabProxy($uri);
$signature = Utils::calculateSignature(
$method,
$alteredUri,
$jsonEncodedData,
$this->apiConfig->secret,
$timestamp
);
$fullApiHeaders = $this->addApiHeaders(
$headersMap,
$signature,
$timestamp
);
return Psr7Utils::modifyRequest($request, [
'set_headers' => $fullApiHeaders,
'body' => $jsonEncodedData,
]);
}
/**
* @param array<string,string> $headers
* @return array<string,string>
*/
protected function addApiHeaders(
array $headers,
string $signature,
\DateTimeInterface $timestamp
): array {
return array_merge(
$headers,
[
'Content-Type' => 'application/json',
'X-API-Key' => $this->apiConfig->apiKey,
'X-API-Signature' => $signature,
'X-Timestamp' => Utils::toRfc3339($timestamp),
]
);
}
/**
* @param array<string,mixed> $data
*/
protected function putAllParamsOnQuery(UriInterface &$uri, array &$data): void
{
$existingQuery = $uri->getQuery();
$queryArray = [];
if ($existingQuery !== '') {
parse_str($existingQuery, $queryArray);
}
$merged = array_merge($queryArray, $data);
$newQuery = $merged ? http_build_query($merged) : '';
$uri = $uri->withQuery($newQuery);
$data = [];
}
/**
* @param array<array-key,mixed> $data
*/
protected function putAllParamInData(UriInterface &$uri, array &$data): void
{
$existingQuery = $uri->getQuery();
if ($existingQuery === '') {
return;
}
$queryArray = [];
parse_str($existingQuery, $queryArray);
$data = array_merge($queryArray, $data);
$uri = $uri->withQuery('');
}
/**
* FIXME: This should be removed, temp fix
*/
protected function transformUriInOrderToMatchLabProxy(UriInterface $uri): UriInterface
{
$scheme = $uri->getScheme();
$authority = str_replace('lesidc', 'svlidc', $uri->getAuthority());
$path = '/gaston/api' . preg_replace('/^\/gaston\/api/', '', $uri->getPath());
$query = ! empty($uri->getQuery()) ? "?{$uri->getQuery()}" : '';
$fragment = ! empty($uri->getFragment()) ? "#{$uri->getFragment()}" : '';
return new Uri(
"{$scheme}://{$authority}{$path}{$query}{$fragment}"
);
}
}