Пример #1
0
 /**
  *	wipePrefix()
  *
  *	Clear out tables matching supplied prefix.
  *
  *	@return			boolean		Currently always true.
  */
 function wipePrefix($prefix, $confirm = false)
 {
     if ($confirm !== true) {
         die('Error #5466566b: Parameter 2 to wipePrefix() must be boolean true to proceed.');
     }
     if ($prefix == '') {
         pb_backupbuddy::status('warning', 'No database prefix specified to wipe.');
         return false;
     }
     pb_backupbuddy::status('message', 'Beginning wipe of database tables matching prefix `' . $prefix . '`...');
     // Connect to database.
     //$this->connect_database();
     global $wpdb;
     $rows = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE table_name LIKE '" . backupbuddy_core::dbEscape(str_replace('_', '\\_', $prefix)) . "%' AND table_schema = DATABASE()", ARRAY_A);
     $table_wipe_count = count($rows);
     foreach ($rows as $row) {
         pb_backupbuddy::status('details', 'Dropping table `' . $row['table_name'] . '`.');
         $wpdb->query('DROP TABLE `' . $row['table_name'] . '`');
     }
     unset($rows);
     pb_backupbuddy::status('message', 'Wiped database of ' . $table_wipe_count . ' tables.');
     return true;
 }
