Completed
Push — master ( 85851c...4b020b )
by Harry
03:30
created

CsvFormat   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 373
Duplicated Lines 0 %

Coupling/Cohesion

Components 5
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 1 Features 2
Metric Value
wmc 41
c 7
b 1
f 2
lcom 5
cbo 2
dl 0
loc 373
ccs 95
cts 95
cp 1
rs 8.2769

30 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
A getDelimiter() 0 4 1
A setDelimiter() 0 5 1
A getQuote() 0 4 1
A hasQuote() 0 4 1
A setQuote() 0 5 1
A getNullValue() 0 4 1
A setNullValue() 0 5 1
A hasHeaderRow() 0 4 1
A setHeaderRow() 0 5 1
A getHeaderRow() 0 4 1
A getDataStart() 0 7 3
A setDataStart() 0 5 1
A getType() 0 4 1
A getEscape() 0 4 1
A setEscape() 0 5 1
A hasEscape() 0 4 1
A getLimit() 0 4 1
A setLimit() 0 5 1
A useDoubleQuotes() 0 4 1
A setDoubleQuote() 0 5 1
A setEncoding() 0 5 1
A getNewLines() 0 4 1
A setNewLine() 0 5 2
A getBom() 0 4 2
A getEncoding() 0 8 3
A getNewLine() 0 4 2
A setBom() 0 9 3
A getBoms() 0 10 3
A getDefaultBoms() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like CsvFormat often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CsvFormat, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * This file is part of graze/data-file
4
 *
5
 * Copyright (c) 2016 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/data-file/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/data-file
12
 */
