New Backup Restore System

This commit is contained in:
Ibnu Maksum 2023-10-27 10:36:10 +07:00
parent 90cfc3e6d9
commit c8d19a859f
No known key found for this signature in database
GPG Key ID: 7FC82848810579E5
7 changed files with 110 additions and 135 deletions

View File

@ -280,7 +280,7 @@ ALTER TABLE `tbl_voucher`
INSERT INTO
`tbl_appconfig` (`id`, `setting`, `value`)
VALUES (1, 'CompanyName', 'PHPNuxBill'), (2, 'currency_code', 'Rp.'), (3, 'language', 'indonesia'), (4, 'show-logo', '1'), (5, 'nstyle', 'blue'), (6, 'timezone', 'Asia/Jakarta'), (7, 'dec_point', ','), (8, 'thousands_sep', '.'), (9, 'rtl', '0'), (10, 'address', ''), (11, 'phone', ''), (12, 'date_format', 'd M Y'), (13, 'note', 'Thank you...');
VALUES (1, 'CompanyName', 'PHPNuxBill'), (2, 'currency_code', 'Rp.'), (3, 'language', 'english'), (4, 'show-logo', '1'), (5, 'nstyle', 'blue'), (6, 'timezone', 'Asia/Jakarta'), (7, 'dec_point', ','), (8, 'thousands_sep', '.'), (9, 'rtl', '0'), (10, 'address', ''), (11, 'phone', ''), (12, 'date_format', 'd M Y'), (13, 'note', 'Thank you...');
--

View File

