diff --git a/src/Reflect/Client.php b/src/Reflect/Client.php index d441a7d..24a1eb0 100644 --- a/src/Reflect/Client.php +++ b/src/Reflect/Client.php @@ -8,61 +8,27 @@ require_once "Method.php"; require_once "Response.php"; - // Supported connection methods - enum Connection { - case HTTP; - case AF_UNIX; - } - class Client { - // API key string private ?string $key; - // Connection method - private Connection $con; - // Request endpoitn string - private string $endpoint; - - // Socket instance - private Socket|false $socket = false; - // Flag: Allow unverified SSL certificates for HTTPS - private bool $https_peer_verify = true; - - // Use this HTTP method if no method specified to call() - const HTTP_DEFAULT_METHOD = Method::GET; - // The amount of bytes to read for each chunk from socket - const SOCKET_READ_BYTES = 2048; - - public function __construct(string $endpoint, string $key = null, Connection $con = null, bool $https_peer_verify = true) { - $this->con = $con ?: self::resolve_connection($endpoint); - $this->endpoint = $endpoint; + private string $base_url; + private bool $https_verify_peer; + + public function __construct(string $base_url, string $key = null, bool $verify_peer = true) { + // Optional API key $this->key = $key; - if ($this->con === Connection::AF_UNIX) { - // Connect to Reflect UNIX socket - $this->_socket = socket_create(AF_UNIX, SOCK_STREAM, 0); - $conn = socket_connect($this->_socket, $this->endpoint); - } else if ($this->con === Connection::HTTP) { - // Append tailing "/" for HTTP if absent - $this->endpoint = substr($this->endpoint, -1) === "/" ? $this->endpoint : $this->endpoint . "/"; - // Flag which enables or disables SSL peer validation (for self-signed certificates) - $this->https_peer_verify = $https_peer_verify; - } + // Append tailing "/" if absent + $this->base_url = substr($this->base_url, -1) === "/" ? $this->base_url : $this->base_url . "/"; + // Flag which enables or disables SSL peer validation (for self-signed certificates) + $this->https_verify_peer = $verify_peer; } - // Resolve connection type from endpoint string. - // If the string is a valid URL we will treat it as HTTP otherwise we will assume it's a path on disk to a UNIX socket file. - private static function resolve_connection(string $endpoint): Connection { - return filter_var($endpoint, FILTER_VALIDATE_URL) - ? Connection::HTTP - : Connection::AF_UNIX; + // Convert assoc array to URL-encoded string or empty string if array is empty + private static function get_params(array $params): string { + return !empty($params) ? "?" . http_build_query($params) : ""; } - // Attempt to resolve Method from backed enum string, or return default - private static function resolve_method(Method|string $method): Method { - return ($method instanceof Method) - ? $method - : Method::tryFrom($method) ?? self::HTTP_DEFAULT_METHOD; - } + // ---- // Construct stream_context_create() compatible header string private function http_headers(): string { @@ -93,9 +59,9 @@ "content" => !empty($payload) ? json_encode($payload) : "" ], "ssl" => [ - "verify_peer" => $this->https_peer_verify, - "verify_peer_name" => $this->https_peer_verify, - "allow_self_signed" => !$this->https_peer_verify + "verify_peer" => $this->https_verify_peer, + "verify_peer_name" => $this->https_verify_peer, + "allow_self_signed" => !$this->https_verify_peer ] ]); @@ -109,37 +75,31 @@ return [$resp, $resp_code]; } - // Make request and return response over socket - private function socket_txn(string $payload): string { - $tx = socket_write($this->_socket, $payload, strlen($payload)); - $rx = socket_read($this->_socket, self::SOCKET_READ_BYTES); + // ---- - if (!$tx || !$rx) { - throw new \Error("Failed to complete transaction"); - } - - return $rx; + // Make a GET request to endpoint with optional search parameters + public function get(string $endpoint, array $params = []): Response { + $resp = $this->http_call($endpoint . self::get_params($params), Method::GET); + return new Response(...$resp); } - // Call a Reflect endpoint and return response as assoc array - public function call(string $endpoint, Method|string $method = self::HTTP_DEFAULT_METHOD, array $payload = null): Response { - // Resolve string to enum - $method = self::resolve_method($method); + public function patch(string $endpoint, array $params, array $payload): Response { + $resp = $this->http_call($endpoint . self::get_params($params), Method::PATCH, $payload); + return new Response(...$resp); + } - // Call endpoint over UNIX socket - if ($this->con === Connection::AF_UNIX) { - // Return response as assoc array - return json_decode($this->socket_txn( - // Send request as stringified JSON - json_encode([ - $endpoint, - $method->value, - $payload - ]) - ), true); - } + public function put(string $endpoint, array $params, array $payload): Response { + $resp = $this->http_call($endpoint . self::get_params($params), Method::PUT, $payload); + return new Response(...$resp); + } - // Call endpoint over HTTP - return new Response($this->http_call(...func_get_args())); + public function post(string $endpoint, array $params, array $payload): Response { + $resp = $this->http_call($endpoint . self::get_params($params), Method::POST, $payload); + return new Response(...$resp); + } + + public function delete(string $endpoint, array $params, ?array $payload = []): Response { + $resp = $this->http_call($endpoint . self::get_params($params), Method::POST, $payload); + return new Response(...$resp); } } \ No newline at end of file