-<?php
-/*
- * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * (see nucleus/documentation/index.html#license for more info)
- */
-/**
- * Scripts to create/restore a backup of the Nucleus database
- *
- * Based on code in phpBB (http://phpBB.sourceforge.net)
- *
- * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: backup.php,v 1.9 2008-02-08 09:31:22 kimitake Exp $
- * $NucleusJP: backup.php,v 1.8.2.1 2007/08/08 05:23:31 kimitake Exp $
- */
-
-
-/**
- * This function creates an sql dump of the database and sends it to
- * the user as a file (can be gzipped if they want)
- *
- * @requires
- * no output may have preceded (new headers are sent)
- * @param gzip
- * 1 = compress backup file, 0 = no compression (default)
- */
-function do_backup($gzip = 0) {
- global $manager;
-
- // tables of which backup is needed
- $tables = array(
- sql_table('actionlog'),
- sql_table('ban'),
- sql_table('blog'),
- sql_table('comment'),
- sql_table('config'),
- sql_table('item'),
- sql_table('karma'),
- sql_table('member'),
- sql_table('skin'),
- sql_table('skin_desc'),
- sql_table('team'),
- sql_table('template'),
- sql_table('template_desc'),
- sql_table('plugin'),
- sql_table('plugin_event'),
- sql_table('plugin_option'),
- sql_table('plugin_option_desc'),
- sql_table('category'),
- sql_table('activation'),
- sql_table('tickets'),
- );
-
- // add tables that plugins want to backup to the list
- // catch all output generated by plugins
- ob_start();
- $res = sql_query('SELECT pfile FROM '.sql_table('plugin'));
- while ($plugName = mysql_fetch_object($res)) {
- $plug =& $manager->getPlugin($plugName->pfile);
- if ($plug) $tables = array_merge($tables, (array) $plug->getTableList());
- }
- ob_end_clean();
-
- // remove duplicates
- $tables = array_unique($tables);
-
- // make sure browsers don't cache the backup
- header("Pragma: no-cache");
-
- // don't allow gzip compression when extension is not loaded
- if (($gzip != 0) && !extension_loaded("zlib"))
- $gzip = 0;
-
-
-
- if ($gzip) {
- // use an output buffer
- @ob_start();
- @ob_implicit_flush(0);
-
- // set filename
- $filename = 'nucleus_db_backup_'.strftime("%Y%m%d", time()).".sql.gz";
- } else {
- $filename = 'nucleus_db_backup_'.strftime("%Y%m%d", time()).".sql";
- }
-
-
- // send headers that tell the browser a file is coming
- header("Content-Type: text/x-delimtext; name=\"$filename\"");
- header("Content-disposition: attachment; filename=$filename");
-
- // dump header
- echo "#\n";
- echo "# This is a backup file generated by Nucleus \n";
- echo "# http://www.nucleuscms.org/\n";
- echo "#\n";
- echo "# backup-date: " . gmdate("d-m-Y H:i:s", time()) . " GMT\n";
- global $nucleus;
- echo "# Nucleus CMS version: " . $nucleus['version'] . "\n";
- echo "#\n";
- echo "# WARNING: Only try to restore on servers running the exact same version of Nucleus\n";
- echo "#\n";
-
- // dump all tables
- reset($tables);
- array_walk($tables, '_backup_dump_table');
-
- if($gzip)
- {
- $Size = ob_get_length();
- $Crc = crc32(ob_get_contents());
- $contents = gzcompress(ob_get_contents());
- ob_end_clean();
- echo "\x1f\x8b\x08\x00\x00\x00\x00\x00".substr($contents, 0, strlen($contents) - 4).gzip_PrintFourChars($Crc).gzip_PrintFourChars($Size);
- }
-
- exit;
-
-}
-
-
-/**
- * Creates a dump for a single table
- * ($tablename and $key are filled in by array_walk)
- */
-function _backup_dump_table($tablename, $key) {
-
- echo "#\n";
- echo "# TABLE: " . $tablename . "\n";
- echo "#\n";
-
- // dump table structure
- _backup_dump_structure($tablename);
-
- // dump table contents
- _backup_dump_contents($tablename);
-}
-
-function _backup_dump_structure($tablename) {
-
- // add command to drop table on restore
- echo "DROP TABLE IF EXISTS $tablename;\n";
- echo "CREATE TABLE $tablename(\n";
-
- //
- // Ok lets grab the fields...
- //
- $result = mysql_query("SHOW FIELDS FROM $tablename");
- $row = mysql_fetch_array($result);
- while ($row) {
-
- echo ' ' . $row['Field'] . ' ' . $row['Type'];
-
- if(isset($row['Default']))
- echo ' DEFAULT \'' . $row['Default'] . '\'';
-
- if($row['Null'] != "YES")
- echo ' NOT NULL';
-
- if($row['Extra'] != "")
- echo ' ' . $row['Extra'];
-
- $row = mysql_fetch_array($result);
-
- // add comma's except for last one
- if ($row)
- echo ",\n";
- }
-
- //
- // Get any Indexed fields from the database...
- //
- $result = mysql_query("SHOW KEYS FROM $tablename");
- while($row = mysql_fetch_array($result)) {
- $kname = $row['Key_name'];
-
- if(($kname != 'PRIMARY') && ($row['Non_unique'] == 0))
- $kname = "UNIQUE|$kname";
- if(($kname != 'PRIMARY') && ($row['Index_type'] == 'FULLTEXT'))
- $kname = "FULLTEXT|$kname";
-
- if(!is_array($index[$kname]))
- $index[$kname] = array();
-
- $index[$kname][] = $row['Column_name'] . ( ($row['Sub_part']) ? ' (' . $row['Sub_part'] . ')' : '');
- }
-
- while(list($x, $columns) = @each($index)) {
- echo ", \n";
-
- if($x == 'PRIMARY')
- echo ' PRIMARY KEY (' . implode($columns, ', ') . ')';
- elseif (substr($x,0,6) == 'UNIQUE')
- echo ' UNIQUE KEY ' . substr($x,7) . ' (' . implode($columns, ', ') . ')';
- elseif (substr($x,0,8) == 'FULLTEXT')
- echo ' FULLTEXT KEY ' . substr($x,9) . ' (' . implode($columns, ', ') . ')';
- elseif (($x == 'ibody') || ($x == 'cbody')) // karma 2004-05-30 quick and dirty fix. fulltext keys were not in SQL correctly.
- echo ' FULLTEXT KEY ' . substr($x,9) . ' (' . implode($columns, ', ') . ')';
- else
- echo " KEY $x (" . implode($columns, ', ') . ')';
- }
-
- echo "\n);\n\n";
-}
-
-/**
- * Returns the field named for the given table in the
- * following format:
- *
- * (column1, column2, ..., columnn)
- */
-function _backup_get_field_names($result, $num_fields) {
-
-/* if (function_exists('mysqli_fetch_fields') ) {
-
- $fields = mysqli_fetch_fields($result);
- for ($j = 0; $j < $num_fields; $j++)
- $fields[$j] = $fields[$j]->name;
-
- } else {*/
-
- $fields = array();
- for ($j = 0; $j < $num_fields; $j++) {
- $fields[] = mysql_field_name($result, $j);
- }
-
-/* }*/
-
- return '(' . implode(', ', $fields) . ')';
-}
-
-function _backup_dump_contents($tablename) {
- //
- // Grab the data from the table.
- //
- $result = mysql_query("SELECT * FROM $tablename");
-
- if(mysql_num_rows($result) > 0)
- echo "\n#\n# Table Data for $tablename\n#\n";
-
- $num_fields = mysql_num_fields($result);
-
- //
- // Compose fieldname list
- //
- $tablename_list = _backup_get_field_names($result, $num_fields);
-
- //
- // Loop through the resulting rows and build the sql statement.
- //
- while ($row = mysql_fetch_array($result))
- {
- // Start building the SQL statement.
-
- echo "INSERT INTO $tablename $tablename_list VALUES(";
-
- // Loop through the rows and fill in data for each column
- for ($j = 0; $j < $num_fields; $j++) {
- if(!isset($row[$j])) {
- // no data for column
- echo ' NULL';
- } elseif ($row[$j] != '') {
- // data
- echo " '" . addslashes($row[$j]) . "'";
- } else {
- // empty column (!= no data!)
- echo "''";
- }
-
- // only add comma when not last column
- if ($j != ($num_fields - 1))
- echo ",";
- }
-
- echo ");\n";
-
- }
-
-
- echo "\n";
-
-}
-
-// copied from phpBB
-function gzip_PrintFourChars($Val)
-{
- for ($i = 0; $i < 4; $i ++)
- {
- $return .= chr($Val % 256);
- $Val = floor($Val / 256);
- }
- return $return;
-}
-
-function do_restore() {
-
- $uploadInfo = postFileInfo('backup_file');
-
- // first of all: get uploaded file:
- if (empty($uploadInfo['name']))
- return 'No file uploaded';
- if (!is_uploaded_file($uploadInfo['tmp_name']))
- return 'No file uploaded';
-
- $backup_file_name = $uploadInfo['name'];
- $backup_file_tmpname = $uploadInfo['tmp_name'];
- $backup_file_type = $uploadInfo['type'];
-
- if (!file_exists($backup_file_tmpname))
- return 'File Upload Error';
-
- if (!preg_match("/^(text\/[a-zA-Z]+)|(application\/(x\-)?gzip(\-compressed)?)|(application\/octet-stream)$/is", $backup_file_type) )
- return 'The uploaded file is not of the correct type';
-
-
-
- if (preg_match("/\.gz/is",$backup_file_name))
- $gzip = 1;
- else
- $gzip = 0;
-
- if (!extension_loaded("zlib") && $gzip)
- return "Cannot decompress gzipped backup (zlib package not installed)";
-
- // get sql query according to gzip setting (either decompress, or not)
- if($gzip)
- {
- // decompress and read
- $gz_ptr = gzopen($backup_file_tmpname, 'rb');
- $sql_query = "";
- while( !gzeof($gz_ptr) )
- $sql_query .= gzgets($gz_ptr, 100000);
- } else {
- // just read
- $fsize = filesize($backup_file_tmpname);
- if ($fsize <= 0)
- $sql_query = '';
- else
- $sql_query = fread(fopen($backup_file_tmpname, 'r'), $fsize);
- }
-
- // time to execute the query
- _execute_queries($sql_query);
-}
-
-function _execute_queries($sql_query) {
- if (!$sql_query) return;
-
- // Strip out sql comments...
- $sql_query = remove_remarks($sql_query);
- $pieces = split_sql_file($sql_query);
-
- $sql_count = count($pieces);
- for($i = 0; $i < $sql_count; $i++)
- {
- $sql = trim($pieces[$i]);
-
- if(!empty($sql) and $sql[0] != "#")
- {
- // DEBUG
-// debug("Executing: " . htmlspecialchars($sql) . "\n");
-
- $result = mysql_query($sql);
- if (!$result) debug('SQL Error: ' . mysql_error());
-
- }
- }
-
-}
-
-//
-// remove_remarks will strip the sql comment lines out of an uploaded sql file
-//
-function remove_remarks($sql)
-{
- $lines = explode("\n", $sql);
-
- // try to keep mem. use down
- $sql = "";
-
- $linecount = count($lines);
- $output = "";
-
- for ($i = 0; $i < $linecount; $i++)
- {
- if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0))
- {
- if ($lines[$i][0] != "#")
- {
- $output .= $lines[$i] . "\n";
- }
- else
- {
- $output .= "\n";
- }
- // Trading a bit of speed for lower mem. use here.
- $lines[$i] = "";
- }
- }
-
- return $output;
-
-}
-
-
-//
-// split_sql_file will split an uploaded sql file into single sql statements.
-// Note: expects trim() to have already been run on $sql.
-//
-// taken from phpBB
-//
-function split_sql_file($sql)
-{
- // Split up our string into "possible" SQL statements.
- $tokens = explode( ";", $sql);
-
- // try to save mem.
- $sql = "";
- $output = array();
-
- // we don't actually care about the matches preg gives us.
- $matches = array();
-
- // this is faster than calling count($tokens) every time thru the loop.
- $token_count = count($tokens);
- for ($i = 0; $i < $token_count; $i++)
- {
- // Don't wanna add an empty string as the last thing in the array.
- if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0)))
- {
-
- // even number of quotes means a complete SQL statement
- if (_evenNumberOfQuotes($tokens[$i]))
- {
- $output[] = $tokens[$i];
- $tokens[$i] = ""; // save memory.
- }
- else
- {
- // incomplete sql statement. keep adding tokens until we have a complete one.
- // $temp will hold what we have so far.
- $temp = $tokens[$i] . ";";
- $tokens[$i] = ""; // save memory..
-
- // Do we have a complete statement yet?
- $complete_stmt = false;
-
- for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++)
- {
- // odd number of quotes means a completed statement
- // (in combination with the odd number we had already)
- if (!_evenNumberOfQuotes($tokens[$j]))
- {
- $output[] = $temp . $tokens[$j];
-
- // save memory.
- $tokens[$j] = "";
- $temp = "";
-
- // exit the loop.
- $complete_stmt = true;
- // make sure the outer loop continues at the right point.
- $i = $j;
- }
- else
- {
- // even number of unescaped quotes. We still don't have a complete statement.
- // (1 odd and 1 even always make an odd)
- $temp .= $tokens[$j] . ";";
- // save memory.
- $tokens[$j] = "";
- }
-
- } // for..
- } // else
- }
- }
-
- return $output;
-}
-
-
-function _evenNumberOfQuotes($text) {
- // This is the total number of single quotes in the token.
- $total_quotes = preg_match_all("/'/", $text, $matches);
- // Counts single quotes that are preceded by an odd number of backslashes,
- // which means they're escaped quotes.
- $escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $text, $matches);
-
- $unescaped_quotes = $total_quotes - $escaped_quotes;
-// debug($total_quotes . "-" . $escaped_quotes . "-" . $unescaped_quotes);
- return (($unescaped_quotes % 2) == 0);
-}
-
-?>
+<?php\r
+/*\r
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
+ * Copyright (C) 2002-2010 The Nucleus Group\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * (see nucleus/documentation/index.html#license for more info)\r
+ */\r
+/**\r
+ * Scripts to create/restore a backup of the Nucleus database\r
+ *\r
+ * Based on code in phpBB (http://phpBB.sourceforge.net)\r
+ *\r
+ * @license http://nucleuscms.org/license.txt GNU General Public License\r
+ * @copyright Copyright (C) 2002-2010 The Nucleus Group\r
+ * @version $Id$\r
+ * $NucleusJP: backup.php,v 1.8.2.1 2007/08/08 05:23:31 kimitake Exp $\r
+ */\r
+\r
+\r
+class Backup\r
+{ \r
+\r
+ /**\r
+ * Constructor\r
+ */\r
+ function Backup()\r
+ {\r
+ // do nothing\r
+ }\r
+ \r
+ \r
+ /**\r
+ * This function creates an sql dump of the database and sends it to\r
+ * the user as a file (can be gzipped if they want)\r
+ *\r
+ * @requires\r
+ * no output may have preceded (new headers are sent)\r
+ * @param gzip\r
+ * 1 = compress backup file, 0 = no compression (default)\r
+ */\r
+ function do_backup($gzip = 0) {\r
+ global $manager;\r
+ \r
+ // tables of which backup is needed\r
+ $tables = array(\r
+ sql_table('actionlog'),\r
+ sql_table('ban'),\r
+ sql_table('blog'),\r
+ sql_table('comment'),\r
+ sql_table('config'),\r
+ sql_table('item'),\r
+ sql_table('karma'),\r
+ sql_table('member'),\r
+ sql_table('skin'),\r
+ sql_table('skin_desc'),\r
+ sql_table('team'),\r
+ sql_table('template'),\r
+ sql_table('template_desc'),\r
+ sql_table('plugin'),\r
+ sql_table('plugin_event'),\r
+ sql_table('plugin_option'),\r
+ sql_table('plugin_option_desc'),\r
+ sql_table('category'),\r
+ sql_table('activation'),\r
+ sql_table('tickets'),\r
+ );\r
+ \r
+ // add tables that plugins want to backup to the list\r
+ // catch all output generated by plugins\r
+ ob_start();\r
+ $res = sql_query('SELECT pfile FROM '.sql_table('plugin'));\r
+ while ($plugName = sql_fetch_object($res)) {\r
+ $plug =& $manager->getPlugin($plugName->pfile);\r
+ if ($plug) $tables = array_merge($tables, (array) $plug->getTableList());\r
+ }\r
+ ob_end_clean();\r
+ \r
+ // remove duplicates\r
+ $tables = array_unique($tables);\r
+ \r
+ // make sure browsers don't cache the backup\r
+ header("Pragma: no-cache");\r
+ \r
+ // don't allow gzip compression when extension is not loaded\r
+ if (($gzip != 0) && !extension_loaded("zlib")) {\r
+ $gzip = 0;\r
+ }\r
+ \r
+ if ($gzip) {\r
+ // use an output buffer\r
+ @ob_start();\r
+ @ob_implicit_flush(0);\r
+ \r
+ // set filename\r
+ $filename = 'nucleus_db_backup_'.strftime("%Y-%m-%d-%H-%M-%S", time()).".sql.gz";\r
+ } else {\r
+ $filename = 'nucleus_db_backup_'.strftime("%Y-%m-%d-%H-%M-%S", time()).".sql";\r
+ }\r
+ \r
+ \r
+ // send headers that tell the browser a file is coming\r
+ header("Content-Type: text/x-delimtext; name=\"$filename\"");\r
+ header("Content-disposition: attachment; filename=$filename");\r
+ \r
+ // dump header\r
+ echo "#\n";\r
+ echo "# " . _BACKUP_BACKUPFILE_TITLE . " \n";\r
+ echo "# " . _ADMINPAGEFOOT_OFFICIALURL . "\n";\r
+ echo "#\n";\r
+ echo "# " . _BACKUP_BACKUPFILE_BACKUPDATE . gmdate("d-m-Y H:i:s", time()) . " GMT\n";\r
+ global $nucleus;\r
+ echo "# " . _BACKUP_BACKUPFILE_NUCLEUSVERSION . $nucleus['version'] . "\n";\r
+ echo "#\n";\r
+ echo "# " . _BACKUP_WARNING_NUCLEUSVERSION . "\n";\r
+ echo "#\n";\r
+ \r
+ // dump all tables\r
+ reset($tables);\r
+ array_walk($tables, array(&$this, '_backup_dump_table'));\r
+ \r
+ if($gzip) {\r
+ $Size = ob_get_length();\r
+ $Crc = crc32(ob_get_contents());\r
+ $contents = gzcompress(ob_get_contents());\r
+ ob_end_clean();\r
+ echo "\x1f\x8b\x08\x00\x00\x00\x00\x00".substr($contents, 0, strlen($contents) - 4).$this->gzip_PrintFourChars($Crc).$this->gzip_PrintFourChars($Size);\r
+ }\r
+ \r
+ exit;\r
+ \r
+ }\r
+ \r
+ \r
+ /**\r
+ * Creates a dump for a single table\r
+ * ($tablename and $key are filled in by array_walk)\r
+ */\r
+ function _backup_dump_table($tablename, $key) {\r
+ \r
+ echo "#\n";\r
+ echo "# " . _BACKUP_BACKUPFILE_TABLE_NAME . $tablename . "\n";\r
+ echo "#\n";\r
+ \r
+ // dump table structure\r
+ $this->_backup_dump_structure($tablename);\r
+ \r
+ // dump table contents\r
+ $this->_backup_dump_contents($tablename);\r
+ }\r
+\r
+ /**\r
+ * Creates a dump of the table structure for one table\r
+ */\r
+ function _backup_dump_structure($tablename) {\r
+ \r
+ // add command to drop table on restore\r
+ echo "DROP TABLE IF EXISTS $tablename;\n";\r
+ $result = sql_query("SHOW CREATE TABLE $tablename");\r
+ $create = sql_fetch_assoc($result);\r
+ echo $create['Create Table'];\r
+ echo ";\n\n";\r
+ }\r
+\r
+ /**\r
+ * Creates a dump of the table structure for one table\r
+ */\r
+/* replaced by code above in 3.5\r
+ function _backup_dump_structure($tablename) {\r
+ \r
+ // add command to drop table on restore\r
+ echo "DROP TABLE IF EXISTS $tablename;\n";\r
+ echo "CREATE TABLE $tablename(\n";\r
+ \r
+ //\r
+ // Ok lets grab the fields...\r
+ //\r
+ $result = mysql_query("SHOW FIELDS FROM $tablename");\r
+ $row = mysql_fetch_array($result);\r
+ while ($row) {\r
+ \r
+ echo ' `' . $row['Field'] . '` ' . $row['Type'];\r
+ \r
+ if(isset($row['Default']))\r
+ echo ' DEFAULT \'' . $row['Default'] . '\'';\r
+ \r
+ if($row['Null'] != "YES")\r
+ echo ' NOT NULL';\r
+ \r
+ if($row['Extra'] != "")\r
+ echo ' ' . $row['Extra'];\r
+ \r
+ $row = mysql_fetch_array($result);\r
+ \r
+ // add comma's except for last one\r
+ if ($row)\r
+ echo ",\n";\r
+ }\r
+ \r
+ //\r
+ // Get any Indexed fields from the database...\r
+ //\r
+ $result = mysql_query("SHOW KEYS FROM $tablename");\r
+ while($row = mysql_fetch_array($result)) {\r
+ $kname = $row['Key_name'];\r
+ \r
+ if(($kname != 'PRIMARY') && ($row['Non_unique'] == 0))\r
+ $kname = "UNIQUE|$kname";\r
+ if(($kname != 'PRIMARY') && ($row['Index_type'] == 'FULLTEXT'))\r
+ $kname = "FULLTEXT|$kname";\r
+ \r
+ if(!is_array($index[$kname]))\r
+ $index[$kname] = array();\r
+ \r
+ $index[$kname][] = $row['Column_name'] . ( ($row['Sub_part']) ? ' (' . $row['Sub_part'] . ')' : '');\r
+ }\r
+\r
+ while(list($x, $columns) = @each($index)) {\r
+ echo ", \n";\r
+ \r
+ if($x == 'PRIMARY')\r
+ echo ' PRIMARY KEY (`' . implode($columns, '`, `') . '`)';\r
+ elseif (substr($x,0,6) == 'UNIQUE')\r
+ echo ' UNIQUE KEY ' . substr($x,7) . ' (`' . implode($columns, '`, `') . '`)';\r
+ elseif (substr($x,0,8) == 'FULLTEXT')\r
+ echo ' FULLTEXT KEY ' . substr($x,9) . ' (`' . implode($columns, '`, `') . '`)';\r
+ elseif (($x == 'ibody') || ($x == 'cbody')) // karma 2004-05-30 quick and dirty fix. fulltext keys were not in SQL correctly.\r
+ echo ' FULLTEXT KEY ' . substr($x,9) . ' (`' . implode($columns, '`, `') . '`)';\r
+ else\r
+ echo " KEY $x (`" . implode($columns, '`, `') . '`)';\r
+ }\r
+ \r
+ echo "\n);\n\n";\r
+ }\r
+*/\r
+\r
+ /**\r
+ * Returns the field named for the given table in the \r
+ * following format:\r
+ *\r
+ * (column1, column2, ..., columnn)\r
+ */\r
+ function _backup_get_field_names($result, $num_fields) {\r
+ \r
+ /* if (function_exists('mysqli_fetch_fields') ) {\r
+ \r
+ $fields = mysqli_fetch_fields($result);\r
+ for ($j = 0; $j < $num_fields; $j++)\r
+ $fields[$j] = $fields[$j]->name;\r
+ \r
+ } else {*/\r
+ \r
+ $fields = array();\r
+ for ($j = 0; $j < $num_fields; $j++) {\r
+ $fields[] = sql_field_name($result, $j);\r
+ }\r
+ \r
+ /* }*/\r
+ \r
+ return '(`' . implode('`, `', $fields) . '`)'; \r
+ }\r
+\r
+ /**\r
+ * Creates a dump of the table content for one table \r
+ */\r
+ function _backup_dump_contents($tablename) {\r
+ //\r
+ // Grab the data from the table.\r
+ //\r
+ $result = sql_query("SELECT * FROM $tablename");\r
+ \r
+ if(sql_num_rows($result) > 0)\r
+ echo "\n#\n# " . sprintf(_BACKUP_BACKUPFILE_TABLEDATAFOR, $tablename) . "\n#\n";\r
+ \r
+ $num_fields = sql_num_fields($result);\r
+ \r
+ //\r
+ // Compose fieldname list\r
+ //\r
+ $tablename_list = $this->_backup_get_field_names($result, $num_fields);\r
+ \r
+ //\r
+ // Loop through the resulting rows and build the sql statement.\r
+ //\r
+ while ($row = sql_fetch_array($result))\r
+ {\r
+ // Start building the SQL statement.\r
+ \r
+ echo "INSERT INTO `".$tablename."` $tablename_list VALUES(";\r
+ \r
+ // Loop through the rows and fill in data for each column\r
+ for ($j = 0; $j < $num_fields; $j++) {\r
+ if(!isset($row[$j])) {\r
+ // no data for column\r
+ echo ' NULL';\r
+ } elseif ($row[$j] != '') {\r
+ // data\r
+ echo " '" . sql_real_escape_string($row[$j]) . "'";\r
+ } else {\r
+ // empty column (!= no data!)\r
+ echo "''";\r
+ }\r
+ \r
+ // only add comma when not last column\r
+ if ($j != ($num_fields - 1))\r
+ echo ",";\r
+ }\r
+ \r
+ echo ");\n";\r
+ \r
+ }\r
+ \r
+ \r
+ echo "\n";\r
+ \r
+ }\r
+\r
+ /**\r
+ * copied from phpBB\r
+ */ \r
+ function gzip_PrintFourChars($Val)\r
+ {\r
+ for ($i = 0; $i < 4; $i ++)\r
+ {\r
+ $return .= chr($Val % 256);\r
+ $Val = floor($Val / 256);\r
+ }\r
+ return $return;\r
+ }\r
+\r
+ /**\r
+ * Restores a database backup\r
+ */ \r
+ function do_restore() {\r
+ \r
+ $uploadInfo = postFileInfo('backup_file');\r
+ \r
+ // first of all: get uploaded file:\r
+ if (empty($uploadInfo['name']))\r
+ return _BACKUP_RESTOR_NOFILEUPLOADED;\r
+ if (!is_uploaded_file($uploadInfo['tmp_name']))\r
+ return _BACKUP_RESTOR_NOFILEUPLOADED;\r
+ \r
+ $backup_file_name = $uploadInfo['name'];\r
+ $backup_file_tmpname = $uploadInfo['tmp_name'];\r
+ $backup_file_type = $uploadInfo['type'];\r
+ \r
+ if (!file_exists($backup_file_tmpname))\r
+ return _BACKUP_RESTOR_UPLOAD_ERROR;\r
+ \r
+ if (!preg_match("/^(text\/[a-zA-Z]+)|(application\/(x\-)?gzip(\-compressed)?)|(application\/octet-stream)$/is", $backup_file_type) )\r
+ return _BACKUP_RESTOR_UPLOAD_NOCORRECTTYPE;\r
+ \r
+ \r
+ if (preg_match("/\.gz/is",$backup_file_name))\r
+ $gzip = 1;\r
+ else\r
+ $gzip = 0;\r
+ \r
+ if (!extension_loaded("zlib") && $gzip)\r
+ return _BACKUP_RESTOR_UPLOAD_NOZLIB;\r
+ \r
+ // get sql query according to gzip setting (either decompress, or not)\r
+ if($gzip)\r
+ {\r
+ // decompress and read\r
+ $gz_ptr = gzopen($backup_file_tmpname, 'rb');\r
+ $sql_query = "";\r
+ while( !gzeof($gz_ptr) )\r
+ $sql_query .= gzgets($gz_ptr, 100000);\r
+ } else {\r
+ // just read\r
+ $fsize = filesize($backup_file_tmpname);\r
+ if ($fsize <= 0)\r
+ $sql_query = '';\r
+ else\r
+ $sql_query = fread(fopen($backup_file_tmpname, 'r'), $fsize);\r
+ }\r
+ \r
+ // time to execute the query\r
+ $this->_execute_queries($sql_query);\r
+ }\r
+\r
+ /**\r
+ * Executes a SQL query\r
+ */ \r
+ function _execute_queries($sql_query) {\r
+ if (!$sql_query) return;\r
+ \r
+ // Strip out sql comments...\r
+ $sql_query = $this->remove_remarks($sql_query);\r
+ $pieces = $this->split_sql_file($sql_query);\r
+ \r
+ $sql_count = count($pieces);\r
+ for($i = 0; $i < $sql_count; $i++)\r
+ {\r
+ $sql = trim($pieces[$i]);\r
+ \r
+ if(!empty($sql) and $sql[0] != "#")\r
+ {\r
+ // DEBUG\r
+ // debug("Executing: " . htmlspecialchars($sql) . "\n");\r
+ \r
+ $result = sql_query($sql);\r
+ if (!$result) debug(_BACKUP_RESTOR_SQL_ERROR . sql_error());\r
+ \r
+ }\r
+ }\r
+ \r
+ }\r
+\r
+ /**\r
+ * remove_remarks will strip the sql comment lines\r
+ * out of an uploaded sql file\r
+ */ \r
+ function remove_remarks($sql)\r
+ {\r
+ $lines = explode("\n", $sql);\r
+ \r
+ // try to keep mem. use down\r
+ $sql = "";\r
+ \r
+ $linecount = count($lines);\r
+ $output = "";\r
+ \r
+ for ($i = 0; $i < $linecount; $i++)\r
+ {\r
+ if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0))\r
+ {\r
+ if ($lines[$i][0] != "#")\r
+ {\r
+ $output .= $lines[$i] . "\n";\r
+ }\r
+ else\r
+ {\r
+ $output .= "\n";\r
+ }\r
+ // Trading a bit of speed for lower mem. use here.\r
+ $lines[$i] = "";\r
+ }\r
+ }\r
+ \r
+ return $output;\r
+ \r
+ }\r
+\r
+ /**\r
+ * split_sql_file will split an uploaded sql file\r
+ * into single sql statements.\r
+ * \r
+ * Note: expects trim() to have already been run on $sql. \r
+ * taken from phpBB\r
+ */ \r
+ function split_sql_file($sql)\r
+ {\r
+ // Split up our string into "possible" SQL statements.\r
+ $tokens = explode( ";", $sql);\r
+ \r
+ // try to save mem.\r
+ $sql = "";\r
+ $output = array();\r
+ \r
+ // we don't actually care about the matches preg gives us.\r
+ $matches = array();\r
+ \r
+ // this is faster than calling count($tokens) every time thru the loop.\r
+ $token_count = count($tokens);\r
+ for ($i = 0; $i < $token_count; $i++)\r
+ {\r
+ // Don't wanna add an empty string as the last thing in the array.\r
+ if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0)))\r
+ {\r
+ \r
+ // even number of quotes means a complete SQL statement\r
+ if ($this->_evenNumberOfQuotes($tokens[$i]))\r
+ {\r
+ $output[] = $tokens[$i];\r
+ $tokens[$i] = ""; // save memory.\r
+ }\r
+ else\r
+ {\r
+ // incomplete sql statement. keep adding tokens until we have a complete one.\r
+ // $temp will hold what we have so far.\r
+ $temp = $tokens[$i] . ";";\r
+ $tokens[$i] = ""; // save memory..\r
+ \r
+ // Do we have a complete statement yet?\r
+ $complete_stmt = false;\r
+ \r
+ for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++)\r
+ {\r
+ // odd number of quotes means a completed statement\r
+ // (in combination with the odd number we had already)\r
+ if (!$this->_evenNumberOfQuotes($tokens[$j]))\r
+ {\r
+ $output[] = $temp . $tokens[$j];\r
+ \r
+ // save memory.\r
+ $tokens[$j] = "";\r
+ $temp = "";\r
+ \r
+ // exit the loop.\r
+ $complete_stmt = true;\r
+ // make sure the outer loop continues at the right point.\r
+ $i = $j;\r
+ }\r
+ else\r
+ {\r
+ // even number of unescaped quotes. We still don't have a complete statement.\r
+ // (1 odd and 1 even always make an odd)\r
+ $temp .= $tokens[$j] . ";";\r
+ // save memory.\r
+ $tokens[$j] = "";\r
+ }\r
+ \r
+ } // for..\r
+ } // else\r
+ }\r
+ }\r
+ \r
+ return $output;\r
+ }\r
+\r
+ /**\r
+ * sub function of split_sql_file\r
+ * \r
+ * taken from phpBB\r
+ */ \r
+ function _evenNumberOfQuotes($text) {\r
+ // This is the total number of single quotes in the token.\r
+ $total_quotes = preg_match_all("/'/", $text, $matches);\r
+ // Counts single quotes that are preceded by an odd number of backslashes,\r
+ // which means they're escaped quotes.\r
+ $escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $text, $matches);\r
+ \r
+ $unescaped_quotes = $total_quotes - $escaped_quotes;\r
+ // debug($total_quotes . "-" . $escaped_quotes . "-" . $unescaped_quotes);\r
+ return (($unescaped_quotes % 2) == 0);\r
+ }\r
+\r
+}\r
+\r
+?>
\ No newline at end of file