Example #1
0
 /**
  * @param $excluded_tables     array Which tables to exclude from exporting. Null or empty array to exclude none
  * @param $include_tables      array Which tables to include (before considering exclusions. Null to include all
  * @param $time_limit_in_hours int How long to make the PHP execution time limit
  * @return array Information about the database snapshot
  */
 static function export_database($excluded_tables = null, $include_tables = null, $time_limit_in_hours = 2)
 {
     require_once 'synthesis-backup-status.php';
     $synthesis_backup_dir = self::get_backup_dir();
     $synthesis_backup_dir_index = $synthesis_backup_dir . 'index.html';
     if (!file_exists($synthesis_backup_dir)) {
         mkdir($synthesis_backup_dir, 0755, true);
     }
     if (!file_exists($synthesis_backup_dir_index)) {
         $index = fopen($synthesis_backup_dir_index, 'w');
         fclose($index);
     }
     // Create a unique GUID for this backup.
     $backup_id = wp_generate_password(12, false, false);
     self::$backup_id = $backup_id;
     $backup_dir = $synthesis_backup_dir . $backup_id . '/';
     $backup_dir_tables = $backup_dir . 'tables/';
     if (!file_exists($backup_dir)) {
         mkdir($backup_dir, 0755);
     }
     if (!file_exists($backup_dir_tables)) {
         mkdir($backup_dir_tables);
     }
     self::increase_php_limits(false, $time_limit_in_hours);
     $tables = $include_tables;
     if (is_null($tables)) {
         $tables = self::get_col('SHOW TABLES');
     }
     if (is_null($excluded_tables)) {
         $excluded_tables = array();
     }
     $tables = array_diff($tables, $excluded_tables);
     $status_path = $backup_dir . self::BACKUP_STATUS_FILE_NAME;
     $status = new Synthesis_Backup_Status($status_path);
     foreach ($tables as $raw_table) {
         // Tables can theoretically contain backticks, so they must be escaped
         $table = str_replace('`', '``', $raw_table);
         // Get the number of rows in the table.
         $row_count = self::get_var("SELECT COUNT(*) FROM `{$table}`");
         // Tables start as pending...
         $status_code = Synthesis_Backup_Status::TABLE_STATUS_PENDING;
         if ($row_count > self::MAX_TABLE_SIZE) {
             // ... unless there are too many rows
             $status_code = Synthesis_Backup_Status::BACKUP_STATUS_SKIPPED;
         }
         // Add this table to the status file.
         $status->add_table($raw_table, $status_code, $row_count);
     }
     $backup_timestamp = current_time('timestamp');
     $status->set_start($backup_timestamp);
     $status->write();
     $backup_zip = 'backup_' . date('m-d-Y_H-i-s', current_time('timestamp')) . '.zip';
     $backup_zip_path = $backup_dir . $backup_zip;
     $snapshot_info = array('path' => $backup_zip_path, 'url' => self::get_backup_url() . '/' . $backup_id . '/' . $backup_zip, 'timestamp' => $backup_timestamp, 'id' => $backup_id);
     $status->set_snapshot_info($snapshot_info);
     // Create our Zip File
     $zip = new ZipArchive();
     $zip->open($backup_zip_path, ZIPARCHIVE::CREATE);
     // Backup tables
     foreach ($tables as $table) {
         if (self::is_backup_halt_requested()) {
             $status->set_status_code(Synthesis_Backup_Status::BACKUP_STATUS_CANCELLED);
             break;
         } else {
             if ($status->get_table_status_code($table) == Synthesis_Backup_Status::TABLE_STATUS_SKIPPED) {
                 // Don't backup tables we've decided to skip
                 continue;
             }
         }
         $status->set_table_status_code($table, Synthesis_Backup_Status::TABLE_STATUS_PROCESSING);
         $status->set_table_start($table, current_time('timestamp'));
         $status->write();
         $export_path = $backup_dir . 'tables/' . $table . '/';
         mkdir($export_path);
         $table_result = self::export_table($table, $export_path, $status);
         $status->set_table_status_code($table, $table_result);
         $status->set_table_end($table, current_time('timestamp'));
         $status->write();
         $full_path = trailingslashit($export_path) . $table . self::FULL_SUFFIX;
         $zip->addFile($full_path, $table . '.sql');
     }
     $status->set_end(current_time('timestamp'));
     $status->set_status_code(Synthesis_Backup_Status::BACKUP_STATUS_FINISHED);
     $status->write();
     $zip->close();
     self::cleanup_old_folders();
     self::end_backup();
     // Force a write to update the timestamp.
     $status->write(true);
     return $snapshot_info;
 }
		<strong><?php 
