/**\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-2009 The Nucleus Group\r
* @version $Id: backup.php 1624 2012-01-09 11:36:20Z sakamocchi $\r
*/\r
\r
-\r
class Backup\r
{\r
/**\r
* Backup::Backup()\r
- * Constructor\r
- * \r
+ * Constructor, just for compatibility\r
+ *\r
+ * @deprecated\r
* @param void\r
* @return void\r
- * \r
+ *\r
*/\r
public function Backup()\r
{\r
return;\r
}\r
- \r
+\r
/**\r
* Backup::do_backup()\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
+ * NOTE: this remains not-static for compatibility\r
+ *\r
* @param boolean $gzip 1 = compress backup file, 0 = no compression (default)\r
* @return void\r
- * \r
+ *\r
*/\r
public function do_backup($gzip = 0)\r
{\r
global $manager, $nucleus;\r
- \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
+ 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
}\r
}\r
ob_end_clean();\r
- \r
+\r
// remove duplicates\r
$tables = array_unique($tables);\r
- \r
+\r
// make sure browsers don't cache the backup\r
header("Pragma: no-cache");\r
- \r
+\r
// don't allow gzip compression when extension is not loaded\r
if ( ($gzip != 0) && !extension_loaded("zlib") )\r
{\r
$gzip = 0;\r
}\r
- \r
+\r
if ( !$gzip )\r
{\r
$filename = 'nucleus_db_backup_' . i18n::formatted_datetime('%Y-%m-%d-%H-%M-%S', time()) . ".sql";\r
// use an output buffer\r
@ob_start();\r
@ob_implicit_flush(0);\r
- \r
+\r
// set filename\r
$filename = 'nucleus_db_backup_' . i18n::formatted_datetime('%Y-%m-%d-%H-%M-%S', time()) . ".sql.gz";\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
+\r
// dump header\r
- echo "#\n";\r
- echo "# This is a backup file generated by Nucleus \n";\r
- echo "# http://www.nucleuscms.org/\n";\r
- echo "#\n";\r
- echo "# backup-date: " . i18n::formatted_datetime('rfc822GMT', time()) . "\n";\r
- echo "# Nucleus CMS version: " . $nucleus['version'] . "\n";\r
- echo "#\n";\r
- echo "# WARNING: Only try to restore on servers running the exact same version of Nucleus\n";\r
- echo "#\n";\r
- \r
+ echo "/*\n";\r
+ echo " * This is a backup file generated by Nucleus \n";\r
+ echo " * http://www.nucleuscms.org/\n";\r
+ echo " * \n";\r
+ echo " * backup-date: " . i18n::formatted_datetime('rfc822GMT', time()) . "\n";\r
+ echo " * Nucleus CMS version: " . $nucleus['version'] . "\n";\r
+ echo " * \n";\r
+ echo " * WARNING: Only try to restore on servers running the exact same version of Nucleus\n";\r
+ echo " */\n";\r
+\r
// dump all tables\r
reset($tables);\r
- array_walk($tables, array(&$this, '_backup_dump_table'));\r
- \r
+ array_walk($tables, array(self, 'dump_table'));\r
+\r
if ( $gzip )\r
{\r
$Size = ob_get_length();\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)\r
- . $this->gzip_PrintFourChars($Crc) . $this->gzip_PrintFourChars($Size);\r
+ . self::gzip_print_four_characters($Crc) . self::gzip_print_four_characters($Size);\r
}\r
exit;\r
}\r
- \r
+\r
/**\r
- * Backup::_backup_dump_table()\r
+ * Backup::dump_table()\r
* Creates a dump for a single table\r
* ($tablename and $key are filled in by array_walk)\r
- * \r
+ *\r
+ * @static\r
* @param string $tablename\r
* @param string $key\r
*/\r
- private function _backup_dump_table($tablename, $key)\r
+ static private function dump_table($tablename, $key)\r
{\r
- echo "#\n";\r
- echo "# TABLE: " . $tablename . "\n";\r
- echo "#\n";\r
- \r
+ echo "/*\n";\r
+ echo " * TABLE: " . $tablename . "\n";\r
+ echo " */\n";\r
+\r
// dump table structure\r
- $this->_backup_dump_structure($tablename);\r
- \r
+ self::dump_structure($tablename);\r
+\r
// dump table contents\r
- $this->_backup_dump_contents($tablename);\r
+ self::dump_contents($tablename);\r
return;\r
}\r
- \r
+\r
/**\r
- * Backup::_backup_dump_structure()\r
+ * Backup::dump_structure()\r
* Creates a dump of the table structure for one table\r
- * \r
+ *\r
+ * @static\r
* @param string $tablename\r
* @return void\r
- * \r
+ *\r
*/\r
- private function _backup_dump_structure($tablename)\r
+ static private function dump_structure($tablename)\r
{\r
// add command to drop table on restore\r
- echo "DROP TABLE IF EXISTS '$tablename';\n\n";\r
+ echo "DROP TABLE IF EXISTS `$tablename`;\n\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
return;\r
}\r
- \r
+\r
/**\r
- * Backup::_backup_get_field_names()\r
- * Returns the field named for the given table in the \r
+ * Backup::get_field_names()\r
+ * Returns the field named for the given table in the\r
* following format:\r
* (column1, column2, ..., columnn)\r
- * \r
- * @param resource $result \r
- * @param integer $num_fields \r
+ *\r
+ * @static\r
+ * @param resource $result\r
+ * @param integer $num_fields\r
* @return string\r
*/\r
- private function _backup_get_field_names($result, $num_fields)\r
+ static private function get_field_names($result, $num_fields)\r
{\r
$fields = array();\r
for ( $j = 0; $j < $num_fields; $j++ )\r
{\r
$fields[] = sql_field_name($result, $j);\r
}\r
- \r
- return '(' . implode(', ', $fields) . ')'; \r
+\r
+ return '(' . implode(', ', $fields) . ')';\r
}\r
- \r
+\r
/**\r
- * Backup::_backup_dump_contents()\r
- * Creates a dump of the table content for one table \r
- * \r
+ * Backup::dump_contents()\r
+ * Creates a dump of the table content for one table\r
+ *\r
+ * @static\r
* @param string $tablename\r
* @return void\r
- * \r
+ *\r
*/\r
- private function _backup_dump_contents($tablename)\r
+ static private function dump_contents($tablename)\r
{\r
/*\r
* Grab the data from the table.\r
- */\r
+ */\r
$result = sql_query("SELECT * FROM $tablename");\r
- \r
+\r
if ( sql_num_rows($result) > 0 )\r
{\r
- echo "\n#\n# Table Data for $tablename\n#\n";\r
+ echo "\n";\r
+ echo "/*\n";\r
+ echo " * Table Data for {$tablename}\n";\r
+ echo " */\n";\r
}\r
- \r
+\r
$num_fields = sql_num_fields($result);\r
- \r
+\r
/*\r
* Compose fieldname list\r
- */\r
- $tablename_list = $this->_backup_get_field_names($result, $num_fields);\r
- \r
+ */\r
+ $tablename_list = self::get_field_names($result, $num_fields);\r
+\r
/*\r
* Loop through the resulting rows and build the sql statement.\r
- */\r
+ */\r
while ( $row = sql_fetch_array($result) )\r
{\r
// Start building the SQL statement.\r
echo "INSERT INTO ".$tablename." $tablename_list VALUES(";\r
- \r
+\r
// Loop through the rows and fill in data for each column\r
for ( $j = 0; $j < $num_fields; $j++ )\r
{\r
// empty column (!= no data!)\r
echo "''";\r
}\r
- \r
+\r
// only add comma when not last column\r
if ( $j != ($num_fields - 1) )\r
{\r
echo "\n";\r
return;\r
}\r
- \r
+\r
/**\r
- * Backup::gzip_PrintFourChars()\r
- * copied from phpBB\r
- * \r
- * @param integer $val\r
+ * Backup::gzip_print_four_characters()\r
+ *\r
+ * @static\r
+ * @param integer $val\r
* @return integer\r
*/\r
- public function gzip_PrintFourChars($Val)\r
+ static private function gzip_print_four_characters($Val)\r
{\r
for ( $i = 0; $i < 4; $i ++ )\r
{\r
}\r
return $return;\r
}\r
- \r
+\r
/**\r
* Backup::do_restore()\r
* Restores a database backup\r
- * \r
- * @param void\r
+ *\r
+ * NOTE: this remains not-static for compatibility\r
+ *\r
+ * @param void\r
* @return void\r
*/\r
public function do_restore()\r
{\r
$uploadInfo = postFileInfo('backup_file');\r
- \r
+\r
// first of all: get uploaded file:\r
if ( array_key_exists('name', $uploadInfo) && empty($uploadInfo['name']) )\r
{\r
{\r
return 'No file uploaded';\r
}\r
- \r
+\r
$backup_file_name = $uploadInfo['name'];\r
$backup_file_tmpname = $uploadInfo['tmp_name'];\r
$backup_file_type = $uploadInfo['type'];\r
- \r
+\r
if ( !file_exists($backup_file_tmpname) )\r
{\r
return 'File Upload Error';\r
}\r
- \r
+\r
if ( !preg_match("#^(text/[a-zA-Z]+)|(application/(x\-)?gzip(\-compressed)?)|(application/octet-stream)$#i", $backup_file_type) )\r
{\r
return 'The uploaded file is not of the correct type';\r
}\r
- \r
- if ( preg_match("#\.gz#i",$backup_file_name) )\r
+\r
+ $gzip = 0;\r
+ if ( preg_match("#\.gz#i", $backup_file_name) )\r
{\r
$gzip = 1;\r
}\r
- else\r
- {\r
- $gzip = 0;\r
- }\r
- \r
+\r
if ( !extension_loaded("zlib") && $gzip )\r
{\r
- return "Cannot decompress gzipped backup (zlib package not installed)";\r
+ return 'Cannot decompress gzipped backup (zlib package not installed)';\r
}\r
- \r
+\r
// get sql query according to gzip setting (either decompress, or not)\r
+ $contents = self::get_contents($backup_file_tmpname, $gzip);\r
+ if ( $contents == '' )\r
+ {\r
+ return 'Cannot get contents from this file.';\r
+ }\r
+\r
+ /* detect lines */\r
+ $lines = preg_split('/[\r\n]/', $contents);\r
+ if( $lines === $contents )\r
+ {\r
+ return 'Cannot parse contents from this file';\r
+ }\r
+\r
+ /* get sql statements from each lines */\r
+ $queries = self::get_queries($lines);\r
+ if ( $queries === array() )\r
+ {\r
+ return "Cannot get SQL queries from this file.";\r
+ }\r
+\r
+ /* execute sql statements */\r
+ foreach ( $queries as $query )\r
+ {\r
+ if ( !sql_query($query) )\r
+ {\r
+ debug('SQL Error: ' . sql_error());\r
+ break;\r
+ }\r
+ continue;\r
+ }\r
+ return;\r
+ }\r
+\r
+ static private function get_contents($temporary_name, $gzip = 0)\r
+ {\r
+ $contents = '';\r
if ( $gzip )\r
{\r
// decompress and read\r
- $gz_ptr = gzopen($backup_file_tmpname, 'rb');\r
- $sql_query = '';\r
+ $gz_ptr = gzopen($temporary_name, 'rb');\r
while ( !gzeof($gz_ptr) )\r
{\r
- $sql_query .= gzgets($gz_ptr, 100000);\r
+ $contents .= gzgets($gz_ptr, 100000);\r
}\r
}\r
else\r
{\r
// just read\r
- $fsize = filesize($backup_file_tmpname);\r
- if ( $fsize <= 0 )\r
+ $fsize = filesize($temporary_name);\r
+ if ( $fsize > 0 )\r
{\r
- $sql_query = '';\r
- }\r
- else\r
- {\r
- $sql_query = fread(fopen($backup_file_tmpname, 'r'), $fsize);\r
+ $contents = fread(fopen($temporary_name, 'r'), $fsize);\r
}\r
}\r
- \r
- $lines = preg_split('/[\r\n]/', $sql_query);\r
+ return $contents;\r
+ }\r
+\r
+ static private function get_queries($lines)\r
+ {\r
$query = '';\r
+ $queries = array();\r
foreach ( $lines as $line )\r
{\r
$line = trim($line);\r
- if ( !$line || $line[0] == '#' )\r
+ if ( !$line || $line[0] == '#' || preg_match('#^[\s|/]?\*#', $line) )\r
{\r
continue;\r
}\r
- \r
+\r
if ( preg_match('/^(.*);$/', $line, $matches) === 0 )\r
{\r
$query .= $line;\r
else\r
{\r
$query .= $matches[1];\r
- $result = sql_query($query);\r
- \r
- if ( !$result )\r
- {\r
- debug('SQL Error: ' . sql_error());\r
- }\r
+ $queries[] = $query;\r
$query = '';\r
}\r
+ continue;\r
}\r
- return;\r
+ return $queries;\r
}\r
-}\r
+}
\ No newline at end of file