From 8926631f6dc16ee053cde515ac8ab1ae2e63420c Mon Sep 17 00:00:00 2001 From: sakamocchi Date: Sat, 31 Mar 2012 16:24:57 +0900 Subject: [PATCH] =?utf8?q?MERGE:=20=E3=83=AA=E3=83=93=E3=82=B8=E3=83=A7?= =?utf8?q?=E3=83=B31716=E3=81=AE=E3=83=9E=E3=83=BC=E3=82=B8=E3=80=82?= =?utf8?q?=E3=83=90=E3=83=83=E3=82=AF=E3=82=A2=E3=83=83=E3=83=97=E3=82=AF?= =?utf8?q?=E3=83=A9=E3=82=B9=E3=81=AE=E5=86=8D=E5=AE=9A=E7=BE=A9=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit CHANGE: reworking Backup class http://nucleuscms.svn.sourceforge.net/viewvc/nucleuscms?view=revision&revision=1716 The comment of my previous commit (revision 1715) is wrong. The commit and this is for Backup class... Now we review whole Backup class and no refering to phpBB's implements. --- nucleus/libs/ADMIN.php | 12 +- nucleus/libs/backup.php | 313 +++++++++++++++++++++++++++--------------------- 2 files changed, 180 insertions(+), 145 deletions(-) diff --git a/nucleus/libs/ADMIN.php b/nucleus/libs/ADMIN.php index 424e392..0dfa98c 100644 --- a/nucleus/libs/ADMIN.php +++ b/nucleus/libs/ADMIN.php @@ -6041,7 +6041,7 @@ selector(); } /** - * Backup::action_backupcreate() + * ADMIN::action_backupcreate() * create file for backup * * @param void @@ -6055,7 +6055,7 @@ selector(); $member->isAdmin() or $this->disallow(); // use compression ? - $useGzip = intval(postVar('gzip')); + $useGzip = (integer) postVar('gzip'); include($DIR_LIBS . 'backup.php'); @@ -6063,13 +6063,12 @@ selector(); // (creating/restoring dumps might take a while) @set_time_limit(1200); - $bu = new Backup(); - $bu->do_backup($useGzip); + Backup::do_backup($useGzip); exit; } /** - * Backup::action_backuprestore() + * ADMIN::action_backuprestore() * restoring from uploaded file * * @param void @@ -6092,8 +6091,7 @@ selector(); // (creating/restoring dumps might take a while) @set_time_limit(1200); - $bu = new Backup(); - $message = $bu->do_restore(); + $message = Backup::do_restore(); if ( $message != '' ) { $this->error($message); diff --git a/nucleus/libs/backup.php b/nucleus/libs/backup.php index b2c5a70..772222c 100644 --- a/nucleus/libs/backup.php +++ b/nucleus/libs/backup.php @@ -12,66 +12,66 @@ /** * 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-2009 The Nucleus Group * @version $Id: backup.php 1624 2012-01-09 11:36:20Z sakamocchi $ */ - class Backup { /** * Backup::Backup() - * Constructor - * + * Constructor, just for compatibility + * + * @deprecated * @param void * @return void - * + * */ public function Backup() { return; } - + /** * Backup::do_backup() * This function creates an sql dump of the database and sends it to * the user as a file (can be gzipped if they want) * + * NOTE: this remains not-static for compatibility + * * @param boolean $gzip 1 = compress backup file, 0 = no compression (default) * @return void - * + * */ public function do_backup($gzip = 0) { global $manager, $nucleus; - + // 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'), - ); - + 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(); @@ -85,19 +85,19 @@ class Backup } } 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 ) { $filename = 'nucleus_db_backup_' . i18n::formatted_datetime('%Y-%m-%d-%H-%M-%S', time()) . ".sql"; @@ -107,30 +107,30 @@ class Backup // use an output buffer @ob_start(); @ob_implicit_flush(0); - + // set filename $filename = 'nucleus_db_backup_' . i18n::formatted_datetime('%Y-%m-%d-%H-%M-%S', time()) . ".sql.gz"; } - + // 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: " . i18n::formatted_datetime('rfc822GMT', time()) . "\n"; - 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"; - + echo "/*\n"; + echo " * This is a backup file generated by Nucleus \n"; + echo " * http://www.nucleuscms.org/\n"; + echo " * \n"; + echo " * backup-date: " . i18n::formatted_datetime('rfc822GMT', time()) . "\n"; + 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, array(&$this, '_backup_dump_table')); - + array_walk($tables, array(self, 'dump_table')); + if ( $gzip ) { $Size = ob_get_length(); @@ -138,108 +138,115 @@ class Backup $contents = gzcompress(ob_get_contents()); ob_end_clean(); echo "\x1f\x8b\x08\x00\x00\x00\x00\x00" . substr($contents, 0, strlen($contents) - 4) - . $this->gzip_PrintFourChars($Crc) . $this->gzip_PrintFourChars($Size); + . self::gzip_print_four_characters($Crc) . self::gzip_print_four_characters($Size); } exit; } - + /** - * Backup::_backup_dump_table() + * Backup::dump_table() * Creates a dump for a single table * ($tablename and $key are filled in by array_walk) - * + * + * @static * @param string $tablename * @param string $key */ - private function _backup_dump_table($tablename, $key) + static private function dump_table($tablename, $key) { - echo "#\n"; - echo "# TABLE: " . $tablename . "\n"; - echo "#\n"; - + echo "/*\n"; + echo " * TABLE: " . $tablename . "\n"; + echo " */\n"; + // dump table structure - $this->_backup_dump_structure($tablename); - + self::dump_structure($tablename); + // dump table contents - $this->_backup_dump_contents($tablename); + self::dump_contents($tablename); return; } - + /** - * Backup::_backup_dump_structure() + * Backup::dump_structure() * Creates a dump of the table structure for one table - * + * + * @static * @param string $tablename * @return void - * + * */ - private function _backup_dump_structure($tablename) + static private function dump_structure($tablename) { // add command to drop table on restore - echo "DROP TABLE IF EXISTS '$tablename';\n\n"; + echo "DROP TABLE IF EXISTS `$tablename`;\n\n"; $result = sql_query("SHOW CREATE TABLE $tablename"); $create = sql_fetch_assoc($result); echo $create['Create Table']; echo ";\n\n"; return; } - + /** - * Backup::_backup_get_field_names() - * Returns the field named for the given table in the + * Backup::get_field_names() + * Returns the field named for the given table in the * following format: * (column1, column2, ..., columnn) - * - * @param resource $result - * @param integer $num_fields + * + * @static + * @param resource $result + * @param integer $num_fields * @return string */ - private function _backup_get_field_names($result, $num_fields) + static private function get_field_names($result, $num_fields) { $fields = array(); for ( $j = 0; $j < $num_fields; $j++ ) { $fields[] = sql_field_name($result, $j); } - - return '(' . implode(', ', $fields) . ')'; + + return '(' . implode(', ', $fields) . ')'; } - + /** - * Backup::_backup_dump_contents() - * Creates a dump of the table content for one table - * + * Backup::dump_contents() + * Creates a dump of the table content for one table + * + * @static * @param string $tablename * @return void - * + * */ - private function _backup_dump_contents($tablename) + static private function dump_contents($tablename) { /* * Grab the data from the table. - */ + */ $result = sql_query("SELECT * FROM $tablename"); - + if ( sql_num_rows($result) > 0 ) { - echo "\n#\n# Table Data for $tablename\n#\n"; + echo "\n"; + echo "/*\n"; + echo " * Table Data for {$tablename}\n"; + echo " */\n"; } - + $num_fields = sql_num_fields($result); - + /* * Compose fieldname list - */ - $tablename_list = $this->_backup_get_field_names($result, $num_fields); - + */ + $tablename_list = self::get_field_names($result, $num_fields); + /* * Loop through the resulting rows and build the sql statement. - */ + */ while ( $row = sql_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++ ) { @@ -258,7 +265,7 @@ class Backup // empty column (!= no data!) echo "''"; } - + // only add comma when not last column if ( $j != ($num_fields - 1) ) { @@ -270,15 +277,15 @@ class Backup echo "\n"; return; } - + /** - * Backup::gzip_PrintFourChars() - * copied from phpBB - * - * @param integer $val + * Backup::gzip_print_four_characters() + * + * @static + * @param integer $val * @return integer */ - public function gzip_PrintFourChars($Val) + static private function gzip_print_four_characters($Val) { for ( $i = 0; $i < 4; $i ++ ) { @@ -287,18 +294,20 @@ class Backup } return $return; } - + /** * Backup::do_restore() * Restores a database backup - * - * @param void + * + * NOTE: this remains not-static for compatibility + * + * @param void * @return void */ public function do_restore() { $uploadInfo = postFileInfo('backup_file'); - + // first of all: get uploaded file: if ( array_key_exists('name', $uploadInfo) && empty($uploadInfo['name']) ) { @@ -308,70 +317,102 @@ class Backup { 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)$#i", $backup_file_type) ) { return 'The uploaded file is not of the correct type'; } - - if ( preg_match("#\.gz#i",$backup_file_name) ) + + $gzip = 0; + if ( preg_match("#\.gz#i", $backup_file_name) ) { $gzip = 1; } - else - { - $gzip = 0; - } - + if ( !extension_loaded("zlib") && $gzip ) { - return "Cannot decompress gzipped backup (zlib package not installed)"; + return 'Cannot decompress gzipped backup (zlib package not installed)'; } - + // get sql query according to gzip setting (either decompress, or not) + $contents = self::get_contents($backup_file_tmpname, $gzip); + if ( $contents == '' ) + { + return 'Cannot get contents from this file.'; + } + + /* detect lines */ + $lines = preg_split('/[\r\n]/', $contents); + if( $lines === $contents ) + { + return 'Cannot parse contents from this file'; + } + + /* get sql statements from each lines */ + $queries = self::get_queries($lines); + if ( $queries === array() ) + { + return "Cannot get SQL queries from this file."; + } + + /* execute sql statements */ + foreach ( $queries as $query ) + { + if ( !sql_query($query) ) + { + debug('SQL Error: ' . sql_error()); + break; + } + continue; + } + return; + } + + static private function get_contents($temporary_name, $gzip = 0) + { + $contents = ''; if ( $gzip ) { // decompress and read - $gz_ptr = gzopen($backup_file_tmpname, 'rb'); - $sql_query = ''; + $gz_ptr = gzopen($temporary_name, 'rb'); while ( !gzeof($gz_ptr) ) { - $sql_query .= gzgets($gz_ptr, 100000); + $contents .= gzgets($gz_ptr, 100000); } } else { // just read - $fsize = filesize($backup_file_tmpname); - if ( $fsize <= 0 ) + $fsize = filesize($temporary_name); + if ( $fsize > 0 ) { - $sql_query = ''; - } - else - { - $sql_query = fread(fopen($backup_file_tmpname, 'r'), $fsize); + $contents = fread(fopen($temporary_name, 'r'), $fsize); } } - - $lines = preg_split('/[\r\n]/', $sql_query); + return $contents; + } + + static private function get_queries($lines) + { $query = ''; + $queries = array(); foreach ( $lines as $line ) { $line = trim($line); - if ( !$line || $line[0] == '#' ) + if ( !$line || $line[0] == '#' || preg_match('#^[\s|/]?\*#', $line) ) { continue; } - + if ( preg_match('/^(.*);$/', $line, $matches) === 0 ) { $query .= $line; @@ -379,15 +420,11 @@ class Backup else { $query .= $matches[1]; - $result = sql_query($query); - - if ( !$result ) - { - debug('SQL Error: ' . sql_error()); - } + $queries[] = $query; $query = ''; } + continue; } - return; + return $queries; } -} +} \ No newline at end of file -- 2.11.0