utiObj = new Utility; $this->utiObj->initFileSystem(); global $wp_filesystem; $this->fiObj = new ActifendFileIntegrity( $wp_filesystem->abspath() ); } /** * Zip extension check */ public function zip_check() { if (extension_loaded('zip')) { return True; } return False; } /** * 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') exit(0); // Send the status to Actifend BE if ($statusOpt == 'complete') { $backupStatus = 'done'; } else { $backupStatus = '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 ($inc_from_time === null) { $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_error' ); // 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_error' ); 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_error' ); 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_error' ); } else { $start_byte = $end_byte + 1; $ie = $i; } } if ($ie != $iters) { debug_log("File upload incomplete! :("); $this->actifend_update_backup_status( 'upload_error' ); } 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) { $response = wp_remote_head($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_del_tmp', $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 = $wpfs->wp_content_dir(); $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 ) { $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_error' => 'Error while uploading backup file ' . BACKUP_FILE ); 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; } } ?>