printf(__("Tables with more than %s rows will not be included in snapshots"), number_format(Synthesis_DB_Backup::MAX_TABLE_SIZE));
?>
</strong>
	</p>

	<p>
		<?php 
$upload_dir = wp_upload_dir();
printf(__('All DB backups are stored in %s'), trailingslashit($upload_dir['basedir']) . Synthesis_DB_Backup::BACKUP_FOLDER . '/');
?>
	</p>

	<form action="" method="post">
		<button class="button" id="take-database-snapshot" <?php 
disabled(false != Synthesis_DB_Backup::is_backup_running());
?>
>New DB Snapshot</button>
		<span class="spinner" id="db-snapshot-spinner" style="float: none; display: none"></span>
	</form>

	<p>
        <a href="" style="display: none" id="db-snapshot-download-link"><?php 
_e('Download last snapshot');
?>
</a>
	</p>

	<div id="db-snapshot-progress" class="smash-container">
		<?php 
Synthesis_Software_Monitor::db_snapshots_markup();
 public static function db_snapshots_markup($snapshot_id = false)
 {
     // Get the previous ID if the snapshot isn't running
     if (empty($snapshot_id)) {
         $most_recent_id = Synthesis_DB_Backup::is_backup_running();
         $is_running = !empty($most_recent_id);
         if ($is_running) {
             $snapshot_id = $most_recent_id;
         } else {
             $snapshot_id = self::get_db_snapshot();
             if (!isset($snapshot_id['id'])) {
                 echo '<p>';
                 _e('You haven\'t taken any snapshots');
                 echo '</p>';
                 return;
             }
             $snapshot_id = $snapshot_id['id'];
         }
     }
     $backup_status = Synthesis_DB_Backup::load_backup_status_from_id($snapshot_id);
     $restore_status = Synthesis_DB_Backup::load_restore_status_from_id($snapshot_id);
     if (!$backup_status->is_loaded_from_file()) {
         echo '<p>';
         _e('Unable to get backup status. The backup files appear to be missing.');
         echo '</p>';
         return;
     }
     // TODO: Make this a friendly message
     $status_message = $backup_status->get_status_code();
     // Get the list of tables.
     $table_names = $backup_status->get_table_names();
     // Calculate totals
     $total_rows = 0;
     $total_processed = 0;
     foreach ($table_names as $table_name) {
         if (Synthesis_Backup_Status::TABLE_STATUS_SKIPPED != $backup_status->get_table_status_code($table_name)) {
             $total_rows += $backup_status->get_table_row_count($table_name, 0);
             $total_processed += $backup_status->get_table_current_row($table_name, 0);
         }
     }
     $percent_total = $total_processed / $total_rows * 100;
     $format_string = '%d / %d (%.2f%%)';
     $backup_title = '';
     if ('finished' == $status_message) {
         $length_string = self::get_duration_string($backup_status->get_start(), $backup_status->get_end());
         $backup_title = sprintf('Snapshot finished at %s (total time: %s)', date('h:i a \\o\\n M d Y', $backup_status->get_end()), $length_string);
     } elseif ('started' == $status_message) {
         $length_string = self::get_duration_string($backup_status['start'], current_time('timestamp'));
         $backup_title = sprintf('Snapshot started at %s (%s ago)', date('h:i a \\o\\n M d Y', $backup_status->get_start()), $length_string);
     } elseif ('cancelled' == $status_message) {
         $backup_title = "Snapshot cancelled";
     }
     echo '<div class="smash-panel"><div id="db-backup-header" class="collapsible">';
     echo '<span id="db-backup-message">' . $backup_title . '</span>';
     echo '<span id="db-backup-status" style="float: right">' . sprintf($format_string, $total_processed, $total_rows, $percent_total) . '</span></div>';
     echo '<div><table class="db-backup-details" style="width: 100%"><thead><tr>';
     echo '<th>' . __('Table Name') . '</th>';
     echo '<th>' . __('Status') . '</th>';
     echo '<th style="text-align: right">' . __('Backup Status') . '</th>';
     echo '<th>' . __('Restore') . '</th>';
     echo '<th>' . __('Restore Status') . '</th>';
     echo '</tr></thead>';
     //echo $status;
     // Old backup versions don't support web-based restore. Defaults to false if not present.
     $able_to_restore = $backup_status->get_version();
     foreach ($table_names as $table_name) {
         $current_row = $backup_status->get_table_current_row($table_name, 0);
         $row_count = $backup_status->get_table_row_count($table_name, 0);
         $table_status_code = $backup_status->get_table_status_code($table_name);
         if (Synthesis_Backup_Status::TABLE_STATUS_SKIPPED == $table_status_code) {
             $backup_progress = sprintf('%s / %s (%s)', $current_row, $row_count, "skipped");
         } else {
             $percentDone = 0 == $row_count ? 100 : $current_row / $row_count * 100;
             $backup_progress = sprintf($format_string, $current_row, $row_count, $percentDone);
         }
         $table_restore_status = isset($restore_status[$table_name]) ? $restore_status[$table_name] : array();
         if (!$able_to_restore) {
             $restore_link = '';
         } else {
             if (empty($table_restore_status) || 'nothing' == $table_restore_status['status'] || 'restored' == $table_restore_status['status'] || 'cancelled' == $table_restore_status['status']) {
                 $restore_link = '<a class="restore-table" href="#" data-table-name="' . esc_attr($table_name) . '" data-backup-id="' . esc_attr($snapshot_id) . '">' . __('restore') . '</a>';
             } else {
                 $restore_link = '<a class="cancel-restore" href="#" data-table-name="' . esc_attr($table_name) . '" data-backup-id="' . esc_attr($snapshot_id) . '">' . __('cancel') . '</a>';
             }
         }
         if (isset($table_restore_status['status']) && 'restored' == $table_restore_status['status']) {
             $restore_progress = sprintf('Restored at %s', date('h:i a \\o\\n M d Y', $table_restore_status['last_update']));
         } elseif (isset($table_restore_status['status']) && 'cancelled' == $table_restore_status['status']) {
             $restore_progress = 'Cancelled';
         } elseif (!empty($table_restore_status['current_row'])) {
             $restore_percent = 0 == $table_restore_status['rows'] ? 100 : $table_restore_status['current_row'] / $table_restore_status['rows'] * 100;
             $restore_progress = sprintf($format_string, $table_restore_status['current_row'], $table_restore_status['rows'], $restore_percent);
         } else {
             $restore_progress = 'N/A';
         }
         echo '<tr><td>' . $table_name . '</td>';
         echo '<td style="text-align: center">' . $table_status_code . '</td>';
         echo '<td style="text-align: right">' . $backup_progress . '</td>';
         echo '<td style="text-align: center">' . $restore_link . '<span class="spinner backup-restore-spinner"></span></td>';
         echo '<td style="text-align: center">' . $restore_progress . '</td></tr>';
     }
     echo '</table>';
     echo '<a href="#" class="restore-all-tables">Restore All Tables</a> | ';
     echo '<a href="#" class="cancel-all-restores">Cancel All Restores</a>';
     echo '</div></div>';
     /*
     	//    Last completed snapshot info
     	$db_snapshot = self::get_db_snapshot();
     	if ( $db_snapshot ) {
     		$snapshot_date = date( 'Y M d, h:i a', $db_snapshot['timestamp'] );
     		$snapshot_url = $db_snapshot['url'];
     
     		return __( sprintf( 'Last snapshot taken: %s - <a href="%s">Download</a>', $snapshot_date, esc_url( $snapshot_url ) ) );
     	} else {
     		return __( 'You haven\'t created a database snapshot yet' );
     	}
     */
 }