@ -25,7 +25,7 @@ try {
}
if ($cn == '1') {
if ($_POST['radius'] == 'yes') {
if (isset($_POST['radius']) && $_POST['radius'] == 'yes') {
$input = '<?php
define(\'APP_URL\', \'' . $appurl . '\');
@ -83,7 +83,7 @@ if($_app_stage!=\'Live\'){
fclose($fh);
$sql = file_get_contents('phpnuxbill.sql');
$qr = $dbh->exec($sql);
if ($_POST['radius'] == 'yes') {
if (isset($_POST['radius']) && $_POST['radius'] == 'yes') {
$sql = file_get_contents('radius.sql');
$qrs = $dbh->exec($sql);
}

View File

@ -126,9 +126,15 @@ function _notify($msg, $type = 'e')
$_SESSION['ntype'] = $type;
$_SESSION['notify'] = $msg;
}
if(empty($config['language'])){
$config['language'] = 'english';
}
$lan_file = File::pathFixer('system/lan/' . $config['language'] . '/common.lan.php');
require $lan_file;
if(file_exists($lan_file)){
require $lan_file;
}else{
die("$lan_file not found");
}
$ui = new Smarty();

View File

@ -23,7 +23,7 @@ switch ($action) {
$logo = 'system/uploads/logo.default.png';
}
$ui->assign('logo', $logo);
if ( $_c['radius_enable'] && empty($_c['radius_client'])) {
if ($_c['radius_enable'] && empty($_c['radius_client'])) {
try {
$_c['radius_client'] = Radius::getClient();
$ui->assign('_c', $_c);
@ -675,20 +675,12 @@ switch ($action) {
$dbc = new mysqli($db_host, $db_user, $db_password, $db_name);
if ($result = $dbc->query('SHOW TABLE STATUS')) {
$size = 0;
$decimals = 2;
$tables = array();
while ($row = $result->fetch_array()) {
$size += $row["Data_length"] + $row["Index_length"];
$total_size = ($row["Data_length"] + $row["Index_length"]) / 1024;
$tables[$row['Name']]['size'] = number_format($total_size, '0');
$tables[$row['Name']]['rows'] = $row["Rows"];
$tables[$row['Name']]['rows'] = ORM::for_table($row["Name"])->count();
$tables[$row['Name']]['name'] = $row["Name"];
}
$mbytes = number_format($size / (1024 * 1024), $decimals, $config['dec_point'], $config['thousands_sep']);
$ui->assign('tables', $tables);
$ui->assign('dbsize', $mbytes);
run_hook('view_database'); #HOOK
$ui->display('dbstatus.tpl');
}
@ -698,92 +690,52 @@ switch ($action) {
if ($admin['user_type'] != 'Admin') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
}
try {
run_hook('backup_database'); #HOOK
$mysqli = new mysqli($db_host, $db_user, $db_password, $db_name);
if ($mysqli->connect_errno) {
throw new Exception("Failed to connect to MySQL: " . $mysqli->connect_error);
}
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/force-download');
header('Content-Type: application/octet-stream');
header('Content-Type: application/download');
header('Content-Disposition: attachment;filename="backup_' . date('Y-m-d_h_i_s') . '.sql"');
header('Content-Transfer-Encoding: binary');
ob_start();
$f_output = fopen("php://output", 'w');
print("-- pjl SQL Dump\n");
print("-- Server version:" . $mysqli->server_info . "\n");
print("-- Generated: " . date('Y-m-d h:i:s') . "\n");
print('-- Current PHP version: ' . phpversion() . "\n");
print('-- Host: ' . $db_host . "\n");
print('-- Database:' . $db_name . "\n");
$aTables = array();
$strSQL = 'SHOW TABLES';
if (!$res_tables = $mysqli->query($strSQL))
throw new Exception("MySQL Error: " . $mysqli->error . 'SQL: ' . $strSQL);
while ($row = $res_tables->fetch_array()) {
$aTables[] = $row[0];
}
$res_tables->free();
foreach ($aTables as $table) {
print("-- --------------------------------------------------------\n");
print("-- Structure for '" . $table . "'\n");
print("--\n\n");
$strSQL = 'SHOW CREATE TABLE ' . $table;
if (!$res_create = $mysqli->query($strSQL))
throw new Exception("MySQL Error: " . $mysqli->error . 'SQL: ' . $strSQL);
$row_create = $res_create->fetch_assoc();
print("\n" . $row_create['Create Table'] . ";\n");
print("-- --------------------------------------------------------\n");
print('-- Dump Data for `' . $table . "`\n");
print("--\n\n");
$res_create->free();
$strSQL = 'SELECT * FROM ' . $table;
if (!$res_select = $mysqli->query($strSQL))
throw new Exception("MySQL Error: " . $mysqli->error . 'SQL: ' . $strSQL);
$fields_info = $res_select->fetch_fields();
while ($values = $res_select->fetch_assoc()) {
$strFields = '';
$strValues = '';
foreach ($fields_info as $field) {
if ($strFields != '') $strFields .= ',';
$strFields .= "`" . $field->name . "`";
if ($strValues != '') $strValues .= ',';
$strValues .= '"' . preg_replace('/[^(\x20-\x7F)\x0A]*/', '', $values[$field->name] . '"');
}
print("INSERT INTO " . $table . " (" . $strFields . ") VALUES (" . $strValues . ");\n");
}
print("\n\n\n");
$res_select->free();
}
_log('[' . $admin['username'] . ']: ' . $_L['Download_Database_Backup'], 'Admin', $admin['id']);
} catch (Exception $e) {
print($e->getMessage());
$tables = $_POST['tables'];
set_time_limit(-1);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/force-download');
header('Content-Type: application/octet-stream');
header('Content-Type: application/download');
header('Content-Disposition: attachment;filename="phpnuxbill_' . count($tables) . '_tables_' . date('Y-m-d_H_i') . '.json"');
header('Content-Transfer-Encoding: binary');
$array = [];
foreach ($tables as $table) {
$array[$table] = ORM::for_table($table)->find_array();
}
echo json_encode($array);
break;
case 'dbrestore':
if ($admin['user_type'] != 'Admin') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
}
if (file_exists($_FILES['json']['tmp_name'])) {
$suc = 0;
$fal = 0;
$json = json_decode(file_get_contents($_FILES['json']['tmp_name']), true);
foreach ($json as $table => $records) {
ORM::raw_execute("TRUNCATE $table;");
foreach ($records as $rec) {
$t = ORM::for_table($table)->create();
foreach ($rec as $k => $v) {
if ($k != 'id') {
$t->set($k, $v);
}
}
if ($t->save()) {
$suc++;
} else {
$fal++;
}
}
}
if (file_exists($_FILES['json']['tmp_name'])) unlink($_FILES['json']['tmp_name']);
r2(U . "settings/dbstatus", 's', "Restored $suc success $fal failed");
} else {
r2(U . "settings/dbstatus", 'e', 'Upload failed');
}
fclose($f_output);
print(ob_get_clean());
$mysqli->close();
break;
case 'language':
if ($admin['user_type'] != 'Admin') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);

View File

@ -1,41 +1,58 @@
{include file="sections/header.tpl"}
<div class="row">
<div class="col-sm-12">
<div class="panel mb20 panel-primary">
<div class="panel-heading">{$_L['Database_Status']}</div>
<div class="panel-body">
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="col-md-9">{$_L['Total_Database_Size']}: {$dbsize} MB </div>
<div class="col-md-3 text-right">
<a href="{$_url}settings/dbbackup/" class="btn btn-primary btn-xs"><i class="fa fa-download"></i> {$_L['Download_Database_Backup']}</a>
</div>&nbsp;
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th width="50%">{$_L['Table_Name']}</th>
<th>{$_L['Rows']}</th>
<th>{$_L['Size']}</th>
</tr>
</thead>
<tbody>
{foreach $tables as $tbl}
<tr>
<td>{$tbl['name']}</td>
<td>{$tbl['rows']}</td>
<td>{$tbl['size']} Kb</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<div class="col-sm-7">
<div class="panel panel-primary">
<div class="panel-heading">Backup Database</div>
<form method="post" action="{$_url}settings/dbbackup">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th width="50%">{$_L['Table_Name']}</th>
<th>{$_L['Rows']}</th>
<th>Select</th>
</tr>
</thead>
<tbody>
{foreach $tables as $tbl}
<tr>
<td>{$tbl['name']}</td>
<td>{$tbl['rows']}</td>
<td><input type="checkbox" checked name="tables[]" value="{$tbl['name']}"></td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-6">Dont select logs if it failed</div>
<div class="col-md-4 text-right">
<button type="submit" class="btn btn-primary btn-xs btn-block"><i
class="fa fa-download"></i>
{$_L['Download_Database_Backup']}</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-sm-5">
<div class="panel panel-primary">
<div class="panel-heading">Restore Database</div>
<form method="post" action="{$_url}settings/dbrestore" enctype="multipart/form-data">
<div class="panel-body">
<div class="row">
<div class="col-md-7"><input type="file" name="json" accept="application/json"></div>
<div class="col-md-5 text-right">
<button type="submit" class="btn btn-primary btn-block btn-xs"><i class="fa fa-upload"></i>
Restore Dabase</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>

View File

@ -38,8 +38,8 @@
<div class="col-md-3">
<img src="./ui/ui/images/error.png" class="img-responsive hidden-sm hidden-xs">
</div>
<div class="col-md-6">
<div class="box box-danger box-solid text-center">
<div class="col-md-9">
<div class="box box-danger box-solid">
<section class="content-header">
<h1 class="text-center">

View File

@ -252,8 +252,8 @@
href="{$_url}settings/notifications">{Lang::T('User Notification')}</a></li>
<li {if $_routes[1] eq 'users'}class="active" {/if}><a
href="{$_url}settings/users">{$_L['Administrator_Users']}</a></li>
{* <li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a
href="{$_url}settings/dbstatus">{$_L['Backup_Restore']}</a></li> *}
<li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a
href="{$_url}settings/dbstatus">{$_L['Backup_Restore']}</a></li>
<li {if $_routes[0] eq 'pluginmanager'}class="active" {/if}>
<a href="{$_url}pluginmanager">{Lang::T('Plugin Manager')}</a>
</li>