2015-10-15 22:52:37 +10:00
< ? php
2020-05-27 00:02:53 -04:00
/**
* MainWP Backup
*
* This file handles all Child Site backup functions .
2020-06-10 17:19:45 +02:00
*
* @ package MainWP\Child
2020-05-27 00:02:53 -04:00
*/
2020-06-10 17:22:15 +02:00
2020-05-05 20:13:38 +07:00
namespace MainWP\Child ;
2020-06-10 17:19:45 +02:00
//phpcs:disable WordPress.WP.AlternativeFunctions, Generic.Metrics.CyclomaticComplexity -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
2020-05-14 19:43:10 +07:00
2020-05-27 00:02:53 -04:00
/**
* Class MainWP_Backup
2020-05-27 04:03:48 +00:00
*
2020-06-10 17:19:45 +02:00
* Handle all Child Site backup functions .
2020-05-27 00:02:53 -04:00
*/
2015-10-15 22:52:37 +10:00
class MainWP_Backup {
2020-06-10 17:19:45 +02:00
/**
* Whether to exclude zip archives .
*
* @ var bool true | false
*/
2020-05-27 04:03:48 +00:00
protected $excludeZip ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Container for zip file .
*
* @ var resource ZIP file
*/
2020-05-27 04:03:48 +00:00
protected $zip ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Backup files count .
*
* @ var int Files count .
*/
2020-05-27 04:03:48 +00:00
protected $zipArchiveFileCount ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Backup archive file size .
*
* @ var float File size .
*/
2020-05-27 04:03:48 +00:00
protected $zipArchiveSizeCount ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Backup archive file name .
*
* @ var string File name .
*/
2020-05-27 04:03:48 +00:00
protected $zipArchiveFileName ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Backup file descriptors .
*
* @ var int File descriptors .
*/
2020-05-27 04:03:48 +00:00
protected $file_descriptors ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Whether to load file before zip .
*
* @ var bool true | false
*/
2020-05-27 04:03:48 +00:00
protected $loadFilesBeforeZip ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Hold the current timeout length .
*
* @ var int Timeout length .
*/
2020-05-27 04:03:48 +00:00
protected $timeout ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Last time a backup has been run .
*
* @ var string Last backup run .
*/
2020-05-27 04:03:48 +00:00
protected $lastRun ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Garbage collection count .
*
* @ var int Garbage collection count .
*/
2020-05-27 04:03:48 +00:00
protected $gcCnt = 0 ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Archive test content .
*
* @ var bool Test backup content .
*/
2020-05-27 04:03:48 +00:00
protected $testContent ;
2020-05-27 00:02:53 -04:00
2020-06-10 17:19:45 +02:00
/**
* Backup process archiver .
*
* @ var object Backup process archiver .
*/
2015-10-15 22:52:37 +10:00
protected $archiver = null ;
2020-05-27 04:03:48 +00:00
/**
2020-06-10 17:19:45 +02:00
* Protected static variable to hold the single instance of the class .
*
* @ var mixed Default null
2020-05-27 04:03:48 +00:00
*/
protected static $instance = null ;
/**
2020-06-10 17:19:45 +02:00
* Create a public static instance .
2020-05-27 04:03:48 +00:00
*
2020-06-10 17:19:45 +02:00
* @ return mixed Class instance .
2020-05-27 04:03:48 +00:00
*/
public static function get () {
2015-10-15 22:52:37 +10:00
if ( null === self :: $instance ) {
2020-05-07 01:03:56 +07:00
self :: $instance = new self ();
2015-10-15 22:52:37 +10:00
}
return self :: $instance ;
}
2020-05-27 04:03:48 +00:00
/**
* Create full backup .
*
2020-06-10 17:19:45 +02:00
* @ param array $excludes Files to exclude from the backup .
* @ param string $filePrefix Backup archive file prefix .
* @ param bool $addConfig Add config file to backup .
* @ param bool $includeCoreFiles Include WordPress core files .
* @ param int $file_descriptors Number of backup archive file descriptors .
* @ param bool $fileSuffix Backup archive file suffix .
* @ param bool $excludezip Exclude zip files from the backup .
* @ param bool $excludenonwp Exclude non - WordPress directories in site root .
* @ param bool $loadFilesBeforeZip Load files before zip .
* @ param string $ext Backup file extension .
* @ param bool $pid PID true | false .
* @ param bool $append Append to backup file name .
*
2020-05-27 04:03:48 +00:00
* @ used - by MainWP_Backup :: backup_full ()
*
2020-06-10 17:19:45 +02:00
* @ return array | bool Action results on success , false on failure .
2020-05-27 04:03:48 +00:00
*/
2020-05-27 00:02:53 -04:00
public function create_full_backup (
2020-05-27 04:03:48 +00:00
$excludes ,
$filePrefix = '' ,
$addConfig = false ,
$includeCoreFiles = false ,
$file_descriptors = 0 ,
$fileSuffix = false ,
$excludezip = false ,
$excludenonwp = false ,
$loadFilesBeforeZip = true ,
$ext = 'zip' ,
$pid = false ,
$append = false ) {
2020-05-27 00:02:53 -04:00
2015-10-15 22:52:37 +10:00
$this -> file_descriptors = $file_descriptors ;
$this -> loadFilesBeforeZip = $loadFilesBeforeZip ;
2020-05-06 00:47:59 +07:00
$dirs = MainWP_Helper :: get_mainwp_dir ( 'backup' );
2015-10-15 22:52:37 +10:00
$backupdir = $dirs [ 0 ];
if ( ! defined ( 'PCLZIP_TEMPORARY_DIR' ) ) {
2020-07-30 01:01:34 -04:00
2020-08-18 15:01:13 +07:00
/**
* Defines PCLZIP temporary directory .
*
* @ const ( string ) Temporary backup directory .
* @ source https :// code - reference . mainwp . com / classes / MainWP . Child . MainWP_Backup . html
*/
2015-10-15 22:52:37 +10:00
define ( 'PCLZIP_TEMPORARY_DIR' , $backupdir );
}
if ( false !== $pid ) {
$pid = trailingslashit ( $backupdir ) . 'backup-' . $pid . '.pid' ;
}
2020-04-15 19:23:05 +02:00
// Verify if another backup is running, if so, return an error.
2015-10-15 22:52:37 +10:00
$files = glob ( $backupdir . '*.pid' );
foreach ( $files as $file ) {
2015-12-09 20:32:56 +01:00
if ( basename ( $file ) == basename ( $pid ) ) {
2015-10-15 22:52:37 +10:00
continue ;
}
if ( ( time () - filemtime ( $file ) ) < 160 ) {
2016-10-24 20:33:37 +02:00
MainWP_Helper :: error ( __ ( 'Another backup process is running. Please, try again later.' , 'mainwp-child' ) );
2015-10-15 22:52:37 +10:00
}
}
$timestamp = time ();
if ( '' !== $filePrefix ) {
$filePrefix .= '-' ;
}
2015-12-09 20:32:56 +01:00
if ( 'zip' == $ext ) {
2015-10-15 22:52:37 +10:00
$this -> archiver = null ;
$ext = '.zip' ;
} else {
$this -> archiver = new Tar_Archiver ( $this , $ext , $pid );
2020-05-06 20:22:11 +07:00
$ext = $this -> archiver -> get_extension ();
2015-10-15 22:52:37 +10:00
}
if ( ( false !== $fileSuffix ) && ! empty ( $fileSuffix ) ) {
2020-03-26 20:01:04 +00:00
// Append already contains extension!
2020-03-19 14:09:54 +01:00
$file = $fileSuffix . ( true === $append ? '' : $ext );
2015-10-15 22:52:37 +10:00
} else {
$file = 'backup-' . $filePrefix . $timestamp . $ext ;
}
$filepath = $backupdir . $file ;
$fileurl = $file ;
if ( ! $addConfig ) {
2020-03-19 19:03:24 +01:00
if ( ! in_array ( str_replace ( ABSPATH , '' , WP_CONTENT_DIR ), $excludes , true ) && ! in_array ( 'wp-admin' , $excludes , true ) && ! in_array ( WPINC , $excludes , true ) ) {
2015-10-15 22:52:37 +10:00
$addConfig = true ;
$includeCoreFiles = true ;
}
}
2020-03-19 14:09:54 +01:00
$this -> timeout = 20 * 60 * 60 ;
2015-10-15 22:52:37 +10:00
$mem = '512M' ;
2020-05-15 01:04:08 +07:00
MainWP_Helper :: set_limit ( $this -> timeout , $mem );
2020-05-14 18:09:17 +00:00
2015-10-15 22:52:37 +10:00
if ( null !== $this -> archiver ) {
2020-05-06 20:22:11 +07:00
$success = $this -> archiver -> create_full_backup ( $filepath , $excludes , $addConfig , $includeCoreFiles , $excludezip , $excludenonwp , $append );
} elseif ( $this -> check_zip_support () ) {
$success = $this -> create_zip_full_backup ( $filepath , $excludes , $addConfig , $includeCoreFiles , $excludezip , $excludenonwp );
} elseif ( $this -> check_zip_console () ) {
$success = $this -> create_zip_console_full_backup ( $filepath , $excludes , $addConfig , $includeCoreFiles , $excludezip , $excludenonwp );
2015-10-15 22:52:37 +10:00
} else {
2020-05-06 20:22:11 +07:00
$success = $this -> create_zip_pcl_full_backup2 ( $filepath , $excludes , $addConfig , $includeCoreFiles , $excludezip , $excludenonwp );
2015-10-15 22:52:37 +10:00
}
return ( $success ) ? array (
'timestamp' => $timestamp ,
'file' => $fileurl ,
'filesize' => filesize ( $filepath ),
) : false ;
}
2020-05-27 04:03:48 +00:00
/**
2020-06-10 17:19:45 +02:00
* Check whether the file is an archive or not & create a json_encoded , serialized , base64_encoded string .
2020-05-27 04:03:48 +00:00
*
2020-06-10 17:19:45 +02:00
* @ uses MainWP_Helper :: write () Write response data to be sent to the MainWP Dashboard .
* @ uses MainWP_Helper :: get_mainwp_dir () Get the MainWP directory .
2020-05-27 04:03:48 +00:00
*/
public function backup_poll () {
2020-05-21 20:10:15 +07:00
$fileNameUID = ( isset ( $_POST [ 'fileNameUID' ] ) ? $_POST [ 'fileNameUID' ] : '' );
$fileName = ( isset ( $_POST [ 'fileName' ] ) ? $_POST [ 'fileName' ] : '' );
if ( 'full' === $_POST [ 'type' ] ) {
if ( '' !== $fileName ) {
$backupFile = $fileName ;
} else {
$backupFile = 'backup-' . $fileNameUID . '-' ;
}
2020-05-27 04:03:48 +00:00
$dirs = MainWP_Helper :: get_mainwp_dir ( 'backup' );
$backupdir = $dirs [ 0 ];
$result = glob ( $backupdir . $backupFile . '*' );
2020-05-27 00:02:53 -04:00
// Check if archive, set $archiveFile = $file & break.
2020-05-21 20:10:15 +07:00
$archiveFile = false ;
foreach ( $result as $file ) {
if ( MainWP_Clone :: is_archive ( $file , $backupFile , '(.*)' ) ) {
$archiveFile = $file ;
break ;
}
}
2020-05-27 00:02:53 -04:00
// When not an archive.
2020-05-21 20:10:15 +07:00
if ( false === $archiveFile ) {
MainWP_Helper :: write ( array () );
}
2020-05-27 00:02:53 -04:00
// When archive found.
2020-05-21 20:10:15 +07:00
MainWP_Helper :: write ( array ( 'size' => filesize ( $archiveFile ) ) );
} else {
2020-05-27 04:03:48 +00:00
// When not an archive.
2020-05-21 20:10:15 +07:00
$backupFile = 'dbBackup-' . $fileNameUID . '-*.sql' ;
2020-06-10 17:19:45 +02:00
$dirs = MainWP_Helper :: get_mainwp_dir ( 'backup' );
$backupdir = $dirs [ 0 ];
$result = glob ( $backupdir . $backupFile . '*' );
2020-05-21 20:10:15 +07:00
if ( 0 === count ( $result ) ) {
MainWP_Helper :: write ( array () );
}
$size = 0 ;
foreach ( $result as $f ) {
$size += filesize ( $f );
}
MainWP_Helper :: write ( array ( 'size' => $size ) );
exit ();
}
}
2020-05-22 00:03:42 +07:00
2020-05-27 04:03:48 +00:00
/**
* Check if backup already exists or is in the process of backing up .
2020-06-10 17:19:45 +02:00
*
* @ uses MainWP_Helper :: write () Write response data to be sent to the MainWP Dashboard .
* @ uses MainWP_Helper :: get_mainwp_dir () Get the MainWP directory .
* @ uses MainWP_Helper :: get_wp_filesystem () Get the WordPress filesystem .
*
* @ uses WP_Filesystem_Base :: is_file () Checks if resource is a file .
* @ see https :// developer . wordpress . org / reference / classes / wp_filesystem_base / is_file /
*
* @ uses WP_Filesystem_Base :: mtime () Gets the file modification time .
* @ see https :// developer . wordpress . org / reference / classes / wp_filesystem_base / mtime /
*
* @ uses WP_Filesystem_Base :: get_contents () Reads entire file into a string .
* @ see https :// developer . wordpress . org / reference / classes / wp_filesystem_base / get_contents /
2020-05-27 04:03:48 +00:00
*/
public function backup_checkpid () {
2020-05-21 20:10:15 +07:00
$pid = $_POST [ 'pid' ];
$dirs = MainWP_Helper :: get_mainwp_dir ( 'backup' );
$backupdir = $dirs [ 0 ];
$information = array ();
global $wp_filesystem ;
MainWP_Helper :: get_wp_filesystem ();
$pidFile = trailingslashit ( $backupdir ) . 'backup-' . $pid . '.pid' ;
$doneFile = trailingslashit ( $backupdir ) . 'backup-' . $pid . '.done' ;
if ( $wp_filesystem -> is_file ( $pidFile ) ) {
$time = $wp_filesystem -> mtime ( $pidFile );
2020-06-10 17:19:45 +02:00
$minutes = date ( 'i' , time () ); // phpcs:ignore -- required to achieve desired results, pull request solutions appreciated.
$seconds = date ( 's' , time () ); // phpcs:ignore -- required to achieve desired results, pull request solutions appreciated.
2020-05-21 20:10:15 +07:00
2020-06-10 17:19:45 +02:00
$file_minutes = date ( 'i' , $time ); // phpcs:ignore -- required to achieve desired results, pull request solutions appreciated.
$file_seconds = date ( 's' , $time ); // phpcs:ignore -- required to achieve desired results, pull request solutions appreciated.
2020-05-21 20:10:15 +07:00
$minuteDiff = $minutes - $file_minutes ;
if ( 59 === $minuteDiff ) {
$minuteDiff = 1 ;
}
$secondsdiff = ( $minuteDiff * 60 ) + $seconds - $file_seconds ;
2020-05-27 04:03:48 +00:00
$file = $wp_filesystem -> get_contents ( $pidFile );
2020-05-21 20:10:15 +07:00
$information [ 'file' ] = basename ( $file );
if ( $secondsdiff < 80 ) {
$information [ 'status' ] = 'busy' ;
} else {
$information [ 'status' ] = 'stalled' ;
}
} elseif ( $wp_filesystem -> is_file ( $doneFile ) ) {
$file = $wp_filesystem -> get_contents ( $doneFile );
$information [ 'status' ] = 'done' ;
$information [ 'file' ] = basename ( $file );
$information [ 'size' ] = filesize ( $file );
} else {
$information [ 'status' ] = 'invalid' ;
}
MainWP_Helper :: write ( $information );
}
2020-05-22 00:03:42 +07:00
2020-05-27 04:03:48 +00:00
/**
* Perform a backup .
*
2020-06-10 17:19:45 +02:00
* @ param bool $write Whether or not to execute MainWP_Helper :: write (), Default : true .
*
* @ uses MainWP_Helper :: set_limit () Set PHP Memory Limit and PHP Max Execution time values .
* @ uses MainWP_Helper :: end_session () End session and flush the output buffer .
* @ uses MainWP_Helper :: get_wp_filesystem () Get the WordPress filesystem .
* @ uses MainWP_Helper :: ends_with () Check if the String 1 ends with the String 2.
* @ uses MainWP_Helper :: write () Write response data to be sent to the MainWP Dashboard .
* @ uses MainWP_Backup :: backup_full () Perform a full backup .
2020-05-27 04:03:48 +00:00
*
2020-06-10 17:19:45 +02:00
* @ return array Array of information on the backup containing the type of backup performed , full , or DB & whether or not it was successful .
2020-05-27 04:03:48 +00:00
*/
2020-06-10 17:19:45 +02:00
public function backup ( $write = true ) {
2020-05-21 20:10:15 +07:00
$timeout = 20 * 60 * 60 ;
MainWP_Helper :: set_limit ( $timeout );
MainWP_Helper :: end_session ();
// Cleanup pid files!
$dirs = MainWP_Helper :: get_mainwp_dir ( 'backup' );
$backupdir = trailingslashit ( $dirs [ 0 ] );
global $wp_filesystem ;
MainWP_Helper :: get_wp_filesystem ();
$files = glob ( $backupdir . '*' );
foreach ( $files as $file ) {
if ( MainWP_Helper :: ends_with ( $file , '/index.php' ) | MainWP_Helper :: ends_with ( $file , '/.htaccess' ) ) {
continue ;
}
if ( ( time () - filemtime ( $file ) ) > ( 60 * 60 * 3 ) ) {
unlink ( $file );
}
}
$fileName = ( isset ( $_POST [ 'fileUID' ] ) ? $_POST [ 'fileUID' ] : '' );
if ( 'full' === $_POST [ 'type' ] ) {
$res = $this -> backup_full ( $fileName );
if ( ! $res ) {
$information [ 'full' ] = false ;
} else {
$information [ 'full' ] = $res [ 'file' ];
$information [ 'size' ] = $res [ 'filesize' ];
}
$information [ 'db' ] = false ;
} elseif ( 'db' == $_POST [ 'type' ] ) {
$ext = 'zip' ;
if ( isset ( $_POST [ 'ext' ] ) ) {
$ext = $_POST [ 'ext' ];
}
$res = $this -> backup_db ( $fileName , $ext );
if ( ! $res ) {
$information [ 'db' ] = false ;
} else {
$information [ 'db' ] = $res [ 'file' ];
$information [ 'size' ] = $res [ 'filesize' ];
}
$information [ 'full' ] = false ;
} else {
$information [ 'full' ] = false ;
$information [ 'db' ] = false ;
}
2020-06-10 17:19:45 +02:00
if ( $write ) {
2020-05-21 20:10:15 +07:00
MainWP_Helper :: write ( $information );
}
return $information ;
}
2020-05-27 04:03:48 +00:00
/**
* Perform a full backup .
*
2020-06-10 17:22:15 +02:00
* @ param string $fileName Backup archive file name .
2020-06-10 17:19:45 +02:00
*
* @ uses MainWP_Backup :: create_full_backup () Create full backup .
*
* @ return array | bool Returns an array containing the Backup location & file size . Return FALSE on failure .
2020-05-27 04:03:48 +00:00
*/
public function backup_full ( $fileName ) {
2020-05-21 20:10:15 +07:00
$excludes = ( isset ( $_POST [ 'exclude' ] ) ? explode ( ',' , $_POST [ 'exclude' ] ) : array () );
$excludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/uploads/mainwp' ;
$uploadDir = MainWP_Helper :: get_mainwp_dir ();
$uploadDir = $uploadDir [ 0 ];
$excludes [] = str_replace ( ABSPATH , '' , $uploadDir );
$excludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/object-cache.php' ;
if ( function_exists ( 'posix_uname' ) ) {
$uname = posix_uname ();
if ( is_array ( $uname ) && isset ( $uname [ 'nodename' ] ) ) {
if ( stristr ( $uname [ 'nodename' ], 'hostgator' ) ) {
if ( ! isset ( $_POST [ 'file_descriptors' ] ) || '0' == $_POST [ 'file_descriptors' ] || $_POST [ 'file_descriptors' ] > 1000 ) {
$_POST [ 'file_descriptors' ] = 1000 ;
}
$_POST [ 'file_descriptors_auto' ] = 0 ;
$_POST [ 'loadFilesBeforeZip' ] = false ;
}
}
}
$file_descriptors = ( isset ( $_POST [ 'file_descriptors' ] ) ? $_POST [ 'file_descriptors' ] : 0 );
$file_descriptors_auto = ( isset ( $_POST [ 'file_descriptors_auto' ] ) ? $_POST [ 'file_descriptors_auto' ] : 0 );
if ( 1 === ( int ) $file_descriptors_auto ) {
if ( function_exists ( 'posix_getrlimit' ) ) {
$result = posix_getrlimit ();
if ( isset ( $result [ 'soft openfiles' ] ) ) {
$file_descriptors = $result [ 'soft openfiles' ];
}
}
}
$loadFilesBeforeZip = ( isset ( $_POST [ 'loadFilesBeforeZip' ] ) ? $_POST [ 'loadFilesBeforeZip' ] : true );
$newExcludes = array ();
foreach ( $excludes as $exclude ) {
$newExcludes [] = rtrim ( $exclude , '/' );
}
$excludebackup = ( isset ( $_POST [ 'excludebackup' ] ) && '1' == $_POST [ 'excludebackup' ] );
$excludecache = ( isset ( $_POST [ 'excludecache' ] ) && '1' == $_POST [ 'excludecache' ] );
$excludezip = ( isset ( $_POST [ 'excludezip' ] ) && '1' == $_POST [ 'excludezip' ] );
$excludenonwp = ( isset ( $_POST [ 'excludenonwp' ] ) && '1' == $_POST [ 'excludenonwp' ] );
if ( $excludebackup ) {
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/uploads/backupbuddy_backups' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/uploads/backupbuddy_temp' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/uploads/pb_backupbuddy' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/managewp' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/infinitewp' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/backups' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/backups' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/uploads/backwpup*' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/plugins/wp-complete-backup/storage' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/backups' ;
$newExcludes [] = '/administrator/backups' ;
}
if ( $excludecache ) {
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/w3tc-cache' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/w3tc' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/cache/config' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/cache/minify' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/cache/page_enhanced' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/cache/tmp' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/cache/supercache' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/cache/quick-cache' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/hyper-cache/cache' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/cache/all' ;
$newExcludes [] = str_replace ( ABSPATH , '' , WP_CONTENT_DIR ) . '/cache/wp-rocket' ;
}
$file = false ;
if ( isset ( $_POST [ 'f' ] ) ) {
$file = $_POST [ 'f' ];
} elseif ( isset ( $_POST [ 'file' ] ) ) {
$file = $_POST [ 'file' ];
}
$ext = 'zip' ;
if ( isset ( $_POST [ 'ext' ] ) ) {
$ext = $_POST [ 'ext' ];
}
$pid = false ;
if ( isset ( $_POST [ 'pid' ] ) ) {
$pid = $_POST [ 'pid' ];
}
$append = ( isset ( $_POST [ 'append' ] ) && ( '1' == $_POST [ 'append' ] ) );
return $this -> create_full_backup ( $newExcludes , $fileName , true , true , $file_descriptors , $file , $excludezip , $excludenonwp , $loadFilesBeforeZip , $ext , $pid , $append );
}
2020-05-27 04:03:48 +00:00
/**
2020-06-10 17:19:45 +02:00
* Backup site database .
*
* @ param string $fileName Backup arhive file name .
* @ param string $ext Backup achive extension .
*
* @ uses MainWP_Helper :: update_option () Update database option by option name .
* @ uses MainWP_Helper :: get_mainwp_dir () Get the MainWP directory .
* @ uses MainWP_Backup :: create_backup_db () Create database backup .
2020-05-27 04:03:48 +00:00
*
* @ return array | bool $success Returns an array containing the Backup location & file size . Return FALSE on failure .
*/
public function backup_db ( $fileName = '' , $ext = 'zip' ) {
2020-05-21 20:10:15 +07:00
$dirs = MainWP_Helper :: get_mainwp_dir ( 'backup' );
$dir = $dirs [ 0 ];
$timestamp = time ();
if ( '' !== $fileName ) {
$fileName .= '-' ;
}
$filepath_prefix = $dir . 'dbBackup-' . $fileName . $timestamp ;
$dh = opendir ( $dir );
if ( $dh ) {
while ( ( $file = readdir ( $dh ) ) !== false ) {
if ( '.' !== $file && '..' !== $file && ( preg_match ( '/dbBackup-(.*).sql(\.zip|\.tar|\.tar\.gz|\.tar\.bz2|\.tmp)?$/' , $file ) ) ) {
unlink ( $dir . $file );
}
}
closedir ( $dh );
}
2020-05-22 00:14:53 +07:00
$result = $this -> create_backup_db ( $filepath_prefix , $ext );
2020-05-21 20:10:15 +07:00
MainWP_Helper :: update_option ( 'mainwp_child_last_db_backup_size' , filesize ( $result [ 'filepath' ] ) );
return ( ! $result ) ? false : array (
'timestamp' => $timestamp ,
'file' => basename ( $result [ 'filepath' ] ),
'filesize' => filesize ( $result [ 'filepath' ] ),
);
}
2020-05-22 00:14:53 +07:00
2020-05-27 04:03:48 +00:00
/**
2020-06-10 17:19:45 +02:00
* Create the ZIP file .
2020-05-27 04:03:48 +00:00
*
* @ param array $files Files to zip .
* @ param string $archive Type of archive to create .
2020-06-10 17:19:45 +02:00
*
* @ uses MainWP_Helper :: set_limit () Set PHP memory limit .
*
* @ return bool Return FALSE on failure , TRUE on success .
2020-05-27 04:03:48 +00:00
*/
public function zip_file ( $files , $archive ) {
2020-03-19 14:09:54 +01:00
$this -> timeout = 20 * 60 * 60 ;
2015-10-15 22:52:37 +10:00
$mem = '512M' ;
2020-05-15 01:04:08 +07:00
MainWP_Helper :: set_limit ( $this -> timeout , $mem );
2020-05-14 18:09:17 +00:00
2020-03-26 17:03:00 +00:00
if ( ! is_array ( $files ) ) {
2020-03-26 15:29:54 +00:00
$files = array ( $files );
2015-12-22 19:18:07 +01:00
}
2015-10-15 22:52:37 +10:00
if ( null !== $this -> archiver ) {
2020-05-06 20:22:11 +07:00
$success = $this -> archiver -> zip_file ( $files , $archive );
} elseif ( $this -> check_zip_support () ) {
$success = $this -> m_zip_file ( $files , $archive );
} elseif ( $this -> check_zip_console () ) {
$success = $this -> m_zip_file_console ( $files , $archive );
2015-10-15 22:52:37 +10:00
} else {
2020-05-06 20:22:11 +07:00
$success = $this -> m_zip_file_pcl ( $files , $archive );
2015-10-15 22:52:37 +10:00
}
return $success ;
}
2020-05-27 04:03:48 +00:00
/**
* Create m_zip_file .
*
2020-06-10 17:19:45 +02:00
* @ param array $files Files to zip .
2020-05-27 04:03:48 +00:00
* @ param string $archive Type of archive to create .
2020-06-10 17:19:45 +02:00
*
* @ return bool Return false on failure .
2020-05-27 04:03:48 +00:00
*/
public function m_zip_file ( $files , $archive ) {
2020-05-14 19:43:10 +07:00
$this -> zip = new \ZipArchive ();
2015-10-15 22:52:37 +10:00
$this -> zipArchiveFileCount = 0 ;
$this -> zipArchiveSizeCount = 0 ;
2020-05-14 19:43:10 +07:00
$zipRes = $this -> zip -> open ( $archive , \ZipArchive :: CREATE );
2015-10-15 22:52:37 +10:00
if ( $zipRes ) {
2015-12-22 19:18:07 +01:00
foreach ( $files as $file ) {
2020-05-06 20:22:11 +07:00
$this -> add_fileToZip ( $file , basename ( $file ) );
2015-12-22 19:18:07 +01:00
}
2015-10-15 22:52:37 +10:00
return $this -> zip -> close ();
}
return false ;
}
2020-05-27 04:03:48 +00:00
/**
* Method m_zip_file_console () .
*
2020-06-10 17:19:45 +02:00
* @ param array $files Files to zip .
2020-05-27 04:03:48 +00:00
* @ param string $archive Type of archive to create .
2020-06-10 17:19:45 +02:00
*
* @ return bool Return false .
2020-05-27 04:03:48 +00:00
*/
public function m_zip_file_console ( $files , $archive ) {
2015-10-15 22:52:37 +10:00
return false ;
}
2020-05-27 04:03:48 +00:00
/**
2020-06-10 17:19:45 +02:00
* Use pclzip to add files to the zip archive .
2020-05-27 04:03:48 +00:00
*
2020-06-10 17:19:45 +02:00
* @ param array $files Files to zip .
2020-05-27 04:03:48 +00:00
* @ param string $archive Type of archive to create .
2020-06-10 17:19:45 +02:00
*
2020-05-27 04:03:48 +00:00
* @ return array $rslt Return array of results .
*/
public function m_zip_file_pcl ( $files , $archive ) {
2020-04-15 19:23:05 +02:00
// Zip this backup folder.
2020-03-26 14:11:33 +00:00
require_once ABSPATH . 'wp-admin/includes/class-pclzip.php' ;
2020-05-14 19:43:10 +07:00
$this -> zip = new \PclZip ( $archive );
2015-10-15 22:52:37 +10:00
$error = false ;
2015-12-22 19:18:07 +01:00
foreach ( $files as $file ) {
2020-04-15 19:23:05 +02:00
$rslt = $this -> zip -> add ( $file , PCLZIP_OPT_REMOVE_PATH , dirname ( $file ) );
if ( 0 === $rslt ) {
2015-12-22 19:18:07 +01:00
$error = true ;
}
2015-10-15 22:52:37 +10:00
}
2020-03-26 17:03:00 +00:00
return ! $error ;
2015-10-15 22:52:37 +10:00
}
/**
2020-05-27 00:02:53 -04:00
* Check for default PHP zip support .
2015-10-15 22:52:37 +10:00
*
2020-06-10 17:19:45 +02:00
* @ return bool Returns true if class_name is a defined class , false otherwise .
2020-05-27 04:03:48 +00:00
*/
2020-05-06 20:22:11 +07:00
public function check_zip_support () {
2020-05-14 19:43:10 +07:00
return class_exists ( '\ZipArchive' );
2015-10-15 22:52:37 +10:00
}
/**
* Check if we could run zip on console
*
2020-06-10 17:19:45 +02:00
* @ return bool Return false .
2015-10-15 22:52:37 +10:00
*/
2020-05-06 20:22:11 +07:00
public function check_zip_console () {
2015-10-15 22:52:37 +10:00
return false ;
}
2020-05-27 04:03:48 +00:00
/**
* Create full backup using default PHP zip library .
*
2020-06-10 17:19:45 +02:00
* @ param string $filepath File path to create .
* @ param array $excludes Files to exclude from the backup .
* @ param bool $addConfig Add config file to backup .
* @ param bool $includeCoreFiles Include WordPress core files .
* @ param bool $excludezip Exclude zip files from the backup .
* @ param bool $excludenonwp Exclude non - WordPress directories in site root .
*
* @ uses MainWP_Helper :: starts_with () Check if the String 1 starts with the String 2.
* @ uses MainWP_Helper :: in_excludes () Check if the value is in the excludes list .
* @ uses MainWP_Backup :: include_core_files () Include core files in backup .
* @ uses MainWP_Backup :: add_config () Add config file to backup .
*
* @ return bool Return true on success & false on failure .
2020-05-27 04:03:48 +00:00
*/
2020-05-27 00:02:53 -04:00
public function create_zip_full_backup (
2020-05-27 04:03:48 +00:00
$filepath ,
$excludes ,
$addConfig ,
$includeCoreFiles ,
$excludezip ,
$excludenonwp ) {
2020-05-27 00:02:53 -04:00
2015-10-15 22:52:37 +10:00
$this -> excludeZip = $excludezip ;
2020-05-14 19:43:10 +07:00
$this -> zip = new \ZipArchive ();
2015-10-15 22:52:37 +10:00
$this -> zipArchiveFileCount = 0 ;
$this -> zipArchiveSizeCount = 0 ;
$this -> zipArchiveFileName = $filepath ;
2020-05-14 19:43:10 +07:00
$zipRes = $this -> zip -> open ( $filepath , \ZipArchive :: CREATE );
2015-10-15 22:52:37 +10:00
if ( $zipRes ) {
$nodes = glob ( ABSPATH . '*' );
if ( ! $includeCoreFiles ) {
2020-05-19 18:08:42 +00:00
$this -> include_core_files ( $nodes );
2015-10-15 22:52:37 +10:00
}
2020-05-06 20:22:11 +07:00
$db_files = $this -> create_backup_db ( dirname ( $filepath ) . DIRECTORY_SEPARATOR . 'dbBackup' );
2015-12-22 19:18:07 +01:00
foreach ( $db_files as $db_file ) {
2020-05-06 20:22:11 +07:00
$this -> add_file_to_zipp ( $db_file , basename ( WP_CONTENT_DIR ) . '/' . basename ( $db_file ) );
2015-12-22 19:18:07 +01:00
}
2015-10-15 22:52:37 +10:00
if ( file_exists ( ABSPATH . '.htaccess' ) ) {
2020-05-06 20:22:11 +07:00
$this -> add_file_to_zipp ( ABSPATH . '.htaccess' , 'mainwp-htaccess' );
2015-10-15 22:52:37 +10:00
}
foreach ( $nodes as $node ) {
if ( $excludenonwp && is_dir ( $node ) ) {
2020-05-06 00:47:59 +07:00
if ( ! MainWP_Helper :: starts_with ( $node , WP_CONTENT_DIR ) && ! MainWP_Helper :: starts_with ( $node , ABSPATH . 'wp-admin' ) && ! MainWP_Helper :: starts_with ( $node , ABSPATH . WPINC ) ) {
2015-10-15 22:52:37 +10:00
continue ;
}
}
2020-05-06 00:47:59 +07:00
if ( ! MainWP_Helper :: in_excludes ( $excludes , str_replace ( ABSPATH , '' , $node ) ) ) {
2015-10-15 22:52:37 +10:00
if ( is_dir ( $node ) ) {
2020-05-06 20:22:11 +07:00
$this -> zip_add_dir ( $node , $excludes );
2020-03-19 14:09:54 +01:00
} elseif ( is_file ( $node ) ) {
2020-05-06 20:22:11 +07:00
$this -> add_file_to_zipp ( $node , str_replace ( ABSPATH , '' , $node ) );
2015-10-15 22:52:37 +10:00
}
}
}
if ( $addConfig ) {
2020-05-19 01:15:36 +07:00
$this -> add_config ();
2015-10-15 22:52:37 +10:00
}
$return = $this -> zip -> close ();
2015-12-22 19:18:07 +01:00
foreach ( $db_files as $db_file ) {
2020-04-23 19:53:22 +02:00
unlink ( $db_file );
2015-12-22 19:18:07 +01:00
}
2015-10-15 22:52:37 +10:00
return true ;
}
return false ;
}
2020-05-27 04:03:48 +00:00
/**
2020-06-10 17:19:45 +02:00
* Exclude certain core files from the backup .
*
* @ param array $nodes Default nodes .
2020-05-27 04:03:48 +00:00
*
2020-06-10 17:19:45 +02:00
* @ uses MainWP_Helper :: starts_with () Check if the String 1 starts with the String 2.
2020-05-27 04:03:48 +00:00
*/
private function include_core_files ( & $nodes ) {
2020-05-21 01:22:51 +07:00
$coreFiles = array (
2020-05-19 13:24:43 +00:00
'favicon.ico' ,
'index.php' ,
'license.txt' ,
'readme.html' ,
'wp-activate.php' ,
'wp-app.php' ,
'wp-blog-header.php' ,
'wp-comments-post.php' ,
'wp-config.php' ,
'wp-config-sample.php' ,
'wp-cron.php' ,
'wp-links-opml.php' ,
'wp-load.php' ,
'wp-login.php' ,
'wp-mail.php' ,
'wp-pass.php' ,
'wp-register.php' ,
'wp-settings.php' ,
'wp-signup.php' ,
'wp-trackback.php' ,
'xmlrpc.php' ,
);
2020-05-20 01:07:47 +07:00
foreach ( $nodes as $key => $node ) {
if ( MainWP_Helper :: starts_with ( $node , ABSPATH . WPINC ) ) {
unset ( $nodes [ $key ] );
} elseif ( MainWP_Helper :: starts_with ( $node , ABSPATH . basename ( admin_url ( '' ) ) ) ) {
unset ( $nodes [ $key ] );
} else {
foreach ( $coreFiles as $coreFile ) {
if ( ABSPATH . $coreFile === $node ) {
unset ( $nodes [ $key ] );
}
}
}
}
unset ( $coreFiles );
2020-05-19 20:08:55 +07:00
}
2020-05-19 13:24:43 +00:00
2020-05-27 04:03:48 +00:00
/**
* Add config file to backup .
2020-06-10 17:19:45 +02:00
*
* @ uses wp_json_encode () Encode a variable into JSON , with some sanity checks .
* @ see https :// developer . wordpress . org / reference / functions / wp_json_encode /
*
* @ uses get_option () Get option by name .
* @ see https :// developer . wordpress . org / reference / functions / get_option /
2020-05-27 04:03:48 +00:00
*/
public function add_config () {
2020-05-27 00:02:53 -04:00
2020-05-19 01:15:36 +07:00
global $wpdb ;
2020-05-27 00:02:53 -04:00
2020-05-19 01:15:36 +07:00
$plugins = array ();
2020-05-22 17:49:27 +00:00
$dir = WP_CONTENT_DIR . '/plugins/' ;
2020-05-19 01:15:36 +07:00
$fh = opendir ( $dir );
while ( $entry = readdir ( $fh ) ) {
if ( ! is_dir ( $dir . $entry ) ) {
continue ;
}
if ( ( '.' == $entry ) || ( '..' == $entry ) ) {
continue ;
}
$plugins [] = $entry ;
}
2020-05-22 17:49:27 +00:00
closedir ( $fh );
2020-05-19 01:15:36 +07:00
$themes = array ();
2020-05-22 17:49:27 +00:00
$dir = WP_CONTENT_DIR . '/themes/' ;
2020-05-19 01:15:36 +07:00
$fh = opendir ( $dir );
while ( $entry = readdir ( $fh ) ) {
if ( ! is_dir ( $dir . $entry ) ) {
continue ;
}
if ( ( '.' == $entry ) || ( '..' == $entry ) ) {
continue ;
}
$themes [] = $entry ;
}
2020-05-22 17:49:27 +00:00
closedir ( $fh );
2020-05-19 01:15:36 +07:00
if ( defined ( 'MAINWP_CHILD_DEBUG' ) && MAINWP_CHILD_DEBUG ) {
$string = wp_json_encode (
array (
'siteurl' => get_option ( 'siteurl' ),
'home' => get_option ( 'home' ),
'abspath' => ABSPATH ,
'prefix' => $wpdb -> prefix ,
'lang' => defined ( 'WPLANG' ) ? WPLANG : '' ,
'plugins' => $plugins ,
'themes' => $themes ,
)
);
} else {
2020-06-10 17:19:45 +02:00
$string = base64_encode ( // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- Safe requst, required for backwards compatibility.
serialize ( // phpcs:ignore -- Safe requst, required for backwards compatibility.
2020-05-19 01:15:36 +07:00
array (
'siteurl' => get_option ( 'siteurl' ),
'home' => get_option ( 'home' ),
'abspath' => ABSPATH ,
'prefix' => $wpdb -> prefix ,
'lang' => defined ( 'WPLANG' ) ? WPLANG : '' ,
'plugins' => $plugins ,
'themes' => $themes ,
)
)
);
}
$this -> add_file_from_string_to_zip ( 'clone/config.txt' , $string );
}
2020-05-18 18:16:30 +00:00
2020-05-27 04:03:48 +00:00
/**
* Copy directory .
*
2020-06-10 17:19:45 +02:00
* @ param array $nodes Default nodes .
* @ param array $excludes Files & directories to exclude .
* @ param string $backupfolder Backup folder .
* @ param bool $excludenonwp Whether or not to exclude any wp core files .
*
* @ uses MainWP_Helper :: starts_with () Check if the String 1 starts with the String 2.
* @ uses MainWP_Helper :: in_excludes () Check if the value is in the excludes list .
* @ uses MainWP_Helper :: ends_with () Check if the String 1 ends with the String 2.
2020-05-27 04:03:48 +00:00
*/
2020-06-10 17:19:45 +02:00
public function copy_dir ( $nodes , $excludes , $backupfolder , $excludenonwp ) {
2015-10-15 22:52:37 +10:00
if ( ! is_array ( $nodes ) ) {
return ;
}
foreach ( $nodes as $node ) {
if ( $excludenonwp && is_dir ( $node ) ) {
2020-05-06 00:47:59 +07:00
if ( ! MainWP_Helper :: starts_with ( $node , WP_CONTENT_DIR ) && ! MainWP_Helper :: starts_with ( $node , ABSPATH . 'wp-admin' ) && ! MainWP_Helper :: starts_with ( $node , ABSPATH . WPINC ) ) {
2015-10-15 22:52:37 +10:00
continue ;
}
}
2020-05-06 00:47:59 +07:00
if ( ! MainWP_Helper :: in_excludes ( $excludes , str_replace ( ABSPATH , '' , $node ) ) ) {
2015-10-15 22:52:37 +10:00
if ( is_dir ( $node ) ) {
if ( ! file_exists ( str_replace ( ABSPATH , $backupfolder , $node ) ) ) {
2020-06-10 17:19:45 +02:00
mkdir ( str_replace ( ABSPATH , $backupfolder , $node ) ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
2015-10-15 22:52:37 +10:00
}
$newnodes = glob ( $node . DIRECTORY_SEPARATOR . '*' );
$this -> copy_dir ( $newnodes , $excludes , $backupfolder , $excludenonwp , false );
unset ( $newnodes );
2020-03-19 14:09:54 +01:00
} elseif ( is_file ( $node ) ) {
2020-05-06 00:47:59 +07:00
if ( $this -> excludeZip && MainWP_Helper :: ends_with ( $node , '.zip' ) ) {
2015-10-15 22:52:37 +10:00
continue ;
}
2020-06-10 17:19:45 +02:00
copy ( $node , str_replace ( ABSPATH , $backupfolder , $node ) ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
2015-10-15 22:52:37 +10:00
}
}
}
}
2020-05-27 04:03:48 +00:00
/**
* Create PCL zip full backup 2.
*
2020-06-10 17:19:45 +02:00
* @ param string $filepath Path to file .
* @ param array $excludes Files & directories to exclude .
* @ param bool $addConfig Add config file to backup .
2020-05-27 04:03:48 +00:00
* @ param bool $includeCoreFiles Whether to include core files .
2020-06-10 17:19:45 +02:00
* @ param bool $excludezip Whether to exclude zip archives .
* @ param bool $excludenonwp Whether or not to exclude any wp core files .
*
* @ uses MainWP_Helper :: delete_dir () Delete wanted directory .
* @ uses MainWP_Helper :: starts_with () Check if the String 1 starts with the String 2.
* @ uses MainWP_Backup :: create_backup_db () Create database backup .
* @ uses MainWP_Backup :: add_file_from_string_to_pcl_zip () Add file from a string to pclzip file .
*
* @ uses wp_json_encode () Encode a variable into JSON , with some sanity checks .
* @ see https :// developer . wordpress . org / reference / functions / wp_json_encode /
2020-05-27 04:03:48 +00:00
*
2020-06-10 17:19:45 +02:00
* @ uses get_option () Get option by name .
* @ see https :// developer . wordpress . org / reference / functions / get_option /
*
* @ return bool Return true on success .
2020-05-27 04:03:48 +00:00
*/
public function create_zip_pcl_full_backup2 ( $filepath , $excludes , $addConfig , $includeCoreFiles , $excludezip , $excludenonwp ) {
2020-04-15 19:23:05 +02:00
// Create backup folder.
2015-10-15 22:52:37 +10:00
$backupFolder = dirname ( $filepath ) . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR ;
2020-06-10 17:19:45 +02:00
mkdir ( $backupFolder ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
2020-04-15 19:23:05 +02:00
// Create DB backup.
2020-05-06 20:22:11 +07:00
$db_files = $this -> create_backup_db ( $backupFolder . 'dbBackup' );
2015-10-15 22:52:37 +10:00
2020-04-15 19:23:05 +02:00
// Copy installation to backup folder.
2015-10-15 22:52:37 +10:00
$nodes = glob ( ABSPATH . '*' );
if ( ! $includeCoreFiles ) {
$coreFiles = array (
'favicon.ico' ,
'index.php' ,
'license.txt' ,
'readme.html' ,
'wp-activate.php' ,
'wp-app.php' ,
'wp-blog-header.php' ,
'wp-comments-post.php' ,
'wp-config.php' ,
'wp-config-sample.php' ,
'wp-cron.php' ,
'wp-links-opml.php' ,
'wp-load.php' ,
'wp-login.php' ,
'wp-mail.php' ,
'wp-pass.php' ,
'wp-register.php' ,
'wp-settings.php' ,
'wp-signup.php' ,
'wp-trackback.php' ,
'xmlrpc.php' ,
);
foreach ( $nodes as $key => $node ) {
2020-05-06 00:47:59 +07:00
if ( MainWP_Helper :: starts_with ( $node , ABSPATH . WPINC ) ) {
2015-10-15 22:52:37 +10:00
unset ( $nodes [ $key ] );
2020-05-06 00:47:59 +07:00
} elseif ( MainWP_Helper :: starts_with ( $node , ABSPATH . basename ( admin_url ( '' ) ) ) ) {
2015-10-15 22:52:37 +10:00
unset ( $nodes [ $key ] );
} else {
foreach ( $coreFiles as $coreFile ) {
2015-12-09 20:32:56 +01:00
if ( ABSPATH . $coreFile == $node ) {
2015-10-15 22:52:37 +10:00
unset ( $nodes [ $key ] );
}
}
}
}
unset ( $coreFiles );
}
$this -> copy_dir ( $nodes , $excludes , $backupFolder , $excludenonwp , true );
2015-12-22 19:18:07 +01:00
foreach ( $db_files as $db_file ) {
2020-06-10 17:19:45 +02:00
copy ( $db_file , $backupFolder . basename ( WP_CONTENT_DIR ) . '/' . basename ( $db_file ) ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
unlink ( $db_file ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
2015-12-22 19:18:07 +01:00
}
2020-04-15 19:23:05 +02:00
2015-10-15 22:52:37 +10:00
unset ( $nodes );
2020-04-15 19:23:05 +02:00
// Zip this backup folder.
2020-03-26 14:11:33 +00:00
require_once ABSPATH . 'wp-admin/includes/class-pclzip.php' ;
2020-05-14 19:43:10 +07:00
$this -> zip = new \PclZip ( $filepath );
2015-10-15 22:52:37 +10:00
$this -> zip -> create ( $backupFolder , PCLZIP_OPT_REMOVE_PATH , $backupFolder );
if ( $addConfig ) {
global $wpdb ;
2020-05-08 09:46:07 +00:00
2020-05-13 01:18:02 +07:00
if ( defined ( 'MAINWP_CHILD_DEBUG' ) && MAINWP_CHILD_DEBUG ) {
2020-05-08 16:44:48 +07:00
$string = wp_json_encode (
2020-05-09 00:55:01 +07:00
array (
'siteurl' => get_option ( 'siteurl' ),
'home' => get_option ( 'home' ),
'abspath' => ABSPATH ,
'prefix' => $wpdb -> prefix ,
'lang' => WPLANG ,
)
);
2020-05-08 16:44:48 +07:00
} else {
2020-06-10 17:19:45 +02:00
$string = base64_encode ( // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- Safe requst, required for backwards compatibility.
serialize ( // phpcs:ignore -- Safe requst, required for backwards compatibility.
2020-05-08 16:44:48 +07:00
array (
'siteurl' => get_option ( 'siteurl' ),
'home' => get_option ( 'home' ),
'abspath' => ABSPATH ,
'prefix' => $wpdb -> prefix ,
'lang' => WPLANG ,
)
2020-04-15 19:23:05 +02:00
)
2020-05-08 16:44:48 +07:00
);
}
2020-05-08 09:46:07 +00:00
2020-05-06 20:22:11 +07:00
$this -> add_file_from_string_to_pcl_zip ( 'clone/config.txt' , $string , $filepath );
2015-10-15 22:52:37 +10:00
}
2020-04-15 19:23:05 +02:00
// Remove backup folder.
2015-10-15 22:52:37 +10:00
MainWP_Helper :: delete_dir ( $backupFolder );
return true ;
}
2020-05-27 04:03:48 +00:00
/**
* Recursively add directory to default PHP zip library .
*
2020-06-10 17:19:45 +02:00
* @ param string $path Path to directory .
* @ param array $excludes Files or directories to exclude .
*
* @ uses MainWP_Helper :: in_excludes () Check if the value is in the excludes list .
2020-05-27 04:03:48 +00:00
*/
2020-05-06 20:22:11 +07:00
public function zip_add_dir ( $path , $excludes ) {
$this -> zip -> add_empty_dir ( str_replace ( ABSPATH , '' , $path ) );
2015-10-15 22:52:37 +10:00
if ( file_exists ( rtrim ( $path , '/' ) . '/.htaccess' ) ) {
2020-05-06 20:22:11 +07:00
$this -> add_file_to_zipp ( rtrim ( $path , '/' ) . '/.htaccess' , rtrim ( str_replace ( ABSPATH , '' , $path ), '/' ) . '/mainwp-htaccess' );
2015-10-15 22:52:37 +10:00
}
2020-06-18 00:20:00 +07:00
$iterator = new \RecursiveIteratorIterator ( new \RecursiveDirectoryIterator ( $path ), \RecursiveIteratorIterator :: SELF_FIRST );
2015-10-15 22:52:37 +10:00
foreach ( $iterator as $path ) {
$name = $path -> __toString ();
if ( ( '.' === basename ( $name ) ) || ( '..' === basename ( $name ) ) ) {
continue ;
}
2020-05-06 00:47:59 +07:00
if ( ! MainWP_Helper :: in_excludes ( $excludes , str_replace ( ABSPATH , '' , $name ) ) ) {
2015-10-15 22:52:37 +10:00
if ( $path -> isDir () ) {
2020-05-06 20:22:11 +07:00
$this -> zip_add_dir ( $name , $excludes );
2015-10-15 22:52:37 +10:00
} else {
2020-05-06 20:22:11 +07:00
$this -> add_file_to_zipp ( $name , str_replace ( ABSPATH , '' , $name ) );
2015-10-15 22:52:37 +10:00
}
}
$name = null ;
unset ( $name );
}
$iterator = null ;
unset ( $iterator );
}
2020-05-27 04:03:48 +00:00
/**
* Add file from a string to zip file .
*
2020-06-10 17:19:45 +02:00
* @ param resource $file File to add to zip .
* @ param string $string String to add .
*
2020-05-27 04:03:48 +00:00
* @ return bool true | false .
*/
public function add_file_from_string_to_zip ( $file , $string ) {
2015-10-15 22:52:37 +10:00
return $this -> zip -> addFromString ( $file , $string );
}
2020-05-27 04:03:48 +00:00
/**
* Add file from a string to pclzip file .
*
2020-06-10 17:19:45 +02:00
* @ param resource $file File to add to zip .
* @ param string $string String to add .
* @ param string $filepath Path to file .
2020-05-27 04:03:48 +00:00
*
* @ return bool true | false .
*/
public function add_file_from_string_to_pcl_zip ( $file , $string , $filepath ) {
2015-10-15 22:52:37 +10:00
$file = preg_replace ( '/(?:\.|\/)*(.*)/' , '$1' , $file );
$localpath = dirname ( $file );
$tmpfilename = dirname ( $filepath ) . '/' . basename ( $file );
if ( false !== file_put_contents ( $tmpfilename , $string ) ) {
$this -> zip -> delete ( PCLZIP_OPT_BY_NAME , $file );
2020-04-15 19:23:05 +02:00
$add = $this -> zip -> add (
$tmpfilename ,
PCLZIP_OPT_REMOVE_PATH ,
dirname ( $filepath ),
PCLZIP_OPT_ADD_PATH ,
$localpath
2020-03-19 14:09:54 +01:00
);
2015-10-15 22:52:37 +10:00
unlink ( $tmpfilename );
if ( ! empty ( $add ) ) {
return true ;
}
}
return false ;
}
2020-05-27 04:03:48 +00:00
/**
* Add file to zip .
*
2020-06-10 17:19:45 +02:00
* @ param string $path Path to zip file .
* @ param string $zipEntryName File to add to zip .
*
2020-05-27 04:03:48 +00:00
* @ return bool True | false .
*/
public function add_file_to_zipp ( $path , $zipEntryName ) {
2015-10-15 22:52:37 +10:00
if ( time () - $this -> lastRun > 20 ) {
2020-06-10 17:19:45 +02:00
set_time_limit ( $this -> timeout ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
2015-10-15 22:52:37 +10:00
$this -> lastRun = time ();
}
2020-05-06 00:47:59 +07:00
if ( $this -> excludeZip && MainWP_Helper :: ends_with ( $path , '.zip' ) ) {
2015-10-15 22:52:37 +10:00
return false ;
}
$this -> zipArchiveSizeCount += filesize ( $path );
$this -> gcCnt ++ ;
if ( ! $this -> loadFilesBeforeZip || ( filesize ( $path ) > 5 * 1024 * 1024 ) ) {
$this -> zipArchiveFileCount ++ ;
2020-05-06 20:22:11 +07:00
$added = $this -> zip -> add_file ( $path , $zipEntryName );
2015-10-15 22:52:37 +10:00
} else {
$this -> zipArchiveFileCount ++ ;
$this -> testContent = file_get_contents ( $path );
2020-04-23 16:42:30 +02:00
if ( false === $this -> testContent ) {
2015-10-15 22:52:37 +10:00
return false ;
}
$added = $this -> zip -> addFromString ( $zipEntryName , $this -> testContent );
}
if ( $this -> gcCnt > 20 ) {
if ( function_exists ( 'gc_enable' ) ) {
2020-04-23 19:53:22 +02:00
gc_enable ();
2015-10-15 22:52:37 +10:00
}
if ( function_exists ( 'gc_collect_cycles' ) ) {
2020-04-23 19:53:22 +02:00
gc_collect_cycles ();
2015-10-15 22:52:37 +10:00
}
$this -> gcCnt = 0 ;
}
2020-04-15 19:23:05 +02:00
if ( ( ( $this -> file_descriptors > 0 ) && ( $this -> zipArchiveFileCount > $this -> file_descriptors ) ) ) {
2015-10-15 22:52:37 +10:00
$this -> zip -> close ();
$this -> zip = null ;
unset ( $this -> zip );
if ( function_exists ( 'gc_enable' ) ) {
2020-04-23 19:53:22 +02:00
gc_enable ();
2015-10-15 22:52:37 +10:00
}
if ( function_exists ( 'gc_collect_cycles' ) ) {
2020-04-23 19:53:22 +02:00
gc_collect_cycles ();
2015-10-15 22:52:37 +10:00
}
2020-05-14 19:43:10 +07:00
$this -> zip = new \ZipArchive ();
2015-10-15 22:52:37 +10:00
$this -> zip -> open ( $this -> zipArchiveFileName );
$this -> zipArchiveFileCount = 0 ;
$this -> zipArchiveSizeCount = 0 ;
}
return $added ;
}
2020-05-27 04:03:48 +00:00
/**
* Create full backup via console .
*
2020-06-10 17:19:45 +02:00
* @ param string $filepath Path to file .
* @ param array $excludes Files & directories to exclude .
* @ param bool $addConfig Add config file to backup .
2020-05-27 04:03:48 +00:00
* @ param bool $includeCoreFiles Whether to include core files .
2020-06-10 17:19:45 +02:00
* @ param bool $excludezip Whether to exclude zip archives .
* @ param bool $excludenonwp Whether or not to exclude any wp core files .
*
* @ return bool Return false .
2020-05-27 04:03:48 +00:00
*/
public function create_zip_console_full_backup (
$filepath ,
$excludes ,
$addConfig ,
$includeCoreFiles ,
$excludezip ,
$excludenonwp ) {
2020-05-27 00:02:53 -04:00
2015-10-15 22:52:37 +10:00
return false ;
}
2020-05-27 04:03:48 +00:00
/**
* Create DB backup .
*
2020-06-10 17:19:45 +02:00
* @ param string $filepath_prefix File path prefix .
* @ param string $archiveExt Archive extension .
* @ param object $archiver Archiver .
*
* @ uses MainWP_Helper :: sanitize_filename () Sanitize filename .
* @ uses MainWP_Helper :: set_limit () Set PHP memory limit .
* @ uses MainWP_Child_DB :: to_query () Run a mysqli query & get a result .
*
* @ uses wpdb :: get_results () Retrieve an entire SQL result set from the database ( i . e . , many rows ) .
* @ see https :// developer . wordpress . org / reference / classes / wpdb / get_results /
*
* @ uses wpdb :: get_row () Retrieve one row from the database .
* @ see https :// developer . wordpress . org / reference / classes / wpdb / get_row /
*
* @ return array Action response .
2020-05-27 04:03:48 +00:00
*/
public function create_backup_db ( $filepath_prefix , $archiveExt = false , & $archiver = null ) {
2020-05-14 18:09:17 +00:00
2020-03-19 14:09:54 +01:00
$timeout = 20 * 60 * 60 ;
2020-05-14 18:09:17 +00:00
$mem = '512M' ;
2020-05-15 01:04:08 +07:00
MainWP_Helper :: set_limit ( $timeout , $mem );
2020-05-14 18:09:17 +00:00
2015-10-15 22:52:37 +10:00
global $wpdb ;
2020-04-15 17:23:12 +00:00
$db_files = array ();
2020-06-10 17:19:45 +02:00
$tables_db = $wpdb -> get_results ( 'SHOW TABLES FROM `' . DB_NAME . '`' , ARRAY_N ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
2015-10-15 22:52:37 +10:00
foreach ( $tables_db as $curr_table ) {
if ( null !== $archiver ) {
2020-05-06 20:22:11 +07:00
$archiver -> update_pid_file ();
2015-10-15 22:52:37 +10:00
}
$table = $curr_table [ 0 ];
2015-12-22 19:18:07 +01:00
$currentfile = $filepath_prefix . '-' . MainWP_Helper :: sanitize_filename ( $table ) . '.sql' ;
2020-03-26 19:45:07 +00:00
$db_files [] = $currentfile ;
2015-12-22 19:18:07 +01:00
if ( file_exists ( $currentfile ) ) {
continue ;
}
2020-04-15 19:23:05 +02:00
$fh = fopen ( $currentfile . '.tmp' , 'w' );
2015-12-22 19:18:07 +01:00
2015-10-15 22:52:37 +10:00
fwrite ( $fh , " \n \n " . 'DROP TABLE IF EXISTS ' . $table . ';' );
2020-06-10 17:19:45 +02:00
$table_create = $wpdb -> get_row ( 'SHOW CREATE TABLE ' . $table , ARRAY_N ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
2015-10-15 22:52:37 +10:00
fwrite ( $fh , " \n " . $table_create [ 1 ] . " ; \n \n " );
2020-06-10 17:19:45 +02:00
$rows = MainWP_Child_DB :: to_query ( 'SELECT * FROM ' . $table , $wpdb -> dbh ); // phpcs:ignore -- required to achieve desired results. Pull requests appreciated.
2015-10-15 22:52:37 +10:00
if ( $rows ) {
$i = 0 ;
$table_insert = 'INSERT INTO `' . $table . '` VALUES (' ;
// @codingStandardsIgnoreStart
2020-05-30 01:19:55 +07:00
while ( $row = MainWP_Child_DB :: fetch_array ( $rows ) ) {
2015-10-15 22:52:37 +10:00
// @codingStandardsIgnoreEnd
$query = $table_insert ;
foreach ( $row as $value ) {
2020-04-23 16:42:30 +02:00
if ( null === $value ) {
2018-04-17 20:33:10 +02:00
$query .= 'NULL, ' ;
} else {
$query .= '"' . MainWP_Child_DB :: real_escape_string ( $value ) . '", ' ;
}
2015-10-15 22:52:37 +10:00
}
$query = trim ( $query , ', ' ) . ');' ;
2020-06-10 17:22:15 +02:00
fwrite ( $fh , " \n " . $query ); // phpcs:ignore -- required to achieve desired results, pull request solutions appreciated.
2015-10-15 22:52:37 +10:00
$i ++ ;
if ( $i >= 50 ) {
fflush ( $fh );
$i = 0 ;
}
$query = null ;
$row = null ;
}
}
$rows = null ;
fflush ( $fh );
2020-06-10 17:22:15 +02:00
fclose ( $fh ); // phpcs:ignore -- required to achieve desired results, pull request solutions appreciated.
2015-12-22 19:18:07 +01:00
rename ( $currentfile . '.tmp' , $currentfile );
2015-10-15 22:52:37 +10:00
}
2020-06-10 17:22:15 +02:00
fclose ( fopen ( $filepath_prefix . '.sql' , 'w' ) ); // phpcs:ignore -- required to achieve desired results, pull request solutions appreciated.
2015-12-22 19:18:07 +01:00
$db_files [] = $filepath_prefix . '.sql' ;
2015-10-15 22:52:37 +10:00
2015-12-22 19:18:07 +01:00
$archivefilePath = null ;
2015-10-15 22:52:37 +10:00
if ( false !== $archiveExt ) {
2015-12-22 19:18:07 +01:00
$archivefilePath = $filepath_prefix . '.sql.' . $archiveExt ;
2015-10-15 22:52:37 +10:00
if ( 'zip' === $archiveExt ) {
$this -> archiver = null ;
} else {
$this -> archiver = new Tar_Archiver ( $this , $archiveExt );
}
2020-05-06 20:22:11 +07:00
if ( $this -> zip_file ( $db_files , $archivefilePath ) && file_exists ( $archivefilePath ) ) {
2015-12-22 19:18:07 +01:00
foreach ( $db_files as $db_file ) {
2020-04-23 19:53:22 +02:00
unlink ( $db_file );
2015-10-15 22:52:37 +10:00
}
2020-05-05 13:19:34 +00:00
}
2015-10-15 22:52:37 +10:00
}
2015-12-22 19:18:07 +01:00
return ( false !== $archiveExt ? array ( 'filepath' => $archivefilePath ) : $db_files );
2015-10-15 22:52:37 +10:00
}
}