Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions src/Cache/ArrayCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@

namespace OpenApi\Cache;

/**
* In-memory cache implementation
* Data is stored in PHP arrays and cleared at end of script execution
*/
class ArrayCache implements CacheInterface
{
private array $cache = [];
private array $expiry = [];

/**
* Retrieve value from cache
* Returns null if key doesn't exist or has expired
*/
public function get(string $key): mixed
{
if (!isset($this->cache[$key])) {
return null;
}

// Check if expired
if (isset($this->expiry[$key]) && time() > $this->expiry[$key]) {
$this->delete($key);
return null;
Expand All @@ -21,26 +30,35 @@ public function get(string $key): mixed
return $this->cache[$key];
}

/**
* Save value to cache with expiration
*/
public function save(string $key, mixed $value, int $ttl = 3600): bool
{
$this->cache[$key] = $value;
$this->expiry[$key] = time() + $ttl;

return true;
}

/**
* Delete value from cache
*/
public function delete(string $key): bool
{
unset($this->cache[$key], $this->expiry[$key]);

return true;
}

/**
* Clear all cached values
*/
public function clear(): bool
{
$this->cache = [];
$this->expiry = [];

return true;
}
}
22 changes: 22 additions & 0 deletions src/Cache/CacheInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,32 @@

namespace OpenApi\Cache;

/**
* Cache interface for SDK implementations
*/
interface CacheInterface
{
/**
* Retrieve value from cache
*/
public function get(string $key): mixed;

/**
* Save value to cache with TTL
*
* @param string $key Cache key
* @param mixed $value Value to store
* @param int $ttl Time-to-live in seconds (default: 3600)
*/
public function save(string $key, mixed $value, int $ttl = 3600): bool;

/**
* Delete value from cache
*/
public function delete(string $key): bool;

/**
* Clear all cached values
*/
public function clear(): bool;
}
42 changes: 39 additions & 3 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,40 @@

namespace OpenApi;

class Client
/**
* Generic HTTP client for OpenAPI services
* Handles REST operations with Bearer token authentication
*/
class Client
{
private string $token;

/**
* Initialize client with Bearer token
*/
public function __construct(string $token)
{
$this->token = $token;
}

/**
* Execute HTTP request
*
* @param string $method HTTP method (GET, POST, PUT, DELETE, PATCH)
* @param string $url Target URL
* @param mixed $payload Request body (for POST/PUT/PATCH)
* @param array|null $params Query parameters (for GET) or form data (for other methods)
* @return string Response body
*/
public function request(string $method, string $url, mixed $payload = null, ?array $params = null): string
{
// Append query parameters for GET requests
if ($params && $method === 'GET') {
$url .= '?' . http_build_query($params);
}

$ch = curl_init();

curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
Expand All @@ -30,12 +47,14 @@ public function request(string $method, string $url, mixed $payload = null, ?arr
]
]);

// Add JSON payload for POST/PUT/PATCH requests
if ($payload && in_array($method, ['POST', 'PUT', 'PATCH'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, is_string($payload) ? $payload : json_encode($payload));
}

// Add form data for non-GET requests
if ($params && $method !== 'GET') {
curl_setopt($ch, CURLOPT_POSTFIELDS,
curl_setopt($ch, CURLOPT_POSTFIELDS,
is_string($params) ? $params : http_build_query($params));
}

Expand All @@ -44,37 +63,54 @@ public function request(string $method, string $url, mixed $payload = null, ?arr
$error = curl_error($ch);
curl_close($ch);

// TODO: Provide more graceful error message with connection context (timeout, DNS, SSL, etc.)
if ($response === false) {
throw new Exception("cURL Error: " . $error);
}

// TODO: Parse response body and provide structured error details (error code, message, request ID)
if ($httpCode >= 400) {
throw new Exception("HTTP Error {$httpCode}: " . $response);
}

return $response;
}

/**
* Perform GET request
*/
public function get(string $url, ?array $params = null): string
{
return $this->request('GET', $url, null, $params);
}

/**
* Perform POST request
*/
public function post(string $url, mixed $payload = null): string
{
return $this->request('POST', $url, $payload);
}

/**
* Perform PUT request
*/
public function put(string $url, mixed $payload = null): string
{
return $this->request('PUT', $url, $payload);
}

/**
* Perform DELETE request
*/
public function delete(string $url): string
{
return $this->request('DELETE', $url);
}

/**
* Perform PATCH request
*/
public function patch(string $url, mixed $payload = null): string
{
return $this->request('PATCH', $url, $payload);
Expand Down
25 changes: 25 additions & 0 deletions src/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,26 @@

namespace OpenApi;

/**
* Custom exception for OpenAPI SDK
* Stores HTTP response details for better error handling
*/
class Exception extends \Exception
{
private mixed $serverResponse = null;
private mixed $headers = null;
private mixed $rawResponse = null;
private ?int $httpCode = null;

/**
* Store server response details
* TODO: Utilize this method in Client and OauthClient to provide structured error context
*
* @param mixed $response Parsed server response
* @param mixed $headers Response headers
* @param mixed $rawResponse Raw response body
* @param int|null $httpCode HTTP status code
*/
public function setServerResponse(mixed $response, mixed $headers = null, mixed $rawResponse = null, ?int $httpCode = null): void
{
$this->serverResponse = $response;
Expand All @@ -17,21 +30,33 @@ public function setServerResponse(mixed $response, mixed $headers = null, mixed
$this->httpCode = $httpCode;
}

/**
* Get parsed server response
*/
public function getServerResponse(): mixed
{
return $this->serverResponse;
}

/**
* Get response headers
*/
public function getHeaders(): mixed
{
return $this->headers;
}

/**
* Get raw response body
*/
public function getRawResponse(): mixed
{
return $this->rawResponse;
}

/**
* Get HTTP status code
*/
public function getHttpCode(): ?int
{
return $this->httpCode;
Expand Down
Loading