Completed
Push — master ( 571a1f...2e24c4 )
by Renato
10s
created

src/VCR/Storage/Yaml.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace VCR\Storage;
4
5
use Symfony\Component\Yaml\Parser;
6
use Symfony\Component\Yaml\Dumper;
7
use VCR\Util\Assertion;
8
9
/**
10
 * Yaml based storage for records.
11
 *
12
 * This storage can be iterated while keeping the memory consumption to the
13
 * amount of memory used by the largest record.
14
 */
15
class Yaml extends AbstractStorage
16
{
17
    /**
18
     * @var Parser Yaml parser.
19
     */
20
    protected $yamlParser;
21
22
    /**
23
     * @var  Dumper Yaml writer.
24
     */
25
    protected $yamlDumper;
26
27
    /**
28
     * Creates a new YAML based file store.
29
     *
30
     * @param string $cassettePath Path to the cassette directory.
31
     * @param string $cassetteName Path to a file, will be created if not existing.
32
     * @param Parser $parser Parser used to decode yaml.
33
     * @param Dumper $dumper Dumper used to encode yaml.
34
     */
35 147
    public function __construct($cassettePath, $cassetteName, Parser $parser = null, Dumper $dumper = null)
36
    {
37 147
        parent::__construct($cassettePath, $cassetteName, '');
38
39 147
        $this->yamlParser = $parser ?: new Parser();
40 147
        $this->yamlDumper = $dumper ?: new Dumper();
41 147
    }
42
43
    /**
44
     * @inheritDoc
45
     */
46 42
    public function storeRecording(array $recording)
47
    {
48 42
        fseek($this->handle, -1, SEEK_END);
49 42
        fwrite($this->handle, "\n" . $this->yamlDumper->dump(array($recording), 4));
50 42
        fflush($this->handle);
51 42
    }
52
53
    /**
54
     * Parses the next record.
55
     *
56
     * @return void
57
     */
58 105
    public function next()
59
    {
60 105
        $recording = $this->yamlParser->parse($this->readNextRecord());
61 105
        $this->current = $recording[0];
62 105
        ++$this->position;
63 105
    }
64
65
    /**
66
     * Returns the next record in raw format.
67
     *
68
     * @return string Next record in raw format.
69
     */
70 105
    private function readNextRecord()
71
    {
72 105
        if ($this->isEOF) {
73 42
            $this->isValidPosition = false;
74 30
        }
75
76 105
        $isInRecord = false;
77 105
        $recording = '';
78 105
        $lastChar = null;
79
80 105
        while (false !== ($char = fgetc($this->handle))) {
81 84
            $isNewArrayStart = ($char === '-') && ($lastChar === "\n" || $lastChar === null);
82 84
            $lastChar = $char;
83
84 84
            if ($isInRecord && $isNewArrayStart) {
85 35
                fseek($this->handle, -1, SEEK_CUR);
86 35
                break;
87
            }
88
89 84
            if (!$isInRecord && $isNewArrayStart) {
90 84
                $isInRecord = true;
91 60
            }
92
93 84
            if ($isInRecord) {
94 84
                $recording .= $char;
95 60
            }
96 60
        }
97
98 105
        if ($char == false) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $char of type string to the boolean false. If you are specifically checking for an empty string, consider using the more explicit === '' instead.
Loading history...
99 98
            $this->isEOF = true;
100 70
        }
101
102 105
        return $recording;
103
    }
104
105
    /**
106
     * Resets the storage to the beginning.
107
     *
108
     * @return void
109
     */
110 112
    public function rewind()
111
    {
112 112
        rewind($this->handle);
113 112
        $this->isEOF = false;
114 112
        $this->isValidPosition = true;
115 112
        $this->position = 0;
116 112
    }
117
118
    /**
119
     * Returns true if the current record is valid.
120
     *
121
     * @return boolean True if the current record is valid.
122
     */
123 112
    public function valid()
124
    {
125 112
        if (is_null($this->current)) {
126 105
            $this->next();
127 75
        }
128
129 112
        return ! is_null($this->current) && $this->isValidPosition;
130
    }
131
}
132