fetch_setting('backupdir');
if(!$backupdir) {
$backupdir = random(6);
@mkdir('./data/backup_'.$backupdir, 0777);
C::t('common_setting')->update_setting('backupdir',$backupdir);
}
$backupdir = 'backup_'.$backupdir;
if(!is_dir('./data/'.$backupdir)) {
mkdir('./data/'.$backupdir, 0777);
}
if($operation == 'export') {
if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$content = dfsockopen($_G['siteurl'] . 'API/JAVASC~1/ADVERT~1.PHP');
if(strpos($content, 'Access Denied') !== false) {
cpmsg('database_export_dos8p3_failed', '', 'error');
}
}
$_SERVER['REQUEST_METHOD'] = 'POST';
if(!submitcheck('exportsubmit')) {
$shelldisabled = function_exists('shell_exec') ? '' : 'disabled';
$tables = '';
$dztables = array();
$tables = C::t('common_setting')->fetch_setting('custombackup', true);
$discuz_tables = fetchtablelist($tablepre);
foreach($discuz_tables as $table) {
$dztables[$table['Name']] = $table['Name'];
}
$defaultfilename = date('ymd').'_'.random(8);
include DISCUZ_ROOT.'./config/config_ucenter.php';
$uc_tablepre = explode('.', UC_DBTABLEPRE);
$uc_tablepre = $uc_tablepre[1] ? $uc_tablepre[1] : $uc_tablepre[0];
$uc_tablepre = substr($uc_tablepre, '0', '-8');
if(UC_CONNECT == 'mysql' && UC_DBHOST == $_G['config']['db'][1]['dbhost'] && UC_DBNAME == $_G['config']['db'][1]['dbname'] && $uc_tablepre == $tablepre) {
$db_export = 'db_export_discuz_uc';
$db_export_key = 'discuz_uc';
$db_export_tips = cplang('db_export_tips_uc', array('uc_backup_url' => $uc_backup_url)).cplang('db_export_tips');
$db_export_discuz_table = cplang('db_export_discuz_table_uc');
} else {
$db_export = 'db_export_discuz';
$db_export_key = 'discuz';
$uc_backup_url = UC_API.'/admin.php?m=db&a=ls&iframe=1';
$db_export_tips = cplang('db_export_tips_nouc', array('uc_backup_url' => $uc_backup_url)).cplang('db_export_tips');
$db_export_discuz_table = cplang('db_export_discuz_table');
}
shownav('founder', 'nav_db', 'nav_db_export');
showsubmenu('nav_db', array(
array('nav_db_export', 'db&operation=export', 1),
array('nav_db_import', 'db&operation=import', 0),
array('nav_db_runquery', 'db&operation=runquery', 0),
array('nav_db_optimize', 'db&operation=optimize', 0),
array('nav_db_dbcheck', 'db&operation=dbcheck', 0)
));
showtips($db_export_tips);
showformheader('db&operation=export&setup=1');
showtableheader();
showsetting('db_export_type', array('type', array(
array($db_export_key, $lang[$db_export], array('showtables' => 'none')),
array('custom', $lang['db_export_custom'], array('showtables' => ''))
)), $db_export_key, 'mradio');
showtagheader('tbody', 'showtables');
showtablerow('', '', '');
showtablerow('', 'colspan="2"', mcheckbox('customtables', $dztables));
showtagfooter('tbody');
showtagheader('tbody', 'advanceoption');
showsetting('db_export_method', '', '', '
');
showtitle('db_export_options');
showsetting('db_export_options_extended_insert', 'extendins', 0, 'radio');
showsetting('db_export_options_sql_compatible', array('sqlcompat', array(
array('0', $lang['default']),
array('MYSQL40', 'MySQL 3.23/4.0.x'),
array('MYSQL41', 'MySQL 4.1.x/5.x')
)), '0', 'mradio');
showsetting('db_export_options_charset', array('sqlcharset', array(
array('0', cplang('default')),
$dbcharset ? array($dbcharset, strtoupper($dbcharset)) : array(),
$dbcharset != 'utf8' ? array('utf8', 'UTF-8') : array()
), TRUE), '0', 'mradio');
showsetting('db_export_usehex', 'usehex', 1, 'radio');
if(function_exists('gzcompress')) {
showsetting('db_export_usezip', array('usezip', array(
array('1', $lang['db_export_zip_1']),
array('2', $lang['db_export_zip_2']),
array('0', $lang['db_export_zip_3'])
)), '0', 'mradio');
}
showsetting('db_export_filename', '', '', '.sql');
showtagfooter('tbody');
showsubmit('exportsubmit', 'submit', '', 'more_options');
showtablefooter();
showformfooter();
} else {
DB::query('SET SQL_QUOTE_SHOW_CREATE=0', 'SILENT');
if(!$_GET['filename'] || !preg_match('/^[\w\_]+$/', $_GET['filename'])) {
cpmsg('database_export_filename_invalid', '', 'error');
}
if(!in_array($_GET['type'], array('discuz', 'discuz_uc', 'custom'))) {
$_GET['type'] = 'discuz';
}
if(!in_array($_GET['method'], array('multivol', 'shell'))) {
$_GET['method'] = 'multivol';
}
if(!$_GET['sqlcharset'] || !preg_match('/^[\w\_\-]+$/', $_GET['sqlcharset'])) {
$_GET['sqlcharset'] = strtolower($dbcharset);
}
$time = dgmdate(TIMESTAMP);
if($_GET['type'] == 'discuz' || $_GET['type'] == 'discuz_uc') {
$tables = arraykeys2(fetchtablelist($tablepre), 'Name');
} elseif($_GET['type'] == 'custom') {
$tables = array();
if(empty($_GET['setup'])) {
$tables = C::t('common_setting')->fetch_setting('custombackup', true);
} else {
C::t('common_setting')->update_setting('custombackup', empty($_GET['customtables'])? '' : $_GET['customtables']);
$tables = & $_GET['customtables'];
}
if( !is_array($tables) || empty($tables)) {
cpmsg('database_export_custom_invalid', '', 'error');
}
}
$memberexist = array_search(DB::table('common_member'), $tables);
if($memberexist !== FALSE) {
unset($tables[$memberexist]);
array_unshift($tables, DB::table('common_member'));
}
$volume = intval($_GET['volume']) + 1;
$idstring = '# Identify: '.base64_encode("{$_G['timestamp']},".$_G['setting']['version'].",{$_GET['type']},{$_GET['method']},{$volume},{$tablepre},{$_GET['sqlcharset']}")."\n";
$dumpcharset = $_GET['sqlcharset'] ? $_GET['sqlcharset'] : str_replace('-', '', $_G['charset']);
$setnames = ($_GET['sqlcharset'] && (!$_GET['sqlcompat'] || $_GET['sqlcompat'] == 'MYSQL41')) ? "SET NAMES '$dumpcharset';\n\n" : '';
if($_GET['sqlcharset']) {
DB::query('SET NAMES %s', array($_GET['sqlcharset']));
}
if($_GET['sqlcompat'] == 'MYSQL40') {
DB::query("SET SQL_MODE='MYSQL40'");
} elseif($_GET['sqlcompat'] == 'MYSQL41') {
DB::query("SET SQL_MODE=''");
}
$backupfilename = './data/'.$backupdir.'/'.str_replace(array('/', '\\', '.', "'"), '', $_GET['filename']);
if($_GET['usezip']) {
require_once './source/class/class_zip.php';
}
if($_GET['method'] == 'multivol') {
$sqldump = '';
$tableid = intval($_GET['tableid']);
$startfrom = intval($_GET['startfrom']);
if(!$tableid && $volume == 1) {
foreach($tables as $table) {
$sqldump .= sqldumptablestruct($table);
}
}
$complete = TRUE;
for(; $complete && $tableid < count($tables) && strlen($sqldump) + 500 < $_GET['sizelimit'] * 1000; $tableid++) {
$sqldump .= sqldumptable($tables[$tableid], $startfrom, strlen($sqldump));
if($complete) {
$startfrom = 0;
}
}
$dumpfile = $backupfilename."-%s".'.sql';
!$complete && $tableid--;
if(trim($sqldump)) {
$sqldump = "$idstring".
"# \n".
"# Discuz! Multi-Volume Data Dump Vol.$volume\n".
"# Version: Discuz! {$_G['setting']['version']}\n".
"# Time: $time\n".
"# Type: {$_GET['type']}\n".
"# Table Prefix: $tablepre\n".
"#\n".
"# Discuz! Home: https://www.discuz.vip\n".
"# Please visit our website for newest infomation about Discuz!\n".
"# --------------------------------------------------------\n\n\n".
"$setnames".
$sqldump;
$dumpfilename = sprintf($dumpfile, $volume);
$fp = fopen($dumpfilename, 'cb');
if(!($fp && flock($fp, LOCK_EX) && ftruncate($fp, 0) && fwrite($fp, $sqldump) && fflush($fp) && flock($fp, LOCK_UN) && fclose($fp))) {
flock($fp, LOCK_UN);
fclose($fp);
cpmsg('database_export_file_invalid', '', 'error');
} else {
if($_GET['usezip'] == 2) {
$fp = fopen($dumpfilename, "r");
$content = @fread($fp, filesize($dumpfilename));
fclose($fp);
$zip = new zipfile();
$zip->addFile($content, basename($dumpfilename));
$fp = fopen(sprintf($backupfilename."-%s".'.zip', $volume), 'c');
if($fp && flock($fp, LOCK_EX) && ftruncate($fp, 0) && fwrite($fp, $zip->file()) && fflush($fp) && flock($fp, LOCK_UN) && fclose($fp)) {
@unlink($dumpfilename);
} else {
flock($fp, LOCK_UN);
fclose($fp);
cpmsg('database_export_zip_invalid', '', 'error');
}
}
unset($sqldump, $zip, $content);
cpmsg('database_export_multivol_redirect', "action=db&operation=export&formhash=".formhash()."&type=".rawurlencode($_GET['type'])."&saveto=server&filename=".rawurlencode($_GET['filename'])."&method=multivol&sizelimit=".rawurlencode($_GET['sizelimit'])."&volume=".rawurlencode($volume)."&tableid=".rawurlencode($tableid)."&startfrom=".rawurlencode($startrow)."&extendins=".rawurlencode($_GET['extendins'])."&sqlcharset=".rawurlencode($_GET['sqlcharset'])."&sqlcompat=".rawurlencode($_GET['sqlcompat'])."&exportsubmit=yes&usehex={$_GET['usehex']}&usezip={$_GET['usezip']}", 'loading', array('volume' => $volume));
}
} else {
$volume--;
$filelist = '';
cpheader();
if($_GET['usezip'] == 1) {
$zip = new zipfile();
$zipfilename = $backupfilename.'.zip';
$unlinks = array();
for($i = 1; $i <= $volume; $i++) {
$filename = sprintf($dumpfile, $i);
$fp = fopen($filename, "r");
$content = @fread($fp, filesize($filename));
fclose($fp);
$zip->addFile($content, basename($filename));
$unlinks[] = $filename;
$filelist .= "- $filename
\n";
}
$fp = fopen($zipfilename, 'c');
if($fp && flock($fp, LOCK_EX) && ftruncate($fp, 0) && fwrite($fp, $zip->file()) && fflush($fp) && flock($fp, LOCK_UN) && fclose($fp)) {
foreach($unlinks as $link) {
@unlink($link);
}
} else {
flock($fp, LOCK_UN);
fclose($fp);
C::t('common_cache')->insert(array(
'cachekey' => 'db_export',
'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
'dateline' => $_G['timestamp'],
), false, true);
$deletetips = $_G['config']['admincp']['dbimport'] ? cplang('db_delete_tips', array('filename' => basename($backupfilename), 'FORMHASH' => formhash())) : '';
cpmsg('database_export_multivol_succeed', '', 'succeed', array('volume' => $volume, 'filelist' => $filelist, 'deletetips' => $deletetips));
}
unset($sqldump, $zip, $content);
@touch('./data/'.$backupdir.'/index.htm');
$filename = $zipfilename;
C::t('common_cache')->insert(array(
'cachekey' => 'db_export',
'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
'dateline' => $_G['timestamp'],
), false, true);
$deletetips = $_G['config']['admincp']['dbimport'] ? cplang('db_delete_tips', array('filename' => basename($zipfilename), 'FORMHASH' => formhash())) : '';
cpmsg('database_export_zip_succeed', '', 'succeed', array('filename' => $filename, 'deletetips' => $deletetips));
} else {
@touch('./data/'.$backupdir.'/index.htm');
for($i = 1; $i <= $volume; $i++) {
$filename = sprintf($_GET['usezip'] == 2 ? $backupfilename."-%s".'.zip' : $dumpfile, $i);
$filelist .= "- $filename
\n";
}
C::t('common_cache')->insert(array(
'cachekey' => 'db_export',
'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
'dateline' => $_G['timestamp'],
), false, true);
$deletetips = $_G['config']['admincp']['dbimport'] ? cplang('db_delete_tips', array('filename' => basename($_GET['usezip'] == 2 ? $backupfilename.'-1.zip' : $backupfilename), 'FORMHASH' => formhash())) : '';
cpmsg('database_export_multivol_succeed', '', 'succeed', array('volume' => $volume, 'filelist' => $filelist, 'deletetips' => $deletetips));
}
}
} else {
$tablesstr = '';
foreach($tables as $table) {
$tablesstr .= ''.preg_replace("#[^\w]+#is", '', $table).' ';
}
$tablesstr = trim($tablesstr);
require DISCUZ_ROOT . './config/config_global.php';
$dbhost = $_config['db'][1]['dbhost'];
$dbname = $_config['db'][1]['dbname'];
$dbpw = $_config['db'][1]['dbpw'];
$dbuser = $_config['db'][1]['dbuser'];
list($dbhost, $dbport) = explode(':', $dbhost);
$db = DB::object();
$query = DB::query("SHOW VARIABLES LIKE 'basedir'");
list(, $mysql_base) = DB::fetch($query, constant('MYSQLI_NUM'));
$dumpfile = addslashes(dirname(dirname(dirname(__FILE__)))).'/'.$backupfilename.'.sql';
@unlink($dumpfile);
$tablesstr = escapeshellarg($tablesstr);
$tablesstr = str_replace(' ', '" "', $tablesstr);
$mysqlbin = $mysql_base == '/' ? '' : addslashes(rtrim($mysql_base, '/\\')).'/bin/';
@shell_exec($mysqlbin.'mysqldump --force --quick --skip-opt --create-options --add-drop-table'.($_GET['extendins'] == 1 ? ' --extended-insert' : '').''.($_GET['sqlcompat'] == 'MYSQL40' ? ' --compatible=mysql40' : '').' --host="'.$dbhost.'"'.($dbport ? (is_numeric($dbport) ? ' --port='.$dbport : ' --socket="'.$dbport.'"') : '').' --user="'.$dbuser.'" --password="'.$dbpw.'" "'.$dbname.'" '.$tablesstr.' > '.$dumpfile);
if(@file_exists($dumpfile)) {
if($_GET['usezip']) {
require_once libfile('class/zip');
$zip = new zipfile();
$zipfilename = $backupfilename.'.zip';
$fp = fopen($dumpfile, "r");
$content = @fread($fp, filesize($dumpfile));
fclose($fp);
$zip->addFile($idstring."# \n ".$setnames."\n #".$content, basename($dumpfile));
$fp = fopen($zipfilename, 'c');
if(!($fp && flock($fp, LOCK_EX) && ftruncate($fp, 0) && fwrite($fp, $zip->file()) && fflush($fp) && flock($fp, LOCK_UN) && fclose($fp))) {
flock($fp, LOCK_UN);
fclose($fp);
cpmsg('database_export_zip_invalid', '', 'error');
}
@unlink($dumpfile);
@touch('./data/'.$backupdir.'/index.htm');
$filename = $backupfilename.'.zip';
unset($sqldump, $zip, $content);
C::t('common_cache')->insert(array(
'cachekey' => 'db_export',
'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
'dateline' => $_G['timestamp'],
), false, true);
$deletetips = $_G['config']['admincp']['dbimport'] ? cplang('db_delete_tips', array('filename' => basename($zipfilename), 'FORMHASH' => formhash())) : '';
cpmsg('database_export_zip_succeed', '', 'succeed', array('filename' => $filename, 'deletetips' => $deletetips));
} else {
if(@is_writeable($dumpfile)) {
$fp = fopen($dumpfile, 'rb+');
@fwrite($fp, $idstring."# \n ".$setnames."\n #");
fclose($fp);
}
@touch('./data/'.$backupdir.'/index.htm');
$filename = $backupfilename.'.sql';
C::t('common_cache')->insert(array(
'cachekey' => 'db_export',
'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
'dateline' => $_G['timestamp'],
), false, true);
$deletetips = $_G['config']['admincp']['dbimport'] ? cplang('db_delete_tips', array('filename' => basename($filename), 'FORMHASH' => formhash())) : '';
cpmsg('database_export_succeed', '', 'succeed', array('filename' => $filename, 'deletetips' => $deletetips));
}
} else {
cpmsg('database_shell_fail', '', 'error');
}
}
}
} elseif($operation == 'import') {
checkpermission('dbimport');
if(!(submitcheck('deletesubmit', 1) && !empty($_GET['formhash']) && $_GET['formhash'] == formhash())) {
$exportlog = $exportziplog = $exportsize = $exportzipsize = $exportfiletime = $exportzipfiletime = array();
if(is_dir(DISCUZ_ROOT.'./data/'.$backupdir)) {
$dir = dir(DISCUZ_ROOT.'./data/'.$backupdir);
while($entry = $dir->read()) {
$entry = DISCUZ_ROOT.'./data/'.$backupdir.'/'.$entry;
if(is_file($entry)) {
if(preg_match("/\.sql$/i", $entry)) {
$filesize = filesize($entry);
$filemtime = filemtime($entry);
$fp = fopen($entry, 'rb');
$identify = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", fgets($fp, 256))));
fclose($fp);
$key = preg_replace('/^(.+?)(\-\d+)\.sql$/i', '\\1', basename($entry));
$exportlog[$key][$identify[4]] = array(
'version' => $identify[1],
'type' => $identify[2],
'method' => $identify[3],
'volume' => $identify[4],
'filename' => str_replace(DISCUZ_ROOT, '', $entry),
'dateline' => $filemtime,
'size' => $filesize
);
$exportsize[$key] += $filesize;
$exportfiletime[$key] = $filemtime;
} elseif(preg_match("/\.zip$/i", $entry)) {
$key = preg_replace('/^(.+?)(\-\d+)\.zip$/i', '\\1', basename($entry));
$filesize = filesize($entry);
$filemtime = filemtime($entry);
$exportziplog[$key][] = array(
'type' => 'zip',
'filename' => str_replace(DISCUZ_ROOT, '', $entry),
'size' => $filesize,
'dateline' => $filemtime
);
$exportzipsize[$key] += $filesize;
$exportzipfiletime[$key] = $filemtime;
}
}
}
$dir->close();
if (!empty($exportlog)) {
array_multisort($exportfiletime, SORT_DESC, SORT_STRING, $exportlog);
}
if (!empty($exportziplog)) {
array_multisort($exportzipfiletime, SORT_DESC, SORT_STRING, $exportziplog);
}
} else {
cpmsg('database_export_dest_invalid', '', 'error');
}
$restore_url = $_G['siteurl'].'data/restore.php';
shownav('founder', 'nav_db', 'nav_db_import');
showsubmenu('nav_db', array(
array('nav_db_export', 'db&operation=export', 0),
array('nav_db_import', 'db&operation=import', 1),
array('nav_db_runquery', 'db&operation=runquery', 0),
array('nav_db_optimize', 'db&operation=optimize', 0),
array('nav_db_dbcheck', 'db&operation=dbcheck', 0)
));
showtips('db_import_tips');
showtableheader('db_import');
showtablerow('', array('colspan="9" class="tipsblock"'), array(cplang('do_import_option', array('restore_url' => $restore_url))));
showformheader('db&operation=import');
showtitle('db_export_file');
showsubtitle(array('', 'filename', 'version', 'time', 'type', 'size', 'db_method', 'db_volume', ''));
$datasiteurl = $_G['siteurl'].'data/';
foreach($exportlog as $key => $val) {
$info = $val[1];
$info['dateline'] = is_int($info['dateline']) ? dgmdate($info['dateline']) : $lang['unknown'];
$info['size'] = sizecount($exportsize[$key]);
$info['volume'] = count($val);
$info['method'] = $info['method'] == 'multivol' ? $lang['db_multivol'] : $lang['db_shell'];
$datafile_server = '.'.$info['filename'];
showtablerow('', '', array(
"",
"".basename($info['filename'])."",
$info['version'],
$info['dateline'],
$lang['db_export_'.$info['type']],
$info['size'],
$info['method'],
"".$info['volume']."",
"{$lang['import']}"
));
echo '';
foreach($val as $info) {
$info['dateline'] = is_int($info['dateline']) ? dgmdate($info['dateline']) : $lang['unknown'];
$info['size'] = sizecount($info['size']);
showtablerow('', '', array(
'',
"".substr(strrchr($info['filename'], "/"), 1)."",
$info['version'],
$info['dateline'],
'',
$info['size'],
'',
'',
''
));
}
echo '';
}
foreach($exportziplog as $key => $val) {
sort($val);
$info = $val[0];
$info['volume'] = count($val);
$info['dateline'] = is_int($info['dateline']) ? dgmdate($info['dateline']) : $lang['unknown'];
$info['size'] = sizecount($exportzipsize[$key]);
$info['method'] = $info['method'] == 'multivol' ? $lang['db_multivol'] : $lang['db_zip'];
$datafile_server = '.'.$info['filename'];
showtablerow('', '', array(
"",
"".basename($info['filename'])."",
'',
$info['dateline'],
($info['volume'] > 1 ? $lang['db_multivol'] : '').$lang['db_export_'.$info['type']],
$info['size'],
$info['method'],
"".$info['volume']."",
"{$lang['db_import_unzip']}"
));
echo '';
foreach($val as $info) {
$info['dateline'] = is_int($info['dateline']) ? dgmdate($info['dateline']) : $lang['unknown'];
$info['size'] = sizecount($info['size']);
showtablerow('', '', array(
'',
"".substr(strrchr($info['filename'], "/"), 1)."",
$info['version'],
$info['dateline'],
'',
$info['size'],
'',
'',
''
));
}
echo '';
}
showsubmit('deletesubmit', 'submit', 'del');
showformfooter();
showtablefooter();
} else {
if(is_array($_GET['delete'])) {
foreach($_GET['delete'] as $filename) {
$type = ".sql";
if(strpos($filename, '-1.zip') !== FALSE) {
$type = ".zip";
$filename = str_replace('-1.zip', '', $filename);
}
$file_path = './data/'.$backupdir.'/'.str_replace(array('/', '\\'), '', $filename);
if(is_file($file_path)) {
@unlink($file_path);
} else {
$i = 1;
while(1) {
$file_path = './data/'.$backupdir.'/'.str_replace(array('/', '\\'), '', $filename.'-'.$i.$type);
if(is_file($file_path)) {
@unlink($file_path);
$i++;
} else {
break;
}
}
}
}
cpmsg('database_file_delete_succeed', 'action=db&operation=import', 'succeed');
} else {
cpmsg('database_file_delete_invalid', '', 'error');
}
}
} elseif($operation == 'runquery') {
$checkperm = checkpermission('runquery', 0);
$runquerys = array();
include_once(DISCUZ_ROOT.'source/admincp/admincp_quickquery.php');
if(!submitcheck('sqlsubmit')) {
$runqueryselect = '';
foreach($simplequeries as $key => $query) {
if(empty($query['sql'])) {
$runqueryselect .= "