ToArrayConverter   A
last analyzed

Complexity

Total Complexity 34

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Test Coverage

Coverage 82.95%

Importance

Changes 0
Metric Value
wmc 34
eloc 100
dl 0
loc 165
ccs 73
cts 88
cp 0.8295
rs 9.68
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A convertEncoding() 0 9 2
A getCache() 0 7 3
F convert() 0 129 29
1
<?php
2
/**
3
 * User: execut
4
 * Date: 19.07.16
5
 * Time: 11:55
6
 */
7
8
namespace execut\import\components;
9
10
11
use PhpOffice\PhpSpreadsheet\IOFactory;
12
use PhpOffice\PhpSpreadsheet\Reader\Csv;
13
use PhpOffice\PhpSpreadsheet\Reader\Html;
14
use yii\base\Component;
15
16
class ToArrayConverter extends Component
17
{
18
    public $file;
19
    public $fileExtension;
20
    public $cache = null;
21
    public $encoding = 'UTF-8';
22
    public $enclosure = '"';
23
    public $delimiter = ',';
24
    public $trim = null;
25
    public $limit = null;
26
    public $mimeType = null;
27 10
    public function convert() {
28 10
        $file = $this->file;
29 10
        if (!is_string($file)) {
30 4
            $isUnlinkFile = true;
31 4
            $fileContent = stream_get_contents($file);
32 4
            $file = tempnam('/tmp', 'test_');
33 4
            file_put_contents($file, $fileContent);
34
        } else {
35 6
            $isUnlinkFile = false;
36
        }
37
38 10
        if ($this->mimeType === 'application/x-rar' || ($this->mimeType === null && mime_content_type($file) === 'application/x-rar')) {
39 1
            exec('unrar lb "' . $file . '"', $out);
40 1
            $unpackedFile = tempnam('/tmp', 'test_') . $out[0];
41 1
            exec('unrar p -inul "' . $file . '" > "' . $unpackedFile . '"');
42 1
            if ($isUnlinkFile) {
43 1
                unlink($file);
44
            }
45
46 1
            $file = $unpackedFile;
47 1
            $isUnlinkFile = true;
48
        }
49
50 10
        if ($this->mimeType === 'application/zip' || ($this->mimeType === null && mime_content_type($file) === 'application/zip')) {
51 1
            $unpackedFile = '/tmp/' . exec('unzip -l "' . $file . '" | awk \'/-----/ {p = ++p % 2; next} p {print $NF}\'');
52 1
            exec('unzip -cqq "' . $file . '" > ' . $unpackedFile);
53 1
            if ($isUnlinkFile) {
54 1
                unlink($file);
55
            }
56
57 1
            $file = $unpackedFile;
58 1
            $isUnlinkFile = true;
59
        }
60
61 10
        $cache = $this->getCache();
62 10
        if ($cache) {
63
            $md5 = md5_file($file);
64
            $cacheKey = $md5 . $this->delimiter . '-' . $this->enclosure . '-' . $this->encoding . '-' . $this->trim;
65
            if ($result = $cache->get($cacheKey)) {
66
//                $result = array_splice($result, 0, 10);
67
                return $result;
68
            }
69
        }
70
71
//        \PHPExcel_Settings::setLocale('ru_RU');
72 10
        \PhpOffice\PhpSpreadsheet\Shared\StringHelper::setDecimalSeparator('.');
73 10
        \PhpOffice\PhpSpreadsheet\Shared\StringHelper::setThousandsSeparator('');
74
        try {
75 10
            $reader = IOFactory::createReaderForFile($file);
76
        } catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
77
            $ext = pathinfo($file, PATHINFO_EXTENSION);
78
            if ($ext === 'xls') {
79
                $reader = IOFactory::createReader('Xls');
80
            } else {
81
                throw $e;
82
            }
83
        }
84
85 10
        if (($reader instanceof Csv) || ($reader instanceof Html)) {
86 9
            $result = [];
87 9
            $content = str_replace(["\r\n", "\n\r", "\r"], "\n", file_get_contents($file));
88 9
            $content = explode("\n", $content);
89 9
            $delimiter = $this->delimiter;
90 9
            foreach ($content as $value) {
91 9
                $value = $this->convertEncoding($value);
92 9
                if ($this->delimiter) {
93 9
                    if (strlen($this->delimiter) == 2) {
94 1
                        $delimiter = '~';
95 1
                        $value = str_replace($this->delimiter, $delimiter, $value);
96
                    }
97
                }
98
99 9
                $parts = str_getcsv($value, $delimiter, $this->enclosure);
100 9
                $result[] = $parts;
101
            }
102
        } else {
103
//            $cacheMethod = \PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;
104
//            $cacheSettings = array( 'memoryCacheSize' => '500MB');
105
//            \PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
106
//            $reader->setReadDataOnly(true);
107 1
            $oldReporting = error_reporting();
108 1
            error_reporting(E_ALL & ~E_NOTICE);
109
            try {
110 1
                $table = $reader->load($file);
111
            } catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
112
                $reader = \PHPExcel_IOFactory::createReaderForFile($file);
0 ignored issues
show
Bug introduced by eXeCUT
The type PHPExcel_IOFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
113
                $table = $reader->load($file);
114
            }
115
116 1
            error_reporting($oldReporting);
117
118 1
            $result = [];
119 1
            $sheets = $table->getAllSheets();
120 1
            foreach ($sheets as $sheet) {
121 1
                $result = array_merge($result, $sheet->toArray(null, false));
122
            }
123
124 1
            if ($this->encoding !== null) {
125 1
                foreach ($result as &$row) {
126 1
                    foreach ($row as $key => $value) {
127 1
                        $value = $this->convertEncoding($value);
128
129 1
                        $row[$key] = $value;
130
                    }
131
                }
132
            }
133
        }
134
135 10
        if ($this->trim !== null) {
136 1
            foreach ($result as &$row) {
137 1
                foreach ($row as $key => $value) {
138 1
                    $value = trim($value, $this->trim);
139
140 1
                    $row[$key] = $value;
141
                }
142
            }
143
        }
144
145
146 10
        if ($isUnlinkFile) {
147 4
            unlink($file);
148
        }
149
150 10
        $cache = $this->getCache();
151 10
        if ($cache) {
152
            $cache->set($cacheKey, $result, 3600);
0 ignored issues
show
Comprehensibility Best Practice introduced by eXeCUT
The variable $cacheKey does not seem to be defined for all execution paths leading up to this point.
Loading history...
153
        }
154
155 10
        return $result;
156
    }
157
158 10
    public function getCache() {
159 10
        if ($this->cache !== null) {
160
            return $this->cache;
161
        }
162
163 10
        if (YII_ENV !== 'test') {
0 ignored issues
show
introduced by eXeCUT
The condition execut\import\components\YII_ENV !== 'test' is always false.
Loading history...
164
            return $this->cache = \yii::$app->cache;
165
        }
166 10
    }
167
168
    /**
169
     * @param $value
170
     * @return mixed|string
171
     */
172 10
    protected function convertEncoding($value)
173
    {
174 10
        if ($this->encoding === 'ISO-8859-1') {
175 1
            $value = \mb_convert_encoding(mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8'), 'UTF-8', 'cp1251');
176
        } else {
177 9
            $value = \mb_convert_encoding($value, 'UTF-8', $this->encoding);
178
        }
179
180 10
        return $value;
181
    }
182
}