Пример #2
0
 private function _dump_php($output_directory, $tables, $resume_starting_row = 0)
 {
     //, $base_dump_mode, $additional_excludes ) {
     $this->time_start = microtime(true);
     $last_file_size_output = microtime(true);
     $output_file_size_every_max = 5;
     // Output current SQL file size no more often than this. Only checks if it has been enough time once each burst of max rows per select is processed.
     $max_rows_per_select = $this->_max_rows_per_select;
     if ($resume_starting_row > 0) {
         pb_backupbuddy::status('details', 'Resuming chunked dump at row `' . $resume_starting_row . '`.');
     }
     global $wpdb;
     if (!is_object($wpdb)) {
         pb_backupbuddy::status('error', 'WordPress database object $wpdb did not exist. This should not happen.');
         error_log('WordPress database object $wpdb did not exist. This should not happen. BackupBuddy Error #8945587973.');
         return false;
     }
     // Connect if not connected for importbuddy.
     if (defined('PB_IMPORTBUDDY')) {
         if (!mysql_ping($wpdb->dbh)) {
             $maybePort = '';
             if ('' != $this->_database_port) {
                 $maybePort = ':' . $this->_database_port;
                 pb_backupbuddy::status('details', 'Using custom specified port `' . $this->_database_port . '` in DB_HOST.');
             }
             $wpdb->dbh = mysql_connect($this->_database_host . $maybePort, $this->_database_user, $this->_database_pass);
             mysql_select_db($this->_database_name, $wpdb->dbh);
         }
     }
     $insert_sql = '';
     pb_backupbuddy::status('details', 'Loading DB kicker for use leter in case database goes away.');
     @(include_once pb_backupbuddy::plugin_path() . '/lib/wpdbutils/wpdbutils.php');
     if (class_exists('pluginbuddy_wpdbutils')) {
         global $wpdb;
         $dbhelper = new pluginbuddy_wpdbutils($wpdb);
     } else {
         pb_backupbuddy::status('details', __('Database Server connection status will not be verified as kicker is not available.', 'it-l10n-backupbuddy'));
     }
     global $wpdb;
     // Used later for checking that we are still connected to DB.
     // Iterate through all the tables to backup.
     // TODO: Future ability to break up DB exporting to multiple page loads if needed.
     $remainingTables = $tables;
     foreach ($tables as $table_key => $table) {
         $_count = 0;
         $insert_sql = '';
         if ($resume_starting_row > 0) {
             pb_backupbuddy::status('details', 'Chunked resume on dumping `' . $table . '`. Resuming where left off.');
             $rows_start = $resume_starting_row;
             $resume_starting_row = 0;
             // Don't want to skip anything on next table.
         } else {
             $rows_start = 0;
         }
         pb_backupbuddy::status('details', 'Dumping database table `' . $table . '`. Max rows per select: ' . $max_rows_per_select . '. Starting at row `' . $resume_starting_row . '`.');
         pb_backupbuddy::status('startTableDump', $table);
         if (false === $this->_force_single_db_file) {
             $output_file = $output_directory . $table . '.sql';
         } else {
             pb_backupbuddy::status('details', 'Advanced option to force to single .sql file enabled.');
             $output_file = $output_directory . 'db_1.sql';
         }
         pb_backupbuddy::status('details', 'SQL dump file `' . $output_file . '`.');
         if ('-1' == $this->_maxExecutionTime) {
             pb_backupbuddy::status('details', 'Database max execution time chunking disabled based on -1 passed.');
         } else {
             pb_backupbuddy::status('details', 'mysqlbuddy: PHP-based database dump with max execution time for this run: ' . $this->_maxExecutionTime . ' seconds.');
         }
         if (false === ($file_handle = fopen($output_file, 'a'))) {
             pb_backupbuddy::status('error', 'Error #9018: Database file is not creatable/writable. Check your permissions for file `' . $output_file . '` in directory `' . $output_directory . '`.');
             return false;
         }
         pb_backupbuddy::status('sqlFile', basename($output_file));
         // Tells status checker which file to request size data for when polling server.
         if (0 == $rows_start) {
             $create_table = $wpdb->get_results("SHOW CREATE TABLE `{$table}`", ARRAY_N);
             if ($create_table === false) {
                 pb_backupbuddy::status('error', 'Unable to access and dump database table `' . $table . '`. Table may not exist. Skipping backup of this table.');
                 //backupbuddy_core::mail_error( 'Error #4537384: Unable to access and dump database table `' . $table . '`. Table may not exist. Skipping backup of this table.' );
                 continue;
                 // Skip this iteration as accessing this table failed.
             }
             // Table creation text
             if (!isset($create_table[0])) {
                 pb_backupbuddy::status('error', 'Error #857835: Unable to get table creation SQL for table `' . $table . '`. Result: `' . print_r($create_table) . '`.');
                 return false;
             }
             $create_table_array = $create_table[0];
             unset($create_table);
             $insert_sql .= str_replace("\n", '', $create_table_array[1]) . ";\n";
             // Remove internal linebreaks; only put one at end.
             unset($create_table_array);
             // Disable keys for this table.
             $insert_sql .= "/*!40000 ALTER TABLE `{$table}` DISABLE KEYS */;\n";
         }
         $queryCount = 0;
         $rows_remain = true;
         while (true === $rows_remain) {
             // Row creation text for all rows within this table.
             $query = "SELECT * FROM `{$table}` LIMIT " . $rows_start . ',' . $max_rows_per_select;
             $table_query = $wpdb->get_results($query, ARRAY_N);
             $rows_start += $max_rows_per_select;
             // Next loop we will begin at this offset.
             if ($table_query === false) {
                 pb_backupbuddy::status('error', 'ERROR #85449745. Unable to retrieve data from table `' . $table . '`. This table may be corrupt (try repairing the database) or too large to hold in memory (increase mysql and/or PHP memory). Check your PHP error log for further errors which may provide further information. Not continuing database dump to insure backup integrity.');
                 return false;
             }
             $tableCount = count($table_query);
             pb_backupbuddy::status('details', 'Got `' . $tableCount . '` rows from `' . $table . '` of `' . $max_rows_per_select . '` max.');
             if (0 == $tableCount || $tableCount < $max_rows_per_select) {
                 $rows_remain = false;
             }
             $columns = $wpdb->get_col_info();
             $num_fields = count($columns);
             foreach ($table_query as $fetch_row) {
                 $insert_sql .= "INSERT INTO `{$table}` VALUES(";
                 for ($n = 1; $n <= $num_fields; $n++) {
                     $m = $n - 1;
                     if ($fetch_row[$m] === NULL) {
                         $insert_sql .= "NULL, ";
                     } else {
                         $insert_sql .= "'" . backupbuddy_core::dbEscape($fetch_row[$m]) . "', ";
                     }
                 }
                 $insert_sql = substr($insert_sql, 0, -2);
                 $insert_sql .= ");\n";
                 $writeReturn = fwrite($file_handle, $insert_sql);
                 if (false === $writeReturn || 0 == $writeReturn) {
                     pb_backupbuddy::status('error', 'Error #843948: Unable to write to SQL file. Return error/bytes written: `' . $writeReturn . '`.');
                     @fclose($file_handle);
                     return false;
                 }
                 $insert_sql = '';
                 $_count++;
                 // Show a heartbeat to keep user up to date [and entertained ;)].
                 if (0 === $_count % self::HEARTBEAT_COUNT_LIMIT || 0 === $_count % ceil($max_rows_per_select / 2)) {
                     // Display every X queries based on heartbeat OR at least display every half max rows per select.
                     pb_backupbuddy::status('details', 'Working... Dumped `' . $_count . '` rows from `' . $table . '` so far.');
                 }
             }
             // end foreach table row.
             if (false === $rows_remain) {
                 pb_backupbuddy::status('details', 'Dumped `' . $_count . '` rows total from `' . $table . '`. No rows remain.');
             } else {
                 if (microtime(true) - $last_file_size_output > $output_file_size_every_max) {
                     // It's been long enough to get the current file size of SQL file.
                     // Display final SQL file size.
                     $sql_filesize = pb_backupbuddy::$format->file_size(filesize($output_file));
                     pb_backupbuddy::status('details', 'Current database dump file `' . basename($output_file) . '` size: ' . $sql_filesize . '.');
                     $last_file_size_output = microtime(true);
                 }
             }
             // If we are within X seconds (self::TIME_WIGGLE_ROOM) of reaching maximum PHP runtime then stop here so that it can be picked up in another PHP process...
             if ('-1' != $this->_maxExecutionTime) {
                 if (microtime(true) - pb_backupbuddy::$start_time + self::TIME_WIGGLE_ROOM >= $this->_maxExecutionTime) {
                     // used to use $this->time_start but this did not take into account time used prior to db step.
                     pb_backupbuddy::status('details', 'Approaching limit of available PHP chunking time of `' . $this->_maxExecutionTime . '` sec. PHP ran for ' . round(microtime(true) - pb_backupbuddy::$start_time, 3) . ' sec, database dumping ran for ' . round(microtime(true) - $this->time_start, 3) . ' sec having dumped `' . $_count . '` rows. Proceeding to use chunking on remaining tables: ' . implode(',', $remainingTables));
                     @fclose($file_handle);
                     return array($remainingTables, $rows_start);
                 }
                 // End if.
             }
             // Verify database is still connected and working properly. Sometimes mysql runs out of memory and dies in the above foreach.
             // No point in reconnecting as we can NOT trust that our dump was succesful anymore (it most likely was not).
             if (isset($dbhelper)) {
                 if (!$dbhelper->kick()) {
                     pb_backupbuddy::status('error', __('ERROR #9026: The mySQL server went away unexpectedly during database dump of table `' . $table . '`. This is almost always caused by mySQL running out of memory. The backup integrity can no longer be guaranteed so the backup has been halted.') . ' ' . __('Last table dumped before database server went away: ') . '`' . $table . '`.');
                     @fclose($file_handle);
                     return false;
                 }
             } else {
                 pb_backupbuddy::status('details', 'Database kicker unavailable so connection status unverified.');
             }
         }
         // End while rows remain.
         // Remove the current table from the list of tables to dump as it is done.
         unset($remainingTables[$table_key]);
         // Re-enable keys for this table.
         $insert_sql .= "/*!40000 ALTER TABLE `{$table}` ENABLE KEYS */;\n";
         $writeReturn = fwrite($file_handle, $insert_sql);
         if (false === $writeReturn || 0 == $writeReturn) {
             pb_backupbuddy::status('error', 'Error #843948: Unable to write to SQL file. Return error/bytes written: `' . $writeReturn . '`.');
             @fclose($file_handle);
             return false;
         }
         $insert_sql = '';
         @fclose($file_handle);
         pb_backupbuddy::status('details', 'Finished dumping database table `' . $table . '`.');
         pb_backupbuddy::status('finishTableDump', $table);
         if (isset($output_file)) {
             $stats = stat($output_file);
             pb_backupbuddy::status('details', 'Database SQL dump file (' . basename($output_file) . ') size: ' . pb_backupbuddy::$format->file_size($stats['size']));
             pb_backupbuddy::status('sqlSize', $stats['size']);
         }
         pb_backupbuddy::status('details', 'About to flush...');
         pb_backupbuddy::flush();
         //unset( $tables[$table_key] );
     }
     // end foreach table.
     @fclose($file_handle);
     unset($file_handle);
     pb_backupbuddy::status('details', __('Finished PHP based SQL dump method. Ran for ' . round(microtime(true) - $this->time_start, 3) . ' sec.', 'it-l10n-backupbuddy'));
     return true;
 }
