official_website/app/admin/controller/DataBackup.php

436 lines
16 KiB
PHP
Raw Normal View History

2024-12-02 13:57:08 +08:00
<?php
/**
* @Descripttion : FOXCMS 是一款高效的 PHP 多端跨平台内容管理系统
* @Author : FoxCMS Team
* @Date : 2023/6/26 14:43
* @version : V1.08
* @copyright : ©2021-现在 贵州黔狐科技股份有限公司 版权所有
* @LastEditTime : 2023/6/26 14:43
*/
namespace app\admin\controller;
use app\admin\util\Basckup;
use app\admin\util\ModelMg;
use app\common\controller\AdminBase;
use think\facade\Db;
use think\facade\View;
class DataBackup extends AdminBase
{
private $filterTable = ['fox_admin_log'];
public function index($page = 1, $pageSize = 1000)
{
if ($this->request->isAjax()) {
$sql = 'SHOW TABLE STATUS';
$list = Db::query($sql);
$rlist = [];
foreach ($list as $table) {
$tableName = $table['Name'];
if (!in_array($tableName, $this->filterTable)) {
$count = Db::table($tableName)->count();
$comment = $table['Comment'];
array_push($rlist, ['name' => $tableName, 'count' => $count, 'comment' => $comment]);
}
}
try {
$bfday = date("Y-m-d", strtotime("-7 day"));
\app\common\model\DataBackup::where([['create_time', '<', $bfday]])->delete();
} catch (\Exception $e) {
}
$this->success('查询成功', '', $rlist);
}
//SQL命令行
$safeExcute = \app\common\model\Safe::where(['dict_label' => 'sql_execute'])->find();
$sql_execute_value = 0;
if ($safeExcute) {
$sql_execute_value = $safeExcute['dict_value'];
}
View::assign("sql_execute_value", $sql_execute_value); //SQL状态
return view('index');
}
// 备份
public function backup()
{
$param = $this->request->param();
$tableName = $param['tableName'];
if (empty($tableName)) {
$this->error("备份失败,表名为空");
}
$random_num = func_random_num(18);
$fileName = $tableName . "-" . $random_num . ".sql";
$content = (new Basckup())->getbackupTable($tableName); //模型表与数据内容
$time = date('Y-m-d');
$path = app()->getRootPath() . 'data' . DIRECTORY_SEPARATOR . 'backupdata' . DIRECTORY_SEPARATOR . $time . DIRECTORY_SEPARATOR;
if (!tp_mkdir($path)) {
$this->error("创建文件夹失败");
}
$fpath = write($path, $fileName, $content); //存入模型字段数据
if (empty($fpath)) {
$this->error("备份失败");
}
$backup_file = $tableName . ".sql";
$dataBackup = new \app\common\model\DataBackup();
$cDataBackup = $dataBackup->where(['backup_file' => $time])->find();
$pid = 0;
if ($cDataBackup) {
$pid = $cDataBackup->id;
} else {
$dataBackup->save(['pid' => 0, 'backup_file' => $time, 'backup_file_path' => $path, 'table_name' => $time]);
if (empty($dataBackup->id)) {
$this->error("操作失败");
}
$pid = $dataBackup->id;
}
$r = (new \app\common\model\DataBackup())->save(['pid' => $pid, 'backup_file' => $backup_file, 'backup_file_path' => $fpath, 'random_num' => $random_num, 'table_name' => $tableName]);
if ($r) {
xn_add_admin_log("备份数据", "backup"); //添加日志
$this->success('操作成功', "", $fpath);
} else {
$this->error("操作失败");
}
}
// 备份全部文件
public function backupAll()
{
$param = $this->request->param();
$tableList = json_decode($param['tableList']);
if (array_key_exists("tableList", $param)) {
if (sizeof($tableList) <= 0) {
$this->error("备份失败,参数错误");
}
}
$saveAll = [];
$time = date('Y-m-d');
$path = app()->getRootPath() . 'data' . DIRECTORY_SEPARATOR . 'backupdata' . DIRECTORY_SEPARATOR . $time . DIRECTORY_SEPARATOR;
if (!tp_mkdir($path)) {
$this->error("创建文件夹失败");
}
$dataBackup = new \app\common\model\DataBackup();
$cDataBackup = $dataBackup->where(['backup_file' => $time])->find();
$pid = 0;
if ($cDataBackup) {
$pid = $cDataBackup->id;
} else {
$dataBackup->save(['pid' => 0, 'backup_file' => $time, 'backup_file_path' => $path, 'table_name' => $time]);
if (empty($dataBackup->id)) {
$this->error("操作失败");
}
$pid = $dataBackup->id;
}
foreach ($tableList as $tableName) {
$random_num = func_random_num(18);
$fileName = $tableName . "-" . $random_num . ".sql";
$content = (new Basckup())->backupTable($tableName); //模型表与数据内容
$fpath = write($path, $fileName, $content); //存入模型字段数据
if (empty($fpath)) {
$this->error("备份失败");
}
$backup_file = $tableName . ".sql";
array_push($saveAll, ['pid' => $pid, 'backup_file' => $backup_file, 'backup_file_path' => $fpath, 'random_num' => $random_num, 'table_name' => $tableName]);
}
$rSaveData = (new \app\common\model\DataBackup())->saveAll($saveAll);
if (sizeof($rSaveData) <= 0) {
$this->error('操作失败');
}
xn_add_admin_log("批量备份数据", "backup"); //添加日志
$this->success('操作成功', "", $rSaveData);
}
// 数据还原初始化 备份系列
public function backupIndex()
{
$fArr = array();
$activepath = '/backupdata';
$basePath = app()->getRootPath() . 'data' . $activepath;
$arr_file = getDirFile($basePath, $activepath, $fArr);
$list = [];
foreach ($arr_file as $ar) {
if ($ar['filetype'] != "dir2" && $ar['filemine'] == "dir") {
$rdata['id'] = $ar['filepath'];
$rdata['backup_file'] = $ar['filename'];
$creationTime = filectime(replaceSymbol($basePath . $ar['filepath']));
$rdata['create_time'] = date("Y-m-d H:i:s", $creationTime);
array_push($list, $rdata);
}
}
$this->success("查询成功", "", $list);
}
// 恢复备份系列
public function restoreSerie()
{
$id = $this->request->param("id");
if (empty($id)) {
$this->error("恢复失败,参数错误");
}
$basePath = app()->getRootPath() . 'data';
$sqlFolderPath = replaceSymbol($basePath . $id); //执行模板sql文件
if (!is_dir($sqlFolderPath)) {
$this->error("恢复失败,没找到对应恢复数据");
}
$files = dirFile($sqlFolderPath);
if (sizeof($files) > 0) {
foreach ($files as $file) {
try {
$sqlPath = $sqlFolderPath . DIRECTORY_SEPARATOR . $file;
$sqlContent = @file_get_contents($sqlPath);
$sqlFormat = (new ModelMg())->sql_split($sqlContent, env('database.prefix', 'fox_'));
// 执行SQL语句
$counts = count($sqlFormat);
for ($i = 0; $i < $counts; $i++) {
$sql = trim($sqlFormat[$i]);
if (stristr($sql, 'CREATE TABLE')) {
Db::execute($sql);
} else {
if (trim($sql) == '')
continue;
Db::execute($sql);
}
}
} catch (\Exception $e) {
$this->error("恢复失败,执行sql错误");
}
}
} else {
$this->error("恢复失败");
}
$this->success("恢复成功");
}
// 删除备份系列
public function delRestoreSerie()
{
$id = $this->request->param("id");
if (empty($id)) {
$this->error("删除失败,参数错误");
}
$basePath = app()->getRootPath() . 'data';
$sqlFolderPath = replaceSymbol($basePath . $id); //执行模板sql文件
if (!is_dir($sqlFolderPath)) {
$this->error("恢复失败,没找到对应恢复数据");
}
delDir($sqlFolderPath); //删除子文件数据
$this->success("删除成功");
}
// 删除批量备份系列
public function delRestoreSeries()
{
$param = $this->request->param();
$idList = json_decode($param['idList']);
if (array_key_exists("idList", $param)) {
if (sizeof($idList) <= 0) {
$this->error("删除失败,参数错误");
}
}
$basePath = app()->getRootPath() . 'data';
foreach ($idList as $id) {
$sqlFolderPath = replaceSymbol($basePath . $id); //执行模板sql文件
if (!is_dir($sqlFolderPath)) {
continue;
}
delDir($sqlFolderPath);
}
$this->success("删除成功");
}
// 点击备份目录文件
public function tempFile()
{
$param = $this->request->param();
if ($this->request->isAjax()) {
$fArr = array();
$activepath = $param['pid'];
$basePath = app()->getRootPath() . 'data';
$basePath1 = replaceSymbol($basePath . $activepath);
$arr_file = getDirFile($basePath1, $activepath, $fArr);
$list = [];
foreach ($arr_file as $ar) {
if ($ar['filemine'] == "file") {
$rdata['id'] = $ar['filepath'];
$rdata['filesize'] = $ar['filesize'];
$rdata['backup_file'] = $ar['filename'];
$creationTime = filectime(replaceSymbol($basePath . $ar['filepath']));
$rdata['create_time'] = date("Y-m-d H:i:s", $creationTime);
array_push($list, $rdata);
}
}
$this->success("查询成功", "", $list);
}
View::assign("pid", $param['id']);
return view();
}
// 执行命令
public function executeCommand()
{
$command = $this->request->param("command");
if (empty($command)) {
$this->error("参数错误");
}
$command = trim($command);
$commands = explode("\n", $command);
$rlist = [];
foreach ($commands as $comm) {
$comm = trim($comm);
$type = 1; //执行语句
$msg = "";
$list = [];
if (strpos($comm, 'drop') !== false || strpos($comm, 'DROP') !== false) { //不能删除
$msg = "删除'数据表'或'数据库'的语句不允许在这里执行!";
} else {
if (strpos($comm, 'select') !== false || strpos($comm, 'SELECT') !== false) { //查询语句
try {
$list = Db::query($comm);
$rfList = [];
foreach ($list as $result) {
$rf = "";
foreach ($result as $key => $kr) {
$rf .= $key . "=" . $kr . ";";
}
array_push($rfList, $rf);
}
$list = $rfList;
$msg = '成功查询SQL语句';
} catch (\Exception $e) {
$msg = '执行SQL语句失败';
}
$type = 2; //查询语句
} else { //执行语句
try {
$r = Db::execute($comm);
if ($r) {
$msg = '成功执行SQL语句';
} else {
$msg = '执行SQL语句无结果';
}
} catch (\Exception $e) {
$msg = '执行SQL语句失败';
}
}
}
array_push($rlist, ['type' => $type, 'msg' => $msg, 'result' => $list, 'command' => $comm]);
}
$this->success("执行成功", '', $rlist);
}
// 删除恢复文件
public function delRestoreFile()
{
$id = $this->request->param("id");
if (empty($id)) {
$this->error("删除失败,参数错误");
}
$sqlPath = app()->getRootPath() . 'data' . $id;
if (!file_exists($sqlPath)) {
$this->error("恢复失败,参数错误");
}
$sqlPath = replaceSymbol($sqlPath);
$r = @unlink($sqlPath);
if ($r) {
$this->success("删除成功");
}
$this->error("删除失败");
}
// 批量删除恢复文件
public function delRestoreFiles()
{
$param = $this->request->param();
$idList = json_decode($param['idList']);
if (array_key_exists("idList", $param)) {
if (sizeof($idList) <= 0) {
$this->error("删除失败,参数错误");
}
}
$errorCount = 0;
$basepath = app()->getRootPath() . 'data';
foreach ($idList as $id) {
$sqlPath = replaceSymbol($basepath . $id);
if (!file_exists($sqlPath)) {
continue;
}
$r = @unlink($sqlPath);
if (!$r) {
$errorCount++;
}
}
if ($errorCount > 0) {
$this->error("删除失败");
}
$this->success("删除成功");
}
// 恢复数据
public function restore()
{
$id = $this->request->param("id");
if (empty($id)) {
$this->error("恢复失败,参数错误");
}
$sqlPath = app()->getRootPath() . 'data' . $id;
if (!file_exists($sqlPath)) {
$this->error("恢复失败,参数错误");
}
$sqlPath = replaceSymbol($sqlPath);
$sqlContent = @file_get_contents($sqlPath);
$sqlFormat = (new ModelMg())->sql_split($sqlContent, env('database.prefix', 'fox_'));
// 执行SQL语句
$counts = count($sqlFormat);
for ($i = 0; $i < $counts; $i++) {
$sql = trim($sqlFormat[$i]);
if (stristr($sql, 'CREATE TABLE')) {
Db::execute($sql);
} else {
if (trim($sql) == '')
continue;
Db::execute($sql);
}
}
$this->success("恢复成功");
}
// 批量恢复数据
public function restores()
{
$param = $this->request->param();
$idList = json_decode($param['idList']);
if (array_key_exists("idList", $param)) {
if (sizeof($idList) <= 0) {
$this->error("删除失败,参数错误");
}
}
$basepath = app()->getRootPath() . 'data';
foreach ($idList as $id) {
$sqlPath = $basepath . $id;
if (!file_exists($sqlPath)) {
continue;
}
$sqlPath = replaceSymbol($sqlPath);
$sqlContent = @file_get_contents($sqlPath);
$sqlFormat = (new ModelMg())->sql_split($sqlContent, env('database.prefix', 'fox_'));
// 执行SQL语句
$counts = count($sqlFormat);
for ($i = 0; $i < $counts; $i++) {
$sql = trim($sqlFormat[$i]);
if (stristr($sql, 'CREATE TABLE')) {
Db::execute($sql);
} else {
if (trim($sql) == '')
continue;
Db::execute($sql);
}
}
}
$this->success("恢复成功");
}
}