Completed
Pull Request — master (#210)
by ignace nyamagana
04:28
created

Writer::getFlushThreshold()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
* This file is part of the League.csv library
4
*
5
* @license http://opensource.org/licenses/MIT
6
* @link https://github.com/thephpleague/csv/
7
* @version 9.0.0
8
* @package League.csv
9
*
10
* For the full copyright and license information, please view the LICENSE
11
* file that was distributed with this source code.
12
*/
13
declare(strict_types=1);
14
15
namespace League\Csv;
16
17
use League\Csv\Exception\InsertionException;
18
use League\Csv\Exception\InvalidArgumentException;
19
use Traversable;
20
21
/**
22
 * A class to manage data insertion into a CSV
23
 *
24
 * @package League.csv
25
 * @since   4.0.0
26
 * @author  Ignace Nyamagana Butera <[email protected]>
27
 *
28
 */
29
class Writer extends AbstractCsv
30
{
31
    /**
32
     * @inheritdoc
33
     */
34
    protected $stream_filter_mode = STREAM_FILTER_WRITE;
35
36
    /**
37
     * callable collection to validate the record before insertion
38
     *
39
     * @var callable[]
40
     */
41
    protected $validators = [];
42
43
    /**
44
     * callable collection to format the record before insertion
45
     *
46
     * @var callable[]
47
     */
48
    protected $formatters = [];
49
50
    /**
51
     * Insert Rows count
52
     *
53
     * @var int
54
     */
55
    protected $insert_count = 0;
56
57
    /**
58
     * newline character
59
     *
60
     * @var string
61
     */
62
    protected $newline = "\n";
63
64
    /**
65
     * Buffer flush threshold
66
     *
67
     * @var int
68
     */
69
    protected $flush_threshold = 500;
70
71
    /**
72
     * Returns the current newline sequence characters
73
     *
74
     * @return string
75
     */
76 4
    public function getNewline(): string
77
    {
78 4
        return $this->newline;
79
    }
80
81
    /**
82
     * Get the flush threshold
83
     *
84
     * @return int|null
85
     */
86 2
    public function getFlushThreshold()
87
    {
88 2
        return $this->flush_threshold;
89
    }
90
91
    /**
92
     * Adds multiple lines to the CSV document
93
     *
94
     * a simple wrapper method around insertOne
95
     *
96
     * @param Traversable|array $rows a multidimensional array or a Traversable object
97
     *
98
     * @throws InvalidArgumentException If the given rows format is invalid
99
     *
100
     * @return int
101
     */
102 6
    public function insertAll($rows): int
103
    {
104 6
        if (!is_array($rows) && !$rows instanceof Traversable) {
105 2
            throw new InvalidArgumentException('the provided data must be an array OR a `Traversable` object');
106
        }
107
108 4
        $bytes = 0;
109 4
        foreach ($rows as $row) {
110 4
            $bytes += $this->insertOne($row);
111
        }
112
113 4
        return $bytes;
114
    }
115
116
    /**
117
     * Adds a single line to a CSV document
118
     *
119
     * @param string[] $row an array
120
     *
121
     * @throws InsertionException If the row can not be inserted
122
     *
123
     * @return int
124
     */
125 32
    public function insertOne(array $row): int
126
    {
127 32
        $record = array_reduce($this->formatters, [$this, 'formatRecord'], $row);
128 32
        $this->validateRecord($record);
129 28
        $bytes = $this->document->fputcsv($record, $this->delimiter, $this->enclosure, $this->escape);
130 28
        if (!$bytes) {
131 2
            throw InsertionException::createFromCsv($record);
132
        }
133
134 26
        return $bytes + $this->consolidate();
135
    }
136
137
    /**
138
     * Format the given row
139
     *
140
     * @param string[] $record
141
     * @param callable $formatter
142
     *
143
     * @return string[]
144
     */
145 4
    protected function formatRecord(array $record, callable $formatter): array
146
    {
147 4
        return $formatter($record);
148
    }
149
150
    /**
151
     * Validate a row
152
     *
153
     * @param string[] $record
154
     *
155
     * @throws InsertionException If the validation failed
156
     */
157 32
    protected function validateRecord(array $record)
158
    {
159 32
        foreach ($this->validators as $name => $validator) {
160 8
            if (true !== ($validator)($record)) {
161 8
                throw InsertionException::createFromValidator($name, $record);
162
            }
163
        }
164 28
    }
165
166
    /**
167
     * Apply post insertion actions
168
     *
169
     * @return int
170
     */
171 26
    protected function consolidate(): int
172
    {
173 26
        $bytes = 0;
174 26
        if ("\n" !== $this->newline) {
175 4
            $this->document->fseek(-1, SEEK_CUR);
176 4
            $bytes = $this->document->fwrite($this->newline, strlen($this->newline)) - 1;
177
        }
178
179 26
        $this->insert_count++;
180 26
        if (null !== $this->flush_threshold && 0 === $this->insert_count % $this->flush_threshold) {
181 2
            $this->document->fflush();
182
        }
183
184 26
        return $bytes;
185
    }
186
187
    /**
188
     * add a formatter to the collection
189
     *
190
     * @param callable $formatter
191
     *
192
     * @return static
193
     */
194 4
    public function addFormatter(callable $formatter): self
195
    {
196 4
        $this->formatters[] = $formatter;
197
198 4
        return $this;
199
    }
200
201
    /**
202
     * add a Validator to the collection
203
     *
204
     * @param callable $validator
205
     * @param string   $name      the validator name
206
     *
207
     * @return static
208
     */
209 8
    public function addValidator(callable $validator, string $name): self
210
    {
211 8
        $this->validators[$name] = $validator;
212
213 8
        return $this;
214
    }
215
216
    /**
217
     * Sets the newline sequence characters
218
     *
219
     * @param string $newline
220
     *
221
     * @return static
222
     */
223 4
    public function setNewline(string $newline): self
224
    {
225 4
        $this->newline = (string) $newline;
226
227 4
        return $this;
228
    }
229
230
    /**
231
     * Set the automatic flush threshold on write
232
     *
233
     * @param int|null $val
234
     */
235 4
    public function setFlushThreshold($val): self
236
    {
237 4
        if (null !== $val) {
238 4
            $val = $this->filterInteger($val, 1, 'The flush threshold must be a valid positive integer or null');
239
        }
240
241 4
        $this->flush_threshold = $val;
242
243 4
        return $this;
244
    }
245
}
246