13
14
namespace Graze\DataFile\Format;
15
16
use Graze\CsvToken\Csv\Bom;
17
use Graze\DataFile\Helper\GetOptionTrait;
18
19
class CsvFormat implements CsvFormatInterface
20
{
21
    use GetOptionTrait;
22
23
    const DEFAULT_DELIMITER    = ',';
24
    const DEFAULT_NULL         = '\\N';
25
    const DEFAULT_HEADER_ROW   = -1;
26
    const DEFAULT_DATA_START   = 1;
27
    const DEFAULT_QUOTE        = '"';
28
    const DEFAULT_ESCAPE       = '\\';
29
    const DEFAULT_LIMIT        = -1;
30
    const DEFAULT_DOUBLE_QUOTE = false;
31
    const DEFAULT_ENCODING     = 'UTF-8';
32
    const DEFAULT_NEW_LINE     = "\n";
33
    const DEFAULT_BOM          = null;
34
35
    const OPTION_DELIMITER    = 'delimiter';
36
    const OPTION_NULL         = 'null';
37
    const OPTION_HEADER_ROW   = 'headerRow';
38
    const OPTION_DATA_START   = 'dataStart';
39
    const OPTION_NEW_LINE     = 'newLine';
40
    const OPTION_QUOTE        = 'quote';
41
    const OPTION_ESCAPE       = 'escape';
42
    const OPTION_LIMIT        = 'limit';
43
    const OPTION_DOUBLE_QUOTE = 'doubleQuote';
44
    const OPTION_BOM          = 'bom';
45
    const OPTION_ENCODING     = 'encoding';
46
47
    /** @var string */
48
    protected $delimiter;
49
    /** @var string */
50
    protected $quote;
51
    /** @var string */
52
    protected $nullValue;
53
    /** @var int */
54
    protected $headerRow;
55
    /** @var string[] */
56
    protected $newLines;
57
    /** @var string */
58
    protected $escape;
59
    /** @var int */
60
    protected $limit;
61
    /** @var bool */
62
    protected $doubleQuote;
63
    /** @var int */
64
    protected $dataStart;
65
    /** @var string[]|string|null */
66
    protected $boms;
67
    /** @var string */
68
    protected $encoding;
69
70
    /**
71
     * @param array $options -delimiter <string> (Default: ,) Character to use between fields
72
     *                       -quoteCharacter <string> (Default: ")
73
     *                       -nullOutput <string> (Default: \N)
74
     *                       -headerRow <int> (Default: -1) -1 for no header row. (1 is the first line of the file)
75
     *                       -dataStart <int> (Default: 1) The line where the data starts (1 is the first list of the
76
     *                       file)
77
     *                       -lineTerminator <array> (Default: ["\n","\r","\r\n"])
78
     *                       -escape <string> (Default: \\) Character to use for escaping
79
     *                       -limit <int> Total number of data rows to return
80
     *                       -doubleQuote <bool> instances of quote in fields are indicated by a double quote
81
     *                       -bom <array> (Default: BOM_ALL) Specify a ByteOrderMark for this file (see Bom::BOM_*)
82
     *                       -encoding <string> (Default: UTF-8) Specify the encoding of the csv file
83
     */
84 16
    public function __construct(array $options = [])
85
    {
86 16
        $this->options = $options;
87 16
        $this->delimiter = $this->getOption(static::OPTION_DELIMITER, static::DEFAULT_DELIMITER);
88 16
        $this->quote = $this->getOption(static::OPTION_QUOTE, static::DEFAULT_QUOTE);
89 16
        $this->nullValue = $this->getOption(static::OPTION_NULL, static::DEFAULT_NULL);
90 16
        $this->headerRow = $this->getOption(static::OPTION_HEADER_ROW, static::DEFAULT_HEADER_ROW);
91 16
        $this->dataStart = $this->getOption(static::OPTION_DATA_START, static::DEFAULT_DATA_START);
92 16
        $this->escape = $this->getOption(static::OPTION_ESCAPE, static::DEFAULT_ESCAPE);
93 16
        $this->limit = $this->getOption(static::OPTION_LIMIT, static::DEFAULT_LIMIT);
94 16
        $this->doubleQuote = $this->getOption(static::OPTION_DOUBLE_QUOTE, static::DEFAULT_DOUBLE_QUOTE);
95 16
        $this->encoding = $this->getOption(static::OPTION_ENCODING, static::DEFAULT_ENCODING);
96 16
        $this->setBom($this->getOption(static::OPTION_BOM, static::DEFAULT_BOM));
97 16
        $this->setNewLine($this->getOption(static::OPTION_NEW_LINE, ["\n", "\r", "\r\n"]));
98 16
    }
99
100
    /**
101
     * @return string
102
     */
103 27
    public function getDelimiter()
104
    {
105 27
        return $this->delimiter;
106
    }
107
108
    /**
109
     * @param string $delimiter
110
     *
111
     * @return static
112
     */
113 2
    public function setDelimiter($delimiter)
114
    {
115 2
        $this->delimiter = $delimiter;
116 2
        return $this;
117
    }
118
119
    /**
120
     * @return string
121
     */
122 26
    public function getQuote()
123
    {
124 26
        return $this->quote;
125
    }
126
127
    /**
128
     * @return bool
129
     */
130 20
    public function hasQuote()
131
    {
132 20
        return $this->quote <> '';
133
    }
134
135
    /**
136
     * @param string $quote
137
     *
138
     * @return static
139
     */
140 1
    public function setQuote($quote)
141
    {
142 1
        $this->quote = $quote;
143 1
        return $this;
144
    }
145
146
    /**
147
     * @return string
148
     */
149 16
    public function getNullValue()
150
    {
151 16
        return $this->nullValue;
152
    }
153
154
    /**
155
     * @param string $nullValue
156
     *
157
     * @return static
158
     */
159 1
    public function setNullValue($nullValue)
160
    {
161 1
        $this->nullValue = $nullValue;
162 1
        return $this;
163
    }
164
165
    /**
166
     * @return bool
167
     */
168 13
    public function hasHeaderRow()
169
    {
170 13
        return $this->headerRow > 0;
171
    }
172
173
    /**
174
     * @param int $headerRow
175
     *
176
     * @return static
177
     */
178 2
    public function setHeaderRow($headerRow)
179
    {
180 2
        $this->headerRow = $headerRow;
181 2
        return $this;
182
    }
183
184
    /**
185
     * @return int
186
     */
187 7
    public function getHeaderRow()
188
    {
189 7
        return $this->headerRow;
190
    }
191
192
    /**
193
     * @return int
194
     */
195 13
    public function getDataStart()
196
    {
197 13
        if ($this->hasHeaderRow() && $this->getHeaderRow() >= $this->dataStart) {
198 4
            return max(1, $this->getHeaderRow() + 1);
199
        }
200 10
        return max(1, $this->dataStart);
201
    }
202
203
    /**
204
     * @param int $row
205
     *
206
     * @return static
207
     */
208 2
    public function setDataStart($row)
209
    {
210 2
        $this->dataStart = $row;
211 2
        return $this;
212
    }
213
214
    /**
215
     * Type type of file format (defined in FileFormatType::)
216
     *
217
     * @return string
218
     */
219 7
    public function getType()
220
    {
221 7
        return 'csv';
222
    }
223
224
    /**
225
     * @return string
226
     */
227 29
    public function getEscape()
228
    {
229 29
        return $this->escape;
230
    }
231
232
    /**
233
     * @param string $escape
234
     *
235
     * @return static
236
     */
237 1
    public function setEscape($escape)
238
    {
239 1
        $this->escape = $escape;
240 1
        return $this;
241
    }
242
243
    /**
244
     * @return bool
245
     */
246 3
    public function hasEscape()
247
    {
248 3
        return $this->escape !== '';
249
    }
250
251
    /**
252
     * Get the limit that should be returned (-1 for no limit)
253
     *
254
     * @return int
255
     */
256 12
    public function getLimit()
257
    {
258 12
        return $this->limit;
259
    }
260
261
    /**
262
     * Set the limit of the number of items to be returned (-1 for not limit)
263
     *
264
     * @param int $limit
265
     *
266
     * @return static
267
     */
268 1
    public function setLimit($limit)
269
    {
270 1
        $this->limit = $limit;
271 1
        return $this;
272
    }
273
274
    /**
275
     * @return bool
276
     */
277 24
    public function useDoubleQuotes()
278
    {
279 24
        return $this->doubleQuote;
280
    }
281
282
    /**
283
     * @param bool $doubleQuote
284
     *
285
     * @return static
286
     */
287 1
    public function setDoubleQuote($doubleQuote)
288
    {
289 1
        $this->doubleQuote = $doubleQuote;
290 1
        return $this;
291
    }
292
293
    /**
294
     * @return string
295
     */
296 24
    public function getEncoding()
297
    {
298 24
        if (!is_null($this->boms)) {
299 3
            $bom = is_array($this->boms) ? reset($this->boms) : $this->boms;
300 3
            return Bom::getEncoding($bom);
301
        }
302 22
        return $this->encoding;
303
    }
304
305
    /**
306
     * @param string $encoding
307
     *
308
     * @return static
309
     */
310 1
    public function setEncoding($encoding)
311
    {
312 1
        $this->encoding = $encoding;
313 1
        return $this;
314
    }
315
316
    /**
317
     * @return string[]
318
     */
319 12
    public function getNewLines()
320
    {
321 12
        return $this->newLines;
322
    }
323
324
    /**
325
     * @param string|string[] $newLine
326
     *
327
     * @return static
328
     */
329 16
    public function setNewLine($newLine)
330
    {
331 16
        $this->newLines = is_array($newLine) ? $newLine : [$newLine];
332 16
        return $this;
333
    }
334
335
    /**
336
     * Get a new line for writing
337
     *
338
     * @return string
339
     */
340 7
    public function getNewLine()
341
    {
342 7
        return is_array($this->newLines) ? reset($this->newLines) : $this->newLines;
343
    }
344
345
    /**
346
     * @param null|string[]|string $bom
347
     *
348
     * @return static
349
     */
350 16
    public function setBom($bom)
351
    {
352 16
        $this->boms = $bom;
353 16
        if (!is_null($bom)) {
354 4
            $testBom = is_array($bom) ? reset($bom) : $bom;
355 4
            Bom::getEncoding($testBom);
356
        }
357 16
        return $this;
358
    }
359
360
    /**
361
     * @return string[]
362
     */
363 12
    public function getBoms()
364
    {
365 12
        if (is_null($this->boms)) {
366 10
            return $this->getDefaultBoms();
367 3
        } elseif (is_array($this->boms)) {
368 1
            return $this->boms;
369
        } else {
370 3
            return [$this->boms];
371
        }
372
    }
373
374
    /**
375
     * Get a ByteOrderMark for writing if applicable
376
     *
377
     * @return string|null
378
     */
379 20
    public function getBom()
380
    {
381 20
        return is_array($this->boms) ? reset($this->boms) : $this->boms;
382
    }
383
384
    /**
385
     * @return string[]
386
     */
387 10
    private function getDefaultBoms()
388
    {
389 10
        return [Bom::BOM_UTF8, Bom::BOM_UTF16_BE, Bom::BOM_UTF16_LE, Bom::BOM_UTF32_BE, Bom::BOM_UTF32_LE];
390
    }
391
}
392