• File: db-backup.php
  • Full Path: /home/matthif/www/wp-content/plugins/wp-file-manager/classes/db-backup.php
  • Date Modified: 02/06/2026 3:42 AM
  • File size: 11.33 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?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); // Comment this line to use same script's directory ('.')
define("TABLES"'*'); // Full backup
define("CHARSET"'utf8');
define("GZIP_BACKUP_FILE"true); // Set to false if you want plain SQL backup files (not gzipped)
define("DISABLE_FOREIGN_KEY_CHECKS"true); // Set to true if you are having foreign key constraint fails
define("BATCH_SIZE"1000); // Batch size when selecting rows from database in order to not exhaust system memory
                            // Also number of rows per INSERT statement in backup file
/**
 * The Backup_Database class
 */
class Backup_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;

    
/**
     * Backup directory where backup files are stored 
     */
    
var $backupDir;

    
/**
     * Output backup file
     */
    
var $backupFile;

    
/**
     * Use gzip compression on backup file
     */
    
var $gzipBackupFile;

    
/**
     * Content of standard output
     */
    
var $output;

    
/**
     * Disable foreign key checks
     */
    
var $disableForeignKeyChecks;

    
/**
     * Batch size, number of rows to process per iteration
     */
    
var $batchSize;

    
/**
     * Constructor initializes database
     */
    
public function __construct($filename) {
        
$this->host                    DB_HOST;
        
$this->username                DB_USER;
        
$this->passwd                  DB_PASSWORD;
        
$this->dbName                  DB_NAME;
        
$this->charset                 DB_CHARSET;
        
$this->conn                    $this->initializeDatabase();
        
$this->backupDir               BACKUP_DIR BACKUP_DIR '.';
        
$this->backupFile              $filename.'-db.sql';
        
$this->gzipBackupFile          defined('GZIP_BACKUP_FILE') ? GZIP_BACKUP_FILE true;
        
$this->disableForeignKeyChecks defined('DISABLE_FOREIGN_KEY_CHECKS') ? DISABLE_FOREIGN_KEY_CHECKS true;
        
$this->batchSize               defined('BATCH_SIZE') ? BATCH_SIZE 1000// default 1000 rows
        
$this->output                  '';
    }

    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);
            }
        } 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 backupTables($tables '*'$bkpDir="") {
        try {
            
/**
             * Tables to export
             */
            
if($tables == '*') {
                
$tables = array();
                
$result mysqli_query($this->conn'SHOW TABLES');
                while(
$row mysqli_fetch_row($result)) {
                    
$tables[] = $row[0];
                }
            } else {
                
$tables is_array($tables) ? $tables explode(','str_replace(' '''$tables));
            }

            
$sql 'CREATE DATABASE IF NOT EXISTS `'.$this->dbName."`;\n\n";
            
$sql .= 'USE `'.$this->dbName."`;\n\n";

            
/**
             * Disable foreign key checks 
             */
            
if ($this->disableForeignKeyChecks === true) {
                
$sql .= "SET foreign_key_checks = 0;\n\n";
            }

            
/**
             * Iterate tables
             */
            
foreach($tables as $table) {
                
$this->obfPrint("Backing up `".$table."` table...".str_repeat('.'50-strlen($table)), 00);

                
/**
                 * CREATE TABLE
                 */
                
$sql .= 'DROP TABLE IF EXISTS `'.$table.'`;';
                
$row mysqli_fetch_row(mysqli_query($this->conn'SHOW CREATE TABLE `'.$table.'`'));
                
$sql .= "\n\n".$row[1].";\n\n";

                
/**
                 * INSERT INTO
                 */

                
$row mysqli_fetch_row(mysqli_query($this->conn'SELECT COUNT(*) FROM `'.$table.'`'));
                
$numRows $row[0];

                
// Split table in batches in order to not exhaust system memory 
                
$numBatches intval($numRows $this->batchSize) + 1// Number of while-loop calls to perform

                
for ($b 1$b <= $numBatches$b++) {
                    
                    
$query 'SELECT * FROM `' $table '` LIMIT ' . ($b $this->batchSize $this->batchSize) . ',' $this->batchSize;
                    
$result mysqli_query($this->conn$query);
                    
$realBatchSize mysqli_num_rows ($result); // Last batch size can be different from $this->batchSize
                    
$numFields mysqli_num_fields($result);

                    if (
$realBatchSize !== 0) {
                        
$sql .= 'INSERT INTO `'.$table.'` VALUES ';

                        for (
$i 0$i $numFields$i++) {
                            
$rowCount 1;
                            while(
$row mysqli_fetch_row($result)) {
                                
$sql.='(';
                                for(
$j=0$j<$numFields$j++) {
                                    if (isset(
$row[$j])) {
                                        
$row[$j] = addslashes($row[$j]);
                                        
$row[$j] = str_replace("\n","\\n",$row[$j]);
                                        
$row[$j] = str_replace("\r","\\r",$row[$j]);
                                        
$row[$j] = str_replace("\f","\\f",$row[$j]);
                                        
$row[$j] = str_replace("\t","\\t",$row[$j]);
                                        
$row[$j] = str_replace("\v","\\v",$row[$j]);
                                        
$row[$j] = str_replace("\a","\\a",$row[$j]);
                                        
$row[$j] = str_replace("\b","\\b",$row[$j]);
                                        if (
preg_match('/^-?[0-9]+$/'$row[$j]) or $row[$j] == 'NULL' or $row[$j] == 'null') {
                                            
$sql .= $row[$j];
                                        } else {
                                            
$sql .= '"'.$row[$j].'"' ;
                                        }
                                    } else {
                                        
$sql.= 'NULL';
                                    }
    
                                    if (
$j < ($numFields-1)) {
                                        
$sql .= ',';
                                    }
                                }
    
                                if (
$rowCount == $realBatchSize) {
                                    
$rowCount 0;
                                    
$sql.= ");\n"//close the insert statement
                                
} else {
                                    
$sql.= "),\n"//close the row
                                
}
    
                                
$rowCount++;
                            }
                        }
    
                        
$this->saveFile($sql);
                        
$sql '';
                    }
                }
                
$sql.="\n\n";

                
$this->obfPrint('OK');
            }

            
/**
             * Re-enable foreign key checks 
             */
            
if ($this->disableForeignKeyChecks === true) {
                
$sql .= "SET foreign_key_checks = 1;\n";
            }

            
$this->saveFile($sql);

            if (
$this->gzipBackupFile) {
                
$this->gzipBackupFile();
            } else {
                
$this->obfPrint('Backup file succesfully saved to ' $this->backupDir.'/'.$this->backupFile11);
            }
        } catch (
Exception $e) {
            
print_r($e->getMessage());
            return 
false;
        }

        return 
true;
    }

    
