-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathUnZip.php
More file actions
146 lines (132 loc) · 3.08 KB
/
UnZip.php
File metadata and controls
146 lines (132 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
/**
* UnZip
*
* @author Ryuji AMANO <ryuji@ryus.co.jp>
* @link http://www.netcommons.org NetCommons Project
* @license http://www.netcommons.org/license.txt NetCommons License
*/
App::uses('TemporaryFolder', 'Files.Utility');
/**
* UnZip
*
* @author Ryuji AMANO <ryuji@ryus.co.jp>
* @link http://www.netcommons.org NetCommons Project
* @license http://www.netcommons.org/license.txt NetCommons License
*/
class UnZip {
/**
* @var string|null password
*/
protected $_password = null;
/**
* @var string zip file path
*/
protected $_zipPath;
/**
* @var string 解凍先フォルダパス
*/
public $path;
/**
* UnZip constructor.
*
* @param string $zipFilePath 解凍するZIPファイルパス
*/
public function __construct($zipFilePath) {
$this->_zipPath = $zipFilePath;
}
/**
* set password
*
* @param string $password ZIPの解凍に使うパスワード
*
* @return void
*/
public function setPassword($password) {
$this->_password = $password;
}
/**
* 解凍実行
*
* @return false|TemporaryFolder
*/
public function extract() {
$tmpFolder = new TemporaryFolder();
$result = $this->_extractTo($tmpFolder->path);
if ($result) {
$this->path = $tmpFolder->path;
return $tmpFolder;
} else {
return false;
}
}
/**
* 解凍
*
* @param string $path 解凍先
* @codeCoverageIgnore
* @return bool
*/
protected function _extractTo($path) {
if (version_compare(PHP_VERSION, '5.6.0', '<') && $this->_password) {
return $this->_extractWithZipCommand($path);
} else {
return $this->_extractWithZipArchiveClass($path);
}
}
/**
* ZIPコマンドを使った解凍
*
* @param string $path zipファイルパス
* @return bool
*/
protected function _extractWithZipCommand($path) {
// コマンドで解凍
$cmd = sprintf('unzip -P %s %s -d %s', ($this->_password), $this->_zipPath, $path);
exec($cmd, $output, $returnVar);
if ($returnVar > 0) {
// エラー
CakeLog::warning(
'Unzip Error:output=' . json_encode($output) . ', return_var=' . $returnVar
);
return false;
}
return true;
}
/**
* ZipArchiveクラスを利用した解凍
*
* @param string $path Zipファイルパス
* @return bool
*/
protected function _extractWithZipArchiveClass($path) {
$encodeCharset = "UTF-8"; // server os のファイルシステム文字コード
mb_language('Japanese');
setlocale(LC_ALL, 'ja_JP.UTF-8'); // スレッドセーフじゃないので直前で
$zip = new ZipArchive();
$result = $zip->open($this->_zipPath);
if ($result !== true) {
return false;
}
if ($this->_password) {
$zip->setPassword($this->_password);
}
$index = 0;
while ($zipEntry = $zip->statIndex($index)) {
$zipEntryName = $zipEntry['name'];
$destName = mb_convert_encoding($zipEntry['name'], $encodeCharset, 'auto');
if ($zip->renameName($zipEntryName, $destName) === false) {
return false;
}
if ($zip->extractTo($path, $destName) === false) {
return false;
}
if ($zip->renameName($destName, $zipEntryName) === false) {
return false;
}
$index++;
}
$zip->close();
return true;
}
}