diff --git a/wp-content/plugins/wp-db-backup.php b/wp-content/plugins/wp-db-backup.php new file mode 100644 index 000000000..c5a9e3b9d --- /dev/null +++ b/wp-content/plugins/wp-db-backup.php @@ -0,0 +1,865 @@ +backup_dir = trailingslashit($this->backup_dir); + $this->basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__); + + if (isset($_POST['do_backup'])) { + switch($_POST['do_backup']) { + case 'backup': + $this->perform_backup(); + break; + case 'fragments': + add_action('admin_menu', array(&$this, 'fragment_menu')); + break; + } + } elseif (isset($_GET['fragment'] )) { + add_action('init', array(&$this, 'init')); + } elseif (isset($_GET['backup'] )) { + add_action('init', array(&$this, 'init')); + } else { + add_action('admin_menu', array(&$this, 'admin_menu')); + } + } + + function init() { + global $user_level; + get_currentuserinfo(); + + if ($user_level < 9) die('Need higher user level.'); + + if (isset($_GET['backup'])) { + $via = isset($_GET['via']) ? $_GET['via'] : 'http'; + + $this->backup_file = $_GET['backup']; + + switch($via) { + case 'smtp': + case 'email': + $this->deliver_backup ($this->backup_file, 'smtp', $_GET['recipient']); + echo ' + + + '; + break; + default: + $this->deliver_backup ($this->backup_file, $via); + } + die(); + } + if (isset($_GET['fragment'] )) { + list($table, $segment, $filename) = explode(':', $_GET['fragment']); + $this->backup_fragment($table, $segment, $filename); + } + + die(); + } + + function build_backup_script() { + global $table_prefix, $wpdb; + + $datum = date("Ymd_B"); + $backup_filename = DB_NAME . "_$table_prefix$datum.sql"; + if ($this->gzip()) $backup_filename .= '.gz'; + + echo "
"; + //echo "
" . print_r($_POST, 1) . "
"; + echo '

' . __('Backup', 'wp-db-backup') . '

+
' . __('Progress', 'wp-db-backup') . ' + ' . __('

DO NOT DO THE FOLLOWING AS IT WILL CAUSE YOUR BACKUP TO FAIL:

  1. Close this browser
  2. Reload this page
  3. Click the Stop or Back buttons in your browser
', 'wp-db-backup') . ' +

' . __('Progress:', 'wp-db-backup') . '

+
 
+
+
+
+ + + '; + } + + function backup_fragment($table, $segment, $filename) { + global $table_prefix, $wpdb; + + echo "$table:$segment:$filename"; + + if($table == '') { + $msg = __("Creating backup file...", 'wp-db-backup'); + } else { + if($segment == -1) { + $msg = sprintf(__('Finished backing up table \\"%s\\".', 'wp-db-backup'), $table); + } else { + $msg = sprintf(__('Backing up table \\"%s\\"...', 'wp-db-backup'), $table); + } + } + + echo ' + '; + } + else { + echo ' + window.parent.nextStep(); + //--> + '; + } + + die(); + } + + function perform_backup() { + // are we backing up any other tables? + $also_backup = array(); + if (isset($_POST['other_tables'])) { + $also_backup = $_POST['other_tables']; + } + + $core_tables = $_POST['core_tables']; + $this->backup_file = $this->db_backup($core_tables, $also_backup); + if (FALSE !== $backup_file) { + if ('smtp' == $_POST['deliver']) { + $this->deliver_backup ($this->backup_file, $_POST['deliver'], $_POST['backup_recipient']); + } elseif ('http' == $_POST['deliver']) { + $this_basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__); + header('Refresh: 3; ' . get_settings('siteurl') . "/wp-admin/edit.php?page={$this_basename}&backup={$this->backup_file}"); + } + // we do this to say we're done. + $this->backup_complete = true; + } + } + + /////////////////////////////// + function admin_menu() { + add_management_page('Backup', 'Backup', 9, basename(__FILE__), array(&$this, 'backup_menu')); + } + + function fragment_menu() { + add_management_page('Backup', 'Backup', 9, basename(__FILE__), array(&$this, 'build_backup_script')); + } + + ///////////////////////////////////////////////////////// + function sql_addslashes($a_string = '', $is_like = FALSE) + { + /* + Better addslashes for SQL queries. + Taken from phpMyAdmin. + */ + if ($is_like) { + $a_string = str_replace('\\', '\\\\\\\\', $a_string); + } else { + $a_string = str_replace('\\', '\\\\', $a_string); + } + $a_string = str_replace('\'', '\\\'', $a_string); + + return $a_string; + } // function sql_addslashes($a_string = '', $is_like = FALSE) + + /////////////////////////////////////////////////////////// + function backquote($a_name) + { + /* + Add backqouotes to tables and db-names in + SQL queries. Taken from phpMyAdmin. + */ + if (!empty($a_name) && $a_name != '*') { + if (is_array($a_name)) { + $result = array(); + reset($a_name); + while(list($key, $val) = each($a_name)) { + $result[$key] = '`' . $val . '`'; + } + return $result; + } else { + return '`' . $a_name . '`'; + } + } else { + return $a_name; + } + } // function backquote($a_name, $do_it = TRUE) + + ///////////// + function open($filename = '', $mode = 'w') { + if ('' == $filename) return false; + if ($this->gzip()) { + $fp = @gzopen($filename, $mode); + } else { + $fp = @fopen($filename, $mode); + } + return $fp; + } + + ////////////// + function close($fp) { + if ($this->gzip()) { + gzclose($fp); + } else { + fclose($fp); + } + } + + ////////////// + function stow($query_line) { + if ($this->gzip()) { + if(@gzwrite($this->fp, $query_line) === FALSE) { + backup_error(__('There was an error writing a line to the backup script:', 'wp-db-backup')); + backup_error('  ' . $query_line); + } + } else { + if(@fwrite($this->fp, $query_line) === FALSE) { + backup_error(__('There was an error writing a line to the backup script:', 'wp-db-backup')); + backup_error('  ' . $query_line); + } + } + } + + function backup_error($err) { + if(count($this->backup_errors) < 20) { + $this->backup_errors[] = $err; + } elseif(count($this->backup_errors) == 20) { + $this->backup_errors[] = __('Subsequent errors have been omitted from this log.', 'wp-db-backup'); + } + } + + ///////////////////////////// + function backup_table($table, $segment = 'none') { + global $wpdb; + + /* + Taken partially from phpMyAdmin and partially from + Alain Wolf, Zurich - Switzerland + Website: http://restkultur.ch/personal/wolf/scripts/db_backup/ + + Modified by Scott Merril (http://www.skippy.net/) + to use the WordPress $wpdb object + */ + + $table_structure = $wpdb->get_results("DESCRIBE $table"); + if (! $table_structure) { + backup_errors(__('Error getting table details', 'wp-db-backup') . ": $table"); + return FALSE; + } + + if(($segment == 'none') || ($segment == 0)) { + // + // Add SQL statement to drop existing table + $this->stow("\n\n"); + $this->stow("#\n"); + $this->stow("# Delete any existing table " . $this->backquote($table) . "\n"); + $this->stow("#\n"); + $this->stow("\n"); + $this->stow("DROP TABLE IF EXISTS " . $this->backquote($table) . ";\n"); + + // + //Table structure + // Comment in SQL-file + $this->stow("\n\n"); + $this->stow("#\n"); + $this->stow("# Table structure of table " . $this->backquote($table) . "\n"); + $this->stow("#\n"); + $this->stow("\n"); + + $create_table = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N); + if (FALSE === $create_table) { + $this->backup_error(sprintf(__("Error with SHOW CREATE TABLE for %s.", 'wp-db-backup'), $table)); + $this->stow("#\n# Error with SHOW CREATE TABLE for $table!\n#\n"); + } + $this->stow($create_table[0][1] . ' ;'); + + if (FALSE === $table_structure) { + $this->backup_error(sprintf(__("Error getting table structure of %s", 'wp-db-backup'), $table)); + $this->stow("#\n# Error getting table structure of $table!\n#\n"); + } + + // + // Comment in SQL-file + $this->stow("\n\n"); + $this->stow("#\n"); + $this->stow('# Data contents of table ' . $this->backquote($table) . "\n"); + $this->stow("#\n"); + } + + if(($segment == 'none') || ($segment >= 0)) { + $ints = array(); + foreach ($table_structure as $struct) { + if ( (0 === strpos($struct->Type, 'tinyint')) || + (0 === strpos(strtolower($struct->Type), 'smallint')) || + (0 === strpos(strtolower($struct->Type), 'mediumint')) || + (0 === strpos(strtolower($struct->Type), 'int')) || + (0 === strpos(strtolower($struct->Type), 'bigint')) || + (0 === strpos(strtolower($struct->Type), 'timestamp')) ) { + $ints[strtolower($struct->Field)] = "1"; + } + } + + + // Batch by $row_inc + + if($segment == 'none') { + $row_start = 0; + $row_inc = ROWS_PER_SEGMENT; + } else { + $row_start = $segment * ROWS_PER_SEGMENT; + $row_inc = ROWS_PER_SEGMENT; + } + + do { + if ( !ini_get('safe_mode')) @set_time_limit(15*60); + $table_data = $wpdb->get_results("SELECT * FROM $table LIMIT {$row_start}, {$row_inc}", ARRAY_A); + + /* + if (FALSE === $table_data) { + $wp_backup_error .= "Error getting table contents from $table\r\n"; + fwrite($fp, "#\n# Error getting table contents fom $table!\n#\n"); + } + */ + + $entries = 'INSERT INTO ' . $this->backquote($table) . ' VALUES ('; + // \x08\\x09, not required + $search = array("\x00", "\x0a", "\x0d", "\x1a"); + $replace = array('\0', '\n', '\r', '\Z'); + if($table_data) { + foreach ($table_data as $row) { + $values = array(); + foreach ($row as $key => $value) { + if ($ints[strtolower($key)]) { + $values[] = $value; + } else { + $values[] = "'" . str_replace($search, $replace, $this->sql_addslashes($value)) . "'"; + } + } + $this->stow(" \n" . $entries . implode(', ', $values) . ') ;'); + } + $row_start += $row_inc; + } + } while((count($table_data) > 0) and ($segment=='none')); + } + + + if(($segment == 'none') || ($segment < 0)) { + // Create footer/closing comment in SQL-file + $this->stow("\n"); + $this->stow("#\n"); + $this->stow("# End of data contents of table " . $this->backquote($table) . "\n"); + $this->stow("# --------------------------------------------------------\n"); + $this->stow("\n"); + } + + } // end backup_table() + + function return_bytes($val) { + $val = trim($val); + $last = strtolower($val{strlen($val)-1}); + switch($last) { + // The 'G' modifier is available since PHP 5.1.0 + case 'g': + $val *= 1024; + case 'm': + $val *= 1024; + case 'k': + $val *= 1024; + } + + return $val; + } + + //////////////////////////// + function db_backup($core_tables, $other_tables) { + global $table_prefix, $wpdb; + + $datum = date("Ymd_B"); + $wp_backup_filename = DB_NAME . "_$table_prefix$datum.sql"; + if ($this->gzip()) { + $wp_backup_filename .= '.gz'; + } + + if (is_writable(ABSPATH . $this->backup_dir)) { + $this->fp = $this->open(ABSPATH . $this->backup_dir . $wp_backup_filename); + if(!$this->fp) { + $this->backup_error(__('Could not open the backup file for writing!', 'wp-db-backup')); + return false; + } + } else { + $this->backup_error(__('The backup directory is not writeable!', 'wp-db-backup')); + return false; + } + + //Begin new backup of MySql + $this->stow("# WordPress MySQL database backup\n"); + $this->stow("#\n"); + $this->stow("# Generated: " . date("l j. F Y H:i T") . "\n"); + $this->stow("# Hostname: " . DB_HOST . "\n"); + $this->stow("# Database: " . $this->backquote(DB_NAME) . "\n"); + $this->stow("# --------------------------------------------------------\n"); + + if ( (is_array($other_tables)) && (count($other_tables) > 0) ) + $tables = array_merge($core_tables, $other_tables); + else + $tables = $core_tables; + + foreach ($tables as $table) { + // Increase script execution time-limit to 15 min for every table. + if ( !ini_get('safe_mode')) @set_time_limit(15*60); + // Create the SQL statements + $this->stow("# --------------------------------------------------------\n"); + $this->stow("# Table: " . $this->backquote($table) . "\n"); + $this->stow("# --------------------------------------------------------\n"); + $this->backup_table($table); + } + + $this->close($this->fp); + + if (count($this->backup_errors)) { + return false; + } else { + return $wp_backup_filename; + } + + } //wp_db_backup + + /////////////////////////// + function deliver_backup ($filename = '', $delivery = 'http', $recipient = '') { + if ('' == $filename) { return FALSE; } + + $diskfile = ABSPATH . $this->backup_dir . $filename; + if ('http' == $delivery) { + if (! file_exists($diskfile)) { + $msg = sprintf(__('File not found:
%1s
', 'wp-db-backup'), $filename); + $this_basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__); + $msg .= '
' . __('Return to Backup', 'wp-db-backup'); + die($msg); + } + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Length: ' . filesize($diskfile)); + header("Content-Disposition: attachment; filename=$filename"); + readfile($diskfile); + unlink($diskfile); + } elseif ('smtp' == $delivery) { + if (! file_exists($diskfile)) return false; + + if (! is_email ($recipient)) { + $recipient = get_settings('admin_email'); + } + $randomish = md5(time()); + $boundary = "==WPBACKUP-BY-SKIPPY-$randomish"; + $fp = fopen($diskfile,"rb"); + $file = fread($fp,filesize($diskfile)); + $this->close($fp); + $data = chunk_split(base64_encode($file)); + $headers = "MIME-Version: 1.0\n"; + $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n"; + $headers .= 'From: ' . get_settings('admin_email') . "\n"; + + $message = sprintf(__("Attached to this email is\n %1s\n Size:%2s kilobytes\n", 'wp-db-backup'), $filename, round(filesize($diskfile)/1024)); + // Add a multipart boundary above the plain message + $message = "This is a multi-part message in MIME format.\n\n" . + "--{$boundary}\n" . + "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . + "Content-Transfer-Encoding: 7bit\n\n" . + $message . "\n\n"; + + // Add file attachment to the message + $message .= "--{$boundary}\n" . + "Content-Type: application/octet-stream;\n" . + " name=\"{$filename}\"\n" . + "Content-Disposition: attachment;\n" . + " filename=\"{$filename}\"\n" . + "Content-Transfer-Encoding: base64\n\n" . + $data . "\n\n" . + "--{$boundary}--\n"; + + if (function_exists('wp_mail')) { + wp_mail ($recipient, get_bloginfo('name') . ' ' . __('Database Backup', 'wp-db-backup'), $message, $headers); + } else { + mail ($recipient, get_bloginfo('name') . ' ' . __('Database Backup', 'wp-db-backup'), $message, $headers); + } + + unlink($diskfile); + } + return; + } + + //////////////////////////// + function backup_menu() { + global $table_prefix, $wpdb; + $feedback = ''; + $WHOOPS = FALSE; + + // did we just do a backup? If so, let's report the status + if ( $this->backup_complete ) { + $feedback = '

' . __('Backup Successful', 'wp-db-backup') . '!'; + $file = $this->backup_file; + switch($_POST['deliver']) { + case 'http': + $feedback .= '
' . sprintf(__('Your backup file:
%2s should begin downloading shortly.', 'wp-db-backup'), get_settings('siteurl') . "/{$this->backup_dir}{$this->backup_file}", $this->backup_file); + break; + case 'smtp': + if (! is_email($_POST['backup_recipient'])) { + $feedback .= get_settings('admin_email'); + } else { + $feedback .= $_POST['backup_recipient']; + } + $feedback = '
' . sprintf(__('Your backup has been emailed to %s', 'wp-db-backup'), $feedback); + break; + case 'none': + $feedback .= '
' . __('Your backup file has been saved on the server. If you would like to download it now, right click and select "Save As"', 'wp-db-backup'); + $feedback .= ':
backup_dir}$file\">$file : " . filesize(ABSPATH . $this->backup_dir . $file) . __(' bytes', 'wp-db-backup'); + } + $feedback .= '