Пример #3
0
 private function _priorRollbackCleanup()
 {
     $this->_before(__FUNCTION__);
     pb_backupbuddy::status('details', 'Checking for any prior failed rollback data to clean up.');
     global $wpdb;
     $shortSerial = substr($this->_state['serial'], 0, 4);
     // NEW prefix
     $sql = "SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'BBnew-" . $shortSerial . "\\_%' AND table_schema = DATABASE()";
     $results = $wpdb->get_results($sql, ARRAY_A);
     pb_backupbuddy::status('details', 'Found ' . count($results) . ' tables to drop with the prefix `BBnew-' . $shortSerial . '_`.');
     $dropCount = 0;
     foreach ($results as $result) {
         if (false === $wpdb->query("DROP TABLE `" . backupbuddy_core::dbEscape($result['table_name']) . "`")) {
             $this->_error('Unable to delete table `' . $result['table_name'] . '`.');
         } else {
             $dropCount++;
         }
     }
     pb_backupbuddy::status('details', 'Dropped `' . $dropCount . '` new tables.');
     // OLD prefix
     $sql = "SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'BBold-" . $shortSerial . "\\_%' AND table_schema = DATABASE()";
     $results = $wpdb->get_results($sql, ARRAY_A);
     pb_backupbuddy::status('details', 'Found ' . count($results) . ' tables to drop with the prefix `BBold-' . $shortSerial . '_`.');
     $dropCount = 0;
     foreach ($results as $result) {
         if (false === $wpdb->query("DROP TABLE `" . backupbuddy_core::dbEscape($result['table_name']) . "`")) {
             $this->_error('Unable to delete table `' . $result['table_name'] . '`.');
         } else {
             $dropCount++;
         }
     }
     pb_backupbuddy::status('details', 'Dropped `' . $dropCount . '` old tables.');
     pb_backupbuddy::status('details', 'Finished prior rollback cleanup.');
 }
 function finalize()
 {
     // LASTLY UPDATE SITE/HOME URLS to prevent double replacement; just in case!
     if (!isset($this->restoreData['dat']['tables_sizes'][$this->restoreData['dat']['db_prefix'] . 'options'])) {
         pb_backupbuddy::status('details', 'Options table was not backed up. Skipping finalizing database URLs for _options table.');
     } else {
         // Update SITEURL in options table. Usually mass replacement will cover this but set these here just in case.
         mysql_query("UPDATE `" . $this->overridePrefix . "options` SET option_value='" . backupbuddy_core::dbEscape($this->restoreData['siteurl']) . "' WHERE option_name='siteurl' LIMIT 1");
         pb_backupbuddy::status('details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating Site URL in options table `' . $this->overridePrefix . 'options` to `' . $this->restoreData['siteurl'] . '`.');
         if (mysql_error() != '') {
             pb_backupbuddy::status('error', 'mysql error: ' . mysql_error());
         }
         // Update HOME URL in options table. Usually mass replacement will cover this but set these here just in case.
         if ($this->restoreData['homeurl'] != '') {
             mysql_query("UPDATE `" . $this->overridePrefix . "options` SET option_value='" . backupbuddy_core::dbEscape($this->restoreData['homeurl']) . "' WHERE option_name='home' LIMIT 1");
             pb_backupbuddy::status('details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating Home URL in options table to `' . $this->restoreData['homeurl'] . '`.');
             if (mysql_error() != '') {
                 pb_backupbuddy::status('error', 'mysql error: ' . mysql_error());
             }
         }
     }
     return true;
 }
