国内流行的内容管理系统(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.

477 lines
16KB

  1. <?php
  2. /**
  3. * 本文件用于从镜像服务器获取升级信息与文件
  4. * 并由用户自行控制升级
  5. *
  6. * @version $Id: vote_main.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(UPDATEHOST.'/verinfo.txt');
  91. $verlist = trim($dhd->GetHtml());
  92. $dhd->Close();
  93. if($cfg_soft_lang=='utf-8')
  94. {
  95. $verlist = gb2utf8($verlist);
  96. }
  97. $verlist = preg_replace("#[\r\n]{1,}#", "\n", $verlist);
  98. $verlists = explode("\n", $verlist);
  99. //分析数据
  100. $updateVers = array();
  101. $upitems = $lastTime = '';
  102. $n = 0;
  103. foreach($verlists as $verstr)
  104. {
  105. if( empty($verstr) || preg_match("#^\/\/#", $verstr) )
  106. {
  107. continue ;
  108. }
  109. list($vtime, $vlang, $issafe, $vmsg) = explode(',', $verstr);
  110. $vtime = trim($vtime);
  111. $vlang = trim($vlang);
  112. $issafe = trim($issafe);
  113. $vmsg = trim($vmsg);
  114. if($vtime > $upTime && $vlang==$cfg_soft_lang)
  115. {
  116. $updateVers[$n]['issafe'] = $issafe;
  117. $updateVers[$n]['vmsg'] = $vmsg;
  118. $upitems .= ($upitems=='' ? $vtime : ','.$vtime);
  119. $lastTime = $vtime;
  120. $updateVers[$n]['vtime'] = substr($vtime,0,4).'-'.substr($vtime,4,2).'-'.substr($vtime,6,2);
  121. $n++;
  122. }
  123. }
  124. //echo "<xmp>";
  125. //判断是否需要更新,并返回适合的结果
  126. if($n==0)
  127. {
  128. $offUrl = SpGetNewInfo();
  129. echo "<div class='updatedvt'><b>你系统版本最后更新时间为:{$oktime},当前没有可用的更新</b></div>\r\n";
  130. echo "<iframe name='stafrm' src='{$offUrl}&uptime={$oktime}' frameborder='0' id='stafrm' width='100%' height='50'></iframe>";
  131. }
  132. else
  133. {
  134. echo "<div style='width:98%'><form name='fup' action='update_guide.php' method='post' onsubmit='ShowWaitDiv()'>\r\n";
  135. echo "<input type='hidden' name='dopost' value='getlist' />\r\n";
  136. echo "<input type='hidden' name='vtime' value='$lastTime' />\r\n";
  137. echo "<input type='hidden' name='upitems' value='$upitems' />\r\n";
  138. echo "<div class='upinfotitle'>你系统版本最后更新时间为:{$oktime},当前可用的更新有:</div>\r\n";
  139. foreach($updateVers as $vers)
  140. {
  141. $style = '';
  142. if($vers['issafe']==1)
  143. {
  144. $style = "color:red;";
  145. }
  146. echo "<div style='{$style}' class='verline'>【".($vers['issafe']==1 ? "安全更新" : "普通更新")."】";
  147. echo $vers['vtime'].",更新说明:{$vers['vmsg']}</div>\r\n";
  148. }
  149. echo "<div style='line-height:32px'><input type='submit' name='sb1' value=' 点击此获取所有更新文件,然后选择安装 ' class='np coolbg' style='cursor:pointer' />\r\n";
  150. echo " &nbsp; <input type='button' name='sb2' value=' 忽略这些更新 ' onclick='SkipReload({$lastTime})' class='np coolbg' style='cursor:pointer' /></div>\r\n";
  151. echo "</form></div>";
  152. }
  153. //echo "</xmp>";
  154. exit();
  155. }
  156. /**
  157. 忽略某个日期前的升级
  158. function _Skip() { }
  159. */
  160. else if($dopost=='skip')
  161. {
  162. AjaxHead();
  163. $fp = fopen($verLockFile, 'w');
  164. fwrite($fp, $vtime);
  165. fclose($fp);
  166. $offUrl = SpGetNewInfo();
  167. echo "<div class='updatedvt'><b>你系统版本最后更新时间为:{$oktime},当前没有可用的更新。</b></div>\r\n";
  168. echo "<iframe name='stafrm' src='{$offUrl}&uptime={$oktime}' frameborder='0' id='stafrm' width='100%' height='60'></iframe>";
  169. exit();
  170. }
  171. else if($dopost=='skipback')
  172. {
  173. $fp = fopen($verLockFile, 'w');
  174. fwrite($fp, $vtime);
  175. fclose($fp);
  176. ShowMsg("成功跳过这些更新!", "index_body.php");
  177. exit();
  178. }
  179. /**
  180. 获取升级文件列表
  181. function _GetList() { }
  182. */
  183. else if($dopost=='getlist')
  184. {
  185. $upitemsArr = explode(',', $upitems);
  186. rsort($upitemsArr);
  187. $tmpdir = substr(md5($cfg_cookie_encode), 0, 16);
  188. $dhd = new DedeHttpDown();
  189. $fileArr = array();
  190. $f = 0;
  191. foreach($upitemsArr as $upitem)
  192. {
  193. $durl = UPDATEHOST.$cfg_soft_lang.'/'.$upitem.'.file.txt';
  194. $dhd->OpenUrl($durl);
  195. $filelist = $dhd->GetHtml();
  196. $filelist = trim( preg_replace("#[\r\n]{1,}#", "\n", $filelist) );
  197. if(!empty($filelist))
  198. {
  199. $filelists = explode("\n", $filelist);
  200. foreach($filelists as $filelist)
  201. {
  202. $filelist = trim($filelist);
  203. if(empty($filelist)) continue;
  204. $fs = explode(',', $filelist);
  205. if( empty($fs[1]) )
  206. {
  207. $fs[1] = $upitem." 常规功能更新文件";
  208. }
  209. if(!isset($fileArr[$fs[0]]))
  210. {
  211. $fileArr[$fs[0]] = $upitem." ".trim($fs[1]);
  212. $f++;
  213. }
  214. }
  215. }
  216. }
  217. $dhd->Close();
  218. $allFileList = '';
  219. if($f==0)
  220. {
  221. $allFileList = "<font color='green'><b>没发现可用的文件列表信息,可能是官方服务器存在问题,请稍后再尝试!</b></font>";
  222. }
  223. else
  224. {
  225. $allFileList .= "<div style='width:98%'><form name='fup' action='update_guide.php' method='post'>\r\n";
  226. $allFileList .= "<input type='hidden' name='vtime' value='$vtime' />\r\n";
  227. $allFileList .= "<input type='hidden' name='dopost' value='getfiles' />\r\n";
  228. $allFileList .= "<input type='hidden' name='upitems' value='$upitems' />\r\n";
  229. $allFileList .= "<div class='upinfotitle'>以下是需要下载的更新文件(路径相对于DedeCMS的根目录):</div>\r\n";
  230. $filelists = explode("\n",$filelist);
  231. foreach($fileArr as $k=>$v)
  232. {
  233. $allFileList .= "<div class='verline'><input type='checkbox' name='files[]' value='{$k}' checked='checked' /> $k({$v})</div>\r\n";
  234. }
  235. $allFileList .= "<div class='verline'>";
  236. $allFileList .= "文件临时存放目录:../data/<input type='text' name='tmpdir' style='width:200px' value='$tmpdir' /><br />\r\n";
  237. $allFileList .= "<input type='checkbox' name='skipnodir' value='1' checked='checked' /> 跳过系统中没有的文件夹(通常是可选模块的补丁)</div>\r\n";
  238. $allFileList .= "<div style='line-height:36px;background:#F8FEDA'>&nbsp;\r\n";
  239. $allFileList .= "<input type='submit' name='sb1' value=' 下载并应用这些补丁 ' class='np coolbg' style='cursor:pointer' />\r\n";
  240. $allFileList .="</form></div>";
  241. }
  242. include DedeInclude('templets/update_guide_getlist.htm');
  243. exit();
  244. }
  245. /**
  246. 下载文件(保存需下载内容列表)
  247. function _GetFiles() { }
  248. */
  249. else if($dopost=='getfilesstart')
  250. {
  251. //update_guide.php?dopost=down&curfile=0
  252. $msg = "如果检测时发现你没安装模块的文件夹有错误,可不必理会<br />";
  253. $msg .= "<a href=update_guide.php?dopost=down&curfile=0>确认目录状态都正常后,请点击开始下载文件&gt;&gt;</a><br />";
  254. ShowMsg($msg,"javascript:;");
  255. exit();
  256. }
  257. else if($dopost=='getfiles')
  258. {
  259. $cacheFiles = DEDEDATA.'/cache/updatetmp.inc';
  260. $skipnodir = (isset($skipnodir) ? 1 : 0);
  261. $adminDir = preg_replace("#(.*)[\/\\\\]#", "", dirname(__FILE__));
  262. if(!isset($files))
  263. {
  264. $doneStr = "<p align='center' style='color:red'><br />你没有指定任何需要下载更新的文件,是否跳过这些更新?<br /><br />";
  265. $doneStr .= "<a href='update_guide.php?dopost=skipback&vtime=$vtime' class='np coolbg'>[跳过这些更新]</a> &nbsp; ";
  266. $doneStr .= "<a href='index_body.php' class='np coolbg'>[保留提示以后再进行操作]</a></p>";
  267. }
  268. else
  269. {
  270. $fp = fopen($cacheFiles, 'w');
  271. fwrite($fp, '<'.'?php'."\r\n");
  272. fwrite($fp, '$tmpdir = "'.$tmpdir.'";'."\r\n");
  273. fwrite($fp, '$vtime = '.$vtime.';'."\r\n");
  274. $dirs = array();
  275. $i = -1;
  276. foreach($files as $filename)
  277. {
  278. $tfilename = $filename;
  279. if( preg_match("#^dede\/#i", $filename) )
  280. {
  281. $tfilename = preg_replace("#^dede\/#", $adminDir.'/', $filename);
  282. }
  283. $curdir = GetDirName($tfilename);
  284. if( !isset($dirs[$curdir]) )
  285. {
  286. $dirs[$curdir] = TestIsFileDir($curdir);
  287. }
  288. if($skipnodir==1 && $dirs[$curdir]['isdir'] == FALSE)
  289. {
  290. continue;
  291. }
  292. else {
  293. @mkdir($curdir, 0777);
  294. $dirs[$curdir] = TestIsFileDir($curdir);
  295. }
  296. $i++;
  297. fwrite($fp, '$files['.$i.'] = "'.$filename.'";'."\r\n");
  298. }
  299. fwrite($fp, '$fileConut = '.$i.';'."\r\n");
  300. $items = explode(',', $upitems);
  301. foreach($items as $sqlfile)
  302. {
  303. fwrite($fp,'$sqls[] = "'.$sqlfile.'.sql";'."\r\n");
  304. }
  305. fwrite($fp, '?'.'>');
  306. fclose($fp);
  307. $dirinfos = '';
  308. if($i > -1)
  309. {
  310. $dirinfos = '<tr bgcolor="#ffffff"><td colspan="2">';
  311. $dirinfos .= "本次升级需要在下面文件夹写入更新文件,请注意文件夹是否有写入权限:<br />\r\n";
  312. foreach($dirs as $curdir)
  313. {
  314. $dirinfos .= $curdir['name']." 状态:".($curdir['writeable'] ? "[√正常]" : "<font color='red'>[×不可写]</font>")."<br />\r\n";
  315. }
  316. $dirinfos .= "</td></tr>\r\n";
  317. }
  318. $doneStr = "<iframe name='stafrm' src='update_guide.php?dopost=getfilesstart' frameborder='0' id='stafrm' width='100%' height='100%'></iframe>\r\n";
  319. }
  320. include DedeInclude('templets/update_guide_getfiles.htm');
  321. exit();
  322. }
  323. /**
  324. 下载文件,具体操作步骤
  325. function _Down() { }
  326. */
  327. else if($dopost=='down')
  328. {
  329. $cacheFiles = DEDEDATA.'/cache/updatetmp.inc';
  330. require_once($cacheFiles);
  331. if(empty($startup))
  332. {
  333. if($fileConut==-1 || $curfile > $fileConut)
  334. {
  335. ShowMsg("已下载所有文件,开始下载数据库升级文件...","update_guide.php?dopost=down&startup=1");
  336. exit();
  337. }
  338. //检查临时文件保存目录是否可用
  339. MkTmpDir($tmpdir, $files[$curfile]);
  340. $downfile = UPDATEHOST.$cfg_soft_lang.'/source/'.$files[$curfile];
  341. $dhd = new DedeHttpDown();
  342. $dhd->OpenUrl($downfile);
  343. $dhd->SaveToBin(DEDEDATA.'/'.$tmpdir.'/'.$files[$curfile]);
  344. $dhd->Close();
  345. ShowMsg("成功下载并保存文件:{$files[$curfile]}; 继续下载下一个文件。","update_guide.php?dopost=down&curfile=".($curfile+1));
  346. exit();
  347. }
  348. else
  349. {
  350. MkTmpDir($tmpdir, 'sql.txt');
  351. $dhd = new DedeHttpDown();
  352. $ct = '';
  353. foreach($sqls as $sql)
  354. {
  355. $downfile = UPDATEHOST.$cfg_soft_lang.'/'.$sql;
  356. $dhd->OpenUrl($downfile);
  357. $ct .= $dhd->GetHtml();
  358. }
  359. $dhd->Close();
  360. $truefile = DEDEDATA.'/'.$tmpdir.'/sql.txt';
  361. $fp = fopen($truefile, 'w');
  362. fwrite($fp, $ct);
  363. fclose($fp);
  364. ShowMsg("完成所有远程文件获取操作:<a href='update_guide.php?dopost=apply'>&lt;&lt;点击此开始直接升级&gt;&gt;</a><br />你也可以直接使用[../data/{$tmpdir}]目录的文件手动升级。","javascript:;");
  365. exit();
  366. }
  367. exit();
  368. }
  369. /**
  370. 应用升级
  371. function _ApplyUpdate() { }
  372. */
  373. else if($dopost=='apply')
  374. {
  375. $cacheFiles = DEDEDATA.'/cache/updatetmp.inc';
  376. require_once($cacheFiles);
  377. if(empty($step))
  378. {
  379. $truefile = DEDEDATA.'/'.$tmpdir.'/sql.txt';
  380. $fp = fopen($truefile, 'r');
  381. $sql = @fread($fp, filesize($truefile));
  382. fclose($fp);
  383. if(!empty($sql))
  384. {
  385. $mysql_version = $dsql->GetVersion(true);
  386. $sql = preg_replace('#ENGINE=MyISAM#i', 'TYPE=MyISAM', $sql);
  387. $sql41tmp = 'ENGINE=MyISAM DEFAULT CHARSET='.$cfg_db_language;
  388. if($mysql_version >= 4.1)
  389. {
  390. $sql = preg_replace('#TYPE=MyISAM#i', $sql41tmp, $sql);
  391. }
  392. $sqls = explode(";\r\n", $sql);
  393. foreach($sqls as $sql)
  394. {
  395. if(trim($sql)!='')
  396. {
  397. $dsql->ExecuteNoneQuery(trim($sql));
  398. }
  399. }
  400. }
  401. ShowMsg("完成数据库更新,现在开始复制文件。","update_guide.php?dopost=apply&step=1");
  402. exit();
  403. }
  404. else
  405. {
  406. $sDir = DEDEDATA."/$tmpdir";
  407. $tDir = DEDEROOT;
  408. $badcp = 0;
  409. $adminDir = preg_replace("#(.*)[\/\\\\]#", "", dirname(__FILE__));
  410. if(isset($files) && is_array($files))
  411. {
  412. foreach($files as $f)
  413. {
  414. if(preg_match('#^dede#', $f))
  415. {
  416. $tf = preg_replace('#^dede#', $adminDir, $f);
  417. }
  418. else {
  419. $tf = $f;
  420. }
  421. if(file_exists($sDir.'/'.$f))
  422. {
  423. $rs = @copy($sDir.'/'.$f, $tDir.'/'.$tf);
  424. if($rs) {
  425. unlink($sDir.'/'.$f);
  426. }
  427. else {
  428. $badcp++;
  429. }
  430. }
  431. }
  432. }
  433. $fp = fopen($verLockFile,'w');
  434. fwrite($fp,$vtime);
  435. fclose($fp);
  436. $badmsg = '!';
  437. if($badcp > 0)
  438. {
  439. $badmsg = ",其中失败 {$badcp} 个文件,<br />请从临时目录[../data/{$tmpdir}]中取出这几个文件手动升级。";
  440. }
  441. ShowMsg("成功完成升级{$badmsg}","javascript:;");
  442. exit();
  443. }
  444. }