PageRenderTime 79ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/installation/includes/bigdump.php

https://bitbucket.org/asosso/joomla15
PHP | 451 lines | 270 code | 82 blank | 99 comment | 78 complexity | b575adfae6964320ae0bec4d17f48b64 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. <?php
  2. // no direct access
  3. defined( '_JEXEC' ) or die( 'Restricted access' );
  4. //TODO: Rewrite this so its cleaner
  5. // BigDump ver. 0.28b from 2007-06-08
  6. // Staggered import of an large MySQL Dump (like phpMyAdmin 2.x Dump)
  7. // Even through the webservers with hard runtime limit and those in safe mode
  8. // Works fine with Internet Explorer 7.0 and Firefox 2.x
  9. // Author: Alexey Ozerov (alexey at ozerov dot de)
  10. // AJAX & CSV functionalities: Krzysiek Herod (kr81uni at wp dot pl)
  11. // Copyright: GPL (C) 2003-2007
  12. // More Infos: http://www.ozerov.de/bigdump.php
  13. // This program is free software; you can redistribute it and/or modify it under the
  14. // terms of the GNU General Public License as published by the Free Software Foundation;
  15. // either version 2 of the License, or (at your option) any later version.
  16. // THIS SCRIPT IS PROVIDED AS IS, WITHOUT ANY WARRANTY OR GUARANTEE OF ANY KIND
  17. // USAGE
  18. // 1. Adjust the database configuration in this file
  19. // 2. Drop the old tables on the target database if your dump doesn't contain "DROP TABLE"
  20. // 3. Create the working directory (e.g. dump) on your web-server
  21. // 4. Upload bigdump.php and your dump files (.sql, .gz) via FTP to the working directory
  22. // 5. Run the bigdump.php from your browser via URL like http://www.yourdomain.com/dump/bigdump.php
  23. // 6. BigDump can start the next import session automatically if you enable the JavaScript
  24. // 7. Wait for the script to finish, do not close the browser window
  25. // 8. IMPORTANT: Remove bigdump.php and your dump files from the web-server
  26. // If Timeout errors still occure you may need to adjust the $linepersession setting in this file
  27. // LAST CHANGES
  28. // *** Improved error message for file open errors
  29. // *** Handle CSV files (you have to specify $csv_insert_table)
  30. // *** Restart script in the background using AJAX
  31. /**
  32. * Big Dump Handler for Migration and Import
  33. * Rewritten by Sam Moffatt from original work by Alexey Ozerov) for Joomla! 1.5
  34. */
  35. //defined('_JEXEC') or die('Access Denied');
  36. // Database configuration
  37. $db_server = '';
  38. $db_name = '';
  39. $db_username = '';
  40. $db_password = '';
  41. ?>
  42. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  43. <html xmlns="http://www.w3.org/1999/xhtml">
  44. <head>
  45. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  46. <title><?php JText::_('Migration load script') ?></title>
  47. <script type="text/javascript" src="includes/js/installation.js"></script>
  48. </head>
  49. <body>
  50. <?php
  51. // Other Settings
  52. $csv_insert_table = ''; // Destination table for CSV files
  53. $ajax = false; // AJAX mode: import will be done without refreshing the website
  54. //$filename = ''; // Specify the dump filename to suppress the file selection dialog
  55. $linespersession = 3000; // Lines to be executed per one import session
  56. $delaypersession = 0; // You can specify a sleep time in milliseconds after each session
  57. // Works only if JavaScript is activated. Use to reduce server overrun
  58. // Allowed comment delimiters: lines starting with these strings will be dropped by BigDump
  59. $comment[] = '#'; // Standard comment lines are dropped by default
  60. $comment[] = '-- ';
  61. // $comment[]='---'; // Uncomment this line if using proprietary dump created by outdated mysqldump
  62. // $comment[]='/*!'; // Or add your own string to leave out other proprietary things
  63. // Connection character set should be the same as the dump file character set (utf8, latin1, cp1251, koi8r etc.)
  64. // See http://dev.mysql.com/doc/refman/5.0/en/charset-charsets.html for the full list
  65. $db_connection_charset = '';
  66. // *******************************************************************************************
  67. // If not familiar with PHP please don't change anything below this line
  68. // *******************************************************************************************
  69. ob_start();
  70. define('VERSION', '0.28b');
  71. define('DATA_CHUNK_LENGTH', 16384); // How many chars are read per time
  72. define('MAX_QUERY_LINES', 300); // How many lines may be considered to be one query (except text lines)
  73. define('TESTMODE', false); // Set to true to process the file without actually accessing the database
  74. header("Expires: Mon, 1 Dec 2003 01:00:00 GMT");
  75. header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  76. header("Cache-Control: no-store, no-cache, must-revalidate");
  77. header("Cache-Control: post-check=0, pre-check=0", false);
  78. header("Pragma: no-cache");
  79. //@ini_set('auto_detect_line_endings', true);
  80. //@set_time_limit(0);
  81. // Clean and strip anything we don't want from user's input [0.27b]
  82. foreach ($_REQUEST as $key => $val) {
  83. $val = preg_replace("/[^_A-Za-z0-9-\.&=]/i", '', $val);
  84. $_REQUEST[$key] = $val;
  85. }
  86. // Determine filename to execute for loading...
  87. $filename = JPATH_BASE . DS . 'sql' . DS . 'migration' . DS . 'migrate.sql';
  88. $_REQUEST['fn'] = $filename;
  89. $error = false;
  90. $file = false;
  91. // Single file mode
  92. if (!$error && !isset ($_REQUEST["fn"]) && $filename != "") {
  93. echo ("<p><a href=\"" . str_replace(array('"', '<', '>', "'"), '', $_SERVER["PHP_SELF"]) . "?start=1&amp;fn=$filename&amp;foffset=0&amp;totalqueries=0\">Start Import</a> from $filename into $db_name at $db_server</p>\n");
  94. }
  95. // Open the file
  96. if (!$error && isset ($_REQUEST["fn"])) {
  97. // Recognize GZip filename
  98. if (preg_match("#\.gz$#i", $_REQUEST["fn"]))
  99. $gzipmode = true;
  100. else
  101. $gzipmode = false;
  102. if ((!$gzipmode && !$file = fopen($_REQUEST["fn"], "rt")) || ($gzipmode && !$file = gzopen($_REQUEST["fn"], "rt"))) {
  103. echo ("<p class=\"error\">". JText::sprintf("Cant open file for import", $_REQUEST["fn"]) ."</p>\n");
  104. echo ("<p>". JText::_('CHECKDUMPFILE') .
  105. " .<br />". JText::_('NEEDTOUPLOADFILE')."</p>\n");
  106. $error = true;
  107. }
  108. // Get the file size (can't do it fast on gzipped files, no idea how)
  109. else
  110. if ((!$gzipmode && fseek($file, 0, SEEK_END) == 0) || ($gzipmode && gzseek($file, 0) == 0)) {
  111. if (!$gzipmode)
  112. $filesize = ftell($file);
  113. else
  114. $filesize = gztell($file); // Always zero, ignore
  115. } else {
  116. echo ("<p class=\"error\">". JText::_('FILESIZEUNKNOWN') . $_REQUEST["fn"] . "</p>\n");
  117. $error = true;
  118. }
  119. }
  120. // *******************************************************************************************
  121. // START IMPORT SESSION HERE
  122. // *******************************************************************************************
  123. if (!$error && isset ($_REQUEST["start"]) && isset ($_REQUEST["foffset"]) && preg_match("#(\.(sql|gz|csv))$#i", $_REQUEST["fn"])) {
  124. // Check start and foffset are numeric values
  125. if (!is_numeric($_REQUEST["start"]) || !is_numeric($_REQUEST["foffset"])) {
  126. echo ("<p class=\"error\">". JText::_('NONNUMERICOFFSET') ."</p>\n");
  127. $error = true;
  128. }
  129. if (!$error) {
  130. $_REQUEST["start"] = floor($_REQUEST["start"]);
  131. $_REQUEST["foffset"] = floor($_REQUEST["foffset"]);
  132. }
  133. // Check $_REQUEST["foffset"] upon $filesize (can't do it on gzipped files)
  134. if (!$error && !$gzipmode && $_REQUEST["foffset"] > $filesize) {
  135. echo ("<p class=\"error\">".JText::_('POINTEREOF')."</p>\n");
  136. $error = true;
  137. }
  138. // Set file pointer to $_REQUEST["foffset"]
  139. if (!$error && ((!$gzipmode && fseek($file, $_REQUEST["foffset"]) != 0) || ($gzipmode && gzseek($file, $_REQUEST["foffset"]) != 0))) {
  140. echo ("<p class=\"error\">". JText::_('UNABLETOSETOFFSET') . $_REQUEST["foffset"] . "</p>\n");
  141. $error = true;
  142. }
  143. // Start processing queries from $file
  144. if (!$error) {
  145. $query = "";
  146. $queries = 0;
  147. $totalqueries = $_REQUEST["totalqueries"];
  148. $linenumber = $_REQUEST["start"];
  149. $querylines = 0;
  150. $inparents = false;
  151. // Stay processing as long as the $linespersession is not reached or the query is still incomplete
  152. while ($linenumber < $_REQUEST["start"] + $linespersession || $query != "") {
  153. // Read the whole next line
  154. $dumpline = "";
  155. while (!feof($file) && substr($dumpline, -1) != "\n") {
  156. if (!$gzipmode)
  157. $dumpline .= fgets($file, DATA_CHUNK_LENGTH);
  158. else
  159. $dumpline .= gzgets($file, DATA_CHUNK_LENGTH);
  160. }
  161. if ($dumpline === "")
  162. break;
  163. // Handle DOS and Mac encoded linebreaks (I don't know if it will work on Win32 or Mac Servers)
  164. $dumpline = str_replace("\r\n", "\n", $dumpline);
  165. $dumpline = str_replace("\r", "\n", $dumpline);
  166. // DIAGNOSTIC
  167. // echo ("<p>Line $linenumber: $dumpline</p>\n");
  168. // Skip comments and blank lines only if NOT in parents
  169. if (!$inparents) {
  170. $skipline = false;
  171. reset($comment);
  172. foreach ($comment as $comment_value) {
  173. if (!$inparents && (trim($dumpline) == "" || strpos($dumpline, $comment_value) === 0)) {
  174. $skipline = true;
  175. break;
  176. }
  177. }
  178. if ($skipline) {
  179. $linenumber++;
  180. continue;
  181. }
  182. }
  183. // Remove double back-slashes from the dumpline prior to count the quotes ('\\' can only be within strings)
  184. $dumpline_deslashed = str_replace("\\\\", "", $dumpline);
  185. // Count ' and \' in the dumpline to avoid query break within a text field ending by ;
  186. // Please don't use double quotes ('"')to surround strings, it wont work
  187. $parents = substr_count($dumpline_deslashed, "'") - substr_count($dumpline_deslashed, "\\'");
  188. if ($parents % 2 != 0)
  189. $inparents = !$inparents;
  190. // Add the line to query
  191. $query .= $dumpline;
  192. // Don't count the line if in parents (text fields may include unlimited linebreaks)
  193. if (!$inparents)
  194. $querylines++;
  195. // Stop if query contains more lines as defined by MAX_QUERY_LINES
  196. if ($querylines > MAX_QUERY_LINES) {
  197. echo ("<p class=\"error\">". JText::_('STOPPEDATLINE') ." $linenumber. </p>");
  198. echo ("<p>". JText::sprintf('TOOMANYLINES',MAX_QUERY_LINES)."</p>");
  199. $error = true;
  200. break;
  201. }
  202. $vars = $this->getVars();
  203. $DBtype = JArrayHelper::getValue($vars, 'DBtype', 'mysql');
  204. $DBhostname = JArrayHelper::getValue($vars, 'DBhostname', '');
  205. $DBuserName = JArrayHelper::getValue($vars, 'DBuserName', '');
  206. $DBpassword = JArrayHelper::getValue($vars, 'DBpassword', '');
  207. $DBname = JArrayHelper::getValue($vars, 'DBname', '');
  208. $DBPrefix = JArrayHelper::getValue($vars, 'DBPrefix', 'jos_');
  209. $DBOld = JArrayHelper::getValue($vars, 'DBOld', 'bu');
  210. //$migration = JArrayHelper::getValue($vars, 'migration', '0');
  211. $migration = JRequest::getVar( 'migration', 0, 'post', 'bool' );
  212. $db = & JInstallationHelper::getDBO($DBtype, $DBhostname, $DBuserName, $DBpassword, $DBname, $DBPrefix);
  213. if(JError::isError($db)) jexit(JText::_('CONNECTION FAIL'));
  214. // echo 'Done.<br />';
  215. // Execute query if end of query detected (; as last character) AND NOT in parents
  216. if (ereg(";$", trim($dumpline)) && !$inparents) {
  217. if (!TESTMODE) {
  218. $db->setQuery(trim($query));
  219. // echo $query . '<br />';
  220. if (!$db->Query()) {
  221. echo ("<p class=\"error\">".JText::_('Error at the line') ." $linenumber: ". trim($dumpline) . "</p>\n");
  222. echo ("<p>".JText::_('Query:') . trim(nl2br(htmlentities($query))) ."</p>\n");
  223. echo ("<p>MySQL: " . mysql_error() . "</p>\n");
  224. $error = true;
  225. break;
  226. }
  227. $totalqueries++;
  228. $queries++;
  229. $query = "";
  230. $querylines = 0;
  231. }
  232. }
  233. $linenumber++;
  234. }
  235. }
  236. // Get the current file position
  237. if (!$error) {
  238. if (!$gzipmode)
  239. $foffset = ftell($file);
  240. else
  241. $foffset = gztell($file);
  242. if (!$foffset) {
  243. echo ("<p class=\"error\">".JText::_('CANTREADPOINTER')."</p>\n");
  244. $error = true;
  245. }
  246. }
  247. // Print statistics
  248. // echo ("<p class=\"centr\"><b>Statistics</b></p>\n");
  249. if (!$error) {
  250. $lines_this = $linenumber - $_REQUEST["start"];
  251. $lines_done = $linenumber -1;
  252. $lines_togo = ' ? ';
  253. $lines_tota = ' ? ';
  254. $queries_this = $queries;
  255. $queries_done = $totalqueries;
  256. $queries_togo = ' ? ';
  257. $queries_tota = ' ? ';
  258. $bytes_this = $foffset - $_REQUEST["foffset"];
  259. $bytes_done = $foffset;
  260. $kbytes_this = round($bytes_this / 1024, 2);
  261. $kbytes_done = round($bytes_done / 1024, 2);
  262. $mbytes_this = round($kbytes_this / 1024, 2);
  263. $mbytes_done = round($kbytes_done / 1024, 2);
  264. if (!$gzipmode) {
  265. $bytes_togo = $filesize - $foffset;
  266. $bytes_tota = $filesize;
  267. $kbytes_togo = round($bytes_togo / 1024, 2);
  268. $kbytes_tota = round($bytes_tota / 1024, 2);
  269. $mbytes_togo = round($kbytes_togo / 1024, 2);
  270. $mbytes_tota = round($kbytes_tota / 1024, 2);
  271. $pct_this = ceil($bytes_this / $filesize * 100);
  272. $pct_done = ceil($foffset / $filesize * 100);
  273. $pct_togo = 100 - $pct_done;
  274. $pct_tota = 100;
  275. if ($bytes_togo == 0) {
  276. $lines_togo = '0';
  277. $lines_tota = $linenumber -1;
  278. $queries_togo = '0';
  279. $queries_tota = $totalqueries;
  280. }
  281. $pct_bar = "<div style=\"height:15px;width:$pct_done%;background-color:#000080;margin:0px;\"></div>";
  282. } else {
  283. $bytes_togo = ' ? ';
  284. $bytes_tota = ' ? ';
  285. $kbytes_togo = ' ? ';
  286. $kbytes_tota = ' ? ';
  287. $mbytes_togo = ' ? ';
  288. $mbytes_tota = ' ? ';
  289. $pct_this = ' ? ';
  290. $pct_done = ' ? ';
  291. $pct_togo = ' ? ';
  292. $pct_tota = 100;
  293. $pct_bar = str_replace(' ', '&nbsp;', '<tt>[ Not available for gzipped files ]</tt>');
  294. }
  295. /*
  296. echo ("
  297. <center>
  298. <table width=\"520\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\">
  299. <tr><th class=\"bg4\"> </th><th class=\"bg4\">Session</th><th class=\"bg4\">Done</th><th class=\"bg4\">To go</th><th class=\"bg4\">Total</th></tr>
  300. <tr><th class=\"bg4\">Lines</th><td class=\"bg3\">$lines_this</td><td class=\"bg3\">$lines_done</td><td class=\"bg3\">$lines_togo</td><td class=\"bg3\">$lines_tota</td></tr>
  301. <tr><th class=\"bg4\">Queries</th><td class=\"bg3\">$queries_this</td><td class=\"bg3\">$queries_done</td><td class=\"bg3\">$queries_togo</td><td class=\"bg3\">$queries_tota</td></tr>
  302. <tr><th class=\"bg4\">Bytes</th><td class=\"bg3\">$bytes_this</td><td class=\"bg3\">$bytes_done</td><td class=\"bg3\">$bytes_togo</td><td class=\"bg3\">$bytes_tota</td></tr>
  303. <tr><th class=\"bg4\">KB</th><td class=\"bg3\">$kbytes_this</td><td class=\"bg3\">$kbytes_done</td><td class=\"bg3\">$kbytes_togo</td><td class=\"bg3\">$kbytes_tota</td></tr>
  304. <tr><th class=\"bg4\">MB</th><td class=\"bg3\">$mbytes_this</td><td class=\"bg3\">$mbytes_done</td><td class=\"bg3\">$mbytes_togo</td><td class=\"bg3\">$mbytes_tota</td></tr>
  305. <tr><th class=\"bg4\">%</th><td class=\"bg3\">$pct_this</td><td class=\"bg3\">$pct_done</td><td class=\"bg3\">$pct_togo</td><td class=\"bg3\">$pct_tota</td></tr>
  306. <tr><th class=\"bg4\">% bar</th><td class=\"bgpctbar\" colspan=\"4\">$pct_bar</td></tr>
  307. </table>
  308. </center>
  309. \n");*/
  310. // Finish message and restart the script
  311. if ($linenumber < $_REQUEST["start"] + $linespersession) {
  312. echo ("<div id=\"installer\"><p class=\"successcentr\">".JText::_('CONGRATSEOF')."</p>\n");
  313. // Do migration
  314. if($migration) {
  315. ?><br />Migration will continue shortly...</div>
  316. <form action="index.php" method="post" name="migrateForm" id="migrateForm" class="form-validate" target="migrationtarget">
  317. <input type="hidden" name="task" value="postmigrate" />
  318. <input type="hidden" name="migration" value="<?php echo $migration ?>" />
  319. <input type="hidden" name="loadchecked" value="1" />
  320. <input type="hidden" name="dataLoaded" value="1" />
  321. <input type="hidden" name="DBtype" value="<?php echo $DBtype ?>" />
  322. <input type="hidden" name="DBhostname" value="<?php echo $DBhostname ?>" />
  323. <input type="hidden" name="DBuserName" value="<?php echo $DBuserName ?>" />
  324. <input type="hidden" name="DBpassword" value="<?php echo $DBpassword ?>" />
  325. <input type="hidden" name="DBname" value="<?php echo $DBname ?>" />
  326. <input type="hidden" name="DBPrefix" value="<?php echo $DBPrefix ?>" />
  327. </form>
  328. <script language="JavaScript" type="text/javascript">window.setTimeout('submitForm(this.document.migrateForm,"postmigrate")',500);</script>
  329. <?php
  330. } else echo '<br />'. JText::_('FINALIZEINSTALL').'</div>';
  331. //echo ("<p class=\"centr\">Thank you for using this tool! Please rate <a href=\"http://www.hotscripts.com/Detailed/20922.html\" target=\"_blank\">Bigdump at Hotscripts.com</a></p>\n");
  332. //echo ("<p class=\"centr\">You can send me some bucks or euros as appreciation <a href=\"http://www.ozerov.de/bigdump.php\" target=\"_blank\">via PayPal</a></p>\n");
  333. $error = true;
  334. } else {
  335. if ($delaypersession != 0)
  336. echo ("<p class=\"centr\">".JText::sprintf('DELAYMSG',$delaypersession)."</p>\n");
  337. ?><script language="JavaScript" type="text/javascript">window.setTimeout('submitForm(this.document.migrateForm,"dumpLoad")',500);</script>
  338. <div id="installer"><p><?php echo JText::_('LOADSQLFILE') ?></p></div>
  339. <form action="index.php" method="post" name="migrateForm" id="migrateForm" class="form-validate" target="migrationtarget">
  340. <input type="hidden" name="task" value="dumpLoad" />
  341. <input type="hidden" name="migration" value="<?php echo $migration ?>" />
  342. <input type="hidden" name="loadchecked" value="1" />
  343. <input type="hidden" name="dataLoaded" value="1" />
  344. <input type="hidden" name="DBtype" value="<?php echo $DBtype ?>" />
  345. <input type="hidden" name="DBhostname" value="<?php echo $DBhostname ?>" />
  346. <input type="hidden" name="DBuserName" value="<?php echo $DBuserName ?>" />
  347. <input type="hidden" name="DBpassword" value="<?php echo $DBpassword ?>" />
  348. <input type="hidden" name="DBname" value="<?php echo $DBname ?>" />
  349. <input type="hidden" name="DBPrefix" value="<?php echo $DBPrefix ?>" />
  350. <input type="hidden" name="start" value="<?php echo $linenumber ?>" />
  351. <input type="hidden" name="foffset" value="<?php echo $foffset ?>" />
  352. <input type="hidden" name="totalqueries" value="<?php echo $totalqueries ?>" />
  353. </form>
  354. <?php
  355. }
  356. } else
  357. echo ("<p class=\"error\">".JText::_('STOPPEDONERROR')."</p>\n");
  358. }
  359. //if ($dbconnection) mysql_close();
  360. if ($file && !$gzipmode)
  361. fclose($file);
  362. else
  363. if ($file && $gzipmode)
  364. gzclose($file);
  365. //ob_flush();
  366. //die();