Пример #5
0
 public function import($sql_file, $old_prefix, $query_start = 0, $ignore_existing = false)
 {
     $return = false;
     // Require a new table prefix.
     if ($this->_database_prefix == '') {
         pb_backupbuddy::status('error', 'ERROR 9008: A database prefix is required for importing.');
     }
     if ($query_start > 0) {
         pb_backupbuddy::status('message', 'Continuing to restore database dump starting at query ' . $query_start . '.');
     } else {
         pb_backupbuddy::status('message', 'Restoring database dump. This may take a moment...');
     }
     global $wpdb;
     // Check whether or not tables already exist that might collide.
     if ($ignore_existing === false) {
         if ($query_start == 0) {
             // Check number of tables already existing with this prefix. Skips this check on substeps of DB import.
             $rows = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE table_name LIKE '" . backupbuddy_core::dbEscape(str_replace('_', '\\_', $this->_database_prefix)) . "%' AND table_schema = DATABASE()", ARRAY_A);
             if (count($rows) > 0) {
                 pb_backupbuddy::status('error', 'Error #9014: Database import halted to prevent overwriting existing WordPress data. The database already contains a WordPress installation with this prefix `' . $this->_database_prefix . '` (' . count($rows) . ' tables). Restore has been stopped to prevent overwriting existing data.');
                 return false;
             }
             unset($rows);
         }
     }
     pb_backupbuddy::status('message', 'Starting database import procedure.');
     pb_backupbuddy::status('details', 'mysqlbuddy: Maximum execution time for this run: ' . $this->_maxExecutionTime . ' seconds.');
     pb_backupbuddy::status('details', 'mysqlbuddy: Old prefix: `' . $old_prefix . '`; New prefix: `' . $this->_database_prefix . '`.');
     pb_backupbuddy::status('details', "mysqlbuddy: Importing SQL file: `{$sql_file}`. Old prefix: `{$old_prefix}`. Query start: `{$query_start}`.");
     pb_backupbuddy::status('details', 'About to flush...');
     pb_backupbuddy::flush();
     // Attempt each method in order.
     pb_backupbuddy::status('details', 'Preparing to import using available method(s) by priority. Basing import methods off dump methods: `' . implode(',', $this->_methods) . '`');
     foreach ($this->_methods as $method) {
         if (method_exists($this, "_import_{$method}")) {
             pb_backupbuddy::status('details', 'mysqlbuddy: Attempting import method `' . $method . '`.');
             $result = call_user_func(array($this, "_import_{$method}"), $sql_file, $old_prefix, $query_start, $ignore_existing);
             if ($result === true) {
                 // Dump completed succesfully with this method.
                 pb_backupbuddy::status('details', 'mysqlbuddy: Import method `' . $method . '` completed successfully.');
                 $return = true;
                 break;
             } elseif ($result === false) {
                 // Dump failed this method. Will try compatibility fallback to next mode if able.
                 // Do nothing. Will try next mode next loop.
                 pb_backupbuddy::status('details', 'mysqlbuddy: Import method `' . $method . '` failed. Trying another compatibility mode next if able.');
             } else {
                 // Something else returned; used for resuming (integer) or a message (string).
                 pb_backupbuddy::status('details', 'mysqlbuddy: Non-boolean response (usually means resume is needed): `' . $result . '`');
                 return $result;
                 // Dont fallback if this happens. Usually means resume is needed to finish.
             }
         }
     }
     if ($return === true) {
         // Success.
         pb_backupbuddy::status('message', 'Database import procedure succeeded.');
         return true;
     } else {
         // Overall failure.
         pb_backupbuddy::status('error', 'Database import procedure did not complete or failed.');
         return false;
     }
 }
Пример #6
0
<?php