/**
     * Save SQL to file
     * @param string $sql
     */
    
protected function saveFile(&$sql) {
        if (!
$sql) return false;

        try {

            if (!
file_exists($this->backupDir)) {
                
mkdir($this->backupDir0777true);
            }

            
file_put_contents($this->backupDir.'/'.$this->backupFile$sqlFILE_APPEND LOCK_EX);

        } catch (
Exception $e) {
            
print_r($e->getMessage());
            return 
false;
        }

        return 
true;
    }

    
/*
     * Gzip backup file
     *
     * @param integer $level GZIP compression level (default: 9)
     * @return string New filename (with .gz appended) if success, or false if operation fails
     */
    
protected function gzipBackupFile($level 9) {
        if (!
$this->gzipBackupFile) {
            return 
true;
        }

        
$source $this->backupDir '/' $this->backupFile;
        
$dest =  $source '.gz';

        
$this->obfPrint('Gzipping backup file to ' $dest '... '10);

        
$mode 'wb' $level;
        if (
$fpOut gzopen($dest$mode)) {
            if (
$fpIn fopen($source,'rb')) {
                while (!
feof($fpIn)) {
                    
gzwrite($fpOutfread($fpIn1024 256));
                }
                
fclose($fpIn);
            } else {
                return 
false;
            }
            
gzclose($fpOut);
            if(!
unlink($source)) {
                return 
false;
            }
        } else {
            return 
false;
        }
        
        
$this->obfPrint('OK');
        return 
$dest;
    }

    
/**
     * Prints message forcing output buffer flush
     *
     */
    
public function obfPrint ($msg ''$lineBreaksBefore 0$lineBreaksAfter 1) {
        if (!
$msg) {
            return 
false;
        }

        if (
$msg != 'OK' and $msg != 'KO') {
            
$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;
            }                
        }


        
// Save output for later use
        
$this->output .= str_replace('<br />''\n'$output);

        return 
$output;


        if (
php_sapi_name() != "cli") {
            if( 
ob_get_level() > ) {
                
ob_flush();
            }
        }

        
$this->output .= " ";

        
flush();
    }

    
/**
     * Returns full execution output
     *
     */
    
public function getOutput() {
        return 
$this->output;
    }
}