'; + } + + if (count($this->backup_errors)) { + $feedback .= '
' . __('The following errors were reported', 'wp-db-backup') . ":
";
+			foreach($this->backup_errors as $error) {
+				$feedback .= "{$error}\n";  //Errors are already localized
+			}
+			$feedback .= "
"; + } + + // did we just save options for wp-cron? + if ( (function_exists('wp_cron_init')) && isset($_POST['wp_cron_backup_options']) ) { + update_option('wp_cron_backup_schedule', intval($_POST['cron_schedule']), FALSE); + update_option('wp_cron_backup_tables', $_POST['wp_cron_backup_tables']); + if (is_email($_POST['cron_backup_recipient'])) { + update_option('wp_cron_backup_recipient', $_POST['cron_backup_recipient'], FALSE); + } + $feedback .= '

' . __('Scheduled Backup Options Saved!', 'wp-db-backup') . '

'; + } + + // Simple table name storage + $wp_table_names = explode(',','categories,comments,linkcategories,links,options,post2cat,postmeta,posts,users,usermeta'); + // Apply WP DB prefix to table names + $wp_table_names = array_map(create_function('$a', 'global $table_prefix;return "{$table_prefix}{$a}";'), $wp_table_names); + + $other_tables = array(); + $also_backup = array(); + + // Get complete db table list + $all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N); + $all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables); + // Get list of WP tables that actually exist in this DB (for 1.6 compat!) + $wp_backup_default_tables = array_intersect($all_tables, $wp_table_names); + // Get list of non-WP tables + $other_tables = array_diff($all_tables, $wp_backup_default_tables); + + if ('' != $feedback) { + echo $feedback; + } + + if (! is_dir(ABSPATH . $this->backup_dir)) { + echo '

