Skip to content

Commit 059fbf7

Browse files
committed
feat: adds HTTP files
1 parent e00fbe8 commit 059fbf7

File tree

5 files changed

+654
-0
lines changed

5 files changed

+654
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WordPress\AiClient\Http\Contracts;
6+
7+
use WordPress\AiClient\Http\DTO\Request;
8+
use WordPress\AiClient\Http\DTO\Response;
9+
10+
/**
11+
* Interface for HTTP transport implementations.
12+
*
13+
* Handles sending HTTP requests and receiving responses using
14+
* PSR-7, PSR-17, and PSR-18 standards internally.
15+
*
16+
* @since n.e.x.t
17+
*/
18+
interface HttpTransporterInterface
19+
{
20+
/**
21+
* Sends an HTTP request and returns the response.
22+
*
23+
* @since n.e.x.t
24+
*
25+
* @param Request $request The request to send.
26+
* @return Response The response received.
27+
*/
28+
public function send(Request $request): Response;
29+
}

src/Http/DTO/Request.php

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WordPress\AiClient\Http\DTO;
6+
7+
use InvalidArgumentException;
8+
use WordPress\AiClient\Common\AbstractDataTransferObject;
9+
10+
/**
11+
* Represents an HTTP request.
12+
*
13+
* This class encapsulates HTTP request data that can be converted
14+
* to PSR-7 requests by the HTTP transporter.
15+
*
16+
* @since n.e.x.t
17+
*
18+
* @phpstan-type RequestArrayShape array{
19+
* method: string,
20+
* uri: string,
21+
* headers: array<string, string|list<string>>,
22+
* body?: string|null
23+
* }
24+
*
25+
* @extends AbstractDataTransferObject<RequestArrayShape>
26+
*/
27+
class Request extends AbstractDataTransferObject
28+
{
29+
public const KEY_METHOD = 'method';
30+
public const KEY_URI = 'uri';
31+
public const KEY_HEADERS = 'headers';
32+
public const KEY_BODY = 'body';
33+
34+
/**
35+
* @var string The HTTP method (GET, POST, etc.).
36+
*/
37+
protected string $method;
38+
39+
/**
40+
* @var string The request URI.
41+
*/
42+
protected string $uri;
43+
44+
/**
45+
* @var array<string, string|list<string>> The request headers.
46+
*/
47+
protected array $headers;
48+
49+
/**
50+
* @var string|null The request body.
51+
*/
52+
protected ?string $body;
53+
54+
/**
55+
* Constructor.
56+
*
57+
* @since n.e.x.t
58+
*
59+
* @param string $method The HTTP method.
60+
* @param string $uri The request URI.
61+
* @param array<string, string|list<string>> $headers The request headers.
62+
* @param string|null $body The request body.
63+
*
64+
* @throws InvalidArgumentException If the method is empty.
65+
*/
66+
public function __construct(string $method, string $uri, array $headers = [], ?string $body = null)
67+
{
68+
if (empty($method)) {
69+
throw new InvalidArgumentException('HTTP method cannot be empty.');
70+
}
71+
72+
if (empty($uri)) {
73+
throw new InvalidArgumentException('URI cannot be empty.');
74+
}
75+
76+
$this->method = strtoupper($method);
77+
$this->uri = $uri;
78+
$this->headers = $headers;
79+
$this->body = $body;
80+
}
81+
82+
/**
83+
* Gets the HTTP method.
84+
*
85+
* @since n.e.x.t
86+
*
87+
* @return string The HTTP method.
88+
*/
89+
public function getMethod(): string
90+
{
91+
return $this->method;
92+
}
93+
94+
/**
95+
* Gets the request URI.
96+
*
97+
* @since n.e.x.t
98+
*
99+
* @return string The URI.
100+
*/
101+
public function getUri(): string
102+
{
103+
return $this->uri;
104+
}
105+
106+
/**
107+
* Gets the request headers.
108+
*
109+
* @since n.e.x.t
110+
*
111+
* @return array<string, string|list<string>> The headers.
112+
*/
113+
public function getHeaders(): array
114+
{
115+
return $this->headers;
116+
}
117+
118+
/**
119+
* Gets the request body.
120+
*
121+
* @since n.e.x.t
122+
*
123+
* @return string|null The body.
124+
*/
125+
public function getBody(): ?string
126+
{
127+
return $this->body;
128+
}
129+
130+
/**
131+
* Returns a new instance with the specified header.
132+
*
133+
* @since n.e.x.t
134+
*
135+
* @param string $name The header name.
136+
* @param string|list<string> $value The header value(s).
137+
* @return self A new instance with the header.
138+
*/
139+
public function withHeader(string $name, $value): self
140+
{
141+
$headers = $this->headers;
142+
$headers[$name] = $value;
143+
144+
return new self($this->method, $this->uri, $headers, $this->body);
145+
}
146+
147+
/**
148+
* Returns a new instance with the specified body.
149+
*
150+
* @since n.e.x.t
151+
*
152+
* @param string $body The request body.
153+
* @return self A new instance with the body.
154+
*/
155+
public function withBody(string $body): self
156+
{
157+
return new self($this->method, $this->uri, $this->headers, $body);
158+
}
159+
160+
/**
161+
* {@inheritDoc}
162+
*
163+
* @since n.e.x.t
164+
*/
165+
public static function getJsonSchema(): array
166+
{
167+
return [
168+
'type' => 'object',
169+
'properties' => [
170+
self::KEY_METHOD => [
171+
'type' => 'string',
172+
'description' => 'The HTTP method.',
173+
],
174+
self::KEY_URI => [
175+
'type' => 'string',
176+
'description' => 'The request URI.',
177+
],
178+
self::KEY_HEADERS => [
179+
'type' => 'object',
180+
'additionalProperties' => [
181+
'oneOf' => [
182+
['type' => 'string'],
183+
[
184+
'type' => 'array',
185+
'items' => ['type' => 'string'],
186+
],
187+
],
188+
],
189+
'description' => 'The request headers.',
190+
],
191+
self::KEY_BODY => [
192+
'type' => ['string', 'null'],
193+
'description' => 'The request body.',
194+
],
195+
],
196+
'required' => [self::KEY_METHOD, self::KEY_URI, self::KEY_HEADERS],
197+
];
198+
}
199+
200+
/**
201+
* {@inheritDoc}
202+
*
203+
* @since n.e.x.t
204+
*
205+
* @return RequestArrayShape
206+
*/
207+
public function toArray(): array
208+
{
209+
$data = [
210+
self::KEY_METHOD => $this->method,
211+
self::KEY_URI => $this->uri,
212+
self::KEY_HEADERS => $this->headers,
213+
];
214+
215+
if ($this->body !== null) {
216+
$data[self::KEY_BODY] = $this->body;
217+
}
218+
219+
return $data;
220+
}
221+
222+
/**
223+
* {@inheritDoc}
224+
*
225+
* @since n.e.x.t
226+
*/
227+
public static function fromArray(array $array): self
228+
{
229+
static::validateFromArrayData($array, [self::KEY_METHOD, self::KEY_URI, self::KEY_HEADERS]);
230+
231+
return new self(
232+
$array[self::KEY_METHOD],
233+
$array[self::KEY_URI],
234+
$array[self::KEY_HEADERS],
235+
$array[self::KEY_BODY] ?? null
236+
);
237+
}
238+
}

0 commit comments

Comments
 (0)