backupbuddy_core::verifyAjaxAccess();
// Check db integrity of a table.
/*	db_check()
*	
*	Check database integrity on a specific table. Used on server info page.
*	
*	@return		null
*/
$table = base64_decode(pb_backupbuddy::_GET('table'));
$check_level = 'MEDIUM';
global $wpdb;
pb_backupbuddy::$ui->ajax_header();
echo '<h2>Database Table Check</h2>';
echo 'Checking table `' . $table . '` using ' . $check_level . ' scan...<br><br>';
$rows = $wpdb->get_results("CHECK TABLE `" . backupbuddy_core::dbEscape($table) . "` " . $check_level, ARRAY_A);
echo '<b>Results:</b><br><br>';
echo '<table class="widefat">';
foreach ($rows as $row) {
    echo '<tr>';
    echo '<td>' . $row['Msg_type'] . '</td>';
    echo '<td>' . $row['Msg_text'] . '</td>';
    echo '</tr>';
}
unset($rows);
echo '</table>';
pb_backupbuddy::$ui->ajax_footer();
die;
Пример #7
0
 public function db_repair()
 {
     $table = base64_decode(pb_backupbuddy::_GET('table'));
     global $wpdb;
     pb_backupbuddy::$ui->ajax_header();
     echo '<h2>Database Table Repair</h2>';
     echo 'Repairing table `' . $table . '`...<br><br>';
     $rows = $wpdb->get_results("REPAIR TABLE `" . backupbuddy_core::dbEscape($table) . "`", ARRAY_A);
     echo '<b>Results:</b><br><br>';
     echo '<table class="widefat">';
     foreach ($rows as $row) {
         echo '<tr>';
         echo '<td>' . $row['Msg_type'] . '</td>';
         echo '<td>' . $row['Msg_text'] . '</td>';
         echo '</tr>';
     }
     unset($rows);
     echo '</table>';
     pb_backupbuddy::$ui->ajax_footer();
     die;
 }
<?php