' . __('WARNING: Your backup directory does not exist!', 'wp-db-backup') . '
' . ABSPATH . $this->backup_dir . "

"; + $WHOOPS = TRUE; + }elseif (! is_writable(ABSPATH . $this->backup_dir)) { + echo '

' . __('WARNING: Your backup directory is NOT writable!', 'wp-db-backup') . '
' . ABSPATH . $this->backup_dir . "

"; + $WHOOPS = TRUE; + } + echo "
"; + echo '

' . __('Backup', 'wp-db-backup') . '

'; + echo '
' . __('Tables', 'wp-db-backup') . ''; + echo '
'; + echo '
'; + echo __('These core WordPress tables will always be backed up', 'wp-db-backup') . ':
    '; + foreach ($wp_backup_default_tables as $table) { + echo "
  • $table
  • "; + } + echo '
'; + if (count($other_tables) > 0) { + echo __('You may choose to include any of the following tables', 'wp-db-backup') . ':
'; + foreach ($other_tables as $table) { + echo ""; + } + } + echo '
'; + echo '
' . __('Backup Options', 'wp-db-backup') . ''; + echo __('What to do with the backup file', 'wp-db-backup') . ":
"; + echo '"; + echo ''; + echo '
'; + echo sprintf(__(' %s', 'wp-db-backup'), ''); + + // Check DB dize. + $table_status = $wpdb->get_results("SHOW TABLE STATUS FROM " . $this->backquote(DB_NAME)); + $core_size = $db_size = 0; + foreach($table_status as $table) { + $table_size = $table->Data_length - $table->Data_free; + if(in_array($table->Name, $wp_backup_default_tables)) { + $core_size += $table_size; + } + $db_size += $table_size; + } + $mem_limit = ini_get('memory_limit'); + $mem_limit = $this->return_bytes($mem_limit); + $mem_limit = ($mem_limit == 0) ? 8*1024*1024 : $mem_limit - 2000000; + + if (! $WHOOPS) { + echo '
'; + echo '

