| 1 |
<?php |
| 2 |
/* |
| 3 |
Plugin Name: WordPress Database Backup |
| 4 |
Plugin URI: http://www.ilfilosofo.com/blog/wp-db-backup |
| 5 |
Description: On-demand backup of your WordPress database. Navigate to <a href="edit.php?page=wp-db-backup.php">Manage → Backup</a> to get started. |
| 6 |
Author: <a href="http://www.skippy.net/">Scott Merrill</a> and <a href="http://www.ilfilosofo.com/blog/">Austin Matzko</a> |
| 7 |
Version: 2.0 |
| 8 |
|
| 9 |
Much of this was modified from Mark Ghosh's One Click Backup, which |
| 10 |
in turn was derived from phpMyAdmin. |
| 11 |
|
| 12 |
Many thanks to Owen (http://asymptomatic.net/wp/) for his patch |
| 13 |
http://dev.wp-plugins.org/ticket/219 |
| 14 |
*/ |
| 15 |
|
| 16 |
// CHANGE THIS IF YOU WANT TO USE A |
| 17 |
// DIFFERENT BACKUP LOCATION |
| 18 |
|
| 19 |
$rand = substr( md5( md5( DB_PASSWORD ) ), -5 ); |
| 20 |
|
| 21 |
define('WP_BACKUP_DIR', 'wp-content/backup-' . $rand); |
| 22 |
|
| 23 |
define('ROWS_PER_SEGMENT', 100); |
| 24 |
|
| 25 |
class wpdbBackup { |
| 26 |
|
| 27 |
var $backup_complete = false; |
| 28 |
var $backup_file = ''; |
| 29 |
var $backup_dir = WP_BACKUP_DIR; |
| 30 |
var $backup_errors = array(); |
| 31 |
var $basename; |
| 32 |
|
| 33 |
function gzip() { |
| 34 |
return function_exists('gzopen'); |
| 35 |
} |
| 36 |
|
| 37 |
function wpdbBackup() { |
| 38 |
global $table_prefix, $wpdb; |
| 39 |
add_action('wp_db_backup_cron', array(&$this, 'cron_backup')); |
| 40 |
add_action('wp_cron_daily', array(&$this, 'wp_cron_daily')); |
| 41 |
add_filter('cron_schedules', array(&$this, 'add_sched_options')); |
| 42 |
add_filter('wp_db_b_schedule_choices', array(&$this, 'schedule_choices')); |
| 43 |
|
| 44 |
$table_prefix = ( isset( $table_prefix ) ) ? $table_prefix : $wpdb->prefix; |
| 45 |
if ( isset( $wpdb->link2cat ) ) |
| 46 |
$this->core_table_names = explode(',',"$wpdb->categories,$wpdb->comments,$wpdb->link2cat,$wpdb->links,$wpdb->options,$wpdb->post2cat,$wpdb->postmeta,$wpdb->posts,$wpdb->users,$wpdb->usermeta"); |
| 47 |
else |
| 48 |
$this->core_table_names = explode(',',"$wpdb->categories,$wpdb->comments,$wpdb->linkcategories,$wpdb->links,$wpdb->options,$wpdb->post2cat,$wpdb->postmeta,$wpdb->posts,$wpdb->users,$wpdb->usermeta"); |
| 49 |
|
| 50 |
$this->backup_dir = trailingslashit($this->backup_dir); |
| 51 |
$this->basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__); |
| 52 |
|
| 53 |
if (isset($_POST['do_backup'])) { |
| 54 |
if ( !$this->user_can_backup() ) die(__('You are not allowed to perform backups.')); |
| 55 |
switch($_POST['do_backup']) { |
| 56 |
case 'backup': |
| 57 |
$this->perform_backup(); |
| 58 |
break; |
| 59 |
case 'fragments': |
| 60 |
add_action('admin_menu', array(&$this, 'fragment_menu')); |
| 61 |
break; |
| 62 |
} |
| 63 |
} elseif (isset($_GET['fragment'] )) { |
| 64 |
if ( !$this->user_can_backup() ) die(__('You are not allowed to perform backups.')); |
| 65 |
add_action('init', array(&$this, 'init')); |
| 66 |
} elseif (isset($_GET['backup'] )) { |
| 67 |
if ( !$this->user_can_backup() ) die(__('You are not allowed to perform backups.')); |
| 68 |
add_action('init', array(&$this, 'init')); |
| 69 |
} else { |
| 70 |
add_action('admin_menu', array(&$this, 'admin_menu')); |
| 71 |
} |
| 72 |
} |
| 73 |
|
| 74 |
function init() { |
| 75 |
if ( !$this->user_can_backup() ) die(__('You are not allowed to perform backups.')); |
| 76 |
|
| 77 |
if (isset($_GET['backup'])) { |
| 78 |
$via = isset($_GET['via']) ? $_GET['via'] : 'http'; |
| 79 |
|
| 80 |
$this->backup_file = $_GET['backup']; |
| 81 |
$this->validate_file($this->backup_file); |
| 82 |
|
| 83 |
switch($via) { |
| 84 |
case 'smtp': |
| 85 |
case 'email': |
| 86 |
$this->deliver_backup ($this->backup_file, 'smtp', $_GET['recipient']); |
| 87 |
echo ' |
| 88 |
<!-- ' . $via . ' --> |
| 89 |
<script type="text/javascript"><!--\\ |
| 90 |
'; |
| 91 |
if($this->backup_errors) { |
| 92 |
foreach($this->backup_errors as $error) { |
| 93 |
echo "window.parent.addError('$error');\n"; |
| 94 |
} |
| 95 |
} |
| 96 |
echo ' |
| 97 |
alert("' . __('Backup Complete!') . '"); |
| 98 |
</script> |
| 99 |
'; |
| 100 |
break; |
| 101 |
default: |
| 102 |
$this->deliver_backup ($this->backup_file, $via); |
| 103 |
} |
| 104 |
die(); |
| 105 |
} |
| 106 |
if (isset($_GET['fragment'] )) { |
| 107 |
list($table, $segment, $filename) = explode(':', $_GET['fragment']); |
| 108 |
$this->validate_file($filename); |
| 109 |
$this->backup_fragment($table, $segment, $filename); |
| 110 |
} |
| 111 |
|
| 112 |
die(); |
| 113 |
} |
| 114 |
|
| 115 |
function build_backup_script() { |
| 116 |
global $table_prefix, $wpdb; |
| 117 |
|
| 118 |
$datum = date("Ymd_B"); |
| 119 |
$backup_filename = DB_NAME . "_$table_prefix$datum.sql"; |
| 120 |
if ($this->gzip()) $backup_filename .= '.gz'; |
| 121 |
|
| 122 |
echo "<div class='wrap'>"; |
| 123 |
//echo "<pre>" . print_r($_POST, 1) . "</pre>"; |
| 124 |
echo '<h2>' . __('Backup') . '</h2> |
| 125 |
<fieldset class="options"><legend>' . __('Progress') . '</legend> |
| 126 |
<p><strong>' . |
| 127 |
__('DO NOT DO THE FOLLOWING AS IT WILL CAUSE YOUR BACKUP TO FAIL:'). |
| 128 |
'</strong></p> |
| 129 |
<ol> |
| 130 |
<li>'.__('Close this browser').'</li> |
| 131 |
<li>'.__('Reload this page').'</li> |
| 132 |
<li>'.__('Click the Stop or Back buttons in your browser').'</li> |
| 133 |
</ol> |
| 134 |
<p><strong>' . __('Progress:') . '</strong></p> |
| 135 |
<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;"> </div></div> |
| 136 |
<div id="progress_message"></div> |
| 137 |
<div id="errors"></div> |
| 138 |
</fieldset> |
| 139 |
<iframe id="backuploader" src="about:blank" style="border:0px solid white;height:1em;width:1em;"></iframe> |
| 140 |
<script type="text/javascript"><!--// |
| 141 |
function setMeter(pct) { |
| 142 |
var meter = document.getElementById("meter"); |
| 143 |
meter.style.width = pct + "%"; |
| 144 |
meter.innerHTML = Math.floor(pct) + "%"; |
| 145 |
} |
| 146 |
function setProgress(str) { |
| 147 |
var progress = document.getElementById("progress_message"); |
| 148 |
progress.innerHTML = str; |
| 149 |
} |
| 150 |
function addError(str) { |
| 151 |
var errors = document.getElementById("errors"); |
| 152 |
errors.innerHTML = errors.innerHTML + str + "<br />"; |
| 153 |
} |
| 154 |
|
| 155 |
function backup(table, segment) { |
| 156 |
var fram = document.getElementById("backuploader"); |
| 157 |
fram.src = "' . $_SERVER['REQUEST_URI'] . '&fragment=" + table + ":" + segment + ":' . $backup_filename . '"; |
| 158 |
} |
| 159 |
|
| 160 |
var curStep = 0; |
| 161 |
|
| 162 |
function nextStep() { |
| 163 |
backupStep(curStep); |
| 164 |
curStep++; |
| 165 |
} |
| 166 |
|
| 167 |
function finishBackup() { |
| 168 |
var fram = document.getElementById("backuploader"); |
| 169 |
setMeter(100); |
| 170 |
'; |
| 171 |
|
| 172 |
$this_basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__); |
| 173 |
$download_uri = get_option('siteurl') . "/wp-admin/edit.php?page={$this_basename}&backup={$backup_filename}"; |
| 174 |
switch($_POST['deliver']) { |
| 175 |
case 'http': |
| 176 |
echo ' |
| 177 |
setProgress("' . sprintf(__("Backup complete, preparing <a href=\\\"%s\\\">backup</a> for download..."), $download_uri) . '"); |
| 178 |
fram.src = "' . $download_uri . '"; |
| 179 |
'; |
| 180 |
break; |
| 181 |
case 'smtp': |
| 182 |
echo ' |
| 183 |
setProgress("' . sprintf(__("Backup complete, sending <a href=\\\"%s\\\">backup</a> via email..."), $download_uri) . '"); |
| 184 |
fram.src = "' . $download_uri . '&via=email&recipient=' . $_POST['backup_recipient'] . '"; |
| 185 |
'; |
| 186 |
break; |
| 187 |
default: |
| 188 |
echo ' |
| 189 |
setProgress("' . sprintf(__("Backup complete, download <a href=\\\"%s\\\">here</a>."), $download_uri) . '"); |
| 190 |
'; |
| 191 |
} |
| 192 |
|
| 193 |
echo ' |
| 194 |
} |
| 195 |
|
| 196 |
function backupStep(step) { |
| 197 |
switch(step) { |
| 198 |
case 0: backup("", 0); break; |
| 199 |
'; |
| 200 |
|
| 201 |
$also_backup = array(); |
| 202 |
if (isset($_POST['other_tables'])) { |
| 203 |
$also_backup = $_POST['other_tables']; |
| 204 |
} else { |
| 205 |
$also_backup = array(); |
| 206 |
} |
| 207 |
$core_tables = $_POST['core_tables']; |
| 208 |
$tables = array_merge($core_tables, $also_backup); |
| 209 |
$step_count = 1; |
| 210 |
foreach ($tables as $table) { |
| 211 |
$rec_count = $wpdb->get_var("SELECT count(*) FROM {$table}"); |
| 212 |
$rec_segments = ceil($rec_count / ROWS_PER_SEGMENT); |
| 213 |
$table_count = 0; |
| 214 |
do { |
| 215 |
echo "case {$step_count}: backup(\"{$table}\", {$table_count}); break;\n"; |
| 216 |
$step_count++; |
| 217 |
$table_count++; |
| 218 |
} while($table_count < $rec_segments); |
| 219 |
echo "case {$step_count}: backup(\"{$table}\", -1); break;\n"; |
| 220 |
$step_count++; |
| 221 |
} |
| 222 |
echo "case {$step_count}: finishBackup(); break;"; |
| 223 |
|
| 224 |
echo ' |
| 225 |
} |
| 226 |
if(step != 0) setMeter(100 * step / ' . $step_count . '); |
| 227 |
} |
| 228 |
|
| 229 |
nextStep(); |
| 230 |
//--></script> |
| 231 |
</div> |
| 232 |
'; |
| 233 |
} |
| 234 |
|
| 235 |
function backup_fragment($table, $segment, $filename) { |
| 236 |
global $table_prefix, $wpdb; |
| 237 |
|
| 238 |
echo "$table:$segment:$filename"; |
| 239 |
|
| 240 |
if($table == '') { |
| 241 |
$msg = __('Creating backup file...'); |
| 242 |
} else { |
| 243 |
if($segment == -1) { |
| 244 |
$msg = sprintf(__('Finished backing up table \\"%s\\".'), $table); |
| 245 |
} else { |
| 246 |
$msg = sprintf(__('Backing up table \\"%s\\"...'), $table); |
| 247 |
} |
| 248 |
} |
| 249 |
|
| 250 |
echo '<script type="text/javascript"><!--// |
| 251 |
var msg = "' . $msg . '"; |
| 252 |
window.parent.setProgress(msg); |
| 253 |
'; |
| 254 |
|
| 255 |
if (is_writable(ABSPATH . $this->backup_dir)) { |
| 256 |
$this->fp = $this->open(ABSPATH . $this->backup_dir . $filename, 'a'); |
| 257 |
if(!$this->fp) { |
| 258 |
$this->backup_error(__('Could not open the backup file for writing!')); |
| 259 |
$this->fatal_error = __('The backup file could not be saved. Please check the permissions for writing to your backup directory and try again.'); |
| 260 |
} |
| 261 |
else { |
| 262 |
if($table == '') { |
| 263 |
//Begin new backup of MySql |
| 264 |
$this->stow("# WordPress MySQL database backup\n"); |
| 265 |
$this->stow("#\n"); |
| 266 |
$this->stow("# Generated: " . date("l j. F Y H:i T") . "\n"); |
| 267 |
$this->stow("# Hostname: " . DB_HOST . "\n"); |
| 268 |
$this->stow("# Database: " . $this->backquote(DB_NAME) . "\n"); |
| 269 |
$this->stow("# --------------------------------------------------------\n"); |
| 270 |
} else { |
| 271 |
if($segment == 0) { |
| 272 |
// Increase script execution time-limit to 15 min for every table. |
| 273 |
if ( !ini_get('safe_mode')) @set_time_limit(15*60); |
| 274 |
//ini_set('memory_limit', '16M'); |
| 275 |
// Create the SQL statements |
| 276 |
$this->stow("# --------------------------------------------------------\n"); |
| 277 |
$this->stow("# Table: " . $this->backquote($table) . "\n"); |
| 278 |
$this->stow("# --------------------------------------------------------\n"); |
| 279 |
} |
| 280 |
$this->backup_table($table, $segment); |
| 281 |
} |
| 282 |
} |
| 283 |
} else { |
| 284 |
$this->backup_error(__('The backup directory is not writeable!')); |
| 285 |
$this->fatal_error = __('The backup directory is not writeable! Please check the permissions for writing to your backup directory and try again.'); |
| 286 |
} |
| 287 |
|
| 288 |
if($this->fp) $this->close($this->fp); |
| 289 |
|
| 290 |
if($this->backup_errors) { |
| 291 |
foreach($this->backup_errors as $error) { |
| 292 |
echo "window.parent.addError('$error');\n"; |
| 293 |
} |
| 294 |
} |
| 295 |
if($this->fatal_error) { |
| 296 |
echo ' |
| 297 |
alert("' . addslashes($this->fatal_error) . '"); |
| 298 |
//--></script> |
| 299 |
'; |
| 300 |
} |
| 301 |
else { |
| 302 |
echo ' |
| 303 |
window.parent.nextStep(); |
| 304 |
//--></script> |
| 305 |
'; |
| 306 |
} |
| 307 |
|
| 308 |
die(); |
| 309 |
} |
| 310 |
|
| 311 |
function perform_backup() { |
| 312 |
// are we backing up any other tables? |
| 313 |
$also_backup = array(); |
| 314 |
if (isset($_POST['other_tables'])) { |
| 315 |
$also_backup = $_POST['other_tables']; |
| 316 |
} |
| 317 |
|
| 318 |
$core_tables = $_POST['core_tables']; |
| 319 |
$this->backup_file = $this->db_backup($core_tables, $also_backup); |
| 320 |
if (FALSE !== $this->backup_file) { |
| 321 |
if ('smtp' == $_POST['deliver']) { |
| 322 |
$this->deliver_backup ($this->backup_file, $_POST['deliver'], $_POST['backup_recipient']); |
| 323 |
} elseif ('http' == $_POST['deliver']) { |
| 324 |
$this_basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__); |
| 325 |
header('Refresh: 3; ' . get_option('siteurl') . "/wp-admin/edit.php?page={$this_basename}&backup={$this->backup_file}"); |
| 326 |
} |
| 327 |
// we do this to say we're done. |
| 328 |
$this->backup_complete = true; |
| 329 |
} |
| 330 |
} |
| 331 |
|
| 332 |
function admin_menu() { |
| 333 |
add_management_page(__('Backup'), __('Backup'), 'import', basename(__FILE__), array(&$this, 'backup_menu')); |
| 334 |
} |
| 335 |
|
| 336 |
function fragment_menu() { |
| 337 |
add_management_page(__('Backup'), __('Backup'), 'import', basename(__FILE__), array(&$this, 'build_backup_script')); |
| 338 |
} |
| 339 |
|
| 340 |
function sql_addslashes($a_string = '', $is_like = FALSE) { |
| 341 |
/* |
| 342 |
Better addslashes for SQL queries. |
| 343 |
Taken from phpMyAdmin. |
| 344 |
*/ |
| 345 |
if ($is_like) { |
| 346 |
$a_string = str_replace('\\', '\\\\\\\\', $a_string); |
| 347 |
} else { |
| 348 |
$a_string = str_replace('\\', '\\\\', $a_string); |
| 349 |
} |
| 350 |
$a_string = str_replace('\'', '\\\'', $a_string); |
| 351 |
|
| 352 |
return $a_string; |
| 353 |
} // function sql_addslashes($a_string = '', $is_like = FALSE) |
| 354 |
|
| 355 |
function backquote($a_name) { |
| 356 |
/* |
| 357 |
Add backqouotes to tables and db-names in |
| 358 |
SQL queries. Taken from phpMyAdmin. |
| 359 |
*/ |
| 360 |
if (!empty($a_name) && $a_name != '*') { |
| 361 |
if (is_array($a_name)) { |
| 362 |
$result = array(); |
| 363 |
reset($a_name); |
| 364 |
while(list($key, $val) = each($a_name)) { |
| 365 |
$result[$key] = '`' . $val . '`'; |
| 366 |
} |
| 367 |
return $result; |
| 368 |
} else { |
| 369 |
return '`' . $a_name . '`'; |
| 370 |
} |
| 371 |
} else { |
| 372 |
return $a_name; |
| 373 |
} |
| 374 |
} // function backquote($a_name, $do_it = TRUE) |
| 375 |
|
| 376 |
function open($filename = '', $mode = 'w') { |
| 377 |
if ('' == $filename) return false; |
| 378 |
if ($this->gzip()) { |
| 379 |
$fp = @gzopen($filename, $mode); |
| 380 |
} else { |
| 381 |
$fp = @fopen($filename, $mode); |
| 382 |
} |
| 383 |
return $fp; |
| 384 |
} |
| 385 |
|
| 386 |
function close($fp) { |
| 387 |
if ($this->gzip()) { |
| 388 |
gzclose($fp); |
| 389 |
} else { |
| 390 |
fclose($fp); |
| 391 |
} |
| 392 |
} |
| 393 |
|
| 394 |
function stow($query_line) { |
| 395 |
if ($this->gzip()) { |
| 396 |
if(@gzwrite($this->fp, $query_line) === FALSE) { |
| 397 |
backup_error(__('There was an error writing a line to the backup script:')); |
| 398 |
backup_error(' ' . $query_line); |
| 399 |
} |
| 400 |
} else { |
| 401 |
if(@fwrite($this->fp, $query_line) === FALSE) { |
| 402 |
backup_error(__('There was an error writing a line to the backup script:')); |
| 403 |
backup_error(' ' . $query_line); |
| 404 |
} |
| 405 |
} |
| 406 |
} |
| 407 |
|
| 408 |
function backup_error($err) { |
| 409 |
if(count($this->backup_errors) < 20) { |
| 410 |
$this->backup_errors[] = $err; |
| 411 |
} elseif(count($this->backup_errors) == 20) { |
| 412 |
$this->backup_errors[] = __('Subsequent errors have been omitted from this log.'); |
| 413 |
} |
| 414 |
} |
| 415 |
|
| 416 |
function backup_table($table, $segment = 'none') { |
| 417 |
global $wpdb; |
| 418 |
|
| 419 |
/* |
| 420 |
Taken partially from phpMyAdmin and partially from |
| 421 |
Alain Wolf, Zurich - Switzerland |
| 422 |
Website: http://restkultur.ch/personal/wolf/scripts/db_backup/ |
| 423 |
|
| 424 |
Modified by Scott Merril (http://www.skippy.net/) |
| 425 |
to use the WordPress $wpdb object |
| 426 |
*/ |
| 427 |
|
| 428 |
$table_structure = $wpdb->get_results("DESCRIBE $table"); |
| 429 |
if (! $table_structure) { |
| 430 |
backup_errors(__('Error getting table details') . ": $table"); |
| 431 |
return FALSE; |
| 432 |
} |
| 433 |
|
| 434 |
if(($segment == 'none') || ($segment == 0)) { |
| 435 |
// Add SQL statement to drop existing table |
| 436 |
$this->stow("\n\n"); |
| 437 |
$this->stow("#\n"); |
| 438 |
$this->stow("# Delete any existing table " . $this->backquote($table) . "\n"); |
| 439 |
$this->stow("#\n"); |
| 440 |
$this->stow("\n"); |
| 441 |
$this->stow("DROP TABLE IF EXISTS " . $this->backquote($table) . ";\n"); |
| 442 |
|
| 443 |
// Table structure |
| 444 |
// Comment in SQL-file |
| 445 |
$this->stow("\n\n"); |
| 446 |
$this->stow("#\n"); |
| 447 |
$this->stow("# Table structure of table " . $this->backquote($table) . "\n"); |
| 448 |
$this->stow("#\n"); |
| 449 |
$this->stow("\n"); |
| 450 |
|
| 451 |
$create_table = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N); |
| 452 |
if (FALSE === $create_table) { |
| 453 |
$this->backup_error(sprintf(__("Error with SHOW CREATE TABLE for %s."), $table)); |
| 454 |
$this->stow("#\n# Error with SHOW CREATE TABLE for $table!\n#\n"); |
| 455 |
} |
| 456 |
$this->stow($create_table[0][1] . ' ;'); |
| 457 |
|
| 458 |
if (FALSE === $table_structure) { |
| 459 |
$this->backup_error(sprintf(__("Error getting table structure of %s"), $table)); |
| 460 |
$this->stow("#\n# Error getting table structure of $table!\n#\n"); |
| 461 |
} |
| 462 |
|
| 463 |
// Comment in SQL-file |
| 464 |
$this->stow("\n\n"); |
| 465 |
$this->stow("#\n"); |
| 466 |
$this->stow('# Data contents of table ' . $this->backquote($table) . "\n"); |
| 467 |
$this->stow("#\n"); |
| 468 |
} |
| 469 |
|
| 470 |
if(($segment == 'none') || ($segment >= 0)) { |
| 471 |
$ints = array(); |
| 472 |
foreach ($table_structure as $struct) { |
| 473 |
if ( (0 === strpos($struct->Type, 'tinyint')) || |
| 474 |
(0 === strpos(strtolower($struct->Type), 'smallint')) || |
| 475 |
(0 === strpos(strtolower($struct->Type), 'mediumint')) || |
| 476 |
(0 === strpos(strtolower($struct->Type), 'int')) || |
| 477 |
(0 === strpos(strtolower($struct->Type), 'bigint')) || |
| 478 |
(0 === strpos(strtolower($struct->Type), 'timestamp')) ) { |
| 479 |
$ints[strtolower($struct->Field)] = "1"; |
| 480 |
} |
| 481 |
} |
| 482 |
|
| 483 |
|
| 484 |
// Batch by $row_inc |
| 485 |
|
| 486 |
if($segment == 'none') { |
| 487 |
$row_start = 0; |
| 488 |
$row_inc = ROWS_PER_SEGMENT; |
| 489 |
} else { |
| 490 |
$row_start = $segment * ROWS_PER_SEGMENT; |
| 491 |
$row_inc = ROWS_PER_SEGMENT; |
| 492 |
} |
| 493 |
|
| 494 |
do { |
| 495 |
if ( !ini_get('safe_mode')) @set_time_limit(15*60); |
| 496 |
$table_data = $wpdb->get_results("SELECT * FROM $table LIMIT {$row_start}, {$row_inc}", ARRAY_A); |
| 497 |
|
| 498 |
/* |
| 499 |
if (FALSE === $table_data) { |
| 500 |
$wp_backup_error .= "Error getting table contents from $table\r\n"; |
| 501 |
fwrite($fp, "#\n# Error getting table contents fom $table!\n#\n"); |
| 502 |
} |
| 503 |
*/ |
| 504 |
|
| 505 |
$entries = 'INSERT INTO ' . $this->backquote($table) . ' VALUES ('; |
| 506 |
// \x08\\x09, not required |
| 507 |
$search = array("\x00", "\x0a", "\x0d", "\x1a"); |
| 508 |
$replace = array('\0', '\n', '\r', '\Z'); |
| 509 |
if($table_data) { |
| 510 |
foreach ($table_data as $row) { |
| 511 |
$values = array(); |
| 512 |
foreach ($row as $key => $value) { |
| 513 |
if ($ints[strtolower($key)]) { |
| 514 |
$values[] = $value; |
| 515 |
} else { |
| 516 |
$values[] = "'" . str_replace($search, $replace, $this->sql_addslashes($value)) . "'"; |
| 517 |
} |
| 518 |
} |
| 519 |
$this->stow(" \n" . $entries . implode(', ', $values) . ') ;'); |
| 520 |
} |
| 521 |
$row_start += $row_inc; |
| 522 |
} |
| 523 |
} while((count($table_data) > 0) and ($segment=='none')); |
| 524 |
} |
| 525 |
|
| 526 |
|
| 527 |
if(($segment == 'none') || ($segment < 0)) { |
| 528 |
// Create footer/closing comment in SQL-file |
| 529 |
$this->stow("\n"); |
| 530 |
$this->stow("#\n"); |
| 531 |
$this->stow("# End of data contents of table " . $this->backquote($table) . "\n"); |
| 532 |
$this->stow("# --------------------------------------------------------\n"); |
| 533 |
$this->stow("\n"); |
| 534 |
} |
| 535 |
|
| 536 |
} // end backup_table() |
| 537 |
|
| 538 |
function return_bytes($val) { |
| 539 |
$val = trim($val); |
| 540 |
$last = strtolower($val{strlen($val)-1}); |
| 541 |
switch($last) { |
| 542 |
// The 'G' modifier is available since PHP 5.1.0 |
| 543 |
case 'g': |
| 544 |
$val *= 1024; |
| 545 |
case 'm': |
| 546 |
$val *= 1024; |
| 547 |
case 'k': |
| 548 |
$val *= 1024; |
| 549 |
} |
| 550 |
|
| 551 |
return $val; |
| 552 |
} |
| 553 |
|
| 554 |
function db_backup($core_tables, $other_tables) { |
| 555 |
global $table_prefix, $wpdb; |
| 556 |
|
| 557 |
$datum = date("Ymd_B"); |
| 558 |
$wp_backup_filename = DB_NAME . "_$table_prefix$datum.sql"; |
| 559 |
if ($this->gzip()) { |
| 560 |
$wp_backup_filename .= '.gz'; |
| 561 |
} |
| 562 |
|
| 563 |
if (is_writable(ABSPATH . $this->backup_dir)) { |
| 564 |
$this->fp = $this->open(ABSPATH . $this->backup_dir . $wp_backup_filename); |
| 565 |
if(!$this->fp) { |
| 566 |
$this->backup_error(__('Could not open the backup file for writing!')); |
| 567 |
return false; |
| 568 |
} |
| 569 |
} else { |
| 570 |
$this->backup_error(__('The backup directory is not writeable!')); |
| 571 |
return false; |
| 572 |
} |
| 573 |
|
| 574 |
//Begin new backup of MySql |
| 575 |
$this->stow("# WordPress MySQL database backup\n"); |
| 576 |
$this->stow("#\n"); |
| 577 |
$this->stow("# Generated: " . date("l j. F Y H:i T") . "\n"); |
| 578 |
$this->stow("# Hostname: " . DB_HOST . "\n"); |
| 579 |
$this->stow("# Database: " . $this->backquote(DB_NAME) . "\n"); |
| 580 |
$this->stow("# --------------------------------------------------------\n"); |
| 581 |
|
| 582 |
if ( (is_array($other_tables)) && (count($other_tables) > 0) ) |
| 583 |
$tables = array_merge($core_tables, $other_tables); |
| 584 |
else |
| 585 |
$tables = $core_tables; |
| 586 |
|
| 587 |
foreach ($tables as $table) { |
| 588 |
// Increase script execution time-limit to 15 min for every table. |
| 589 |
if ( !ini_get('safe_mode')) @set_time_limit(15*60); |
| 590 |
// Create the SQL statements |
| 591 |
$this->stow("# --------------------------------------------------------\n"); |
| 592 |
$this->stow("# Table: " . $this->backquote($table) . "\n"); |
| 593 |
$this->stow("# --------------------------------------------------------\n"); |
| 594 |
$this->backup_table($table); |
| 595 |
} |
| 596 |
|
| 597 |
$this->close($this->fp); |
| 598 |
|
| 599 |
if (count($this->backup_errors)) { |
| 600 |
return false; |
| 601 |
} else { |
| 602 |
return $wp_backup_filename; |
| 603 |
} |
| 604 |
|
| 605 |
} //wp_db_backup |
| 606 |
|
| 607 |
function deliver_backup ($filename = '', $delivery = 'http', $recipient = '') { |
| 608 |
if ('' == $filename) { return FALSE; } |
| 609 |
|
| 610 |
$diskfile = ABSPATH . $this->backup_dir . $filename; |
| 611 |
if ('http' == $delivery) { |
| 612 |
if (! file_exists($diskfile)) { |
| 613 |
$msg = sprintf(__('File not found:%s'), "<br /><strong>$filename</strong><br />"); |
| 614 |
$this_basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__); |
| 615 |
$msg .= '<br /><a href="' . get_option('siteurl') . "/wp-admin/edit.php?page={$this_basename}" . '">' . __('Return to Backup'); |
| 616 |
die($msg); |
| 617 |
} |
| 618 |
header('Content-Description: File Transfer'); |
| 619 |
header('Content-Type: application/octet-stream'); |
| 620 |
header('Content-Length: ' . filesize($diskfile)); |
| 621 |
header("Content-Disposition: attachment; filename=$filename"); |
| 622 |
readfile($diskfile); |
| 623 |
unlink($diskfile); |
| 624 |
} elseif ('smtp' == $delivery) { |
| 625 |
if (! file_exists($diskfile)) return false; |
| 626 |
|
| 627 |
if (! is_email ($recipient)) { |
| 628 |
$recipient = get_option('admin_email'); |
| 629 |
} |
| 630 |
$randomish = md5(time()); |
| 631 |
$boundary = "==WPBACKUP-BY-SKIPPY-$randomish"; |
| 632 |
$fp = fopen($diskfile,"rb"); |
| 633 |
$file = fread($fp,filesize($diskfile)); |
| 634 |
$this->close($fp); |
| 635 |
$data = chunk_split(base64_encode($file)); |
| 636 |
$headers = "MIME-Version: 1.0\n"; |
| 637 |
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n"; |
| 638 |
$headers .= 'From: ' . get_option('admin_email') . "\n"; |
| 639 |
|
| 640 |
$message = sprintf(__("Attached to this email is\n %1s\n Size:%2s kilobytes\n"), $filename, round(filesize($diskfile)/1024)); |
| 641 |
// Add a multipart boundary above the plain message |
| 642 |
$message = "This is a multi-part message in MIME format.\n\n" . |
| 643 |
"--{$boundary}\n" . |
| 644 |
"Content-Type: text/plain; charset=\"utf-8\"\n" . |
| 645 |
"Content-Transfer-Encoding: 7bit\n\n" . |
| 646 |
$message . "\n\n"; |
| 647 |
|
| 648 |
// Add file attachment to the message |
| 649 |
$message .= "--{$boundary}\n" . |
| 650 |
"Content-Type: application/octet-stream;\n" . |
| 651 |
" name=\"{$filename}\"\n" . |
| 652 |
"Content-Disposition: attachment;\n" . |
| 653 |
" filename=\"{$filename}\"\n" . |
| 654 |
"Content-Transfer-Encoding: base64\n\n" . |
| 655 |
$data . "\n\n" . |
| 656 |
"--{$boundary}--\n"; |
| 657 |
|
| 658 |
if (function_exists('wp_mail')) { |
| 659 |
wp_mail ($recipient, get_bloginfo('name') . ' ' . __('Database Backup'), $message, $headers); |
| 660 |
} else { |
| 661 |
mail ($recipient, get_bloginfo('name') . ' ' . __('Database Backup'), $message, $headers); |
| 662 |
} |
| 663 |
|
| 664 |
unlink($diskfile); |
| 665 |
} |
| 666 |
return; |
| 667 |
} |
| 668 |
|
| 669 |
function backup_menu() { |
| 670 |
global $table_prefix, $wpdb; |
| 671 |
$feedback = ''; |
| 672 |
$WHOOPS = FALSE; |
| 673 |
|
| 674 |
// did we just do a backup? If so, let's report the status |
| 675 |
if ( $this->backup_complete ) { |
| 676 |
$feedback = '<div class="updated"><p>' . __('Backup Successful') . '!'; |
| 677 |
$file = $this->backup_file; |
| 678 |
switch($_POST['deliver']) { |
| 679 |
case 'http': |
| 680 |
$feedback .= '<br />' . sprintf(__('Your backup file: <a href="%1s">%2s</a> should begin downloading shortly.'), get_option('siteurl') . "/{$this->backup_dir}{$this->backup_file}", $this->backup_file); |
| 681 |
break; |
| 682 |
case 'smtp': |
| 683 |
if (! is_email($_POST['backup_recipient'])) { |
| 684 |
$feedback .= get_option('admin_email'); |
| 685 |
} else { |
| 686 |
$feedback .= $_POST['backup_recipient']; |
| 687 |
} |
| 688 |
$feedback = '<br />' . sprintf(__('Your backup has been emailed to %s'), $feedback); |
| 689 |
break; |
| 690 |
case 'none': |
| 691 |
$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"'); |
| 692 |
$feedback .= ':<br /> <a href="' . get_option('siteurl') . "/{$this->backup_dir}$file\">$file</a> : " . sprintf(__('%s bytes'), filesize(ABSPATH . $this->backup_dir . $file)); |
| 693 |
} |
| 694 |
$feedback .= '</p></div>'; |
| 695 |
} |
| 696 |
|
| 697 |
if (count($this->backup_errors)) { |
| 698 |
$feedback .= '<div class="updated error">' . __('The following errors were reported:') . "<pre>"; |
| 699 |
foreach($this->backup_errors as $error) { |
| 700 |
$feedback .= "{$error}\n"; //Errors are already localized |
| 701 |
} |
| 702 |
$feedback .= "</pre></div>"; |
| 703 |
} |
| 704 |
|
| 705 |
// did we just save options for wp-cron? |
| 706 |
if ( (function_exists('wp_schedule_event') || function_exists('wp_cron_init')) |
| 707 |
&& isset($_POST['wp_cron_backup_options']) ) : |
| 708 |
if ( function_exists('wp_schedule_event') ) { |
| 709 |
wp_clear_scheduled_hook( 'wp_db_backup_cron' ); // unschedule previous |
| 710 |
$scheds = (array) wp_get_schedules(); |
| 711 |
$name = strval($_POST['wp_cron_schedule']); |
| 712 |
$interval = ( isset($scheds[$name]['interval']) ) ? |
| 713 |
(int) $scheds[$name]['interval'] : 0; |
| 714 |
update_option('wp_cron_backup_schedule', $name, FALSE); |
| 715 |
if ( ! 0 == $interval ) { |
| 716 |
wp_schedule_event(time() + $interval, $name, 'wp_db_backup_cron'); |
| 717 |
} |
| 718 |
} |
| 719 |
else { |
| 720 |
update_option('wp_cron_backup_schedule', intval($_POST['cron_schedule']), FALSE); |
| 721 |
} |
| 722 |
update_option('wp_cron_backup_tables', $_POST['wp_cron_backup_tables']); |
| 723 |
if (is_email($_POST['cron_backup_recipient'])) { |
| 724 |
update_option('wp_cron_backup_recipient', $_POST['cron_backup_recipient'], FALSE); |
| 725 |
} |
| 726 |
$feedback .= '<div class="updated"><p>' . __('Scheduled Backup Options Saved!') . '</p></div>'; |
| 727 |
endif; |
| 728 |
|
| 729 |
$other_tables = array(); |
| 730 |
$also_backup = array(); |
| 731 |
|
| 732 |
// Get complete db table list |
| 733 |
$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N); |
| 734 |
$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables); |
| 735 |
// Get list of WP tables that actually exist in this DB (for 1.6 compat!) |
| 736 |
$wp_backup_default_tables = array_intersect($all_tables, $this->core_table_names); |
| 737 |
// Get list of non-WP tables |
| 738 |
$other_tables = array_diff($all_tables, $wp_backup_default_tables); |
| 739 |
|
| 740 |
if ('' != $feedback) { |
| 741 |
echo $feedback; |
| 742 |
} |
| 743 |
|
| 744 |
// Give the new dirs the same perms as wp-content. |
| 745 |
$stat = stat( ABSPATH . 'wp-content' ); |
| 746 |
$dir_perms = $stat['mode'] & 0000777; // Get the permission bits. |
| 747 |
|
| 748 |
if ( !file_exists( ABSPATH . $this->backup_dir) ) { |
| 749 |
if ( @ mkdir( ABSPATH . $this->backup_dir) ) { |
| 750 |
@ chmod( ABSPATH . $this->backup_dir, $dir_perms); |
| 751 |
} else { |
| 752 |
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>"; |
| 753 |
$WHOOPS = TRUE; |
| 754 |
} |
| 755 |
} |
| 756 |
|
| 757 |
if ( !is_writable( ABSPATH . $this->backup_dir) ) { |
| 758 |
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>"; |
| 759 |
} |
| 760 |
|
| 761 |
if ( !file_exists( ABSPATH . $this->backup_dir . 'index.php') ) { |
| 762 |
@ touch( ABSPATH . $this->backup_dir . "index.php"); |
| 763 |
} |
| 764 |
|
| 765 |
?><div class='wrap'> |
| 766 |
<h2><?php _e('Backup') ?></h2> |
| 767 |
<form method="post" action=""> |
| 768 |
<fieldset class="options"><legend><?php _e('Tables') ?></legend> |
| 769 |
<table align="center" cellspacing="5" cellpadding="5"><tr><td width="50%" align="left" class="alternate" valign="top"> |
| 770 |
<?php _e('These core WordPress tables will always be backed up:') ?><br /><ul><?php |
| 771 |
foreach ($wp_backup_default_tables as $table) { |
| 772 |
echo "<li><input type='hidden' name='core_tables[]' value='$table' />$table</li>"; |
| 773 |
} |
| 774 |
?></ul></td><td width="50%" align="left" valign="top"><?php |
| 775 |
if (count($other_tables) > 0) { |
| 776 |
echo __('You may choose to include any of the following tables:') . ' <br />'; |
| 777 |
foreach ($other_tables as $table) { |
| 778 |
echo "<label style=\"display:block;\"><input type='checkbox' name='other_tables[]' value='{$table}' /> {$table}</label>"; |
| 779 |
} |
| 780 |
} |
| 781 |
?></td></tr></table></fieldset> |
| 782 |
<fieldset class="options"><legend><?php _e('Backup Options') ?></legend> |
| 783 |
<?php _e('What to do with the backup file:') ?><br /> |
| 784 |
<label for="do_save" style="display:block;"><input type="radio" id="do_save" name="deliver" value="none" style="border:none;" /> |
| 785 |
<?php echo __('Save to server') . " ({$this->backup_dir})</label>"; |
| 786 |
?><label for="do_download" style="display:block;"><input type="radio" checked="checked" id="do_download" name="deliver" value="http" style="border:none;" /> |
| 787 |
<?php _e('Download to your computer') ?></label> |
| 788 |
<label for="do_email"><input type="radio" name="deliver" id="do_email" value="smtp" style="border:none;" /> |
| 789 |
<?php _e('Email backup to:') ?></label><input type="text" name="backup_recipient" size="20" value="<?php echo get_option('admin_email') ?>" /> |
| 790 |
|
| 791 |
<?php |
| 792 |
// Check DB dize. |
| 793 |
$table_status = $wpdb->get_results("SHOW TABLE STATUS FROM " . $this->backquote(DB_NAME)); |
| 794 |
$core_size = $db_size = 0; |
| 795 |
foreach($table_status as $table) { |
| 796 |
$table_size = $table->Data_length - $table->Data_free; |
| 797 |
if(in_array($table->Name, $wp_backup_default_tables)) { |
| 798 |
$core_size += $table_size; |
| 799 |
} |
| 800 |
$db_size += $table_size; |
| 801 |
} |
| 802 |
$mem_limit = ini_get('memory_limit'); |
| 803 |
$mem_limit = $this->return_bytes($mem_limit); |
| 804 |
$mem_limit = ($mem_limit == 0) ? 8*1024*1024 : $mem_limit - 2000000; |
| 805 |
|
| 806 |
if (! $WHOOPS) { |
| 807 |
echo '<input type="hidden" name="do_backup" id="do_backup" value="backup" />'; |
| 808 |
echo '<p class="submit"><input type="submit" name="submit" onclick="document.getElementById(\'do_backup\').value=\'fragments\';" value="' . __('Backup') . '!" /></p>'; |
| 809 |
} else { |
| 810 |
echo '<p class="alternate">' . __('WARNING: Your backup directory is <strong>NOT</strong> writable!') . '</p>'; |
| 811 |
} |
| 812 |
echo '</fieldset>'; |
| 813 |
echo '</form>'; |
| 814 |
|
| 815 |
// this stuff only displays if some sort of wp-cron is available |
| 816 |
$cron = ( function_exists('wp_schedule_event') ) ? true : false; // wp-cron in WP 2.1+ |
| 817 |
$cron_old = ( function_exists('wp_cron_init') && ! $cron ) ? true : false; // wp-cron plugin by Skippy |
| 818 |
if ( $cron_old || $cron ) : |
| 819 |
echo '<fieldset class="options"><legend>' . __('Scheduled Backup') . '</legend>'; |
| 820 |
$datetime = get_option('date_format') . ' @ ' . get_option('time_format'); |
| 821 |
if ( $cron ) : |
| 822 |
if ( ! ( 'never' == $this->get_sched() ) ) : |
| 823 |
echo '<p>' . __('Next Backup') . ': '; |
| 824 |
echo gmdate($datetime, wp_next_scheduled('wp_db_backup_cron') + (get_option('gmt_offset') * 3600)) . '</p>'; |
| 825 |
endif; |
| 826 |
elseif ( $cron_old ) : |
| 827 |
echo '<p>' . __('Last WP-Cron Daily Execution') . ': ' . gmdate($datetime, get_option('wp_cron_daily_lastrun') + (get_option('gmt_offset') * 3600)) . '<br />'; |
| 828 |
echo __('Next WP-Cron Daily Execution') . ': ' . gmdate($datetime, (get_option('wp_cron_daily_lastrun') + (get_option('gmt_offset') * 3600) + 86400)) . '</p>'; |
| 829 |
endif; |
| 830 |
?><form method="post" action=""> |
| 831 |
<table width="100%" cellpadding="5" cellspacing="5"> |
| 832 |
<tr><td align="center"><?php |
| 833 |
echo __('Schedule: '); |
| 834 |
if ( $cron_old ) : |
| 835 |
$wp_cron_backup_schedule = get_option('wp_cron_backup_schedule'); |
| 836 |
$schedule = array(0 => __('None'), 1 => __('Daily')); |
| 837 |
foreach ($schedule as $value => $name) { |
| 838 |
echo ' <input type="radio" style="border:none;" name="cron_schedule"'; |
| 839 |
if ($wp_cron_backup_schedule == $value) { |
| 840 |
echo ' checked="checked" '; |
| 841 |
} |
| 842 |
echo 'value="' . $value . '" /> ' . __($name); |
| 843 |
} |
| 844 |
elseif ( $cron ) : |
| 845 |
echo apply_filters('wp_db_b_schedule_choices', wp_get_schedules() ); |
| 846 |
endif; |
| 847 |
echo '</td><td align="center">'; |
| 848 |
$cron_recipient = get_option('wp_cron_backup_recipient'); |
| 849 |
if (! is_email($cron_recipient)) { |
| 850 |
$cron_recipient = get_option('admin_email'); |
| 851 |
} |
| 852 |
echo __('Email backup to:') . ' <input type="text" name="cron_backup_recipient" size="20" value="' . $cron_recipient . '" />'; |
| 853 |
echo '</td></tr>'; |
| 854 |
$cron_tables = get_option('wp_cron_backup_tables'); |
| 855 |
if (! is_array($cron_tables)) { |
| 856 |
$cron_tables = array(); |
| 857 |
} |
| 858 |
if (count($other_tables) > 0) { |
| 859 |
echo '<tr><td colspan="2" align="left">' . __('Tables to include:') . '<br />'; |
| 860 |
foreach ($other_tables as $table) { |
| 861 |
echo '<input type="checkbox" '; |
| 862 |
if (in_array($table, $cron_tables)) { |
| 863 |
echo 'checked=checked '; |
| 864 |
} |
| 865 |
echo "name='wp_cron_backup_tables[]' value='{$table}' /> {$table}<br />"; |
| 866 |
} |
| 867 |
echo '</td></tr>'; |
| 868 |
} |
| 869 |
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>'; |
| 870 |
echo '</fieldset>'; |
| 871 |
endif; // end of wp_cron (legacy) section |
| 872 |
|
| 873 |
echo '</div>'; |
| 874 |
|
| 875 |
} // end wp_backup_menu() |
| 876 |
|
| 877 |
function get_sched() { |
| 878 |
$options = array_keys( (array) wp_get_schedules() ); |
| 879 |
$freq = get_option('wp_cron_backup_schedule'); |
| 880 |
$freq = ( in_array( $freq , $options ) ) ? $freq : 'never'; |
| 881 |
return $freq; |
| 882 |
} |
| 883 |
|
| 884 |
function schedule_choices($schedule) { // create the cron menu based on the schedule |
| 885 |
$wp_cron_backup_schedule = $this->get_sched(); |
| 886 |
$sort = array(); |
| 887 |
foreach ( (array) $schedule as $key => $value ) $sort[$key] = $value['interval']; |
| 888 |
asort( $sort ); |
| 889 |
$schedule_sorted = array(); |
| 890 |
foreach ( (array) $sort as $key => $value ) $schedule_sorted[$key] = $schedule[$key]; |
| 891 |
$menu = '<ul style="list-style: none; text-align: left">'; |
| 892 |
$schedule = array_merge( array( 'never' => array( 'interval' => 0, 'display' => __('Never') ) ), |
| 893 |
(array) $schedule_sorted ); |
| 894 |
foreach ( $schedule as $name => $settings) { |
| 895 |
$interval = (int) $settings['interval']; |
| 896 |
if ( 0 == $interval && ! 'never' == $name ) continue; |
| 897 |
$display = ( ! '' == $settings['display'] ) ? $settings['display'] : sprintf(__('%s seconds'),$interval); |
| 898 |
$menu .= "<li><input type='radio' name='wp_cron_schedule' style='border:none;'"; |
| 899 |
if ($wp_cron_backup_schedule == $name) { |
| 900 |
$menu .= ' checked="checked" '; |
| 901 |
} |
| 902 |
$menu .= "value='$name' /> $display</li>"; |
| 903 |
} |
| 904 |
$menu .= '</ul>'; |
| 905 |
return $menu; |
| 906 |
} // end schedule_choices() |
| 907 |
|
| 908 |
function wp_cron_daily() { // for legacy cron plugin |
| 909 |
$schedule = intval(get_option('wp_cron_backup_schedule')); |
| 910 |
if (0 == $schedule) { |
| 911 |
// Scheduled backup is disabled |
| 912 |
return; |
| 913 |
} |
| 914 |
else { $this->cron_backup(); } |
| 915 |
} // wp_cron_daily |
| 916 |
|
| 917 |
function cron_backup() { |
| 918 |
global $table_prefix, $wpdb; |
| 919 |
|
| 920 |
$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N); |
| 921 |
$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables); |
| 922 |
$core_tables = array_intersect($all_tables, $this->core_table_names); |
| 923 |
$other_tables = get_option('wp_cron_backup_tables'); |
| 924 |
|
| 925 |
$recipient = get_option('wp_cron_backup_recipient'); |
| 926 |
|
| 927 |
$backup_file = $this->db_backup($core_tables, $other_tables); |
| 928 |
if (FALSE !== $backup_file) { |
| 929 |
$this->deliver_backup ($backup_file, 'smtp', $recipient); |
| 930 |
} |
| 931 |
return; |
| 932 |
} |
| 933 |
|
| 934 |
function add_sched_options($sched) { |
| 935 |
$sched['weekly'] = array('interval' => 604800, 'display' => __('Once Weekly')); |
| 936 |
return $sched; |
| 937 |
} |
| 938 |
|
| 939 |
function user_can_backup() { |
| 940 |
return current_user_can('import'); |
| 941 |
} |
| 942 |
|
| 943 |
function validate_file($file) { |
| 944 |
if (false !== strpos($file, '..')) |
| 945 |
die(__("Cheatin' uh ?")); |
| 946 |
|
| 947 |
if (false !== strpos($file, './')) |
| 948 |
die(__("Cheatin' uh ?")); |
| 949 |
|
| 950 |
if (':' == substr($file, 1, 1)) |
| 951 |
die(__("Cheatin' uh ?")); |
| 952 |
} |
| 953 |
|
| 954 |
} |
| 955 |
|
| 956 |
function wpdbBackup_init() { |
| 957 |
global $mywpdbbackup; |
| 958 |
$mywpdbbackup = new wpdbBackup(); |
| 959 |
} |
| 960 |
|
| 961 |
add_action('plugins_loaded', 'wpdbBackup_init'); |
| 962 |
|
| 963 |
?> |
| 964 |
|