-
-
Notifications
You must be signed in to change notification settings - Fork 315
/
FileClient.php
100 lines (83 loc) · 2.86 KB
/
FileClient.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
declare(strict_types = 1);
namespace Embed\Tests;
use Brick\VarExporter\VarExporter;
use Embed\Http\CurlClient;
use Embed\Http\FactoryDiscovery;
use Exception;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
/**
* Decorator to cache requests into files
*/
final class FileClient implements ClientInterface
{
private int $mode = 0;
private string $path;
private ResponseFactoryInterface $responseFactory;
private ClientInterface $client;
public function __construct(string $path)
{
$this->path = $path;
$this->responseFactory = FactoryDiscovery::getResponseFactory();
$this->client = new CurlClient($this->responseFactory);
}
public function setMode(int $mode): void
{
$this->mode = $mode;
}
public function sendRequest(RequestInterface $request): ResponseInterface
{
$uri = $request->getUri();
$filename = $this->path.'/'.self::getFilename($uri);
if ($this->mode < 1 && is_file($filename)) {
$response = $this->readResponse($filename);
} elseif ($this->mode === -1) {
throw new Exception("New unexpected request to {$uri}");
} else {
$response = $this->client->sendRequest($request);
}
if ($this->mode === 2 || !is_file($filename)) {
$this->saveResponse($response, $filename);
}
return $response;
}
public static function getFilename(UriInterface $uri): string
{
$query = $uri->getQuery();
return sprintf(
'%s.%s%s.php',
$uri->getHost(),
trim(preg_replace('/[^\w.-]+/', '-', strtolower($uri->getPath())), '-'),
$query ? '.'.md5($uri->getQuery()) : ''
);
}
private function readResponse(string $filename): ResponseInterface
{
$message = require $filename;
$response = $this->responseFactory->createResponse($message['statusCode'], $message['reasonPhrase']);
foreach ($message['headers'] as $name => $value) {
$response = $response->withHeader($name, $value);
}
$body = $response->getBody();
$body->write($message['body']);
$body->rewind();
return $response;
}
private function saveResponse(ResponseInterface $response, string $filename): void
{
$message = [
'headers' => $response->getHeaders(),
'statusCode' => $response->getStatusCode(),
'reasonPhrase' => $response->getReasonPhrase(),
'body' => (string) $response->getBody(),
];
file_put_contents(
$filename,
sprintf("<?php\ndeclare(strict_types = 1);\n\nreturn %s;\n", VarExporter::export($message))
);
}
}