[ Index ]

WordPress Source Cross Reference

title

Body

[close]

/wp-content/plugins/ -> wp-db-backup.php (source)

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

Your comment here...

Name: Location:
Comments:


List: Classes | Functions | Variables | Constants | Tables

Generated: Sat Jul 15 11:57:04 2006 Courtesy of Taragana