diff --git a/src/Csv.php b/src/Csv.php index 74381e4..bed8292 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -540,6 +540,41 @@ class Csv { return $this->delimiter; } + /** + * Get total number of rows in csv without parsing whole data. + * + * @return bool|int + */ + public function getTotalRowCount(){ + if (empty($this->file_data)){ + return false; + } + + $this->_detect_and_remove_sep_row_from_data($this->file_data); + + $pattern = sprintf('/("[^%s]*")|[^%s]*/i',$this->enclosure, $this->enclosure); + preg_match_all($pattern,$this->file_data, $matches); + + foreach ($matches[0] as $match){ + if (empty($match) || !preg_match("/{$this->enclosure}/", $match)){ + continue; + } + + $replace = str_replace(["\r", "\n"], '', $match); + $this->file_data = str_replace($match, $replace, $this->file_data); + } + + $headingRow = $this->heading ? 1 : 0; + + $count = substr_count($this->file_data, "\r") + + substr_count($this->file_data, "\n") + - substr_count($this->file_data, "\r\n") + - $headingRow; + + + return $count; + } + // ============================================== // ----- [ Core Functions ] --------------------- // ============================================== diff --git a/tests/methods/ParseTest.php b/tests/methods/ParseTest.php index 9566499..c81876a 100644 --- a/tests/methods/ParseTest.php +++ b/tests/methods/ParseTest.php @@ -198,4 +198,41 @@ class ParseTest extends TestCase $this->assertArrayHasKey('column1', $csv->data[0], 'Data parsed incorrectly with enclosure ' . $enclosure); $this->assertEquals('value1', $csv->data[0]['column1'], 'Data parsed incorrectly with enclosure ' . $enclosure); } + + public function countRowsProvider(){ + return [ + 'auto-double-enclosure' => [ + 'auto-double-enclosure.csv', + 2 + ], + 'auto-single-enclosure' => [ + 'auto-single-enclosure.csv', + 2 + ], + 'UTF-8_sep_row' => [ + 'datatype.csv', + 3 + ] + ]; + } + + /** + * @dataProvider countRowsProvider + * + * @param string $file + * @param int $expectedRows + */ + public function testGetTotalRowCountFromFile($file, $expectedRows){ + $this->csv->heading = true; + $this->csv->load_data(__DIR__ . '/fixtures/' . $file); + $this->assertEquals($expectedRows, $this->csv->getTotalRowCount()); + } + + public function testGetTotalRowCountMissingEndingLineBreak(){ + $this->csv->heading = false; + $this->csv->enclosure = '"'; + $sInput = "86545235689,a\r\n34365587654,b\r\n13469874576,\"c\r\nd\""; + $this->csv->load_data($sInput); + $this->assertEquals(3, $this->csv->getTotalRowCount()); + } }