787 lines
21 KiB
PHP
787 lines
21 KiB
PHP
|
<?php
|
|||
|
/** 安装界面需要的各种模块 */
|
|||
|
|
|||
|
class installModel
|
|||
|
{
|
|||
|
private $host;
|
|||
|
private $name;
|
|||
|
private $user;
|
|||
|
private $encoding;
|
|||
|
private $password;
|
|||
|
private $port;
|
|||
|
private $prefix;
|
|||
|
private $successTable = [];
|
|||
|
/**
|
|||
|
* @var bool
|
|||
|
*/
|
|||
|
private $allowNext = true;
|
|||
|
/**
|
|||
|
* @var PDO|string
|
|||
|
*/
|
|||
|
private $dbh = null;
|
|||
|
/**
|
|||
|
* @var bool
|
|||
|
*/
|
|||
|
private $clearDB = false;
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: php版本
|
|||
|
* @author luzg(2020/8/25 9:56)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function getPhpVersion()
|
|||
|
{
|
|||
|
return PHP_VERSION;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 当前版本是否符合
|
|||
|
* @author luzg(2020/8/25 9:57)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkPHP()
|
|||
|
{
|
|||
|
return $result = version_compare(PHP_VERSION, '8.0.0') >= 0 ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否有PDO
|
|||
|
* @author luzg(2020/8/25 9:57)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkPDO()
|
|||
|
{
|
|||
|
return $result = extension_loaded('pdo') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否有PDO::MySQL
|
|||
|
* @author luzg(2020/8/25 9:58)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkPDOMySQL()
|
|||
|
{
|
|||
|
return $result = extension_loaded('pdo_mysql') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否支持JSON
|
|||
|
* @author luzg(2020/8/25 9:58)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkJSON()
|
|||
|
{
|
|||
|
return $result = extension_loaded('json') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否支持openssl
|
|||
|
* @author luzg(2020/8/25 9:58)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkOpenssl()
|
|||
|
{
|
|||
|
return $result = extension_loaded('openssl') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否支持mbstring
|
|||
|
* @author luzg(2020/8/25 9:58)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkMbstring()
|
|||
|
{
|
|||
|
return $result = extension_loaded('mbstring') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否支持zlib
|
|||
|
* @author luzg(2020/8/25 9:59)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkZlib()
|
|||
|
{
|
|||
|
return $result = extension_loaded('zlib') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否支持curl
|
|||
|
* @author luzg(2020/8/25 9:59)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkCurl()
|
|||
|
{
|
|||
|
return $result = extension_loaded('curl') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查GD2扩展
|
|||
|
* @author luzg(2020/8/26 9:59)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkGd2()
|
|||
|
{
|
|||
|
return $result = extension_loaded('gd') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查Dom扩展
|
|||
|
* @author luzg(2020/8/26 9:59)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkDom()
|
|||
|
{
|
|||
|
return $result = extension_loaded('dom') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否支持filter
|
|||
|
* @author luzg(2020/8/25 9:59)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkFilter()
|
|||
|
{
|
|||
|
return $result = extension_loaded('filter') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否支持iconv
|
|||
|
* @author luzg(2020/8/25 9:59)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkIconv()
|
|||
|
{
|
|||
|
return $result = extension_loaded('iconv') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查fileinfo扩展
|
|||
|
* @author 段誉(2021/6/28 11:03)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkFileInfo()
|
|||
|
{
|
|||
|
return $result = extension_loaded('fileinfo') ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 取得临时目录路径
|
|||
|
* @author luzg(2020/8/25 10:05)
|
|||
|
* @return array
|
|||
|
*/
|
|||
|
public function getTmpRoot()
|
|||
|
{
|
|||
|
$path = $this->getAppRoot() . '/runtime';
|
|||
|
return [
|
|||
|
'path' => $path,
|
|||
|
'exists' => is_dir($path),
|
|||
|
'writable' => is_writable($path),
|
|||
|
];
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查临时路径
|
|||
|
* @author luzg(2020/8/25 10:06)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkTmpRoot()
|
|||
|
{
|
|||
|
$tmpRoot = $this->getTmpRoot()['path'];
|
|||
|
return $result = (is_dir($tmpRoot) and is_writable($tmpRoot)) ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: SESSION路径是否可写
|
|||
|
* @author luzg(2020/8/25 10:06)
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function getSessionSavePath()
|
|||
|
{
|
|||
|
$sessionSavePath = preg_replace("/\d;/", '', session_save_path());
|
|||
|
|
|||
|
return [
|
|||
|
'path' => $sessionSavePath,
|
|||
|
'exists' => is_dir($sessionSavePath),
|
|||
|
'writable' => is_writable($sessionSavePath),
|
|||
|
];
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查session路径可写状态
|
|||
|
* @author luzg(2020/8/25 10:13)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkSessionSavePath()
|
|||
|
{
|
|||
|
$sessionSavePath = preg_replace("/\d;/", '', session_save_path());
|
|||
|
$result = (is_dir($sessionSavePath) and is_writable($sessionSavePath)) ? 'ok' : 'fail';
|
|||
|
if ($result == 'fail') return $result;
|
|||
|
|
|||
|
file_put_contents($sessionSavePath . '/zentaotest', 'zentao');
|
|||
|
$sessionContent = file_get_contents($sessionSavePath . '/zentaotest');
|
|||
|
if ($sessionContent == 'zentao') {
|
|||
|
unlink($sessionSavePath . '/zentaotest');
|
|||
|
return 'ok';
|
|||
|
}
|
|||
|
return 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 取得data目录是否可选
|
|||
|
* @author luzg(2020/8/25 10:58)
|
|||
|
* @return array
|
|||
|
*/
|
|||
|
public function getDataRoot()
|
|||
|
{
|
|||
|
$path = $this->getAppRoot();
|
|||
|
return [
|
|||
|
'path' => $path . 'www' . DS . 'data',
|
|||
|
'exists' => is_dir($path),
|
|||
|
'writable' => is_writable($path),
|
|||
|
];
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 取得root路径
|
|||
|
* @author luzg(2020/8/25 11:02)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkDataRoot()
|
|||
|
{
|
|||
|
$dataRoot = $this->getAppRoot() . 'www' . DS . 'data';
|
|||
|
return $result = (is_dir($dataRoot) and is_writable($dataRoot)) ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 取得php.ini信息
|
|||
|
* @author luzg(2020/8/25 11:03)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function getIniInfo()
|
|||
|
{
|
|||
|
$iniInfo = '';
|
|||
|
ob_start();
|
|||
|
phpinfo(1);
|
|||
|
$lines = explode("\n", strip_tags(ob_get_contents()));
|
|||
|
ob_end_clean();
|
|||
|
foreach ($lines as $line) if (strpos($line, 'ini') !== false) $iniInfo .= $line . "\n";
|
|||
|
return $iniInfo;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 创建安装锁定文件
|
|||
|
* @author luzg(2020/8/28 11:32)
|
|||
|
* @return bool
|
|||
|
*/
|
|||
|
public function mkLockFile()
|
|||
|
{
|
|||
|
return touch($this->getAppRoot() . '/config/install.lock');
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查之前是否有安装
|
|||
|
* @author luzg(2020/8/28 11:36)
|
|||
|
*/
|
|||
|
public function appIsInstalled()
|
|||
|
{
|
|||
|
return file_exists($this->getAppRoot() . '/config/install.lock');
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 取得配置信息
|
|||
|
* @author luzg(2020/8/25 11:05)
|
|||
|
* @param string $dbName 数据库名称
|
|||
|
* @param array $connectionInfo 连接信息
|
|||
|
* @return stdclass
|
|||
|
* @throws Exception
|
|||
|
*/
|
|||
|
public function checkConfig($dbName, $connectionInfo)
|
|||
|
{
|
|||
|
$return = new stdclass();
|
|||
|
$return->result = 'ok';
|
|||
|
|
|||
|
/* Connect to database. */
|
|||
|
$this->setDBParam($connectionInfo);
|
|||
|
$this->dbh = $this->connectDB();
|
|||
|
if (strpos($dbName, '.') !== false) {
|
|||
|
$return->result = 'fail';
|
|||
|
$return->error = '没有发现数据库信息';
|
|||
|
return $return;
|
|||
|
}
|
|||
|
if ( !is_object($this->dbh)) {
|
|||
|
$return->result = 'fail';
|
|||
|
$return->error = '安装错误,请检查连接信息:'.mb_strcut($this->dbh,0,30).'...';
|
|||
|
echo $this->dbh;
|
|||
|
return $return;
|
|||
|
}
|
|||
|
|
|||
|
/* Get mysql version. */
|
|||
|
$version = $this->getMysqlVersion();
|
|||
|
|
|||
|
/* check mysql sql_model */
|
|||
|
// if(!$this->checkSqlMode($version)) {
|
|||
|
// $return->result = 'fail';
|
|||
|
// $return->error = '请在mysql配置文件修改sql-mode添加NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
|
|||
|
// return $return;
|
|||
|
// }
|
|||
|
|
|||
|
/* If database no exits, try create it. */
|
|||
|
if ( !$this->dbExists()) {
|
|||
|
if ( !$this->createDB($version)) {
|
|||
|
$return->result = 'fail';
|
|||
|
$return->error = '创建数据库错误';
|
|||
|
return $return;
|
|||
|
}
|
|||
|
} elseif ($this->tableExits() and $this->clearDB == false) {
|
|||
|
$return->result = 'fail';
|
|||
|
$return->error = '数据表已存在,您之前可能已安装本系统,如需继续安装请选择新的数据库。';
|
|||
|
return $return;
|
|||
|
} elseif ($this->dbExists() and $this->clearDB == true) {
|
|||
|
if (!$this->dropDb($connectionInfo['name'])) {
|
|||
|
$return->result = 'fail';
|
|||
|
$return->error = '数据表已经存在,删除已存在库错误,请手动清除';
|
|||
|
return $return;
|
|||
|
} else {
|
|||
|
if ( !$this->createDB($version)) {
|
|||
|
$return->result = 'fail';
|
|||
|
$return->error = '创建数据库错误!';
|
|||
|
return $return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Create tables. */
|
|||
|
if ( !$this->createTable($version, $connectionInfo)) {
|
|||
|
$return->result = 'fail';
|
|||
|
$return->error = '创建表格失败';
|
|||
|
return $return;
|
|||
|
}
|
|||
|
|
|||
|
return $return;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 设置数据库相关信息
|
|||
|
* @author luzg(2020/8/25 11:17)
|
|||
|
* @param $post
|
|||
|
*/
|
|||
|
public function setDBParam($post)
|
|||
|
{
|
|||
|
$this->host = $post['host'];
|
|||
|
$this->name = $post['name'];
|
|||
|
$this->user = $post['user'];
|
|||
|
$this->encoding = 'utf8mb4';
|
|||
|
$this->password = $post['password'];
|
|||
|
$this->port = $post['port'];
|
|||
|
$this->prefix = $post['prefix'];
|
|||
|
$this->clearDB = $post['clear_db'] == 'on';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 连接数据库
|
|||
|
* @author luzg(2020/8/25 11:56)
|
|||
|
* @return PDO|string
|
|||
|
*/
|
|||
|
public function connectDB()
|
|||
|
{
|
|||
|
$dsn = "mysql:host={$this->host}; port={$this->port}";
|
|||
|
try {
|
|||
|
$dbh = new PDO($dsn, $this->user, $this->password);
|
|||
|
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
|
|||
|
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|||
|
$dbh->exec("SET NAMES {$this->encoding}");
|
|||
|
$dbh->exec("SET NAMES {$this->encoding}");
|
|||
|
try{
|
|||
|
$dbh->exec("SET GLOBAL sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';");
|
|||
|
}catch (Exception $e){
|
|||
|
|
|||
|
}
|
|||
|
return $dbh;
|
|||
|
} catch (PDOException $exception) {
|
|||
|
return $exception->getMessage();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查数据库是否存在
|
|||
|
* @author luzg(2020/8/25 11:56)
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function dbExists()
|
|||
|
{
|
|||
|
$sql = "SHOW DATABASES like '{$this->name}'";
|
|||
|
return $this->dbh->query($sql)->fetch();
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查表是否存在
|
|||
|
* @author luzg(2020/8/25 11:56)
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function tableExits()
|
|||
|
{
|
|||
|
$configTable = sprintf("'%s'", $this->prefix . TESTING_TABLE);
|
|||
|
$sql = "SHOW TABLES FROM {$this->name} like $configTable";
|
|||
|
return $this->dbh->query($sql)->fetch();
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 获取mysql版本号
|
|||
|
* @author luzg(2020/8/25 11:56)
|
|||
|
* @return false|string
|
|||
|
*/
|
|||
|
public function getMysqlVersion()
|
|||
|
{
|
|||
|
$sql = "SELECT VERSION() AS version";
|
|||
|
$result = $this->dbh->query($sql)->fetch();
|
|||
|
return substr($result->version, 0, 3);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @notes 检测数据库sql_mode
|
|||
|
* @param $version
|
|||
|
* @return bool
|
|||
|
* @author 段誉
|
|||
|
* @date 2021/8/27 17:17
|
|||
|
*/
|
|||
|
public function checkSqlMode($version)
|
|||
|
{
|
|||
|
$sql = "SELECT @@global.sql_mode";
|
|||
|
$result = $this->dbh->query($sql)->fetch();
|
|||
|
$result = (array)$result;
|
|||
|
|
|||
|
if ($version >= 5.7 && $version < 8.0) {
|
|||
|
if ((strpos($result['@@global.sql_mode'],'NO_AUTO_CREATE_USER') !== false)
|
|||
|
&& (strpos($result['@@global.sql_mode'],'NO_ENGINE_SUBSTITUTION') !== false)) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 创建数据库
|
|||
|
* @author luzg(2020/8/25 11:57)
|
|||
|
* @param $version
|
|||
|
* @return mixed
|
|||
|
*/
|
|||
|
public function createDB($version)
|
|||
|
{
|
|||
|
$sql = "CREATE DATABASE `{$this->name}`";
|
|||
|
if ($version > 4.1) $sql .= " DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
|
|||
|
return $this->dbh->query($sql);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 创建表
|
|||
|
* @author luzg(2020/8/25 11:57)
|
|||
|
* @param $version
|
|||
|
* @param $post
|
|||
|
* @return bool
|
|||
|
* @throws Exception
|
|||
|
*/
|
|||
|
public function createTable($version, $post)
|
|||
|
{
|
|||
|
$dbFile = $this->getInstallRoot() . '/db/like.sql';
|
|||
|
//file_put_contents($dbFile, $this->initAccount($post), FILE_APPEND);
|
|||
|
$content = str_replace(";\r\n", ";\n", file_get_contents($dbFile));
|
|||
|
$tables = explode(";\n", $content);
|
|||
|
$tables[] = $this->initAccount($post);
|
|||
|
$installTime = microtime(true) * 10000;
|
|||
|
|
|||
|
foreach ($tables as $table) {
|
|||
|
$table = trim($table);
|
|||
|
if (empty($table)) continue;
|
|||
|
|
|||
|
if (strpos($table, 'CREATE') !== false and $version <= 4.1) {
|
|||
|
$table = str_replace('DEFAULT CHARSET=utf8', '', $table);
|
|||
|
}
|
|||
|
// elseif (strpos($table, 'DROP') !== false and $this->clearDB != false) {
|
|||
|
// $table = str_replace('--', '', $table);
|
|||
|
// }
|
|||
|
|
|||
|
/* Skip sql that is note. */
|
|||
|
if (strpos($table, '--') === 0) continue;
|
|||
|
|
|||
|
$table = str_replace('`la_', $this->name . '.`la_', $table);
|
|||
|
$table = str_replace('`la_', '`' . $this->prefix, $table);
|
|||
|
|
|||
|
if (strpos($table, 'CREATE') !== false) {
|
|||
|
$tableName = explode('`', $table)[1];
|
|||
|
$installTime += random_int(3000, 7000);
|
|||
|
$this->successTable[] = [$tableName, date('Y-m-d H:i:s', $installTime / 10000)];
|
|||
|
}
|
|||
|
|
|||
|
// if (strpos($table, "INSERT INTO ") !== false) {
|
|||
|
// $table = str_replace('INSERT INTO ', 'INSERT INTO ' .$this->name .'.', $table);
|
|||
|
// }
|
|||
|
|
|||
|
try {
|
|||
|
if ( !$this->dbh->query($table)) return false;
|
|||
|
} catch (Exception $e) {
|
|||
|
echo 'error sql: ' . $table . "<br>";
|
|||
|
echo $e->getMessage() . "<br>";
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 删除数据库
|
|||
|
* @param $db
|
|||
|
* @return false|PDOStatement
|
|||
|
*/
|
|||
|
public function dropDb($db)
|
|||
|
{
|
|||
|
$sql = "drop database {$db};";
|
|||
|
return $this->dbh->query($sql);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 取得安装成功的表列表
|
|||
|
* @author luzg(2020/8/26 18:28)
|
|||
|
* @return array
|
|||
|
*/
|
|||
|
public function getSuccessTable()
|
|||
|
{
|
|||
|
return $this->successTable;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 创建演示数据
|
|||
|
* @author luzg(2020/8/25 11:58)
|
|||
|
* @return bool
|
|||
|
*/
|
|||
|
public function importDemoData()
|
|||
|
{
|
|||
|
$demoDataFile = 'ys.sql';
|
|||
|
$demoDataFile = $this->getInstallRoot() . '/db/' . $demoDataFile;
|
|||
|
if (!is_file($demoDataFile)) {
|
|||
|
echo "<br>";
|
|||
|
echo 'no file:' .$demoDataFile;
|
|||
|
return false;
|
|||
|
}
|
|||
|
$content = str_replace(";\r\n", ";\n", file_get_contents($demoDataFile));
|
|||
|
$insertTables = explode(";\n", $content);
|
|||
|
foreach ($insertTables as $table) {
|
|||
|
$table = trim($table);
|
|||
|
if (empty($table)) continue;
|
|||
|
|
|||
|
$table = str_replace('`la_', $this->name . '.`la_', $table);
|
|||
|
$table = str_replace('`la_', '`' .$this->prefix, $table);
|
|||
|
if ( !$this->dbh->query($table)) return false;
|
|||
|
}
|
|||
|
|
|||
|
// 移动图片资源
|
|||
|
$this->cpFiles($this->getInstallRoot().'/uploads', $this->getAppRoot().'/public/uploads');
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 将一个文件夹下的所有文件及文件夹
|
|||
|
* 复制到另一个文件夹里(保持原有结构)
|
|||
|
*
|
|||
|
* @param <string> $rootFrom 源文件夹地址(最好为绝对路径)
|
|||
|
* @param <string> $rootTo 目的文件夹地址(最好为绝对路径)
|
|||
|
*/
|
|||
|
function cpFiles($rootFrom, $rootTo){
|
|||
|
|
|||
|
$handle = opendir($rootFrom);
|
|||
|
while (false !== ($file = readdir($handle))) {
|
|||
|
//DIRECTORY_SEPARATOR 为系统的文件夹名称的分隔符 例如:windos为'/'; linux为'/'
|
|||
|
$fileFrom = $rootFrom . DIRECTORY_SEPARATOR . $file;
|
|||
|
$fileTo = $rootTo . DIRECTORY_SEPARATOR . $file;
|
|||
|
if ($file == '.' || $file == '..') {
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (is_dir($fileFrom)) {
|
|||
|
if (!is_dir($fileTo)) { //目标目录不存在则创建
|
|||
|
mkdir($fileTo, 0777);
|
|||
|
}
|
|||
|
$this->cpFiles($fileFrom, $fileTo);
|
|||
|
} else {
|
|||
|
if (!file_exists($fileTo)) {
|
|||
|
@copy($fileFrom, $fileTo);
|
|||
|
if (strstr($fileTo, "access_token.txt")) {
|
|||
|
chmod($fileTo, 0777);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 当前应用程序的相对路径
|
|||
|
* @author luzg(2020/8/25 10:55)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function getAppRoot()
|
|||
|
{
|
|||
|
return realpath($this->getInstallRoot() . '/../../');
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 获取安装目录
|
|||
|
* @author luzg(2020/8/26 16:15)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function getInstallRoot()
|
|||
|
{
|
|||
|
return INSTALL_ROOT;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 目录的容量
|
|||
|
* @author luzg(2020/8/25 15:21)
|
|||
|
* @param $dir
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function freeDiskSpace($dir)
|
|||
|
{
|
|||
|
// M
|
|||
|
$freeDiskSpace = disk_free_space(realpath(__DIR__)) / 1024 / 1024;
|
|||
|
|
|||
|
// G
|
|||
|
if ($freeDiskSpace > 1024) {
|
|||
|
return number_format($freeDiskSpace / 1024, 2) . 'G';
|
|||
|
}
|
|||
|
|
|||
|
return number_format($freeDiskSpace, 2) . 'M';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 获取状态标志
|
|||
|
* @author luzg(2020/8/25 16:10)
|
|||
|
* @param $statusSingle
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function correctOrFail($statusSingle)
|
|||
|
{
|
|||
|
if ($statusSingle == 'ok')
|
|||
|
return '<td class="layui-icon green"></td>';
|
|||
|
$this->allowNext = false;
|
|||
|
return '<td class="layui-icon wrong">ဆ</td>';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 是否允许下一步
|
|||
|
* @author luzg(2020/8/25 17:29)
|
|||
|
* @return bool
|
|||
|
*/
|
|||
|
public function getAllowNext()
|
|||
|
{
|
|||
|
return $this->allowNext;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查session auto start
|
|||
|
* @author luzg(2020/8/25 16:55)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkSessionAutoStart()
|
|||
|
{
|
|||
|
return $result = ini_get('session.auto_start') == '0' ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查auto tags
|
|||
|
* @author luzg(2020/8/25 16:55)
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkAutoTags()
|
|||
|
{
|
|||
|
return $result = ini_get('session.auto_start') == '0' ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查目录是否可写
|
|||
|
* @param $dir
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkDirWrite($dir='')
|
|||
|
{
|
|||
|
$route = $this->getAppRoot().'/'.$dir;
|
|||
|
return $result = is_writable($route) ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 检查目录是否可写
|
|||
|
* @param $dir
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function checkSuperiorDirWrite($dir='')
|
|||
|
{
|
|||
|
$route = $this->getAppRoot().'/'.$dir;
|
|||
|
return $result = is_writable($route) ? 'ok' : 'fail';
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 初始化管理账号
|
|||
|
* @param $post
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function initAccount($post)
|
|||
|
{
|
|||
|
$time = time();
|
|||
|
$salt = substr(md5($time . $post['admin_user']), 0, 4);//随机4位密码盐
|
|||
|
|
|||
|
global $uniqueSalt;
|
|||
|
$uniqueSalt = $salt;
|
|||
|
|
|||
|
$password = $this->createPassword($post['admin_password'], $salt);
|
|||
|
|
|||
|
// 超级管理员
|
|||
|
$sql = "INSERT INTO `la_admin`(`id`, `root`, `name`, `avatar`, `account`, `password`, `login_time`, `login_ip`, `multipoint_login`, `disable`, `create_time`, `update_time`, `delete_time`) VALUES (1, 1, '{$post['admin_user']}', '', '{$post['admin_user']}', '{$password}','{$time}', '', 1, 0, '{$time}', '{$time}', NULL);";
|
|||
|
// 超级管理员关联部门
|
|||
|
$sql .= "INSERT INTO `la_admin_dept` (`admin_id`, `dept_id`) VALUES (1, 1);";
|
|||
|
|
|||
|
return $sql;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Notes: 生成密码密文
|
|||
|
* @param $pwd
|
|||
|
* @param $salt
|
|||
|
* @return string
|
|||
|
*/
|
|||
|
public function createPassword($pwd, $salt)
|
|||
|
{
|
|||
|
return md5($salt . md5($pwd . $salt));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @notes 恢复admin,mobile index文件
|
|||
|
* @author 段誉
|
|||
|
* @date 2021/9/16 15:51
|
|||
|
*/
|
|||
|
public function restoreIndexLock()
|
|||
|
{
|
|||
|
$this->checkIndexFile($this->getAppRoot().'/public/mobile');
|
|||
|
$this->checkIndexFile($this->getAppRoot().'/public/admin');
|
|||
|
}
|
|||
|
|
|||
|
public function checkIndexFile($path)
|
|||
|
{
|
|||
|
if(file_exists($path.'/index_lock.html')) {
|
|||
|
// 删除提示文件
|
|||
|
unlink($path.'/index.html');
|
|||
|
// 恢复原入口
|
|||
|
rename($path.'/index_lock.html', $path.'/index.html');
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|