diff options
author | ignace nyamagana butera <nyamsprod@gmail.com> | 2014-03-22 13:34:59 +0100 |
---|---|---|
committer | ignace nyamagana butera <nyamsprod@gmail.com> | 2014-03-24 21:39:41 +0100 |
commit | 774c56e5ca7c86895ce5b05e8b93c6c64834e7f2 (patch) | |
tree | 1e2cade7a3a6c838802aea27f3f99452dc6c1474 | |
parent | d271a29ce97c03c9d4a46b8c8b801c78ed571ca9 (diff) | |
download | csv-774c56e5ca7c86895ce5b05e8b93c6c64834e7f2.zip csv-774c56e5ca7c86895ce5b05e8b93c6c64834e7f2.tar.gz csv-774c56e5ca7c86895ce5b05e8b93c6c64834e7f2.tar.bz2 |
adding null value handling in Writer class #28
-rw-r--r-- | src/Writer.php | 72 | ||||
-rw-r--r-- | test/WriterTest.php | 46 |
2 files changed, 116 insertions, 2 deletions
diff --git a/src/Writer.php b/src/Writer.php index 41c5609..9318f23 100644 --- a/src/Writer.php +++ b/src/Writer.php @@ -32,8 +32,9 @@ */ namespace League\Csv; -use InvalidArgumentException; use Traversable; +use InvalidArgumentException; +use OutOfBoundsException; /** * A class to manage data insertion into a CSV @@ -44,6 +45,15 @@ use Traversable; */ class Writer extends AbstractCsv { + + const NULL_AS_EXCEPTION = 1; + + const NULL_AS_SKIP_CELL = 2; + + const NULL_AS_EMPTY = 3; + + private $null_handling = self::NULL_AS_EXCEPTION; + /** * The constructor * @@ -56,6 +66,62 @@ class Writer extends AbstractCsv } /** + * Tell the class how to handle null value + * + * @param integer $value a Writer null behavior constant + * + * @return self + * + * @throws OutOfBoundsException If the Integer is not valid + */ + public function setNullHandling($value) + { + if (!in_array($value, [self::NULL_AS_SKIP_CELL, self::NULL_AS_EXCEPTION, self::NULL_AS_EMPTY])) { + throw new OutOfBoundsException( + 'invalid value for null behavior' + ); + } + $this->null_handling = $value; + + return $this; + } + + /** + * null handling getter + * + * @return integer + */ + public function getNullHandling() + { + return $this->null_handling; + } + + /** + * Format the row according to the null handling behavior + * + * @param array $row + * + * @return array + */ + private function formatRow(array $row) + { + if (self::NULL_AS_EMPTY == $this->null_handling) { + foreach ($row as &$value) { + if (is_null($value)) { + $value = ''; + } + } + unset($value); + + return $row; + } + + return array_filter($row, function ($value) { + return ! is_null($value); + }); + } + + /** * Add a new CSV row to the generated CSV * * @param mixed $row a string, an array or an object implementing to '__toString' method @@ -75,9 +141,11 @@ class Writer extends AbstractCsv ); } $check = array_filter($row, function ($value) { - return self::isValidString($value); + return (is_null($value) && self::NULL_AS_EXCEPTION != $this->null_handling) + || self::isValidString($value); }); if (count($check) == count($row)) { + $row = $this->formatRow($row); $this->csv->fputcsv($row, $this->delimiter, $this->enclosure); return $this; diff --git a/test/WriterTest.php b/test/WriterTest.php index e22cd9a..2e87c91 100644 --- a/test/WriterTest.php +++ b/test/WriterTest.php @@ -4,6 +4,7 @@ namespace League\Csv\Test; use SplTempFileObject; use ArrayIterator; +use LimitIterator; use PHPUnit_Framework_TestCase; use DateTime; use League\Csv\Writer; @@ -39,6 +40,51 @@ class WriterTest extends PHPUnit_Framework_TestCase } /** + * @expectedException OutOfBoundsException + */ + public function testSetterGetterNullBehavior() + { + $this->csv->setNullHandling(Writer::NULL_AS_SKIP_CELL); + $this->assertSame(Writer::NULL_AS_SKIP_CELL, $this->csv->getNullHandling()); + + $this->csv->setNullHandling(23); + } + + public function testInsertNullToSkipCell() + { + $expected = [ + ['john', 'doe', 'john.doe@example.com'], + 'john,doe,john.doe@example.com', + ['john', null, 'john.doe@example.com'], + ]; + $this->csv->setNullHandling(Writer::NULL_AS_SKIP_CELL); + foreach ($expected as $row) { + $this->csv->insertOne($row); + } + $iterator = new LimitIterator($this->csv->getIterator(), 2, 1); + $iterator->rewind(); + $res = $iterator->getInnerIterator()->current(); + $this->assertSame(['john', 'john.doe@example.com'], $res); + } + + public function testInsertNullToEmpty() + { + $expected = [ + ['john', 'doe', 'john.doe@example.com'], + 'john,doe,john.doe@example.com', + ['john', null, 'john.doe@example.com'], + ]; + $this->csv->setNullHandling(Writer::NULL_AS_EMPTY); + foreach ($expected as $row) { + $this->csv->insertOne($row); + } + $iterator = new LimitIterator($this->csv->getIterator(), 2, 1); + $iterator->rewind(); + $res = $iterator->getInnerIterator()->current(); + $this->assertSame(['john', '', 'john.doe@example.com'], $res); + } + + /** * @expectedException InvalidArgumentException */ public function testFailedInsertWithWrongData() |