Completed
Push — master ( 53b99e...05e097 )
by Basil
03:48
created

ImportHelper::csv()   B

Complexity

Conditions 10
Paths 16

Size

Total Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 45
rs 7.3333
c 0
b 0
f 0
cc 10
nc 16
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace luya\helpers;
4
5
use Yii;
6
7
/**
8
 * Import from Formats to Array.
9
 *
10
 * @author Basil Suter <[email protected]>
11
 * @since 1.0.0
12
 */
13
class ImportHelper
14
{
15
    /**
16
     * Import a CSV from a string or filename and return array.
17
     *
18
     * The filename can be either a resource from fopen() or a string containing the csv data. Filenames will be wrapped trough {{Yii::getAlias()}} method.
19
     *
20
     * @param string $filename Can be either a filename which is parsed by {{luya\helpers\FileHelper::getFileContent()}} or a string with the contained csv data.
21
     * @param array $options Provide options to the csv
22
     * + removeHeader: boolean, Whether the import csv contains a header in the first row to skip or not. Default value is false.
23
     * + delimiter: string, The delimiter which is used to explode the columns. Default value is `,`.
24
     * + enclosure: string, The encloser which is used betweend the columns. Default value is `"`.
25
     * + fields: array, An array with fielnames (based on the array header if any, or position) which should be parsed into the final export.
26
     * ```php
27
     * 'fields' => ['firstname', 'lastname'] // will only parse those fields based on table header (row 0)
28
     * 'fields' => [0,1,3] // will only parse fields by those positions if no table header is present. Positions starts at 0
29
     * ```
30
     * @return Returns an array with the csv data.
31
     */
32
    public static function csv($filename, array $options = [])
33
    {
34
        $filename = Yii::getAlias($filename);
35
        
36
        // check if a given file name is provided or a csv based on the content
37
        if (FileHelper::getFileInfo($filename)->extension) {
0 ignored issues
show
Bug introduced by
It seems like $filename defined by \Yii::getAlias($filename) on line 34 can also be of type boolean; however, luya\helpers\FileHelper::getFileInfo() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
38
            $resource = fopen($filename, 'r');
39
        } else {
40
            $resource = fopen('php://memory', 'rw');
41
            fwrite($resource, $filename);
42
            rewind($resource);
43
        }
44
        $data = [];
45
        while (($row = fgetcsv($resource, 0, ArrayHelper::getValue($options, 'delimiter', ','), ArrayHelper::getValue($options, 'enclosure', '"'))) !== false) {
46
            $data[] = $row;
47
        }
48
        fclose($resource);
49
        
50
        // check whether only an amount of fields should be parsed into the final array
51
        $fields = ArrayHelper::getValue($options, 'fields', false);
52
        if ($fields && is_array($fields)) {
53
            $filteredData = [];
54
            foreach ($fields as $fieldColumn) {
55
                if (!is_numeric($fieldColumn)) {
56
                    $fieldColumn = array_search($fieldColumn, $data[0]);
57
                }
58
                foreach ($data as $key => $rowValue) {
59
                    if (array_key_exists($fieldColumn, $rowValue)) {
60
                        $filteredData[$key][] = $rowValue[$fieldColumn];
61
                    }
62
                }
63
            }
64
65
            $data = $filteredData;
66
            unset($filteredData);
67
        }
68
        
69
        // if the option to remove a header is provide. remove the first key and reset and array keys
70
        if (ArrayHelper::getValue($options, 'removeHeader', false)) {
71
            unset($data[0]);
72
            $data = array_values($data);
73
        }
74
        
75
        return $data;
76
    }
77
}
78