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 | 11 | public function convert() { |
|
28 | 11 | $file = $this->file; |
|
29 | 11 | 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 | 7 | $isUnlinkFile = false; |
|
36 | } |
||
37 | |||
38 | 11 | 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 | 11 | 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 | 11 | $cache = $this->getCache(); |
|
62 | 11 | 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 | 11 | \PhpOffice\PhpSpreadsheet\Shared\StringHelper::setDecimalSeparator('.'); |
|
73 | 11 | \PhpOffice\PhpSpreadsheet\Shared\StringHelper::setThousandsSeparator(''); |
|
74 | try { |
||
75 | 11 | $reader = IOFactory::createReaderForFile($file); |
|
76 | 1 | } catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) { |
|
77 | 1 | $ext = pathinfo($file, PATHINFO_EXTENSION); |
|
78 | 1 | if ($ext === 'txt') { |
|
79 | 1 | $reader = IOFactory::createReader('Csv'); |
|
80 | } else if ($ext === 'xls') { |
||
81 | $reader = IOFactory::createReader('Xls'); |
||
82 | } else { |
||
83 | throw $e; |
||
84 | } |
||
85 | } |
||
86 | |||
87 | 11 | if (($reader instanceof Csv) || ($reader instanceof Html)) { |
|
88 | 10 | $result = []; |
|
89 | 10 | $content = str_replace(["\r\n", "\n\r", "\r"], "\n", file_get_contents($file)); |
|
90 | 10 | $content = explode("\n", $content); |
|
91 | 10 | $delimiter = $this->delimiter; |
|
92 | 10 | foreach ($content as $value) { |
|
93 | 10 | $value = $this->convertEncoding($value); |
|
94 | 10 | if ($this->delimiter) { |
|
95 | 10 | if (strlen($this->delimiter) == 2) { |
|
96 | 1 | $delimiter = '~'; |
|
97 | 1 | $value = str_replace($this->delimiter, $delimiter, $value); |
|
98 | } |
||
99 | } |
||
100 | |||
101 | 10 | $parts = str_getcsv($value, $delimiter, $this->enclosure); |
|
102 | 10 | $result[] = $parts; |
|
103 | } |
||
104 | } else { |
||
105 | // $cacheMethod = \PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp; |
||
106 | // $cacheSettings = array( 'memoryCacheSize' => '500MB'); |
||
107 | // \PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); |
||
108 | // $reader->setReadDataOnly(true); |
||
109 | 1 | $oldReporting = error_reporting(); |
|
110 | 1 | error_reporting(E_ALL & ~E_NOTICE); |
|
111 | try { |
||
112 | 1 | $table = $reader->load($file); |
|
113 | } catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) { |
||
114 | $reader = \PHPExcel_IOFactory::createReaderForFile($file); |
||
115 | $table = $reader->load($file); |
||
116 | } |
||
117 | |||
118 | 1 | error_reporting($oldReporting); |
|
119 | |||
120 | 1 | $result = []; |
|
121 | 1 | $sheets = $table->getAllSheets(); |
|
122 | 1 | foreach ($sheets as $sheet) { |
|
123 | 1 | $result = array_merge($result, $sheet->toArray(null, false)); |
|
124 | } |
||
125 | |||
126 | 1 | if ($this->encoding !== null) { |
|
127 | 1 | foreach ($result as &$row) { |
|
128 | 1 | foreach ($row as $key => $value) { |
|
129 | 1 | $value = $this->convertEncoding($value); |
|
130 | |||
131 | 1 | $row[$key] = $value; |
|
132 | } |
||
133 | } |
||
134 | } |
||
135 | } |
||
136 | |||
137 | 11 | if ($this->trim !== null) { |
|
138 | 1 | foreach ($result as &$row) { |
|
139 | 1 | foreach ($row as $key => $value) { |
|
140 | 1 | $value = trim($value, $this->trim); |
|
141 | |||
142 | 1 | $row[$key] = $value; |
|
143 | } |
||
144 | } |
||
145 | } |
||
146 | |||
147 | |||
148 | 11 | if ($isUnlinkFile) { |
|
149 | 4 | unlink($file); |
|
150 | } |
||
151 | |||
152 | 11 | $cache = $this->getCache(); |
|
153 | 11 | if ($cache) { |
|
154 | $cache->set($cacheKey, $result, 3600); |
||
155 | } |
||
156 | |||
157 | 11 | return $result; |
|
158 | } |
||
159 | |||
160 | 11 | public function getCache() { |
|
161 | 11 | return false; |
|
162 | if ($this->cache !== null) { |
||
163 | return $this->cache; |
||
164 | } |
||
165 | |||
166 | if (YII_ENV !== 'test') { |
||
167 | return $this->cache = \yii::$app->cache; |
||
168 | } |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * @param $value |
||
173 | * @return mixed|string |
||
174 | */ |
||
175 | 11 | protected function convertEncoding($value) |
|
176 | { |
||
177 | 11 | if ($this->encoding === 'ISO-8859-1') { |
|
178 | 1 | $value = \mb_convert_encoding(mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8'), 'UTF-8', 'cp1251'); |
|
179 | } else { |
||
180 | 10 | $value = \mb_convert_encoding($value, 'UTF-8', $this->encoding); |
|
181 | } |
||
182 | |||
183 | 11 | return $value; |
|
184 | } |
||
185 | } |