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

Writer::formatRow()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 2
cts 2
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
crap 2
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 Traversable;
18
19
/**
20
 *  A class to manage data insertion into a CSV
21
 *
22
 * @package League.csv
23
 * @since  4.0.0
24
 *
25
 */
26
class Writer extends AbstractCsv
27
{
28
    /**
29
     * Callables to validate the record before insertion
30
     *
31
     * @var callable[]
32
     */
33
    protected $validators = [];
34
35
    /**
36
     * Callables to format the record before insertion
37
     *
38
     * @var callable[]
39
     */
40
    protected $formatters = [];
41
42
    /**
43
     * @inheritdoc
44
     */
45
    protected $stream_filter_mode = STREAM_FILTER_WRITE;
46
47
    /**
48
     * Insert Rows count
49
     *
50
     * @var int
51
     */
52
    protected $insert_count = 0;
53
54
    /**
55
     * add a formatter to the collection
56
     *
57
     * @param callable $callable
58
     *
59
     * @return $this
60
     */
61 69
    public function addFormatter(callable $callable): self
62
    {
63 69
        $this->formatters[] = $callable;
64 69
65 69
        return $this;
66
    }
67
68
    /**
69
     * add a Validator to the collection
70 69
     *
71
     * @param callable $callable
72 69
     * @param string   $name     the rule name
73 3
     *
74 3
     * @return $this
75 2
     */
76 69
    public function addValidator(callable $callable, string $name): self
77
    {
78
        $this->validators[$name] = $callable;
79
80
        return $this;
81
    }
82
83
    /**
84
     * Adds multiple lines to the CSV document
85
     *
86
     * a simple wrapper method around insertOne
87
     *
88
     * @param Traversable|array $rows a multidimensional array or a Traversable object
89 12
     *
90
     * @throws Exception If the given rows format is invalid
91 12
     *
92 3
     * @return static
93 1
     */
94 2
    public function insertAll($rows): self
95
    {
96
        if (!is_array($rows) && !$rows instanceof Traversable) {
97 9
            throw new Exception('the provided data must be an array OR a `Traversable` object');
98 9
        }
99 6
100
        foreach ($rows as $row) {
101 9
            $this->insertOne($row);
102
        }
103
104
        return $this;
105
    }
106
107
    /**
108
     * Adds a single line to a CSV document
109
     *
110
     * @param string[] $row a string, an array or an object implementing to '__toString' method
111 39
     *
112
     * @return static
113 39
     */
114 15
    public function insertOne(array $row): self
115 10
    {
116 39
        $row = array_reduce($this->formatters, [$this, 'formatRecord'], $row);
117 39
        $this->validateRecord($row);
118
        $this->document->fputcsv($row, $this->delimiter, $this->enclosure, $this->escape);
119 36
        if ("\n" !== $this->newline) {
120 36
            $this->document->fseek(-1, SEEK_CUR);
121 24
            $this->document->fwrite($this->newline, strlen($this->newline));
122
        }
123 36
124 36
        $this->insert_count++;
125 3
        if (0 === $this->insert_count % $this->flush_threshold) {
126 3
            $this->document->fflush();
127 2
        }
128
129 36
        return $this;
130
    }
131
132
    /**
133
     * Format the given row
134
     *
135
     * @param string[] $row
136
     * @param callable $formatter
137
     *
138
     * @return string[]
139 36
     */
140
    protected function formatRecord(array $row, callable $formatter): array
141 36
    {
142 36
        return $formatter($row);
143 36
    }
144 24
145
    /**
146 36
    * Validate a row
147
    *
148
    * @param array $row
149
    *
150
    * @throws InvalidRowException If the validation failed
151
    */
152 6
    protected function validateRecord(array $row)
153
    {
154 6
        foreach ($this->validators as $name => $validator) {
155
            if (true !== $validator($row)) {
156
                throw new InvalidRowException($name, $row, 'row validation failed');
157
            }
158
        }
159
    }
160
}
161