/**
  * The main loop triggered in step 5. Up here to keep it out of the way of the
  * HTML. This walks every table in the db that was selected in step 3 and then
  * walks every row and column replacing all occurences of a string with another.
  * We split large tables into 50,000 row blocks when dealing with them to save
  * on memmory consumption.
  *
  * @param mysql  $connection The db connection object
  * @param string $search     What we want to replace
  * @param string $replace    What we want to replace it with.
  * @param array  $tables     The tables we want to look at.
  *
  * @return array    Collection of information gathered during the run.
  */
 function icit_srdb_replacer($connection, $search = '', $replace = '', $tables = array())
 {
     global $guid, $exclude_cols;
     $report = array('tables' => 0, 'rows' => 0, 'change' => 0, 'updates' => 0, 'start' => microtime(), 'end' => microtime(), 'errors' => array());
     if (is_array($tables) && !empty($tables)) {
         foreach ($tables as $table) {
             $report['tables']++;
             $columns = array();
             // Get a list of columns in this table
             $fields = MainWPChildDB::_query('DESCRIBE ' . $table, $connection);
             while ($column = MainWPChildDB::fetch_array($fields)) {
                 $columns[$column['Field']] = $column['Key'] == 'PRI' ? true : false;
             }
             // Count the number of rows we have in the table if large we'll split into blocks, This is a mod from Simon Wheatley
             $row_count = MainWPChildDB::_query('SELECT COUNT(*) as count FROM ' . $table, $connection);
             // to fix bug
             $rows_result = MainWPChildDB::fetch_array($row_count);
             $row_count = $rows_result['count'];
             if ($row_count == 0) {
                 continue;
             }
             $page_size = 50000;
             $pages = ceil($row_count / $page_size);
             for ($page = 0; $page < $pages; $page++) {
                 $current_row = 0;
                 $start = $page * $page_size;
                 $end = $start + $page_size;
                 // Grab the content of the table
                 $data = MainWPChildDB::_query(sprintf('SELECT * FROM %s LIMIT %d, %d', $table, $start, $end), $connection);
                 if (!$data) {
                     $report['errors'][] = MainWPChildDB::error();
                 }
                 while ($row = MainWPChildDB::fetch_array($data)) {
                     $report['rows']++;
                     // Increment the row counter
                     $current_row++;
                     $update_sql = array();
                     $where_sql = array();
                     $upd = false;
                     foreach ($columns as $column => $primary_key) {
                         if ($guid == 1 && in_array($column, $exclude_cols)) {
                             continue;
                         }
                         $edited_data = $data_to_fix = $row[$column];
                         // Run a search replace on the data that'll respect the serialisation.
                         $edited_data = $this->recursive_unserialize_replace($search, $replace, $data_to_fix);
                         // Something was changed
                         if ($edited_data != $data_to_fix) {
                             $report['change']++;
                             $update_sql[] = $column . ' = "' . MainWPChildDB::real_escape_string($edited_data) . '"';
                             $upd = true;
                         }
                         if ($primary_key) {
                             $where_sql[] = $column . ' = "' . MainWPChildDB::real_escape_string($data_to_fix) . '"';
                         }
                     }
                     if ($upd && !empty($where_sql)) {
                         $sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $update_sql) . ' WHERE ' . implode(' AND ', array_filter($where_sql));
                         $result = MainWPChildDB::_query($sql, $connection);
                         if (!$result) {
                             $report['errors'][] = MainWPChildDB::error();
                         } else {
                             $report['updates']++;
                         }
                     } elseif ($upd) {
                         $report['errors'][] = sprintf('"%s" has no primary key, manual change needed on row %s.', $table, $current_row);
                     }
                 }
             }
         }
     }
     $report['end'] = microtime();
     return $report;
 }
예제 #2
0
 public function createBackupDB($filepath, $archiveExt = false, &$archiver = NULL)
 {
     $timeout = 20 * 60 * 60;
     //20minutes
     @set_time_limit($timeout);
     @ini_set('max_execution_time', $timeout);
     $mem = '512M';
     @ini_set('memory_limit', $mem);
     $fh = fopen($filepath, 'w');
     //or error;
     /** @var $wpdb wpdb */
     global $wpdb;
     //Get all the tables
     $tables_db = $wpdb->get_results('SHOW TABLES FROM `' . DB_NAME . '`', ARRAY_N);
     foreach ($tables_db as $curr_table) {
         if ($archiver != NULL) {
             $archiver->updatePidFile();
         }
         $table = $curr_table[0];
         fwrite($fh, "\n\n" . 'DROP TABLE IF EXISTS ' . $table . ';');
         $table_create = $wpdb->get_row('SHOW CREATE TABLE ' . $table, ARRAY_N);
         fwrite($fh, "\n" . $table_create[1] . ";\n\n");
         $rows = @MainWPChildDB::_query('SELECT * FROM ' . $table, $wpdb->dbh);
         if ($rows) {
             $i = 0;
             $table_insert = 'INSERT INTO `' . $table . '` VALUES (';
             while ($row = @MainWPChildDB::fetch_array($rows)) {
                 $query = $table_insert;
                 foreach ($row as $value) {
                     $query .= '"' . MainWPChildDB::real_escape_string($value) . '", ';
                 }
                 $query = trim($query, ', ') . ");";
                 fwrite($fh, "\n" . $query);
                 $i++;
                 if ($i >= 50) {
                     fflush($fh);
                     $i = 0;
                 }
                 $query = null;
                 $row = null;
             }
         }
         $rows = null;
         fflush($fh);
     }
     fclose($fh);
     if ($archiveExt != false) {
         $newFilepath = $filepath . '.' . $archiveExt;
         if ($archiveExt == 'zip') {
             $this->archiver = null;
         } else {
             $this->archiver = new TarArchiver($this, $archiveExt);
         }
         if ($this->zipFile($filepath, $newFilepath) && file_exists($newFilepath)) {
             @unlink($filepath);
             $filepath = $newFilepath;
         }
     }
     return array('filepath' => $filepath);
 }