wp/wp-content/plugins/wp-db-backup/wp-db-backup.php
changeset 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
-1:000000000000 0:d970ebf37754
       
     1 <?php
       
     2 /*
       
     3 Plugin Name: WordPress Database Backup
       
     4 Plugin URI: http://austinmatzko.com/wordpress-plugins/wp-db-backup/
       
     5 Description: On-demand backup of your WordPress database. Navigate to <a href="edit.php?page=wp-db-backup">Tools &rarr; Backup</a> to get started.
       
     6 Author: Austin Matzko 
       
     7 Author URI: http://austinmatzko.com/
       
     8 Version: 2.2.4
       
     9 
       
    10 Copyright 2013  Austin Matzko  (email : austin at pressedcode.com)
       
    11 
       
    12     This program is free software; you can redistribute it and/or modify
       
    13     it under the terms of the GNU General Public License as published by
       
    14     the Free Software Foundation; either version 2 of the License, or
       
    15     (at your option) any later version.
       
    16 
       
    17     This program is distributed in the hope that it will be useful,
       
    18     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    20     GNU General Public License for more details.
       
    21 
       
    22     You should have received a copy of the GNU General Public License
       
    23     along with this program; if not, write to the Free Software
       
    24     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
       
    25 */
       
    26 
       
    27 /**
       
    28  * Change WP_BACKUP_DIR if you want to
       
    29  * use a different backup location
       
    30  */
       
    31 
       
    32 if ( ! defined('ABSPATH') ) {
       
    33 	die('Please do not load this file directly.');
       
    34 }
       
    35 
       
    36 $rand = substr( md5( md5( DB_PASSWORD ) ), -5 );
       
    37 global $wpdbb_content_dir, $wpdbb_content_url, $wpdbb_plugin_dir;
       
    38 $wpdbb_content_dir = ( defined('WP_CONTENT_DIR') ) ? WP_CONTENT_DIR : ABSPATH . 'wp-content';
       
    39 $wpdbb_content_url = ( defined('WP_CONTENT_URL') ) ? WP_CONTENT_URL : get_option('siteurl') . '/wp-content';
       
    40 $wpdbb_plugin_dir = ( defined('WP_PLUGIN_DIR') ) ? WP_PLUGIN_DIR : $wpdbb_content_dir . '/plugins';
       
    41 
       
    42 if ( ! defined('WP_BACKUP_DIR') ) {
       
    43 	define('WP_BACKUP_DIR', $wpdbb_content_dir . '/backup-' . $rand . '/');
       
    44 }
       
    45 
       
    46 if ( ! defined('WP_BACKUP_URL') ) {
       
    47 	define('WP_BACKUP_URL', $wpdbb_content_url . '/backup-' . $rand . '/');
       
    48 }
       
    49 
       
    50 if ( ! defined('ROWS_PER_SEGMENT') ) {
       
    51 	define('ROWS_PER_SEGMENT', 100);
       
    52 }
       
    53 
       
    54 /** 
       
    55  * Set MOD_EVASIVE_OVERRIDE to true 
       
    56  * and increase MOD_EVASIVE_DELAY 
       
    57  * if the backup stops prematurely.
       
    58  */
       
    59 // define('MOD_EVASIVE_OVERRIDE', false);
       
    60 if ( ! defined('MOD_EVASIVE_DELAY') ) {
       
    61 	define('MOD_EVASIVE_DELAY', '500');
       
    62 }
       
    63 
       
    64 class wpdbBackup {
       
    65 
       
    66 	var $backup_complete = false;
       
    67 	var $backup_file = '';
       
    68 	var $backup_filename;
       
    69 	var $core_table_names = array();
       
    70 	var $errors = array();
       
    71 	var $basename;
       
    72 	var $page_url;
       
    73 	var $referer_check_key;
       
    74 	var $version = '2.1.5-alpha';
       
    75 
       
    76 	function module_check() {
       
    77 		$mod_evasive = false;
       
    78 		if ( defined( 'MOD_EVASIVE_OVERRIDE' ) && true === MOD_EVASIVE_OVERRIDE ) return true;
       
    79 		if ( ! defined( 'MOD_EVASIVE_OVERRIDE' ) || false === MOD_EVASIVE_OVERRIDE ) return false;
       
    80 		if ( function_exists('apache_get_modules') ) 
       
    81 			foreach( (array) apache_get_modules() as $mod ) 
       
    82 				if ( false !== strpos($mod,'mod_evasive') || false !== strpos($mod,'mod_dosevasive') )
       
    83 					return true;
       
    84 		return false;
       
    85 	}
       
    86 
       
    87 	function wpdbBackup() {
       
    88 		global $table_prefix, $wpdb;
       
    89 		add_action('wp_ajax_save_backup_time', array(&$this, 'save_backup_time'));
       
    90 		add_action('init', array(&$this, 'init_textdomain'));
       
    91 		add_action('init', array(&$this, 'set_page_url'));
       
    92 		add_action('load-update-core.php', array(&$this, 'update_notice_action'));
       
    93 		add_action('wp_db_backup_cron', array(&$this, 'cron_backup'));
       
    94 		add_action('wp_cron_daily', array(&$this, 'wp_cron_daily'));
       
    95 		add_filter('cron_schedules', array(&$this, 'add_sched_options'));
       
    96 		add_filter('wp_db_b_schedule_choices', array(&$this, 'schedule_choices'));
       
    97 		
       
    98 		$table_prefix = ( isset( $table_prefix ) ) ? $table_prefix : $wpdb->prefix;
       
    99 		$datum = date("Ymd_B");
       
   100 		$this->backup_filename = DB_NAME . "_$table_prefix$datum.sql";
       
   101 
       
   102 		$possible_names = array(
       
   103 			'categories',
       
   104 			'commentmeta',
       
   105 			'comments',
       
   106 			'link2cat',
       
   107 			'linkcategories',
       
   108 			'links',
       
   109 			'options',
       
   110 			'post2cat',
       
   111 			'postmeta',
       
   112 			'posts',
       
   113 			'terms',
       
   114 			'term_taxonomy',
       
   115 			'term_relationships',
       
   116 			'users',
       
   117 			'usermeta',
       
   118 		);
       
   119 
       
   120 		foreach( $possible_names as $name ) {
       
   121 			if ( isset( $wpdb->{$name} ) ) {
       
   122 				$this->core_table_names[] = $wpdb->{$name};
       
   123 			}
       
   124 		}
       
   125 	
       
   126 		$this->backup_dir = trailingslashit(apply_filters('wp_db_b_backup_dir', WP_BACKUP_DIR));
       
   127 		$this->basename = 'wp-db-backup';
       
   128 	
       
   129 		$this->referer_check_key = $this->basename . '-download_' . DB_NAME;
       
   130 		if (isset($_POST['do_backup'])) {
       
   131 			$this->wp_secure('fatal');
       
   132 			check_admin_referer($this->referer_check_key);
       
   133 			$this->can_user_backup('main');
       
   134 			// save exclude prefs
       
   135 
       
   136 			$exc_revisions = isset( $_POST['exclude-revisions'] ) ? (array) $_POST['exclude-revisions'] : array();
       
   137 			$exc_spam = isset( $_POST['exclude-spam'] ) ? (array) $_POST['exclude-spam'] : array();
       
   138 			update_option('wp_db_backup_excs', array('revisions' => $exc_revisions, 'spam' => $exc_spam));
       
   139 			switch($_POST['do_backup']) {
       
   140 			case 'backup':
       
   141 				add_action('init', array(&$this, 'perform_backup'));
       
   142 				break;
       
   143 			case 'fragments':
       
   144 				add_action('admin_menu', array(&$this, 'fragment_menu'));
       
   145 				break;				
       
   146 			}
       
   147 		} elseif (isset($_GET['fragment'] )) {
       
   148 			$this->can_user_backup('frame');
       
   149 			add_action('init', array(&$this, 'init'));
       
   150 		} elseif (isset($_GET['backup'] )) {
       
   151 			$this->can_user_backup();
       
   152 			add_action('init', array(&$this, 'init'));
       
   153 		} else {
       
   154 			add_action('admin_menu', array(&$this, 'admin_menu'));
       
   155 		}
       
   156 	}
       
   157 	
       
   158 	function init() {
       
   159 		$this->can_user_backup();
       
   160 		if (isset($_GET['backup'])) {
       
   161 			$via = isset($_GET['via']) ? $_GET['via'] : 'http';
       
   162 			
       
   163 			$this->backup_file = $_GET['backup'];
       
   164 			$this->validate_file($this->backup_file);
       
   165 
       
   166 			switch($via) {
       
   167 			case 'smtp':
       
   168 			case 'email':
       
   169 				$success = $this->deliver_backup($this->backup_file, 'smtp', $_GET['recipient'], 'frame');
       
   170 				$this->error_display( 'frame' );
       
   171 				if ( $success ) {
       
   172 					echo '
       
   173 						<!-- ' . $via . ' -->
       
   174 						<script type="text/javascript"><!--\\
       
   175 					';
       
   176 					echo '
       
   177 						alert("' . __('Backup Complete!','wp-db-backup') . '");
       
   178 						window.onbeforeunload = null; 
       
   179 						</script>
       
   180 					';
       
   181 				}
       
   182 				break;
       
   183 			default:
       
   184 				$success = $this->deliver_backup($this->backup_file, $via);
       
   185 				echo $this->error_display( 'frame', false );
       
   186 				
       
   187 				if ( $success ) {
       
   188 					echo '
       
   189 					<script type="text/javascript">
       
   190 						window.parent.setProgress("' . __('Backup Complete!','wp-db-backup') . '");
       
   191 					</script>
       
   192 					';
       
   193 				}
       
   194 			}
       
   195 			exit;
       
   196 		}
       
   197 		if (isset($_GET['fragment'] )) {
       
   198 			list($table, $segment, $filename) = explode(':', $_GET['fragment']);
       
   199 			$this->validate_file($filename);
       
   200 			$this->backup_fragment($table, $segment, $filename);
       
   201 		}
       
   202 
       
   203 		die();
       
   204 	}
       
   205 
       
   206 	function init_textdomain() {
       
   207 		load_plugin_textdomain('wp-db-backup', str_replace(ABSPATH, '', dirname(__FILE__)), dirname(plugin_basename(__FILE__)));
       
   208 	}
       
   209 
       
   210 	function set_page_url() {
       
   211 		$query_args = array( 'page' => $this->basename );
       
   212 		if ( function_exists('wp_create_nonce') )
       
   213 			$query_args = array_merge( $query_args, array('_wpnonce' => wp_create_nonce($this->referer_check_key)) );
       
   214 		$base = ( function_exists('site_url') ) ? site_url('', 'admin') : get_option('siteurl');
       
   215 		$this->page_url = add_query_arg( $query_args, $base . '/wp-admin/edit.php');
       
   216 	}
       
   217 
       
   218 	/*
       
   219 	 * Add a link to back up your database when doing a core upgrade 
       
   220 	 */
       
   221 	function update_notice_action() {
       
   222 		if ( 'upgrade-core' == $_REQUEST['action'] ) :
       
   223 			ob_start(array(&$this, 'update_notice'));
       
   224 			add_action('admin_footer', create_function('', 'ob_end_flush();'));
       
   225 		endif;
       
   226 	}
       
   227 		function update_notice($text = '') {
       
   228 			$pattern = '#(<a href\="' . __('http://codex.wordpress.org/WordPress_Backups') . '">.*?</p>)#';
       
   229 			$replace = '$1' . "\n<p>" . sprintf(__('Click <a href="%s" target="_blank">here</a> to back up your database using the WordPress Database Backup plugin. <strong>Note:</strong> WordPress Database Backup does <em>not</em> back up your files, just your database.', 'wp-db-backup'), 'tools.php?page=wp-db-backup') . "</p>\n"; 
       
   230 			$text = preg_replace($pattern, $replace, $text);
       
   231 			return $text;
       
   232 		}
       
   233 
       
   234 	function build_backup_script() {
       
   235 		global $table_prefix, $wpdb;
       
   236 	
       
   237 		echo "<div class='wrap'>";
       
   238 		echo 	'<fieldset class="options"><legend>' . __('Progress','wp-db-backup') . '</legend>
       
   239 			<p><strong>' .
       
   240 				__('DO NOT DO THE FOLLOWING AS IT WILL CAUSE YOUR BACKUP TO FAIL:','wp-db-backup').
       
   241 			'</strong></p>
       
   242 			<ol>
       
   243 				<li>'.__('Close this browser','wp-db-backup').'</li>
       
   244 				<li>'.__('Reload this page','wp-db-backup').'</li>
       
   245 				<li>'.__('Click the Stop or Back buttons in your browser','wp-db-backup').'</li>
       
   246 			</ol>
       
   247 			<p><strong>' . __('Progress:','wp-db-backup') . '</strong></p>
       
   248 			<div id="meterbox" style="height:11px;width:80%;padding:3px;border:1px solid #659fff;"><div id="meter" style="color:#fff;height:11px;line-height:11px;background-color:#659fff;width:0%;text-align:center;font-size:6pt;">&nbsp;</div></div>
       
   249 			<div id="progress_message"></div>
       
   250 			<div id="errors"></div>
       
   251 			</fieldset>
       
   252 			<iframe id="backuploader" src="about:blank" style="visibility:hidden;border:none;height:1em;width:1px;"></iframe>
       
   253 			<script type="text/javascript">
       
   254 			//<![CDATA[
       
   255 			window.onbeforeunload = function() {
       
   256 				return "' . __('Navigating away from this page will cause your backup to fail.', 'wp-db-backup') . '";
       
   257 			}
       
   258 			function setMeter(pct) {
       
   259 				var meter = document.getElementById("meter");
       
   260 				meter.style.width = pct + "%";
       
   261 				meter.innerHTML = Math.floor(pct) + "%";
       
   262 			}
       
   263 			function setProgress(str) {
       
   264 				var progress = document.getElementById("progress_message");
       
   265 				progress.innerHTML = str;
       
   266 			}
       
   267 			function addError(str) {
       
   268 				var errors = document.getElementById("errors");
       
   269 				errors.innerHTML = errors.innerHTML + str + "<br />";
       
   270 			}
       
   271 
       
   272 			function backup(table, segment) {
       
   273 				var fram = document.getElementById("backuploader");
       
   274 				fram.src = "' . $this->page_url . '&fragment=" + table + ":" + segment + ":' . $this->backup_filename . ':";
       
   275 			}
       
   276 			
       
   277 			var curStep = 0;
       
   278 			
       
   279 			function nextStep() {
       
   280 				backupStep(curStep);
       
   281 				curStep++;
       
   282 			}
       
   283 			
       
   284 			function finishBackup() {
       
   285 				var fram = document.getElementById("backuploader");				
       
   286 				setMeter(100);
       
   287 		';
       
   288 
       
   289 		$download_uri = add_query_arg('backup', $this->backup_filename, $this->page_url);
       
   290 		switch($_POST['deliver']) {
       
   291 		case 'http':
       
   292 			echo '
       
   293 				setProgress("' . __('Preparing download.','wp-db-backup') . '");
       
   294 				window.onbeforeunload = null; 
       
   295 				fram.src = "' . $download_uri . '";
       
   296 				
       
   297 				setTimeout( function() {
       
   298 					var secondFrame = document.createElement("iframe");				
       
   299 					fram.parentNode.insertBefore(secondFrame, fram);
       
   300 					secondFrame.src = "' . $download_uri . '&download-retry=1";
       
   301 				}, 30000 );
       
   302 			';
       
   303 			break;
       
   304 		case 'smtp':
       
   305 			if ( get_option('wpdb_backup_recip') != $_POST['backup_recipient'] ) {
       
   306 				update_option('wpdb_backup_recip', $_POST['backup_recipient'] );
       
   307 			}
       
   308 			echo '
       
   309 				setProgress("' . sprintf(__('Your backup has been emailed to %s','wp-db-backup'), $_POST['backup_recipient']) . '");
       
   310 				window.onbeforeunload = null; 
       
   311 				fram.src = "' . $download_uri . '&via=email&recipient=' . $_POST['backup_recipient'] . '";
       
   312 			';
       
   313 			break;
       
   314 		default:
       
   315 			echo '
       
   316 				setProgress("' . __('Backup Complete!','wp-db-backup') . '");
       
   317 				window.onbeforeunload = null; 
       
   318 			';
       
   319 		}
       
   320 		
       
   321 		echo '
       
   322 			}
       
   323 			
       
   324 			function backupStep(step) {
       
   325 				switch(step) {
       
   326 				case 0: backup("", 0); break;
       
   327 		';
       
   328 		
       
   329 		$also_backup = array();
       
   330 		if (isset($_POST['other_tables'])) {
       
   331 			$also_backup = $_POST['other_tables'];
       
   332 		} else {
       
   333 			$also_backup = array();
       
   334 		}
       
   335 		$core_tables = $_POST['core_tables'];
       
   336 		$tables = array_merge($core_tables, $also_backup);
       
   337 		$step_count = 1;
       
   338 		foreach ($tables as $table) {
       
   339 			$rec_count = $wpdb->get_var("SELECT count(*) FROM {$table}");
       
   340 			$rec_segments = ceil($rec_count / ROWS_PER_SEGMENT);
       
   341 			$table_count = 0;
       
   342 			if ( $this->module_check() ) {
       
   343 				$delay = "setTimeout('";
       
   344 				$delay_time = "', " . (int) MOD_EVASIVE_DELAY . ")";
       
   345 			}
       
   346 			else { $delay = $delay_time = ''; }
       
   347 			do {
       
   348 				echo "case {$step_count}: {$delay}backup(\"{$table}\", {$table_count}){$delay_time}; break;\n";
       
   349 				$step_count++;
       
   350 				$table_count++;
       
   351 			} while($table_count < $rec_segments);
       
   352 			echo "case {$step_count}: {$delay}backup(\"{$table}\", -1){$delay_time}; break;\n";
       
   353 			$step_count++;
       
   354 		}
       
   355 		echo "case {$step_count}: finishBackup(); break;";
       
   356 		
       
   357 		echo '
       
   358 				}
       
   359 				if(step != 0) setMeter(100 * step / ' . $step_count . ');
       
   360 			}
       
   361 
       
   362 			nextStep();
       
   363 			// ]]>
       
   364 			</script>
       
   365 	</div>
       
   366 		';
       
   367 		$this->backup_menu();
       
   368 	}
       
   369 
       
   370 	function backup_fragment($table, $segment, $filename) {
       
   371 		global $table_prefix, $wpdb;
       
   372 			
       
   373 		echo "$table:$segment:$filename";
       
   374 		
       
   375 		if($table == '') {
       
   376 			$msg = __('Creating backup file...','wp-db-backup');
       
   377 		} else {
       
   378 			if($segment == -1) {
       
   379 				$msg = sprintf(__('Finished backing up table \\"%s\\".','wp-db-backup'), $table);
       
   380 			} else {
       
   381 				$msg = sprintf(__('Backing up table \\"%s\\"...','wp-db-backup'), $table);
       
   382 			}
       
   383 		}
       
   384 		
       
   385 		if (is_writable($this->backup_dir)) {
       
   386 			$this->fp = $this->open($this->backup_dir . $filename, 'a');
       
   387 			if(!$this->fp) {
       
   388 				$this->error(__('Could not open the backup file for writing!','wp-db-backup'));
       
   389 				$this->error(array('loc' => 'frame', 'kind' => 'fatal', 'msg' =>  __('The backup file could not be saved.  Please check the permissions for writing to your backup directory and try again.','wp-db-backup')));
       
   390 			}
       
   391 			else {
       
   392 				if($table == '') {		
       
   393 					//Begin new backup of MySql
       
   394 					$this->stow("# " . __('WordPress MySQL database backup','wp-db-backup') . "\n");
       
   395 					$this->stow("#\n");
       
   396 					$this->stow("# " . sprintf(__('Generated: %s','wp-db-backup'),date("l j. F Y H:i T")) . "\n");
       
   397 					$this->stow("# " . sprintf(__('Hostname: %s','wp-db-backup'),DB_HOST) . "\n");
       
   398 					$this->stow("# " . sprintf(__('Database: %s','wp-db-backup'),$this->backquote(DB_NAME)) . "\n");
       
   399 					$this->stow("# --------------------------------------------------------\n");
       
   400 				} else {
       
   401 					if($segment == 0) {
       
   402 						// Increase script execution time-limit to 15 min for every table.
       
   403 						if ( !ini_get('safe_mode')) @set_time_limit(15*60);
       
   404 						// Create the SQL statements
       
   405 						$this->stow("# --------------------------------------------------------\n");
       
   406 						$this->stow("# " . sprintf(__('Table: %s','wp-db-backup'),$this->backquote($table)) . "\n");
       
   407 						$this->stow("# --------------------------------------------------------\n");
       
   408 					}			
       
   409 					$this->backup_table($table, $segment);
       
   410 				}
       
   411 			}
       
   412 		} else {
       
   413 			$this->error(array('kind' => 'fatal', 'loc' => 'frame', 'msg' => __('The backup directory is not writeable!  Please check the permissions for writing to your backup directory and try again.','wp-db-backup')));
       
   414 		}
       
   415 
       
   416 		if($this->fp) $this->close($this->fp);
       
   417 		
       
   418 		$this->error_display('frame');
       
   419 
       
   420 		echo '<script type="text/javascript"><!--//
       
   421 		var msg = "' . $msg . '";
       
   422 		window.parent.setProgress(msg);
       
   423 		window.parent.nextStep();
       
   424 		//--></script>
       
   425 		';
       
   426 		die();
       
   427 	}
       
   428 
       
   429 	function perform_backup() {
       
   430 		// are we backing up any other tables?
       
   431 		$also_backup = array();
       
   432 		if (isset($_POST['other_tables']))
       
   433 			$also_backup = $_POST['other_tables'];
       
   434 		$core_tables = $_POST['core_tables'];
       
   435 		$this->backup_file = $this->db_backup($core_tables, $also_backup);
       
   436 		if (false !== $this->backup_file) {
       
   437 			if ('smtp' == $_POST['deliver']) {
       
   438 				$this->deliver_backup($this->backup_file, $_POST['deliver'], $_POST['backup_recipient'], 'main');
       
   439 				if ( get_option('wpdb_backup_recip') != $_POST['backup_recipient'] ) {
       
   440 					update_option('wpdb_backup_recip', $_POST['backup_recipient'] );
       
   441 				}
       
   442 				wp_redirect($this->page_url);
       
   443 			} elseif ('http' == $_POST['deliver']) {
       
   444 				$download_uri = add_query_arg('backup',$this->backup_file,$this->page_url);
       
   445 				wp_redirect($download_uri); 
       
   446 				exit;
       
   447 			}
       
   448 			// we do this to say we're done.
       
   449 			$this->backup_complete = true;
       
   450 		}
       
   451 	}
       
   452 
       
   453 	function admin_header() {
       
   454 		?>
       
   455 		<script type="text/javascript">
       
   456 		//<![CDATA[
       
   457 		if ( 'undefined' != typeof addLoadEvent ) {
       
   458 			addLoadEvent(function() {
       
   459 				var t = {'extra-tables-list':{name: 'other_tables[]'}, 'include-tables-list':{name: 'wp_cron_backup_tables[]'}};
       
   460 
       
   461 				for ( var k in t ) {
       
   462 					t[k].s = null;
       
   463 					var d = document.getElementById(k);
       
   464 					if ( ! d )
       
   465 						continue;
       
   466 					var ul = d.getElementsByTagName('ul').item(0);
       
   467 					if ( ul ) {
       
   468 						var lis = ul.getElementsByTagName('li');
       
   469 						if ( 2 < lis.length ) {
       
   470 							var text = document.createElement('p');
       
   471 							text.className = 'instructions';
       
   472 							text.innerHTML = '<?php _e('Click and hold down <code>[SHIFT]</code> to toggle multiple checkboxes', 'wp-db-backup'); ?>';
       
   473 							ul.parentNode.insertBefore(text, ul);
       
   474 						}
       
   475 					}
       
   476 					t[k].p = d.getElementsByTagName("input");
       
   477 					for(var i=0; i < t[k].p.length; i++) {
       
   478 						if(t[k].name == t[k].p[i].getAttribute('name')) {
       
   479 							t[k].p[i].id = k + '-table-' + i;
       
   480 							t[k].p[i].onkeyup = t[k].p[i].onclick = function(e) {
       
   481 								e = e ? e : event;
       
   482 								if ( 16  == e.keyCode ) 
       
   483 									return;
       
   484 								var match = /([\w-]*)-table-(\d*)/.exec(this.id);
       
   485 								var listname = match[1];
       
   486 								var that = match[2];
       
   487 								if ( null === t[listname].s )
       
   488 									t[listname].s = that;
       
   489 								else if ( e.shiftKey ) {
       
   490 									var start = Math.min(that, t[listname].s) + 1;
       
   491 									var end = Math.max(that, t[listname].s);
       
   492 									for( var j=start; j < end; j++)
       
   493 										t[listname].p[j].checked = t[listname].p[j].checked ? false : true;
       
   494 									t[listname].s = null;
       
   495 								}
       
   496 							}
       
   497 						}
       
   498 					}
       
   499 				}
       
   500 
       
   501 				<?php if ( function_exists('wp_schedule_event') ) : // needs to be at least WP 2.1 for ajax ?>
       
   502 				if ( 'undefined' == typeof XMLHttpRequest ) 
       
   503 					var xml = new ActiveXObject( navigator.userAgent.indexOf('MSIE 5') >= 0 ? 'Microsoft.XMLHTTP' : 'Msxml2.XMLHTTP' );
       
   504 				else
       
   505 					var xml = new XMLHttpRequest();
       
   506 
       
   507 				var initTimeChange = function() {
       
   508 					var timeWrap = document.getElementById('backup-time-wrap');
       
   509 					var backupTime = document.getElementById('next-backup-time');
       
   510 					if ( !! timeWrap && !! backupTime && ( 1 == <?php
       
   511 						echo (int) ( 'en' == strtolower( substr( get_locale(), 0, 2 ) ) );	
       
   512 					?> ) ) {
       
   513 						var span = document.createElement('span');
       
   514 						span.className = 'submit';
       
   515 						span.id = 'change-wrap';
       
   516 						span.innerHTML = '<input type="submit" id="change-backup-time" name="change-backup-time" value="<?php _e('Change','wp-db-backup'); ?>" />';
       
   517 						timeWrap.appendChild(span);
       
   518 						backupTime.ondblclick = function(e) { span.parentNode.removeChild(span); clickTime(e, backupTime); };
       
   519 						span.onclick = function(e) { span.parentNode.removeChild(span); clickTime(e, backupTime); };
       
   520 					}
       
   521 				}
       
   522 
       
   523 				var clickTime = function(e, backupTime) {
       
   524 					var tText = backupTime.innerHTML;
       
   525 					backupTime.innerHTML = '<input type="text" value="' + tText + '" name="backup-time-text" id="backup-time-text" /> <span class="submit"><input type="submit" name="save-backup-time" id="save-backup-time" value="<?php _e('Save', 'wp-db-backup'); ?>" /></span>';
       
   526 					backupTime.ondblclick = null;
       
   527 					var mainText = document.getElementById('backup-time-text');
       
   528 					mainText.focus();
       
   529 					var saveTButton = document.getElementById('save-backup-time');
       
   530 					if ( !! saveTButton )
       
   531 						saveTButton.onclick = function(e) { saveTime(backupTime, mainText); return false; };
       
   532 					if ( !! mainText )
       
   533 						mainText.onkeydown = function(e) { 
       
   534 							e = e || window.event;
       
   535 							if ( 13 == e.keyCode ) {
       
   536 								saveTime(backupTime, mainText);
       
   537 								return false;
       
   538 							}
       
   539 						}
       
   540 				}
       
   541 
       
   542 				var saveTime = function(backupTime, mainText) {
       
   543 					var tVal = mainText.value;
       
   544 
       
   545 					xml.open('POST', 'admin-ajax.php', true);
       
   546 					xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
       
   547 					if ( xml.overrideMimeType )
       
   548 						xml.setRequestHeader('Connection', 'close');
       
   549 					xml.send('action=save_backup_time&_wpnonce=<?php echo wp_create_nonce($this->referer_check_key); ?>&backup-time='+tVal);
       
   550 					xml.onreadystatechange = function() {
       
   551 						if ( 4 == xml.readyState && '0' != xml.responseText ) {
       
   552 							backupTime.innerHTML = xml.responseText;
       
   553 							initTimeChange();
       
   554 						}
       
   555 					}
       
   556 				}
       
   557 
       
   558 				initTimeChange();
       
   559 				<?php endif; // wp_schedule_event exists ?>
       
   560 			});
       
   561 		}
       
   562 		//]]>
       
   563 		</script>
       
   564 		<style type="text/css">
       
   565 			.wp-db-backup-updated {
       
   566 				margin-top: 1em;
       
   567 			}
       
   568 
       
   569 			fieldset.options {
       
   570 				border: 1px solid;
       
   571 				margin-top: 1em;
       
   572 				padding: 1em;
       
   573 				-moz-border-radius: 8px;
       
   574 				-khtml-border-radius: 8px;
       
   575 				-webkit-border-top-left-radius: 8px;
       
   576 				-webkit-border-top-right-radius: 8px;
       
   577 				-webkit-border-bottom-left-radius: 8px;
       
   578 				-webkit-border-bottom-right-radius: 8px;
       
   579 				border-radius: 8px;
       
   580 			}
       
   581 				fieldset.options div.tables-list {
       
   582 					float: left;
       
   583 					padding: 1em;
       
   584 				}
       
   585 
       
   586 				fieldset.options input {
       
   587 				}
       
   588 
       
   589 				fieldset.options legend {
       
   590 					font-size: larger;
       
   591 					font-weight: bold;
       
   592 					margin-bottom: .5em;
       
   593 					padding: 1em;
       
   594 				}
       
   595 		
       
   596 				fieldset.options .instructions {
       
   597 					font-size: smaller;
       
   598 				}
       
   599 
       
   600 				fieldset.options ul {
       
   601 					list-style-type: none;
       
   602 				}
       
   603 					fieldset.options li {
       
   604 						text-align: left;
       
   605 					}
       
   606 
       
   607 				fieldset.options .submit {
       
   608 					border-top: none;
       
   609 				}
       
   610 		</style>
       
   611 		<?php 
       
   612 	}
       
   613 
       
   614 	function admin_load() {
       
   615 		add_action('admin_head', array(&$this, 'admin_header'));
       
   616 	}
       
   617 
       
   618 	function admin_menu() {
       
   619 		$_page_hook = add_management_page(__('Backup','wp-db-backup'), __('Backup','wp-db-backup'), 'import', $this->basename, array(&$this, 'backup_menu'));
       
   620 		add_action('load-' . $_page_hook, array(&$this, 'admin_load'));
       
   621 		if (function_exists('get_current_screen')) {
       
   622 			$screen = convert_to_screen($_page_hook);
       
   623 			if (method_exists($screen,'add_help_tab')) {
       
   624 				$screen->add_help_tab(array(
       
   625 					'title' => __('Backup','wp-db-backup'),
       
   626 					'id' => $_page_hook,
       
   627 					'content' => $this->help_menu(),
       
   628 				));
       
   629 			}
       
   630 		} elseif ( function_exists('add_contextual_help') ) {
       
   631 			$text = $this->help_menu();
       
   632 			add_contextual_help($_page_hook, $text);
       
   633 		}
       
   634 	}
       
   635 
       
   636 	function fragment_menu() {
       
   637 		$page_hook = add_management_page(__('Backup','wp-db-backup'), __('Backup','wp-db-backup'), 'import', $this->basename, array(&$this, 'build_backup_script'));
       
   638 		add_action('load-' . $page_hook, array(&$this, 'admin_load'));
       
   639 	}
       
   640 
       
   641 	/** 
       
   642 	 * Add WP-DB-Backup-specific help options to the 2.7 =< WP contextual help menu
       
   643 	 * @return string The text of the help menu.
       
   644 	 */
       
   645 	function help_menu() {
       
   646 		$text = "\n<a href=\"http://wordpress.org/extend/plugins/wp-db-backup/faq/\" target=\"_blank\">" . __('FAQ', 'wp-db-backup') . '</a>';
       
   647 		return $text;
       
   648 	}
       
   649 
       
   650 	function save_backup_time() {
       
   651 		if ( $this->can_user_backup() ) {
       
   652 			// try to get a time from the input string
       
   653 			$time = strtotime(strval($_POST['backup-time']));
       
   654 			if ( ! empty( $time ) && time() < $time ) {
       
   655 				wp_clear_scheduled_hook( 'wp_db_backup_cron' ); // unschedule previous
       
   656 				$scheds = (array) wp_get_schedules();
       
   657 				$name = get_option('wp_cron_backup_schedule');
       
   658 				if ( 0 != $time ) {
       
   659 					wp_schedule_event($time, $name, 'wp_db_backup_cron');
       
   660 					echo gmdate(get_option('date_format') . ' ' . get_option('time_format'), $time + (get_option('gmt_offset') * 3600));
       
   661 					exit;
       
   662 				}
       
   663 			}
       
   664 		} else {
       
   665 			die(0);
       
   666 		}
       
   667 	}
       
   668 
       
   669 	/**
       
   670 	 * Better addslashes for SQL queries.
       
   671 	 * Taken from phpMyAdmin.
       
   672 	 */
       
   673 	function sql_addslashes($a_string = '', $is_like = false) {
       
   674 		if ($is_like) $a_string = str_replace('\\', '\\\\\\\\', $a_string);
       
   675 		else $a_string = str_replace('\\', '\\\\', $a_string);
       
   676 		return str_replace('\'', '\\\'', $a_string);
       
   677 	} 
       
   678 
       
   679 	/**
       
   680 	 * Add backquotes to tables and db-names in
       
   681 	 * SQL queries. Taken from phpMyAdmin.
       
   682 	 */
       
   683 	function backquote($a_name) {
       
   684 		if (!empty($a_name) && $a_name != '*') {
       
   685 			if (is_array($a_name)) {
       
   686 				$result = array();
       
   687 				reset($a_name);
       
   688 				while(list($key, $val) = each($a_name)) 
       
   689 					$result[$key] = '`' . $val . '`';
       
   690 				return $result;
       
   691 			} else {
       
   692 				return '`' . $a_name . '`';
       
   693 			}
       
   694 		} else {
       
   695 			return $a_name;
       
   696 		}
       
   697 	} 
       
   698 
       
   699 	function open($filename = '', $mode = 'w') {
       
   700 		if ('' == $filename) return false;
       
   701 		$fp = @fopen($filename, $mode);
       
   702 		return $fp;
       
   703 	}
       
   704 
       
   705 	function close($fp) {
       
   706 		fclose($fp);
       
   707 	}
       
   708 
       
   709 	/**
       
   710 	 * Write to the backup file
       
   711 	 * @param string $query_line the line to write
       
   712 	 * @return null
       
   713 	 */
       
   714 	function stow($query_line) {
       
   715 		if(false === @fwrite($this->fp, $query_line))
       
   716 			$this->error(__('There was an error writing a line to the backup script:','wp-db-backup') . '  ' . $query_line . '  ' . $php_errormsg);
       
   717 	}
       
   718 	
       
   719 	/**
       
   720 	 * Logs any error messages
       
   721 	 * @param array $args
       
   722 	 * @return bool
       
   723 	 */
       
   724 	function error($args = array()) {
       
   725 		if ( is_string( $args ) ) 
       
   726 			$args = array('msg' => $args);
       
   727 		$args = array_merge( array('loc' => 'main', 'kind' => 'warn', 'msg' => ''), $args);
       
   728 		$this->errors[$args['kind']][] = $args['msg'];
       
   729 		if ( 'fatal' == $args['kind'] || 'frame' == $args['loc'])
       
   730 			$this->error_display($args['loc']);
       
   731 		return true;
       
   732 	}
       
   733 
       
   734 	/**
       
   735 	 * Displays error messages 
       
   736 	 * @param array $errs
       
   737 	 * @param string $loc
       
   738 	 * @return string
       
   739 	 */
       
   740 	function error_display($loc = 'main', $echo = true) {
       
   741 		$errs = $this->errors;
       
   742 		unset( $this->errors );
       
   743 		if ( ! count($errs) ) return;
       
   744 		$msg = '';
       
   745 		$errs['fatal'] = isset( $errs['fatal'] ) ? (array) $errs['fatal'] : array();
       
   746 		$errs['warn'] = isset( $errs['warn'] ) ? (array) $errs['warn'] : array();
       
   747 		$err_list = array_slice( array_merge( $errs['fatal'], $errs['warn'] ), 0, 10);
       
   748 		if ( 10 == count( $err_list ) )
       
   749 			$err_list[9] = __('Subsequent errors have been omitted from this log.','wp-db-backup');
       
   750 		$wrap = ( 'frame' == $loc ) ? "<script type=\"text/javascript\">\n var msgList = ''; \n %1\$s \n if ( msgList ) alert(msgList); \n </script>" : '%1$s';
       
   751 		$line = ( 'frame' == $loc ) ? 
       
   752 			"try{ window.parent.addError('%1\$s'); } catch(e) { msgList += ' %1\$s';}\n" :
       
   753 			"%1\$s<br />\n";
       
   754 		foreach( (array) $err_list as $err )
       
   755 			$msg .= sprintf($line,str_replace(array("\n","\r"), '', addslashes($err)));
       
   756 		$msg = sprintf($wrap,$msg);
       
   757 		if ( count($errs['fatal'] ) ) {
       
   758 			if ( function_exists('wp_die') && 'frame' != $loc ) wp_die(stripslashes($msg));
       
   759 			else die($msg);
       
   760 		}
       
   761 		else {
       
   762 			if ( $echo ) echo $msg;
       
   763 			else return $msg;
       
   764 		}
       
   765 	}
       
   766 
       
   767 	/**
       
   768 	 * Taken partially from phpMyAdmin and partially from
       
   769 	 * Alain Wolf, Zurich - Switzerland
       
   770 	 * Website: http://restkultur.ch/personal/wolf/scripts/db_backup/
       
   771 	
       
   772 	 * Modified by Scott Merrill (http://www.skippy.net/) 
       
   773 	 * to use the WordPress $wpdb object
       
   774 	 * @param string $table
       
   775 	 * @param string $segment
       
   776 	 * @return void
       
   777 	 */
       
   778 	function backup_table($table, $segment = 'none') {
       
   779 		global $wpdb;
       
   780 
       
   781 		$table_structure = $wpdb->get_results("DESCRIBE $table");
       
   782 		if (! $table_structure) {
       
   783 			$this->error(__('Error getting table details','wp-db-backup') . ": $table");
       
   784 			return false;
       
   785 		}
       
   786 	
       
   787 		if(($segment == 'none') || ($segment == 0)) {
       
   788 			// Add SQL statement to drop existing table
       
   789 			$this->stow("\n\n");
       
   790 			$this->stow("#\n");
       
   791 			$this->stow("# " . sprintf(__('Delete any existing table %s','wp-db-backup'),$this->backquote($table)) . "\n");
       
   792 			$this->stow("#\n");
       
   793 			$this->stow("\n");
       
   794 			$this->stow("DROP TABLE IF EXISTS " . $this->backquote($table) . ";\n");
       
   795 			
       
   796 			// Table structure
       
   797 			// Comment in SQL-file
       
   798 			$this->stow("\n\n");
       
   799 			$this->stow("#\n");
       
   800 			$this->stow("# " . sprintf(__('Table structure of table %s','wp-db-backup'),$this->backquote($table)) . "\n");
       
   801 			$this->stow("#\n");
       
   802 			$this->stow("\n");
       
   803 			
       
   804 			$create_table = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N);
       
   805 			if (false === $create_table) {
       
   806 				$err_msg = sprintf(__('Error with SHOW CREATE TABLE for %s.','wp-db-backup'), $table);
       
   807 				$this->error($err_msg);
       
   808 				$this->stow("#\n# $err_msg\n#\n");
       
   809 			}
       
   810 			$this->stow($create_table[0][1] . ' ;');
       
   811 			
       
   812 			if (false === $table_structure) {
       
   813 				$err_msg = sprintf(__('Error getting table structure of %s','wp-db-backup'), $table);
       
   814 				$this->error($err_msg);
       
   815 				$this->stow("#\n# $err_msg\n#\n");
       
   816 			}
       
   817 		
       
   818 			// Comment in SQL-file
       
   819 			$this->stow("\n\n");
       
   820 			$this->stow("#\n");
       
   821 			$this->stow('# ' . sprintf(__('Data contents of table %s','wp-db-backup'),$this->backquote($table)) . "\n");
       
   822 			$this->stow("#\n");
       
   823 		}
       
   824 		
       
   825 		if(($segment == 'none') || ($segment >= 0)) {
       
   826 			$defs = array();
       
   827 			$ints = array();
       
   828 			foreach ($table_structure as $struct) {
       
   829 				if ( (0 === strpos($struct->Type, 'tinyint')) ||
       
   830 					(0 === strpos(strtolower($struct->Type), 'smallint')) ||
       
   831 					(0 === strpos(strtolower($struct->Type), 'mediumint')) ||
       
   832 					(0 === strpos(strtolower($struct->Type), 'int')) ||
       
   833 					(0 === strpos(strtolower($struct->Type), 'bigint')) ) {
       
   834 						$defs[strtolower($struct->Field)] = ( null === $struct->Default ) ? 'NULL' : $struct->Default;
       
   835 						$ints[strtolower($struct->Field)] = "1";
       
   836 				}
       
   837 			}
       
   838 			
       
   839 			
       
   840 			// Batch by $row_inc
       
   841 			
       
   842 			if($segment == 'none') {
       
   843 				$row_start = 0;
       
   844 				$row_inc = ROWS_PER_SEGMENT;
       
   845 			} else {
       
   846 				$row_start = $segment * ROWS_PER_SEGMENT;
       
   847 				$row_inc = ROWS_PER_SEGMENT;
       
   848 			}
       
   849 			
       
   850 			do {	
       
   851 				// don't include extra stuff, if so requested
       
   852 				$excs = (array) get_option('wp_db_backup_excs');
       
   853 				$where = '';
       
   854 				if ( is_array($excs['spam'] ) && in_array($table, $excs['spam']) ) {
       
   855 					$where = ' WHERE comment_approved != "spam"';
       
   856 				} elseif ( is_array($excs['revisions'] ) && in_array($table, $excs['revisions']) ) {
       
   857 					$where = ' WHERE post_type != "revision"';
       
   858 				}
       
   859 				
       
   860 				if ( !ini_get('safe_mode')) @set_time_limit(15*60);
       
   861 				$table_data = $wpdb->get_results("SELECT * FROM $table $where LIMIT {$row_start}, {$row_inc}", ARRAY_A);
       
   862 
       
   863 				$entries = 'INSERT INTO ' . $this->backquote($table) . ' VALUES (';	
       
   864 				//    \x08\\x09, not required
       
   865 				$search = array("\x00", "\x0a", "\x0d", "\x1a");
       
   866 				$replace = array('\0', '\n', '\r', '\Z');
       
   867 				if($table_data) {
       
   868 					foreach ($table_data as $row) {
       
   869 						$values = array();
       
   870 						foreach ($row as $key => $value) {
       
   871 							if ($ints[strtolower($key)]) {
       
   872 								// make sure there are no blank spots in the insert syntax,
       
   873 								// yet try to avoid quotation marks around integers
       
   874 								$value = ( null === $value || '' === $value) ? $defs[strtolower($key)] : $value;
       
   875 								$values[] = ( '' === $value ) ? "''" : $value;
       
   876 							} else {
       
   877 								$values[] = "'" . str_replace($search, $replace, $this->sql_addslashes($value)) . "'";
       
   878 							}
       
   879 						}
       
   880 						$this->stow(" \n" . $entries . implode(', ', $values) . ');');
       
   881 					}
       
   882 					$row_start += $row_inc;
       
   883 				}
       
   884 			} while((count($table_data) > 0) and ($segment=='none'));
       
   885 		}
       
   886 		
       
   887 		if(($segment == 'none') || ($segment < 0)) {
       
   888 			// Create footer/closing comment in SQL-file
       
   889 			$this->stow("\n");
       
   890 			$this->stow("#\n");
       
   891 			$this->stow("# " . sprintf(__('End of data contents of table %s','wp-db-backup'),$this->backquote($table)) . "\n");
       
   892 			$this->stow("# --------------------------------------------------------\n");
       
   893 			$this->stow("\n");
       
   894 		}
       
   895 	} // end backup_table()
       
   896 	
       
   897 	function db_backup($core_tables, $other_tables) {
       
   898 		global $table_prefix, $wpdb;
       
   899 		
       
   900 		if (is_writable($this->backup_dir)) {
       
   901 			$this->fp = $this->open($this->backup_dir . $this->backup_filename);
       
   902 			if(!$this->fp) {
       
   903 				$this->error(__('Could not open the backup file for writing!','wp-db-backup'));
       
   904 				return false;
       
   905 			}
       
   906 		} else {
       
   907 			$this->error(__('The backup directory is not writeable!','wp-db-backup'));
       
   908 			return false;
       
   909 		}
       
   910 		
       
   911 		//Begin new backup of MySql
       
   912 		$this->stow("# " . __('WordPress MySQL database backup','wp-db-backup') . "\n");
       
   913 		$this->stow("#\n");
       
   914 		$this->stow("# " . sprintf(__('Generated: %s','wp-db-backup'),date("l j. F Y H:i T")) . "\n");
       
   915 		$this->stow("# " . sprintf(__('Hostname: %s','wp-db-backup'),DB_HOST) . "\n");
       
   916 		$this->stow("# " . sprintf(__('Database: %s','wp-db-backup'),$this->backquote(DB_NAME)) . "\n");
       
   917 		$this->stow("# --------------------------------------------------------\n");
       
   918 		
       
   919 			if ( (is_array($other_tables)) && (count($other_tables) > 0) )
       
   920 			$tables = array_merge($core_tables, $other_tables);
       
   921 		else
       
   922 			$tables = $core_tables;
       
   923 		
       
   924 		foreach ($tables as $table) {
       
   925 			// Increase script execution time-limit to 15 min for every table.
       
   926 			if ( !ini_get('safe_mode')) @set_time_limit(15*60);
       
   927 			// Create the SQL statements
       
   928 			$this->stow("# --------------------------------------------------------\n");
       
   929 			$this->stow("# " . sprintf(__('Table: %s','wp-db-backup'),$this->backquote($table)) . "\n");
       
   930 			$this->stow("# --------------------------------------------------------\n");
       
   931 			$this->backup_table($table);
       
   932 		}
       
   933 				
       
   934 		$this->close($this->fp);
       
   935 		
       
   936 		if (count($this->errors)) {
       
   937 			return false;
       
   938 		} else {
       
   939 			return $this->backup_filename;
       
   940 		}
       
   941 		
       
   942 	} //wp_db_backup
       
   943 
       
   944 	/**
       
   945 	 * Sends the backed-up file via email
       
   946 	 * @param string $to
       
   947 	 * @param string $subject
       
   948 	 * @param string $message
       
   949 	 * @return bool
       
   950 	 */
       
   951 	function send_mail( $to, $subject, $message, $diskfile) {
       
   952 		global $phpmailer;
       
   953 
       
   954 		$filename = basename($diskfile);
       
   955 
       
   956 		extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message' ) ) );
       
   957 
       
   958 		if ( !is_object( $phpmailer ) || ( strtolower(get_class( $phpmailer )) != 'phpmailer' ) ) {
       
   959 			if ( file_exists( ABSPATH . WPINC . '/class-phpmailer.php' ) )
       
   960 				require_once ABSPATH . WPINC . '/class-phpmailer.php';
       
   961 			if ( file_exists( ABSPATH . WPINC . '/class-smtp.php' ) )
       
   962 				require_once ABSPATH . WPINC . '/class-smtp.php';
       
   963 			if ( class_exists( 'PHPMailer') )
       
   964 				$phpmailer = new PHPMailer();
       
   965 		}
       
   966 
       
   967 		// try to use phpmailer directly (WP 2.2+)
       
   968 		if ( is_object( $phpmailer ) && ( strtolower(get_class( $phpmailer )) == 'phpmailer' ) ) {
       
   969 			
       
   970 			// Get the site domain and get rid of www.
       
   971 			$sitename = strtolower( $_SERVER['SERVER_NAME'] );
       
   972 			if ( substr( $sitename, 0, 4 ) == 'www.' ) {
       
   973 				$sitename = substr( $sitename, 4 );
       
   974 			}
       
   975 			$from_email = 'wordpress@' . $sitename;
       
   976 			$from_name = 'WordPress';
       
   977 
       
   978 			// Empty out the values that may be set
       
   979 			$phpmailer->ClearAddresses();
       
   980 			$phpmailer->ClearAllRecipients();
       
   981 			$phpmailer->ClearAttachments();
       
   982 			$phpmailer->ClearBCCs();
       
   983 			$phpmailer->ClearCCs();
       
   984 			$phpmailer->ClearCustomHeaders();
       
   985 			$phpmailer->ClearReplyTos();
       
   986 
       
   987 			$phpmailer->AddAddress( $to );
       
   988 			$phpmailer->AddAttachment($diskfile, $filename);
       
   989 			$phpmailer->Body = $message;
       
   990 			$phpmailer->CharSet = apply_filters( 'wp_mail_charset', get_bloginfo('charset') );
       
   991 			$phpmailer->From = apply_filters( 'wp_mail_from', $from_email );
       
   992 			$phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name );
       
   993 			$phpmailer->IsMail();
       
   994 			$phpmailer->Subject = $subject;
       
   995 
       
   996 			do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
       
   997 			
       
   998 			$result = @$phpmailer->Send();
       
   999 
       
  1000 		// old-style: build the headers directly
       
  1001 		} else {
       
  1002 			$randomish = md5(time());
       
  1003 			$boundary = "==WPBACKUP-$randomish";
       
  1004 			$fp = fopen($diskfile,"rb");
       
  1005 			$file = fread($fp,filesize($diskfile)); 
       
  1006 			$this->close($fp);
       
  1007 			
       
  1008 			$data = chunk_split(base64_encode($file));
       
  1009 			
       
  1010 			$headers .= "MIME-Version: 1.0\n";
       
  1011 			$headers = 'From: wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])) . "\n";
       
  1012 			$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
       
  1013 		
       
  1014 			// Add a multipart boundary above the plain message
       
  1015 			$message = "This is a multi-part message in MIME format.\n\n" .
       
  1016 		        	"--{$boundary}\n" .
       
  1017 				"Content-Type: text/plain; charset=\"" . get_bloginfo('charset') . "\"\n" .
       
  1018 				"Content-Transfer-Encoding: 7bit\n\n" .
       
  1019 				$message . "\n\n";
       
  1020 
       
  1021 			// Add file attachment to the message
       
  1022 			$message .= "--{$boundary}\n" .
       
  1023 				"Content-Type: application/octet-stream;\n" .
       
  1024 				" name=\"{$filename}\"\n" .
       
  1025 				"Content-Disposition: attachment;\n" .
       
  1026 				" filename=\"{$filename}\"\n" .
       
  1027 				"Content-Transfer-Encoding: base64\n\n" .
       
  1028 				$data . "\n\n" .
       
  1029 				"--{$boundary}--\n";
       
  1030 			
       
  1031 			$result = @wp_mail($to, $subject, $message, $headers);
       
  1032 		}
       
  1033 		return $result;
       
  1034 
       
  1035 	}
       
  1036 
       
  1037 	function deliver_backup($filename = '', $delivery = 'http', $recipient = '', $location = 'main') {
       
  1038 		if ('' == $filename) { return false; }
       
  1039 		
       
  1040 		$diskfile = $this->backup_dir . $filename;
       
  1041 		$gz_diskfile = "{$diskfile}.gz";
       
  1042 
       
  1043 		/**
       
  1044 		 * Try upping the memory limit before gzipping
       
  1045 		 */
       
  1046 		if ( function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < 64 ) ) {
       
  1047 			@ini_set('memory_limit', '64M' );
       
  1048 		}
       
  1049 
       
  1050 		if ( file_exists( $diskfile ) && empty( $_GET['download-retry'] ) ) {
       
  1051 			/**
       
  1052 			 * Try gzipping with an external application
       
  1053 			 */
       
  1054 			if ( file_exists( $diskfile ) && ! file_exists( $gz_diskfile ) ) {
       
  1055 				@exec( "gzip $diskfile" );
       
  1056 			}
       
  1057 
       
  1058 			if ( file_exists( $gz_diskfile ) ) {
       
  1059 				if ( file_exists( $diskfile ) ) {
       
  1060 					unlink($diskfile);
       
  1061 				}
       
  1062 				$diskfile = $gz_diskfile;
       
  1063 				$filename = "{$filename}.gz";
       
  1064 			
       
  1065 			/**
       
  1066 			 * Try to compress to gzip, if available 
       
  1067 			 */
       
  1068 			} else {
       
  1069 				if ( function_exists('gzencode') ) {
       
  1070 					if ( function_exists('file_get_contents') ) {
       
  1071 						$text = file_get_contents($diskfile);
       
  1072 					} else {
       
  1073 						$text = implode("", file($diskfile));
       
  1074 					}
       
  1075 					$gz_text = gzencode($text, 9);
       
  1076 					$fp = fopen($gz_diskfile, "w");
       
  1077 					fwrite($fp, $gz_text);
       
  1078 					if ( fclose($fp) ) {
       
  1079 						unlink($diskfile);
       
  1080 						$diskfile = $gz_diskfile;
       
  1081 						$filename = "{$filename}.gz";
       
  1082 					}
       
  1083 				}
       
  1084 			}
       
  1085 			/*
       
  1086 			 * 
       
  1087 			 */
       
  1088 		} elseif ( file_exists( $gz_diskfile ) && empty( $_GET['download-retry'] ) ) {
       
  1089 			$diskfile = $gz_diskfile;
       
  1090 			$filename = "{$filename}.gz";
       
  1091 		}
       
  1092 
       
  1093 		if ('http' == $delivery) {
       
  1094 			if ( ! file_exists( $diskfile ) ) {
       
  1095 				if ( empty( $_GET['download-retry'] ) ) { 
       
  1096 					$this->error(array('kind' => 'fatal', 'msg' => sprintf(__('File not found:%s','wp-db-backup'), "&nbsp;<strong>$filename</strong><br />") . '<br /><a href="' . $this->page_url . '">' . __('Return to Backup','wp-db-backup') . '</a>'));
       
  1097 				} else {
       
  1098 					return true;
       
  1099 				}
       
  1100 			} elseif ( file_exists( $diskfile ) ) {
       
  1101 				header('Content-Description: File Transfer');
       
  1102 				header('Content-Type: application/octet-stream');
       
  1103 				header('Content-Length: ' . filesize($diskfile));
       
  1104 				header("Content-Disposition: attachment; filename=$filename");
       
  1105 				$success = readfile($diskfile);
       
  1106 				if ( $success ) {
       
  1107 					unlink($diskfile);
       
  1108 				}
       
  1109 			}
       
  1110 		} elseif ('smtp' == $delivery) {
       
  1111 			if (! file_exists($diskfile)) {
       
  1112 				$msg = sprintf(__('File %s does not exist!','wp-db-backup'), $diskfile);
       
  1113 				$this->error($msg);
       
  1114 				return false;
       
  1115 			}
       
  1116 			if (! is_email($recipient)) {
       
  1117 				$recipient = get_option('admin_email');
       
  1118 			}
       
  1119 			$message = sprintf(__("Attached to this email is\n   %1s\n   Size:%2s kilobytes\n",'wp-db-backup'), $filename, round(filesize($diskfile)/1024));
       
  1120 			$success = $this->send_mail($recipient, get_bloginfo('name') . ' ' . __('Database Backup','wp-db-backup'), $message, $diskfile);
       
  1121 
       
  1122 			if ( false === $success ) {
       
  1123 				$msg = __('The following errors were reported:','wp-db-backup') . "\n ";
       
  1124 				if ( function_exists('error_get_last') ) {
       
  1125 					$err = error_get_last();
       
  1126 					$msg .= $err['message'];
       
  1127 				} else {
       
  1128 					$msg .= __('ERROR: The mail application has failed to deliver the backup.','wp-db-backup'); 
       
  1129 				}
       
  1130 				$this->error(array('kind' => 'fatal', 'loc' => $location, 'msg' => $msg));
       
  1131 			} else {
       
  1132 				if ( file_exists( $diskfile ) ) {
       
  1133 					unlink($diskfile);
       
  1134 				}
       
  1135 			}
       
  1136 		}
       
  1137 		return $success;
       
  1138 	}
       
  1139 	
       
  1140 	function backup_menu() {
       
  1141 		global $table_prefix, $wpdb;
       
  1142 		$feedback = '';
       
  1143 		$whoops = false;
       
  1144 		
       
  1145 		// did we just do a backup?  If so, let's report the status
       
  1146 		if ( $this->backup_complete ) {
       
  1147 			$feedback = '<div class="updated wp-db-backup-updated"><p>' . __('Backup Successful','wp-db-backup') . '!';
       
  1148 			$file = $this->backup_file;
       
  1149 			switch($_POST['deliver']) {
       
  1150 			case 'http':
       
  1151 				$feedback .= '<br />' . sprintf(__('Your backup file: <a href="%1s">%2s</a> should begin downloading shortly.','wp-db-backup'), WP_BACKUP_URL . "{$this->backup_file}", $this->backup_file);
       
  1152 				break;
       
  1153 			case 'smtp':
       
  1154 				if (! is_email($_POST['backup_recipient'])) {
       
  1155 					$feedback .= get_option('admin_email');
       
  1156 				} else {
       
  1157 					$feedback .= $_POST['backup_recipient'];
       
  1158 				}
       
  1159 				$feedback = '<br />' . sprintf(__('Your backup has been emailed to %s','wp-db-backup'), $feedback);
       
  1160 				break;
       
  1161 			case 'none':
       
  1162 				$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"','wp-db-backup');
       
  1163 				$feedback .= ':<br /> <a href="' . WP_BACKUP_URL . "$file\">$file</a> : " . sprintf(__('%s bytes','wp-db-backup'), filesize($this->backup_dir . $file));
       
  1164 			}
       
  1165 			$feedback .= '</p></div>';
       
  1166 		}
       
  1167 	
       
  1168 		// security check
       
  1169 		$this->wp_secure();  
       
  1170 
       
  1171 		if (count($this->errors)) {
       
  1172 			$feedback .= '<div class="updated wp-db-backup-updated error"><p><strong>' . __('The following errors were reported:','wp-db-backup') . '</strong></p>';
       
  1173 			$feedback .= '<p>' . $this->error_display( 'main', false ) . '</p>';
       
  1174 			$feedback .= "</p></div>";
       
  1175 		}
       
  1176 
       
  1177 		// did we just save options for wp-cron?
       
  1178 		if ( (function_exists('wp_schedule_event') || function_exists('wp_cron_init')) 
       
  1179 			&& isset($_POST['wp_cron_backup_options']) ) :
       
  1180 			do_action('wp_db_b_update_cron_options');
       
  1181 			if ( function_exists('wp_schedule_event') ) {
       
  1182 				wp_clear_scheduled_hook( 'wp_db_backup_cron' ); // unschedule previous
       
  1183 				$scheds = (array) wp_get_schedules();
       
  1184 				$name = strval($_POST['wp_cron_schedule']);
       
  1185 				$interval = ( isset($scheds[$name]['interval']) ) ? 
       
  1186 					(int) $scheds[$name]['interval'] : 0;
       
  1187 				update_option('wp_cron_backup_schedule', $name, false);
       
  1188 				if ( 0 !== $interval ) {
       
  1189 					wp_schedule_event(time() + $interval, $name, 'wp_db_backup_cron');
       
  1190 				}
       
  1191 			}
       
  1192 			else {
       
  1193 				update_option('wp_cron_backup_schedule', intval($_POST['cron_schedule']), false);
       
  1194 			}
       
  1195 			update_option('wp_cron_backup_tables', isset( $_POST['wp_cron_backup_tables'] ) ? $_POST['wp_cron_backup_tables'] : array() );
       
  1196 			if (is_email($_POST['cron_backup_recipient'])) {
       
  1197 				update_option('wp_cron_backup_recipient', $_POST['cron_backup_recipient'], false);
       
  1198 			}
       
  1199 			$feedback .= '<div class="updated wp-db-backup-updated"><p>' . __('Scheduled Backup Options Saved!','wp-db-backup') . '</p></div>';
       
  1200 		endif;
       
  1201 		
       
  1202 		$other_tables = array();
       
  1203 		$also_backup = array();
       
  1204 	
       
  1205 		// Get complete db table list	
       
  1206 		$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
       
  1207 		$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
       
  1208 		// Get list of WP tables that actually exist in this DB (for 1.6 compat!)
       
  1209 		$wp_backup_default_tables = array_intersect($all_tables, $this->core_table_names);
       
  1210 		// Get list of non-WP tables
       
  1211 		$other_tables = array_diff($all_tables, $wp_backup_default_tables);
       
  1212 		
       
  1213 		if ('' != $feedback)
       
  1214 			echo $feedback;
       
  1215 
       
  1216 		if ( ! $this->wp_secure() ) 	
       
  1217 			return;
       
  1218 
       
  1219 		// Give the new dirs the same perms as wp-content.
       
  1220 //		$stat = stat( ABSPATH . 'wp-content' );
       
  1221 //		$dir_perms = $stat['mode'] & 0000777; // Get the permission bits.
       
  1222 		$dir_perms = '0777';
       
  1223 
       
  1224 		// the file doesn't exist and can't create it
       
  1225 		if ( ! file_exists($this->backup_dir) && ! @mkdir($this->backup_dir) ) {
       
  1226 			?><div class="updated wp-db-backup-updated error"><p><?php _e('WARNING: Your backup directory does <strong>NOT</strong> exist, and we cannot create it.','wp-db-backup'); ?></p>
       
  1227 			<p><?php printf(__('Using your FTP client, try to create the backup directory yourself: %s', 'wp-db-backup'), '<code>' . $this->backup_dir . '</code>'); ?></p></div><?php
       
  1228 			$whoops = true;
       
  1229 		// not writable due to write permissions
       
  1230 		} elseif ( !is_writable($this->backup_dir) && ! @chmod($this->backup_dir, $dir_perms) ) {
       
  1231 			?><div class="updated wp-db-backup-updated error"><p><?php _e('WARNING: Your backup directory is <strong>NOT</strong> writable! We cannot create the backup files.','wp-db-backup'); ?></p>
       
  1232 			<p><?php printf(__('Using your FTP client, try to set the backup directory&rsquo;s write permission to %1$s or %2$s: %3$s', 'wp-db-backup'), '<code>777</code>', '<code>a+w</code>', '<code>' . $this->backup_dir . '</code>'); ?>
       
  1233 			</p></div><?php 
       
  1234 			$whoops = true;
       
  1235 		} else {
       
  1236 			$this->fp = $this->open($this->backup_dir . 'test' );
       
  1237 			if( $this->fp ) { 
       
  1238 				$this->close($this->fp);
       
  1239 				@unlink($this->backup_dir . 'test' );
       
  1240 			// the directory is not writable probably due to safe mode
       
  1241 			} else {
       
  1242 				?><div class="updated wp-db-backup-updated error"><p><?php _e('WARNING: Your backup directory is <strong>NOT</strong> writable! We cannot create the backup files.','wp-db-backup'); ?></p><?php 
       
  1243 				if( ini_get('safe_mode') ){
       
  1244 					?><p><?php _e('This problem seems to be caused by your server&rsquo;s <code>safe_mode</code> file ownership restrictions, which limit what files web applications like WordPress can create.', 'wp-db-backup'); ?></p><?php 
       
  1245 				}
       
  1246 				?><?php printf(__('You can try to correct this problem by using your FTP client to delete and then re-create the backup directory: %s', 'wp-db-backup'), '<code>' . $this->backup_dir . '</code>');
       
  1247 				?></div><?php 
       
  1248 				$whoops = true;
       
  1249 			}
       
  1250 		}
       
  1251 
       
  1252 		
       
  1253 
       
  1254 		if ( !file_exists($this->backup_dir . 'index.php') )
       
  1255 			@ touch($this->backup_dir . 'index.php');
       
  1256 		?><div class='wrap'>
       
  1257 		<h2><?php _e('Backup','wp-db-backup') ?></h2>
       
  1258 		<form method="post" action="">
       
  1259 		<?php if ( function_exists('wp_nonce_field') ) wp_nonce_field($this->referer_check_key); ?>
       
  1260 		<fieldset class="options"><legend><?php _e('Tables','wp-db-backup') ?></legend>
       
  1261 		<div class="tables-list core-tables alternate">
       
  1262 		<h4><?php _e('These core WordPress tables will always be backed up:','wp-db-backup') ?></h4><ul><?php
       
  1263 		$excs = (array) get_option('wp_db_backup_excs');
       
  1264 		foreach ($wp_backup_default_tables as $table) {
       
  1265 			if ( $table == $wpdb->comments ) {
       
  1266 				$checked = ( isset($excs['spam']) && is_array($excs['spam'] ) && in_array($table, $excs['spam']) ) ? ' checked=\'checked\'' : '';
       
  1267 				echo "<li><input type='hidden' name='core_tables[]' value='$table' /><code>$table</code> <span class='instructions'> <input type='checkbox' name='exclude-spam[]' value='$table' $checked /> " . __('Exclude spam comments', 'wp-db-backup') . '</span></li>';
       
  1268 			} elseif ( function_exists('wp_get_post_revisions') && $table == $wpdb->posts ) {
       
  1269 					$checked = ( isset($excs['revisions']) && is_array($excs['revisions'] ) && in_array($table, $excs['revisions']) ) ? ' checked=\'checked\'' : '';
       
  1270 				echo "<li><input type='hidden' name='core_tables[]' value='$table' /><code>$table</code> <span class='instructions'> <input type='checkbox' name='exclude-revisions[]' value='$table' $checked /> " . __('Exclude post revisions', 'wp-db-backup') . '</span></li>';
       
  1271 			} else {
       
  1272 				echo "<li><input type='hidden' name='core_tables[]' value='$table' /><code>$table</code></li>";
       
  1273 			}
       
  1274 		}
       
  1275 		?></ul>
       
  1276 		</div>
       
  1277 		<div class="tables-list extra-tables" id="extra-tables-list">
       
  1278 		<?php 
       
  1279 		if (count($other_tables) > 0) { 
       
  1280 			?>
       
  1281 			<h4><?php _e('You may choose to include any of the following tables:','wp-db-backup'); ?></h4>
       
  1282 			<ul>
       
  1283 			<?php
       
  1284 			foreach ($other_tables as $table) {
       
  1285 				?>
       
  1286 				<li><label><input type="checkbox" name="other_tables[]" value="<?php echo $table; ?>" /> <code><?php echo $table; ?></code></label>
       
  1287 				<?php 
       
  1288 			}
       
  1289 			?></ul><?php 
       
  1290 		}
       
  1291 		?></div>
       
  1292 		</fieldset>
       
  1293 		
       
  1294 		<fieldset class="options">
       
  1295 			<legend><?php _e('Backup Options','wp-db-backup'); ?></legend>
       
  1296 			<p><?php  _e('What to do with the backup file:','wp-db-backup'); ?></p>
       
  1297 			<ul>
       
  1298 			<li><label for="do_save">
       
  1299 				<input type="radio" id="do_save" name="deliver" value="none" style="border:none;" />
       
  1300 				<?php _e('Save to server','wp-db-backup'); 
       
  1301 				echo " (<code>" . $this->backup_dir . "</code>)"; ?>
       
  1302 			</label></li>
       
  1303 			<li><label for="do_download">
       
  1304 				<input type="radio" checked="checked" id="do_download" name="deliver" value="http" style="border:none;" />
       
  1305 				<?php _e('Download to your computer','wp-db-backup'); ?>
       
  1306 			</label></li>
       
  1307 			<li><label for="do_email">
       
  1308 				<input type="radio" name="deliver" id="do_email" value="smtp" style="border:none;" />
       
  1309 				<?php _e('Email backup to:','wp-db-backup'); ?>
       
  1310 				<input type="text" name="backup_recipient" size="20" value="<?php 
       
  1311 					$backup_recip = get_option('wpdb_backup_recip');
       
  1312 					if ( empty( $backup_recip ) ) {
       
  1313 						$backup_recip = get_option('admin_email');
       
  1314 					}
       
  1315 
       
  1316 					echo $backup_recip; ?>" />
       
  1317 			</label></li>
       
  1318 			</ul>
       
  1319 			<?php if ( ! $whoops ) : ?>
       
  1320 			<input type="hidden" name="do_backup" id="do_backup" value="backup" /> 
       
  1321 			<p class="submit">
       
  1322 				<input type="submit" name="submit" onclick="document.getElementById('do_backup').value='fragments';" value="<?php _e('Backup now!','wp-db-backup'); ?>" />
       
  1323 			</p>
       
  1324 			<?php else : ?>
       
  1325 				<div class="updated wp-db-backup-updated error"><p><?php _e('WARNING: Your backup directory is <strong>NOT</strong> writable!','wp-db-backup'); ?></p></div>
       
  1326 			<?php endif; // ! whoops ?>
       
  1327 		</fieldset>
       
  1328 		<?php do_action('wp_db_b_backup_opts'); ?>
       
  1329 		</form>
       
  1330 		
       
  1331 		<?php
       
  1332 		// this stuff only displays if some sort of wp-cron is available 
       
  1333 		$cron = ( function_exists('wp_schedule_event') ) ? true : false; // wp-cron in WP 2.1+
       
  1334 		$cron_old = ( function_exists('wp_cron_init') && ! $cron ) ? true : false; // wp-cron plugin by Skippy
       
  1335 		if ( $cron_old || $cron ) :
       
  1336 			echo '<fieldset class="options"><legend>' . __('Scheduled Backup','wp-db-backup') . '</legend>';
       
  1337 			$datetime = get_option('date_format') . ' ' . get_option('time_format');
       
  1338 			if ( $cron ) :
       
  1339 				$next_cron = wp_next_scheduled('wp_db_backup_cron');
       
  1340 				if ( ! empty( $next_cron ) ) :
       
  1341 					?>
       
  1342 					<p id="backup-time-wrap">
       
  1343 					<?php printf(__('Next Backup: %s','wp-db-backup'), '<span id="next-backup-time">' . gmdate($datetime, $next_cron + (get_option('gmt_offset') * 3600)) . '</span>'); ?>
       
  1344 					</p>
       
  1345 					<?php 
       
  1346 				endif;
       
  1347 			elseif ( $cron_old ) :
       
  1348 				?><p><?php printf(__('Last WP-Cron Daily Execution: %s','wp-db-backup'), gmdate($datetime, get_option('wp_cron_daily_lastrun') + (get_option('gmt_offset') * 3600))); ?><br /><?php 
       
  1349 				printf(__('Next WP-Cron Daily Execution: %s','wp-db-backup'), gmdate($datetime, (get_option('wp_cron_daily_lastrun') + (get_option('gmt_offset') * 3600) + 86400))); ?></p><?php 
       
  1350 			endif;
       
  1351 			?><form method="post" action="">
       
  1352 			<?php if ( function_exists('wp_nonce_field') ) wp_nonce_field($this->referer_check_key); ?>
       
  1353 			<div class="tables-list">
       
  1354 			<h4><?php _e('Schedule: ','wp-db-backup'); ?></h4>
       
  1355 			<?php 
       
  1356 			if ( $cron_old ) :
       
  1357 				$wp_cron_backup_schedule = get_option('wp_cron_backup_schedule');
       
  1358 				$schedule = array(0 => __('None','wp-db-backup'), 1 => __('Daily','wp-db-backup'));
       
  1359 				foreach ($schedule as $value => $name) {
       
  1360 					echo ' <input type="radio" style="border:none;" name="cron_schedule"';
       
  1361 					if ($wp_cron_backup_schedule == $value) {
       
  1362 						echo ' checked="checked" ';
       
  1363 					}
       
  1364 					echo 'value="' . $value . '" /> ' . $name;
       
  1365 				}
       
  1366 			elseif ( $cron ) :
       
  1367 				echo apply_filters('wp_db_b_schedule_choices', wp_get_schedules() );
       
  1368 			endif;
       
  1369 			$cron_recipient = get_option('wp_cron_backup_recipient');
       
  1370 			if (! is_email($cron_recipient)) {
       
  1371 				$cron_recipient = get_option('admin_email');
       
  1372 			}
       
  1373 			$cron_recipient_input = '<p><label for="cron_backup_recipient">' . __('Email backup to:','wp-db-backup') . ' <input type="text" name="cron_backup_recipient" id="cron_backup_recipient" size="20" value="' . $cron_recipient . '" /></label></p>';
       
  1374 			echo apply_filters('wp_db_b_cron_recipient_input', $cron_recipient_input);
       
  1375 			echo '<p class="submit"><input type="submit" name="submit" value="' . __('Schedule backup','wp-db-backup') . '" /></p>';
       
  1376 			echo '</div>';
       
  1377 			$cron_tables = get_option('wp_cron_backup_tables');
       
  1378 			if (! is_array($cron_tables)) {
       
  1379 				$cron_tables = array();
       
  1380 			}
       
  1381 			if (count($other_tables) > 0) {
       
  1382 				echo '<div class="tables-list alternate" id="include-tables-list">';
       
  1383 				echo '<h4>' . __('Tables to include in the scheduled backup:','wp-db-backup') . '</h4><ul>';
       
  1384 				foreach ($other_tables as $table) {
       
  1385 					echo '<li><input type="checkbox" ';
       
  1386 					if (in_array($table, $cron_tables)) {
       
  1387 						echo 'checked="checked" ';
       
  1388 					}
       
  1389 					echo "name='wp_cron_backup_tables[]' value='{$table}' /> <code>{$table}</code></li>";
       
  1390 				}
       
  1391 				echo '</ul></div>';
       
  1392 			}
       
  1393 			echo '<input type="hidden" name="wp_cron_backup_options" value="SET" /></form>';
       
  1394 			echo '</fieldset>';
       
  1395 		endif; // end of wp_cron (legacy) section
       
  1396 		
       
  1397 		echo '</div><!-- .wrap -->';
       
  1398 		
       
  1399 	} // end wp_backup_menu()
       
  1400 
       
  1401 	function get_sched() {
       
  1402 		$options = array_keys( (array) wp_get_schedules() );
       
  1403 		$freq = get_option('wp_cron_backup_schedule'); 
       
  1404 		$freq = ( in_array( $freq , $options ) ) ? $freq : 'never';
       
  1405 		return $freq;
       
  1406 	}
       
  1407 
       
  1408 	function schedule_choices($schedule) { // create the cron menu based on the schedule
       
  1409 		$wp_cron_backup_schedule = $this->get_sched();
       
  1410 		$next_cron = wp_next_scheduled('wp_db_backup_cron');
       
  1411 		$wp_cron_backup_schedule = ( empty( $next_cron ) ) ? 'never' : $wp_cron_backup_schedule;
       
  1412 		$sort = array();
       
  1413 		foreach ( (array) $schedule as $key => $value ) $sort[$key] = $value['interval'];
       
  1414 		asort( $sort );
       
  1415 		$schedule_sorted = array();
       
  1416 		foreach ( (array) $sort as $key => $value ) $schedule_sorted[$key] = $schedule[$key];
       
  1417 		$menu = '<ul>';
       
  1418 		$schedule = array_merge( array( 'never' => array( 'interval' => 0, 'display' => __('Never','wp-db-backup') ) ),
       
  1419 			(array) $schedule_sorted );
       
  1420 		foreach ( $schedule as $name => $settings) {
       
  1421 			$interval = (int) $settings['interval'];
       
  1422 			if ( 0 == $interval && ! 'never' == $name ) continue;
       
  1423 			$display = ( ! '' == $settings['display'] ) ? $settings['display'] : sprintf(__('%s seconds','wp-db-backup'),$interval);
       
  1424 			$menu .= "<li><input type='radio' name='wp_cron_schedule' style='border:none;' ";
       
  1425 			if ($wp_cron_backup_schedule == $name) {
       
  1426 				$menu .= " checked='checked' ";
       
  1427 			}
       
  1428 			$menu .= "value='$name' /> $display</li>";
       
  1429 		}
       
  1430 		$menu .= '</ul>';
       
  1431 		return $menu;
       
  1432 	} // end schedule_choices()
       
  1433 	
       
  1434 	function wp_cron_daily() { // for legacy cron plugin
       
  1435 		$schedule = intval(get_option('wp_cron_backup_schedule'));
       
  1436 		// If scheduled backup is disabled
       
  1437 		if (0 == $schedule)
       
  1438 		        return;
       
  1439 		else return $this->cron_backup();
       
  1440 	} 
       
  1441 
       
  1442 	function cron_backup() {
       
  1443 		global $table_prefix, $wpdb;
       
  1444 		$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
       
  1445 		$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
       
  1446 		$core_tables = array_intersect($all_tables, $this->core_table_names);
       
  1447 		$other_tables = get_option('wp_cron_backup_tables');
       
  1448 		$recipient = get_option('wp_cron_backup_recipient');
       
  1449 		$backup_file = $this->db_backup($core_tables, $other_tables);
       
  1450 		if (false !== $backup_file) 
       
  1451 			return $this->deliver_backup($backup_file, 'smtp', $recipient, 'main');
       
  1452 		else return false;
       
  1453 	}
       
  1454 
       
  1455 	function add_sched_options($sched) {
       
  1456 		$sched['weekly'] = array('interval' => 604800, 'display' => __('Once Weekly','wp-db-backup'));
       
  1457 		return $sched;
       
  1458 	}
       
  1459 
       
  1460 	/**
       
  1461 	 * Checks that WordPress has sufficient security measures 
       
  1462 	 * @param string $kind
       
  1463 	 * @return bool
       
  1464 	 */
       
  1465 	function wp_secure($kind = 'warn', $loc = 'main') {
       
  1466 		global $wp_version;
       
  1467 		if ( function_exists('wp_verify_nonce') ) return true;
       
  1468 		else {
       
  1469 			$this->error(array('kind' => $kind, 'loc' => $loc, 'msg' => sprintf(__('Your WordPress version, %1s, lacks important security features without which it is unsafe to use the WP-DB-Backup plugin.  Hence, this plugin is automatically disabled.  Please consider <a href="%2s">upgrading WordPress</a> to a more recent version.','wp-db-backup'),$wp_version,'http://wordpress.org/download/')));
       
  1470 			return false;
       
  1471 		}
       
  1472 	}
       
  1473 
       
  1474 	/**
       
  1475 	 * Checks that the user has sufficient permission to backup
       
  1476 	 * @param string $loc
       
  1477 	 * @return bool
       
  1478 	 */
       
  1479 	function can_user_backup($loc = 'main') {
       
  1480 		$can = false;
       
  1481 		// make sure WPMU users are site admins, not ordinary admins
       
  1482 		if ( function_exists('is_site_admin') && ! is_site_admin() )
       
  1483 			return false;
       
  1484 		if ( ( $this->wp_secure('fatal', $loc) ) && current_user_can('import') )
       
  1485 			$can = $this->verify_nonce($_REQUEST['_wpnonce'], $this->referer_check_key, $loc);
       
  1486 		if ( false == $can ) 
       
  1487 			$this->error(array('loc' => $loc, 'kind' => 'fatal', 'msg' => __('You are not allowed to perform backups.','wp-db-backup')));
       
  1488 		return $can;
       
  1489 	}
       
  1490 
       
  1491 	/**
       
  1492 	 * Verify that the nonce is legitimate
       
  1493 	 * @param string $rec 	the nonce received
       
  1494 	 * @param string $nonce	what the nonce should be
       
  1495 	 * @param string $loc 	the location of the check
       
  1496 	 * @return bool
       
  1497 	 */
       
  1498 	function verify_nonce($rec = '', $nonce = 'X', $loc = 'main') {
       
  1499 		if ( wp_verify_nonce($rec, $nonce) )
       
  1500 			return true;
       
  1501 		else 
       
  1502 			$this->error(array('loc' => $loc, 'kind' => 'fatal', 'msg' => sprintf(__('There appears to be an unauthorized attempt from this site to access your database located at %1s.  The attempt has been halted.','wp-db-backup'),get_option('home'))));
       
  1503 	}
       
  1504 
       
  1505 	/**
       
  1506 	 * Check whether a file to be downloaded is  
       
  1507 	 * surreptitiously trying to download a non-backup file
       
  1508 	 * @param string $file
       
  1509 	 * @return null
       
  1510 	 */ 
       
  1511 	function validate_file($file) {
       
  1512 		if ( (false !== strpos($file, '..')) || (false !== strpos($file, './')) || (':' == substr($file, 1, 1)) )
       
  1513 			$this->error(array('kind' => 'fatal', 'loc' => 'frame', 'msg' => __("Cheatin' uh ?",'wp-db-backup')));
       
  1514 	}
       
  1515 
       
  1516 }
       
  1517 
       
  1518 function wpdbBackup_init() {
       
  1519 	global $mywpdbbackup;
       
  1520 	$mywpdbbackup = new wpdbBackup(); 	
       
  1521 }
       
  1522 
       
  1523 add_action('plugins_loaded', 'wpdbBackup_init');
       
  1524 ?>