1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Http\Client\Plugin\Vcr\Recorder; |
6
|
|
|
|
7
|
|
|
use GuzzleHttp\Psr7; |
8
|
|
|
use Psr\Http\Message\ResponseInterface; |
9
|
|
|
use Psr\Log\LoggerAwareInterface; |
10
|
|
|
use Psr\Log\LoggerAwareTrait; |
11
|
|
|
use Symfony\Component\Filesystem\Exception\IOException; |
12
|
|
|
use Symfony\Component\Filesystem\Filesystem; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Stores responses using the `guzzlehttp/psr7` library to serialize and deserialize the response. |
16
|
|
|
* Target directory should be part of your VCS. |
17
|
|
|
* |
18
|
|
|
* @author Gary PEGEOT <[email protected]> |
19
|
|
|
*/ |
20
|
|
|
final class FilesystemRecorder implements RecorderInterface, PlayerInterface, LoggerAwareInterface |
21
|
|
|
{ |
22
|
|
|
use LoggerAwareTrait; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var string |
26
|
|
|
*/ |
27
|
|
|
private $directory; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var Filesystem |
31
|
|
|
*/ |
32
|
|
|
private $filesystem; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var array |
36
|
|
|
*/ |
37
|
|
|
private $filters; |
38
|
|
|
|
39
|
3 |
|
public function __construct(string $directory, ?Filesystem $filesystem = null, array $filters = []) |
40
|
|
|
{ |
41
|
3 |
|
$this->filesystem = $filesystem ?? new Filesystem(); |
42
|
|
|
|
43
|
3 |
|
if (!$this->filesystem->exists($directory)) { |
44
|
|
|
try { |
45
|
|
|
$this->filesystem->mkdir($directory); |
46
|
|
|
} catch (IOException $e) { |
47
|
|
|
throw new \InvalidArgumentException("Unable to create directory \"$directory\"/: {$e->getMessage()}", $e->getCode(), $e); |
48
|
|
|
} |
49
|
|
|
} |
50
|
|
|
|
51
|
3 |
|
$this->directory = realpath($directory).\DIRECTORY_SEPARATOR; |
52
|
3 |
|
$this->filters = $filters; |
53
|
3 |
|
} |
54
|
|
|
|
55
|
3 |
|
public function replay(string $name): ?ResponseInterface |
56
|
|
|
{ |
57
|
3 |
|
$filename = "{$this->directory}$name.txt"; |
58
|
3 |
|
$context = compact('filename'); |
59
|
|
|
|
60
|
3 |
|
if (!$this->filesystem->exists($filename)) { |
61
|
1 |
|
$this->log('Unable to replay {filename}', $context); |
62
|
|
|
|
63
|
1 |
|
return null; |
64
|
|
|
} |
65
|
|
|
|
66
|
2 |
|
$this->log('Response replayed from {filename}', $context); |
67
|
|
|
|
68
|
2 |
|
return Psr7\parse_response(file_get_contents($filename)); |
|
|
|
|
69
|
|
|
} |
70
|
|
|
|
71
|
2 |
|
public function record(string $name, ResponseInterface $response): void |
72
|
|
|
{ |
73
|
2 |
|
$filename = "{$this->directory}$name.txt"; |
74
|
2 |
|
$context = compact('name', 'filename'); |
75
|
|
|
|
76
|
2 |
|
$content = preg_replace(array_keys($this->filters), array_values($this->filters), Psr7\str($response)); |
|
|
|
|
77
|
2 |
|
$this->filesystem->dumpFile($filename, $content); |
78
|
|
|
|
79
|
2 |
|
$this->log('Response for {name} stored into {filename}', $context); |
80
|
2 |
|
} |
81
|
|
|
|
82
|
3 |
|
private function log(string $message, array $context = []): void |
83
|
|
|
{ |
84
|
3 |
|
if ($this->logger) { |
85
|
2 |
|
$this->logger->debug("[VCR-PLUGIN][FilesystemRecorder] $message", $context); |
86
|
|
|
} |
87
|
3 |
|
} |
88
|
|
|
} |
89
|
|
|
|
This function has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.