diff options
author | Ignace Nyamagana Butera <nyamsprod@gmail.com> | 2014-12-01 09:14:54 +0100 |
---|---|---|
committer | Ignace Nyamagana Butera <nyamsprod@gmail.com> | 2014-12-01 09:14:54 +0100 |
commit | bcb0fd0dd7a3c8d913f9262f76b6b6665fdc8828 (patch) | |
tree | 9c23318bf25bd59bbba7ada6584fa780860a83ff | |
parent | 28eabada4d2ccefc272b506dbcf1d6e9ebab9b06 (diff) | |
download | csv-bcb0fd0dd7a3c8d913f9262f76b6b6665fdc8828.zip csv-bcb0fd0dd7a3c8d913f9262f76b6b6665fdc8828.tar.gz csv-bcb0fd0dd7a3c8d913f9262f76b6b6665fdc8828.tar.bz2 |
Bug fix in implementing issue #62
-rw-r--r-- | src/Reader.php | 67 | ||||
-rw-r--r-- | test/ReaderTest.php | 44 |
2 files changed, 78 insertions, 33 deletions
diff --git a/src/Reader.php b/src/Reader.php index 5b9f23b..dddd33b 100644 --- a/src/Reader.php +++ b/src/Reader.php @@ -17,6 +17,7 @@ use InvalidArgumentException; use Iterator; use League\Csv\Iterator\MapIterator; use League\Csv\Iterator\Query; +use LimitIterator; /** * A class to manage extracting and filtering a CSV @@ -38,12 +39,6 @@ class Reader extends AbstractCsv protected $stream_filter_mode = STREAM_FILTER_READ; /** - * Contain the header (csv first line) - * @var array - */ - protected $header; - - /** * Return a Filtered Iterator * * @param callable $callable a callable function to be applied to each Iterator item @@ -132,29 +127,22 @@ class Reader extends AbstractCsv * The rows are presented as associated arrays * The callable function will be applied to each Iterator item * - * @param array $keys the name for each key member - * @param callable $callable a callable function + * @param array|int $keys the name for each key member OR the row Index to be + * used as the associated named keys + * @param callable $callable a callable function * * @throws \InvalidArgumentException If the submitted keys are not integer or strng * * @return array */ - public function fetchAssoc(array $keys = [], callable $callable = null) + public function fetchAssoc($keys = 0, callable $callable = null) { - if (empty($keys)) { - $keys = $this->getDefaultKeys(); - } - - $validKeys = array_unique(array_filter($keys, function ($value) { - return self::isValidString($value); - })); - - if ($keys !== $validKeys) { + $keys = $this->formatAssocKeys($keys); + if (! $this->isValidAssocKeys($keys)) { throw new InvalidArgumentException( 'The named keys should be unique strings Or integer' ); } - $iterator = $this->query($callable); $iterator = new MapIterator($iterator, function ($row) use ($keys) { return self::combineArray($keys, $row); @@ -164,21 +152,46 @@ class Reader extends AbstractCsv } /** - * Get the first line and add a filter to not get it again when - * fetching. + * Select the array to be used as key for the fetchAssoc method + * @param array|int $keys the assoc key OR the row Index to be used + * as the key index + * + * @throws \InvalidArgumentException If the row index is invalid * * @return array */ - protected function getDefaultKeys() + protected function formatAssocKeys($keys) { - if (isset($this->header)) { - return $this->header; + if (is_array($keys)) { + return $keys; + } elseif (false === filter_var($keys, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { + throw new InvalidArgumentException('the column index must be a positive integer or 0'); } - $this->header = $this->fetchOne(); - $this->addFilter(function ($row, $index) { return $index > 0; }); + $this->addFilter(function ($row, $rowIndex) use ($keys) { + return is_array($row) && $rowIndex != $keys; + }); + + $iterator = new LimitIterator($this->getIterator(), $keys, 1); + $iterator->rewind(); + + return $iterator->current(); + } + + /** + * Validate the array to be used by the fetchAssoc method + * + * @param array $keys + * + * @return boolean + */ + protected function isValidAssocKeys(array $keys) + { + $validKeys = array_unique(array_filter($keys, function ($value) { + return self::isValidString($value); + })); - return $this->header; + return count($keys) && $keys === $validKeys; } /** diff --git a/test/ReaderTest.php b/test/ReaderTest.php index 47e38fb..05e4824 100644 --- a/test/ReaderTest.php +++ b/test/ReaderTest.php @@ -287,12 +287,44 @@ EOF; $this->assertInstanceOf('\League\Csv\Writer', $csv); } - public function testFetchAssocWithoutKeys() + public function testFetchAssocWithARowIndex() { - $csv = Reader::createFromPath(__DIR__.'/data/prenoms.csv'); - $csv->setDelimiter(';'); - $csv->setEncodingFrom("iso-8859-15"); - $data = $csv->fetchAssoc(); - $this->assertTrue($data[0]['prenoms'] == 'Aaron'); + $arr = [ + ['A', 'B', 'C'], + [1, 2, 3], + ['D', 'E', 'F'], + [6, 7, 8], + ]; + + $tmpFile = new SplTempFileObject(); + foreach ($arr as $row) { + $tmpFile->fputcsv($row); + } + + $csv = Reader::createFromFileObject($tmpFile); + $res = $csv->setOffSet(2)->fetchAssoc(2); + $this->assertSame([['D' => '6', 'E' => '7', 'F' => '8']], $res); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage the column index must be a positive integer or 0 + */ + public function testFetchAssocWithInvalidKey() + { + $arr = [ + ['A', 'B', 'C'], + [1, 2, 3], + ['D', 'E', 'F'], + [6, 7, 8], + ]; + + $tmpFile = new SplTempFileObject(); + foreach ($arr as $row) { + $tmpFile->fputcsv($row); + } + + $csv = Reader::createFromFileObject($tmpFile); + $res = $csv->fetchAssoc(-23); } } |