'; + } else { + echo '

' . __('WARNING: Your backup directory is NOT writable!', 'wp-db-backup') . '

'; + } + echo '
'; + echo ''; + + // this stuff only displays if wp_cron is installed + if (function_exists('wp_cron_init')) { + echo '
' . __('Scheduled Backup', 'wp-db-backup') . ''; + $datetime = get_settings('date_format') . ' @ ' . get_settings('time_format'); + echo '

' . __('Last WP-Cron Daily Execution', 'wp-db-backup') . ': ' . date($datetime, get_option('wp_cron_daily_lastrun')) . '
'; + echo __('Next WP-Cron Daily Execution', 'wp-db-backup') . ': ' . date($datetime, (get_option('wp_cron_daily_lastrun') + 86400)) . '

'; + echo '
'; + echo ''; + echo ''; + $cron_tables = get_option('wp_cron_backup_tables'); + if (! is_array($cron_tables)) { + $cron_tables = array(); + } + if (count($other_tables) > 0) { + echo ''; + } + echo '
'; + echo __('Schedule: ', 'wp-db-backup'); + $wp_cron_backup_schedule = get_option('wp_cron_backup_schedule'); + $schedule = array(0 => __('None', 'wp-db-backup'), 1 => __('Daily', 'wp-db-backup')); + foreach ($schedule as $value => $name) { + echo ' ' . __($name, 'wp-db-backup'); + } + echo ''; + $cron_recipient = get_option('wp_cron_backup_recipient'); + if (! is_email($cron_recipient)) { + $cron_recipient = get_settings('admin_email'); + } + echo __('Email backup to', 'wp-db-backup') . ': '; + echo '
' . __('Tables to include', 'wp-db-backup') . ':
'; + foreach ($other_tables as $table) { + echo ' {$table}
"; + } + echo '
'; + echo '
'; + } + // end of wp_cron section + + echo '
'; + + }// end wp_backup_menu() + + ///////////////////////////// + function wp_cron_daily() { + + $schedule = intval(get_option('wp_cron_backup_schedule')); + if (0 == $schedule) { + // Scheduled backup is disabled + return; + } + + global $table_prefix, $wpdb; + + $wp_table_names = explode(',','categories,comments,linkcategories,links,options,post2cat,postmeta,posts,users,usermeta'); + $wp_table_names = array_map(create_function('$a', 'global $table_prefix;return "{$table_prefix}{$a}";'), $wp_table_names); + $all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N); + $all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables); + $core_tables = array_intersect($all_tables, $wp_table_names); + $other_tables = get_option('wp_cron_backup_tables'); + + $recipient = get_option('wp_cron_backup_recipient'); + + $backup_file = $this->db_backup($core_tables, $other_tables); + if (FALSE !== $backup_file) { + $this->deliver_backup ($backup_file, 'smtp', $recipient); + } + + return; + } // wp_cron_db_backup +} + +$mywpdbbackup = new wpdbBackup(); + +?> \ No newline at end of file