utiObj = new Utility;
$this->utiObj->initFileSystem();
global $wp_filesystem;
$this->fiObj = new ActifendFileIntegrity( $wp_filesystem->abspath() );
}
/**
* Zip extension check
*/
public function zip_check() {
return extension_loaded( 'zip' );
}
/**
* actifend_backup_process
* After completion of upload to Actifend-cloud status is to be sent
* Actifend BE
*/
public function actifend_backup_process() {
// get asset id
$result = $this->utiObj->getActifendInfo();
if ( isset( $result->asset_id ) && !empty( $result->asset_id ) ) {
$assetid = $result->asset_id;
} else {
debug_log( 'No ASSET ID assigned .... ' );
return 'NO_ASSETID';
}
// Execute Backup process
$this->actifend_wordpress_backup( $assetid );
$statusOpt = get_option( 'ActifendBackupStatus' );
// check if no requests are pending exit without doing anything
if ( strtoupper( $statusOpt ) == 'NONE' ) return;
// Send the status to Actifend BE
$backupStatus = ( $statusOpt == 'complete' ) ? 'done' : 'failed';
$actifend_array = array('status' => $backupStatus,
'zip_enabled' => $this->zip_check(),
'reason' => $this->addlMsg,
'reqid' => $this->req_id);
$actifend_params = json_encode( $actifend_array );
// send status done status by curl usind the PATCH method when backup send to azure successfully.
$actifend_url = ACTIFEND_BACKUP_END_POINT . $assetid . '/wpbackup';
$this->utiObj->actifend_postViaCurl( $actifend_url, $actifend_params, 'PATCH' );
debug_log( 'Status update sent to Actifend BE.' );
}
/**
* actifend_wordpress_backup
*
* This function create the receive the backup request after that create
* the zip of all your wordpress files and database as per the request full
* backup and the at send those files to the azure stroage in
* chunks of 3MB and then send the done status after completion of all steps.
*
* @return null
*/
public function actifend_wordpress_backup( $asset_id ) {
try {
debug_log( 'Check for backup requests initiated ...' );
// check if any backup requests are waiting at BE
$response = $this->utiObj->getViaCurl(ACTIFEND_BACKUP_END_POINT, $asset_id, 'wpbackup');
if ( isset( $response ) && !empty( $response ) && !is_wp_error( $response ) ) {
if ( $response['ResponseCode'] == '2000' && $response['Message'] == 'success' ) {
// It create the backup of the files of the wordpress
$assetid = $response['Result']['asset_id'];
$account_name = $response['Result']['stor_name'];
$share_name = $response['Result']['share_name'];
$sas_token = $response['Result']['sas_token'];
$this->req_id = $response['Result']['_id'];
$backup_type = $response['Result']['backup_type'];
$this->max_uploads_size = intval( $response['Result']['max_uploads_size'] );
// suspend the crons until backup & restore is completed
$this->utiObj->reset_actifend_crons( 'remove' );
// option setting
$this->actifend_update_backup_status( 'initiated' );
$file = BACKUP_FILE; // defined in actifendConstants
$max_range = 3 * 1024 * 1024;
if ( strcmp( $backup_type, 'full' ) === 0 ) {
// create the backup zip file
$this->actifend_wp_backup();
} else {
$backup_type = 'content';
@$inc_from_time = $response['Result']['full_backup_timestamp'];
debug_log( "Latest Full Backup Time: $inc_from_time" );
if ( is_null( $inc_from_time ) ) {
$inc_from_time = '2017-03-01 00:00:00';
debug_log( "Revised Full Backup Time: $inc_from_time" );
}
$filesChanged = $this->afend_get_incremental_changes( $inc_from_time );
// TODO - backup the files identified
$this->afend_do_backup( $filesChanged );
// create the backup zip file
$this->actifend_db_backup();
}
global $wp_filesystem;
$content_path = $wp_filesystem->wp_content_dir();
$backup_path = trailingslashit( $content_path ) . basename( BACKUP_DIR );
// remove the directory used to keep the backup content directory.
$this->utiObj->actifend_rrmdir( $backup_path );
// List the files and the directory ----------------------------------
// check if the folder with assetid as name exists
$uri = 'https://' . $account_name . '.file.core.windows.net/' . $share_name . "/" . $assetid . "?" . $sas_token . "&restype=directory";
$today = gmdate( 'D, d M Y G:i:s T' );
$az_headers = array( 'x-ms-date' => $today, 'x-ms-version' => '2015-04-05' );
$resp_status = $this->actifend_storage_asset_check( $uri, $az_headers );
if ($resp_status === 404) {
debug_log( "$assetid Folder does not exist!" );
// create the folder!
$uri = 'http://' . $account_name . '.file.core.windows.net/' . $share_name . "/" . $assetid . "?" . $sas_token . "&restype=directory";
$az_headers = array_merge( $az_headers, array( 'Content-Length' => '0' ) );
$response = wp_remote_request($uri, array('headers' => $az_headers,
'method' => 'PUT'));
if ( $response['response']['code'] == 201 ) {
debug_log( "$assetid Folder created on Actifend-cloud!" );
}
// Now create a sub folder
$subfolder = date( 'Y-m-d_G_i_s' );
$uri = 'http://' . $account_name . '.file.core.windows.net/' . $share_name . '/' . $assetid . '/' . $subfolder . '?' . $sas_token . '&restype=directory';
$addl_headers = array('x-ms-meta-bkp_type' => $backup_type,
'x-ms-meta-category' => 'backup');
$args = array_merge($az_headers, $addl_headers);
$response = wp_remote_request($uri, array('headers' => $args, 'method' => 'PUT'));
if ($response['response']['code'] === 201) {
debug_log("Subfolder $subfolder with metadata created. Now move on and place the file there ...
");
}
} elseif ( $resp_status === 200 ) {
debug_log("Folder $assetid exists! move on and look for the subfolder...
");
// Build the subfolder name
// create the subfolder as it would not be existing!!
$subfolder = date( 'Y-m-d_G_i_s' );
$uri = 'http://' . $account_name . '.file.core.windows.net/' . $share_name . "/" . $assetid . "/" . $subfolder . "?" . $sas_token . "&restype=directory";
$addl_headers = array('x-ms-meta-bkp_type' => $backup_type,
'x-ms-meta-category' => 'backup',
'Content-Length' => '0');
$args = array_merge( $az_headers, $addl_headers );
$response = wp_remote_request( $uri, array( 'headers' => $args, 'method' => 'PUT' ) );
if ( $response['response']['code'] === 201 ) {
debug_log( "Subfolder $subfolder with metadata created. Now move on and place the file there ...
" );
} else {
debug_log( 'Unable to create the Subfolder in Actifend-cloud.' );
$this->actifend_update_backup_status( 'upload_error1' );
// exit("Unable to create the folder, exiting!");
return;
}
} else {
$error_msg = 'Storage Lookup Error: ' . $response['response']['message'];
debug_log( $error_msg );
$this->actifend_update_backup_status( 'upload_error2', $response['response']['message'] );
return;
}
// Call Azure API to save the file in the storage.
$fsize = filesize( trailingslashit( $content_path ) . BACKUP_FILE );
$uri = 'https://' . $account_name . '.file.core.windows.net/' . $share_name . '/' . $assetid . '/' . $subfolder . '/' . $file . '?' . $sas_token;
$today = gmdate( 'D, d M Y G:i:s T' );
$addl_headers = array('Content-Length' => '0',
'x-ms-type' => 'file',
'x-ms-content-length' => (string) $fsize);
$heads = array_merge( $az_headers, $addl_headers );
$response = wp_remote_request($uri, array('headers' => $heads,
'method' => 'PUT'));
if ( is_wp_error( $response ) || $response['response']['code'] == 400 ) {
debug_log( 'Starting file upload to Actifend-cloud failed!' );
$this->actifend_update_backup_status( 'upload_error3' );
return;
}
$handle = fopen( trailingslashit( $content_path ) . BACKUP_FILE, 'rb' );
$uri_range = $uri . '&comp=range';
// For an update operation, the range can be up to 4 MB in size.
// file needs to be uploaded in chunks of $max_range (defined above)
if ( $fsize > $max_range ) {
$mod = $fsize / $max_range;
$iters = round( $mod, 0 );
if ( $iters < $mod ) {
$iters += 1;
}
} else {
$iters = 1;
}
$start_byte = 0;
$ie = 0;
for ( $i = 1; $i <= $iters; $i++ ) {
// set the start and end byte values for the range
$end_byte = $start_byte + $max_range - 1;
if ( $i == $iters ) {
$end_byte = $fsize - 1;
}
// Read the contents in the file
$contentLength = $end_byte - $start_byte + 1;
$contents = fread( $handle, $contentLength );
// initiate the api call
$addl_headers = array('x-ms-write' => 'update',
'x-ms-range' => "bytes=" . $start_byte . "-" . $end_byte,
'Content-Length' => (string) $contentLength);
$heads = array_merge($az_headers, $addl_headers);
$response = wp_remote_request($uri_range,
array('headers' => $heads,
'body' => $contents,
'method' => 'PUT'));
if ( is_wp_error($response) || $response['response']['code'] !== 201 ) {
$this->actifend_update_backup_status( 'upload_error4' );
} else {
$start_byte = $end_byte + 1;
$ie = $i;
}
}
if ( $ie != $iters ) {
debug_log( 'File upload incomplete! :(' );
$this->actifend_update_backup_status( 'upload_error5' );
} else {
debug_log( 'File upload to Azure storage completed!
' );
// delete backup zip file
$wp_filesystem->delete( trailingslashit( $content_path ) . BACKUP_FILE );
// update status of the process
$this->actifend_update_backup_status( 'complete' );
// reinitate the cron for backup & restore
$this->utiObj->reset_actifend_crons( 'add' );
}
} else {
$this->actifend_update_backup_status( 'none' );
return;
}
} elseif( is_wp_error( $response ) ) {
debug_log( $response->get_error_message() );
$this->actifend_update_backup_status( 'error' );
return;
}
} catch ( Exception $e ) {
debug_log( $e->getMessage() );
$this->actifend_update_backup_status( 'error' );
return;
}
}
/**
* actifend_storage_asset_check
* @az_uri actifend storage url
* @az_headers request header information
* @return response status code
* @access private
*/
public function actifend_storage_asset_check( $az_uri, $az_headers ) {
$response = wp_remote_head( $az_uri, array( 'headers' => $az_headers ) );
$resp_status = $response['response']['code'];
// v1.4.4.3 Retry if the check fails first time
if ( $resp_status != 404 || $resp_status != 200 ) {
debug_log( "Received $resp_status .... retrying ... ");
// v1.5.3 changed head to get on retry
$response = wp_remote_get( $az_uri, array( 'headers' => $az_headers ) );
$resp_status = $response['response']['code'];
}
return $resp_status;
}
/**
* actifend_db_backup
* Takes database backup and creates a zip file
*/
public function actifend_db_backup() {
try {
global $wp_filesystem;
$content_path = $wp_filesystem->wp_content_dir();
$backup_path = trailingslashit( $content_path ) . 'wp_backup';
// database access credentials.
$dbcreds = array(
'db_host' => DB_HOST, //mysql host
'db_uname' => DB_USER, //user
'db_password' => DB_PASSWORD, //pass
'db_to_backup' => DB_NAME, //database name
'db_backup_path' => trailingslashit( BACKUP_DIR ) . trailingslashit( 'wp-db' ), //where to backup
'db_exclude_tables' => array() //tables to exclude
);
// use function to backup the sql.
$res = $this->__backup_mysql_database( $dbcreds );
if ( $res ) {
debug_log( 'Database dump completed successfully.' );
} else {
$this->actifend_update_backup_status( 'db_error' );
return false;
}
// // copy the wp-content/uploads in wp_backup directory
// $destination = trailingslashit( BACKUP_DIR ) . "wp-content/uploads";
// $this->copy_directory(UPLOADS_DIR, $destination);
// send files with pcl zip compression using PclZip
$zipDone = $this->utiObj->pclZipData(trailingslashit( $backup_path ),
trailingslashit( $content_path ) . BACKUP_FILE);
if ($zipDone != 0) {
debug_log( 'Pcl zip compression is used!' );
$this->actifend_update_backup_status( 'zip_complete' );
return true;
} else {
debug_log( 'Pcl zip compression failed.' );
// chek if zip extension is enabled
if ( $this->zip_check() ) {
$this->utiObj->zipData(trailingslashit( $backup_path ),
trailingslashit( $content_path ) . BACKUP_FILE);
if ( $wp_filesystem->exists( trailingslashit( $content_path ) . BACKUP_FILE ) ) {
$wp_filesystem->chmod( trailingslashit( $content_path ) . BACKUP_FILE, 0777 );
}
debug_log( 'DB backup Zipping complete!' );
$this->actifend_update_backup_status( 'zip_complete' );
return true;
} else {
$this->actifend_update_backup_status( 'zip_error' );
return false;
}
}
} catch ( Exception $e ) {
$this->actifend_update_backup_status( 'error' );
return false;
}
}
/**
* actifend_uploads_backup
* Takes uploads folder backup to the stating location
*/
public function actifend_uploads_backup() {
global $wp_filesystem;
$abspath = $wp_filesystem->abspath();
$content_path = $wp_filesystem->wp_content_dir();
$uploads_dir = trailingslashit( $content_path ) . 'uploads';
if ( is_link( $uploads_dir ) ) $uploads_dir = readlink( $uploads_dir );
$backup_path = trailingslashit( $content_path ) . 'wp_backup';
// Add uploads folder upto a limit`specified
$uploads_size = $this->utiObj->get_size_of_folder( $uploads_dir );
if ( $uploads_size < $this->max_uploads_size
|| $this->max_uploads_size !== 0 ) {
// create necessary folders in the staging location
if ( defined( 'UPLOADS' ) ) {
$uploads = UPLOADS;
} else {
$abslen = strlen( $abspath );
$uploads = substr( $uploads_dir, $abslen );
}
$uploads_dest = trailingslashit( $backup_path ) . untrailingslashit( $uploads );
// Recursive directory creation based on full path
wp_mkdir_p( $uploads_dest );
$is_added = copy_dir( $uploads_dir, $uploads_dest );
if ( $is_added ) {
debug_log( $uploads . " folder added to backup... " );
} else {
debug_log( $uploads . " folder could NOT be aded to backup..." );
}
}
}
/**
* Actifend Wp Backup
*
* This function copy the all wordpress files and create a .aql file of wordpress database and add those to wp_backup directory.Create a zip file in the wp-content
* with wp_backup.zip file.
*
* @return null
* @access private
*/
private function actifend_wp_backup() {
try {
global $wp_filesystem;
$content_path = $wp_filesystem->wp_content_dir();
$abspath = $wp_filesystem->abspath();
$admin_path = trailingslashit( $abspath ) . 'wp-admin';
$includes_path = trailingslashit( $abspath ) . 'wp-includes';
$plugins_dir = $wp_filesystem->wp_plugins_dir();
$themes_dir = $wp_filesystem->wp_themes_dir();
$backup_path = trailingslashit( $content_path ) . 'wp_backup';
$uploads_dir = trailingslashit( $content_path ) . 'uploads';
$locations = array( $content_path => trailingslashit( $backup_path ) . 'wp-content',
$admin_path => trailingslashit( $backup_path ) . 'wp-admin',
$includes_path => trailingslashit( $backup_path ) . 'wp-includes',
$abspath => $backup_path );
// if plugins and themes are in a custom location (other then default wp-content)
if (! is_link( trailingslashit( $content_path ) . 'plugins' )
&& dirname( $plugins_dir ) !== $content_path
&& ! in_array( dirname( $plugins_dir ), array_keys( $locations ) ) ) {
debug_log( 'Backing up plugins from custom location ...' );
$locations[$plugins_dir] = trailingslashit( $backup_path )
. trailingslashit( 'wp-content' )
. 'plugins';
}
if (! is_link( trailingslashit( $content_path ) . 'themes' )
&& dirname( $themes_dir ) !== $content_path
&& ! in_array( dirname( $themes_dir ), array_keys( $locations ) ) ) {
debug_log( 'Backing up themes from custom location ...' );
$locations[ $themes_dir ] = trailingslashit( $backup_path )
. trailingslashit( 'wp-content' )
. 'themes';
}
// Add uploads folder upto a limit`specified
$uploads_size = $this->utiObj->get_size_of_folder( $uploads_dir );
if ( $uploads_size > $this->max_uploads_size
&& $this->max_uploads_size !== 0 ) {
array_push( $this->wpcontent2skip, 'uploads' );
debug_log( 'Skipping uploads folder backup ... ' );
}
foreach ( $locations as $source => $destination ) {
if ( strcmp( $source, $abspath ) === 0 ) {
// recursive should be false
$this->copy_directory( $source, $destination, false );
debug_log( "$source FILES are added to backup." );
} else {
// $this->copy_directory($source, $destination);
$this->actifend_cpdir( $source, $destination );
}
// debug_log("$source folder added to backup.");
}
// database access credentials.
$para = array(
'db_host' => DB_HOST, //mysql host
'db_uname' => DB_USER, //user
'db_password' => DB_PASSWORD, //pass
'db_to_backup' => DB_NAME, //database name
'db_backup_path' => trailingslashit( $backup_path ) . trailingslashit('wp-db'), //where to backup
'db_exclude_tables' => array() //tables to exclude
);
// use function to backup the sql.
$res = $this->__backup_mysql_database( $para );
if ( $res ) {
debug_log( 'Database dump completed successfully.' );
} else {
debug_log( 'ERROR: Database dump failed.' );
}
// send files with pcl zip compression using PclZip
$zipDone = $this->utiObj->pclZipData(trailingslashit( $backup_path ),
trailingslashit( $content_path ) . BACKUP_FILE);
if ( $zipDone != 0 ) {
debug_log( 'PclZip compression DONE!' );
return true;
}else {
debug_log( 'pcl zip compression failed.' );
if ( $this->zip_check() ) {
debug_log( 'Checking with ZIP extension ... ' );
$this->utiObj->zipData(trailingslashit( $backup_path ),
trailingslashit( $content_path ) . BACKUP_FILE);
global $wp_filesystem;
if ($wp_filesystem->exists( trailingslashit( $content_path ) . BACKUP_FILE )) {
$wp_filesystem->chmod( trailingslashit( $content_path ) . BACKUP_FILE, 0777 );
}
// if (file_exists(trailingslashit( WP_CONTENT_DIR ) . BACKUP_FILE)) {
// chmod(trailingslashit( WP_CONTENT_DIR ) . BACKUP_FILE, 0777);
// }
debug_log( 'Site backup Zipping complete!' );
return true;
} else {
$this->actifend_update_backup_status( 'zip_error' );
return false;
}
}
} catch ( Exception $e ) {
$this->actifend_update_backup_status( 'error' );
return False;
}
}
/**
* copy directory
*
* Copy directory function is used to copy the full content of one directory to another directory.
* Skips folders that are mentioned in the class array variable wpcontent2skip
* Skips files with extension .log and file defined as BACKUP_FILE constant that are
* inside the source folder
*
* @param string $source Source directory path.
* @param string $destination Destination path where the content of source directory copied.
*/
private function copy_directory( $source, $destination, $recursive=true ) {
try {
global $wp_filesystem;
$content_path = $wp_filesystem->wp_content_dir();
$backup_path = trailingslashit( $content_path ) . 'wp_backup';
$wp_filesystem->mkdir( $backup_path );
if ( $source != $backup_path ) {
$directory = opendir( $source );
$wp_filesystem->mkdir( $destination );
while ( false !== ( $file = readdir( $directory ) ) ) {
if ( $file != '.' && $file != '..' ) {
if ( is_dir( trailingslashit( $source ) . $file ) && $recursive === true ) {
if ( ! in_array( $file, $this->wpcontent2skip ) ) {
$this->copy_directory(trailingslashit( $source ) . $file,
trailingslashit( $destination ) . $file);
}
} else {
@$ext = pathinfo($file, PATHINFO_EXTENSION);
if ($ext != 'log'
&& $file != BACKUP_FILE
&& !is_dir( trailingslashit( $source ) . $file )) {
$wp_filesystem->copy(trailingslashit( $source ) . $file,
trailingslashit( $destination ) . $file);
}
}
}
}
closedir( $directory );
return True;
}
} catch ( Exception $e ) {
debug_log( $e->getMessage() );
$this->actifend_update_backup_status( 'error' );
return False;
}
}
private function actifend_cpdir( $source, $destination ) {
try {
global $wp_filesystem;
$content_dir = $wp_filesystem->wp_content_dir();
$backup_path = trailingslashit( $content_dir ) . 'wp_backup';
$wp_filesystem->mkdir( $backup_path );
$skip_lst = $this->wpcontent2skip;
array_push( $skip_lst, '*.log' );
array_push( $skip_lst, BACKUP_FILE );
if ( $source != $backup_path ) {
$wp_filesystem->mkdir( $destination );
$ret = copy_dir( $source, $destination, $skip_lst );
if ( is_wp_error( $ret ) ) {
$error_msg = $ret->get_error_message();
debug_log( $error_msg );
return $error_msg;
}
debug_log( "Backup of $source completed." );
}
return true;
} catch ( Exception $e ) {
debug_log( $e->getMessage() );
$this->actifend_update_backup_status( 'error' );
return false;
}
}
/**
* __backup_mysql_database (using mysqldump method)
* @param sql filename
* @return void
*/
private function __backup_mysql_database( $params ) {
try {
global $wp_filesystem;
$content_path = $wp_filesystem->wp_content_dir();
$backup_path = trailingslashit( $content_path ) . 'wp_backup';
$this->fiObj->createBaseline();
if ( !is_dir( $params['db_backup_path'] ) ) {
mkdir( $params['db_backup_path'], 0777, true );
}
$dir = trailingslashit( $backup_path ) . trailingslashit( 'wp-db' );
$backup_file_name = $dir . 'actifend-db-backup.sql';
$cmd = 'mysqldump';
$host = explode( ':', DB_HOST );
$port = strpos( DB_HOST, ':' ) ? end( $host ) : '';
$host = reset( $host );
// We don't want to create a new DB
$cmd .= ' --no-create-db';
// Allow lock-tables to be overridden
$cmd .= ' --single-transaction';
// Make sure binary data is exported properly
$cmd .= ' --hex-blob';
// Username
$cmd .= ' -u ' . escapeshellarg( DB_USER );
// Don't pass the password if it's blank
if ( DB_PASSWORD )
$cmd .= ' -p' . escapeshellarg( DB_PASSWORD );
// Set the host
$cmd .= ' -h ' . escapeshellarg( $host );
// Set the port if it was set
if ( !empty( $port ) && is_numeric( $port ) )
$cmd .= ' -P ' . $port;
// The file we're saving too
$cmd .= ' -r ' . escapeshellarg( $backup_file_name );
// Exclude tables if any (default is empty array)
$wp_db_exclude_table = array();
if ( !empty( $wp_db_exclude_table ) ) {
foreach ( $wp_db_exclude_table as $wp_db_exclude_table ) {
$cmd .= ' --ignore-table=' . DB_NAME . '.' . $wp_db_exclude_table;
}
}
// The database we're dumping
$cmd .= ' ' . escapeshellarg( DB_NAME );
// Pipe STDERR to STDOUT
$cmd .= ' 2>&1';
// Store any returned data in an error
$stderr = shell_exec( $cmd );
// Skip the new password warning that is output in mysql > 5.6
if ( trim( $stderr ) === 'Warning: Using a password on the command line interface can be insecure.' ) {
$stderr = '';
}
debug_log( 'mysqldump: SQL Dump completed.' );
return $this->verify_mysqldump( $backup_file_name );
} catch ( Exception $e ) {
debug_log( $e->getMessage() );
$this->actifend_update_backup_status( 'error' );
return False;
}
}
public function verify_mysqldump( $SQLfilename ) {
// If we've already passed then no need to check again
if ( !empty( $this->mysqldump_verified ) )
return true;
// If we have an empty file delete it
if ( @filesize( $SQLfilename ) === 0 )
unlink( $SQLfilename );
// If the file still exists then it must be good
if ( file_exists( $SQLfilename ) )
debug_log( 'DB backup verification complete.' );
return $this->mysqldump_verified = true;
return false;
}
/**
* afend_get_incremental_changes
*
* Gets files from uploads folder incrementally since last backup
* If no last backup, uploads folder should be considered fully
* @param timestamp from where incremental changes need to apply
* format -> "Y-m-d H:M:S"
* @return array of files
*/
private function afend_get_incremental_changes( $fromTime ) {
global $wp_filesystem;
$abspath = $wp_filesystem->abspath();
$content_path = $wp_filesystem->wp_content_dir();
$fromTime_ms = strtotime( $fromTime );
$selectedFiles = array ();
$fiObj = new ActifendFileIntegrity( $abspath );
$prefix = trailingslashit( basename( $content_path ));
$ignore_dirs = array(
$prefix . 'actifend_tmp',
$prefix . 'wp_backup',
$prefix . 'wflogs',
$prefix . 'afend_quarantine'
);
$files = $fiObj->takeSnapshot( 'mtime', $abspath, $ignore_dirs );
$this->__get_fs_as_json( $files );
foreach ( $files as $file ) {
if ( is_file( $file['file_path'] )
&& $file['file_mtime'] > $fromTime_ms ) {
$selectedFiles[] = $file;
}
}
debug_log( "# of changed files after $fromTime is " . (string) count($selectedFiles) );
return $selectedFiles;
}
/**
* afend_do_backup
*
* does backup of the files specified to the staging folder
* @param files to backup
* @return null
*/
private function afend_do_backup( $files ) {
global $wp_filesystem;
$wpfs = $wp_filesystem;
$abspath = $wpfs->abspath();
$content_path = trailingslashit( $abspath ) . 'wp-content';
$admin_dir = trailingslashit( $abspath ) . 'wp-admin';
$includes_dir = trailingslashit( $abspath ) . 'wp-includes';
$backup_path = trailingslashit( $content_path ) . 'wp_backup';
$wpfs->mkdir( $backup_path );
$count = 0;
$nocount = 0;
$fcount = 0;
foreach ( $files as $file ) {
if ( $wpfs->is_file( $file['file_path' ]) ) {
$fcount++;
$dirName = dirname( $file['file_path'] );
$fName = basename( $file['file_path'] );
if ( strcmp( $dirName, untrailingslashit( $abspath ) ) === 0 ) {
$postCdir = '';
$count++;
} elseif ( strstr( $dirName, $content_path ) ) {
$postCdir = substr( $dirName, strlen( $content_path ) );
$postCdir = trailingslashit( basename( $content_path ) ) . $postCdir;
$count++;
} elseif ( strstr( $dirName, $admin_dir ) ) {
$postCdir = substr( $dirName, strlen( $admin_dir ) );
$postCdir = trailingslashit( basename( $admin_dir ) ) . $postCdir;
$count++;
} elseif ( strstr( $dirName, $includes_dir ) ) {
$postCdir = substr( $dirName, strlen( $includes_dir ) );
$postCdir = trailingslashit( basename( $includes_dir ) ) . $postCdir;
$count++;
} else {
debug_log( "$dirName not available to backup." );
$nocount++;
}
$dest = trailingslashit( $backup_path ) . $postCdir;
// create folder recursively
wp_mkdir_p( $dest );
if (! $wpfs->copy( $file['file_path'],
trailingslashit( $dest ) . $fName ) ) {
debug_log( "Could not copy $fName to $dest" );
}
}
}
debug_log( "$count of $fcount files copied to staging folder." );
debug_log( "$nocount files skipped..." );
}
/**
* actifend_update_backup_status
*
* Updates the status of the backup process
*/
public function actifend_update_backup_status( $status, $message=null ) {
$status_lst = array (
'failed' => 'Backup process failed.',
'initiated' => 'Backup process initiated.',
'complete' => 'Backup to Actifend-cloud successful.',
'error' => 'Unexpected error during backup.',
'db_error' => 'DB error occurred.',
'zip_error' => 'Error during zip compression.',
'zip_complete' => 'Zip compression successfully completed.',
'no_backup' => 'Backup file does not exist.',
'none' => 'No backup request pending.',
'upload_error1' => 'Unable to create the Subfolder in ActiFend-cloud',
'upload_error2' => ( !is_null( $message ) ? $message : 'ActiFend-Cloud storage lookup error' ),
'upload_error3' => 'Starting file upload to ActiFend-cloud failed!',
'upload_error4' => 'Error while uploading backup file ' . BACKUP_FILE,
'upload_error5' => 'File upload incomplete.'
);
if ( in_array( $status, array_keys( $status_lst )) ) {
update_option( 'ActifendBackupStatus', $status );
$this->addlMsg = $status_lst[$status];
debug_log( $this->addlMsg );
}
}
public function __get_fs_as_json( $files ) {
global $wp_filesystem;
$js_file = trailingslashit( $wp_filesystem->wp_content_dir() )
. trailingslashit( 'wp_backup' )
. 'files.json';
if (! $wp_filesystem->exists( dirname( $js_file )))
wp_mkdir_p( dirname( $js_file ));
$wp_filesystem->put_contents( $js_file, json_encode( $files ), false );
// $fsha1 = sha1_file( $file_path );
// return fsha1;
}
}
?>