From 49728a74bb42d770d486063783edcd44eb620f65 Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 10:31:09 +0100 Subject: [PATCH 1/9] Only reformatted the source code --- src/Csv.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Csv.php b/src/Csv.php index f0daee0..316b755 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -811,7 +811,7 @@ class Csv { // create data foreach ($data as $key => $row) { - foreach (array_keys($fieldOrder) as $index){ + foreach (array_keys($fieldOrder) as $index) { $cell_value = $row[$index]; $entry[] = $this->_enclose_value($cell_value, $delimiter); } @@ -827,19 +827,19 @@ class Csv { return $string; } - private function _validate_fields_for_unparse($fields){ + private function _validate_fields_for_unparse($fields) { // this is needed because sometime titles property is overwritten instead of using fields parameter! $titlesOnParse = !empty($this->data) ? array_keys($this->data[0]) : array(); - if (empty($fields)){ + if (empty($fields)) { $fields = $this->titles; } - if (empty($fields)){ + if (empty($fields)) { return array(); } // both are identical, also in ordering - if (array_values($fields) === array_values($titlesOnParse)){ + if (array_values($fields) === array_values($titlesOnParse)) { return array_combine($fields, $fields); } From 7498a963aca17a1471993318f35d654ae0c3b121 Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 10:31:25 +0100 Subject: [PATCH 2/9] _validate_fields_for_unparse: more info in UnexpectedValueException --- src/Csv.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Csv.php b/src/Csv.php index 316b755..a6a76e7 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -857,7 +857,10 @@ class Csv { // original titles are not given in fields. that is okay if count is okay. if (count($fields) != count($titlesOnParse)) { - throw new \UnexpectedValueException('The specified fields do not match any titles and do not match column count.'); + throw new \UnexpectedValueException( + "The specified fields do not match any titles and do not match column count.\n" . + "\$fields was " . print_r($fields, true) . + "\$titlesOnParse was " . print_r($titlesOnParse, true)); } return array_combine($titlesOnParse, $fields); From ffed7ffdc0c66ab5c9f85a981e0b0c56ee679f33 Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 11:40:31 +0100 Subject: [PATCH 3/9] Only improved PHPDoc blocks, including sentance for output() --- src/Csv.php | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/Csv.php b/src/Csv.php index a6a76e7..af727e8 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -298,14 +298,15 @@ class Csv { * Class constructor * * @param string|null $input The CSV string or a direct filepath - * @param integer|null $offset Number of rows to ignore from the beginning - * of the data - * @param integer|null $limit Limits the number of returned rows to - * specified amount + * @param integer|null $offset Number of rows to ignore from the + * beginning of the data + * @param integer|null $limit Limits the number of returned rows + * to specified amount * @param string|null $conditions Basic SQL-like conditions for row * matching * @param null|true $keep_file_data Keep raw file data in memory after - * successful parsing (useful for debugging) + * successful parsing + * (useful for debugging) */ public function __construct($input = null, $offset = null, $limit = null, $conditions = null, $keep_file_data = null) { $this->init($offset, $limit, $conditions, $keep_file_data); @@ -316,14 +317,15 @@ class Csv { } /** - * @param integer|null $offset Number of rows to ignore from the beginning - * of the data - * @param integer|null $limit Limits the number of returned rows to - * specified amount + * @param integer|null $offset Number of rows to ignore from the + * beginning of the data + * @param integer|null $limit Limits the number of returned rows + * to specified amount * @param string|null $conditions Basic SQL-like conditions for row * matching * @param null|true $keep_file_data Keep raw file data in memory after - * successful parsing (useful for debugging) + * successful parsing + * (useful for debugging) */ public function init($offset = null, $limit = null, $conditions = null, $keep_file_data = null) { if (!is_null($offset)) { @@ -352,9 +354,12 @@ class Csv { * Parse a CSV file or string * * @param string|null $input The CSV string or a direct filepath - * @param integer $offset Number of rows to ignore from the beginning of the data - * @param integer $limit Limits the number of returned rows to specified amount - * @param string $conditions Basic SQL-like conditions for row matching + * @param integer $offset Number of rows to ignore from the + * beginning of the data + * @param integer $limit Limits the number of returned rows to + * specified amount + * @param string $conditions Basic SQL-like conditions for row + * matching * * @return bool True on success */ @@ -394,8 +399,10 @@ class Csv { * * @param string $file File location to save to * @param array $data 2D array of data - * @param bool $append Append current data to end of target CSV, if file exists - * @param array $fields Field names. Sets the header. If it is not set $this->titles would be used instead. + * @param bool $append Append current data to end of target CSV, if file + * exists + * @param array $fields Field names. Sets the header. If it is not set + * $this->titles would be used instead. * * @return bool */ @@ -417,7 +424,10 @@ class Csv { * @param string|null $filename If a filename is specified here or in the * object, headers and data will be output * directly to browser as a downloadable - * file. + * file. This file doesn't have to exist on + * the server; the parameter only affects + * how the download is called to the + * browser. * @param array[] $data 2D array with data * @param array $fields Field names * @param string|null $delimiter character used to separate data @@ -525,8 +535,8 @@ class Csv { } /** - * Get total number of data rows (exclusive heading line if present) in csv - * without parsing whole data. + * Get total number of data rows (exclusive heading line if present) in CSV + * without parsing the whole data string. * * @return bool|int */ From 10895788c856a6161e0d946ed6606b58e7ff77c4 Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 11:54:04 +0100 Subject: [PATCH 4/9] Slightly simplified getTotalDataRowCount, added test The brackets () in the pattern were not needed, as only $matches[0] was accessed, not $matches[1]. The @var is useful for PhpStorm's Php Inspections (EA Extended). More details here: https://github.com/kalessil/phpinspectionsea/blob/master/docs/types-compatibility.md#foreach-source-to-iterate-over --- src/Csv.php | 3 ++- tests/methods/DataRowCountTest.php | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Csv.php b/src/Csv.php index af727e8..094e353 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -549,9 +549,10 @@ class Csv { $this->_detect_and_remove_sep_row_from_data($data); - $pattern = sprintf('/(%1$s[^%1$s]*%1$s)/i', $this->enclosure); + $pattern = sprintf('/%1$s[^%1$s]*%1$s/i', $this->enclosure); preg_match_all($pattern, $data, $matches); + /** @var array[] $matches */ foreach ($matches[0] as $match) { if (empty($match) || (strpos($match, $this->enclosure) === false)) { continue; diff --git a/tests/methods/DataRowCountTest.php b/tests/methods/DataRowCountTest.php index 693d736..a256fde 100644 --- a/tests/methods/DataRowCountTest.php +++ b/tests/methods/DataRowCountTest.php @@ -64,7 +64,6 @@ class DataRowCountTest extends TestCase { $this->assertEquals(3, $this->csv->getTotalDataRowCount()); } - public function testGetTotalRowCountSingleEnclosure() { $this->csv->heading = false; $this->csv->enclosure = "'"; @@ -73,4 +72,11 @@ class DataRowCountTest extends TestCase { $this->assertEquals(3, $this->csv->getTotalDataRowCount()); } + public function testGetTotalRowCountSingleRow() { + $this->csv->heading = false; + $this->csv->enclosure = "'"; + $sInput = "86545235689"; + $this->csv->load_data($sInput); + $this->assertEquals(1, $this->csv->getTotalDataRowCount()); + } } From c8d15557cb18104f701303a52fbec5f89e3925ae Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 12:01:45 +0100 Subject: [PATCH 5/9] Fixed parse()'s return value: return true only if $data is useful --- src/Csv.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Csv.php b/src/Csv.php index 094e353..deeba47 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -369,13 +369,11 @@ class Csv { } if (empty($input)) { - // todo: but why true? - return true; + return false; } $this->init($offset, $limit, $conditions); - if (strlen($input) <= PHP_MAXPATHLEN && is_readable($input)) { $this->file = $input; $this->data = $this->parse_file(); @@ -385,12 +383,7 @@ class Csv { $this->data = $this->parse_string(); } - if ($this->data === false) { - return false; - } - - return true; - + return $this->data !== false; } /** From 4b60d38fb0a7fc6d9c639df1694407343488b357 Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 12:03:38 +0100 Subject: [PATCH 6/9] Tell PhpStorm not to complain about reference mismatch http://blog.jpauli.tech/2014/06/27/references-mismatch.html#what-is-a-reference-mismatch --- src/Csv.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Csv.php b/src/Csv.php index deeba47..a8557af 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -797,6 +797,7 @@ class Csv { $entry = array(); // create heading + /** @noinspection ReferenceMismatchInspection */ $fieldOrder = $this->_validate_fields_for_unparse($fields); if (!$fieldOrder && !empty($data)) { $column_count = count($data[0]); From 07846d33c1cf80e2357df98c23da4be7e6cdc571 Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 12:05:41 +0100 Subject: [PATCH 7/9] Added OutputTest to verify issue #132 is a bug. --- tests/methods/OutputTest.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/methods/OutputTest.php diff --git a/tests/methods/OutputTest.php b/tests/methods/OutputTest.php new file mode 100644 index 0000000..f323411 --- /dev/null +++ b/tests/methods/OutputTest.php @@ -0,0 +1,21 @@ + ['a', 'b', 'c'], 1 => ['d', 'e', 'f']]; + $fields = ['col1', 'col2', 'col3']; + $output = $csv->output('test.csv', $data, $fields, ','); + $expected = "col1,col2,col3\ra,b,c\rd,e,f\r"; + self::assertEquals($expected, $output); + } +} From f5ff7332a42a36474e775a97f18afe1ff2c47523 Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 12:14:04 +0100 Subject: [PATCH 8/9] Set $data field on unparse. This fixes issue #132. --- src/Csv.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Csv.php b/src/Csv.php index a8557af..5c691e7 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -783,6 +783,9 @@ class Csv { public function unparse($data = array(), $fields = array(), $append = FileProcessingModeEnum::MODE_FILE_OVERWRITE, $is_php = false, $delimiter = null) { if (!is_array($data) || empty($data)) { $data = &$this->data; + } else { + /** @noinspection ReferenceMismatchInspection */ + $this->data = $data; } if (!is_array($fields) || empty($fields)) { @@ -833,8 +836,6 @@ class Csv { } private function _validate_fields_for_unparse($fields) { - // this is needed because sometime titles property is overwritten instead of using fields parameter! - $titlesOnParse = !empty($this->data) ? array_keys($this->data[0]) : array(); if (empty($fields)) { $fields = $this->titles; } @@ -843,6 +844,9 @@ class Csv { return array(); } + // this is needed because sometime titles property is overwritten instead of using fields parameter! + $titlesOnParse = !empty($this->data) ? array_keys($this->data[0]) : array(); + // both are identical, also in ordering if (array_values($fields) === array_values($titlesOnParse)) { return array_combine($fields, $fields); From 93f177a3967bcf93286c032b3d28002855252f34 Mon Sep 17 00:00:00 2001 From: Fonata Date: Sat, 17 Mar 2018 12:17:25 +0100 Subject: [PATCH 9/9] Merged two ifs in _validate_row_condition to prevent This is to a sane count of zero PhpStorm inspections. In particular, this is NestedPositiveIfStatementsInspection from EA Extended. --- src/Csv.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Csv.php b/src/Csv.php index 5c691e7..6a97509 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -1017,16 +1017,14 @@ class Csv { $op = $capture[2]; $value = $capture[3]; - if (preg_match('/^([\'\"]{1})(.*)([\'\"]{1})$/', $value, $capture)) { - if ($capture[1] == $capture[3]) { - $value = strtr($capture[2], array( - "\\n" => "\n", - "\\r" => "\r", - "\\t" => "\t", - )); + if (preg_match('/^([\'\"]{1})(.*)([\'\"]{1})$/', $value, $capture) && $capture[1] == $capture[3]) { + $value = strtr($capture[2], array( + "\\n" => "\n", + "\\r" => "\r", + "\\t" => "\t", + )); - $value = stripslashes($value); - } + $value = stripslashes($value); } if (array_key_exists($field, $row)) {