<?php
defined('IN_YUNYECMSAdmin') or exit('No permission.');
core::load_admin_class('admin');
class autoupdate extends YUNYE_admin
{
	private $server;
	private $PostHash;
	function __construct()
	{
		parent::__construct();
		$this->server = yunyecms_strdecode("YmM0OWM5ZWY1ODk5ZGRkNzM0YUhSMGNEb3ZMM2QzZHk1NWRXNTVaV050Y3k1amIyMD04ZDdlNzk5NTliNDQyYTI1ZDE0ZWUzODZmZDI4MzY5OTM0YQ==");
		$this->PostHash = GetyunyecmsHash();
	}
	//加载首页
	public function init()
	{
		if (!getroot('lang', 'view')) {
			messagebox(Lan('no_permission_langview'), 'back', "warn");
		}
		$parnav = '<li class=\"breadcrumb-item\"><a href=\"' . url_admin('init', "autoupdate") . '\" target=\"maincontent\">系统</a></li><li class=\"breadcrumb-item\"><a href=\"' . url_admin('init', 'autoupdate') . '\" target=\"maincontent\">自动更新</a></li><li class=\"breadcrumb-item active\">自动更新</li>';
		if (!getroot('users', 'logs')) {
			messagebox(Lan('no_permission'), 'back', "warn");
		}
		require tpl_adm('autoupdate');
	}

