You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
6.0 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: huajie <banhuajie@163.com>
// +----------------------------------------------------------------------
namespace Admin\Controller;
use OT\File;
/**
* 在线更新
* @author huajie <banhuajie@163.com>
*/
class UpdateController extends AdminController{
/**
* 初始化页面
* @author huajie <banhuajie@163.com>
*/
public function index(){
$this->meta_title = '在线更新';
if(IS_POST){
$this->display();
//检查新版本
$version = $this->checkVersion();
//在线更新
$this->update($version);
}else{
$this->display();
}
}
/**
* 检查新版本
* @author huajie <banhuajie@163.com>
*/
private function checkVersion(){
if(extension_loaded('curl')){
$url = 'http://www.onethink.cn/index.php?m=home&c=check_version';
$params = array(
'version' => ONETHINK_VERSION,
'domain' => $_SERVER['HTTP_HOST'],
'auth' => sha1(C('DATA_AUTH_KEY')),
);
$vars = http_build_query($params);
//获取版本数据
$data = $this->getRemoteUrl($url, 'post', $vars);
if(!empty($data) && strlen($data)<400 ){
$this->showMsg('发现新版本:'.$data, 'success');
return $data;
}else{
$this->showMsg("未发现新版本", 'error');
exit;
}
}else{
$this->error('请配置支持curl');
}
}
/**
* 在线更新
* @author huajie <banhuajie@163.com>
*/
private function update($version){
//PclZip类库不支持命名空间
import('OT/PclZip');
$date = date('YmdHis');
$backupFile = I('post.backupfile');
$backupDatabase = I('post.backupdatabase');
sleep(1);
$this->showMsg('系统原始版本:'.ONETHINK_VERSION);
$this->showMsg('OneThink在线更新日志');
$this->showMsg('更新开始时间:'.date('Y-m-d H:i:s'));
sleep(1);
/* 建立更新文件夹 */
$folder = $this->getUpdateFolder();
File::mk_dir($folder);
$folder = $folder.'/'.$date;
File::mk_dir($folder);
//备份重要文件
if($backupFile){
$this->showMsg('开始备份重要程序文件...');
G('start1');
$backupallPath = $folder.'/backupall.zip';
$zip = new \PclZip($backupallPath);
$zip->create('Application,ThinkPHP,.htaccess,admin.php,index.php');
$this->showMsg('成功完成重要程序备份,备份文件路径:<a href=\''.__ROOT__.$backupallPath.'\'>'.$backupallPath.'</a>, 耗时:'.G('start1','stop1').'s','success');
}
/* 获取更新包 */
//获取更新包地址
$updatedUrl = 'http://www.onethink.cn/index.php?m=home&c=check_version&a=getDownloadUrl';
$params = array('version' => ONETHINK_VERSION);
$updatedUrl = $this->getRemoteUrl($updatedUrl, 'post', http_build_query($params));
if(empty($updatedUrl)){
$this->showMsg('未获取到更新包的下载地址', 'error');
exit;
}
//下载并保存
$this->showMsg('开始获取远程更新包...');
sleep(1);
$zipPath = $folder.'/update.zip';
$downZip = $this->getRemoteUrl($updatedUrl);
if(empty($downZip)){
$this->showMsg('下载更新包出错,请重试!', 'error');
exit;
}
File::write_file($zipPath, $downZip);
$this->showMsg('获取远程更新包成功,更新包路径:<a href=\''.__ROOT__.ltrim($zipPath,'.').'\'>'.$zipPath.'</a>', 'success');
sleep(1);
/* 解压缩更新包 */ //TODO: 检查权限
$this->showMsg('更新包解压缩...');
sleep(1);
$zip = new \PclZip($zipPath);
$res = $zip->extract(PCLZIP_OPT_PATH,'./');
if($res === 0){
$this->showMsg('解压缩失败:'.$zip->errorInfo(true).'------更新终止', 'error');
exit;
}
$this->showMsg('更新包解压缩成功', 'success');
sleep(1);
/* 更新数据库 */
$updatesql = './update.sql';
if(is_file($updatesql))
{
$this->showMsg('更新数据库开始...');
if(file_exists($updatesql))
{
$Model = M();
$sql = File::read_file($updatesql);
$sql = str_replace("\r\n", "\n", $sql);
foreach(explode(";\n", trim($sql)) as $query)
{
$Model->query(trim($query));
}
}
unlink($updatesql);
$this->showMsg('更新数据库完毕', 'success');
}
/* 系统版本号更新 */
$file = File::read_file(COMMON_PATH.'Common/function.php');
$file = str_replace(ONETHINK_VERSION, $version, $file);
$res = File::write_file(COMMON_PATH.'Common/function.php', $file);
if($res === false){
$this->showMsg('更新系统版本号失败', 'error');
}else{
$this->showMsg('更新系统版本号成功', 'success');
}
sleep(1);
$this->showMsg('##################################################################');
$this->showMsg('在线更新全部完成如有备份请及时将备份文件移动至非web目录下', 'success');
}
/**
* 获取远程数据
* @author huajie <banhuajie@163.com>
*/
private function getRemoteUrl($url = '', $method = '', $param = ''){
$opts = array(
CURLOPT_TIMEOUT => 20,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $url,
CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'],
);
if($method === 'post'){
$opts[CURLOPT_POST] = 1;
$opts[CURLOPT_POSTFIELDS] = $param;
}
/* 初始化并执行curl请求 */
$ch = curl_init();
curl_setopt_array($ch, $opts);
$data = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
return $data;
}
/**
* 实时显示提示信息
* @param string $msg 提示信息
* @param string $class 输出样式success:成功error:失败)
* @author huajie <banhuajie@163.com>
*/
private function showMsg($msg, $class = ''){
echo "<script type=\"text/javascript\">showmsg(\"{$msg}\",\"{$class}\")</script>";
flush();
ob_flush();
}
/**
* 生成更新文件夹名
* @author huajie <banhuajie@163.com>
*/
private function getUpdateFolder(){
$key = sha1(C('DATA_AUTH_KEY'));
return 'update_'.$key;
}
}