2005-11-18 18:43:41 -05:00
< ? php
/*
Plugin Name : WordPress Database Backup
Plugin URI : http :// www . skippy . net / blog / plugins /
Description : On - demand backup of your WordPress database .
Author : Scott Merrill
Version : 1.7
Author URI : http :// www . skippy . net /
Much of this was modified from Mark Ghosh ' s One Click Backup , which
in turn was derived from phpMyAdmin .
Many thanks to Owen ( http :// asymptomatic . net / wp / ) for his patch
http :// dev . wp - plugins . org / ticket / 219
*/
// CHANGE THIS IF YOU WANT TO USE A
// DIFFERENT BACKUP LOCATION
$rand = substr ( md5 ( md5 ( DB_PASSWORD ) ), - 5 );
define ( 'WP_BACKUP_DIR' , 'wp-content/backup-' . $rand );
define ( 'ROWS_PER_SEGMENT' , 100 );
class wpdbBackup {
var $backup_complete = false ;
var $backup_file = '' ;
var $backup_dir = WP_BACKUP_DIR ;
var $backup_errors = array ();
var $basename ;
function gzip () {
return function_exists ( 'gzopen' );
}
function wpdbBackup () {
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
add_action ( 'wp_cron_daily' , array ( & $this , 'wp_cron_daily' ));
$this -> backup_dir = trailingslashit ( $this -> backup_dir );
$this -> basename = preg_replace ( '/^.*wp-content[\\\\\/]plugins[\\\\\/]/' , '' , __FILE__ );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
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' ));
2006-02-12 02:53:23 -05:00
break ;
2005-11-18 18:43:41 -05:00
}
} 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' ));
2005-11-30 14:39:19 -05:00
}
2005-11-18 18:43:41 -05:00
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
function init () {
global $user_level ;
get_currentuserinfo ();
2005-11-30 14:39:19 -05:00
if ( $user_level < 9 ) die ( __ ( 'Need higher user level.' ));
2005-11-18 18:43:41 -05:00
if ( isset ( $_GET [ 'backup' ])) {
$via = isset ( $_GET [ 'via' ]) ? $_GET [ 'via' ] : 'http' ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$this -> backup_file = $_GET [ 'backup' ];
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
switch ( $via ) {
case 'smtp' :
case 'email' :
$this -> deliver_backup ( $this -> backup_file , 'smtp' , $_GET [ 'recipient' ]);
echo '
<!-- ' . $via . ' -->
< script type = " text/javascript " ><!-- \\
' ;
if ( $this -> backup_errors ) {
foreach ( $this -> backup_errors as $error ) {
echo " window.parent.addError(' $error '); \n " ;
}
}
echo '
2005-11-30 14:39:19 -05:00
alert ( " ' . __('Backup Complete!') . ' " );
2005-11-18 18:43:41 -05:00
</ script >
' ;
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 ();
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
function build_backup_script () {
2006-03-03 12:19:05 -05:00
global $wpdb ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$datum = date ( " Ymd_B " );
2006-03-03 15:36:40 -05:00
$backup_filename = DB_NAME . '_' . $wpdb -> prefix . $datum . '.sql' ;
2005-11-18 18:43:41 -05:00
if ( $this -> gzip ()) $backup_filename .= '.gz' ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
echo " <div class='wrap'> " ;
//echo "<pre>" . print_r($_POST, 1) . "</pre>";
2005-11-30 14:39:19 -05:00
echo '<h2>' . __ ( 'Backup' ) . ' </ h2 >
< fieldset class = " options " >< legend > ' . __(' Progress ') . ' </ legend >
2005-12-02 12:35:36 -05:00
< p >< strong > ' .
__ ( 'DO NOT DO THE FOLLOWING AS IT WILL CAUSE YOUR BACKUP TO FAIL:' ) .
' </ strong ></ p >
< ol >
< li > '.__(' Close this browser ').' </ li >
< li > '.__(' Reload this page ').' </ li >
< li > '.__(' Click the Stop or Back buttons in your browser ').' </ li >
</ ol >
2005-11-30 14:39:19 -05:00
< p >< strong > ' . __(' Progress : ') . ' </ strong ></ p >
2005-11-18 18:43:41 -05:00
< div id = " meterbox " style = " height:11px;width:80%;padding:3px;border:1px solid #659fff; " >< div id = " meter " style = " height:11px;background-color:#659fff;width:0%;text-align:center;font-size:6pt; " >& nbsp ; </ div ></ div >
< div id = " progress_message " ></ div >
< div id = " errors " ></ div >
</ fieldset >
< iframe id = " backuploader " src = " about:blank " style = " border:0px solid white;height:1em;width:1em; " ></ iframe >
< script type = " text/javascript " ><!--//
function setMeter ( pct ) {
var meter = document . getElementById ( " meter " );
meter . style . width = pct + " % " ;
meter . innerHTML = Math . floor ( pct ) + " % " ;
}
function setProgress ( str ) {
var progress = document . getElementById ( " progress_message " );
progress . innerHTML = str ;
}
function addError ( str ) {
var errors = document . getElementById ( " errors " );
errors . innerHTML = errors . innerHTML + str + " <br /> " ;
}
2005-11-30 14:39:19 -05:00
2005-11-18 18:43:41 -05:00
function backup ( table , segment ) {
2006-02-12 02:53:23 -05:00
var fram = document . getElementById ( " backuploader " );
2005-11-18 18:43:41 -05:00
fram . src = " ' . $_SERVER['REQUEST_URI'] . '&fragment= " + table + " : " + segment + " :' . $backup_filename . ' " ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
var curStep = 0 ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
function nextStep () {
backupStep ( curStep );
curStep ++ ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
function finishBackup () {
2006-02-12 02:53:23 -05:00
var fram = document . getElementById ( " backuploader " );
2005-11-18 18:43:41 -05:00
setMeter ( 100 );
' ;
$this_basename = preg_replace ( '/^.*wp-content[\\\\\/]plugins[\\\\\/]/' , '' , __FILE__ );
$download_uri = get_settings ( 'siteurl' ) . " /wp-admin/edit.php?page= { $this_basename } &backup= { $backup_filename } " ;
switch ( $_POST [ 'deliver' ]) {
case 'http' :
echo '
2005-11-30 14:39:19 -05:00
setProgress ( " ' . sprintf(__( " Backup complete , preparing < a href = \\\ " %s \\ \" >backup</a> for download... " ), $download_uri ) . ' " );
2005-11-18 18:43:41 -05:00
fram . src = " ' . $download_uri . ' " ;
' ;
break ;
case 'smtp' :
echo '
2005-11-30 14:39:19 -05:00
setProgress ( " ' . sprintf(__( " Backup complete , sending < a href = \\\ " %s \\ \" >backup</a> via email... " ), $download_uri ) . ' " );
2005-11-18 18:43:41 -05:00
fram . src = " ' . $download_uri . '&via=email&recipient=' . $_POST['backup_recipient'] . ' " ;
' ;
break ;
default :
echo '
2005-11-30 14:39:19 -05:00
setProgress ( " ' . sprintf(__( " Backup complete , download < a href = \\\ " %s \\ \" >here</a>. " ), $download_uri ) . ' " );
2005-11-18 18:43:41 -05:00
' ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
echo '
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
function backupStep ( step ) {
switch ( step ) {
case 0 : backup ( " " , 0 ); break ;
' ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$also_backup = array ();
if ( isset ( $_POST [ 'other_tables' ])) {
$also_backup = $_POST [ 'other_tables' ];
} else {
$also_backup = array ();
}
$core_tables = $_POST [ 'core_tables' ];
$tables = array_merge ( $core_tables , $also_backup );
$step_count = 1 ;
foreach ( $tables as $table ) {
$rec_count = $wpdb -> get_var ( " SELECT count(*) FROM { $table } " );
$rec_segments = ceil ( $rec_count / ROWS_PER_SEGMENT );
$table_count = 0 ;
do {
echo " case { $step_count } : backup( \" { $table } \" , { $table_count } ); break; \n " ;
$step_count ++ ;
$table_count ++ ;
} while ( $table_count < $rec_segments );
echo " case { $step_count } : backup( \" { $table } \" , -1); break; \n " ;
$step_count ++ ;
}
echo " case { $step_count } : finishBackup(); break; " ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
echo '
}
if ( step != 0 ) setMeter ( 100 * step / ' . $step_count . ' );
}
2005-11-30 14:39:19 -05:00
2005-11-18 18:43:41 -05:00
nextStep ();
//--></script>
</ div >
' ;
}
function backup_fragment ( $table , $segment , $filename ) {
2006-03-03 12:19:05 -05:00
global $wpdb ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
echo " $table : $segment : $filename " ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( $table == '' ) {
2005-12-02 12:35:36 -05:00
$msg = __ ( 'Creating backup file...' );
2005-11-18 18:43:41 -05:00
} else {
if ( $segment == - 1 ) {
2005-11-30 14:39:19 -05:00
$msg = sprintf ( __ ( 'Finished backing up table \\"%s\\".' ), $table );
2005-11-18 18:43:41 -05:00
} else {
2005-11-30 14:39:19 -05:00
$msg = sprintf ( __ ( 'Backing up table \\"%s\\"...' ), $table );
2005-11-18 18:43:41 -05:00
}
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
echo ' < script type = " text/javascript " ><!--//
var msg = " ' . $msg . ' " ;
window . parent . setProgress ( msg );
' ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( is_writable ( ABSPATH . $this -> backup_dir )) {
$this -> fp = $this -> open ( ABSPATH . $this -> backup_dir . $filename , 'a' );
if ( ! $this -> fp ) {
2005-11-30 14:39:19 -05:00
$this -> backup_error ( __ ( 'Could not open the backup file for writing!' ));
$this -> fatal_error = __ ( 'The backup file could not be saved. Please check the permissions for writing to your backup directory and try again.' );
2005-11-18 18:43:41 -05:00
}
else {
2006-02-12 02:53:23 -05:00
if ( $table == '' ) {
2005-11-18 18:43:41 -05:00
//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 " );
} else {
if ( $segment == 0 ) {
// Increase script execution time-limit to 15 min for every table.
if ( ! ini_get ( 'safe_mode' )) @ set_time_limit ( 15 * 60 );
//ini_set('memory_limit', '16M');
// Create the SQL statements
$this -> stow ( " # -------------------------------------------------------- \n " );
$this -> stow ( " # Table: " . $this -> backquote ( $table ) . " \n " );
$this -> stow ( " # -------------------------------------------------------- \n " );
2006-02-12 02:53:23 -05:00
}
2005-11-18 18:43:41 -05:00
$this -> backup_table ( $table , $segment );
}
}
} else {
2005-11-30 14:39:19 -05:00
$this -> backup_error ( __ ( 'The backup directory is not writeable!' ));
$this -> fatal_error = __ ( 'The backup directory is not writeable! Please check the permissions for writing to your backup directory and try again.' );
2005-11-18 18:43:41 -05:00
}
if ( $this -> fp ) $this -> close ( $this -> fp );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( $this -> backup_errors ) {
foreach ( $this -> backup_errors as $error ) {
echo " window.parent.addError(' $error '); \n " ;
}
}
if ( $this -> fatal_error ) {
echo '
alert ( " ' . addslashes( $this->fatal_error ) . ' " );
//--></script>
' ;
}
else {
echo '
window . parent . nextStep ();
//--></script>
' ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
die ();
}
function perform_backup () {
// are we backing up any other tables?
$also_backup = array ();
if ( isset ( $_POST [ 'other_tables' ])) {
$also_backup = $_POST [ 'other_tables' ];
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$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 ;
}
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
///////////////////////////////
function admin_menu () {
2005-11-30 14:39:19 -05:00
add_management_page ( __ ( 'Backup' ), __ ( 'Backup' ), 9 , basename ( __FILE__ ), array ( & $this , 'backup_menu' ));
2005-11-18 18:43:41 -05:00
}
function fragment_menu () {
2005-11-30 14:39:19 -05:00
add_management_page ( __ ( 'Backup' ), __ ( 'Backup' ), 9 , basename ( __FILE__ ), array ( & $this , 'build_backup_script' ));
2005-11-18 18:43:41 -05:00
}
2005-11-30 14:39:19 -05:00
2005-11-18 18:43:41 -05:00
/////////////////////////////////////////////////////////
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 );
2005-11-30 14:39:19 -05:00
2005-11-18 18:43:41 -05:00
return $a_string ;
} // function sql_addslashes($a_string = '', $is_like = FALSE)
2005-11-30 14:39:19 -05:00
2005-11-18 18:43:41 -05:00
///////////////////////////////////////////////////////////
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 );
}
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
//////////////
function stow ( $query_line ) {
if ( $this -> gzip ()) {
if ( @ gzwrite ( $this -> fp , $query_line ) === FALSE ) {
2005-11-30 14:39:19 -05:00
backup_error ( __ ( 'There was an error writing a line to the backup script:' ));
2005-11-18 18:43:41 -05:00
backup_error ( ' ' . $query_line );
}
} else {
if ( @ fwrite ( $this -> fp , $query_line ) === FALSE ) {
2005-11-30 14:39:19 -05:00
backup_error ( __ ( 'There was an error writing a line to the backup script:' ));
2005-11-18 18:43:41 -05:00
backup_error ( ' ' . $query_line );
}
}
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
function backup_error ( $err ) {
if ( count ( $this -> backup_errors ) < 20 ) {
$this -> backup_errors [] = $err ;
} elseif ( count ( $this -> backup_errors ) == 20 ) {
2005-11-30 14:39:19 -05:00
$this -> backup_errors [] = __ ( 'Subsequent errors have been omitted from this log.' );
2005-11-18 18:43:41 -05:00
}
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
/////////////////////////////
function backup_table ( $table , $segment = 'none' ) {
global $wpdb ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
/*
Taken partially from phpMyAdmin and partially from
Alain Wolf , Zurich - Switzerland
Website : http :// restkultur . ch / personal / wolf / scripts / db_backup /
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
Modified by Scott Merril ( http :// www . skippy . net / )
to use the WordPress $wpdb object
*/
$table_structure = $wpdb -> get_results ( " DESCRIBE $table " );
if ( ! $table_structure ) {
2005-11-30 14:39:19 -05:00
backup_errors ( __ ( 'Error getting table details' ) . " : $table " );
2005-11-18 18:43:41 -05:00
return FALSE ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
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 " );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
//
//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 " );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$create_table = $wpdb -> get_results ( " SHOW CREATE TABLE $table " , ARRAY_N );
if ( FALSE === $create_table ) {
2005-11-30 14:39:19 -05:00
$this -> backup_error ( sprintf ( __ ( " Error with SHOW CREATE TABLE for %s. " ), $table ));
2005-11-18 18:43:41 -05:00
$this -> stow ( " # \n # Error with SHOW CREATE TABLE for $table ! \n # \n " );
}
$this -> stow ( $create_table [ 0 ][ 1 ] . ' ;' );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( FALSE === $table_structure ) {
2005-11-30 14:39:19 -05:00
$this -> backup_error ( sprintf ( __ ( " Error getting table structure of %s " ), $table ));
2005-11-18 18:43:41 -05:00
$this -> stow ( " # \n # Error getting table structure of $table ! \n # \n " );
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
//
// Comment in SQL-file
$this -> stow ( " \n \n " );
$this -> stow ( " # \n " );
$this -> stow ( '# Data contents of table ' . $this -> backquote ( $table ) . " \n " );
$this -> stow ( " # \n " );
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
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 " ;
}
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
// Batch by $row_inc
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( $segment == 'none' ) {
$row_start = 0 ;
$row_inc = ROWS_PER_SEGMENT ;
} else {
$row_start = $segment * ROWS_PER_SEGMENT ;
$row_inc = ROWS_PER_SEGMENT ;
}
2006-02-12 02:53:23 -05:00
do {
2005-11-18 18:43:41 -05:00
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 );
2005-11-30 14:39:19 -05:00
2005-11-18 18:43:41 -05:00
/*
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 " );
}
*/
2006-02-12 02:53:23 -05:00
$entries = 'INSERT INTO ' . $this -> backquote ( $table ) . ' VALUES (' ;
2005-11-18 18:43:41 -05:00
// \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' ));
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
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 " );
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
} // end backup_table()
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
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 ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
return $val ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
////////////////////////////
function db_backup ( $core_tables , $other_tables ) {
2006-03-03 12:19:05 -05:00
global $wpdb ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$datum = date ( " Ymd_B " );
2006-03-03 15:36:40 -05:00
$wp_backup_filename = DB_NAME . '_' . $wpdb -> prefix . $datum . '.sql' ;
2005-11-18 18:43:41 -05:00
if ( $this -> gzip ()) {
$wp_backup_filename .= '.gz' ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( is_writable ( ABSPATH . $this -> backup_dir )) {
$this -> fp = $this -> open ( ABSPATH . $this -> backup_dir . $wp_backup_filename );
if ( ! $this -> fp ) {
2005-11-30 14:39:19 -05:00
$this -> backup_error ( __ ( 'Could not open the backup file for writing!' ));
2005-11-18 18:43:41 -05:00
return false ;
}
} else {
2005-11-30 14:39:19 -05:00
$this -> backup_error ( __ ( 'The backup directory is not writeable!' ));
2005-11-18 18:43:41 -05:00
return false ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
//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 " );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( ( is_array ( $other_tables )) && ( count ( $other_tables ) > 0 ) )
$tables = array_merge ( $core_tables , $other_tables );
else
$tables = $core_tables ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
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 );
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$this -> close ( $this -> fp );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( count ( $this -> backup_errors )) {
return false ;
} else {
return $wp_backup_filename ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
} //wp_db_backup
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
///////////////////////////
function deliver_backup ( $filename = '' , $delivery = 'http' , $recipient = '' ) {
if ( '' == $filename ) { return FALSE ; }
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$diskfile = ABSPATH . $this -> backup_dir . $filename ;
if ( 'http' == $delivery ) {
if ( ! file_exists ( $diskfile )) {
2005-12-02 12:35:36 -05:00
$msg = sprintf ( __ ( 'File not found:%s' ), " <br /><strong> $filename </strong><br /> " );
2005-11-18 18:43:41 -05:00
$this_basename = preg_replace ( '/^.*wp-content[\\\\\/]plugins[\\\\\/]/' , '' , __FILE__ );
2005-11-30 14:39:19 -05:00
$msg .= '<br /><a href="' . get_settings ( 'siteurl' ) . " /wp-admin/edit.php?page= { $this_basename } " . '">' . __ ( 'Return to Backup' );
2005-11-18 18:43:41 -05:00
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 " ;
2006-02-12 02:53:23 -05:00
2005-11-30 14:39:19 -05:00
$message = sprintf ( __ ( " Attached to this email is \n %1s \n Size:%2s kilobytes \n " ), $filename , round ( filesize ( $diskfile ) / 1024 ));
2005-11-18 18:43:41 -05:00
// Add a multipart boundary above the plain message
$message = " This is a multi-part message in MIME format. \n \n " .
" -- { $boundary } \n " .
2006-01-16 19:51:34 -05:00
" Content-Type: text/plain; charset= \" utf-8 \" \n " .
2005-11-18 18:43:41 -05:00
" Content-Transfer-Encoding: 7bit \n \n " .
$message . " \n \n " ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
// 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 " ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( function_exists ( 'wp_mail' )) {
2005-11-30 14:39:19 -05:00
wp_mail ( $recipient , get_bloginfo ( 'name' ) . ' ' . __ ( 'Database Backup' ), $message , $headers );
2005-11-18 18:43:41 -05:00
} else {
2005-11-30 14:39:19 -05:00
mail ( $recipient , get_bloginfo ( 'name' ) . ' ' . __ ( 'Database Backup' ), $message , $headers );
2005-11-18 18:43:41 -05:00
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
unlink ( $diskfile );
}
return ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
////////////////////////////
function backup_menu () {
2006-03-03 12:19:05 -05:00
global $wpdb ;
2005-11-18 18:43:41 -05:00
$feedback = '' ;
$WHOOPS = FALSE ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
// did we just do a backup? If so, let's report the status
if ( $this -> backup_complete ) {
2005-11-30 14:39:19 -05:00
$feedback = '<div class="updated"><p>' . __ ( 'Backup Successful' ) . '!' ;
2005-11-18 18:43:41 -05:00
$file = $this -> backup_file ;
switch ( $_POST [ 'deliver' ]) {
case 'http' :
2005-11-30 14:39:19 -05:00
$feedback .= '<br />' . sprintf ( __ ( 'Your backup file: <a href="%1s">%2s</a> should begin downloading shortly.' ), get_settings ( 'siteurl' ) . " / { $this -> backup_dir } { $this -> backup_file } " , $this -> backup_file );
2005-11-18 18:43:41 -05:00
break ;
case 'smtp' :
if ( ! is_email ( $_POST [ 'backup_recipient' ])) {
$feedback .= get_settings ( 'admin_email' );
} else {
$feedback .= $_POST [ 'backup_recipient' ];
}
2005-11-30 14:39:19 -05:00
$feedback = '<br />' . sprintf ( __ ( 'Your backup has been emailed to %s' ), $feedback );
2005-11-18 18:43:41 -05:00
break ;
case 'none' :
2005-11-30 14:39:19 -05:00
$feedback .= '<br />' . __ ( 'Your backup file has been saved on the server. If you would like to download it now, right click and select "Save As"' );
2005-12-02 12:35:36 -05:00
$feedback .= ':<br /> <a href="' . get_settings ( 'siteurl' ) . " / { $this -> backup_dir } $file\ " > $file </ a > : " . sprintf(__('%s bytes'), filesize(ABSPATH . $this->backup_dir . $file ));
2005-11-18 18:43:41 -05:00
}
$feedback .= '</p></div>' ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( count ( $this -> backup_errors )) {
2005-12-02 12:35:36 -05:00
$feedback .= '<div class="updated error">' . __ ( 'The following errors were reported:' ) . " <pre> " ;
2005-11-18 18:43:41 -05:00
foreach ( $this -> backup_errors as $error ) {
$feedback .= " { $error } \n " ; //Errors are already localized
}
$feedback .= " </pre></div> " ;
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
// 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 );
}
2005-11-30 14:39:19 -05:00
$feedback .= '<div class="updated"><p>' . __ ( 'Scheduled Backup Options Saved!' ) . '</p></div>' ;
2005-11-18 18:43:41 -05:00
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
// 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
2006-03-03 15:36:40 -05:00
$wp_table_names = array_map ( create_function ( '$a' , 'global $wpdb;return "{$wpdb->prefix}{$a}";' ), $wp_table_names );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$other_tables = array ();
$also_backup = array ();
2006-02-12 02:53:23 -05:00
// Get complete db table list
2005-11-18 18:43:41 -05:00
$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 );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( '' != $feedback ) {
echo $feedback ;
}
// Give the new dirs the same perms as wp-content.
$stat = stat ( ABSPATH . 'wp-content' );
$dir_perms = $stat [ 'mode' ] & 0000777 ; // Get the permission bits.
if ( ! file_exists ( ABSPATH . $this -> backup_dir ) ) {
if ( @ mkdir ( ABSPATH . $this -> backup_dir ) ) {
@ chmod ( ABSPATH . $this -> backup_dir , $dir_perms );
} else {
2005-11-30 14:39:19 -05:00
echo '<div class="updated error"><p align="center">' . __ ( 'WARNING: Your wp-content directory is <strong>NOT</strong> writable! We can not create the backup directory.' ) . '<br />' . ABSPATH . $this -> backup_dir . " </p></div> " ;
2005-11-18 18:43:41 -05:00
$WHOOPS = TRUE ;
}
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( ! is_writable ( ABSPATH . $this -> backup_dir ) ) {
2005-11-30 14:39:19 -05:00
echo '<div class="updated error"><p align="center">' . __ ( 'WARNING: Your backup directory is <strong>NOT</strong> writable! We can not create the backup directory.' ) . '<br />' . ABSPATH . " </p></div> " ;
2005-11-18 18:43:41 -05:00
}
if ( ! file_exists ( ABSPATH . $this -> backup_dir . 'index.php' ) ) {
@ touch ( ABSPATH . $this -> backup_dir . " index.php " );
}
echo " <div class='wrap'> " ;
2005-11-30 14:39:19 -05:00
echo '<h2>' . __ ( 'Backup' ) . '</h2>' ;
echo '<fieldset class="options"><legend>' . __ ( 'Tables' ) . '</legend>' ;
2005-11-18 18:43:41 -05:00
echo '<form method="post">' ;
echo '<table align="center" cellspacing="5" cellpadding="5"><tr><td width="50%" align="left" class="alternate" valign="top">' ;
2005-12-02 12:35:36 -05:00
echo __ ( 'These core WordPress tables will always be backed up:' ) . '<br /><ul>' ;
2005-11-18 18:43:41 -05:00
foreach ( $wp_backup_default_tables as $table ) {
echo " <li><input type='hidden' name='core_tables[]' value=' $table ' /> $table </li> " ;
}
echo '</ul></td><td width="50%" align="left" valign="top">' ;
if ( count ( $other_tables ) > 0 ) {
2005-12-02 12:35:36 -05:00
echo __ ( 'You may choose to include any of the following tables:' ) . ' <br />' ;
2005-11-18 18:43:41 -05:00
foreach ( $other_tables as $table ) {
echo " <label style= \" display:block; \" ><input type='checkbox' name='other_tables[]' value=' { $table } ' /> { $table } </label> " ;
}
}
echo '</tr></table></fieldset>' ;
2005-11-30 14:39:19 -05:00
echo '<fieldset class="options"><legend>' . __ ( 'Backup Options' ) . '</legend>' ;
2005-12-02 12:35:36 -05:00
echo __ ( 'What to do with the backup file:' ) . " <br /> " ;
2005-11-30 14:39:19 -05:00
echo '<label style="display:block;"><input type="radio" name="deliver" value="none" /> ' . __ ( 'Save to server' ) . " ( { $this -> backup_dir } )</label> " ;
echo '<label style="display:block;"><input type="radio" checked="checked" name="deliver" value="http" /> ' . __ ( 'Download to your computer' ) . '</label>' ;
2005-11-18 18:43:41 -05:00
echo '<div><input type="radio" name="deliver" id="do_email" value="smtp" /> ' ;
2005-12-02 13:00:36 -05:00
echo '<label for="do_email">' . __ ( 'Email backup to:' ) . '</label><input type="text" name="backup_recipient" size="20" value="' . get_settings ( 'admin_email' ) . '" />' ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
// 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 )) {
2006-02-12 02:53:23 -05:00
$core_size += $table_size ;
2005-11-18 18:43:41 -05:00
}
$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 ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
if ( ! $WHOOPS ) {
echo '<input type="hidden" name="do_backup" id="do_backup" value="backup" /></div>' ;
2005-11-30 14:39:19 -05:00
echo '<p class="submit"><input type="submit" name="submit" onclick="document.getElementById(\'do_backup\').value=\'fragments\';" value="' . __ ( 'Backup' ) . '!" / ></p>' ;
2005-11-18 18:43:41 -05:00
} else {
2005-11-30 14:39:19 -05:00
echo '<p class="alternate">' . __ ( 'WARNING: Your backup directory is <strong>NOT</strong> writable!' ) . '</p>' ;
2005-11-18 18:43:41 -05:00
}
echo '</fieldset>' ;
echo '</form>' ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
// this stuff only displays if wp_cron is installed
if ( function_exists ( 'wp_cron_init' )) {
2005-11-30 14:39:19 -05:00
echo '<fieldset class="options"><legend>' . __ ( 'Scheduled Backup' ) . '</legend>' ;
2005-11-18 18:43:41 -05:00
$datetime = get_settings ( 'date_format' ) . ' @ ' . get_settings ( 'time_format' );
2005-11-30 14:39:19 -05:00
echo '<p>' . __ ( 'Last WP-Cron Daily Execution' ) . ': ' . date ( $datetime , get_option ( 'wp_cron_daily_lastrun' )) . '<br />' ;
echo __ ( 'Next WP-Cron Daily Execution' ) . ': ' . date ( $datetime , ( get_option ( 'wp_cron_daily_lastrun' ) + 86400 )) . '</p>' ;
2005-11-18 18:43:41 -05:00
echo '<form method="post">' ;
echo '<table width="100%" callpadding="5" cellspacing="5">' ;
echo '<tr><td align="center">' ;
2005-11-30 14:39:19 -05:00
echo __ ( 'Schedule: ' );
2005-11-18 18:43:41 -05:00
$wp_cron_backup_schedule = get_option ( 'wp_cron_backup_schedule' );
2005-11-30 14:39:19 -05:00
$schedule = array ( 0 => __ ( 'None' ), 1 => __ ( 'Daily' ));
2005-11-18 18:43:41 -05:00
foreach ( $schedule as $value => $name ) {
echo ' <input type="radio" name="cron_schedule"' ;
if ( $wp_cron_backup_schedule == $value ) {
echo ' checked="checked" ' ;
}
2005-11-30 14:39:19 -05:00
echo 'value="' . $value . '" /> ' . __ ( $name );
2005-11-18 18:43:41 -05:00
}
echo '</td><td align="center">' ;
$cron_recipient = get_option ( 'wp_cron_backup_recipient' );
if ( ! is_email ( $cron_recipient )) {
$cron_recipient = get_settings ( 'admin_email' );
}
2005-12-02 12:35:36 -05:00
echo __ ( 'Email backup to:' ) . ' <input type="text" name="cron_backup_recipient" size="20" value="' . $cron_recipient . '" />' ;
2005-11-18 18:43:41 -05:00
echo '</td></tr>' ;
$cron_tables = get_option ( 'wp_cron_backup_tables' );
if ( ! is_array ( $cron_tables )) {
$cron_tables = array ();
}
if ( count ( $other_tables ) > 0 ) {
2005-12-02 12:35:36 -05:00
echo '<tr><td colspan="2" align="left">' . __ ( 'Tables to include:' ) . '<br />' ;
2005-11-18 18:43:41 -05:00
foreach ( $other_tables as $table ) {
echo '<input type="checkbox" ' ;
if ( in_array ( $table , $cron_tables )) {
echo 'checked=checked ' ;
}
echo " name='wp_cron_backup_tables[]' value=' { $table } ' /> { $table } <br /> " ;
}
echo '</td></tr>' ;
}
2005-11-30 14:39:19 -05:00
echo '<tr><td colspan="2" align="center"><input type="hidden" name="wp_cron_backup_options" value="SET" /><input type="submit" name="submit" value="' . __ ( 'Submit' ) . '" /></td></tr></table></form>' ;
2005-11-18 18:43:41 -05:00
echo '</fieldset>' ;
}
// end of wp_cron section
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
echo '</div>' ;
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
} // end wp_backup_menu()
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
/////////////////////////////
function wp_cron_daily () {
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$schedule = intval ( get_option ( 'wp_cron_backup_schedule' ));
if ( 0 == $schedule ) {
// Scheduled backup is disabled
return ;
}
2006-02-12 02:53:23 -05:00
2006-03-03 12:19:05 -05:00
global $wpdb ;
2005-11-18 18:43:41 -05:00
$wp_table_names = explode ( ',' , 'categories,comments,linkcategories,links,options,post2cat,postmeta,posts,users,usermeta' );
2006-03-03 15:36:40 -05:00
$wp_table_names = array_map ( create_function ( '$a' , 'global $wpdb;return "{$wpdb->prefix}{$a}";' ), $wp_table_names );
2005-11-18 18:43:41 -05:00
$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' );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$recipient = get_option ( 'wp_cron_backup_recipient' );
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
$backup_file = $this -> db_backup ( $core_tables , $other_tables );
if ( FALSE !== $backup_file ) {
$this -> deliver_backup ( $backup_file , 'smtp' , $recipient );
}
2006-02-12 02:53:23 -05:00
2005-11-18 18:43:41 -05:00
return ;
} // wp_cron_db_backup
}
$mywpdbbackup = new wpdbBackup ();
2005-12-02 12:35:36 -05:00
?>