	public function upgrade()
	{
		if (!empty($_POST['step'])) {
			$step = usafestr($_POST['step']);
		} else {
			$msg['code'] = "100";
			$msg['desc'] = "参数错误";
			$msg['step'] = $step;
			exit(json_encode($msg));
		}
		if (!getroot('autoupgrade', 'upgrade')) {
			$msg['code'] = "111";
			$msg['desc'] = "您没有安装自动更新的权限，请联系管理员";
			exit(json_encode($msg));
		}
		if (!empty($_POST['para'])) {
			$para = usafestr($_POST['para']);
		}
		if (!function_exists('gzopen') || !extension_loaded('zip')) {
			$msg['code'] = "109";
			$msg['desc'] = "您的服务器不支持ZIP模块，请联系管理员";
			exit(json_encode($msg));
		}
		$docroot = $this->getdocroot();
		if ($step == "getpackage") {
			$remoteurl = "{$this->server}/index.php?m=version&c=index&a=getpackage";
			$postdata["version"] = YUNYECMS_VER;
			$postdata["token"] = "yunyecms_upgrade";
			$remotedata = curl_post($remoteurl, $postdata);
			$remotedata = yunyecms_json_decode($remotedata);
			$upgrade_file = $remotedata['upgrade_file'];
			$upgrade_sql = $remotedata['upgrade_sql'];
			$upkfile_md5 = $remotedata['upkfile_md5'];
			$sql_md5 = $remotedata['sql_md5'];
			$msg['loaded'] = "<label class='info' id='upgrade_loading'>正在升级中 <i class='fa fa-spin fa-refresh'></i></label>";
			if (empty($upgrade_file)) {
				$msg['code'] = "101";
				$msg['desc'] = "升级文件不存在！";
			} else {
				$upgrade_local_file = Get_RemoteFile($upgrade_file, UPGRADE_ROOT, $upkfile_md5);
				if (!$upgrade_local_file) {
					$msg['code'] = "102";
					$msg['desc'] = "下载升级包失败！";
				} else {
					$file = str_replace('\\', '/', str_ireplace($docroot, '', $upgrade_local_file));
					$msg['code'] = "103";
					$msg['step'] = "upzip";
					$msg['para'] = GetFileName($upgrade_file);
					$msg['desc'] = "成功下载升级包文件{$file}！";
				}
			}
		} elseif ($step == "upzip") {
			if ($para) {
				$zipfile = UPGRADE_ROOT . $para;
				$zip = new ZipArchive(); //新建一个ZipArchive的对象
				if ($zip->open($zipfile) != true) {
					$msg['code'] = "111";
					$msg['desc'] = "升级包{$para}读取失败！";
					exit(json_encode($msg));
				}
				$extractpath = UPGRADE_ROOT . RemoveFileext($para);
				$zip->extractTo($extractpath);
				$zip->close(); //关闭处理的zip文件
				$msg['code'] = "112";
				$msg['step'] = "backupSource";
				$msg['para'] = RemoveFileext($para);
				$msg['desc'] = "成功解压升级包{$para}！";
			}
		} elseif ($step == "backupSource") {
			if ($para) {
				$extractpath = ToBackslash(UPGRADE_ROOT . $para);
				if (is_dir($extractpath)) {
					$upgradefiles = getDir($extractpath);
					foreach ($upgradefiles as $key => $var) {
						$pathfile = ToBackslash(str_ireplace($extractpath, '', ToBackslash($var)));
						if (substr($pathfile, 0, 1) == "/") {
							$pathfile = substr($pathfile, 1);
						}
						$sourcefile = YUNYECMS_ROOT . $pathfile;
						if (is_file($sourcefile)) {
							$backupSourcefile = $extractpath . "_old" . DIRECTORY_SEPARATOR . $pathfile;
							dir_create(dirname($backupSourcefile));
							$retcopy = @copy($sourcefile, $backupSourcefile);
						}
					}
				}
				$msg['code'] = "120";
				$msg['step'] = "upgradeSource";
				$msg['para'] = $para . ".zip";
				$msg['desc'] = "成功备份源文件至" . str_ireplace($docroot, '', $extractpath) . "_old 目录";
			}
		} elseif ($step == "upgradeSource") {
			if ($para) {
				$zipfile = UPGRADE_ROOT . $para;
				$zipfile_path = UPGRADE_ROOT . RemoveFileext($para);
				//$zipfilepath=ROOT."data/backup".DIRECTORY_SEPARATOR.$para;
				$zip = new ZipArchive(); //新建一个ZipArchive的对象
				if ($zip->open($zipfile) != true) {
					$msg['code'] = "131";
					$msg['desc'] = "升级包{$para}读取失败！";
					exit(json_encode($msg));
				}
				$zip->extractTo(YUNYECMS_ROOT);
				$zip->close(); //关闭处理的zip文件
				$ret = file_delete($zipfile, 1);
				$retdir = dir_delete($zipfile_path);
				$msg['code'] = "132";
				$msg['step'] = "getsqlpackage";
				$msg['desc'] = "<span class='text-red'>成功升级程序文件！</span><br/>删除更新包" . ToBackslash(str_ireplace($docroot, '', $zipfile)) . "成功！<br/> 请稍等片刻，更新程序正在检测数据库更新......";
			}
		} elseif ($step == "getsqlpackage") {
			$remoteurl = "{$this->server}/index.php?m=version&c=index&a=getpackage";
			$postdata["version"] = YUNYECMS_VER;
			$postdata["token"] = "yunyecms_upgrade";
			$remotedata = curl_post($remoteurl, $postdata);
			$remotedata = yunyecms_json_decode($remotedata);
			$upgrade_sql = $remotedata['upgrade_sql'];
			$sql_md5 = $remotedata['sql_md5'];
			if ($upgrade_sql && $sql_md5) {
				$msg['loaded'] = "<label class='info' id='upgrade_sql_loading'>正在升级数据库 <i class='fa fa-spin fa-refresh'></i></label>";
			}
			if (empty($upgrade_sql)) {
				$msg['code'] = "141";
				$msg['desc'] = "本次更新无需更改数据库！";
				$msg['step'] = "setlocalver";
			} else {
				$upgrade_local_sqlfile = Get_RemoteFile($upgrade_sql, UPGRADE_ROOT, $sql_md5);
				if (!$upgrade_local_sqlfile) {
					$msg['code'] = "142";
					$msg['desc'] = "下载数据库文件失败！";
					exit(json_encode($msg));
				} else {

					$sqlfile = str_replace('\\', '/', str_ireplace($docroot, '', $upgrade_local_sqlfile));
					$sqlfilename = GetFileName($upgrade_sql);
					$zipfile = $upgrade_local_sqlfile;
					$zip = new ZipArchive();
					if ($zip->open($zipfile) != true) {
						$msg['code'] = "143";
						$msg['desc'] = "数据库升级包{$sqlfilename}读取失败！";
						exit(json_encode($msg));
					}
					$extractpath = UPGRADE_ROOT . RemoveFileext($sqlfilename);
					$zip->extractTo($extractpath);
					$zip->close();
					$msg['code'] = "144";
					$msg['step'] = "upgradesql";
					$msg['para'] = RemoveFileext($sqlfilename);
					$msg['desc'] = "成功下载数据库升级包文件{$sqlfile}！";
				}
			}
		} elseif ($step == "upgradesql") {
			if ($para) {
				$extractpath = ToBackslash(UPGRADE_ROOT . $para);
				if (is_dir($extractpath)) {
					$upgradesqlfiles = getDir($extractpath);
					foreach ($upgradesqlfiles as $key => $var) {
						$sqldata = file_get_contents(ToBackslash($var));
						global $yunyecms_dbconfig;
						$dbpre = $yunyecms_dbconfig['tablepre'];
						$this->sql_execute($sqldata, $dbpre);
					}
					$msg['code'] = "151";
					$msg['step'] = "setlocalver";
					$msg['desc'] = "成功升级数据库！";
				}
				$zipsqlfile = UPGRADE_ROOT . $para . ".zip";
				$zipsqlfile_path = UPGRADE_ROOT . $para;
				$ret = file_delete($zipsqlfile, 1);
				$retdir = dir_delete($zipsqlfile_path);
			}
		} elseif ($step == "setlocalver") {
			$remoteurl = "{$this->server}/index.php?m=version&c=index&a=getpackage";
			$postdata["version"] = YUNYECMS_VER;
			$postdata["token"] = "yunyecms_upgrade";
			$remotedata = curl_post($remoteurl, $postdata);
			$remotedata = yunyecms_json_decode($remotedata);
			$upgrade_sql = $remotedata['upgrade_sql'];
			$sql_md5 = $remotedata['sql_md5'];
			$version_num = usafestr($remotedata["version_num"]);
			if (!is_numeric($version_num)) {
				$msg['code'] = "161";
				$msg['step'] = "";
				$msg['desc'] = "更新版本号出错！";
				exit(json_encode($msg));
			} else {
				if ($this->check_version($version_num)) {
					$msg['code'] = "161";
					$msg['step'] = "";
					$msg['desc'] = "更新版本号出错,该版本已存在！";
					exit(json_encode($msg));
				}
				$data["version_num"] = $version_num;
			}
			$data["version_num_old"] = YUNYECMS_VER;
			$data["vid"] = usafestr($remotedata["id"]);
			$data["vtid"] = usafestr($remotedata["vid"]);
			$data["upgrade_sql"] = uhtmlspecialchars($remotedata["upgrade_sql"]);
			$data["upgrade_file"] = uhtmlspecialchars($remotedata["upgrade_file"]);
			$data["upkfile_md5"] = usafestr($remotedata["upkfile_md5"]);
			$data["sql_md5"] = usafestr($remotedata['sql_md5']);
			$data["version_time"] = usafestr($remotedata['version_time']);
			$data["build_time"] = usafestr($remotedata['build_time']);
			$upgrade_file_name = GetFileName($data["upgrade_file"]);
			$data["oldver_backup"] = str_ireplace($docroot, '', ToBackslash(UPGRADE_ROOT . RemoveFileext($upgrade_file_name))) . "_old";
			$data["remark"] = "升级信息：<br/>升级时间：" . udate(time()) . " <br/> 旧版本：" . YUNYECMS_VERSION . "<br/>新版本：" . formatver($version_num) . "<br/>旧版本备份目录:" . $data["oldver_backup"];
			$data["soft_type"] = usafestr($remotedata["soft_type"]);
			$data["soft_name"] = usafestr($remotedata["soft_name"]);
			$data["addtime"] = time();
			$data["status"] = 1;
			$retres = $this->db->insert($data, 'version');
			if ($retres) {
				$doing = "自动更新—(" . YUNYECMS_VERSION . " 升级到 " . formatver($version_num) . ")";
				$yyact = "upgrade_version";
				insert_admlogs($doing, $yyact);
				$msg['code'] = "999";
				$msg['step'] = "";
				$msg['desc'] = "<span class='text-red'>成功更新版本信息，您已升级至" . formatver($version_num) . "版本！</span>";
			} else {
				$msg['code'] = "163";
				$msg['step'] = "";
				$msg['desc'] = "更新版本号出错！";
			}
		} else {
			$msg['desc'] = "升级完成！";
			$msg['step'] = "";
			$msg['code'] = "999";
		}
		exit(json_encode($msg));
	}

