Skip to content

Commit 86f03de

Browse files
authored
Merge pull request #40 from keboola/zajca-csv-options
separate csv options to own class
2 parents aed833b + b0ff27c commit 86f03de

File tree

7 files changed

+183
-102
lines changed

7 files changed

+183
-102
lines changed

src/AbstractCsvFile.php

Lines changed: 13 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,98 +4,42 @@
44

55
abstract class AbstractCsvFile
66
{
7-
const DEFAULT_DELIMITER = ',';
8-
const DEFAULT_ENCLOSURE = '"';
97
/**
10-
* @var string
8+
* @deprecated use Keboola\Csv\CsvOptions::DEFAULT_DELIMITER
119
*/
12-
protected $fileName;
10+
const DEFAULT_DELIMITER = CsvOptions::DEFAULT_DELIMITER;
1311
/**
14-
* @var resource
12+
* @deprecated use Keboola\Csv\CsvOptions::DEFAULT_ENCLOSURE
1513
*/
16-
protected $filePointer;
14+
const DEFAULT_ENCLOSURE = CsvOptions::DEFAULT_ENCLOSURE;
1715

1816
/**
1917
* @var string
2018
*/
21-
private $delimiter;
22-
19+
protected $fileName;
2320
/**
24-
* @var string
21+
* @var resource
2522
*/
26-
private $enclosure;
27-
23+
protected $filePointer;
2824
/**
29-
* @return string
25+
* @var CsvOptions
3026
*/
31-
public function getDelimiter()
32-
{
33-
return $this->delimiter;
34-
}
27+
protected $options;
3528

3629
/**
37-
* @param string $delimiter
38-
* @throws InvalidArgumentException
39-
*/
40-
protected function setDelimiter($delimiter)
41-
{
42-
$this->validateDelimiter($delimiter);
43-
$this->delimiter = $delimiter;
44-
}
45-
46-
/**
47-
* @param string $delimiter
48-
* @throws InvalidArgumentException
30+
* @return string
4931
*/
50-
protected function validateDelimiter($delimiter)
32+
public function getDelimiter()
5133
{
52-
if (strlen($delimiter) > 1) {
53-
throw new InvalidArgumentException(
54-
"Delimiter must be a single character. " . json_encode($delimiter) . " received",
55-
Exception::INVALID_PARAM
56-
);
57-
}
58-
59-
if (strlen($delimiter) == 0) {
60-
throw new InvalidArgumentException(
61-
"Delimiter cannot be empty.",
62-
Exception::INVALID_PARAM
63-
);
64-
}
34+
return $this->options->getDelimiter();
6535
}
6636

6737
/**
6838
* @return string
6939
*/
7040
public function getEnclosure()
7141
{
72-
return $this->enclosure;
73-
}
74-
75-
/**
76-
* @param string $enclosure
77-
* @return $this
78-
* @throws InvalidArgumentException
79-
*/
80-
protected function setEnclosure($enclosure)
81-
{
82-
$this->validateEnclosure($enclosure);
83-
$this->enclosure = $enclosure;
84-
return $this;
85-
}
86-
87-
/**
88-
* @param string $enclosure
89-
* @throws InvalidArgumentException
90-
*/
91-
protected function validateEnclosure($enclosure)
92-
{
93-
if (strlen($enclosure) > 1) {
94-
throw new InvalidArgumentException(
95-
"Enclosure must be a single character. " . json_encode($enclosure) . " received",
96-
Exception::INVALID_PARAM
97-
);
98-
}
42+
return $this->options->getEnclosure();
9943
}
10044

10145
public function __destruct()

src/CsvOptions.php

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
namespace Keboola\Csv;
4+
5+
class CsvOptions
6+
{
7+
const DEFAULT_DELIMITER = ',';
8+
const DEFAULT_ENCLOSURE = '"';
9+
const DEFAULT_ESCAPED_BY = "";
10+
11+
/**
12+
* @var string
13+
*/
14+
private $delimiter;
15+
16+
/**
17+
* @var string
18+
*/
19+
private $enclosure;
20+
21+
/**
22+
* @var string
23+
*/
24+
private $escapedBy;
25+
26+
/**
27+
* @param string $delimiter
28+
* @param string $enclosure
29+
* @param string $escapedBy
30+
* @throws InvalidArgumentException
31+
*/
32+
public function __construct(
33+
$delimiter = self::DEFAULT_DELIMITER,
34+
$enclosure = self::DEFAULT_ENCLOSURE,
35+
$escapedBy = self::DEFAULT_ESCAPED_BY
36+
) {
37+
$this->escapedBy = $escapedBy;
38+
$this->validateDelimiter($delimiter);
39+
$this->delimiter = $delimiter;
40+
$this->validateEnclosure($enclosure);
41+
$this->enclosure = $enclosure;
42+
}
43+
44+
/**
45+
* @param string $enclosure
46+
* @throws InvalidArgumentException
47+
*/
48+
protected function validateEnclosure($enclosure)
49+
{
50+
if (strlen($enclosure) > 1) {
51+
throw new InvalidArgumentException(
52+
"Enclosure must be a single character. " . json_encode($enclosure) . " received",
53+
Exception::INVALID_PARAM
54+
);
55+
}
56+
}
57+
58+
/**
59+
* @param string $delimiter
60+
* @throws InvalidArgumentException
61+
*/
62+
protected function validateDelimiter($delimiter)
63+
{
64+
if (strlen($delimiter) > 1) {
65+
throw new InvalidArgumentException(
66+
"Delimiter must be a single character. " . json_encode($delimiter) . " received",
67+
Exception::INVALID_PARAM
68+
);
69+
}
70+
71+
if (strlen($delimiter) == 0) {
72+
throw new InvalidArgumentException(
73+
"Delimiter cannot be empty.",
74+
Exception::INVALID_PARAM
75+
);
76+
}
77+
}
78+
79+
/**
80+
* @return string
81+
*/
82+
public function getEscapedBy()
83+
{
84+
return $this->escapedBy;
85+
}
86+
87+
/**
88+
* @return string
89+
*/
90+
public function getDelimiter()
91+
{
92+
return $this->delimiter;
93+
}
94+
95+
/**
96+
* @return string
97+
*/
98+
public function getEnclosure()
99+
{
100+
return $this->enclosure;
101+
}
102+
}

src/CsvReader.php

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44

55
class CsvReader extends AbstractCsvFile implements \Iterator
66
{
7-
const DEFAULT_ESCAPED_BY = "";
8-
97
/**
10-
* @var string
8+
* @deprecated use Keboola\Csv\CsvOptions::DEFAULT_ENCLOSURE
119
*/
12-
private $escapedBy;
10+
const DEFAULT_ESCAPED_BY = CsvOptions::DEFAULT_ESCAPED_BY;
1311

1412
/**
1513
* @var int
@@ -47,14 +45,12 @@ class CsvReader extends AbstractCsvFile implements \Iterator
4745
*/
4846
public function __construct(
4947
$file,
50-
$delimiter = self::DEFAULT_DELIMITER,
51-
$enclosure = self::DEFAULT_ENCLOSURE,
52-
$escapedBy = self::DEFAULT_ESCAPED_BY,
48+
$delimiter = CsvOptions::DEFAULT_DELIMITER,
49+
$enclosure = CsvOptions::DEFAULT_ENCLOSURE,
50+
$escapedBy = CsvOptions::DEFAULT_ESCAPED_BY,
5351
$skipLines = 0
5452
) {
55-
$this->escapedBy = $escapedBy;
56-
$this->setDelimiter($delimiter);
57-
$this->setEnclosure($enclosure);
53+
$this->options = new CsvOptions($delimiter, $enclosure, $escapedBy);
5854
$this->setSkipLines($skipLines);
5955
$this->setFile($file);
6056
$this->lineBreak = $this->detectLineBreak();
@@ -151,7 +147,7 @@ protected function readLine()
151147

152148
// allow empty enclosure hack
153149
$enclosure = !$this->getEnclosure() ? chr(0) : $this->getEnclosure();
154-
$escapedBy = !$this->escapedBy ? chr(0) : $this->escapedBy;
150+
$escapedBy = !$this->getEscapedBy() ? chr(0) : $this->getEscapedBy();
155151
return fgetcsv($this->getFilePointer(), null, $this->getDelimiter(), $enclosure, $escapedBy);
156152
}
157153

@@ -206,7 +202,7 @@ public function rewind()
206202
*/
207203
public function getEscapedBy()
208204
{
209-
return $this->escapedBy;
205+
return $this->options->getEscapedBy();
210206
}
211207

212208
/**

src/CsvWriter.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ class CsvWriter extends AbstractCsvFile
2020
*/
2121
public function __construct(
2222
$file,
23-
$delimiter = self::DEFAULT_DELIMITER,
24-
$enclosure = self::DEFAULT_ENCLOSURE,
23+
$delimiter = CsvOptions::DEFAULT_DELIMITER,
24+
$enclosure = CsvOptions::DEFAULT_ENCLOSURE,
2525
$lineBreak = "\n"
2626
) {
27-
$this->setDelimiter($delimiter);
28-
$this->setEnclosure($enclosure);
27+
$this->options = new CsvOptions($delimiter, $enclosure);
2928
$this->setLineBreak($lineBreak);
3029
$this->setFile($file);
3130
}

tests/CsvOptionsTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Keboola\Csv\Tests;
4+
5+
use Keboola\Csv\CsvOptions;
6+
use Keboola\Csv\InvalidArgumentException;
7+
8+
class CsvOptionsTest extends \PHPUnit_Framework_TestCase
9+
{
10+
public function testAccessors()
11+
{
12+
$csvFile = new CsvOptions();
13+
self::assertEquals("\"", $csvFile->getEnclosure());
14+
self::assertEquals("", $csvFile->getEscapedBy());
15+
self::assertEquals(",", $csvFile->getDelimiter());
16+
}
17+
18+
public function testInvalidDelimiter()
19+
{
20+
self::expectException(InvalidArgumentException::class);
21+
self::expectExceptionMessage('Delimiter must be a single character. ",," received');
22+
new CsvOptions(",,");
23+
}
24+
25+
public function testInvalidDelimiterEmpty()
26+
{
27+
self::expectException(InvalidArgumentException::class);
28+
self::expectExceptionMessage('Delimiter cannot be empty.');
29+
new CsvOptions("");
30+
}
31+
32+
public function testInvalidEnclosure()
33+
{
34+
self::expectException(InvalidArgumentException::class);
35+
self::expectExceptionMessage('Enclosure must be a single character. ",," received');
36+
new CsvOptions(CsvOptions::DEFAULT_DELIMITER, ",,");
37+
}
38+
}

tests/CsvReadTest.php

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Keboola\Csv\Tests;
44

5+
use Keboola\Csv\CsvOptions;
56
use Keboola\Csv\CsvReader;
67
use Keboola\Csv\CsvWriter;
78
use Keboola\Csv\Exception;
@@ -218,9 +219,9 @@ public function testSkipsHeaders()
218219

219220
$csvFile = new CsvReader(
220221
$fileName,
221-
CsvReader::DEFAULT_DELIMITER,
222-
CsvReader::DEFAULT_ENCLOSURE,
223-
CsvReader::DEFAULT_ESCAPED_BY,
222+
CsvOptions::DEFAULT_DELIMITER,
223+
CsvOptions::DEFAULT_ENCLOSURE,
224+
CsvOptions::DEFAULT_ESCAPED_BY,
224225
1
225226
);
226227
self::assertEquals(['id', 'isImported'], $csvFile->getHeader());
@@ -237,9 +238,9 @@ public function testSkipNoLines()
237238

238239
$csvFile = new CsvReader(
239240
$fileName,
240-
CsvReader::DEFAULT_DELIMITER,
241-
CsvReader::DEFAULT_ENCLOSURE,
242-
CsvReader::DEFAULT_ESCAPED_BY,
241+
CsvOptions::DEFAULT_DELIMITER,
242+
CsvOptions::DEFAULT_ENCLOSURE,
243+
CsvOptions::DEFAULT_ESCAPED_BY,
243244
0
244245
);
245246
self::assertEquals(['id', 'isImported'], $csvFile->getHeader());
@@ -257,9 +258,9 @@ public function testSkipsMultipleLines()
257258

258259
$csvFile = new CsvReader(
259260
$fileName,
260-
CsvReader::DEFAULT_DELIMITER,
261-
CsvReader::DEFAULT_ENCLOSURE,
262-
CsvReader::DEFAULT_ESCAPED_BY,
261+
CsvOptions::DEFAULT_DELIMITER,
262+
CsvOptions::DEFAULT_ENCLOSURE,
263+
CsvOptions::DEFAULT_ESCAPED_BY,
263264
3
264265
);
265266
self::assertEquals(['id', 'isImported'], $csvFile->getHeader());
@@ -274,9 +275,9 @@ public function testSkipsOverflow()
274275

275276
$csvFile = new CsvReader(
276277
$fileName,
277-
CsvReader::DEFAULT_DELIMITER,
278-
CsvReader::DEFAULT_ENCLOSURE,
279-
CsvReader::DEFAULT_ESCAPED_BY,
278+
CsvOptions::DEFAULT_DELIMITER,
279+
CsvOptions::DEFAULT_ENCLOSURE,
280+
CsvOptions::DEFAULT_ESCAPED_BY,
280281
100
281282
);
282283
self::assertEquals(['id', 'isImported'], $csvFile->getHeader());
@@ -348,9 +349,9 @@ public function testInvalidSkipLines($skipLines, $message)
348349
self::expectExceptionMessage($message);
349350
new CsvReader(
350351
'dummy',
351-
CsvReader::DEFAULT_DELIMITER,
352-
CsvReader::DEFAULT_ENCLOSURE,
353-
CsvReader::DEFAULT_ENCLOSURE,
352+
CsvOptions::DEFAULT_DELIMITER,
353+
CsvOptions::DEFAULT_ENCLOSURE,
354+
CsvOptions::DEFAULT_ENCLOSURE,
354355
$skipLines
355356
);
356357
}

0 commit comments

Comments
 (0)