国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

435 lines
14KB

  1. <?php
  2. /**
  3. * 本文件用于从镜像服务器获取升级信息与文件
  4. * 并由用户自行控制升级
  5. *
  6. * @version $Id: update_guide.php 1 23:54 2010年7月20日Z tianya $
  7. * @package DedeCMS.Administrator
  8. * @copyright Copyright (c) 2020, DedeBIZ.COM
  9. * @license https://www.dedebiz.com/license
  10. * @link https://www.dedebiz.com
  11. */
  12. require(dirname(__FILE__).'/config.php');
  13. CheckPurview('sys_Edit');
  14. @set_time_limit(0);
  15. require(DEDEINC.'/inc/inc_fun_funAdmin.php');
  16. require(DEDEINC.'/dedehttpdown.class.php');
  17. function TestWriteAble($d)
  18. {
  19. $tfile = '_dedet.txt';
  20. $fp = @fopen($d.$tfile,'w');
  21. if(!$fp) {
  22. return false;
  23. }
  24. else {
  25. fclose($fp);
  26. $rs = @unlink($d.'/'.$tfile);
  27. return true;
  28. }
  29. }
  30. function GetDirName($filename)
  31. {
  32. $dirname = '../'.preg_replace("#[\\\\\/]{1,}#", '/', $filename);
  33. $dirname = preg_replace("#([^\/]*)$#", '', $dirname);
  34. return $dirname;
  35. }
  36. function TestIsFileDir($dirname)
  37. {
  38. $dirs = array('name'=>'', 'isdir'=>FALSE, 'writeable'=>FALSE);
  39. $dirs['name'] = $dirname;
  40. if(is_dir($dirname))
  41. {
  42. $dirs['isdir'] = TRUE;
  43. $dirs['writeable'] = TestWriteAble($dirname);
  44. }
  45. return $dirs;
  46. }
  47. function MkTmpDir($tmpdir,$filename)
  48. {
  49. $basedir = DEDEDATA.'/'.$tmpdir;
  50. $dirname = trim(preg_replace("#[\\\\\/]{1,}#", '/', $filename));
  51. $dirname = preg_replace("#([^\/]*)$#","",$dirname);
  52. if(!is_dir($basedir))
  53. {
  54. mkdir($basedir,0777);
  55. }
  56. if($dirname=='')
  57. {
  58. return TRUE;
  59. }
  60. $dirs = explode('/', $dirname);
  61. $curdir = $basedir;
  62. foreach($dirs as $d)
  63. {
  64. $d = trim($d);
  65. if(empty($d)) continue;
  66. $curdir = $curdir.'/'.$d;
  67. if(!is_dir($curdir))
  68. {
  69. mkdir($curdir, 0777) or die($curdir);
  70. }
  71. }
  72. return TRUE;
  73. }
  74. if(empty($dopost)) $dopost = 'test';
  75. //当前软件版本锁定文件
  76. $verLockFile = DEDEDATA.'/admin/ver.txt';
  77. $fp = fopen($verLockFile,'r');
  78. $upTime = trim(fread($fp,64));
  79. fclose($fp);
  80. $oktime = substr($upTime,0,4).'-'.substr($upTime,4,2).'-'.substr($upTime,6,2);
  81. /**
  82. 用AJAX获取最新版本信息
  83. function _Test() { }
  84. */
  85. if($dopost=='test')
  86. {
  87. AjaxHead();
  88. //下载远程数据
  89. $dhd = new DedeHttpDown();
  90. $dhd->OpenUrl(DEDECDNURL.'/release/latest.txt');
  91. $verlatest = trim($dhd->GetHtml());
  92. $dhd->Close();
  93. //echo "<xmp>";
  94. //判断是否需要更新,并返回适合的结果
  95. if(version_compare($verlatest, $cfg_version_detail,"<="))
  96. {
  97. $offUrl = SpGetNewInfo();
  98. echo "<div class='updatedvt'><b>你系统版本最后更新时间为:{$oktime},当前没有可用的更新</b></div>\r\n";
  99. echo "<iframe name='stafrm' src='{$offUrl}&uptime={$oktime}' frameborder='0' id='stafrm' width='100%' height='50'></iframe>";
  100. }
  101. else
  102. {
  103. echo "<div style='width:98%'><form name='fup' action='update_guide.php' method='post' onsubmit='ShowWaitDiv()'>\r\n";
  104. echo "<input type='hidden' name='dopost' value='getlist' />\r\n";
  105. echo "<div class='upinfotitle'>当前有可用的更新,可以通过<a href='$cfg_biz_gitUrl' target='_blank'>代码托管</a>查看更新记录:</div>\r\n";
  106. echo "<div style='line-height:32px'><button type='submit' name='sb1' class='btn btn-success btn-sm' style='cursor:pointer'>获取并安装</button>\r\n";
  107. echo " &nbsp;</div>\r\n";
  108. echo "</form></div>";
  109. }
  110. //echo "</xmp>";
  111. exit();
  112. }
  113. /**
  114. 忽略某个日期前的升级
  115. function _Skip() { }
  116. */
  117. else if($dopost=='skip')
  118. {
  119. AjaxHead();
  120. $fp = fopen($verLockFile, 'w');
  121. fwrite($fp, $vtime);
  122. fclose($fp);
  123. $offUrl = SpGetNewInfo();
  124. echo "<div class='updatedvt'><b>你系统版本最后更新时间为:{$oktime},当前没有可用的更新。</b></div>\r\n";
  125. echo "<iframe name='stafrm' src='{$offUrl}&uptime={$oktime}' frameborder='0' id='stafrm' width='100%' height='60'></iframe>";
  126. exit();
  127. }
  128. else if($dopost=='skipback')
  129. {
  130. $fp = fopen($verLockFile, 'w');
  131. fwrite($fp, $vtime);
  132. fclose($fp);
  133. ShowMsg("成功跳过这些更新!", "index_body.php");
  134. exit();
  135. }
  136. /**
  137. 获取升级文件列表
  138. function _GetList() { }
  139. */
  140. else if($dopost=='getlist')
  141. {
  142. $upitemsArr = explode(',', $upitems);
  143. rsort($upitemsArr);
  144. $tmpdir = substr(md5($cfg_cookie_encode), 0, 16);
  145. $dhd = new DedeHttpDown();
  146. $fileArr = array();
  147. $f = 0;
  148. foreach($upitemsArr as $upitem)
  149. {
  150. $durl = UPDATEHOST.$cfg_soft_lang.'/'.$upitem.'.file.txt';
  151. $dhd->OpenUrl($durl);
  152. $filelist = $dhd->GetHtml();
  153. $filelist = trim( preg_replace("#[\r\n]{1,}#", "\n", $filelist) );
  154. if(!empty($filelist))
  155. {
  156. $filelists = explode("\n", $filelist);
  157. foreach($filelists as $filelist)
  158. {
  159. $filelist = trim($filelist);
  160. if(empty($filelist)) continue;
  161. $fs = explode(',', $filelist);
  162. if( empty($fs[1]) )
  163. {
  164. $fs[1] = $upitem." 常规功能更新文件";
  165. }
  166. if(!isset($fileArr[$fs[0]]))
  167. {
  168. $fileArr[$fs[0]] = $upitem." ".trim($fs[1]);
  169. $f++;
  170. }
  171. }
  172. }
  173. }
  174. $dhd->Close();
  175. $allFileList = '';
  176. if($f==0)
  177. {
  178. $allFileList = "<font color='green'><b>没发现可用的文件列表信息,可能是官方服务器存在问题,请稍后再尝试!</b></font>";
  179. }
  180. else
  181. {
  182. $allFileList .= "<div style='width:98%'><form name='fup' action='update_guide.php' method='post'>\r\n";
  183. $allFileList .= "<input type='hidden' name='vtime' value='$vtime' />\r\n";
  184. $allFileList .= "<input type='hidden' name='dopost' value='getfiles' />\r\n";
  185. $allFileList .= "<input type='hidden' name='upitems' value='$upitems' />\r\n";
  186. $allFileList .= "<div class='upinfotitle'>以下是需要下载的更新文件(路径相对于DedeCMS的根目录):</div>\r\n";
  187. $filelists = explode("\n",$filelist);
  188. foreach($fileArr as $k=>$v)
  189. {
  190. $allFileList .= "<div class='verline'><input type='checkbox' name='files[]' value='{$k}' checked='checked' /> $k({$v})</div>\r\n";
  191. }
  192. $allFileList .= "<div class='verline'>";
  193. $allFileList .= "文件临时存放目录:../data/<input type='text' name='tmpdir' style='width:200px' value='$tmpdir' /><br />\r\n";
  194. $allFileList .= "<input type='checkbox' name='skipnodir' value='1' checked='checked' /> 跳过系统中没有的文件夹(通常是可选模块的补丁)</div>\r\n";
  195. $allFileList .= "<div style='line-height:36px;background:#F8FEDA'>&nbsp;\r\n";
  196. $allFileList .= "<input type='submit' name='sb1' value=' 下载并应用这些补丁 ' class='np coolbg' style='cursor:pointer' />\r\n";
  197. $allFileList .="</form></div>";
  198. }
  199. include DedeInclude('templets/update_guide_getlist.htm');
  200. exit();
  201. }
  202. /**
  203. 下载文件(保存需下载内容列表)
  204. function _GetFiles() { }
  205. */
  206. else if($dopost=='getfilesstart')
  207. {
  208. //update_guide.php?dopost=down&curfile=0
  209. $msg = "如果检测时发现你没安装模块的文件夹有错误,可不必理会<br />";
  210. $msg .= "<a href=update_guide.php?dopost=down&curfile=0>确认目录状态都正常后,请点击开始下载文件&gt;&gt;</a><br />";
  211. ShowMsg($msg,"javascript:;");
  212. exit();
  213. }
  214. else if($dopost=='getfiles')
  215. {
  216. $cacheFiles = DEDEDATA.'/cache/updatetmp.inc';
  217. $skipnodir = (isset($skipnodir) ? 1 : 0);
  218. $adminDir = preg_replace("#(.*)[\/\\\\]#", "", dirname(__FILE__));
  219. if(!isset($files))
  220. {
  221. $doneStr = "<p align='center' style='color:red'><br />你没有指定任何需要下载更新的文件,是否跳过这些更新?<br /><br />";
  222. $doneStr .= "<a href='update_guide.php?dopost=skipback&vtime=$vtime' class='np coolbg'>[跳过这些更新]</a> &nbsp; ";
  223. $doneStr .= "<a href='index_body.php' class='np coolbg'>[保留提示以后再进行操作]</a></p>";
  224. }
  225. else
  226. {
  227. $fp = fopen($cacheFiles, 'w');
  228. fwrite($fp, '<'.'?php'."\r\n");
  229. fwrite($fp, '$tmpdir = "'.$tmpdir.'";'."\r\n");
  230. fwrite($fp, '$vtime = '.$vtime.';'."\r\n");
  231. $dirs = array();
  232. $i = -1;
  233. foreach($files as $filename)
  234. {
  235. $tfilename = $filename;
  236. if( preg_match("#^dede\/#i", $filename) )
  237. {
  238. $tfilename = preg_replace("#^dede\/#", $adminDir.'/', $filename);
  239. }
  240. $curdir = GetDirName($tfilename);
  241. if( !isset($dirs[$curdir]) )
  242. {
  243. $dirs[$curdir] = TestIsFileDir($curdir);
  244. }
  245. if($skipnodir==1 && $dirs[$curdir]['isdir'] == FALSE)
  246. {
  247. continue;
  248. }
  249. else {
  250. @mkdir($curdir, 0777);
  251. $dirs[$curdir] = TestIsFileDir($curdir);
  252. }
  253. $i++;
  254. fwrite($fp, '$files['.$i.'] = "'.$filename.'";'."\r\n");
  255. }
  256. fwrite($fp, '$fileConut = '.$i.';'."\r\n");
  257. $items = explode(',', $upitems);
  258. foreach($items as $sqlfile)
  259. {
  260. fwrite($fp,'$sqls[] = "'.$sqlfile.'.sql";'."\r\n");
  261. }
  262. fwrite($fp, '?'.'>');
  263. fclose($fp);
  264. $dirinfos = '';
  265. if($i > -1)
  266. {
  267. $dirinfos = '<tr bgcolor="#ffffff"><td colspan="2">';
  268. $dirinfos .= "本次升级需要在下面文件夹写入更新文件,请注意文件夹是否有写入权限:<br />\r\n";
  269. foreach($dirs as $curdir)
  270. {
  271. $dirinfos .= $curdir['name']." 状态:".($curdir['writeable'] ? "[√正常]" : "<font color='red'>[×不可写]</font>")."<br />\r\n";
  272. }
  273. $dirinfos .= "</td></tr>\r\n";
  274. }
  275. $doneStr = "<iframe name='stafrm' src='update_guide.php?dopost=getfilesstart' frameborder='0' id='stafrm' width='100%' height='100%'></iframe>\r\n";
  276. }
  277. include DedeInclude('templets/update_guide_getfiles.htm');
  278. exit();
  279. }
  280. /**
  281. 下载文件,具体操作步骤
  282. function _Down() { }
  283. */
  284. else if($dopost=='down')
  285. {
  286. $cacheFiles = DEDEDATA.'/cache/updatetmp.inc';
  287. require_once($cacheFiles);
  288. if(empty($startup))
  289. {
  290. if($fileConut==-1 || $curfile > $fileConut)
  291. {
  292. ShowMsg("已下载所有文件,开始下载数据库升级文件...","update_guide.php?dopost=down&startup=1");
  293. exit();
  294. }
  295. //检查临时文件保存目录是否可用
  296. MkTmpDir($tmpdir, $files[$curfile]);
  297. $downfile = UPDATEHOST.$cfg_soft_lang.'/source/'.$files[$curfile];
  298. $dhd = new DedeHttpDown();
  299. $dhd->OpenUrl($downfile);
  300. $dhd->SaveToBin(DEDEDATA.'/'.$tmpdir.'/'.$files[$curfile]);
  301. $dhd->Close();
  302. ShowMsg("成功下载并保存文件:{$files[$curfile]}; 继续下载下一个文件。","update_guide.php?dopost=down&curfile=".($curfile+1));
  303. exit();
  304. }
  305. else
  306. {
  307. MkTmpDir($tmpdir, 'sql.txt');
  308. $dhd = new DedeHttpDown();
  309. $ct = '';
  310. foreach($sqls as $sql)
  311. {
  312. $downfile = UPDATEHOST.$cfg_soft_lang.'/'.$sql;
  313. $dhd->OpenUrl($downfile);
  314. $ct .= $dhd->GetHtml();
  315. }
  316. $dhd->Close();
  317. $truefile = DEDEDATA.'/'.$tmpdir.'/sql.txt';
  318. $fp = fopen($truefile, 'w');
  319. fwrite($fp, $ct);
  320. fclose($fp);
  321. ShowMsg("完成所有远程文件获取操作:<a href='update_guide.php?dopost=apply'>&lt;&lt;点击此开始直接升级&gt;&gt;</a><br />你也可以直接使用[../data/{$tmpdir}]目录的文件手动升级。","javascript:;");
  322. exit();
  323. }
  324. exit();
  325. }
  326. /**
  327. 应用升级
  328. function _ApplyUpdate() { }
  329. */
  330. else if($dopost=='apply')
  331. {
  332. $cacheFiles = DEDEDATA.'/cache/updatetmp.inc';
  333. require_once($cacheFiles);
  334. if(empty($step))
  335. {
  336. $truefile = DEDEDATA.'/'.$tmpdir.'/sql.txt';
  337. $fp = fopen($truefile, 'r');
  338. $sql = @fread($fp, filesize($truefile));
  339. fclose($fp);
  340. if(!empty($sql))
  341. {
  342. $mysql_version = $dsql->GetVersion(true);
  343. $sql = preg_replace('#ENGINE=MyISAM#i', 'TYPE=MyISAM', $sql);
  344. $sql41tmp = 'ENGINE=MyISAM DEFAULT CHARSET='.$cfg_db_language;
  345. if($mysql_version >= 4.1)
  346. {
  347. $sql = preg_replace('#TYPE=MyISAM#i', $sql41tmp, $sql);
  348. }
  349. $sqls = explode(";\r\n", $sql);
  350. foreach($sqls as $sql)
  351. {
  352. if(trim($sql)!='')
  353. {
  354. $dsql->ExecuteNoneQuery(trim($sql));
  355. }
  356. }
  357. }
  358. ShowMsg("完成数据库更新,现在开始复制文件。","update_guide.php?dopost=apply&step=1");
  359. exit();
  360. }
  361. else
  362. {
  363. $sDir = DEDEDATA."/$tmpdir";
  364. $tDir = DEDEROOT;
  365. $badcp = 0;
  366. $adminDir = preg_replace("#(.*)[\/\\\\]#", "", dirname(__FILE__));
  367. if(isset($files) && is_array($files))
  368. {
  369. foreach($files as $f)
  370. {
  371. if(preg_match('#^dede#', $f))
  372. {
  373. $tf = preg_replace('#^dede#', $adminDir, $f);
  374. }
  375. else {
  376. $tf = $f;
  377. }
  378. if(file_exists($sDir.'/'.$f))
  379. {
  380. $rs = @copy($sDir.'/'.$f, $tDir.'/'.$tf);
  381. if($rs) {
  382. unlink($sDir.'/'.$f);
  383. }
  384. else {
  385. $badcp++;
  386. }
  387. }
  388. }
  389. }
  390. $fp = fopen($verLockFile,'w');
  391. fwrite($fp,$vtime);
  392. fclose($fp);
  393. $badmsg = '!';
  394. if($badcp > 0)
  395. {
  396. $badmsg = ",其中失败 {$badcp} 个文件,<br />请从临时目录[../data/{$tmpdir}]中取出这几个文件手动升级。";
  397. }
  398. ShowMsg("成功完成升级{$badmsg}","javascript:;");
  399. exit();
  400. }
  401. }