	public function getver()
	{
		//获取官方最新版本
		$remoteurl = "{$this->server}/index.php?m=version&c=index&a=getver";
		$postdata = array();
		$remotedata = curl_post($remoteurl, $postdata);
		$remotedata = yunyecms_json_decode($remotedata);
		$soft_type = $remotedata["soft_type"];
		$version_time = $remotedata["version_time"];
		$build_time = $remotedata["build_time"];
		$soft_name = $remotedata["soft_name"];
		$version_num = $remotedata["version_num"];
		$version_name = formatver($remotedata["version_num"]);
		$downurl = $remotedata["downurl"];
		$verdetail = "{$this->server}/index.php?a=detail&c=index&m=version&id={$remotedata["vid"]}";
		if ($remotedata["content"]) $remote_content = uhtmlspecialchars_decode($remotedata["content"]);
		$ver_time = getsofttime($soft_type, $version_time, $build_time);
		$ver_name = strtoupper($version_name);
		//$guanfang_ver=empty($remotedata["version_time"])?$ver_name:$ver_name."_".$ver_time;
		$cur_ver = getversion(YUNYECMS_SOFT_TYPE, strtoupper(YUNYECMS_VERSION), strtotime(YUNYECMS_VERSION_TIME), strtotime(YUNYECMS_BUILD_TIME));
		$guanfang_ver = getversion($soft_type, $version_name, $version_time, $build_time);
		if (YUNYECMS_SOFT_TYPE == 1) {
			$cur_ver_time = YUNYECMS_VERSION_TIME;
		} elseif (YUNYECMS_SOFT_TYPE == 2) {
			$cur_ver_time = YUNYECMS_BUILD_TIME;
		} else {
			$cur_ver_time = YUNYECMS_VERSION_TIME;
		}
		if ($version_num == YUNYECMS_VER) {
			$ver_isnew = 0;
			$verdata["cur_ver"] = $cur_ver . "&nbsp;&nbsp;<span class='text-red'> <br/>您的程序已经是最新版</span>&nbsp;&nbsp;";
		} else {
			$ver_isnew = 1;
			$verdata["cur_ver"] = $cur_ver . "&nbsp;&nbsp;<span class='text-red'> <br/>官方新版：<a href='{$verdetail}' class='btn btn-danger btn-sm btn-flat' target='_blank'>{$guanfang_ver} </a></span>&nbsp;&nbsp; <a href='javascript:;' class='btn btn-info btn-sm btn-flat'  onclick='javascript:upgrade(\"getpackage\");'> <i class='fa fa-cloud-upload'></i> 去升级 </a>";
			$verdata["ver_content"] = "<br/> 更新信息：<br/> {$remote_content}";
		}
		$verdata["ver_isnew"] = $ver_isnew;
		//$verdata["guanfang_ver"]=$guanfang_ver;
		exit(json_encode($verdata));
	}


