Fantasy-field/framework/libraries/Autoupdate.class.php

344 lines
7.7 KiB
PHP
Raw Blame History

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
namespace framework\libraries;
/**
* 幻想领域自动更新
* @author: 阿珏
* @link: http://img.52ecy.cn
*/
class Autoupdate {
/*
* 保存日志
*/
private $_log = false;
/*
* 日志保存路径
*/
public $logFile = 'update.log';
/*
* 最后的错误
*/
private $_lastError = null;
/*
* 当前版本
*/
public $currentVersion = 0;
/*
* 最新版本
*/
public $latestVersion = null;
/*
* 最新版本地址
*/
public $latestUpdate = null;
/*
* 更新服务器地址(带/
*/
public $updateUrl = 'https://img.52ecy.cn/service/';
/*
* 服务器上的版本文件名称
*/
public $updateIni = 'CheckUpdate.php';
/*
* 临时下载目录
*/
public $tempDir = 'temp/';
/*
* 安装完成后删除临时目录
*/
public $removeTempDir = true;
/*
* 安装目录
*/
public $installDir = '';
/**
* 创建新实例
* @param [type] $installDir 安装路径
* @param boolean $log 是否启用日志
*/
public function __construct($installDir,$log = false) {
ini_set('max_execution_time', 600);
$this->_log = $log;
$this->installDir = $installDir;
}
/*
* 日志记录
*
* @param string $message 信息
*/
public function log($message) {
$this->_lastError = $message;
if ($this->_log) {
$log = fopen($this->logFile, 'a');
if ($log) {
$message = date('[Y-m-d H:i:s] ').$message."\r\n";
fputs($log, $message);
fclose($log);
}else {
$this->_lastError = '无法写入日志文件!';
}
}
}
/*
* 获取错误信息
*
* @return string 最后的错误
*/
public function getLastError() {
if (!is_null($this->_lastError))
return $this->_lastError;
else
return '日志尚未开启!';
}
/**
* 删除指定路径下所有文件
* @param [type] $dir 路径
*/
private function _removeDir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir")
// 是路径
$this->_removeDir($dir."/".$object);
else
// 删除文件
unlink($dir."/".$object);
}
}
reset($objects);
rmdir($dir);
}
}
/*
* 检查新版本
*
* @return string 最新版本号
*/
public function checkUpdate() {
$this->log('检查更新. . .');
$updateFile = $this->updateUrl.$this->updateIni;
$update = @file_get_contents($updateFile);
if ($update === false) {
$this->log('无法获取更新文件 -->'.$updateFile);
return false;
}else {
$versions = parse_ini_string($update, true);
if (is_array($versions)) {
$this->log('最新版本号 -->'.$versions[1]['version']);
$this->latestVersion = $versions[1]['version'];
$this->latestUpdate = $versions[1]['url'];
return $versions[1]['version'];
}else {
$this->log('服务端配置文件有误!');
return false;
}
}
}
/*
* 下载更新文件
*
* @param string $updateUrl 更新文件URL
* @param string $updateFile 下载文件保存目录
*/
public function downloadUpdate($updateUrl, $updateFile) {
$this->log('正在下载更新...');
$update = @file_get_contents($updateUrl);
if ($update === false) {
$this->log('无法下载更新 -->'.$updateUrl);
return false;
}
$handle = fopen($updateFile, 'w');
if (!$handle) {
$this->log('无法保存更新文件 -->'.$updateFile);
return false;
}
if (!fwrite($handle, $update)) {
$this->log('无法写入更新文件 -->'.$updateFile);
return false;
}
fclose($handle);
return true;
}
/*
* 安装更新文件
*
* @param string $updateFile 更新文件路径
*/
private function install($updateFile) {
$zip = zip_open($updateFile);
while ($file = zip_read($zip)) {
$filename = zip_entry_name($file);
$foldername = $this->installDir.dirname($filename);
$this->log('更新中 -->'. $filename);
if (!is_dir($foldername)) {
if (!mkdir($foldername, 0755, true)) {
$this->log('无法创建目录 -->'.$foldername);
}
}
$contents = zip_entry_read($file, zip_entry_filesize($file));
//跳过目录
if (substr($filename, -1, 1) == '/')
continue;
//写入文件
if (file_exists($this->installDir.$filename)) {
if (!is_writable($this->installDir.$filename)) {
$this->log('无法更新 -->'.$this->installDir.$filename.' 不可写入!');
return false;
}
} else {
$this->log('文件 -->'.$this->installDir.$filename.' 不存在!');
$new_file = fopen($this->installDir.$filename, "w") or $this->log('文件 -->'.$this->installDir.$filename.' 不能创建!');
fclose($new_file);
$this->log('文件 -->'.$this->installDir.$filename.' 创建成功.');
}
$updateHandle = @fopen($this->installDir.$filename, 'w');
if (!$updateHandle) {
$this->log('无法更新文件 -->'.$this->installDir.$filename);
return false;
}
if (!fwrite($updateHandle, $contents)) {
$this->log('无法写入文件 -->'.$this->installDir.$filename);
return false;
}
fclose($updateHandle);
}
zip_close($zip);
if ($this->removeTempDir) {
$this->log('临时目录 -->'.$this->tempDir.' 被删除');
$this->_removeDir($this->tempDir);
}
$this->log('更新 -->'.$this->latestVersion.' 安装完成');
return true;
}
/*
* 更新最新版本
*/
public function update() {
//检查最新版本
if ((is_null($this->latestVersion)) or (is_null($this->latestUpdate))) {
$this->checkUpdate();
}
if ((is_null($this->latestVersion)) or (is_null($this->latestUpdate))) {
return false;
}
//开始更新
if ($this->latestVersion > $this->currentVersion) {
$this->log('开始更新....');
//排除文件
if ($this->tempDir[strlen($this->tempDir)-1] != '/');
$this->tempDir = $this->tempDir.'/';
if ((!is_dir($this->tempDir)) and (!mkdir($this->tempDir, 0777, true))) {
$this->log('临时目录 -->'.$this->tempDir.' 不存在并且无法创建!');
return false;
}
if (!is_writable($this->tempDir)) {
$this->log('临时目录 -->'.$this->tempDir.' 不可写入!');
return false;
}
$updateFile = $this->tempDir.$this->latestVersion.'.zip';
$updateUrl = $this->latestUpdate;
//下载更新
if (!is_file($updateFile)) {
if (!$this->downloadUpdate($updateUrl, $updateFile)) {
$this->log('无法下载更新!');
return false;
}
$this->log('最新更新下载 -->'.$updateFile);
}else {
$this->log('最新更新下载到 -->'.$updateFile);
}
//解压
return $this->install($updateFile);
}else {
$this->log('没有可用更新!');
return false;
}
}
/**
* 替换旧文件
*/
public function replaceupdate(){
if(is_dir($this->installDir)){
@unlink($this->installDir.'Fantasy-field-master/install.php');
@unlink($this->installDir.'Fantasy-field-master/config.php');
@unlink($this->installDir.'Fantasy-field-master/application/config.php');
}else{
$this->log('文件效验失败!');
return false;
}
$this->recurse_rename($this->installDir.'Fantasy-field-master',$this->installDir);
return true;
}
/**
* 移动程序文件替换旧版本
* @param [type] $src 原目录
* @param [type] $dst 移动到的目录
*/
private function recurse_rename($src,$dst) {
$dir = opendir($src);
@mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
$this->recurse_rename($src . '/' . $file,$dst . '/' . $file);
} else {
rename($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
}