if (!is_admin()) {
    die('Access denied.');
}
// Repair db integrity of a table.
/*	db_repair()
*	
*	Repair specific table. Used on server info page.
*	
*	@return		null
*/
$table = base64_decode(pb_backupbuddy::_GET('table'));
global $wpdb;
pb_backupbuddy::$ui->ajax_header();
echo '<h2>Database Table Repair</h2>';
echo 'Repairing table `' . $table . '`...<br><br>';
$rows = $wpdb->get_results("REPAIR TABLE `" . backupbuddy_core::dbEscape($table) . "`", ARRAY_A);
echo '<b>Results:</b><br><br>';
echo '<table class="widefat">';
foreach ($rows as $row) {
    echo '<tr>';
    echo '<td>' . $row['Msg_type'] . '</td>';
    echo '<td>' . $row['Msg_text'] . '</td>';
    echo '</tr>';
}
unset($rows);
echo '</table>';
pb_backupbuddy::$ui->ajax_footer();
die;
Пример #9
0
 private static function _render_insert($table_no_prefix, $column, $value)
 {
     global $wpdb;
     $table = $wpdb->prefix . $table_no_prefix;
     $query = "SELECT * FROM `{$table}` WHERE {$column} = %s";
     $table_query = $wpdb->get_results($wpdb->prepare($query, array($value)), ARRAY_N);
     if ($table_query === false) {
         pb_backupbuddy::status('error', 'ERROR #237273. Unable to retrieve data from table `' . $table . '`. This table may be corrupt (try repairing the database) or too large to hold in memory (increase mysql and/or PHP memory). Check your PHP error log for further errors which may provide further information. Not continuing database dump to insure backup integrity.');
         return false;
     }
     $tableCount = count($table_query);
     pb_backupbuddy::status('details', 'Got `' . $tableCount . '` rows from `' . $table . '`.');
     $insert_sql = $wpdb->prepare("DELETE FROM `{$table}` WHERE {$column} = %s", array($value)) . ";\n";
     // Initially delete everything that matches this query to get ready for insert.
     $columns = $wpdb->get_col_info();
     $num_fields = count($columns);
     foreach ($table_query as $fetch_row) {
         $insert_sql .= "INSERT INTO `{$table}` VALUES(";
         for ($n = 1; $n <= $num_fields; $n++) {
             $m = $n - 1;
             if ($fetch_row[$m] === NULL) {
                 $insert_sql .= "NULL, ";
             } else {
                 $insert_sql .= "'" . backupbuddy_core::dbEscape($fetch_row[$m]) . "', ";
             }
         }
         $insert_sql = substr($insert_sql, 0, -2);
         $insert_sql .= ");\n";
         /*
         $writeReturn = fwrite( $file_handle, $insert_sql );
         if ( ( false === $writeReturn ) || ( 0 == $writeReturn ) ) {
         	pb_backupbuddy::status( 'error', 'Error #549546: Unable to write to SQL file. Return error/bytes written: `' . $writeReturn . '`.' );
         	@fclose( $file_handle );
         	return false;
         }
         */
         //$insert_sql = '';
     }
     // end foreach table row.
     return $insert_sql;
 }
     $rows_changed = 0;
     foreach ($tables as $table) {
         pb_backupbuddy::status('message', 'Replacing in table `' . $table . '`.');
         $rows_changed += $dbreplace->bruteforce_table($table, array($needle), array($replacement));
     }
     pb_backupbuddy::status('message', 'Total rows updated across all tables: ' . $rows_changed . '.');
     pb_backupbuddy::status('message', 'Replacement finished.');
 } elseif (pb_backupbuddy::_POST('table_selection') == 'single_table') {
     $table = backupbuddy_core::dbEscape(pb_backupbuddy::_POST('table'));
     // Single specified table.
     pb_backupbuddy::status('message', 'Replacing in single table `' . $table . '` based on settings.');
     $dbreplace->bruteforce_table($table, array($needle), array($replacement));
     pb_backupbuddy::status('message', 'Replacement finished.');
 } elseif (pb_backupbuddy::_POST('table_selection') == 'prefix') {
     // Matching table prefix.
     $prefix = backupbuddy_core::dbEscape(pb_backupbuddy::_POST('table_prefix'));
     pb_backupbuddy::status('message', 'Replacing in all tables matching prefix `' . $prefix . '`.');
     $tables = array();
     $escaped_prefix = str_replace('_', '\\_', $prefix);
     $rows = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE table_name LIKE '{$escaped_prefix}%' AND table_schema = DATABASE()", ARRAY_A);
     foreach ($rows as $row) {
         $tables[] = $row['table_name'];
     }
     unset($rows);
     $rows_changed = 0;
     foreach ($tables as $table) {
         pb_backupbuddy::status('message', 'Replacing in table `' . $table . '`.');
         $rows_changed += $dbreplace->bruteforce_table($table, array($needle), array($replacement));
     }
     pb_backupbuddy::status('message', 'Total rows updated across all tables: ' . $rows_changed . '.');
     pb_backupbuddy::status('message', 'Replacement finished.');
Пример #11
0
 /**
  *	bruteforce_table()
  *
  *	!!! HANDLES SERIALIZED DATA !!!!
  *	Replaces text, serialized or not, within the entire table. Bruteforce method iterates through every row & column in the entire table and replaces if needed.
  *	
  *	@param		string		$table		Text (possibly serialized) to update.
  *	@param		mixed		$olds		Text to search for to replace. May be an array of strings to search for.
  *	@param		mixed		$news		New value(s) to be replaced with. May be a string or array. If array there must be the same number of values as $olds.
  *	@return		int						Number of rows changed.
  *
  */
 function bruteforce_table($table, $olds, $news, $rows_start = '')
 {
     pb_backupbuddy::status('message', 'Starting brute force data migration for table `' . $table . '`...');
     if (!is_array($olds)) {
         $olds = array($olds);
     }
     if (!is_array($news)) {
         $news = array($news);
     }
     $count_items_checked = 0;
     $count_items_changed = 0;
     global $wpdb;
     // Get the total row count for this table
     $total_rows = 0;
     $tables_status = $wpdb->get_results("SHOW TABLE STATUS", ARRAY_A);
     foreach ($tables_status as $table_status) {
         if ($table === $table_status['Name']) {
             // Fix up row count and average row length for InnoDB engine which returns inaccurate
             // (and changing) values for these
             if ('InnoDB' === $table_status['Engine']) {
                 if (false !== ($count = $wpdb->get_var("SELECT COUNT(1) FROM `{$table_status['Name']}`"))) {
                     $table_status['Rows'] = $count;
                 }
             }
             $total_rows = $table_status['Rows'];
         }
     }
     $fields = $wpdb->get_results("DESCRIBE `{$table}`", ARRAY_A);
     $index_fields = '';
     // Reset fields for each table.
     $column_name = '';
     $table_index = '';
     $i = 0;
     $found_primary_key = false;
     foreach ($fields as $field) {
         $column_name[$i++] = $field['Field'];
         if ($field['Key'] == 'PRI') {
             $table_index[$i] = true;
             $found_primary_key = true;
         }
     }
     // Skips migration of this table if there is no primary key. Modifying on any other key is not safe. mysql automatically returns a PRIMARY if a UNIQUE non-primary is found according to http://dev.mysql.com/doc/refman/5.1/en/create-table.html  @since 2.2.32.
     if ($found_primary_key === false) {
         pb_backupbuddy::status('warning', 'Error #9029b: Warning only! Table `' . $table . '` does not contain a primary key; BackupBuddy cannot safely modify the contents of this table. Skipping migration of this table. (bruteforce_table()).');
         return true;
     }
     $row_loop = 0;
     $rows_remain = true;
     // More rows remaining / aka another query for more rows needed.
     if ('' == $rows_start) {
         $rows_start = 0;
     }
     while (true === $rows_remain) {
         // Keep looping through rows until none remain. Looping through like this to limit memory usage as wpdb classes loads all results into memory.
         $data = $wpdb->get_results("SELECT * FROM `{$table}` LIMIT {$rows_start}," . self::MAX_ROWS_PER_SELECT, ARRAY_A);
         if (false === $data) {
             pb_backupbuddy::status('error', 'ERROR #44545343 ... SQL ERROR: ' . $wpdb->last_error);
         }
         // Provide an update on progress
         $rowsCount = count($data);
         if (0 === $rowsCount) {
             pb_backupbuddy::status('details', 'Table: `' . $table . '` - processing ' . $rowsCount . ' rows ( of ' . $total_rows . ' )');
         } else {
             pb_backupbuddy::status('details', 'Table: `' . $table . '` - processing ' . $rowsCount . ' rows ( Rows ' . $rows_start . '-' . ($rows_start + $rowsCount - 1) . ' of ' . $total_rows . ' )');
         }
         $rows_start += self::MAX_ROWS_PER_SELECT;
         // Next loop we will begin at this offset.
         if (0 == $rowsCount || $rowsCount < self::MAX_ROWS_PER_SELECT) {
             $rows_remain = false;
         }
         foreach ($data as $row) {
             $need_to_update = false;
             $UPDATE_SQL = 'UPDATE `' . $table . '` SET ';
             $WHERE_SQL = ' WHERE ';
             $j = 0;
             foreach ($column_name as $current_column) {
                 $j++;
                 $count_items_checked++;
                 $data_to_fix = $row[$current_column];
                 if (false !== ($edited_data = $this->replace_maybe_serialized($data_to_fix, $olds, $news))) {
                     // no change needed
                     $count_items_changed++;
                     if ($need_to_update != false) {
                         // If this isn't our first time here, we need to add a comma.
                         $UPDATE_SQL = $UPDATE_SQL . ',';
                     }
                     $UPDATE_SQL = $UPDATE_SQL . ' ' . $current_column . ' = "' . backupbuddy_core::dbEscape($edited_data) . '"';
                     $need_to_update = true;
                     // Only set if we need to update - avoids wasted UPDATE statements.
                 }
                 if (isset($table_index[$j])) {
                     $WHERE_SQL = $WHERE_SQL . '`' . $current_column . '` = "' . $row[$current_column] . '" AND ';
                 }
             }
             if ($need_to_update) {
                 $WHERE_SQL = substr($WHERE_SQL, 0, -4);
                 // Strip off the excess AND - the easiest way to code this without extra flags, etc.
                 $UPDATE_SQL = $UPDATE_SQL . $WHERE_SQL;
                 $result = $wpdb->query($UPDATE_SQL);
                 if (false === $result) {
                     pb_backupbuddy::status('error', 'ERROR: mysql error updating db: ' . mysql_error() . '. SQL Query: ' . htmlentities($UPDATE_SQL));
                 }
             }
         }
         unset($data);
         // See how we are doing on time. Trigger chunking if needed.
         if (microtime(true) - $this->startTime + $this->timeWiggleRoom >= $this->maxExecutionTime) {
             return array($rows_start);
         }
     }
     pb_backupbuddy::status('message', 'Brute force data migration for table `' . $table . '` complete. Checked ' . $count_items_checked . ' items; ' . $count_items_changed . ' changed.');
     return true;
 }
    if (mysql_error() != '') {
        pb_backupbuddy::status('error', 'mysql error: ' . mysql_error());
    }
    mysql_query("UPDATE `" . $new_prefix . "options` SET option_name = '" . $new_prefix . "user_roles' WHERE option_name ='" . $old_prefix . "user_roles' LIMIT 1");
    pb_backupbuddy::status('details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating option_name user_roles DB prefix in [subsite if multisite] options table to `' . backupbuddy_core::dbEscape($new_prefix) . '`.');
    if (mysql_error() != '') {
        pb_backupbuddy::status('error', 'mysql error: ' . mysql_error());
    }
    pb_backupbuddy::status('message', 'Updated prefix META data.');
}
// LASTLY UPDATE SITE/HOME URLS to prevent double replacement; just in case!
// Update SITEURL in options table. Usually mass replacement will cover this but set these here just in case.
mysql_query("UPDATE `" . $destination_db_prefix . "options` SET option_value='" . backupbuddy_core::dbEscape($destination_siteurl) . "' WHERE option_name='siteurl' LIMIT 1");
pb_backupbuddy::status('details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating Site URL in options table `' . $destination_db_prefix . 'options` to `' . $destination_siteurl . '`.');
if (mysql_error() != '') {
    pb_backupbuddy::status('error', 'mysql error: ' . mysql_error());
}
// Update HOME URL in options table. Usually mass replacement will cover this but set these here just in case.
if ($destination_home != '') {
    mysql_query("UPDATE `" . $destination_db_prefix . "options` SET option_value='" . backupbuddy_core::dbEscape($destination_home) . "' WHERE option_name='home' LIMIT 1");
    pb_backupbuddy::status('details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating Home URL in options table to `' . $destination_home . '`.');
    if (mysql_error() != '') {
        pb_backupbuddy::status('error', 'mysql error: ' . mysql_error());
    }
}
pb_backupbuddy::status('message', 'Migrated ' . count($bruteforce_tables) . ' tables via brute force.');
pb_backupbuddy::status('message', 'Took ' . round(microtime(true) - pb_backupbuddy::$start_time, 3) . ' seconds. Done.');
pb_backupbuddy::status('message', 'Database content migrated.');
$return = true;
// Needed for importbuddy since the following return does not trigger since it's in an include.
return true;
Пример #13
0
 public static function remove_temp_tables($forceSerial = '')
 {
     global $wpdb;
     if ('' != $forceSerial) {
         $cleanups = array($forceSerial => 0);
     } else {
         $cleanups = pb_backupbuddy::$options['rollback_cleanups'];
     }
     foreach ($cleanups as $cleanup_serial => $start_time) {
         if (time() - $start_time > backupbuddy_constants::CLEANUP_MAX_STATUS_LOG_AGE) {
             $results = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE ( ( table_name LIKE 'bbnew-" . substr($cleanup_serial, 0, 4) . "\\_%' ) OR ( table_name LIKE 'bbold-" . substr($cleanup_serial, 0, 4) . "\\_%' ) ) AND table_schema = DATABASE()", ARRAY_A);
             if (count($results) > 0) {
                 foreach ($results as $result) {
                     if (false === $wpdb->query("DROP TABLE `" . backupbuddy_core::dbEscape($result['table_name']) . "`")) {
                         return $this->_error('Error #372837683: Unable to copy over BackupBuddy settings from live site to incoming database in temp table. Details: `' . $wpdb->last_error . '`.');
                         pb_backupbuddy::status('details', 'Error #83947944: Unable to drop temp rollback/deploy table `' . $result['table_name'] . '`. Details: `' . $wpdb->last_error . '`.');
                     }
                 }
             }
             unset(pb_backupbuddy::$options['rollback_cleanups'][$cleanup_serial]);
             pb_backupbuddy::save();
         }
     }
     // end foreach.
     // Delete any undo PHP files.
     $undoFiles = glob(ABSPATH . 'backupbuddy_deploy_undo-*.php');
     if (!is_array($undoFiles)) {
         $undoFiles = array();
     }
     foreach ($undoFiles as $undoFile) {
         @unlink($undoFile);
     }
     return;
 }
