Skip to content

Commit

Permalink
Merge pull request #40 from keboola/zajca-csv-options
Browse files Browse the repository at this point in the history
separate csv options to own class
  • Loading branch information
zajca authored Nov 11, 2019
2 parents aed833b + b0ff27c commit 86f03de
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 102 deletions.
82 changes: 13 additions & 69 deletions src/AbstractCsvFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,98 +4,42 @@

abstract class AbstractCsvFile
{
const DEFAULT_DELIMITER = ',';
const DEFAULT_ENCLOSURE = '"';
/**
* @var string
* @deprecated use Keboola\Csv\CsvOptions::DEFAULT_DELIMITER
*/
protected $fileName;
const DEFAULT_DELIMITER = CsvOptions::DEFAULT_DELIMITER;
/**
* @var resource
* @deprecated use Keboola\Csv\CsvOptions::DEFAULT_ENCLOSURE
*/
protected $filePointer;
const DEFAULT_ENCLOSURE = CsvOptions::DEFAULT_ENCLOSURE;

/**
* @var string
*/
private $delimiter;

protected $fileName;
/**
* @var string
* @var resource
*/
private $enclosure;

protected $filePointer;
/**
* @return string
* @var CsvOptions
*/
public function getDelimiter()
{
return $this->delimiter;
}
protected $options;

/**
* @param string $delimiter
* @throws InvalidArgumentException
*/
protected function setDelimiter($delimiter)
{
$this->validateDelimiter($delimiter);
$this->delimiter = $delimiter;
}

/**
* @param string $delimiter
* @throws InvalidArgumentException
* @return string
*/
protected function validateDelimiter($delimiter)
public function getDelimiter()
{
if (strlen($delimiter) > 1) {
throw new InvalidArgumentException(
"Delimiter must be a single character. " . json_encode($delimiter) . " received",
Exception::INVALID_PARAM
);
}

if (strlen($delimiter) == 0) {
throw new InvalidArgumentException(
"Delimiter cannot be empty.",
Exception::INVALID_PARAM
);
}
return $this->options->getDelimiter();
}

/**
* @return string
*/
public function getEnclosure()
{
return $this->enclosure;
}

/**
* @param string $enclosure
* @return $this
* @throws InvalidArgumentException
*/
protected function setEnclosure($enclosure)
{
$this->validateEnclosure($enclosure);
$this->enclosure = $enclosure;
return $this;
}

/**
* @param string $enclosure
* @throws InvalidArgumentException
*/
protected function validateEnclosure($enclosure)
{
if (strlen($enclosure) > 1) {
throw new InvalidArgumentException(
"Enclosure must be a single character. " . json_encode($enclosure) . " received",
Exception::INVALID_PARAM
);
}
return $this->options->getEnclosure();
}

public function __destruct()
Expand Down
102 changes: 102 additions & 0 deletions src/CsvOptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

namespace Keboola\Csv;

class CsvOptions
{
const DEFAULT_DELIMITER = ',';
const DEFAULT_ENCLOSURE = '"';
const DEFAULT_ESCAPED_BY = "";

/**
* @var string
*/
private $delimiter;

/**
* @var string
*/
private $enclosure;

/**
* @var string
*/
private $escapedBy;

/**
* @param string $delimiter
* @param string $enclosure
* @param string $escapedBy
* @throws InvalidArgumentException
*/
public function __construct(
$delimiter = self::DEFAULT_DELIMITER,
$enclosure = self::DEFAULT_ENCLOSURE,
$escapedBy = self::DEFAULT_ESCAPED_BY
) {
$this->escapedBy = $escapedBy;
$this->validateDelimiter($delimiter);
$this->delimiter = $delimiter;
$this->validateEnclosure($enclosure);
$this->enclosure = $enclosure;
}

/**
* @param string $enclosure
* @throws InvalidArgumentException
*/
protected function validateEnclosure($enclosure)
{
if (strlen($enclosure) > 1) {
throw new InvalidArgumentException(
"Enclosure must be a single character. " . json_encode($enclosure) . " received",
Exception::INVALID_PARAM
);
}
}

/**
* @param string $delimiter
* @throws InvalidArgumentException
*/
protected function validateDelimiter($delimiter)
{
if (strlen($delimiter) > 1) {
throw new InvalidArgumentException(
"Delimiter must be a single character. " . json_encode($delimiter) . " received",
Exception::INVALID_PARAM
);
}

if (strlen($delimiter) == 0) {
throw new InvalidArgumentException(
"Delimiter cannot be empty.",
Exception::INVALID_PARAM
);
}
}

/**
* @return string
*/
public function getEscapedBy()
{
return $this->escapedBy;
}

/**
* @return string
*/
public function getDelimiter()
{
return $this->delimiter;
}

/**
* @return string
*/
public function getEnclosure()
{
return $this->enclosure;
}
}
20 changes: 8 additions & 12 deletions src/CsvReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@

class CsvReader extends AbstractCsvFile implements \Iterator
{
const DEFAULT_ESCAPED_BY = "";

/**
* @var string
* @deprecated use Keboola\Csv\CsvOptions::DEFAULT_ENCLOSURE
*/
private $escapedBy;
const DEFAULT_ESCAPED_BY = CsvOptions::DEFAULT_ESCAPED_BY;

/**
* @var int
Expand Down Expand Up @@ -47,14 +45,12 @@ class CsvReader extends AbstractCsvFile implements \Iterator
*/
public function __construct(
$file,
$delimiter = self::DEFAULT_DELIMITER,
$enclosure = self::DEFAULT_ENCLOSURE,
$escapedBy = self::DEFAULT_ESCAPED_BY,
$delimiter = CsvOptions::DEFAULT_DELIMITER,
$enclosure = CsvOptions::DEFAULT_ENCLOSURE,
$escapedBy = CsvOptions::DEFAULT_ESCAPED_BY,
$skipLines = 0
) {
$this->escapedBy = $escapedBy;
$this->setDelimiter($delimiter);
$this->setEnclosure($enclosure);
$this->options = new CsvOptions($delimiter, $enclosure, $escapedBy);
$this->setSkipLines($skipLines);
$this->setFile($file);
$this->lineBreak = $this->detectLineBreak();
Expand Down Expand Up @@ -151,7 +147,7 @@ protected function readLine()

// allow empty enclosure hack
$enclosure = !$this->getEnclosure() ? chr(0) : $this->getEnclosure();
$escapedBy = !$this->escapedBy ? chr(0) : $this->escapedBy;
$escapedBy = !$this->getEscapedBy() ? chr(0) : $this->getEscapedBy();
return fgetcsv($this->getFilePointer(), null, $this->getDelimiter(), $enclosure, $escapedBy);
}

Expand Down Expand Up @@ -206,7 +202,7 @@ public function rewind()
*/
public function getEscapedBy()
{
return $this->escapedBy;
return $this->options->getEscapedBy();
}

/**
Expand Down
7 changes: 3 additions & 4 deletions src/CsvWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ class CsvWriter extends AbstractCsvFile
*/
public function __construct(
$file,
$delimiter = self::DEFAULT_DELIMITER,
$enclosure = self::DEFAULT_ENCLOSURE,
$delimiter = CsvOptions::DEFAULT_DELIMITER,
$enclosure = CsvOptions::DEFAULT_ENCLOSURE,
$lineBreak = "\n"
) {
$this->setDelimiter($delimiter);
$this->setEnclosure($enclosure);
$this->options = new CsvOptions($delimiter, $enclosure);
$this->setLineBreak($lineBreak);
$this->setFile($file);
}
Expand Down
38 changes: 38 additions & 0 deletions tests/CsvOptionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Keboola\Csv\Tests;

use Keboola\Csv\CsvOptions;
use Keboola\Csv\InvalidArgumentException;

class CsvOptionsTest extends \PHPUnit_Framework_TestCase
{
public function testAccessors()
{
$csvFile = new CsvOptions();
self::assertEquals("\"", $csvFile->getEnclosure());
self::assertEquals("", $csvFile->getEscapedBy());
self::assertEquals(",", $csvFile->getDelimiter());
}

public function testInvalidDelimiter()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('Delimiter must be a single character. ",," received');
new CsvOptions(",,");
}

public function testInvalidDelimiterEmpty()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('Delimiter cannot be empty.');
new CsvOptions("");
}

public function testInvalidEnclosure()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('Enclosure must be a single character. ",," received');
new CsvOptions(CsvOptions::DEFAULT_DELIMITER, ",,");
}
}
31 changes: 16 additions & 15 deletions tests/CsvReadTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Keboola\Csv\Tests;

