File "manager.php"
Full path: /home/bud/public_html/swamp/wp-admin/wp-content/plugins/backup-backup/includes/database/manager.php
File size: 9.44 KB
MIME-type: text/x-php
Charset: utf-8
<?php
// Namespace
namespace BMI\Plugin\Database;
// Use
use BMI\Plugin\BMI_Logger AS Logger;
use BMI\Plugin\Progress\BMI_ZipProgress AS Progress;
// Exit on direct access
if (!defined('ABSPATH')) exit;
/**
* BMI_Database
*/
class BMI_Database {
function __construct($host, $user, $pass, $name) {
$this->host = $host;
$this->user = $user;
$this->pass = $pass;
$this->name = $name;
}
public function exportDatabase($backup_name = false) {
$mysqli = new \mysqli($this->host, $this->user, $this->pass, $this->name);
$mysqli->select_db($this->name);
$mysqli->query("SET NAMES 'utf8'");
$file = fopen(BMI_INCLUDES . DIRECTORY_SEPARATOR . 'htaccess' . DIRECTORY_SEPARATOR . $backup_name, 'w');
$queryTables = $mysqli->query('SHOW TABLES');
while ($row = $queryTables->fetch_row()) $target_tables[] = $row[0];
fwrite($file, "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";\r\n");
fwrite($file, "SET time_zone = \"+00:00\";\r\n\r\n\r\n");
fwrite($file, "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\r\n");
fwrite($file, "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\r\n");
fwrite($file, "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\r\n");
fwrite($file, "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";\r\n");
fwrite($file, "/*!40101 SET NAMES utf8 */;\r\n");
fwrite($file, "--\r\n-- Database: `" . $this->name . "`\r\n");
fwrite($file, "--\r\n\r\n\r\n");
foreach ($target_tables as $table) {
if (empty($table)) { continue; }
$chunks_req = $mysqli->query('SELECT count(1) FROM `'.$table.'`');
$chunks_res = mysqli_fetch_array($chunks_req);
$chunks = intval($chunks_res[0]);
$res = $mysqli->query('SHOW CREATE TABLE `' . $table . '`');
$TableMLine = $res->fetch_row();
fwrite($file, "\n\n".$TableMLine[1].";\n\n");
$TableMLine[1] = str_ireplace('CREATE TABLE `','CREATE TABLE IF NOT EXISTS `', $TableMLine[1]);
if ($chunks > 0) {
$g = 0;
while($g < $chunks) {
if (($g + 100) > $chunks) $limit_str = 'LIMIT '. $g . ',1000';
else $limit_str = 'LIMIT '. $g . ',100';
$this->saveDatabaseFields($mysqli, $table, $file, $limit_str);
$g += 100;
}
} else $this->saveDatabaseFields($mysqli, $table, $file);
fwrite($file, "\n\n\n");
}
fwrite($file, "\r\n\r\n/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\r\n");
fwrite($file, "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\r\n");
fwrite($file, "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;");
$mysqli->close();
$backup_name = $backup_name ? $backup_name : $this->name.'___('.date('H-i-s').'_'.date('d-m-Y').').sql';
fclose($file);
}
public function saveDatabaseFields(&$mysqli, $table, &$file, $limit = '') {
$result = $mysqli->query('SELECT * FROM `'.$table.'` ' . $limit);
$fields_amount = $result->field_count;
$rows_num = $mysqli->affected_rows;
for ($i = 0, $st_counter = 0; $i < $fields_amount; $i++, $st_counter = 0) {
while ($row = $result->fetch_row()) {
if ($st_counter % 100 == 0 || $st_counter == 0) {
fwrite($file, "\nINSERT INTO `" . $table . "` VALUES");
}
fwrite($file, "\n(");
for ($j = 0; $j < $fields_amount; $j++) {
$row[$j] = str_replace("\n","\\n", addslashes($row[$j]));
if (isset($row[$j])) fwrite($file, '"'.$row[$j].'"');
else fwrite($file, '""');
if ($j<($fields_amount-1)) fwrite($file, ',');
}
fwrite($file, ")");
if ((($st_counter+1)%100==0 && $st_counter!=0) || $st_counter+1==$rows_num) {
fwrite($file, ";");
} else fwrite($file, ",");
$st_counter = $st_counter + 1;
}
}
}
public function recursiveReplace(&$line, &$at, &$from, &$to) {
$end = -1;
for ($i = $at; $i > 3; --$i) {
$str = $line[$i-2] . $line[$i-1] . $line[$i];
if ($str === ':\"') {
$end = $i;
break;
}
unset($str);
}
$start = -1; $semi = false;
for ($i = $end; $i > 0; --$i) {
$str = $line[$i] . $line[$i+1] . $line[$i+2];
if ($str === ';s:') {
$semi = true;
$start = $i + 3;
break;
}
if ($str === '{s:') {
$start = $i + 3;
break;
}
unset($str);
}
if ($start == -1 || $end == -1) return $line;
$diff = $end - $start; $eof = -1;
$len = intval(substr($line, $start, $diff));
$maxend = strlen($line);
if ($maxend > ($end + 3 + $len + 6)) {
$maxend = ($end + 3 + $len + 6);
}
for ($j = ($end + 3); $j < $maxend; ++$j) {
$str = $line[$j] . $line[$j+1] . $line[$j+2];
if ($str === '\";') {
$eof = $j;
break;
}
unset($str);
}
if ($eof == -1) {
for ($i = $maxend; $i > ($end + 3); --$i) {
$str = $line[$i] . $line[$i+1] . $line[$i+2];;
if ($str === '\";') {
$eof = $i;
break;
}
unset($str);
}
}
if ($eof == -1 || $eof < $end || $eof < $start) return $line;
$should = abs(strlen($from) - strlen($to));
$toreplace = substr($line, $start - 3, (($eof + 6) - $start));
$content = str_replace($from, $to, substr($toreplace, $diff + 6, -3));
if ($semi) $newreplace = ';s:' . strlen($content) . ':\"' . $content . '\";';
else $newreplace = '{s:' . strlen($content) . ':\"' . $content . '\";';
$line = str_replace($toreplace, $newreplace, $line);
// if (strlen($len >= $content)) {
// error_log($start . ' - ' . $end . ' - ' . $eof . ' - ' . $len . '['.strlen($toreplace).']' . ' - ' . '['.strlen($newreplace).']');
// error_log(strlen($toreplace) . ' -> ' . strlen($newreplace));
// error_log($toreplace);
// error_log($newreplace);
// error_log('');
// }
// Do the same for every occurence
$d = strpos($line, $from);
if ($d !== false) $line = $this->recursiveReplace($line, $d, $from, $to);
return $line;
}
public function replaceInLine(&$line) {
if (strpos($line, ':\"') !== false) {
$d = strpos($line, $this->old_domain);
if ($d !== false) $this->recursiveReplace($line, $d, $this->old_domain, $this->new_domain);
$b = strpos($line, $this->abs);
if ($b !== false) $this->recursiveReplace($line, $b, $this->abs, $this->newabs);
} else {
// Replace in case user had this wrongly defined in wp-config.
// Of course, those two ifs will take a lot of memory...
if (substr($line, 0, 16) === '("1","siteurl","') $line = '("1","siteurl","' . $this->new_domain . '","yes"),';
if (substr($line, 0, 13) === '("2","home","') $line = '("2","home","' . $this->new_domain . '","yes"),';
$line = str_replace($this->old_domain, $this->new_domain, $line);
$line = str_replace($this->abs, $this->newabs, $line);
}
return $line;
}
public function importDatabase($file, $old_domain, $new_domain, $abs, $newabs, $newprefix, $siteurl, $home) {
@ignore_user_abort(true);
@set_time_limit(16000);
$SQL_CONTENT = $file;
$mysqli = new \mysqli($this->host, $this->user, $this->pass, $this->name, $siteurl, $home);
if (mysqli_connect_errno()) {
Logger::error(__("Failed to connect to MySQL: ", 'backup-backup') . mysqli_connect_error());
return __("Importing failed - cannot connect to the database.", 'backup-backup');
}
$this->old_domain = $old_domain;
$this->new_domain = $new_domain;
$this->escaped_old = str_replace('/', '\\\/', $old_domain);
$this->escaped_new = str_replace('/', '\\\/', $new_domain);
$this->abs = $abs;
$this->newabs = $newabs;
$this->e_abs_old = str_replace('/', '\\\/', $abs);
$this->e_abs_new = str_replace('/', '\\\/', $newabs);
$handle = fopen($file, 'r');
if ($handle) {
$templine = '';
$qyr = $mysqli->query('SET foreign_key_checks = 0');
while (($line = fgets($handle)) !== false) {
preg_match_all("/\nCREATE TABLE(.*?)\`(.*?)\`/si", "\n" . $line, $target_tables);
foreach ($target_tables[2] as $table) $mysqli->query('DROP TABLE IF EXISTS `' . $table . '`');
if (substr($line, 0, 2) != '--' && $line != '') {
$this->replaceInLine($line);
$templine .= $line;
if (substr(trim($line), -1, 1) == ';') {
if (!$mysqli->query($templine)) {
Logger::error('Error performing query ' . $templine . ': ' . $mysqli->error);
}
$templine = '';
$line = '';
}
}
}
fclose($handle);
} else {
Logger::error(__("Cannot open SQL file...", 'backup-backup'));
return __("Importing failed - Cannot open SQL file...", 'backup-backup');
}
$qyr = $mysqli->query('SET foreign_key_checks = 1');
$mysqli->query("SET NAMES 'utf8'");
// $mysqli->query("UPDATE `".$new_prefix."options` SET option_value = '" . $siteurl. "' WHERE option_name = 'siteurl'");
// $mysqli->query("UPDATE `".$new_prefix."options` SET option_value = '" . $home. "' WHERE option_name = 'home'");
$mysqli->close();
return __("Importing finished. Now, Delete the import file.", 'backup-backup');
}
}