Code

< 40 %
40-60 %
> 60 %
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
}