admincp_db.php 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Comsenz Inc.
  4. * This is NOT a freeware, use is subject to license terms
  5. *
  6. * $Id: admincp_db.php 34644 2014-06-16 09:07:08Z hypowang $
  7. */
  8. if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) {
  9. exit('Access Denied');
  10. }
  11. $db = & DB::object();
  12. $tabletype = $db->version() > '4.1' ? 'Engine' : 'Type';
  13. $tablepre = $_G['config']['db'][1]['tablepre'];
  14. $dbcharset = $_G['config']['db'][1]['dbcharset'];
  15. require_once libfile('function/attachment');
  16. cpheader();
  17. if(!isfounder()) cpmsg('noaccess_isfounder', '', 'error');
  18. $excepttables = array($tablepre.'common_admincp_session', $tablepre.'common_syscache', $tablepre.'common_failedlogin', $tablepre.'forum_rsscache', $tablepre.'common_searchindex', $tablepre.'forum_spacecache', $tablepre.'common_session');
  19. $backupdir = C::t('common_setting')->fetch('backupdir');
  20. if(!$backupdir) {
  21. $backupdir = random(6);
  22. @mkdir('./data/backup_'.$backupdir, 0777);
  23. C::t('common_setting')->update('backupdir',$backupdir);
  24. }
  25. $backupdir = 'backup_'.$backupdir;
  26. if(!is_dir('./data/'.$backupdir)) {
  27. mkdir('./data/'.$backupdir, 0777);
  28. }
  29. if($operation == 'export') {
  30. $_SERVER['REQUEST_METHOD'] = 'POST';
  31. if(!submitcheck('exportsubmit')) {
  32. $shelldisabled = function_exists('shell_exec') ? '' : 'disabled';
  33. $tables = '';
  34. $dztables = array();
  35. $tables = C::t('common_setting')->fetch('custombackup', true);
  36. $discuz_tables = fetchtablelist($tablepre);
  37. foreach($discuz_tables as $table) {
  38. $dztables[$table['Name']] = $table['Name'];
  39. }
  40. $defaultfilename = date('ymd').'_'.random(8);
  41. include DISCUZ_ROOT.'./config/config_ucenter.php';
  42. $uc_tablepre = explode('.', UC_DBTABLEPRE);
  43. $uc_tablepre = $uc_tablepre[1] ? $uc_tablepre[1] : $uc_tablepre[0];
  44. $uc_tablepre = substr($uc_tablepre, '0', '-8');
  45. if(UC_CONNECT == 'mysql' && UC_DBHOST == $_G['config']['db'][1]['dbhost'] && UC_DBNAME == $_G['config']['db'][1]['dbname'] && $uc_tablepre == $tablepre) {
  46. $db_export = 'db_export_discuz_uc';
  47. $db_export_key = 'discuz_uc';
  48. $db_export_tips = cplang('db_export_tips_uc', array('uc_backup_url' => $uc_backup_url)).cplang('db_export_tips');
  49. $db_export_discuz_table = cplang('db_export_discuz_table_uc');
  50. } else {
  51. $db_export = 'db_export_discuz';
  52. $db_export_key = 'discuz';
  53. $uc_backup_url = UC_API.'/admin.php?m=db&a=ls&iframe=1';
  54. $db_export_tips = cplang('db_export_tips_nouc', array('uc_backup_url' => $uc_backup_url)).cplang('db_export_tips');
  55. $db_export_discuz_table = cplang('db_export_discuz_table');
  56. }
  57. shownav('founder', 'nav_db', 'nav_db_export');
  58. showsubmenu('nav_db', array(
  59. array('nav_db_export', 'db&operation=export', 1),
  60. array('nav_db_import', 'db&operation=import', 0),
  61. array('nav_db_runquery', 'db&operation=runquery', 0),
  62. array('nav_db_optimize', 'db&operation=optimize', 0),
  63. array('nav_db_dbcheck', 'db&operation=dbcheck', 0)
  64. ));
  65. showtips($db_export_tips);
  66. showformheader('db&operation=export&setup=1');
  67. showtableheader();
  68. showsetting('db_export_type', array('type', array(
  69. array($db_export_key, $lang[$db_export], array('showtables' => 'none')),
  70. array('custom', $lang['db_export_custom'], array('showtables' => ''))
  71. )), $db_export_key, 'mradio');
  72. showtagheader('tbody', 'showtables');
  73. showtablerow('', '', '<input class="checkbox" name="chkall" onclick="checkAll(\'prefix\', this.form, \'customtables\', \'chkall\', true)" checked="checked" type="checkbox" id="chkalltables" /><label for="chkalltables"> '.cplang('db_export_custom_select_all').' - '.$db_export_discuz_table ).'</label>';
  74. showtablerow('', 'colspan="2"', mcheckbox('customtables', $dztables));
  75. showtagfooter('tbody');
  76. showtagheader('tbody', 'advanceoption');
  77. showsetting('db_export_method', '', '', '<ul class="nofloat"><li><input class="radio" type="radio" name="method" value="shell" '.$shelldisabled.' onclick="if(\''.intval($db->version() < '4.1').'\') {if(this.form.sqlcompat[2].checked==true) this.form.sqlcompat[0].checked=true; this.form.sqlcompat[2].disabled=true; this.form.sizelimit.disabled=true;} else {this.form.sqlcharset[0].checked=true; for(var i=1; i<=5; i++) {if(this.form.sqlcharset[i]) this.form.sqlcharset[i].disabled=true;}}" id="method_shell" /><label="method_shell"> '.$lang['db_export_shell'].'</label></li><li><input class="radio" type="radio" name="method" value="multivol" checked="checked" onclick="this.form.sqlcompat[2].disabled=false; this.form.sizelimit.disabled=false; for(var i=1; i<=5; i++) {if(this.form.sqlcharset[i]) this.form.sqlcharset[i].disabled=false;}" id="method_multivol" /><label for="method_multivol"> '.$lang['db_export_multivol'].'</label> <input type="text" class="txt" size="40" name="sizelimit" value="2048" /></li></ul>');
  78. showtitle('db_export_options');
  79. showsetting('db_export_options_extended_insert', 'extendins', 0, 'radio');
  80. showsetting('db_export_options_sql_compatible', array('sqlcompat', array(
  81. array('', $lang['default']),
  82. array('MYSQL40', 'MySQL 3.23/4.0.x'),
  83. array('MYSQL41', 'MySQL 4.1.x/5.x')
  84. )), '', 'mradio');
  85. showsetting('db_export_options_charset', array('sqlcharset', array(
  86. array('', cplang('default')),
  87. $dbcharset ? array($dbcharset, strtoupper($dbcharset)) : array(),
  88. $db->version() > '4.1' && $dbcharset != 'utf8' ? array('utf8', 'UTF-8') : array()
  89. ), TRUE), 0, 'mradio');
  90. showsetting('db_export_usehex', 'usehex', 1, 'radio');
  91. if(function_exists('gzcompress')) {
  92. showsetting('db_export_usezip', array('usezip', array(
  93. array('1', $lang['db_export_zip_1']),
  94. array('2', $lang['db_export_zip_2']),
  95. array('0', $lang['db_export_zip_3'])
  96. )), 0, 'mradio');
  97. }
  98. showsetting('db_export_filename', '', '', '<input type="text" class="txt" name="filename" value="'.$defaultfilename.'" />.sql');
  99. showtagfooter('tbody');
  100. showsubmit('exportsubmit', 'submit', '', 'more_options');
  101. showtablefooter();
  102. showformfooter();
  103. } else {
  104. DB::query('SET SQL_QUOTE_SHOW_CREATE=0', 'SILENT');
  105. if(!$_GET['filename'] || !preg_match('/^[\w\_]+$/', $_GET['filename'])) {
  106. cpmsg('database_export_filename_invalid', '', 'error');
  107. }
  108. $time = dgmdate(TIMESTAMP);
  109. if($_GET['type'] == 'discuz' || $_GET['type'] == 'discuz_uc') {
  110. $tables = arraykeys2(fetchtablelist($tablepre), 'Name');
  111. } elseif($_GET['type'] == 'custom') {
  112. $tables = array();
  113. if(empty($_GET['setup'])) {
  114. $tables = C::t('common_setting')->fetch('custombackup', true);
  115. } else {
  116. C::t('common_setting')->update('custombackup', empty($_GET['customtables'])? '' : $_GET['customtables']);
  117. $tables = & $_GET['customtables'];
  118. }
  119. if( !is_array($tables) || empty($tables)) {
  120. cpmsg('database_export_custom_invalid', '', 'error');
  121. }
  122. }
  123. $memberexist = array_search(DB::table('common_member'), $tables);
  124. if($memberexist !== FALSE) {
  125. unset($tables[$memberexist]);
  126. array_unshift($tables, DB::table('common_member'));
  127. }
  128. $volume = intval($_GET['volume']) + 1;
  129. $idstring = '# Identify: '.base64_encode("$_G[timestamp],".$_G['setting']['version'].",{$_GET['type']},{$_GET['method']},{$volume},{$tablepre},{$dbcharset}")."\n";
  130. $dumpcharset = $_GET['sqlcharset'] ? $_GET['sqlcharset'] : str_replace('-', '', $_G['charset']);
  131. $setnames = ($_GET['sqlcharset'] && $db->version() > '4.1' && (!$_GET['sqlcompat'] || $_GET['sqlcompat'] == 'MYSQL41')) ? "SET NAMES '$dumpcharset';\n\n" : '';
  132. if($db->version() > '4.1') {
  133. if($_GET['sqlcharset']) {
  134. DB::query('SET NAMES %s', array($_GET['sqlcharset']));
  135. }
  136. if($_GET['sqlcompat'] == 'MYSQL40') {
  137. DB::query("SET SQL_MODE='MYSQL40'");
  138. } elseif($_GET['sqlcompat'] == 'MYSQL41') {
  139. DB::query("SET SQL_MODE=''");
  140. }
  141. }
  142. $backupfilename = './data/'.$backupdir.'/'.str_replace(array('/', '\\', '.', "'"), '', $_GET['filename']);
  143. if($_GET['usezip']) {
  144. require_once './source/class/class_zip.php';
  145. }
  146. if($_GET['method'] == 'multivol') {
  147. $sqldump = '';
  148. $tableid = intval($_GET['tableid']);
  149. $startfrom = intval($_GET['startfrom']);
  150. if(!$tableid && $volume == 1) {
  151. foreach($tables as $table) {
  152. $sqldump .= sqldumptablestruct($table);
  153. }
  154. }
  155. $complete = TRUE;
  156. for(; $complete && $tableid < count($tables) && strlen($sqldump) + 500 < $_GET['sizelimit'] * 1000; $tableid++) {
  157. $sqldump .= sqldumptable($tables[$tableid], $startfrom, strlen($sqldump));
  158. if($complete) {
  159. $startfrom = 0;
  160. }
  161. }
  162. $dumpfile = $backupfilename."-%s".'.sql';
  163. !$complete && $tableid--;
  164. if(trim($sqldump)) {
  165. $sqldump = "$idstring".
  166. "# <?php exit();?>\n".
  167. "# Discuz! Multi-Volume Data Dump Vol.$volume\n".
  168. "# Version: Discuz! {$_G[setting][version]}\n".
  169. "# Time: $time\n".
  170. "# Type: {$_GET['type']}\n".
  171. "# Table Prefix: $tablepre\n".
  172. "#\n".
  173. "# Discuz! Home: http://www.discuz.com\n".
  174. "# Please visit our website for newest infomation about Discuz!\n".
  175. "# --------------------------------------------------------\n\n\n".
  176. "$setnames".
  177. $sqldump;
  178. $dumpfilename = sprintf($dumpfile, $volume);
  179. @$fp = fopen($dumpfilename, 'wb');
  180. @flock($fp, 2);
  181. if(@!fwrite($fp, $sqldump)) {
  182. @fclose($fp);
  183. cpmsg('database_export_file_invalid', '', 'error');
  184. } else {
  185. fclose($fp);
  186. if($_GET['usezip'] == 2) {
  187. $fp = fopen($dumpfilename, "r");
  188. $content = @fread($fp, filesize($dumpfilename));
  189. fclose($fp);
  190. $zip = new zipfile();
  191. $zip->addFile($content, basename($dumpfilename));
  192. $fp = fopen(sprintf($backupfilename."-%s".'.zip', $volume), 'w');
  193. if(@fwrite($fp, $zip->file()) !== FALSE) {
  194. @unlink($dumpfilename);
  195. }
  196. fclose($fp);
  197. }
  198. unset($sqldump, $zip, $content);
  199. 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));
  200. }
  201. } else {
  202. $volume--;
  203. $filelist = '<ul>';
  204. cpheader();
  205. if($_GET['usezip'] == 1) {
  206. $zip = new zipfile();
  207. $zipfilename = $backupfilename.'.zip';
  208. $unlinks = array();
  209. for($i = 1; $i <= $volume; $i++) {
  210. $filename = sprintf($dumpfile, $i);
  211. $fp = fopen($filename, "r");
  212. $content = @fread($fp, filesize($filename));
  213. fclose($fp);
  214. $zip->addFile($content, basename($filename));
  215. $unlinks[] = $filename;
  216. $filelist .= "<li><a href=\"$filename\">$filename</a></li>\n";
  217. }
  218. $fp = fopen($zipfilename, 'w');
  219. if(@fwrite($fp, $zip->file()) !== FALSE) {
  220. foreach($unlinks as $link) {
  221. @unlink($link);
  222. }
  223. } else {
  224. C::t('common_cache')->insert(array(
  225. 'cachekey' => 'db_export',
  226. 'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
  227. 'dateline' => $_G['timestamp'],
  228. ), false, true);
  229. cpmsg('database_export_multivol_succeed', '', 'succeed', array('volume' => $volume, 'filelist' => $filelist));
  230. }
  231. unset($sqldump, $zip, $content);
  232. fclose($fp);
  233. @touch('./data/'.$backupdir.'/index.htm');
  234. $filename = $zipfilename;
  235. C::t('common_cache')->insert(array(
  236. 'cachekey' => 'db_export',
  237. 'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
  238. 'dateline' => $_G['timestamp'],
  239. ), false, true);
  240. cpmsg('database_export_zip_succeed', '', 'succeed', array('filename' => $filename));
  241. } else {
  242. @touch('./data/'.$backupdir.'/index.htm');
  243. for($i = 1; $i <= $volume; $i++) {
  244. $filename = sprintf($_GET['usezip'] == 2 ? $backupfilename."-%s".'.zip' : $dumpfile, $i);
  245. $filelist .= "<li><a href=\"$filename\">$filename</a></li>\n";
  246. }
  247. C::t('common_cache')->insert(array(
  248. 'cachekey' => 'db_export',
  249. 'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
  250. 'dateline' => $_G['timestamp'],
  251. ), false, true);
  252. cpmsg('database_export_multivol_succeed', '', 'succeed', array('volume' => $volume, 'filelist' => $filelist));
  253. }
  254. }
  255. } else {
  256. $tablesstr = '';
  257. foreach($tables as $table) {
  258. $tablesstr .= '"'.$table.'" ';
  259. }
  260. require DISCUZ_ROOT . './config/config_global.php';
  261. list($dbhost, $dbport) = explode(':', $dbhost);
  262. $query = DB::query("SHOW VARIABLES LIKE 'basedir'");
  263. list(, $mysql_base) = DB::fetch($query, DB::$drivertype == 'mysqli' ? MYSQLI_NUM : MYSQL_NUM);
  264. $dumpfile = addslashes(dirname(dirname(__FILE__))).'/'.$backupfilename.'.sql';
  265. @unlink($dumpfile);
  266. $mysqlbin = $mysql_base == '/' ? '' : addslashes($mysql_base).'bin/';
  267. @shell_exec($mysqlbin.'mysqldump --force --quick '.($db->version() > '4.1' ? '--skip-opt --create-options' : '-all').' --add-drop-table'.($_GET['extendins'] == 1 ? ' --extended-insert' : '').''.($db->version() > '4.1' && $_GET['sqlcompat'] == 'MYSQL40' ? ' --compatible=mysql40' : '').' --host="'.$dbhost.($dbport ? (is_numeric($dbport) ? ' --port='.$dbport : ' --socket="'.$dbport.'"') : '').'" --user="'.$dbuser.'" --password="'.$dbpw.'" "'.$dbname.'" '.$tablesstr.' > '.$dumpfile);
  268. if(@file_exists($dumpfile)) {
  269. if($_GET['usezip']) {
  270. require_once libfile('class/zip');
  271. $zip = new zipfile();
  272. $zipfilename = $backupfilename.'.zip';
  273. $fp = fopen($dumpfile, "r");
  274. $content = @fread($fp, filesize($dumpfile));
  275. fclose($fp);
  276. $zip->addFile($idstring."# <?php exit();?>\n ".$setnames."\n #".$content, basename($dumpfile));
  277. $fp = fopen($zipfilename, 'w');
  278. @fwrite($fp, $zip->file());
  279. fclose($fp);
  280. @unlink($dumpfile);
  281. @touch('./data/'.$backupdir.'/index.htm');
  282. $filename = $backupfilename.'.zip';
  283. unset($sqldump, $zip, $content);
  284. C::t('common_cache')->insert(array(
  285. 'cachekey' => 'db_export',
  286. 'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
  287. 'dateline' => $_G['timestamp'],
  288. ), false, true);
  289. cpmsg('database_export_zip_succeed', '', 'succeed', array('filename' => $filename));
  290. } else {
  291. if(@is_writeable($dumpfile)) {
  292. $fp = fopen($dumpfile, 'rb+');
  293. @fwrite($fp, $idstring."# <?php exit();?>\n ".$setnames."\n #");
  294. fclose($fp);
  295. }
  296. @touch('./data/'.$backupdir.'/index.htm');
  297. $filename = $backupfilename.'.sql';
  298. C::t('common_cache')->insert(array(
  299. 'cachekey' => 'db_export',
  300. 'cachevalue' => serialize(array('dateline' => $_G['timestamp'])),
  301. 'dateline' => $_G['timestamp'],
  302. ), false, true);
  303. cpmsg('database_export_succeed', '', 'succeed', array('filename' => $filename));
  304. }
  305. } else {
  306. cpmsg('database_shell_fail', '', 'error');
  307. }
  308. }
  309. }
  310. } elseif($operation == 'import') {
  311. checkpermission('dbimport');
  312. if(!submitcheck('deletesubmit')) {
  313. $exportlog = $exportsize = $exportziplog = array();
  314. if(is_dir(DISCUZ_ROOT.'./data/'.$backupdir)) {
  315. $dir = dir(DISCUZ_ROOT.'./data/'.$backupdir);
  316. while($entry = $dir->read()) {
  317. $entry = './data/'.$backupdir.'/'.$entry;
  318. if(is_file($entry)) {
  319. if(preg_match("/\.sql$/i", $entry)) {
  320. $filesize = filesize($entry);
  321. $fp = fopen($entry, 'rb');
  322. $identify = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", fgets($fp, 256))));
  323. fclose($fp);
  324. $key = preg_replace('/^(.+?)(\-\d+)\.sql$/i', '\\1', basename($entry));
  325. $exportlog[$key][$identify[4]] = array(
  326. 'version' => $identify[1],
  327. 'type' => $identify[2],
  328. 'method' => $identify[3],
  329. 'volume' => $identify[4],
  330. 'filename' => $entry,
  331. 'dateline' => filemtime($entry),
  332. 'size' => $filesize
  333. );
  334. $exportsize[$key] += $filesize;
  335. } elseif(preg_match("/\.zip$/i", $entry)) {
  336. $filesize = filesize($entry);
  337. $exportziplog[] = array(
  338. 'type' => 'zip',
  339. 'filename' => $entry,
  340. 'size' => filesize($entry),
  341. 'dateline' => filemtime($entry)
  342. );
  343. }
  344. }
  345. }
  346. $dir->close();
  347. } else {
  348. cpmsg('database_export_dest_invalid', '', 'error');
  349. }
  350. $restore_url = $_G['siteurl'].'data/restore.php';
  351. shownav('founder', 'nav_db', 'nav_db_import');
  352. showsubmenu('nav_db', array(
  353. array('nav_db_export', 'db&operation=export', 0),
  354. array('nav_db_import', 'db&operation=import', 1),
  355. array('nav_db_runquery', 'db&operation=runquery', 0),
  356. array('nav_db_optimize', 'db&operation=optimize', 0),
  357. array('nav_db_dbcheck', 'db&operation=dbcheck', 0)
  358. ));
  359. showtips('db_import_tips');
  360. showtableheader('db_import');
  361. showtablerow('', array('colspan="9" class="tipsblock"'), array(cplang('do_import_option', array('restore_url' => $restore_url))));
  362. showformheader('db&operation=import');
  363. showtitle('db_export_file');
  364. showsubtitle(array('', 'filename', 'version', 'time', 'type', 'size', 'db_method', 'db_volume', ''));
  365. $datasiteurl = $_G['siteurl'].'data/';
  366. foreach($exportlog as $key => $val) {
  367. $info = $val[1];
  368. $info['dateline'] = is_int($info['dateline']) ? dgmdate($info['dateline']) : $lang['unknown'];
  369. $info['size'] = sizecount($exportsize[$key]);
  370. $info['volume'] = count($val);
  371. $info['method'] = $info['type'] != 'zip' ? ($info['method'] == 'multivol' ? $lang['db_multivol'] : $lang['db_shell']) : '';
  372. $datafile_server = '.'.$info['filename'];
  373. showtablerow('', '', array(
  374. "<input class=\"checkbox\" type=\"checkbox\" name=\"delete[]\" value=\"".$key."\">",
  375. "<a href=\"javascript:;\" onclick=\"display('exportlog_$key')\">".$key."</a>",
  376. $info['version'],
  377. $info['dateline'],
  378. $lang['db_export_'.$info['type']],
  379. $info['size'],
  380. $info['method'],
  381. $info['volume'],
  382. $info['type'] == 'zip' ? "<a href=\"".$datasiteurl."restore.php?operation=importzip&datafile_server=$datafile_server&importsubmit=yes\" onclick=\"return confirm('$lang[db_import_confirm_zip]');\" class=\"act\" target=\"_blank\">$lang[db_import_unzip]</a>" : "<a class=\"act\" href=\"".$datasiteurl."restore.php?operation=import&from=server&datafile_server=$datafile_server&importsubmit=yes\"".($info['version'] != $_G['setting']['version'] ? " onclick=\"return confirm('$lang[db_import_confirm]');\"" : " onclick=\"return confirm('$lang[db_import_confirm_sql]');\"")." class=\"act\" target=\"_blank\">$lang[import]</a>"
  383. ));
  384. echo '<tbody id="exportlog_'.$key.'" style="display:none">';
  385. foreach($val as $info) {
  386. $info['dateline'] = is_int($info['dateline']) ? dgmdate($info['dateline']) : $lang['unknown'];
  387. $info['size'] = sizecount($info['size']);
  388. showtablerow('', '', array(
  389. '',
  390. "<a href=\"$info[filename]\">".substr(strrchr($info['filename'], "/"), 1)."</a>",
  391. $info['version'],
  392. $info['dateline'],
  393. '',
  394. $info['size'],
  395. '',
  396. $info['volume'],
  397. ''
  398. ));
  399. }
  400. echo '</tbody>';
  401. }
  402. foreach($exportziplog as $info) {
  403. $info['dateline'] = is_int($info['dateline']) ? dgmdate($info['dateline']) : $lang['unknown'];
  404. $info['size'] = sizecount($info['size']);
  405. $info['method'] = $info['method'] == 'multivol' ? $lang['db_multivol'] : $lang['db_zip'];
  406. $datafile_server = '.'.$info['filename'];
  407. showtablerow('', '', array(
  408. "<input class=\"checkbox\" type=\"checkbox\" name=\"delete[]\" value=\"".basename($info['filename'])."\">",
  409. "<a href=\"$info[filename]\">".substr(strrchr($info['filename'], "/"), 1)."</a>",
  410. '',
  411. $info['dateline'],
  412. $lang['db_export_'.$info['type']],
  413. $info['size'],
  414. $info['method'],
  415. '',
  416. "<a href=\"".$datasiteurl."restore.php?operation=importzip&datafile_server=$datafile_server&importsubmit=yes\" onclick=\"return confirm('$lang[db_import_confirm_zip]');\" class=\"act\" target=\"_blank\">$lang[db_import_unzip]</a>"
  417. ));
  418. }
  419. showsubmit('deletesubmit', 'submit', 'del');
  420. showformfooter();
  421. showtablefooter();
  422. } else {
  423. if(is_array($_GET['delete'])) {
  424. foreach($_GET['delete'] as $filename) {
  425. $file_path = './data/'.$backupdir.'/'.str_replace(array('/', '\\'), '', $filename);
  426. if(is_file($file_path)) {
  427. @unlink($file_path);
  428. } else {
  429. $i = 1;
  430. while(1) {
  431. $file_path = './data/'.$backupdir.'/'.str_replace(array('/', '\\'), '', $filename.'-'.$i.'.sql');
  432. if(is_file($file_path)) {
  433. @unlink($file_path);
  434. $i++;
  435. } else {
  436. break;
  437. }
  438. }
  439. }
  440. }
  441. cpmsg('database_file_delete_succeed', '', 'succeed');
  442. } else {
  443. cpmsg('database_file_delete_invalid', '', 'error');
  444. }
  445. }
  446. } elseif($operation == 'runquery') {
  447. $checkperm = checkpermission('runquery', 0);
  448. $runquerys = array();
  449. include_once(DISCUZ_ROOT.'source/admincp/admincp_quickquery.php');
  450. if(!submitcheck('sqlsubmit')) {
  451. $runqueryselect = '';
  452. foreach($simplequeries as $key => $query) {
  453. if(empty($query['sql'])) {
  454. $runqueryselect .= "<optgroup label=\"$query[comment]\">";
  455. } else {
  456. $runqueryselect .= '<option value="'.$key.'">'.$query['comment'].'</option>';
  457. }
  458. }
  459. if($runqueryselect) {
  460. $runqueryselect = '<select name="queryselect" style="width:500px">'.$runqueryselect.'</select>';
  461. }
  462. $queryselect = intval($_GET['queryselect']);
  463. $queries = $queryselect ? $runquerys[$queryselect] : '';
  464. shownav('founder', 'nav_db', 'nav_db_runquery');
  465. showsubmenu('nav_db', array(
  466. array('nav_db_export', 'db&operation=export', 0),
  467. array('nav_db_import', 'db&operation=import', 0),
  468. array('nav_db_runquery', 'db&operation=runquery', 1),
  469. array('nav_db_optimize', 'db&operation=optimize', 0),
  470. array('nav_db_dbcheck', 'db&operation=dbcheck', 0)
  471. ));
  472. showtips('db_runquery_tips');
  473. showtableheader();
  474. showformheader('db&operation=runquery&option=simple');
  475. showsetting('db_runquery_simply', '', '', $runqueryselect);
  476. showsetting('', '', '', '<input type="checkbox" class="checkbox" name="createcompatible" value="1" checked="checked" />'.cplang('db_runquery_createcompatible'));
  477. showsubmit('sqlsubmit');
  478. showformfooter();
  479. if($checkperm) {
  480. showformheader('db&operation=runquery&option=');
  481. showsetting('db_runquery_sql', '', '', '<textarea cols="85" rows="10" name="queries" style="width:500px;" onkeyup="textareasize(this)" onkeydown="textareakey(this, event)">'.$queries.'</textarea>');
  482. showsetting('', '', '', '<input type="checkbox" class="checkbox" name="createcompatible" value="1" checked="checked" />'.cplang('db_runquery_createcompatible'));
  483. showsubmit('sqlsubmit', 'submit', '', cplang('db_runquery_comment'));
  484. showformfooter();
  485. }
  486. showtablefooter();
  487. } else {
  488. $queries = $_GET['queries'];
  489. if($_GET['option'] == 'simple') {
  490. $queryselect = intval($_GET['queryselect']);
  491. $queries = isset($simplequeries[$queryselect]) && $simplequeries[$queryselect]['sql'] ? $simplequeries[$queryselect]['sql'] : '';
  492. } elseif(!$checkperm) {
  493. cpmsg('database_run_query_denied', '', 'error');
  494. }
  495. $sqlquery = splitsql(str_replace(array(' {tablepre}', ' cdb_', ' `cdb_', ' pre_', ' `pre_'), array(' '.$tablepre, ' '.$tablepre, ' `'.$tablepre, ' '.$tablepre, ' `'.$tablepre), $queries));
  496. $affected_rows = 0;
  497. foreach($sqlquery as $sql) {
  498. if(trim($sql) != '') {
  499. $sql = !empty($_GET['createcompatible']) ? syntablestruct(trim($sql), $db->version() > '4.1', $dbcharset) : $sql;
  500. DB::query($sql, 'SILENT');
  501. if($sqlerror = DB::error()) {
  502. break;
  503. } else {
  504. $affected_rows += intval(DB::affected_rows());
  505. }
  506. }
  507. }
  508. $sqlerror ? cpmsg('database_run_query_invalid', '', 'error', array('sqlerror' => $sqlerror)) : cpmsg('database_run_query_succeed', '', 'succeed', array('affected_rows' => $affected_rows));
  509. }
  510. } elseif($operation == 'optimize') {
  511. $optimizetable = '';
  512. $totalsize = 0;
  513. $tablearray = array( 0 => $tablepre);
  514. shownav('founder', 'nav_db', 'nav_db_optimize');
  515. showsubmenu('nav_db', array(
  516. array('nav_db_export', 'db&operation=export', 0),
  517. array('nav_db_import', 'db&operation=import', 0),
  518. array('nav_db_runquery', 'db&operation=runquery', 0),
  519. array('nav_db_optimize', 'db&operation=optimize', 1),
  520. array('nav_db_dbcheck', 'db&operation=dbcheck', 0)
  521. ));
  522. showtips('db_optimize_tips');
  523. showformheader('db&operation=optimize');
  524. showtableheader('db_optimize_tables');
  525. showsubtitle(array('', 'db_optimize_table_name', 'type', 'db_optimize_rows', 'db_optimize_data', 'db_optimize_index', 'db_optimize_frag'));
  526. if(!submitcheck('optimizesubmit')) {
  527. foreach($tablearray as $tp) {
  528. $query = DB::query("SHOW TABLE STATUS LIKE '$tp%'", 'SILENT');
  529. while($table = DB::fetch($query)) {
  530. if($table['Data_free'] && $table[$tabletype] == 'MyISAM') {
  531. $checked = $table[$tabletype] == 'MyISAM' ? 'checked' : 'disabled';
  532. showtablerow('', '', array(
  533. "<input class=\"checkbox\" type=\"checkbox\" name=\"optimizetables[]\" value=\"$table[Name]\" $checked>",
  534. $table[Name],
  535. $table[$tabletype],
  536. $table[Rows],
  537. $table[Data_length],
  538. $table[Index_length],
  539. $table[Data_free],
  540. ));
  541. $totalsize += $table['Data_length'] + $table['Index_length'];
  542. }
  543. }
  544. }
  545. if(empty($totalsize)) {
  546. showtablerow('', 'colspan="6"', $lang['db_optimize_done']);
  547. } else {
  548. showtablerow('', 'colspan="6"', $lang['db_optimize_used'].' '.sizecount($totalsize));
  549. showsubmit('optimizesubmit', 'submit', '<input name="chkall" id="chkall" class="checkbox" onclick="checkAll(\'prefix\', this.form)" checked="checked" type="checkbox" /><label for="chkall">'.$lang[db_optimize_opt].'</label>');
  550. }
  551. } else {
  552. foreach($tablearray as $tp) {
  553. $query = DB::query("SHOW TABLE STATUS LIKE '$tp%'", 'SILENT');
  554. while($table = DB::fetch($query)) {
  555. if($table['Data_free'] && $table[$tabletype] == 'MyISAM') {
  556. $optimizeinput = "<input class=\"checkbox\" type=\"checkbox\" name=\"optimizetables[]\" value=\"$table[Name]\" $checked>";
  557. if(is_array($_GET['optimizetables']) && in_array($table['Name'], $_GET['optimizetables'])) {
  558. DB::query("OPTIMIZE TABLE $table[Name]");
  559. $table[Data_free] = 0;
  560. $optimizeinput = '';
  561. }
  562. showtablerow('', '', array(
  563. $optimizeinput,
  564. $table[Name],
  565. $db->version() > '4.1' ? $table['Engine'] : $table['Type'],
  566. $table[Rows],
  567. $table[Data_length],
  568. $table[Index_length],
  569. $table[Data_free]
  570. ));
  571. $totalsize += $table['Data_length'] + $table['Index_length'];
  572. }
  573. }
  574. }
  575. showtablerow('', 'colspan="6"', $lang['db_optimize_used'].' '.sizecount($totalsize));
  576. }
  577. showtablefooter();
  578. showformfooter();
  579. } elseif($operation == 'dbcheck') {
  580. if(!C::t('common_setting')->fetch_all_field()) {
  581. cpmsg('dbcheck_permissions_invalid', '', 'error');
  582. }
  583. $step = max(1, intval($_GET['step']));
  584. if($step == 3) {
  585. if(!file_exists('source/admincp/discuzdb.md5')) {
  586. cpmsg('dbcheck_nofound_md5file', '', 'error');
  587. }
  588. $dbcharset = $discuz->config['db'][1]['dbcharset'];
  589. unset($dbuser, $dbpw, $dbname);
  590. $fp = fopen(DISCUZ_ROOT.'./source/admincp/discuzdb.md5', "rb");
  591. $discuzdb = fread($fp, filesize(DISCUZ_ROOT.'./source/admincp/discuzdb.md5'));
  592. fclose($fp);
  593. $dbmd5 = substr($discuzdb, 0, 32);
  594. $discuzdb = dunserialize(substr($discuzdb, 34));
  595. $settingsdata = $discuzdb[1];
  596. $discuzdb = $discuzdb[0][0];
  597. $repair = !empty($_GET['repair']) ? $_GET['repair'] : array();
  598. $setting = !empty($_GET['setting']) ? $_GET['setting'] : array();
  599. $missingtable = !empty($_GET['missingtable']) ? $_GET['missingtable'] : array();
  600. $repairtable = is_array($_GET['repairtable']) && !empty($_GET['repairtable']) ? $_GET['repairtable'] : array();
  601. $except = array('threads' => array('sgid'));
  602. foreach(C::t('common_member_profile_setting')->range() as $profilefields) {
  603. $except['memberfields'][] = 'field_'.$profilefields[$fieldid];
  604. }
  605. if(submitcheck('repairsubmit') && (!empty($repair) || !empty($setting) || !empty($repairtable) || !empty($missingtable))) {
  606. $error = '';
  607. $errorcount = 0;
  608. $alter = $fielddefault = array();
  609. foreach($missingtable as $value) {
  610. if(!isset($installdata)) {
  611. $fp = fopen(DISCUZ_ROOT.'./install/install.sql', "rb");
  612. $installdata = fread($fp, filesize(DISCUZ_ROOT.'./install/install.sql'));
  613. fclose($fp);
  614. }
  615. preg_match("/CREATE TABLE ".DB::table($value)."\s+\(.+?;/is", $installdata, $a);
  616. DB::query(createtable($a[0], $dbcharset));
  617. }
  618. foreach($repair as $value) {
  619. if(!in_array($r_table, $repairtable)) {
  620. list($r_table, $r_field, $option) = explode('|', $value);
  621. if(!isset($repairrtable[$r_table]) && $fieldsquery = DB::query("SHOW FIELDS FROM ".DB::table($r_table), 'SILENT')) {
  622. while($fields = DB::fetch($fieldsquery)) {
  623. $fielddefault[$r_table][$fields['Field']] = $fields['Default'];
  624. }
  625. }
  626. $field = $discuzdb[$r_table][$r_field];
  627. $altersql = '`'.$field['Field'].'` '.$field['Type'];
  628. $altersql .= $field['Null'] == 'NO' ? ' NOT NULL' : '';
  629. $altersql .= in_array($fielddefault[$r_table][$field['Field']], array('', '0')) && in_array($field['Default'], array('', '0')) ||
  630. $field['Null'] == 'NO' && $field['Default'] == '' ||
  631. preg_match('/text/i', $field['Type']) || preg_match('/auto_increment/i', $field['Extra']) ?
  632. '' : ' default \''.$field['Default'].'\'';
  633. $altersql .= $field['Extra'] != '' ? ' '.$field['Extra'] : '';
  634. $altersql = $option == 'modify' ? "MODIFY COLUMN ".$altersql : "ADD COLUMN ".$altersql;
  635. $alter[$r_table][] = $altersql;
  636. }
  637. }
  638. foreach($alter as $r_table => $sqls) {
  639. DB::query("ALTER TABLE `$tablepre$r_table` ".implode(',', $sqls), 'SILENT');
  640. if($sqlerror = DB::error()) {
  641. $errorcount += count($sqls);
  642. $error .= $sqlerror.'<br /><br />';
  643. }
  644. }
  645. $alter = array();
  646. foreach($repairtable as $value) {
  647. foreach($discuzdb[$value] as $field) {
  648. if(!isset($fielddefault[$value]) && $fieldsquery = DB::query("SHOW FIELDS FROM ".DB::table($value), 'SILENT')) {
  649. while($fields = DB::fetch($fieldsquery)) {
  650. $fielddefault[$value][$fields['Field']] = $fields['Default'];
  651. }
  652. }
  653. $altersql = '`'.$field['Field'].'` '.$field['Type'];
  654. $altersql .= $field['Null'] == 'NO' ? ' NOT NULL' : '';
  655. $altersql .= in_array($fielddefault[$value][$field['Field']], array('', '0')) && in_array($field['Default'], array('', '0')) ||
  656. $field['Null'] == 'NO' && $field['Default'] == '' ||
  657. preg_match('/text/i', $field['Type']) || preg_match('/auto_increment/i', $field['Extra']) ?
  658. '' : ' default \''.$field['Default'].'\'';
  659. $altersql .= $field['Extra'] != '' ? ' '.$field['Extra'] : '';
  660. $altersql = "MODIFY COLUMN ".$altersql;
  661. $alter[$value][] = $altersql;
  662. }
  663. }
  664. foreach($alter as $r_table => $sqls) {
  665. DB::query("ALTER TABLE `".DB::table($r_table)."` ".implode(',', $sqls), 'SILENT');
  666. if($sqlerror = DB::error()) {
  667. $errorcount += count($sqls);
  668. $error .= $sqlerror.'<br /><br />';
  669. }
  670. }
  671. if(!empty($setting)) {
  672. $settingsdatanow = $newsettings = array();
  673. $allsetting = C::t('common_setting')->fetch_all();
  674. $settingsdatanew = array_keys($allsetting);
  675. unset($allsetting);
  676. $settingsdellist = @array_diff($settingsdata, $settingsdatanew);
  677. if($setting['del'] && is_array($settingsdellist)) {
  678. foreach($settingsdellist as $variable) {
  679. $newsettings[$variable] = '';
  680. }
  681. }
  682. if($newsettings) {
  683. C::t('common_setting')->update_batch($newsettings);
  684. updatecache('setting');
  685. }
  686. }
  687. if($errorcount) {
  688. cpmsg('dbcheck_repair_error', '', 'error', array('errorcount' => $errorcount, 'error' => $error));
  689. } else {
  690. cpmsg('dbcheck_repair_completed', 'action=db&operation=dbcheck&step=3', 'succeed');
  691. }
  692. }
  693. $installexists = file_exists(DISCUZ_ROOT.'./install/install.sql');
  694. $discuzdbnew = $deltables = $excepttables = $missingtables = $charseterror = array();
  695. foreach($discuzdb as $dbtable => $fields) {
  696. if($fieldsquery = DB::query("SHOW FIELDS FROM ".DB::table($dbtable), 'SILENT')) {
  697. while($fields = DB::fetch($fieldsquery)) {
  698. $r = '/^'.$tablepre.'/';
  699. $cuttable = preg_replace($r, '', $dbtable);
  700. if($db->version() < '4.1' && $cuttable == 'sessions' && $fields['Field'] == 'sid') {
  701. $fields['Type'] = str_replace(' binary', '', $fields['Type']);
  702. }
  703. if($cuttable == 'memberfields' && preg_match('/^field\_\d+$/', $fields['Field'])) {
  704. unset($discuzdbnew[$cuttable][$fields['Field']]);
  705. continue;
  706. }
  707. $discuzdbnew[$cuttable][$fields['Field']]['Field'] = $fields['Field'];
  708. $discuzdbnew[$cuttable][$fields['Field']]['Type'] = $fields['Type'];
  709. $discuzdbnew[$cuttable][$fields['Field']]['Null'] = $fields['Null'] == '' ? 'NO' : $fields['Null'];
  710. $discuzdbnew[$cuttable][$fields['Field']]['Extra'] = $fields['Extra'];
  711. $discuzdbnew[$cuttable][$fields['Field']]['Default'] = $fields['Default'] == '' || $fields['Default'] == '0' ? '' : $fields['Default'];
  712. }
  713. ksort($discuzdbnew[$cuttable]);
  714. } else {
  715. $missingtables[] = '<span style="float:left;width:33%">'.(($installexists ? '<input name="missingtable[]" type="checkbox" class="checkbox" value="'.$dbtable.'">' : '').$tablepre.$dbtable).'</span>';
  716. $excepttables[] = $dbtable;
  717. }
  718. }
  719. if($db->version() > '4.1') {
  720. $dbcharset = strtoupper($dbcharset) == 'UTF-8' ? 'UTF8' : strtoupper($dbcharset);
  721. $query = DB::query("SHOW TABLE STATUS LIKE '$tablepre%'");
  722. while($tables = DB::fetch($query)) {
  723. $r = '/^'.$tablepre.'/';
  724. $cuttable = preg_replace($r, '', $tables['Name']);
  725. $tabledbcharset = substr($tables['Collation'], 0, strpos($tables['Collation'], '_'));
  726. if($dbcharset != strtoupper($tabledbcharset)) {
  727. $charseterror[] = '<span style="float:left;width:33%">'.$tablepre.$cuttable.'('.$tabledbcharset.')</span>';
  728. }
  729. }
  730. }
  731. $dbmd5new = md5(serialize($discuzdbnew));
  732. $settingsdatanow = array();
  733. $allsetting = C::t('common_setting')->fetch_all();
  734. $settingsdatanew = array_keys($allsetting);
  735. unset($allsetting);
  736. $settingsdellist = @array_diff($settingsdata, $settingsdatanew);
  737. if($dbmd5 == $dbmd5new && empty($charseterror) && empty($settingsdellist)) {
  738. cpmsg('dbcheck_ok', '', 'succeed');
  739. }
  740. $showlist = $addlists = '';
  741. foreach($discuzdb as $dbtable => $fields) {
  742. $addlist = $modifylist = $dellist = array();
  743. if($fields != $discuzdbnew[$dbtable]) {
  744. foreach($discuzdb[$dbtable] as $key => $value) {
  745. $tempvalue = str_replace('mediumtext', 'text', $value);
  746. $discuzdbnew[$dbtable][$key] = str_replace('mediumtext', 'text', $discuzdbnew[$dbtable][$key]);
  747. if(is_array($missingtables) && in_array($tablepre.$dbtable, $missingtables)) {
  748. } elseif(!isset($discuzdbnew[$dbtable][$key])) {
  749. $dellist[] = $value;
  750. } elseif($tempvalue != $discuzdbnew[$dbtable][$key]) {
  751. $modifylist[] = $value;
  752. }
  753. }
  754. if(is_array($discuzdbnew[$dbtable])) {
  755. foreach($discuzdbnew[$dbtable] as $key => $value) {
  756. if(!isset($discuzdb[$dbtable][$key]) && !@in_array($value['Field'], $except[$dbtable])) {
  757. $addlist[] = $value;
  758. }
  759. }
  760. }
  761. }
  762. if(($modifylist || $dellist) && !in_array($dbtable, $excepttables)) {
  763. $showlist .= showtablerow('', '', array("<span class=\"diffcolor3\">$tablepre$dbtable</span> $lang[dbcheck_field]", $lang[dbcheck_org_field], $lang[dbcheck_status]), TRUE);
  764. foreach($modifylist as $value) {
  765. $slowstatus = slowcheck($discuzdbnew[$dbtable][$value['Field']]['Type'], $value['Type']);
  766. $showlist .= "<tr><td><input name=\"repair[]\" class=\"checkbox\" type=\"checkbox\" value=\"$dbtable|$value[Field]|modify\"> <b>".$value['Field']."</b> ".
  767. $discuzdbnew[$dbtable][$value['Field']]['Type'].
  768. ($discuzdbnew[$dbtable][$value['Field']]['Null'] == 'NO' ? ' NOT NULL' : '').
  769. (!preg_match('/auto_increment/i', $discuzdbnew[$dbtable][$value['Field']]['Extra']) && !preg_match('/text/i', $discuzdbnew[$dbtable][$value['Field']]['Type']) ? ' default \''.$discuzdbnew[$dbtable][$value['Field']]['Default'].'\'' : '').
  770. ' '.$discuzdbnew[$dbtable][$value['Field']]['Extra'].
  771. "</td><td><b>".$value['Field']."</b> ".$value['Type'].
  772. ($value['Null'] == 'NO' ? ' NOT NULL' : '').
  773. (!preg_match('/auto_increment/i', $value['Extra']) && !preg_match('/text/i', $value['Type']) ? ' default \''.$value['Default'].'\'' : '').
  774. ' '.$value['Extra']."</td><td>".
  775. (!$slowstatus ? "<em class=\"edited\">$lang[dbcheck_modify]</em></td></tr>" : "<em class=\"unknown\">$lang[dbcheck_slow]</em>")."</td></tr>";
  776. }
  777. if($modifylist) {
  778. $showlist .= showtablerow('', 'colspan="3"', "<input onclick=\"setrepaircheck(this, this.form, '$dbtable')\" name=\"repairtable[]\" class=\"checkbox\" type=\"checkbox\" value=\"$dbtable\"> <b>$lang[dbcheck_repairtable]</b>", TRUE);
  779. }
  780. foreach($dellist as $value) {
  781. $showlist .= "<tr><td><input name=\"repair[]\" class=\"checkbox\" type=\"checkbox\" value=\"$dbtable|$value[Field]|add\"> <strike><b>".$value['Field']."</b></strike></td><td> <b>".$value['Field']."</b> ".$value['Type'].($value['Null'] == 'NO' ? ' NOT NULL' : '')."</td><td>".
  782. "<em class=\"del\">$lang[dbcheck_delete]</em></td></tr>";
  783. }
  784. }
  785. if($addlist) {
  786. $addlists .= "<tr><td colspan=\"3\"><b>$tablepre$dbtable</b> $lang[dbcheck_new_field]</td></tr>";
  787. foreach($addlist as $value) {
  788. $addlists .= "<tr><td colspan=\"3\">&nbsp;&nbsp;&nbsp;&nbsp;<b>".$value['Field']."</b> ".$discuzdbnew[$dbtable][$value['Field']]['Type'].($discuzdbnew[$dbtable][$value['Field']]['Null'] == 'NO' ? ' NOT NULL' : '')."</td></tr>";
  789. }
  790. }
  791. }
  792. if($showlist) {
  793. $showlist = showtablerow('', 'colspan="3" class="partition"', $lang['dbcheck_errorfields_tables'], TRUE).$showlist;
  794. }
  795. if($missingtables) {
  796. $showlist .= showtablerow('', 'colspan="3" class="partition"', $lang['dbcheck_missing_tables'], TRUE);
  797. $showlist .= showtablerow('', 'colspan="3" class="partition"', implode('', $missingtables), TRUE);
  798. }
  799. if($settingsdellist) {
  800. $showlist .= "<tr class=\"partition\"><td colspan=\"3\">$lang[dbcheck_setting]</td></tr>";
  801. $showlist .= '<tr><td colspan="3">';
  802. $showlist .= "<input name=\"setting[del]\" class=\"checkbox\" type=\"checkbox\" value=\"1\"> ".implode(', ', $settingsdellist).'<br />';
  803. $showlist .= '</td></tr>';
  804. }
  805. if($showlist) {
  806. $showlist .= '<tr><td colspan="3"><input class="btn" type="submit" value="'.$lang['dbcheck_repair'].'" name="repairsubmit"></td></tr>';
  807. }
  808. if($charseterror) {
  809. $showlist .= "<tr><td class=\"partition\" colspan=\"3\">$lang[dbcheck_charseterror_tables] ($lang[dbcheck_charseterror_notice] $dbcharset)</td></tr>";
  810. $showlist .= '<tr><td colspan="3">'.implode('', $charseterror).'</td></tr>';
  811. }
  812. if($addlists) {
  813. $showlist .= '<tr><td class="partition" colspan="3">'.$lang['dbcheck_userfields'].'</td></tr>'.$addlists;
  814. }
  815. }
  816. shownav('founder', 'nav_db', 'nav_db_dbcheck');
  817. showsubmenu('nav_db', array(
  818. array('nav_db_export', 'db&operation=export', 0),
  819. array('nav_db_import', 'db&operation=import', 0),
  820. array('nav_db_runquery', 'db&operation=runquery', 0),
  821. array('nav_db_optimize', 'db&operation=optimize', 0),
  822. array('nav_db_dbcheck', 'db&operation=dbcheck', 1)
  823. ));
  824. showsubmenusteps('', array(
  825. array('nav_filecheck_confirm', $step == 1),
  826. array('nav_filecheck_verify', $step == 2),
  827. array('nav_filecheck_completed', $step == 3)
  828. ));
  829. if($step == 1) {
  830. cpmsg(cplang('dbcheck_tips_step1'), 'action=db&operation=dbcheck&step=2', 'button', '', FALSE);
  831. } elseif($step == 2) {
  832. cpmsg(cplang('dbcheck_verifying'), "action=db&operation=dbcheck&step=3", 'loading', '', FALSE);
  833. } elseif($step == 3) {
  834. showtips('dbcheck_tips');
  835. echo <<<EOT
  836. <script type="text/JavaScript">
  837. function setrepaircheck(obj, form, table) {
  838. eval('var rem = /^' + table + '\\\\|.+?\\\\|modify$/;');
  839. eval('var rea = /^' + table + '\\\\|.+?\\\\|add$/;');
  840. for(var i = 0; i < form.elements.length; i++) {
  841. var e = form.elements[i];
  842. if(e.type == 'checkbox' && e.name == 'repair[]') {
  843. if(rem.exec(e.value) != null) {
  844. if(obj.checked) {
  845. e.checked = false;
  846. e.disabled = true;
  847. } else {
  848. e.checked = false;
  849. e.disabled = false;
  850. }
  851. }
  852. if(rea.exec(e.value) != null) {
  853. if(obj.checked) {
  854. e.checked = true;
  855. e.disabled = false;
  856. } else {
  857. e.checked = false;
  858. e.disabled = false;
  859. }
  860. }
  861. }
  862. }
  863. }
  864. </script>
  865. EOT;
  866. showformheader('db&operation=dbcheck&step=3', 'fixpadding');
  867. showtableheader();
  868. echo $showlist;
  869. showtablefooter();
  870. showformfooter();
  871. }
  872. }
  873. function createtable($sql, $dbcharset) {
  874. $type = strtoupper(preg_replace("/^\s*CREATE TABLE\s+.+\s+\(.+?\).*(ENGINE|TYPE)\s*=\s*([a-z]+?).*$/isU", "\\2", $sql));
  875. $type = in_array($type, array('MYISAM', 'HEAP', 'MEMORY')) ? $type : 'MYISAM';
  876. return preg_replace("/^\s*(CREATE TABLE\s+.+\s+\(.+?\)).*$/isU", "\\1", $sql).
  877. (DB::$db->version() > '4.1' ? " ENGINE=$type DEFAULT CHARSET=$dbcharset" : " TYPE=$type");
  878. }
  879. function fetchtablelist($tablepre = '') {
  880. global $db;
  881. $arr = explode('.', $tablepre);
  882. $dbname = $arr[1] ? $arr[0] : '';
  883. $tablepre = str_replace('_', '\_', $tablepre);
  884. $sqladd = $dbname ? " FROM $dbname LIKE '$arr[1]%'" : "LIKE '$tablepre%'";
  885. $tables = $table = array();
  886. $query = DB::query("SHOW TABLE STATUS $sqladd");
  887. while($table = DB::fetch($query)) {
  888. $table['Name'] = ($dbname ? "$dbname." : '').$table['Name'];
  889. $tables[] = $table;
  890. }
  891. return $tables;
  892. }
  893. function arraykeys2($array, $key2) {
  894. $return = array();
  895. foreach($array as $val) {
  896. $return[] = $val[$key2];
  897. }
  898. return $return;
  899. }
  900. function syntablestruct($sql, $version, $dbcharset) {
  901. if(strpos(trim(substr($sql, 0, 18)), 'CREATE TABLE') === FALSE) {
  902. return $sql;
  903. }
  904. $sqlversion = strpos($sql, 'ENGINE=') === FALSE ? FALSE : TRUE;
  905. if($sqlversion === $version) {
  906. return $sqlversion && $dbcharset ? preg_replace(array('/ character set \w+/i', '/ collate \w+/i', "/DEFAULT CHARSET=\w+/is"), array('', '', "DEFAULT CHARSET=$dbcharset"), $sql) : $sql;
  907. }
  908. if($version) {
  909. return preg_replace(array('/TYPE=HEAP/i', '/TYPE=(\w+)/is'), array("ENGINE=MEMORY DEFAULT CHARSET=$dbcharset", "ENGINE=\\1 DEFAULT CHARSET=$dbcharset"), $sql);
  910. } else {
  911. return preg_replace(array('/character set \w+/i', '/collate \w+/i', '/ENGINE=MEMORY/i', '/\s*DEFAULT CHARSET=\w+/is', '/\s*COLLATE=\w+/is', '/ENGINE=(\w+)(.*)/is'), array('', '', 'ENGINE=HEAP', '', '', 'TYPE=\\1\\2'), $sql);
  912. }
  913. }
  914. function sqldumptablestruct($table) {
  915. global $_G, $db, $excepttables;
  916. if(in_array($table, $excepttables)) {
  917. return;
  918. }
  919. $createtable = DB::query("SHOW CREATE TABLE $table", 'SILENT');
  920. if(!DB::error()) {
  921. $tabledump = "DROP TABLE IF EXISTS $table;\n";
  922. } else {
  923. return '';
  924. }
  925. $create = $db->fetch_row($createtable);
  926. if(strpos($table, '.') !== FALSE) {
  927. $tablename = substr($table, strpos($table, '.') + 1);
  928. $create[1] = str_replace("CREATE TABLE $tablename", 'CREATE TABLE '.$table, $create[1]);
  929. }
  930. $tabledump .= $create[1];
  931. if($_GET['sqlcompat'] == 'MYSQL41' && $db->version() < '4.1') {
  932. $tabledump = preg_replace("/TYPE\=(.+)/", "ENGINE=\\1 DEFAULT CHARSET=".$dumpcharset, $tabledump);
  933. }
  934. if($db->version() > '4.1' && $_GET['sqlcharset']) {
  935. $tabledump = preg_replace("/(DEFAULT)*\s*CHARSET=.+/", "DEFAULT CHARSET=".$_GET['sqlcharset'], $tabledump);
  936. }
  937. $tablestatus = DB::fetch_first("SHOW TABLE STATUS LIKE '$table'");
  938. $tabledump .= ($tablestatus['Auto_increment'] ? " AUTO_INCREMENT=$tablestatus[Auto_increment]" : '').";\n\n";
  939. if($_GET['sqlcompat'] == 'MYSQL40' && $db->version() >= '4.1' && $db->version() < '5.1') {
  940. if($tablestatus['Auto_increment'] <> '') {
  941. $temppos = strpos($tabledump, ',');
  942. $tabledump = substr($tabledump, 0, $temppos).' auto_increment'.substr($tabledump, $temppos);
  943. }
  944. if($tablestatus['Engine'] == 'MEMORY') {
  945. $tabledump = str_replace('TYPE=MEMORY', 'TYPE=HEAP', $tabledump);
  946. }
  947. }
  948. return $tabledump;
  949. }
  950. function sqldumptable($table, $startfrom = 0, $currsize = 0) {
  951. global $_G, $db, $startrow, $dumpcharset, $complete, $excepttables;
  952. $offset = 300;
  953. $tabledump = '';
  954. $tablefields = array();
  955. $query = DB::query("SHOW FULL COLUMNS FROM $table", 'SILENT');
  956. if(strexists($table, 'adminsessions')) {
  957. return ;
  958. } elseif(!$query && DB::errno() == 1146) {
  959. return;
  960. } elseif(!$query) {
  961. $_GET['usehex'] = FALSE;
  962. } else {
  963. while($fieldrow = DB::fetch($query)) {
  964. $tablefields[] = $fieldrow;
  965. }
  966. }
  967. if(!in_array($table, $excepttables)) {
  968. $tabledumped = 0;
  969. $numrows = $offset;
  970. $firstfield = $tablefields[0];
  971. if($_GET['extendins'] == '0') {
  972. while($currsize + strlen($tabledump) + 500 < $_GET['sizelimit'] * 1000 && $numrows == $offset) {
  973. if($firstfield['Extra'] == 'auto_increment') {
  974. $selectsql = "SELECT * FROM $table WHERE $firstfield[Field] > $startfrom ORDER BY $firstfield[Field] LIMIT $offset";
  975. } else {
  976. $selectsql = "SELECT * FROM $table LIMIT $startfrom, $offset";
  977. }
  978. $tabledumped = 1;
  979. $rows = DB::query($selectsql);
  980. $numfields = $db->num_fields($rows);
  981. $numrows = DB::num_rows($rows);
  982. while($row = $db->fetch_row($rows)) {
  983. $comma = $t = '';
  984. for($i = 0; $i < $numfields; $i++) {
  985. $t .= $comma.($_GET['usehex'] && !empty($row[$i]) && (strexists($tablefields[$i]['Type'], 'char') || strexists($tablefields[$i]['Type'], 'text')) ? '0x'.bin2hex($row[$i]) : '\''.$db->escape_string($row[$i]).'\'');
  986. $comma = ',';
  987. }
  988. if(strlen($t) + $currsize + strlen($tabledump) + 500 < $_GET['sizelimit'] * 1000) {
  989. if($firstfield['Extra'] == 'auto_increment') {
  990. $startfrom = $row[0];
  991. } else {
  992. $startfrom++;
  993. }
  994. $tabledump .= "INSERT INTO $table VALUES ($t);\n";
  995. } else {
  996. $complete = FALSE;
  997. break 2;
  998. }
  999. }
  1000. }
  1001. } else {
  1002. while($currsize + strlen($tabledump) + 500 < $_GET['sizelimit'] * 1000 && $numrows == $offset) {
  1003. if($firstfield['Extra'] == 'auto_increment') {
  1004. $selectsql = "SELECT * FROM $table WHERE $firstfield[Field] > $startfrom LIMIT $offset";
  1005. } else {
  1006. $selectsql = "SELECT * FROM $table LIMIT $startfrom, $offset";
  1007. }
  1008. $tabledumped = 1;
  1009. $rows = DB::query($selectsql);
  1010. $numfields = $db->num_fields($rows);
  1011. if($numrows = DB::num_rows($rows)) {
  1012. $t1 = $comma1 = '';
  1013. while($row = $db->fetch_row($rows)) {
  1014. $t2 = $comma2 = '';
  1015. for($i = 0; $i < $numfields; $i++) {
  1016. $t2 .= $comma2.($_GET['usehex'] && !empty($row[$i]) && (strexists($tablefields[$i]['Type'], 'char') || strexists($tablefields[$i]['Type'], 'text'))? '0x'.bin2hex($row[$i]) : '\''.$db->escape_string($row[$i]).'\'');
  1017. $comma2 = ',';
  1018. }
  1019. if(strlen($t1) + $currsize + strlen($tabledump) + 500 < $_GET['sizelimit'] * 1000) {
  1020. if($firstfield['Extra'] == 'auto_increment') {
  1021. $startfrom = $row[0];
  1022. } else {
  1023. $startfrom++;
  1024. }
  1025. $t1 .= "$comma1 ($t2)";
  1026. $comma1 = ',';
  1027. } else {
  1028. $tabledump .= "INSERT INTO $table VALUES $t1;\n";
  1029. $complete = FALSE;
  1030. break 2;
  1031. }
  1032. }
  1033. $tabledump .= "INSERT INTO $table VALUES $t1;\n";
  1034. }
  1035. }
  1036. }
  1037. $startrow = $startfrom;
  1038. $tabledump .= "\n";
  1039. }
  1040. return $tabledump;
  1041. }
  1042. function splitsql($sql) {
  1043. $sql = str_replace("\r", "\n", $sql);
  1044. $ret = array();
  1045. $num = 0;
  1046. $queriesarray = explode(";\n", trim($sql));
  1047. unset($sql);
  1048. foreach($queriesarray as $query) {
  1049. $queries = explode("\n", trim($query));
  1050. foreach($queries as $query) {
  1051. $ret[$num] .= $query[0] == "#" ? NULL : $query;
  1052. }
  1053. $num++;
  1054. }
  1055. return($ret);
  1056. }
  1057. function slowcheck($type1, $type2) {
  1058. $t1 = explode(' ', $type1);$t1 = $t1[0];
  1059. $t2 = explode(' ', $type2);$t2 = $t2[0];
  1060. $arr = array($t1, $t2);
  1061. sort($arr);
  1062. if($arr == array('mediumtext', 'text')) {
  1063. return TRUE;
  1064. } elseif(substr($arr[0], 0, 4) == 'char' && substr($arr[1], 0, 7) == 'varchar') {
  1065. return TRUE;
  1066. }
  1067. return FALSE;
  1068. }
  1069. ?>