From 1d6f013b295959abb9236105236165f179ebcb39 Mon Sep 17 00:00:00 2001 From: Nadar Date: Wed, 14 Feb 2024 14:13:59 +0000 Subject: [PATCH 1/3] Add ImportHelper::csvFromResource() method to import CSV from a resource object --- CHANGELOG.md | 3 +- src/helpers/ImportHelper.php | 63 +++++++++++++++++------------- tests/helpers/ImportHelperTest.php | 14 +++++++ 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c32b22c..75db313 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). -## 1.5.1 +## 1.6.0 (14. February 2024) + [#19](https://github.com/luyadev/yii-helpers/pull/19) Fixed issue with ordinal numbers. ++ []() Added `ImportHelper::csvFromResource()` method to import CSV from a resource object like `fopen()`. ## 1.5.0 (26. October 2023) diff --git a/src/helpers/ImportHelper.php b/src/helpers/ImportHelper.php index 86581fe..e298193 100644 --- a/src/helpers/ImportHelper.php +++ b/src/helpers/ImportHelper.php @@ -12,34 +12,10 @@ */ class ImportHelper { - /** - * Import a CSV from a string or filename and return array. - * - * The filename can be either a resource from `fopen()` or a string containing the CSV data. Filenames will be wrapped through {{`Yii::getAlias()`}} method. - * - * @param string $filename Can be either a filename which is parsed by {{luya\yii\helpers\FileHelper::getFileContent()}} or a string with the contained CSV data. - * @param array $options Provide options to the CSV - * + `removeHeader`: boolean, Whether the import CSV contains a header in the first row to skip or not. Default value is false. - * + `delimiter`: string, The delimiter which is used to explode the columns. Default value is `,`. - * + `enclosure`: string, The enclosure which is used between the columns. Default value is `"`. - * + `fields`: array, An array with filenames (based on the array header if any, or position) which should be parsed into the final export. - * ```php - * 'fields' => ['firstname', 'lastname'] // will only parse those fields based on table header (row 0) - * 'fields' => [0,1,3] // will only parse fields by those positions if no table header is present. Positions starts at 0. - * ``` - * @return array an array with the CSV data. - */ - public static function csv($filename, array $options = []) + public static function csvFromResource($resource, array $options = []) : array { - $filename = Yii::getAlias($filename); - - // check if a given file name is provided or a CSV based on the content - if (FileHelper::getFileInfo($filename)->extension) { - $resource = fopen($filename, 'r'); - } else { - $resource = fopen('php://memory', 'rw'); - fwrite($resource, $filename); - rewind($resource); + if (!is_resource($resource)) { + throw new \InvalidArgumentException("The provided resource is not a valid resource."); } $data = []; while (($row = fgetcsv($resource, 0, ArrayHelper::getValue($options, 'delimiter', ','), ArrayHelper::getValue($options, 'enclosure', '"'))) !== false) { @@ -74,4 +50,37 @@ public static function csv($filename, array $options = []) return $data; } + + /** + * Import a CSV from a string or filename and return array. + * + * The filename can be either a resource from `fopen()` or a string containing the CSV data. Filenames will be wrapped through {{`Yii::getAlias()`}} method. + * + * @param string $filename Can be either a filename which is parsed by {{luya\yii\helpers\FileHelper::getFileContent()}} or a string with the contained CSV data. + * @param array $options Provide options to the CSV + * + `removeHeader`: boolean, Whether the import CSV contains a header in the first row to skip or not. Default value is false. + * + `delimiter`: string, The delimiter which is used to explode the columns. Default value is `,`. + * + `enclosure`: string, The enclosure which is used between the columns. Default value is `"`. + * + `fields`: array, An array with filenames (based on the array header if any, or position) which should be parsed into the final export. + * ```php + * 'fields' => ['firstname', 'lastname'] // will only parse those fields based on table header (row 0) + * 'fields' => [0,1,3] // will only parse fields by those positions if no table header is present. Positions starts at 0. + * ``` + * @return array an array with the CSV data. + */ + public static function csv($filename, array $options = []) + { + $filename = Yii::getAlias($filename); + + // check if a given file name is provided or a CSV based on the content + if (FileHelper::getFileInfo($filename)->extension) { + $resource = fopen($filename, 'r'); + } else { + $resource = fopen('php://memory', 'rw'); + fwrite($resource, $filename); + rewind($resource); + } + + return self::csvFromResource($resource, $options); + } } diff --git a/tests/helpers/ImportHelperTest.php b/tests/helpers/ImportHelperTest.php index f983c2f..5ea02de 100644 --- a/tests/helpers/ImportHelperTest.php +++ b/tests/helpers/ImportHelperTest.php @@ -2,6 +2,7 @@ namespace luya\yii\tests\helpers; +use luya\console\Importer; use luya\yii\helpers\ExportHelper; use luya\yii\helpers\ImportHelper; use luya\yii\tests\HelpersTestCase; @@ -50,4 +51,17 @@ public function testCsvWithNewline() 2 => ['Jane', 'World\nHello'], ], ImportHelper::csv($csv)); } + + public function testResourceImport() + { + $resource = fopen('php://memory', 'rw'); + fwrite($resource, 'foobarcontent'); + rewind($resource); + + $result = ImportHelper::csvFromResource($resource); + + $this->assertSame([ + 0 => ['foobarcontent'], + ], $result); + } } From e415782635f79d3ab97d089a93a603778d9bbacd Mon Sep 17 00:00:00 2001 From: nadar Date: Wed, 14 Feb 2024 14:14:24 +0000 Subject: [PATCH 2/3] Apply php-cs-fixer changes --- src/helpers/ImportHelper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/ImportHelper.php b/src/helpers/ImportHelper.php index e298193..a262731 100644 --- a/src/helpers/ImportHelper.php +++ b/src/helpers/ImportHelper.php @@ -12,7 +12,7 @@ */ class ImportHelper { - public static function csvFromResource($resource, array $options = []) : array + public static function csvFromResource($resource, array $options = []): array { if (!is_resource($resource)) { throw new \InvalidArgumentException("The provided resource is not a valid resource."); @@ -80,7 +80,7 @@ public static function csv($filename, array $options = []) fwrite($resource, $filename); rewind($resource); } - + return self::csvFromResource($resource, $options); } } From 3bc941e45426822a2b827c17b82bf3f7f41fb6e3 Mon Sep 17 00:00:00 2001 From: Nadar Date: Wed, 14 Feb 2024 14:19:00 +0000 Subject: [PATCH 3/3] Add ImportHelper::csvFromResource() method to ImportHelper class --- CHANGELOG.md | 2 +- src/helpers/ImportHelper.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75db313..24c903f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. This projec ## 1.6.0 (14. February 2024) + [#19](https://github.com/luyadev/yii-helpers/pull/19) Fixed issue with ordinal numbers. -+ []() Added `ImportHelper::csvFromResource()` method to import CSV from a resource object like `fopen()`. ++ [#21](https://github.com/luyadev/yii-helpers/pull/21) Added `ImportHelper::csvFromResource()` method to import CSV from a resource object like `fopen()`. ## 1.5.0 (26. October 2023) diff --git a/src/helpers/ImportHelper.php b/src/helpers/ImportHelper.php index a262731..4c0d4ea 100644 --- a/src/helpers/ImportHelper.php +++ b/src/helpers/ImportHelper.php @@ -12,6 +12,14 @@ */ class ImportHelper { + /** + * Import a CSV from a resource and return array. + * + * @param resource $resource + * @param array $options See {{luya\yii\helpers\ExportHelper::csv()}} for all options. + * @return array + * @since 1.6.0 + */ public static function csvFromResource($resource, array $options = []): array { if (!is_resource($resource)) {