Initial commit
Some checks failed
定时更新GitHub源插件 / 自动更新GitHub插件 (push) Has been cancelled

This commit is contained in:
chorblack
2026-03-07 11:19:25 +08:00
commit e75f275ef4
4484 changed files with 645480 additions and 0 deletions

209
DbManager/Action.php Normal file
View File

@@ -0,0 +1,209 @@
<?php
class DbManager_Action extends Typecho_Widget implements Widget_Interface_Do
{
/**
* 导出备份
*
* @access public
* @return void
*/
public function doExport()
{
// 需要备份的数据表
$tableSelect = $this->request->getArray('tableSelect');
// 备份的数据
$content = $this->sqlBuild($tableSelect);
// 备份文件名
$fileName = $this->request->get('fileName');
if (0 == $this->request->get('bakplace')) {
header('Content-Type: text/x-sql');
header('Content-Disposition: attachment; filename=' . $fileName);
if (preg_match("/MSIE ([0-9].[0-9]{1,2})/", $_SERVER['HTTP_USER_AGENT'])) {
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
} else {
header('Pragma: no-cache');
header('Last-Modified: '. gmdate('D, d M Y H:i:s',
Typecho_Date::gmtTime() + (Typecho_Date::$timezoneOffset - Typecho_Date::$serverTimezoneOffset)) . ' GMT');
}
header('Expires: ' . gmdate('D, d M Y H:i:s',
Typecho_Date::gmtTime() + (Typecho_Date::$timezoneOffset - Typecho_Date::$serverTimezoneOffset)) . ' GMT');
echo $content;
} else {
// 备份目录及路径
$config = Typecho_Widget::widget('Widget_Options')->plugin('DbManager');
$path = __TYPECHO_ROOT_DIR__ . '/' . trim($config->path, '/') . '/';
$file = $path . $fileName;
if (!empty($fileName)) {
if ((is_dir($path) || @mkdir($path, 0777)) && is_writable($path)) {
$handle = fopen($file, 'wb');
if ($handle && fwrite($handle, $content)) {
fclose($handle);
$this->widget('Widget_Notice')->set(_t('备份文件 ' . $fileName . ' 已创建'), 'success');
} else {
$this->widget('Widget_Notice')->set(_t('备份文件创建失败,请检查目录权限'), 'error');
}
} else {
$this->widget('Widget_Notice')->set(_t('文件夹创建失败或目录权限限制'), 'error');
}
} else {
$this->widget('Widget_Notice')->set(_t('备份文件名不能为空'), 'error');
}
$this->response->goBack();
}
}
/**
* 导入备份
*
* @access public
* @return void
*/
public function doImport()
{
// 数据库对象
$db = Typecho_Db::get();
// 获取备份目录并设置文件
$config = Typecho_Widget::widget('Widget_Options')->plugin('DbManager');
$path = __TYPECHO_ROOT_DIR__ . '/' . trim($config->path, '/') . '/';
$bid = $this->request->getArray('bid');
$deleteCount = 0;
$scripts = '';
if ($bid) {
foreach ($bid as $import) {
$scripts .= file_get_contents($path . $import);
$deleteCount ++;
}
// 导入数据
$scripts = explode(";\r\n", $scripts);
foreach ($scripts as $script) {
$script = trim($script);
if ($script) {
$db->query($script, Typecho_Db::WRITE);
}
}
}
$this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('备份已经被导入') : _t('没有备份被导入'),
$deleteCount > 0 ? 'success' : 'notice');
$this->response->goBack();
}
/**
* 删除备份
*
* @access public
* @return void
*/
public function doDelete()
{
// 获取备份目录并设置文件
$config = Typecho_Widget::widget('Widget_Options')->plugin('DbManager');
$path = __TYPECHO_ROOT_DIR__ . '/' . trim($config->path, '/') . '/';
$bid = $this->request->getArray('bid');
$deleteCount = 0;
if ($bid) {
foreach ($bid as $fileName) {
@unlink($path . $fileName);
$deleteCount ++;
}
}
$this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('备份已经被删除') : _t('没有备份被删除'),
$deleteCount > 0 ? 'success' : 'notice');
$this->response->goBack();
}
/**
* 数据库优化
*
* @access public
* @return void
*/
public function doOptimize()
{
$db = Typecho_Db::get();
$select = $this->request->getArray('tableSelect');
$sql = 'OPTIMIZE TABLE ';
foreach ($select as $value) {
$sql .= '`' . $value . '`, ';
}
$sql = rtrim($sql, ', ') . ';';
$result = $db->query($sql, Typecho_Db::WRITE);
$this->widget('Widget_Notice')->set($result ? _t('所选表已优化')
: _t('数据库优化失败'), $result ? 'success' : 'notice');
$this->response->goBack();
}
/**
* 构建SQL语句
*
* @access public
* @param array $tables 数据表数组
* @return string $sql SQL语句
*/
public function sqlBuild(array $tables)
{
// 数据库对象
$db = Typecho_Db::get();
// SQL语句
$sql = "-- Typecho Backup SQL\r\n"
. "-- version: " . Typecho_Common::VERSION . "\r\n"
. "--\r\n"
. "-- generator: DbManager\r\n"
. "-- author: ShingChi <http://lcz.me>\r\n"
. "-- date: " . date('F jS, Y', Typecho_Date::gmtTime()) . "\r\n\r\n";
foreach ($tables as $table) {
$sql .= "\r\n-- ----------------------------------"
. "----------------------\r\n\r\n"
. "--\r\n"
. "-- 数据表 $table\r\n"
. "--\r\n\r\n";
$sql .= "DROP TABLE IF EXISTS `$table`;\r\n";
$createSql = $db->fetchRow($db->query("SHOW CREATE TABLE $table"));
$sql .= $createSql['Create Table'] . ";\r\n\r\n";
$resource = $db->query($db->select()->from($table));
while ($row = $db->fetchRow($resource)) {
foreach ($row as $key => $value) {
$keys[] = "`" . $key . "`";
$values[] = "'" . mysql_escape_string($value) . "'";
}
$sql .= "INSERT INTO `" . $table . "` ("
. implode(", ", $keys) . ") VALUES ("
. implode(", ", $values) . ");\r\n";
unset($keys);
unset($values);
}
}
return $sql;
}
/**
* 绑定动作
*
* @access public
* @return void
*/
public function action()
{
$this->widget('Widget_User')->pass('administrator');
$this->on($this->request->is('export'))->doExport();
$this->on($this->request->is('import'))->doImport();
$this->on($this->request->is('delete'))->doDelete();
$this->on($this->request->is('optimize'))->doOptimize();
}
}

