diff --git a/config/zentaopms.php b/config/zentaopms.php
index 21556a4d39..97c9b578c8 100644
--- a/config/zentaopms.php
+++ b/config/zentaopms.php
@@ -199,6 +199,7 @@ $config->openMethods[] = 'misc.ping';
$config->openMethods[] = 'misc.captcha';
$config->openMethods[] = 'misc.features';
$config->openMethods[] = 'misc.getremind';
+$config->openMethods[] = 'misc.checknetconnect';
$config->openMethods[] = 'sso.login';
$config->openMethods[] = 'sso.logout';
$config->openMethods[] = 'sso.bind';
diff --git a/module/misc/control.php b/module/misc/control.php
index e5652f241c..55dcf81c89 100644
--- a/module/misc/control.php
+++ b/module/misc/control.php
@@ -210,12 +210,13 @@ class misc extends control
* Check net connect.
*
* @access public
- * @return string
+ * @return void
*/
- public function checkNetConnect(): string
+ public function checkNetConnect(): void
{
$this->app->loadConfig('extension');
- $check = @fopen(dirname($this->config->extension->apiRoot), "r");
+ $context = stream_context_create(array("ssl" => array("verify_peer" => false, "verify_peer_name" => false)));
+ $check = @fopen(dirname($this->config->extension->apiRoot), "r", false, $context);
print($check ? 'success' : 'fail');
}
diff --git a/module/upgrade/control.php b/module/upgrade/control.php
index 8e5d181a61..1a0cd8356c 100644
--- a/module/upgrade/control.php
+++ b/module/upgrade/control.php
@@ -847,6 +847,38 @@ class upgrade extends control
return print(json_encode(array('log' => str_replace("\n", "
", $log) . ($log ? '
' : ''), 'progress' => $progress, 'offset' => $offset + strlen($log))));
}
+ /**
+ * Ajax get fix consistency logs.
+ *
+ * @param int $offset
+ * @access public
+ * @return void
+ */
+ public function ajaxGetFixLogs($offset = 0)
+ {
+ $logFile = $this->upgrade->getConsistencyLogFile();
+ $lines = !file_exists($logFile) ? array() : file($logFile);
+
+ $log = array_slice($lines, $offset);
+ $finished = ($log and end($log) == 'Finished') ? true : false;
+
+ return print(json_encode(array('log' => implode("
", $log), 'finished' => $finished, 'offset' => count($lines))));
+ }
+
+ /**
+ * Ajax fix for consistency.
+ *
+ * @param string $version
+ * @access public
+ * @return void
+ */
+ public function ajaxFixConsistency($version)
+ {
+ set_time_limit(0);
+ session_write_close();
+ $this->upgrade->fixConsistency($version);
+ }
+
/**
* Get the project of the program it belongs to.
*
@@ -900,8 +932,14 @@ class upgrade extends control
$alterSQL = $this->upgrade->checkConsistency($this->config->version);
if(!empty($alterSQL))
{
+ $logFile = $this->upgrade->getConsistencyLogFile();
+ $hasError = $this->upgrade->hasConsistencyError();
+ if(file_exists($logFile)) unlink($logFile);
+
$this->view->title = $this->lang->upgrade->consistency;
+ $this->view->hasError = $hasError;
$this->view->alterSQL = $alterSQL;
+ $this->view->version = $this->config->version;
return $this->display('upgrade', 'consistency');
}
@@ -953,9 +991,11 @@ class upgrade extends control
*/
public function consistency($netConnect = true)
{
- set_time_limit(0);
+ $logFile = $this->upgrade->getConsistencyLogFile();
+ $hasError = $this->upgrade->hasConsistencyError();
+ if(file_exists($logFile)) unlink($logFile);
+
$alterSQL = $this->upgrade->checkConsistency();
- $alterSQL = str_replace('ENGINE=MyISAM', 'ENGINE=InnoDB', $alterSQL);
if(empty($alterSQL))
{
if(!$netConnect) $this->locate(inlink('selectVersion'));
@@ -963,7 +1003,9 @@ class upgrade extends control
}
$this->view->title = $this->lang->upgrade->consistency;
+ $this->view->hasError = $hasError;
$this->view->alterSQL = $alterSQL;
+ $this->view->version = $this->config->installedVersion;
$this->display();
}
diff --git a/module/upgrade/js/backup.ui.js b/module/upgrade/js/backup.ui.js
index 43f954392b..3e59952cd5 100644
--- a/module/upgrade/js/backup.ui.js
+++ b/module/upgrade/js/backup.ui.js
@@ -1,17 +1,14 @@
-$(function()
+$.ajax(
{
- $.ajax(
+ url: $.createLink('misc', 'checkNetConnect'),
+ timeout: 3000,
+ success: function(data)
{
- url: $.createLink('misc', 'checkNetConnect'),
- timeout: 3000,
- success: function(data)
- {
- if(data == 'fail') $('.btn.primary.disabled').attr('onclick', "self.location.href=\"" + $.createLink('upgrade', 'consistency', "netConnect=0") + "\"");
- $('.btn.primary.disabled').removeClass('disabled');
- },
- error: function(XMLHttpRequest, textStatus)
- {
- $('.btn.primary.disabled').attr('onclick', "self.location.href=\"" + $.createLink('upgrade', 'consistency', "netConnect=0") + "\"").removeClass('disabled');
- }
- });
+ if(data == 'fail') $('.btn.primary.disabled').attr('onclick', "self.location.href=\"" + $.createLink('upgrade', 'consistency', "netConnect=0") + "\"");
+ $('.btn.primary.disabled').removeClass('disabled');
+ },
+ error: function(XMLHttpRequest, textStatus)
+ {
+ $('.btn.primary.disabled').attr('onclick', "self.location.href=\"" + $.createLink('upgrade', 'consistency', "netConnect=0") + "\"").removeClass('disabled');
+ }
});
diff --git a/module/upgrade/js/consistency.ui.js b/module/upgrade/js/consistency.ui.js
new file mode 100644
index 0000000000..33c9645c0d
--- /dev/null
+++ b/module/upgrade/js/consistency.ui.js
@@ -0,0 +1,29 @@
+function updateProgressInterval()
+{
+ $.get($.createLink('upgrade', 'ajaxFixConsistency', 'version=' + version));
+ showLogs(0);
+}
+
+function showLogs(logOffset)
+{
+ var url = $.createLink('upgrade', 'ajaxGetFixLogs', 'offset=' + logOffset);
+ $.getJSON(url, function(result)
+ {
+ logOffset = result.offset;
+
+ if(result.log) $('#logBox').append(result.log);
+
+ let element = document.getElementById('logBox');
+ element.scrollTop = element.scrollHeight;
+
+ if(result.finished)
+ {
+ loadCurrentPage();
+ return;
+ }
+
+ showLogs(logOffset);
+ })
+}
+
+if(execFixSQL) updateProgressInterval()
diff --git a/module/upgrade/lang/zh-cn.php b/module/upgrade/lang/zh-cn.php
index 3b6de84b7d..5f8dbbe275 100644
--- a/module/upgrade/lang/zh-cn.php
+++ b/module/upgrade/lang/zh-cn.php
@@ -68,7 +68,8 @@ $lang->upgrade->sureExecute = '确认执行';
$lang->upgrade->upgradingTips = '正在升级中,请耐心等待,切勿刷新页面、断电、关机!';
$lang->upgrade->forbiddenExt = '以下插件与新版本不兼容,已经自动禁用:';
$lang->upgrade->updateFile = '需要更新附件信息。';
-$lang->upgrade->noticeSQL = '检查到你的数据库跟标准不一致,尝试修复失败。请执行以下SQL语句,再刷新页面检查。';
+$lang->upgrade->showSQLLog = '检查到你的数据库跟标准不一致,正在尝试修复。以下是修复SQL语句。';
+$lang->upgrade->noticeErrSQL = '检查到你的数据库跟标准不一致,尝试修复失败。请手动执行以下SQL语句,再刷新页面检查。';
$lang->upgrade->afterDeleted = '请执行上面命令删除文件, 删除后刷新!';
$lang->upgrade->afterExec = '请根据以上报错信息手动修改数据库,修改后刷新!';
$lang->upgrade->mergeProgram = '数据迁移';
diff --git a/module/upgrade/model.php b/module/upgrade/model.php
index 55d6ba6eef..0780702710 100644
--- a/module/upgrade/model.php
+++ b/module/upgrade/model.php
@@ -997,29 +997,90 @@ class upgradeModel extends model
}
elseif($line != $fields[$field])
{
+ $stdConfigs = explode(' ', $line);
+ $dbConfigs = explode(' ', $fields[$field]);
+
+ if($stdConfigs[1] != $dbConfigs[1])
+ {
+ $stdType = $stdConfigs[1];
+ $dbType = $dbConfigs[1];
+ $stdLength = 0;
+ $dbLength = 0;
+
+ preg_match_all('/^(\w+)(\((\d+)\))?$/', $stdConfigs[1], $stdOutput);
+ if(!empty($stdOutput[1][0])) $stdType = $stdOutput[1][0];
+ if(!empty($stdOutput[3][0])) $stdLength = $stdOutput[3][0];
+
+ preg_match_all('/^(\w+)(\((\d+)\))?$/', $dbConfigs[1], $dbOutput);
+ if(!empty($dbOutput[1][0])) $dbType = $dbOutput[1][0];
+ if(!empty($dbOutput[3][0])) $dbLength = $dbOutput[3][0];
+
+ $stdIsInt = stripos($stdType, 'int') !== false;
+ $stdIsVarchar = stripos($stdType, 'varchar') !== false;
+ $stdIsText = stripos($stdType, 'text') !== false;
+ $dbIsInt = stripos($dbType, 'int') !== false;
+ $dbIsVarchar = stripos($dbType, 'varchar') !== false;
+ $dbIsText = stripos($dbType, 'text') !== false;
+
+ if($dbLength > $stdLength) $stdConfigs[1] = $dbConfigs[1];
+ if($stdIsInt && $dbIsText) $stdConfigs[1] = $dbConfigs[1];
+ if($stdIsVarchar && $dbIsText) $stdConfigs[1] = $dbConfigs[1];
+ if($stdIsText && $dbIsText)
+ {
+ if($stdType == 'text' && in_array($dbType, array('mediumtext', 'longtext'))) $stdConfigs[1] = $dbConfigs[1];
+ if($stdType == 'mediumtext' && $dbType == 'longtext') $stdConfigs[1] = $dbConfigs[1];
+ }
+ if(stripos($stdConfigs[1], 'int') === false && $stdConfigs[2] == 'unsigned') unset($stdConfigs[2]);
+ $line = implode(' ', $stdConfigs);
+ if($line == $fields[$field]) continue;
+ }
+
$execSQL = "ALTER TABLE `$table` CHANGE $field $line";
}
if($execSQL)
{
- if(stripos($execSQL, 'auto_increment') !== false) $execSQL .= ' primary key';
+ if(stripos($execSQL, 'auto_increment') !== false) $execSQL .= ' FIRST';
$alterSQL[] = "$execSQL";
}
}
}
- if(count($alterSQL) > 100) return implode(";\n", $alterSQL);
- foreach($alterSQL as $i => $execSQL)
+ return implode(";\n", $alterSQL);
+ }
+
+ /**
+ * Exec fix sql for consistency.
+ *
+ * @param string $version
+ * @access public
+ * @return void
+ */
+ public function fixConsistency($version)
+ {
+ $logFile = $this->getConsistencyLogFile();
+ if(file_exists($logFile)) unlink($logFile);
+
+ $hasError = false;
+ $fixSqls = $this->checkConsistency($version);
+ if($fixSqls) $fixSqls = "SET @@sql_mode= '';" . $fixSqls;
+ foreach(explode(';', $fixSqls) as $fixSQL)
{
+ file_put_contents($logFile, $fixSQL, FILE_APPEND);
try
{
- $this->dbh->exec($execSQL);
- unset($alterSQL[$i]);
+ $this->dbh->exec($fixSQL);
+ }
+ catch(PDOException $e)
+ {
+ $hasError = true;
+ file_put_contents($logFile, $e->getMessage() . "\n", FILE_APPEND);
}
- catch(PDOException $e){}
}
- return implode(";\n", $alterSQL);
+ $finishTag = "\nFinished";
+ if($hasError) $finishTag = "\nHasError" . $finishTag;
+ file_put_contents($logFile, $finishTag, FILE_APPEND);
}
/**
@@ -2751,6 +2812,17 @@ class upgradeModel extends model
return $errors;
}
+ /**
+ * Get upgrade log file.
+ *
+ * @access public
+ * @return string
+ */
+ public function getConsistencyLogFile()
+ {
+ return $this->app->getTmpRoot() . 'log/consistency.' . date('Ymd') . '.log.php';
+ }
+
/**
* Get upgrade log file.
*
@@ -9304,4 +9376,23 @@ class upgradeModel extends model
{
touch($this->app->getCacheRoot() . 'restartcron');
}
+
+ public function hasConsistencyError()
+ {
+ $logFile = $this->getConsistencyLogFile();
+ if(!file_exists($logFile)) return false;
+
+ $lastTwoLines = array(0 =>'', 1 => '');
+
+ $fh = fopen($logFile, 'r');
+ while(!feof($fh))
+ {
+ $lastTwoLines[0] = $lastTwoLines[1];
+ $lastTwoLines[1] = fgets($fh);
+ }
+ fclose($fh);
+
+ if(trim($lastTwoLines[0]) == 'HasError') return true;
+ return false;
+ }
}
diff --git a/module/upgrade/ui/consistency.html.php b/module/upgrade/ui/consistency.html.php
index c416cb138b..aa163cd482 100644
--- a/module/upgrade/ui/consistency.html.php
+++ b/module/upgrade/ui/consistency.html.php
@@ -12,7 +12,9 @@ namespace zin;
set::zui(true);
-$alterSQL = "SET @@sql_mode= '';\n{$alterSQL}";
+jsVar('version', $version);
+jsVar('execFixSQL', !empty($alterSQL) && !$hasError);
+
div
(
setID('main'),
@@ -31,13 +33,13 @@ div
div
(
setClass('article-h3 mb-2'),
- $lang->upgrade->noticeSQL
+ $hasError ? $lang->upgrade->noticeErrSQL : $lang->upgrade->showSQLLog
),
- h::textarea
+ div
(
- set::style(array('height' => '200px', 'width' => '100%')),
- set::readonly(true),
- html($alterSQL)
+ set::style(array('height' => '200px', 'width' => '100%', 'overflow' => 'auto')),
+ set::id('logBox'),
+ $hasError ? html($alterSQL) : null
)
),
div