PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/adm/admin_db_backup.php

http://github.com/MightyGorgon/icy_phoenix
PHP | 466 lines | 380 code | 68 blank | 18 comment | 71 complexity | 38955f66559f348155310f03467dd0f4 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * @package Icy Phoenix
  5. * @version $Id$
  6. * @copyright (c) 2008 Icy Phoenix
  7. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8. *
  9. */
  10. define('IN_ICYPHOENIX', true);
  11. // Mighty Gorgon - ACP Privacy - BEGIN
  12. if (function_exists('check_acp_module_access'))
  13. {
  14. $is_allowed = check_acp_module_access();
  15. if (empty($is_allowed))
  16. {
  17. return;
  18. }
  19. }
  20. // Mighty Gorgon - ACP Privacy - END
  21. if(!empty($setmodules))
  22. {
  23. $filename = basename(__FILE__);
  24. $module['1400_DB_Maintenance']['120_Backup_DB'] = $filename . '?mode=backup';
  25. $ja_module['1400_DB_Maintenance']['120_Backup_DB'] = false;
  26. $module['1400_DB_Maintenance']['130_Restore_DB'] = $filename . '?mode=restore';
  27. $ja_module['1400_DB_Maintenance']['130_Restore_DB'] = false;
  28. return;
  29. }
  30. // If download action is enabled, don't load header
  31. if (isset($_GET['action']) && ($_GET['action'] == 'download'))
  32. {
  33. $no_page_header = true;
  34. }
  35. if (!defined('IP_ROOT_PATH')) define('IP_ROOT_PATH', './../');
  36. if (!defined('PHP_EXT')) define('PHP_EXT', substr(strrchr(__FILE__, '.'), 1));
  37. require('pagestart.' . PHP_EXT);
  38. // Mighty Gorgon - ACP Privacy - BEGIN
  39. $is_allowed = check_acp_module_access();
  40. if (empty($is_allowed))
  41. {
  42. message_die(GENERAL_MESSAGE, $lang['Not_Auth_View']);
  43. }
  44. // Mighty Gorgon - ACP Privacy - END
  45. // Define constants and then include functions
  46. define('ROWS_PER_STEP', 3000);
  47. include_once(IP_ROOT_PATH . 'includes/class_db_backup.' . PHP_EXT);
  48. // Request some vars
  49. $mode = request_var('mode', '');
  50. $action = request_var('cancel', '') ? '' : request_var('action', '');
  51. $u_action = append_sid(basename(__FILE__) . '?mode=' . $mode);
  52. $submit = isset($_POST['submit']) ? true : false;
  53. $template->set_filenames(array('body' => ADM_TPL . 'admin_db_backup.tpl'));
  54. $template->assign_vars(array(
  55. 'MODE' => $mode
  56. )
  57. );
  58. switch ($mode)
  59. {
  60. case 'backup':
  61. $template->assign_block_vars('backup', array());
  62. switch ($action)
  63. {
  64. case 'download':
  65. $type = request_var('type', '');
  66. $table = request_var('table', array(''));
  67. $format = request_var('method', '');
  68. $where = request_var('where', '');
  69. $complete = request_var('complete', 1);
  70. $complete = $complete ? 1 : 0;
  71. $extended = request_var('extended', 1);
  72. $extended = $extended ? 1 : 0;
  73. $compact = request_var('compact', 1);
  74. $compact = $compact ? 1 : 0;
  75. $table_get = request_var('table_get', '');
  76. if (function_exists('gzcompress') && function_exists('gzuncompress') && !empty($table_get))
  77. {
  78. $table_get = unserialize(gzuncompress(stripslashes(base64_decode(strtr($table_get, '-_,', '+/=')))));
  79. }
  80. $start_default = 0;
  81. $limit_default = ROWS_PER_STEP;
  82. $started = request_var('started', false);
  83. $start = request_var('start', $start_default);
  84. $limit = request_var('limit', $limit_default);
  85. $progress = request_var('progress', 'false');
  86. $progress = ($progress == 'false') ? false : true;
  87. $time = request_var('time', time());
  88. $datecode = request_var('datecode', gmdate('Ymd'));
  89. $unique_id = request_var('unique_id', unique_id());
  90. $filepath = IP_ROOT_PATH . BACKUP_PATH;
  91. $filename = 'backup_' . $time . '_' . $datecode . '_' . $unique_id;
  92. $table = (!empty($table_get) ? explode(',', $table_get) : $table);
  93. $this_file_url = IP_ROOT_PATH . ADM . '/admin_db_backup.' . PHP_EXT . '?started=1&amp;mode=' . $mode . '&amp;action=' . $action . '&amp;method=' . $format . '&amp;where=' . $where . '&amp;complete=' . $complete . '&amp;extended=' . $extended . '&amp;compact=' . $compact . '&amp;type=' . $type . '&amp;time=' . $time . '&amp;datecode=' . $datecode . '&amp;unique_id=' . $unique_id;
  94. // Reassign these to boolean...
  95. $complete = $complete ? true : false;
  96. $extended = $extended ? true : false;
  97. $compact = $compact ? true : false;
  98. if (!sizeof($table))
  99. {
  100. message_die(GENERAL_ERROR, $lang['Table_Select_Error'] . '<br /><br />' . sprintf($lang['Click_return_lastpage'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/admin_db_backup.' . PHP_EXT . '?mode=backup') . '">', '</a>'), $lang['Error']);
  101. }
  102. $store = $download = $structure = $schema_data = false;
  103. if (($where == 'store_and_download') || ($where == 'store'))
  104. {
  105. $store = true;
  106. }
  107. if (($where == 'store_and_download') || ($where == 'download'))
  108. {
  109. $download = true;
  110. }
  111. if (($type == 'full') || ($type == 'structure'))
  112. {
  113. $structure = true;
  114. }
  115. if (($type == 'full') || ($type == 'data'))
  116. {
  117. $schema_data = true;
  118. }
  119. @set_time_limit(1200);
  120. $extractor = new mysql_extractor($download, $store, $format, $time, $filepath, $filename);
  121. $extractor->write_start($table_prefix, $started);
  122. if ($schema_data)
  123. {
  124. $archived_rows = 0;
  125. $table_get = $table;
  126. }
  127. foreach ($table as $table_name)
  128. {
  129. // Table Structure
  130. if (!$progress)
  131. {
  132. if ($structure)
  133. {
  134. $extractor->write_table($table_name);
  135. }
  136. else
  137. {
  138. $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
  139. }
  140. }
  141. // Table Data
  142. if ($schema_data)
  143. {
  144. $archived_rows_this_step = $extractor->write_data_mysql($table_name, $start, $limit, $complete, $extended, $compact);
  145. $archived_rows_prev_step = $archived_rows;
  146. $archived_rows += ($archived_rows_this_step !== false) ? $archived_rows_this_step : 0;
  147. if (($limit > 0) && ($archived_rows_this_step !== false) && ($archived_rows >= $limit))
  148. {
  149. $extractor->write_end();
  150. $limit = $limit_default;
  151. if ($archived_rows_prev_step == 0)
  152. {
  153. $start += $archived_rows_this_step;
  154. }
  155. $table_get = implode(',', $table_get);
  156. if (function_exists('gzcompress') && function_exists('gzuncompress') && !empty($table_get))
  157. {
  158. $table_get = strtr(base64_encode(addslashes(gzcompress(serialize($table_get), 9))), '+/=', '-_,');
  159. }
  160. $this_file_url .= '&amp;progress=true';
  161. $this_file_url .= '&amp;table_get=' . $table_get;
  162. $this_file_url .= '&amp;start=' . $start . '&amp;limit=' . $limit;
  163. $redirect_url = append_sid($this_file_url);
  164. $meta_tag = '</body><head><meta http-equiv="refresh" content="1;url=' . $redirect_url . '"></head><body>';
  165. $message .= $lang['BACKUP_IN_PROGRESS'] . '<br /><br />' . sprintf($lang['BACKUP_IN_PROGRESS_TABLE'], $table_name) . '<br /><br />' . $lang['BACKUP_IN_PROGRESS_REDIRECT'] . '<br /><br />' . sprintf($lang['BACKUP_IN_PROGRESS_REDIRECT_CLICK'], '<a href="' . $redirect_url . '">', '</a>');
  166. message_die(GENERAL_MESSAGE, $meta_tag . $message);
  167. }
  168. else
  169. {
  170. $progress = false;
  171. $start = $start_default;
  172. $limit -= (($limit > 0) && ($archived_rows_this_step !== false)) ? $archived_rows_this_step : 0;
  173. $table_get = array_diff($table_get, array($table_name));
  174. }
  175. }
  176. }
  177. $extractor->write_end();
  178. if ($download == true)
  179. {
  180. exit;
  181. }
  182. message_die(GENERAL_MESSAGE, $lang['BACKUP_SUCCESS'] . '<br /><br />' . sprintf($lang['Click_return_lastpage'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/admin_db_backup.' . PHP_EXT . '?mode=backup') . '">', '</a>') . '<br /><br />' . sprintf($lang['Click_return_admin_index'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/index.' . PHP_EXT . '?pane=right') . '">', '</a>'), $lang['Information']);
  183. break;
  184. default:
  185. $sql = 'SHOW TABLES';
  186. $result = $db->sql_query($sql);
  187. $tables = array();
  188. while ($row = $db->sql_fetchrow($result))
  189. {
  190. $tables[] = current($row);
  191. }
  192. $db->sql_freeresult($result);
  193. foreach ($tables as $table_name)
  194. {
  195. if (strlen($table_prefix) === 0 || strpos(strtolower($table_name), strtolower($table_prefix)) === 0)
  196. {
  197. $template->assign_block_vars('backup.tables', array(
  198. 'TABLE' => $table_name
  199. )
  200. );
  201. }
  202. }
  203. unset($tables);
  204. $template->assign_vars(array(
  205. 'U_ACTION' => $u_action . '&amp;action=download'
  206. )
  207. );
  208. $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
  209. foreach ($available_methods as $type => $module)
  210. {
  211. if (!@extension_loaded($module))
  212. {
  213. continue;
  214. }
  215. $template->assign_block_vars('backup.methods', array(
  216. 'FIRST_ROW' => (($type == 'gzip') ? ' id="method" checked="checked"' : ''),
  217. 'TYPE' => $type
  218. )
  219. );
  220. }
  221. $template->assign_block_vars('backup.methods', array(
  222. 'TYPE' => 'text'
  223. )
  224. );
  225. break;
  226. }
  227. break;
  228. case 'restore':
  229. $template->assign_block_vars('restore', array());
  230. switch ($action)
  231. {
  232. case 'submit':
  233. $delete = request_var('delete', '');
  234. $file = request_var('file', '');
  235. $confirm = request_var('confirm', '');
  236. if (!preg_match('#^backup_\d{10,}_[a-z\d]{8}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
  237. {
  238. message_die(GENERAL_ERROR, $lang['No_Backup_Selected'] . '<br /><br />' . sprintf($lang['Click_return_lastpage'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/admin_db_backup.' . PHP_EXT . '?mode=restore') . '">', '</a>'), $lang['Error']);
  239. }
  240. $file_name = IP_ROOT_PATH . BACKUP_PATH . $matches[0];
  241. if (!file_exists($file_name) || !is_readable($file_name))
  242. {
  243. message_die(GENERAL_ERROR, $lang['Backup_Invalid'] . '<br /><br />' . sprintf($lang['Click_return_lastpage'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/admin_db_backup.' . PHP_EXT . '?mode=restore') . '">', '</a>'), $lang['Error']);
  244. }
  245. if ($delete)
  246. {
  247. if (!$confirm)
  248. {
  249. $hidden_fields = '<input type="hidden" name="file" value="' . $file . '" /><input type="hidden" name="delete" value="' . $delete . '" /><input type="hidden" name="action" value="' . $action . '" />';
  250. $template->set_filenames(array('body' => ADM_TPL . 'confirm_body.tpl'));
  251. $template->assign_vars(array(
  252. 'MESSAGE_TITLE' => $lang['Delete'],
  253. 'MESSAGE_TEXT' => $lang['DELETE_SELECTED_BACKUP'],
  254. 'U_INDEX' => '',
  255. 'L_INDEX' => '',
  256. 'L_YES' => $lang['Yes'],
  257. 'L_NO' => $lang['No'],
  258. 'S_CONFIRM_ACTION' => append_sid('admin_db_backup.' . PHP_EXT . '?mode=restore'),
  259. 'S_HIDDEN_FIELDS' => $hidden_fields
  260. )
  261. );
  262. }
  263. else
  264. {
  265. @unlink($file_name);
  266. message_die(GENERAL_MESSAGE, $lang['BACKUP_DELETED'] . '<br /><br />' . sprintf($lang['Click_return_lastpage'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/admin_db_backup.' . PHP_EXT . '?mode=restore') . '">', '</a>') . '<br /><br />' . sprintf($lang['Click_return_admin_index'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/index.' . PHP_EXT . '?pane=right').'">', '</a>'), $lang['Information']);
  267. }
  268. }
  269. else
  270. {
  271. $download = request_var('download', '');
  272. if ($download)
  273. {
  274. $name = $matches[0];
  275. switch ($matches[1])
  276. {
  277. case 'sql':
  278. $mimetype = 'text/x-sql';
  279. break;
  280. case 'sql.bz2':
  281. $mimetype = 'application/x-bzip2';
  282. break;
  283. case 'sql.gz':
  284. $mimetype = 'application/x-gzip';
  285. break;
  286. }
  287. header('Pragma: no-cache');
  288. header("Content-Type: $mimetype; name=\"$name\"");
  289. header("Content-disposition: attachment; filename=$name");
  290. @set_time_limit(0);
  291. $fp = @fopen($file_name, 'rb');
  292. if ($fp !== false)
  293. {
  294. while (!feof($fp))
  295. {
  296. echo fread($fp, 8192);
  297. }
  298. fclose($fp);
  299. }
  300. flush();
  301. exit;
  302. }
  303. switch ($matches[1])
  304. {
  305. case 'sql':
  306. $fp = fopen($file_name, 'rb');
  307. $read = 'fread';
  308. $seek = 'fseek';
  309. $eof = 'feof';
  310. $close = 'fclose';
  311. $fgetd = 'fgetd';
  312. break;
  313. case 'sql.bz2':
  314. $fp = bzopen($file_name, 'r');
  315. $read = 'bzread';
  316. $seek = '';
  317. $eof = 'feof';
  318. $close = 'bzclose';
  319. $fgetd = 'fgetd_seekless';
  320. break;
  321. case 'sql.gz':
  322. $fp = gzopen($file_name, 'rb');
  323. $read = 'gzread';
  324. $seek = 'gzseek';
  325. $eof = 'gzeof';
  326. $close = 'gzclose';
  327. $fgetd = 'fgetd';
  328. break;
  329. }
  330. while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
  331. {
  332. $db->sql_query($sql);
  333. }
  334. $close($fp);
  335. message_die(GENERAL_MESSAGE, $lang['Restore_Success'] . '<br /><br />' . sprintf($lang['Click_return_lastpage'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/admin_db_backup.' . PHP_EXT . '?mode=restore') . '">', '</a>') . '<br /><br />' . sprintf($lang['Click_return_admin_index'], '<a href="' . append_sid(IP_ROOT_PATH . ADM . '/index.' . PHP_EXT . '?pane=right').'">', '</a>'), $lang['Information']);
  336. break;
  337. }
  338. default:
  339. $methods = array('sql');
  340. $available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2');
  341. foreach ($available_methods as $type => $module)
  342. {
  343. if (!@extension_loaded($module))
  344. {
  345. continue;
  346. }
  347. $methods[] = $type;
  348. }
  349. $dir = IP_ROOT_PATH . BACKUP_PATH;
  350. $dh = @opendir($dir);
  351. if ($dh)
  352. {
  353. while (($file = @readdir($dh)) !== false)
  354. {
  355. if (preg_match('#^backup_(\d{10,})_[a-z\d]{8}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
  356. {
  357. $supported = in_array($matches[2], $methods);
  358. if ($supported == 'true')
  359. {
  360. $tz = $config['board_timezone'];
  361. $time_mode = $user->data['user_time_mode'];
  362. $dst_time_lag = $user->data['user_dst_time_lag'];
  363. switch ($time_mode)
  364. {
  365. case MANUAL_DST:
  366. $dst_sec = $dst_time_lag * 60;
  367. $backup_time = $matches[1] + (3600 * $tz) + $dst_sec;
  368. break;
  369. case SERVER_SWITCH:
  370. $dst_sec = gmdate('I', $matches[1]) * $dst_time_lag * 60;
  371. $backup_time = $matches[1] + (3600 * $tz) + $dst_sec;
  372. break;
  373. default:
  374. $backup_time = $matches[1] + (3600 * $tz);
  375. break;
  376. }
  377. $template->assign_block_vars('restore.files', array(
  378. 'FILE' => $file,
  379. 'NAME' => gmdate('Y/m/d - H:i:s', $backup_time),
  380. 'SUPPORTED' => $supported
  381. )
  382. );
  383. }
  384. }
  385. }
  386. @closedir($dh);
  387. }
  388. $template->assign_vars(array(
  389. 'U_ACTION' => $u_action . '&amp;action=submit'
  390. )
  391. );
  392. break;
  393. }
  394. break;
  395. }
  396. $template->pparse('body');
  397. include(IP_ROOT_PATH . ADM . '/page_footer_admin.' . PHP_EXT);
  398. ?>