65
DbManager/Plugin.php Normal file
View File

@@ -0,0 +1,65 @@
<?php
/**
* 数据备份
*
* @package DbManager
* @author ShingChi
* @version 2.0.1
* @link http://lcz.me
*/
class DbManager_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
Helper::addAction('dbmanager', 'DbManager_Action');
Helper::addPanel(1, 'DbManager/panel.php', _t('数据备份'), _t('数据备份'), 'administrator');
return _t('插件已经激活,请设置插件以正常使用!');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate()
{
Helper::removeAction('dbmanager');
Helper::removePanel(1, 'DbManager/panel.php');
}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form){
$path = new Typecho_Widget_Helper_Form_Element_Text(
'path', NULL, '/usr/plugins/DbManager/backup',
_t('备份文件夹'),
_t('备份文件夹默认在插件目录下的 backup路径规则请以 Typecho 根目录为准,如:/usr/backup<br>请正确设置目录权限,以便正常插件正常运行')
);
$form->addInput($path->addRule('required', _t('备份文件夹不能为空')));
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
}

21
DbManager/README.md Normal file
View File

@@ -0,0 +1,21 @@
> Typecho1.1开始已自带数据备份功能,旧版可酌情安装。
## 插件说明 ##
嗯,涉及到数据库操作,慎用!
后台启用插件后如果要更改备份文件保存文件夹的路径请自行设置插件。实在不想动的话无所谓不用设置默认就在插件目录的backup文件夹下。
数据导入后,**需要注意:**
1. 假如配置表也导入,如有网址更新,请重新设置一次网址。
2. 必须重新设置下**永久链接**,先是恢复到不启用的状态,然后再重新设置一次。
> 修正参数获取方式兼容Typecho1.0+。
## 更新 ##
1. 更名为 DbManager
2. 增加数据表优化功能
###### 更多详见论坛原帖http://forum.typecho.org/viewtopic.php?f=6&t=4803

View File

@@ -0,0 +1 @@
sql 文件保存目录

View File

@@ -0,0 +1,19 @@
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<script>
$(document).ready(function () {
$('#dbmanager-plugin .typecho-option-tabs li').click(function() {
var tabBox = $('#dbmanager-plugin > div');
$(this).siblings('li')
.removeClass('active').end()
.addClass('active');
tabBox.siblings('div')
.addClass('hidden').end()
.eq($(this).index()).removeClass('hidden');
console.log($(this).index());
return false;
});
});
</script>

172
DbManager/panel.php Normal file
View File

