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))
);
}
}
|