Пример #14
0
     if (!isset($restore->_state['databaseSettings']['importResumeFiles']) && '' == $restore->_state['databaseSettings']['importResumePoint']) {
         // Only do this if not in process of resuming.
         pb_backupbuddy::status('message', 'Wiping ALL existing database tables based on settings (use with caution)...');
         if (TRUE !== pb_backupbuddy::$classes['import']->wipeDatabase(TRUE)) {
             pb_backupbuddy::status('error', 'Unable to wipe entire database as configured in the settings.');
         }
     }
 }
 // Restore the database.
 if ('true' == pb_backupbuddy::_GET('deploy')) {
     // Drop any previous incomplete deployment / rollback tables.
     pb_backupbuddy::status('details', 'Dropping any existing temporary deployment or rollback tables.');
     $results = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE ( ( table_name LIKE 'bbnew-\\_%' ) OR ( table_name LIKE 'bbold-\\_%' ) ) AND table_schema = DATABASE()", ARRAY_A);
     if (count($results) > 0) {
         foreach ($results as $result) {
             if (false === $wpdb->query("DROP TABLE `" . backupbuddy_core::dbEscape($result['table_name']) . "`")) {
                 return $this->_error('Error #372837683: Unable to copy over BackupBuddy settings from live site to incoming database in temp table. Details: `' . $wpdb->last_error . '`.');
                 pb_backupbuddy::status('details', 'Error #8493984: Unable to drop temp rollback/deploy table `' . $result['table_name'] . '`. Details: `' . $wpdb->last_error . '`.');
             }
         }
     }
     $restore->_state['databaseSettings']['tempPrefix'] = 'bbnew-' . substr($restore->_state['serial'], 0, 4) . '_' . $restore->_state['databaseSettings']['prefix'];
 }
 pb_backupbuddy::status('details', 'About to restore database.');
 $restoreResult = $restore->restoreDatabase($restore->_state['databaseSettings']['tempPrefix']);
 if ('true' == pb_backupbuddy::_GET('deploy')) {
     if (is_array($restoreResult)) {
         // Chunking. Resume same step.
         $nextStepNum = 4;
     } else {
         // Next step.
Пример #15
0
            // Update comment author IDs with the user's new user ID.
            pb_backupbuddy::status('details', 'Updating comment author ID from old user ID `' . $old_user_id . '` to new ID `' . $user_id . '` in table `' . $new_db_prefix . 'comments`.');
            $rows_updated = $wpdb->update($new_db_prefix . 'comments', array('user_id' => absint($user_id)), array('user_id' => $old_user_id), array('%d'));
            pb_backupbuddy::status('details', 'Row(s) modified: `' . $rows_updated . '`.');
        }
        // Handle usermeta.
        $sql = "select meta_key,meta_value from `{$new_db_prefix}usermeta` WHERE user_id={$old_user_id} AND meta_key NOT LIKE '%\\_capabilities'";
        pb_backupbuddy::status('details', 'Getting usermeta data. SQL query: `' . $sql . '`.');
        $usermetas = $wpdb->get_results($sql);
        // Users to import.
        if (is_array($usermetas)) {
            pb_backupbuddy::status('message', 'Found usermeta data to migrate for this user (old ID: `' . $old_user_id . '`). Importing & migrating...');
            $user_meta_rows_count = 0;
            foreach ($usermetas as $usermeta) {
                $meta_key = backupbuddy_core::dbEscape($usermeta->meta_key);
                $meta_value = backupbuddy_core::dbEscape($usermeta->meta_value);
                $sql = "INSERT INTO `{$wpdb->base_prefix}usermeta` (user_id,meta_key,meta_value) VALUES('{$user_id}','{$meta_key}','{$meta_value}');";
                pb_backupbuddy::status('details', 'Copying usermeta row. SQL query: `' . $sql . '`.');
                $rows_modified = $wpdb->query($sql);
                // $wpdb->base_prefix gives the network prefix.
                pb_backupbuddy::status('details', 'Row(s) modified: `' . $rows_modified . '`.');
                $user_meta_rows_count++;
            }
            pb_backupbuddy::status('details', 'Copied and migrated `' . $user_meta_rows_count . '` usermeta rows.');
        }
    } else {
        // User already exists.
        pb_backupbuddy::status('warning', 'Username `' . $user->user_login . '` or email `' . $user->user_email . '` already exists with user ID `' . $user_id . '`. User skipped.');
        $users_skipped++;
    }
}