@@ -0,0 +1,172 @@
<?php
$db = Typecho_Db::get();
// 数据表
$tables = array();
$resource = $db->fetchAll($db->query('SHOW TABLES'));
foreach ($resource as $value) {
foreach ($value as $tableName) {
if (!is_null(strpos($tableName, $db->getPrefix()))) {
$tables[] = $tableName;
}
}
}
// 获取备份目录并设置文件
$exportConfig = $options->plugin('DbManager');
$path = __TYPECHO_ROOT_DIR__ . '/' . trim($exportConfig->path, '/');
if (is_dir($path)) {
$filePaths = glob($path . '/*.sql', GLOB_BRACE);
$files = array();
for ($i = 0; $i < sizeof($filePaths); $i++) {
$files[$i]['name'] = basename($filePaths[$i]);
$files[$i]['time'] = date('Y年m月d日', filemtime($filePaths[$i]));
$files[$i]['size'] = ceil(filesize($filePaths[$i]) / 1024) . ' KB';
}
}
include_once 'common.php';
include 'header.php';
include 'menu.php';
?>
<div class="main">
<div class="body container">
<div class="typecho-page-title">
<h2><?php _e('数据备份'); ?></h2>
</div>
<div class="row typecho-page-main" role="form">
<div id="dbmanager-plugin" class="col-mb-12 col-tb-8 col-tb-offset-2">
<ul class="typecho-option-tabs clearfix">
<li style="width:33%;" class="active"><a href="#tab-export"><?php _e('备份'); ?></a></li>
<li style="width:33%;"><a href="#tab-import" id="tab-files-btn"><?php _e('导入'); ?></a></li>
<li style="width:33%;"><a href="#tab-optimize" id="tab-files-btn"><?php _e('优化'); ?></a></li>
</ul>
<div id="tab-export" class="tab-content">
<form action="<?php $options->index('/action/dbmanager?export'); ?>" method="post" enctype="application/x-www-form-urlencoded">
<ul class="typecho-option" id="typecho-option-item-tableSelect-0">
<li>
<label class="typecho-label" for="tableSelect-0"><?php _e('数据表'); ?></label>
<select name="tableSelect[]" id="tableSelect-0" size="10" multiple="multiple" class="w-100 mono" style="height: 100%;">
<?php foreach ($tables as $table): ?>
<option value="<?php echo $table; ?>" selected="selected"><?php echo $table; ?></option>
<?php endforeach; ?>
</select>
</li>
</ul>
<ul class="typecho-option" id="typecho-option-item-filename-1">
<li>
<label class="typecho-label" for="filename-0-1"><?php _e('备份文件名'); ?></label>
<input id="filename-0-1" name="fileName" type="text" class="w-100" value="<?php echo 'typecho_' . date('YmdHi', Typecho_Date::gmtTime() + (Typecho_Date::$timezoneOffset - Typecho_Date::$serverTimezoneOffset)) . '_' . sprintf('%u', crc32(uniqid())) . '.sql'; ?>">
<p class="description"><?php _e('备份文件默认生成在插件的 backup 文件夹下'); ?></p>
</li>
</ul>
<ul class="typecho-option" id="typecho-option-item-bakplace-2">
<li>
<label class="typecho-label"><?php _e('备份保存'); ?></label>
<span>
<input name="bakplace" type="radio" value="0" id="bakplace-0" checked="true">
<label for="bakplace-0"><?php _e('本地'); ?></label>
</span>
<span>
<input name="bakplace" type="radio" value="1" id="bakplace-1">
<label for="bakplace-1"><?php _e('服务器'); ?></label>
</span>
<p class="description"></p>
</li>
</ul>
<ul class="typecho-option typecho-option-submit" id="typecho-option-item-submit-3">
<li>
<button type="submit" class="primary"><?php _e('开始备份'); ?></button>
</li>
</ul>
</form>
</div>
<div id="tab-import" class="tab-content hidden">
<div class="typecho-list">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all"></label>
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要导入这些备份吗?'); ?>" href="<?php $options->index('/action/dbmanager?import'); ?>"><?php _e('导入'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些备份吗?'); ?>" href="<?php $options->index('/action/dbmanager?delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</div>
</form>
</div>
<form method="post" name="manageBackup" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="8">
<col width="50%">
<col width="27%">
<col width="15%">
</colgroup>
<thead>
<tr>
<th> </th>
<th><?php _e('备份文件'); ?></th>
<th><?php _e('备份时间'); ?></th>
<th><?php _e('文件大小'); ?></th>
</tr>
</thead>
<tbody>
<?php if (!empty($files)): ?>
<?php foreach ($files as $key => $file): ?>
<tr id="bid-<?php echo $key; ?>">
<td><input type="checkbox" value="<?php echo $file['name']; ?>" name="bid[]"></td>
<td><?php echo $file['name']; ?></td>
<td><?php echo $file['time']; ?></td>
<td><?php echo $file['size']; ?></td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr id="bid-no">
<td></td>
<td colspan="4"><?php _e('暂无备份文件'); ?></td>
<td></td>
<td></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</form>
</div>
</div>
<div id="tab-optimize" class="tab-content hidden">
<form action="<?php $options->index('/action/dbmanager?optimize'); ?>" method="post" enctype="application/x-www-form-urlencoded">
<ul class="typecho-option" id="typecho-option-item-tableSelect-0">
<li>
<label class="typecho-label" for="tableSelect-0"><?php _e('数据表'); ?></label>
<select name="tableSelect[]" id="tableSelect-0" size="10" multiple="multiple" class="w-100 mono" style="height: 100%;">
<?php foreach ($tables as $table): ?>
<option value="<?php echo $table; ?>" selected="selected"><?php echo $table; ?></option>
<?php endforeach; ?>
</select>
</li>
</ul>
<ul class="typecho-option typecho-option-submit" id="typecho-option-item-submit-1">
<li>
<button type="submit" class="primary"><?php _e('开始优化'); ?></button>
</li>
</ul>
</form>
</div>
</div>
</div>
</div>
</div>
<?php
include 'copyright.php';
include 'common-js.php';
include 'dbmanager-js.php';
include 'table-js.php';
include 'footer.php';
?>