/
AdminUpdateController.class.php
241 lines (206 loc) · 8.36 KB
/
AdminUpdateController.class.php
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
<?php
namespace Api\Controller;
use Think\Controller;
class AdminUpdateController extends BaseController {
//检测showdoc版本更新
public function checkUpdate(){
//获取当前版本
$text = file_get_contents("../composer.json");
$composer = json_decode($text, true);
$version = $composer['version'] ;
$url = "https://www.showdoc.cc/server/api/open/checkUpdate";
$ch = curl_init();
$timeout = 2;
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, "version={$version}" );
curl_setopt($ch,CURLOPT_URL,$url);
$sContent = curl_exec($ch);
curl_close($ch);
echo $sContent ;
}
// 下载更新代码包
public function download(){
$this->checkLogin();
$this->checkAdmin();
set_time_limit(1000);
ini_set('memory_limit','500M');
//获取当前版本
$text = file_get_contents("../composer.json");
$composer = json_decode($text, true);
$version = $composer['version'] ;
$url = "https://www.showdoc.cc/server/api/open/checkUpdate";
$res = http_post($url , array("version"=>$version));
$res_array = json_decode($res,true);
$new_version =$res_array['data']['new_version'] ;
$file_url =$res_array['data']['file_url'] ;
if(!$file_url){
$this->sendError(10101,'检测更新时异常');
return ;
}
$version_num = str_replace("v","",$new_version) ;
$showdoc_path = "../" ;
// 进行文件读写权限检查
if(!$this->new_is_writeable($showdoc_path)
|| !$this->new_is_writeable($showdoc_path."Sqlite/" )
|| !$this->new_is_writeable($showdoc_path."web/" )
|| !$this->new_is_writeable($showdoc_path."web/index.php" )
|| !$this->new_is_writeable($showdoc_path."server/" )
|| !$this->new_is_writeable($showdoc_path."server/vendor/autoload.php" )
|| !$this->new_is_writeable($showdoc_path."server/Application/Api" )
){
$this->sendError(10101,'请手动给showdoc安装目录下的所有文件可写权限,否则程序无法覆盖旧文件');
return ;
}
$temp_dir = sys_get_temp_dir()."/showdoc_update/";
$zip_file = $temp_dir.'showdoc-'.$version_num.'.zip' ;
mkdir($temp_dir) ;
unlink($zip_file);
$file = file_get_contents($file_url);
file_put_contents($zip_file,$file);
$zip = new \ZipArchive();
$flag = $zip->open($zip_file);
if($flag!==true){
$this->sendError(10101,'下载更新压缩包失败');
return ;
}
$zip->extractTo($temp_dir);
$flag = $zip->close();
$zip_file_subpath = $temp_dir.'showdoc-'.$version_num."/" ;
if(file_exists($zip_file_subpath.'composer.json') && file_exists($zip_file_subpath.'web/index.php') && file_exists($zip_file_subpath.'server/vendor/autoload.php') ){
//echo $zip_file_subpath.'存在';
// 移动目录到upload/update
$this->copydir($zip_file_subpath ,$showdoc_path.'Public/Uploads/update/' );
$this->deldir($temp_dir);
$this->sendResult(array());
}else{
$this->sendError(10101,'下载更新压缩包后,解压的文件缺失');
return ;
}
}
// 执行升级操作,升级覆盖文件
public function updateFiles(){
$this->checkLogin();
$this->checkAdmin();
set_time_limit(1000);
ini_set('memory_limit','500M');
$showdoc_path = "../" ;
// 进行文件读写权限检查
if(!$this->new_is_writeable($showdoc_path)
|| !$this->new_is_writeable($showdoc_path."Sqlite/" )
|| !$this->new_is_writeable($showdoc_path."web/" )
|| !$this->new_is_writeable($showdoc_path."web/index.php" )
|| !$this->new_is_writeable($showdoc_path."server/" )
|| !$this->new_is_writeable($showdoc_path."server/vendor/autoload.php" )
|| !$this->new_is_writeable($showdoc_path."server/Application/Api" )
){
$this->sendError(10101,'请手动给showdoc安装目录下的所有文件可写权限,否则程序无法覆盖旧文件');
return ;
}
if(file_exists($showdoc_path.'Public/Uploads/update/composer.json') && file_exists($showdoc_path.'Public/Uploads/update/server/vendor/autoload.php') ){
$text = file_get_contents($showdoc_path."composer.json");
$composer = json_decode($text, true);
$cur_version = $composer['version'] ;
$cur_version = str_replace("v","",$cur_version) ;
$text = file_get_contents($showdoc_path."Public/Uploads/update/composer.json");
$composer = json_decode($text, true);
$update_version = $composer['version'] ;
$update_version = str_replace("v","",$update_version) ;
if(version_compare($update_version,$cur_version) > 0 ){
//复制数据库文件备份
$bak_name = $showdoc_path.'Sqlite/showdoc.db.bak.'.date("Y-m-d-H-i-s").'.php';
copy($showdoc_path.'Sqlite/showdoc.db.php', $bak_name);
// 目录覆盖
$this->copydir($showdoc_path.'Public/Uploads/update/',$showdoc_path);
// 用备份的数据库还原
copy($bak_name, $showdoc_path.'Sqlite/showdoc.db.php' );
$this->deldir($showdoc_path.'Public/Uploads/update/') ;
// echo '升级成功!' ;
$this->sendResult(array());
}else{
// echo '不需要升级';
$this->sendError(10101,'版本号显示不需要升级');
}
}else{
$this->sendError(10101,'升级文件不存在');
}
}
/**
* 复制到目录
* $dirsrc 原目录
* $dirto 目标目录
*
*/
private function copydir($dirsrc, $dirto) {
//如果原来的文件存在, 是不是一个目录
if(file_exists($dirto)) {
if(!is_dir($dirto)) {
echo "目标不是一个目录, 不能copy进去<br>";
exit;
}
}else{
mkdir($dirto);
}
$dir = opendir($dirsrc);
while($filename = readdir($dir)) {
if($filename != "." && $filename !="..") {
$srcfile = $dirsrc."/".$filename; //原文件
$tofile = $dirto."/".$filename; //目标文件
if(is_dir($srcfile)) {
$this->copydir($srcfile, $tofile); //递归处理所有子目录
}else{
copy($srcfile, $tofile);
}
}
}
}
// 删除文件夹及文件夹下所有的文件
private function deldir($dir) {
//先删除目录下的文件:
$dh = opendir($dir);
while ($file = readdir($dh)) {
if($file != "." && $file!="..") {
$fullpath = $dir."/".$file;
if(!is_dir($fullpath)) {
unlink($fullpath);
} else {
$this->deldir($fullpath);
}
}
}
closedir($dh);
//删除当前文件夹:
if(rmdir($dir)) {
return true;
} else {
return false;
}
}
/**
* 判断 文件/目录 是否可写(取代系统自带的 is_writeable 函数)
*
* @param string $file 文件/目录
* @return boolean
*/
private function new_is_writeable($file) {
if (is_dir($file)){
$dir = $file;
if ($fp = @fopen("$dir/test.txt", 'w')) {
@fclose($fp);
@unlink("$dir/test.txt");
$writeable = 1;
} else {
$writeable = 0;
}
} else {
if ($fp = @fopen($file, 'a+')) {
@fclose($fp);
$writeable = 1;
} else {
$writeable = 0;
}
}
return $writeable;
}
}