use Keboola\Csv\CsvOptions;
use Keboola\Csv\CsvReader;
use Keboola\Csv\CsvWriter;
use Keboola\Csv\Exception;
Expand Down Expand Up @@ -218,9 +219,9 @@ public function testSkipsHeaders()

$csvFile = new CsvReader(
$fileName,
CsvReader::DEFAULT_DELIMITER,
CsvReader::DEFAULT_ENCLOSURE,
CsvReader::DEFAULT_ESCAPED_BY,
CsvOptions::DEFAULT_DELIMITER,
CsvOptions::DEFAULT_ENCLOSURE,
CsvOptions::DEFAULT_ESCAPED_BY,
1
);
self::assertEquals(['id', 'isImported'], $csvFile->getHeader());
Expand All @@ -237,9 +238,9 @@ public function testSkipNoLines()

$csvFile = new CsvReader(
$fileName,
CsvReader::DEFAULT_DELIMITER,
CsvReader::DEFAULT_ENCLOSURE,
CsvReader::DEFAULT_ESCAPED_BY,
CsvOptions::DEFAULT_DELIMITER,
CsvOptions::DEFAULT_ENCLOSURE,
CsvOptions::DEFAULT_ESCAPED_BY,
0
);
self::assertEquals(['id', 'isImported'], $csvFile->getHeader());
Expand All @@ -257,9 +258,9 @@ public function testSkipsMultipleLines()

