PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/sources/DumpDatabase.php

https://github.com/Arantor/Elkarte
PHP | 233 lines | 140 code | 35 blank | 58 comment | 24 complexity | ea6c4fc742f5deb97211f816281bc244 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-3.0
  1. <?php
  2. /**
  3. * @name ElkArte Forum
  4. * @copyright ElkArte Forum contributors
  5. * @license BSD http://opensource.org/licenses/BSD-3-Clause
  6. *
  7. * This software is a derived product, based on:
  8. *
  9. * Simple Machines Forum (SMF)
  10. * copyright: 2011 Simple Machines (http://www.simplemachines.org)
  11. * license: BSD, See included LICENSE.TXT for terms and conditions.
  12. *
  13. * @version 1.0 Alpha
  14. *
  15. * This file has a single job - database backup.
  16. *
  17. */
  18. if (!defined('ELKARTE'))
  19. die('No access...');
  20. /**
  21. * Dumps the database.
  22. * It writes all of the database to standard output.
  23. * It uses gzip compression if compress is set in the URL/post data.
  24. * It may possibly time out, and mess up badly if you were relying on it. :P
  25. * The data dumped depends on whether "struct" and "data" are passed.
  26. * It requires an administrator and the session hash by post.
  27. * It is called from ManageMaintenance.php.
  28. */
  29. function DumpDatabase2()
  30. {
  31. global $db_name, $scripturl, $context, $modSettings, $crlf, $smcFunc, $db_prefix, $db_show_debug;
  32. // Administrators only!
  33. if (!allowedTo('admin_forum'))
  34. fatal_lang_error('no_dump_database', 'critical');
  35. // We don't need debug when dumping the database
  36. $modSettings['disableQueryCheck'] = true;
  37. $db_show_debug = false;
  38. // You can't dump nothing!
  39. if (!isset($_REQUEST['struct']) && !isset($_REQUEST['data']))
  40. $_REQUEST['data'] = true;
  41. checkSession('post');
  42. // We will need this, badly!
  43. db_extend();
  44. // Attempt to stop from dying...
  45. @set_time_limit(600);
  46. $time_limit = ini_get('max_execution_time');
  47. $start_time = time();
  48. // @todo ... fail on not getting the requested memory?
  49. setMemoryLimit('256M');
  50. $memory_limit = memoryReturnBytes(ini_get('memory_limit')) / 4;
  51. $current_used_memory = 0;
  52. $db_backup = '';
  53. $output_function = 'un_compressed';
  54. @ob_end_clean();
  55. // Start saving the output... (don't do it otherwise for memory reasons.)
  56. if (isset($_REQUEST['compress']) && function_exists('gzencode'))
  57. {
  58. $output_function = 'gzencode';
  59. // Send faked headers so it will just save the compressed output as a gzip.
  60. header('Content-Type: application/x-gzip');
  61. header('Accept-Ranges: bytes');
  62. header('Content-Encoding: none');
  63. // Gecko browsers... don't like this. (Mozilla, Firefox, etc.)
  64. if (!isBrowser('gecko'))
  65. header('Content-Transfer-Encoding: binary');
  66. // The file extension will include .gz...
  67. $extension = '.sql.gz';
  68. }
  69. else
  70. {
  71. // Get rid of the gzipping alreading being done.
  72. if (!empty($modSettings['enableCompressedOutput']))
  73. @ob_end_clean();
  74. // If we can, clean anything already sent from the output buffer...
  75. elseif (ob_get_length() != 0)
  76. ob_clean();
  77. // Tell the client to save this file, even though it's text.
  78. header('Content-Type: ' . (isBrowser('ie') || isBrowser('opera') ? 'application/octetstream' : 'application/octet-stream'));
  79. header('Content-Encoding: none');
  80. // This time the extension should just be .sql.
  81. $extension = '.sql';
  82. }
  83. // This should turn off the session URL parser.
  84. $scripturl = '';
  85. // If this database is flat file and has a handler function pass it to that.
  86. if (!empty($smcFunc['db_get_backup']))
  87. {
  88. $smcFunc['db_get_backup']();
  89. exit;
  90. }
  91. // Send the proper headers to let them download this file.
  92. header('Content-Disposition: attachment; filename="' . $db_name . '-' . (empty($_REQUEST['struct']) ? 'data' : (empty($_REQUEST['data']) ? 'structure' : 'complete')) . '_' . strftime('%Y-%m-%d') . $extension . '"');
  93. header('Cache-Control: private');
  94. header('Connection: close');
  95. // This makes things simpler when using it so very very often.
  96. $crlf = "\r\n";
  97. // SQL Dump Header.
  98. $db_chunks =
  99. '-- ==========================================================' . $crlf .
  100. '--' . $crlf .
  101. '-- Database dump of tables in `' . $db_name . '`' . $crlf .
  102. '-- ' . timeformat(time(), false) . $crlf .
  103. '--' . $crlf .
  104. '-- ==========================================================' . $crlf .
  105. $crlf;
  106. // Get all tables in the database....
  107. if (preg_match('~^`(.+?)`\.(.+?)$~', $db_prefix, $match) != 0)
  108. {
  109. $db = strtr($match[1], array('`' => ''));
  110. $dbp = str_replace('_', '\_', $match[2]);
  111. }
  112. else
  113. {
  114. $db = false;
  115. $dbp = $db_prefix;
  116. }
  117. // Dump each table.
  118. $tables = $smcFunc['db_list_tables'](false, $db_prefix . '%');
  119. foreach ($tables as $tableName)
  120. {
  121. // Are we dumping the structures?
  122. if (isset($_REQUEST['struct']))
  123. {
  124. $db_chunks .=
  125. $crlf .
  126. '--' . $crlf .
  127. '-- Table structure for table `' . $tableName . '`' . $crlf .
  128. '--' . $crlf .
  129. $crlf .
  130. $smcFunc['db_table_sql']($tableName) . ';' . $crlf;
  131. }
  132. else
  133. // This is needed to speedup things later
  134. $smcFunc['db_table_sql']($tableName);
  135. // How about the data?
  136. if (!isset($_REQUEST['data']) || substr($tableName, -10) == 'log_errors')
  137. continue;
  138. $first_round = true;
  139. $close_table = false;
  140. // Are there any rows in this table?
  141. while ($get_rows = $smcFunc['db_insert_sql']($tableName, $first_round))
  142. {
  143. if (empty($get_rows))
  144. break;
  145. // Time is what we need here!
  146. if (function_exists('apache_reset_timeout'))
  147. @apache_reset_timeout();
  148. elseif (!empty($time_limit) && ($start_time + $time_limit - 20 > time()))
  149. {
  150. $start_time = time();
  151. @set_time_limit(150);
  152. }
  153. if ($first_round)
  154. {
  155. $db_chunks .=
  156. $crlf .
  157. '--' . $crlf .
  158. '-- Dumping data in `' . $tableName . '`' . $crlf .
  159. '--' . $crlf .
  160. $crlf;
  161. $first_round = false;
  162. }
  163. $db_chunks .=
  164. $get_rows;
  165. $current_used_memory += $smcFunc['strlen']($db_chunks);
  166. $db_backup .= $db_chunks;
  167. unset($db_chunks);
  168. $db_chunks = '';
  169. if ($current_used_memory > $memory_limit)
  170. {
  171. echo $output_function($db_backup);
  172. $current_used_memory = 0;
  173. // This is probably redundant
  174. unset($db_backup);
  175. $db_backup = '';
  176. }
  177. $close_table = true;
  178. }
  179. // No rows to get - skip it.
  180. if ($close_table)
  181. $db_backup .=
  182. '-- --------------------------------------------------------' . $crlf;
  183. }
  184. $db_backup .=
  185. $crlf .
  186. '-- Done' . $crlf;
  187. echo $output_function($db_backup);
  188. exit;
  189. }
  190. /**
  191. * Dummy/helper function, it simply returns the string passed as argument
  192. * @param $string, a string
  193. * @return the string passed
  194. */
  195. function un_compressed($string = '')
  196. {
  197. return $string;
  198. }