266 lines
7.9 KiB
PHP
266 lines
7.9 KiB
PHP
<?php
|
|
/**
|
|
* Define database parameters here
|
|
*/
|
|
$upload_dir = wp_upload_dir();
|
|
$backup_dirname = $upload_dir['basedir'].'/wp-file-manager-pro/fm_backup';
|
|
define("BACKUP_DIR", $backup_dirname);
|
|
define("CHARSET", 'utf8');
|
|
define("DISABLE_FOREIGN_KEY_CHECKS", true);
|
|
|
|
/**
|
|
* The Restore_Database class
|
|
*/
|
|
class Restore_Database {
|
|
/**
|
|
* Host where the database is located
|
|
*/
|
|
var $host;
|
|
|
|
/**
|
|
* Username used to connect to database
|
|
*/
|
|
var $username;
|
|
|
|
/**
|
|
* Password used to connect to database
|
|
*/
|
|
var $passwd;
|
|
|
|
/**
|
|
* Database to backup
|
|
*/
|
|
var $dbName;
|
|
|
|
/**
|
|
* Database charset
|
|
*/
|
|
var $charset;
|
|
|
|
/**
|
|
* Database connection
|
|
*/
|
|
var $conn;
|
|
|
|
/**
|
|
* Disable foreign key checks
|
|
*/
|
|
var $disableForeignKeyChecks;
|
|
|
|
/**
|
|
* Constructor initializes database
|
|
*/
|
|
function __construct($filename) {
|
|
$this->host = DB_HOST;
|
|
$this->username = DB_USER;
|
|
$this->passwd = DB_PASSWORD;
|
|
$this->dbName = DB_NAME;
|
|
$this->charset = DB_CHARSET;
|
|
$this->disableForeignKeyChecks = defined('DISABLE_FOREIGN_KEY_CHECKS') ? DISABLE_FOREIGN_KEY_CHECKS : true;
|
|
$this->conn = $this->initializeDatabase();
|
|
$this->backupDir = defined('BACKUP_DIR') ? BACKUP_DIR : '.';
|
|
$this->backupFile = $filename;
|
|
}
|
|
|
|
/**
|
|
* Destructor re-enables foreign key checks
|
|
*/
|
|
function __destructor() {
|
|
/**
|
|
* Re-enable foreign key checks
|
|
*/
|
|
if ($this->disableForeignKeyChecks === true) {
|
|
mysqli_query($this->conn, 'SET foreign_key_checks = 1');
|
|
}
|
|
}
|
|
|
|
protected function initializeDatabase() {
|
|
try {
|
|
$conn = mysqli_connect($this->host, $this->username, $this->passwd, $this->dbName);
|
|
if (mysqli_connect_errno()) {
|
|
throw new Exception('ERROR connecting database: ' . mysqli_connect_error());
|
|
die();
|
|
}
|
|
if (!mysqli_set_charset($conn, $this->charset)) {
|
|
mysqli_query($conn, 'SET NAMES '.$this->charset);
|
|
}
|
|
|
|
/**
|
|
* Disable foreign key checks
|
|
*/
|
|
if ($this->disableForeignKeyChecks === true) {
|
|
mysqli_query($conn, 'SET foreign_key_checks = 0');
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
print_r($e->getMessage());
|
|
die();
|
|
}
|
|
|
|
return $conn;
|
|
}
|
|
|
|
/**
|
|
* Backup the whole database or just some tables
|
|
* Use '*' for whole database or 'table1 table2 table3...'
|
|
* @param string $tables
|
|
*/
|
|
public function restoreDb() {
|
|
try {
|
|
$sql = '';
|
|
$multiLineComment = false;
|
|
|
|
$backupDir = $this->backupDir;
|
|
$backupFile = $this->backupFile;
|
|
|
|
/**
|
|
* Gunzip file if gzipped
|
|
*/
|
|
$backupFileIsGzipped = substr($backupFile, -3, 3) == '.gz' ? true : false;
|
|
|
|
if ($backupFileIsGzipped) {
|
|
if (!$backupFile = $this->gunzipBackupFile()) {
|
|
throw new Exception("ERROR: couldn't gunzip backup file " . $backupDir . '/' . $backupFile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Read backup file line by line
|
|
*/
|
|
$handle = fopen($backupDir . '/' . $backupFile, "r");
|
|
if ($handle) {
|
|
while (($line = fgets($handle)) !== false) {
|
|
$line = ltrim(rtrim($line));
|
|
if (strlen($line) > 1) { // avoid blank lines
|
|
$lineIsComment = false;
|
|
if (preg_match('/^\/\*/', $line)) {
|
|
$multiLineComment = true;
|
|
$lineIsComment = true;
|
|
}
|
|
if ($multiLineComment or preg_match('/^\/\//', $line)) {
|
|
$lineIsComment = true;
|
|
}
|
|
if (!$lineIsComment) {
|
|
$sql .= $line;
|
|
if (preg_match('/;$/', $line)) {
|
|
|
|
mysqli_query($this->conn, "SET sql_mode = ''");
|
|
// execute query
|
|
if(mysqli_query($this->conn, $sql)) {
|
|
if (preg_match('/^CREATE TABLE `([^`]+)`/i', $sql, $tableName)) {
|
|
$this->obfPrint("Table succesfully created: `" . $tableName[1] . "`");
|
|
}
|
|
$sql = '';
|
|
} else {
|
|
throw new Exception("ERROR: SQL execution error: " . mysqli_error($this->conn));
|
|
}
|
|
}
|
|
} else if (preg_match('/\*\/$/', $line)) {
|
|
$multiLineComment = false;
|
|
}
|
|
}
|
|
}
|
|
fclose($handle);
|
|
} else {
|
|
throw new Exception("ERROR: couldn't open backup file " . $backupDir . '/' . $backupFile);
|
|
}
|
|
} catch (Exception $e) {
|
|
print_r($e->getMessage());
|
|
return false;
|
|
}
|
|
|
|
if ($backupFileIsGzipped) {
|
|
unlink($backupDir . '/' . $backupFile);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Gunzip backup file
|
|
*
|
|
* @return string New filename (without .gz appended and without backup directory) if success, or false if operation fails
|
|
*/
|
|
protected function gunzipBackupFile() {
|
|
// Raising this value may increase performance
|
|
$bufferSize = 4096; // read 4kb at a time
|
|
$error = false;
|
|
|
|
$source = $this->backupDir . '/' . $this->backupFile;
|
|
$dest = $this->backupDir . '/' . date("Ymd_His", time()) . '_' . substr($this->backupFile, 0, -3);
|
|
|
|
$this->obfPrint('Gunzipping backup file ' . $source . '... ', 1, 1);
|
|
|
|
// Remove $dest file if exists
|
|
if (file_exists($dest)) {
|
|
if (!unlink($dest)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Open gzipped and destination files in binary mode
|
|
if (!$srcFile = gzopen($this->backupDir . '/' . $this->backupFile, 'rb')) {
|
|
return false;
|
|
}
|
|
if (!$dstFile = fopen($dest, 'wb')) {
|
|
return false;
|
|
}
|
|
|
|
while (!gzeof($srcFile)) {
|
|
// Read buffer-size bytes
|
|
// Both fwrite and gzread are binary-safe
|
|
if(!fwrite($dstFile, gzread($srcFile, $bufferSize))) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
fclose($dstFile);
|
|
gzclose($srcFile);
|
|
|
|
// Return backup filename excluding backup directory
|
|
return str_replace($this->backupDir . '/', '', $dest);
|
|
}
|
|
|
|
/**
|
|
* Prints message forcing output buffer flush
|
|
*
|
|
*/
|
|
public function obfPrint ($msg = '', $lineBreaksBefore = 0, $lineBreaksAfter = 1) {
|
|
if (!$msg) {
|
|
return false;
|
|
}
|
|
|
|
$msg = date("Y-m-d H:i:s") . ' - ' . $msg;
|
|
$output = '';
|
|
|
|
if (php_sapi_name() != "cli") {
|
|
$lineBreak = "<br />";
|
|
} else {
|
|
$lineBreak = "\n";
|
|
}
|
|
|
|
if ($lineBreaksBefore > 0) {
|
|
for ($i = 1; $i <= $lineBreaksBefore; $i++) {
|
|
$output .= $lineBreak;
|
|
}
|
|
}
|
|
|
|
$output .= $msg;
|
|
|
|
if ($lineBreaksAfter > 0) {
|
|
for ($i = 1; $i <= $lineBreaksAfter; $i++) {
|
|
$output .= $lineBreak;
|
|
}
|
|
}
|
|
|
|
if (php_sapi_name() == "cli") {
|
|
$output .= "\n";
|
|
}
|
|
|
|
if (php_sapi_name() != "cli") {
|
|
ob_flush();
|
|
}
|
|
|
|
flush();
|
|
}
|
|
}
|