Passed
Push — master ( 044967...aa7def )
by
unknown
17:39 queued 08:33
created

Import::xlsToArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use League\Csv\Reader;
6
7
/**
8
 * Class Import
9
 * This class provides some functions which can be used when importing data from
10
 * external files into Chamilo.
11
 */
12
class Import
13
{
14
    /**
15
     * @param string $path
16
     * @param bool   $setFirstRowAsHeader
17
     *
18
     * @return array
19
     */
20
    public static function csv_reader($path, $setFirstRowAsHeader = true)
21
    {
22
        return self::csvToArray($path);
23
    }
24
25
    /**
26
     * Guess the CSV delimiter by scanning the first non-empty line.
27
     */
28
    public static function detectCsvSeparator(string $filePath): ?string
29
    {
30
        if (!is_readable($filePath)) {
31
            return null;
32
        }
33
        $h = @fopen($filePath, 'rb');
34
        if (!$h) {
0 ignored issues
show
introduced by
$h is of type false|resource, thus it always evaluated to false.
Loading history...
35
            return null;
36
        }
37
        $line = '';
38
        for ($i = 0; $i < 5 && !feof($h); $i++) {
39
            $line = fgets($h, 1024 * 1024);
40
            if ($line !== false && trim($line) !== '') {
41
                break;
42
            }
43
        }
44
        fclose($h);
45
        if ($line === false || $line === '') {
46
            return null;
47
        }
48
49
        $cands = [',', ';', "\t", '|'];
50
        $scores = array_fill_keys($cands, 0);
51
        $inQuotes = false;
52
        $len = strlen($line);
53
        for ($i = 0; $i < $len; $i++) {
54
            $ch = $line[$i];
55
            if ($ch === '"') {
56
                $prev = $i > 0 ? $line[$i - 1] : null;
57
                if ($prev !== '\\') {
58
                    $inQuotes = !$inQuotes;
59
                }
60
            } elseif (!$inQuotes && isset($scores[$ch])) {
61
                $scores[$ch]++;
62
            }
63
        }
64
        arsort($scores);
65
        $top = array_key_first($scores);
66
        return ($scores[$top] > 0) ? $top : null;
67
    }
68
69
    /**
70
     * Check if the CSV appears to be comma-separated.
71
     */
72
    public static function assertCommaSeparated(string $filePath): bool
73
    {
74
        $det = self::detectCsvSeparator($filePath);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $det is correct as self::detectCsvSeparator($filePath) targeting Import::detectCsvSeparator() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
75
76
        if ($det === null) {
77
            return true;
78
        }
79
80
        return $det === ',';
81
    }
82
83
    /**
84
     * Reads a CSV-file into an array. The first line of the CSV-file should contain the array-keys.
85
     * The encoding of the input file is tried to be detected.
86
     * The elements of the returned array are encoded in the system encoding.
87
     * Example:
88
     *   FirstName;LastName;Email
89
     *   John;Doe;[email protected]
90
     *   Adam;Adams;[email protected]
91
     *  returns
92
     *   $result [0]['FirstName'] = 'John';
93
     *   $result [0]['LastName'] = 'Doe';
94
     *   $result [0]['Email'] = 'john.doe@mail. com';
95
     *   $result [1]['FirstName'] = 'Adam';
96
     *   ...
97
     *
98
     * @param string $filename the path to the CSV-file which should be imported
99
     *
100
     * @return array returns an array (in the system encoding) that contains all data from the CSV-file
101
     */
102
    public static function csvToArray($filename, $delimiter = ','): array
103
    {
104
        if (empty($filename)) {
105
            return [];
106
        }
107
108
        $reader = Reader::createFromPath($filename, 'r');
109
        if ($reader) {
110
            $reader->setDelimiter($delimiter);
111
            $reader->setHeaderOffset(0);
112
            $iterator = $reader->getRecords();
113
114
            return iterator_to_array($iterator);
115
        }
116
117
        return [];
118
    }
119
120
    /**
121
     * @param string $filename
122
     *
123
     * @return array
124
     */
125
    public static function xlsToArray($filename)
126
    {
127
        if (empty($filename)) {
128
            return [];
129
        }
130
131
        $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
132
        $spreadsheet = $reader->load($filename);
133
        $sheet = $spreadsheet->getActiveSheet();
134
135
        return $sheet->toArray();
136
    }
137
}
138