	private function sql_execute($sql, $tablepre)
	{
		$sqls = $this->sql_split($sql, $tablepre);
		if (is_array($sqls)) {
			foreach ($sqls as $sql) {
				if (trim($sql) != '') {
					try {
						@$this->db->query($sql, false);
					} catch (Exception $e) {
						echo '异常：' . $e->getMessage() . '<br>错误代码：' . $e->getCode() . '<br>';
					}
				}
			}
		} else {
			@$this->db->query($sqls, false);
		}
		return true;
	}

	private function  sql_split($sql, $tablepre)
	{
		if ($tablepre != "yunyecms_") $sql = str_ireplace("yunyecms_", $tablepre, $sql);
		$sql = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=utf8", $sql);
		//if($r_tablepre != $s_tablepre) $sql = str_replace($s_tablepre, $r_tablepre, $sql);
		$sql = str_replace("\r", "\n", $sql);
		$ret = array();
		$num = 0;
		$queriesarray = explode(";\n", trim($sql));
		unset($sql);
		foreach ($queriesarray as $query) {
			$ret[$num] = '';
			$queries = explode("\n", trim($query));
			$queries = array_filter($queries);
			foreach ($queries as $query) {
				$str1 = substr($query, 0, 1);
				if ($str1 != '#' && $str1 != '-') $ret[$num] .= $query;
			}
			$num++;
		}
		return $ret;
	}

	private function getdocroot()
	{
		$doc_root = $_SERVER['DOCUMENT_ROOT'];
		if (!empty($doc_root) && substr($doc_root, -1) == "/") {
			$doc_root = substr($doc_root, 0, -1);
		}
		if (strpos($doc_root, "\\")) {
			$doc_root = str_ireplace('\\', '/', $doc_root);
		}
		return $doc_root;
	}


