Completed
Pull Request — master (#153)
by Hannes
14:09
created

Writer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
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 8.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
namespace League\Csv;
14
15
use InvalidArgumentException;
16
use League\Csv\Modifier\RowFilter;
17
use ReflectionMethod;
18
use SplFileObject;
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
 *
27
 */
28
class Writer extends AbstractCsv
29
{
30
    use RowFilter;
31
32
    /**
33
     * @inheritdoc
34
     */
35
    protected $stream_filter_mode = STREAM_FILTER_WRITE;
36
37
    /**
38
     * The CSV object holder
39
     *
40
     * @var SplFileObject
41
     */
42
    protected $csv;
43
44
    /**
45
     * fputcsv method from SplFileObject
46
     *
47
     * @var ReflectionMethod
48
     */
49
    protected static $fputcsv;
50
51
    /**
52
     * Nb parameters for SplFileObject::fputcsv method
53
     *
54
     * @var integer
55
     */
56
    protected static $fputcsv_param_count;
57
58
    /**
59
     * @inheritdoc
60
     */
61 69
    protected function __construct($path, $open_mode = 'r+')
62
    {
63 69
        parent::__construct($path, $open_mode);
64 69
        static::initFputcsv();
65 69
        $this->addDefaultFormatters();
66
    }
67
68
    /**
69
     * initiate a SplFileObject::fputcsv method
70 69
     */
71
    protected static function initFputcsv()
72 69
    {
73 3
        if (null === static::$fputcsv) {
74 3
            static::$fputcsv = new ReflectionMethod('\SplFileObject', 'fputcsv');
75 2
            static::$fputcsv_param_count = static::$fputcsv->getNumberOfParameters();
76 69
        }
77
    }
78
79
    /**
80
     * Adds multiple lines to the CSV document
81
     *
82
     * a simple wrapper method around insertOne
83
     *
84
     * @param Traversable|array $rows a multidimensional array or a Traversable object
85
     *
86
     * @throws InvalidArgumentException If the given rows format is invalid
87
     *
88
     * @return static
89 12
     */
90
    public function insertAll($rows)
91 12
    {
92 3
        if (!is_array($rows) && !$rows instanceof Traversable) {
93 1
            throw new InvalidArgumentException(
94 2
                'the provided data must be an array OR a `Traversable` object'
95
            );
96
        }
97 9
98 9
        foreach ($rows as $row) {
99 6
            $this->insertOne($row);
100
        }
101 9
102
        return $this;
103
    }
104
105
    /**
106
     * Adds a single line to a CSV document
107
     *
108
     * @param string[]|string $row a string, an array or an object implementing to '__toString' method
109
     *
110
     * @return static
111 39
     */
112
    public function insertOne($row)
113 39
    {
114 15
        $row = $this->formatRow($row);
0 ignored issues
show
Bug introduced by
It seems like $row can also be of type string; however, League\Csv\Modifier\RowFilter::formatRow() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
115 10
        $this->validateRow($row);
116 39
117 39
        if (null === $this->csv) {
118
            $this->csv = $this->getIterator();
119 36
        }
120 36
121 24
        static::$fputcsv->invokeArgs($this->csv, $this->getFputcsvParameters($row));
122
        if ("\n" !== $this->newline) {
123 36
            $this->csv->fseek(-1, SEEK_CUR);
124 36
            $this->csv->fwrite($this->newline);
125 3
        }
126 3
127 2
        return $this;
128
    }
129 36
130
    /**
131
     * returns the parameters for SplFileObject::fputcsv
132
     *
133
     * @param array $fields The fields to be add
134
     *
135
     * @return array
136
     */
137
    protected function getFputcsvParameters(array $fields)
138
    {
139 36
        $parameters = [$fields, $this->delimiter, $this->enclosure];
140
        if (4 == static::$fputcsv_param_count) {
141 36
            $parameters[] = $this->escape;
142 36
        }
143 36
144 24
        return $parameters;
145
    }
146 36
147
    /**
148
     * Adds default formatters.
149
     *
150
     * @return static
151
     */
152 6
    private function addDefaultFormatters()
153
    {
154 6
        $this->addFormatter(function ($row) {
155
            if (is_array($row)) {
156
                return $row;
157
            }
158
159
            return str_getcsv($row, $this->delimiter, $this->enclosure, $this->escape);
160 69
        });
161
162 69
        return $this;
163 69
    }
164 69
165
    /**
166
     *  {@inheritdoc}
167
     */
168
    public function isActiveStreamFilter()
169
    {
170
        return parent::isActiveStreamFilter() && null === $this->csv;
171
    }
172
173
    /**
174
     *  {@inheritdoc}
175
     */
176
    public function __destruct()
177
    {
178
        $this->csv = null;
179
        parent::__destruct();
180
    }
181
}
182