summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Reader.php67
-rw-r--r--test/ReaderTest.php44
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);
}
}