	public function uplist()
	{
		if (!getroot('shop', 'ordersview')) {
			messagebox(Lan('no_permission'), 'back', "warn");
		}
		$parnav = '<li class=\"breadcrumb-item\"><a href=\"' . url_admin('init', "lang") . '\" target=\"maincontent\">系统</a></li><li class=\"breadcrumb-item\"><a href=\"' . url_admin('init', 'autoupdate') . '\" target=\"maincontent\">自动更新</a></li><li class=\"breadcrumb-item active\">更新记录</li>';
		$pagesize = 20;
		$sqlquery = "select * from `#yunyecms_version`  ";
		$where = " where version_num>0 ";
		$sqlcnt = " select count(*) from `#yunyecms_version` ";
		$order = " order by `version_num` desc,`id` desc ";
		if (isset($_REQUEST)) {
			if (!empty($_REQUEST["searchkey"])) {
				$searchkey = usafestr(trim($_REQUEST["searchkey"]));
				$where = $where . " and `version_num`  = '{$searchkey}' ";
			}
		}
		$pagearr = $this->db->pagelist($sqlcnt, $sqlquery, $where, $order, $pagesize);
		if ($pagearr["count"] != 0) {
			$list = $pagearr["query"];
			foreach ($list as $key => $var) {
				$soft_type = $var["soft_type"];
				$version_name = formatver($var["version_num"]);
				$version_time = $var["version_time"];
				$build_time = $var["build_time"];
				$list[$key]["ver_name"] = $version_name;
				$list[$key]["old_ver_name"] = formatver($var["version_num_old"]);
				$list[$key]["softname"] = getsoftname($soft_type, $version_name, $version_time, $build_time);
				$list[$key]["softtime"] = getsofttime($soft_type, $version_time, $build_time);
				$list[$key]["version"] = getversion($soft_type, $version_name, $version_time, $build_time);
				$list[$key]["softtype"] = getsofttype($soft_type);
			}

			$page = $pagearr["page"];
		}
		require tpl_adm('upgrade_list');
	}


	public function delbak()
	{
		$id = $_REQUEST["id"];
		$id = usafestr($id);
		if (!getroot('autoupgrade', 'del')) {
			messagebox("您没有删除更新备份文件权限，请联系管理员！", 'back', "warn");
		}
		if (is_numeric($id) && !empty($id)) {
			$cur_version = $this->db->getbyid($id, 'version');
			$oldver_backup = $cur_version['oldver_backup'];
			if ($oldver_backup) {
				if (substr($oldver_backup, 0, 1) == "/") $oldver_backup = substr($oldver_backup, 1);
				$todel_dir = YUNYECMS_ROOT . $oldver_backup;
				if (is_dir($todel_dir)) {
					$retdir = dir_delete($todel_dir);
				} else {
					messagebox("该备份文件夹已经删除过了！", 'back', "warn");
				}
			}
			if ($retdir !== false) {
				$yyact = "oldver_backup_Del";
				$logcontent['tablename'] = "version";
				$logcontent['action'] = $yyact;
				$logcontent['ids'] = serialize($id);
				$logcontent = serialize($logcontent);
				$doing = "删除旧版本备份目录：{$oldver_backup} ";
				insert_admlogs($doing, $yyact, $logcontent);
				messagebox('删除旧版本备份目录成功！', url_admin('uplist'), "success");
			} else {
				messagebox(Lan('admin_delete_error'), url_admin('uplist'), "warn");
			}
		} else {
			messagebox("错误的参数！", 'back', "warn");
		}
	}





	private function check_exist($id)
	{
		$id = trim($id);
		if (empty($id)) {
			return false;
		} else {
			if (!is_numeric($id)) {
				return false;
			}
			if ($this->db->find("select count(*) as cnt from `#yunyecms_lang` where `id`= {$id}")) {
				return true;
			}
		}
	}

	private function check_version($version_name)
	{
		$version_name = usafestr(trim($version_name));
		if (empty($version_name)) {
			return false;
		} else {
			$cntcheckone = $this->db->GetCount("select count(*) from `#yunyecms_version` where  `version_num`='$version_name' ");
			if ($cntcheckone >= 1) {
				return true;
			} else {
				return false;
			}
		}
	}
}
