Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ImportHelper::csvFromResource() method to import CSV from a resou… #21

Merged
merged 3 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
+ [#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)

Expand Down
65 changes: 41 additions & 24 deletions src/helpers/ImportHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,17 @@
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.
* Import a CSV from a resource and return array.
*
* @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.
* @param resource $resource
* @param array $options See {{luya\yii\helpers\ExportHelper::csv()}} for all options.
* @return array
* @since 1.6.0
*/
public static function csv($filename, array $options = [])
public static function csvFromResource($resource, array $options = []): array
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function csvFromResource has a Cognitive Complexity of 17 (exceeds 5 allowed). Consider refactoring.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method csvFromResource has 29 lines of code (exceeds 25 allowed). Consider refactoring.

{
$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) {
Expand Down Expand Up @@ -74,4 +58,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);
}
}
14 changes: 14 additions & 0 deletions tests/helpers/ImportHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
Loading