$csvFile = new CsvReader(
$fileName,
CsvReader::DEFAULT_DELIMITER,
CsvReader::DEFAULT_ENCLOSURE,
CsvReader::DEFAULT_ESCAPED_BY,
CsvOptions::DEFAULT_DELIMITER,
CsvOptions::DEFAULT_ENCLOSURE,
CsvOptions::DEFAULT_ESCAPED_BY,
3
);
self::assertEquals(['id', 'isImported'], $csvFile->getHeader());
Expand All @@ -274,9 +275,9 @@ public function testSkipsOverflow()

$csvFile = new CsvReader(
$fileName,
CsvReader::DEFAULT_DELIMITER,
CsvReader::DEFAULT_ENCLOSURE,
CsvReader::DEFAULT_ESCAPED_BY,
CsvOptions::DEFAULT_DELIMITER,
CsvOptions::DEFAULT_ENCLOSURE,
CsvOptions::DEFAULT_ESCAPED_BY,
100
);
self::assertEquals(['id', 'isImported'], $csvFile->getHeader());
Expand Down Expand Up @@ -348,9 +349,9 @@ public function testInvalidSkipLines($skipLines, $message)
self::expectExceptionMessage($message);
new CsvReader(
'dummy',
CsvReader::DEFAULT_DELIMITER,
CsvReader::DEFAULT_ENCLOSURE,
CsvReader::DEFAULT_ENCLOSURE,
CsvOptions::DEFAULT_DELIMITER,
CsvOptions::DEFAULT_ENCLOSURE,
CsvOptions::DEFAULT_ENCLOSURE,
$skipLines
);
}
Expand Down
Loading

0 comments on commit 86f03de

Please sign in to comment.