admin_init(); } function admin_init() { add_action('core_upgrade_preamble', array($this, 'core_upgrade_preamble')); add_action('admin_action_upgrade-plugin', array($this, 'admin_action_upgrade_pluginortheme')); add_action('admin_action_upgrade-theme', array($this, 'admin_action_upgrade_pluginortheme')); add_action('admin_head', array($this,'admin_head')); add_filter((is_multisite() ? 'network_admin_' : '').'plugin_action_links', array($this, 'plugin_action_links'), 10, 2); add_action('wp_ajax_updraft_download_backup', array($this, 'updraft_download_backup')); add_action('wp_ajax_updraft_ajax', array($this, 'updraft_ajax_handler')); add_action('wp_ajax_plupload_action', array($this,'plupload_action')); add_action('wp_ajax_plupload_action2', array($this,'plupload_action2')); global $updraftplus, $wp_version, $pagenow; add_filter('updraftplus_dirlist_others', array($updraftplus, 'backup_others_dirlist')); add_filter('updraftplus_dirlist_uploads', array($updraftplus, 'backup_uploads_dirlist')); // First, the checks that are on all (admin) pages: $service = UpdraftPlus_Options::get_updraft_option('updraft_service'); if (UpdraftPlus_Options::user_can_manage() && ('googledrive' === $service || is_array($service) && in_array('googledrive', $service)) && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid','') != '' && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token','') == '') { add_action('all_admin_notices', array($this,'show_admin_warning_googledrive') ); } if (UpdraftPlus_Options::user_can_manage() && ('dropbox' === $service || is_array($service) && in_array('dropbox', $service)) && UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token','') == '') { add_action('all_admin_notices', array($this,'show_admin_warning_dropbox') ); } if (UpdraftPlus_Options::user_can_manage() && $this->disk_space_check(1024*1024*35) === false) add_action('all_admin_notices', array($this, 'show_admin_warning_diskspace')); // Next, the actions that only come on the UpdraftPlus page if ($pagenow != UpdraftPlus_Options::admin_page() || empty($_REQUEST['page']) || 'updraftplus' != $_REQUEST['page']) return; if (UpdraftPlus_Options::user_can_manage() && defined('DISABLE_WP_CRON') && DISABLE_WP_CRON == true) { add_action('all_admin_notices', array($this, 'show_admin_warning_disabledcron')); } if(UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) { @ini_set('display_errors',1); @error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); add_action('all_admin_notices', array($this, 'show_admin_debug_warning')); } # Avoid false positives, by attempting to raise the limit (as happens when we actually do a backup) @set_time_limit(900); $max_execution_time = (int)@ini_get('max_execution_time'); if ($max_execution_time>0 && $max_execution_time<20) { add_action('all_admin_notices', array($this, 'show_admin_warning_execution_time')); } // LiteSpeed has a generic problem with terminating cron jobs if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false) { if (!is_file(ABSPATH.'.htaccess') || !preg_match('/noabort/i', file_get_contents(ABSPATH.'.htaccess'))) { add_action('all_admin_notices', array($this, 'show_admin_warning_litespeed')); } } if (version_compare($wp_version, '3.2', '<')) add_action('all_admin_notices', array($this, 'show_admin_warning_wordpressversion')); wp_enqueue_script('updraftplus-admin-ui', UPDRAFTPLUS_URL.'/includes/updraft-admin-ui.js', array('jquery', 'jquery-ui-dialog', 'plupload-all'), '31'); wp_localize_script( 'updraftplus-admin-ui', 'updraftlion', array( 'sendonlyonwarnings' => __('Send a report only when there are warnings/errors', 'updraftplus'), 'wholebackup' => __('When the Email storage method is enabled, also send the entire backup', 'updraftplus'), 'emailsizelimits' => esc_attr(sprintf(__('Be aware that mail servers tend to have size limits; typically around %s Mb; backups larger than any limits will likely not arrive.','updraftplus'), '10-20')), 'rescanning' => __('Rescanning (looking for backups that you have uploaded manually into the internal backup store)...','updraftplus'), 'enteremailhere' => esc_attr(__('To send to more than one address, separate each address with a comma.', 'updraftplus')), 'excludedeverything' => __('If you exclude both the database and the files, then you have excluded everything!', 'updraftplus'), 'restoreproceeding' => __('The restore operation has begun. Do not press stop or close your browser until it reports itself as having finished.', 'updraftplus'), 'unexpectedresponse' => __('Unexpected response:','updraftplus'), 'servererrorcode' => __('The web server returned an error code (try again, or check your web server logs)', 'updraftplus'), 'newuserpass' => __("The new user's RackSpace console password is (this will not be shown again):", 'updraftplus'), 'trying' => __('Trying...', 'updraftplus'), 'calculating' => __('calculating...','updraftplus'), 'begunlooking' => __('Begun looking for this entity','updraftplus'), 'stilldownloading' => __('Some files are still downloading or being processed - please wait.', 'updraftplus'), 'processing' => __('Processing files - please wait...', 'updraftplus'), 'emptyresponse' => __('Error: the server sent an empty response.', 'updraftplus'), 'warnings' => __('Warnings:','updraftplus'), 'errors' => __('Errors:','updraftplus'), 'jsonnotunderstood' => __('Error: the server sent us a response (JSON) which we did not understand.', 'updraftplus'), 'error' => __('Error:','updraftplus'), 'fileready' => __('File ready.','updraftplus'), 'youshould' => __('You should:','updraftplus'), 'deletefromserver' => __('Delete from your web server','updraftplus'), 'downloadtocomputer' => __('Download to your computer','updraftplus'), 'andthen' => __('and then, if you wish,', 'updraftplus'), 'notunderstood' => __('Download error: the server sent us a response which we did not understand.', 'updraftplus'), 'requeststart' => __('Requesting start of backup...', 'updraftplus'), 'phpinfo' => __('PHP information', 'updraftplus'), 'delete_old_dirs' => __('Delete Old Directories', 'updraftplus'), 'raw' => __('Raw backup history', 'updraftplus'), 'notarchive' => __('This file does not appear to be an UpdraftPlus backup archive (such files are .zip or .gz files which have a name like: backup_(time)_(site name)_(code)_(type).(zip|gz)). However, UpdraftPlus archives are standard zip/SQL files - so if you are sure that your file has the right format, then you can rename it to match that pattern.','updraftplus'), 'makesure' => __('(make sure that you were trying to upload a zip file previously created by UpdraftPlus)','updraftplus'), 'uploaderror' => __('Upload error:','updraftplus'), 'notdba' => __('This file does not appear to be an UpdraftPlus encrypted database archive (such files are .gz.crypt files which have a name like: backup_(time)_(site name)_(code)_db.crypt.gz).','updraftplus'), 'uploaderr' => __('Upload error', 'updraftplus'), 'followlink' => __('Follow this link to attempt decryption and download the database file to your computer.','updraftplus'), 'thiskey' => __('This decryption key will be attempted:','updraftplus'), 'unknownresp' => __('Unknown server response:','updraftplus'), 'ukrespstatus' => __('Unknown server response status:','updraftplus'), 'uploaded' => __('The file was uploaded.','updraftplus'), 'backupnow' => __('Backup Now', 'updraftplus'), 'cancel' => __('Cancel', 'updraftplus'), 'deletebutton' => __('Delete', 'updraftplus'), 'createbutton' => __('Create', 'updraftplus'), 'close' => __('Close', 'updraftplus'), 'restore' => __('Restore', 'updraftplus'), ) ); } function core_upgrade_preamble() { if (!class_exists('UpdraftPlus_Addon_Autobackup')) { if (defined('UPDRAFTPLUS_NOADS_A')) return; # TODO: Remove legacy/wrong use of transient any time from 1 Jun 2014 if (true == get_transient('updraftplus_dismissedautobackup')) return; $dismissed_until = UpdraftPlus_Options::get_updraft_option('updraftplus_dismissedautobackup', 0); if ($dismissed_until > time()) return; } ?>

automatically take a backup of your plugins or themes and database before you update.', 'updraftplus').' '.__('Be safe every time, without needing to remember - follow this link to learn more.' ,'updraftplus').''); ?>
'html5,silverlight,flash,html4', 'browse_button' => 'plupload-browse-button', 'container' => 'plupload-upload-ui', 'drop_element' => 'drag-drop-area', 'file_data_name' => 'async-upload', 'multiple_queues' => true, 'max_file_size' => '100Gb', 'chunk_size' => $chunk_size.'b', 'url' => admin_url('admin-ajax.php'), 'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'), 'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'), 'filters' => array(array('title' => __('Allowed Files'), 'extensions' => 'zip,gz,crypt,txt')), 'multipart' => true, 'multi_selection' => true, 'urlstream_upload' => true, // additional post data to send to our ajax hook 'multipart_params' => array( '_ajax_nonce' => wp_create_nonce('updraft-uploader'), 'action' => 'plupload_action' ) ); ?> __('Allowed Files'), 'extensions' => 'crypt')); ?> backups_dir_location(); $disk_free_space = @disk_free_space($updraft_dir); if ($disk_free_space == false) return -1; return ($disk_free_space > $space) ? true : false; } # Adds the settings link under the plugin on the plugin screen. function plugin_action_links($links, $file) { if ($file == 'updraftplus/updraftplus.php'){ $settings_link = ''.__("Settings", "updraftplus").''; array_unshift($links, $settings_link); // $settings_link = ''.__("Donate","UpdraftPlus").''; // array_unshift($links, $settings_link); $settings_link = ''.__("Add-Ons / Pro Support","updraftplus").''; array_unshift($links, $settings_link); } return $links; } function admin_action_upgrade_pluginortheme() { if (isset($_GET['action']) && ($_GET['action'] == 'upgrade-plugin' || $_GET['action'] == 'upgrade-theme') && !class_exists('UpdraftPlus_Addon_Autobackup') && !defined('UPDRAFTPLUS_NOADS_A')) { # TODO: Remove legacy/erroneous use of transient any time after 1 Jun 2014 $dismissed = get_transient('updraftplus_dismissedautobackup'); if (true == $dismissed) return; $dismissed_until = UpdraftPlus_Options::get_updraft_option('updraftplus_dismissedautobackup', 0); if ($dismissed_until > time()) return; if ( 'upgrade-plugin' == $_GET['action'] ) { $title = __('Update Plugin'); $parent_file = 'plugins.php'; $submenu_file = 'plugins.php'; } else { $title = __('Update Theme'); $parent_file = 'themes.php'; $submenu_file = 'themes.php'; } require_once(ABSPATH.'wp-admin/admin-header.php'); ?>

automatically take a backup of your plugins or themes and database before you update.', 'updraftplus').' '.__('Be safe every time, without needing to remember - follow this link to learn more.' ,'updraftplus').''; ?>

'."

$message

"; } public function show_admin_warning_execution_time() { $this->show_admin_warning(''.__('Warning','updraftplus').': '.sprintf(__('The amount of time allowed for WordPress plugins to run is very low (%s seconds) - you should increase it to avoid backup failures due to time-outs (consult your web hosting company for more help - it is the max_execution_time PHP setting; the recommended value is %s seconds or more)', 'updraftplus'), (int)@ini_get('max_execution_time'), 90)); } function show_admin_warning_disabledcron() { $this->show_admin_warning(''.__('Warning','updraftplus').': '.__('The scheduler is disabled in your WordPress install, via the DISABLE_WP_CRON setting. No backups can run (even "Backup Now") unless either you have set up a facility to call the scheduler manually, or until it is enabled.','updraftplus').' '.__('Go here for more information.','updraftplus').''); } function show_admin_warning_diskspace() { $this->show_admin_warning(''.__('Warning','updraftplus').': '.sprintf(__('You have less than %s of free disk space on the disk which UpdraftPlus is configured to use to create backups. UpdraftPlus could well run out of space. Contact your the operator of your server (e.g. your web hosting company) to resolve this issue.','updraftplus'),'35 Mb')); } function show_admin_warning_wordpressversion() { $this->show_admin_warning(''.__('Warning','updraftplus').': '.sprintf(__('UpdraftPlus does not officially support versions of WordPress before %s. It may work for you, but if it does not, then please be aware that no support is available until you upgrade WordPress.'),'3.2'),'updraftplus'); } function show_admin_warning_litespeed() { $this->show_admin_warning(''.__('Warning','updraftplus').': '.sprintf(__('Your website is hosted using the %s web server.','updraftplus'),'LiteSpeed').' '.__('Please consult this FAQ if you have problems backing up.', 'updraftplus').''); } function show_admin_debug_warning() { $this->show_admin_warning(''.__('Notice','updraftplus').': '.__('UpdraftPlus\'s debug mode is on. You may see debugging notices on this page not just from UpdraftPlus, but from any other plugin installed. Please try to make sure that the notice you are seeing is from UpdraftPlus before you raise a support request.', 'updraftplus').''); } function show_admin_warning_w3_total_cache() { $url = (is_multisite()) ? network_admin_url('admin.php?page=w3tc_general') : admin_url('admin.php?page=w3tc_general'); $this->show_admin_warning(''.__('Warning','updraftplus').': '.__('W3 Total Cache\'s object cache is active. This is known to have a bug that messes with all scheduled tasks (including backup jobs).','updraftplus').' '.__('Go here to turn it off.','updraftplus').' '.sprintf(__('Go here for more information.', 'updraftplus'),'http://updraftplus.com/faqs/whats-the-deal-with-w3-total-caches-object-cache/')); } function show_admin_warning_dropbox() { $this->show_admin_warning(''.__('UpdraftPlus notice:','updraftplus').' '.sprintf(__('Click here to authenticate your %s account (you will not be able to back up to %s without it).','updraftplus'),'Dropbox','Dropbox').''); } function show_admin_warning_googledrive() { $this->show_admin_warning(''.__('UpdraftPlus notice:','updraftplus').' '.sprintf(__('Click here to authenticate your %s account (you will not be able to back up to %s without it).','updraftplus'),'Google Drive','Google Drive').''); } // This options filter removes ABSPATH off the front of updraft_dir, if it is given absolutely and contained within it function prune_updraft_dir_prefix($updraft_dir) { if ('/' == substr($updraft_dir, 0, 1) || "\\" == substr($updraft_dir, 0, 1) || preg_match('/^[a-zA-Z]:/', $updraft_dir)) { $wcd = trailingslashit(WP_CONTENT_DIR); if (strpos($updraft_dir, $wcd) === 0) { $updraft_dir = substr($updraft_dir, strlen($wcd)); } # Legacy // if (strpos($updraft_dir, ABSPATH) === 0) { // $updraft_dir = substr($updraft_dir, strlen(ABSPATH)); // } } return $updraft_dir; } function updraft_download_backup() { @set_time_limit(900); global $updraftplus; if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'], 'updraftplus_download')) die; if (!isset($_REQUEST['timestamp']) || !is_numeric($_REQUEST['timestamp']) || !isset($_REQUEST['type'])) exit; $findex = (isset($_REQUEST['findex'])) ? $_REQUEST['findex'] : 0; if (empty($findex)) $findex=0; $backupable_entities = $updraftplus->get_backupable_file_entities(true); $type_match = false; foreach ($backupable_entities as $type => $info) { if ($_REQUEST['type'] == $type) $type_match = true; } if (!$type_match && 'db' != $_REQUEST['type']) exit; // Get the information on what is wanted $type = $_REQUEST['type']; $timestamp = $_REQUEST['timestamp']; // You need a nonce before you can set job data. And we certainly don't yet have one. $updraftplus->backup_time_nonce($timestamp); $debug_mode = UpdraftPlus_Options::get_updraft_option('updraft_debug_mode'); // Set the job type before logging, as there can be different logging destinations $updraftplus->jobdata_set('job_type', 'download'); $updraftplus->jobdata_set('job_time_ms', $updraftplus->job_time_ms); // Retrieve the information from our backup history $backup_history = $updraftplus->get_backup_history(); // Base name $file = $backup_history[$timestamp][$type]; // Deal with multi-archive sets if (is_array($file)) $file=$file[$findex]; // Where it should end up being downloaded to $fullpath = $updraftplus->backups_dir_location().'/'.$file; if (isset($_GET['stage']) && '2' == $_GET['stage']) { $updraftplus->spool_file($type, $fullpath); die; } if (isset($_POST['stage']) && 'delete' == $_POST['stage']) { @unlink($fullpath); echo 'deleted'; $updraftplus->log('The file has been deleted'); die; } // TODO: FIXME: Failed downloads may leave log files forever (though they are small) // Note that log() assumes that the data is in _POST, not _GET if ($debug_mode) $updraftplus->logfile_open($updraftplus->nonce); set_error_handler(array($updraftplus, 'php_error'), E_ALL & ~E_STRICT); $updraftplus->log("Requested to obtain file: timestamp=$timestamp, type=$type, index=$findex"); $itext = (empty($findex)) ? '' : $findex; $known_size = isset($backup_history[$timestamp][$type.$itext.'-size']) ? $backup_history[$timestamp][$type.$itext.'-size'] : 0; $services = (isset($backup_history[$timestamp]['service'])) ? $backup_history[$timestamp]['service'] : false; if (is_string($services)) $services = array($services); $updraftplus->jobdata_set('service', $services); // Fetch it from the cloud, if we have not already got it $needs_downloading = false; if(!file_exists($fullpath)) { //if the file doesn't exist and they're using one of the cloud options, fetch it down from the cloud. $needs_downloading = true; $updraftplus->log('File does not yet exist locally - needs downloading'); } elseif ($known_size>0 && filesize($fullpath) < $known_size) { $updraftplus->log("The file was found locally (".filesize($fullpath).") but did not match the size in the backup history ($known_size) - will resume downloading"); $needs_downloading = true; } elseif ($known_size>0) { $updraftplus->log('The file was found locally and matched the recorded size from the backup history ('.round($known_size/1024,1).' Kb)'); } else { $updraftplus->log('No file size was found recorded in the backup history. We will assume the local one is complete.'); $known_size = filesize($fullpath); } // The AJAX responder that updates on progress wants to see this $updraftplus->jobdata_set('dlfile_'.$timestamp.'_'.$type.'_'.$findex, "downloading:$known_size:$fullpath"); if ($needs_downloading) { // Close browser connection so that it can resume AJAX polling header('Content-Length: 0'); header('Connection: close'); header('Content-Encoding: none'); if (session_id()) session_write_close(); echo "\r\n\r\n"; $is_downloaded = false; foreach ($services as $service) { if ($is_downloaded) continue; $download = $this->download_file($file, $service); if (is_readable($fullpath) && $download !== false) { clearstatcache(); $updraftplus->log('Remote fetch was successful (file size: '.round(filesize($fullpath)/1024,1).' Kb)'); $is_downloaded = true; } else { clearstatcache(); if (0 === @filesize($fullpath)) @unlink($fullpath); $updraftplus->log('Remote fetch failed'); } } } // Now, spool the thing to the browser if(is_file($fullpath) && is_readable($fullpath)) { // That message is then picked up by the AJAX listener $updraftplus->jobdata_set('dlfile_'.$timestamp.'_'.$type.'_'.$findex, 'downloaded:'.filesize($fullpath).":$fullpath"); } else { $updraftplus->jobdata_set('dlfile_'.$timestamp.'_'.$type.'_'.$findex, 'failed'); $updraftplus->jobdata_set('dlerrors_'.$timestamp.'_'.$type.'_'.$findex, $updraftplus->errors); $updraftplus->log('Remote fetch failed. File '.$fullpath.' did not exist or was unreadable. If you delete local backups then remote retrieval may have failed.'); } restore_error_handler(); @fclose($updraftplus->logfile_handle); if (!$debug_mode) @unlink($updraftplus->logfile_name); exit; } # Pass only a single service, as a string, into this function function download_file($file, $service) { global $updraftplus; @set_time_limit(900); $updraftplus->log("Requested file from remote service: $service: $file"); $method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php'; if (file_exists($method_include)) require_once($method_include); $objname = "UpdraftPlus_BackupModule_${service}"; if (method_exists($objname, "download")) { $remote_obj = new $objname; return $remote_obj->download($file); } else { $updraftplus->log("Automatic backup restoration is not available with the method: $service."); $updraftplus->log("$file: ".sprintf(__("The backup archive for this file could not be found. The remote storage method in use (%s) does not allow us to retrieve files. To perform any restoration using UpdraftPlus, you will need to obtain a copy of this file and place it inside UpdraftPlus's working folder", 'updraftplus'), $service)." (".$this->prune_updraft_dir_prefix($updraftplus->backups_dir_location()).")", 'error'); return false; } } // Called via AJAX function updraft_ajax_handler() { global $updraftplus; // Test the nonce $nonce = (empty($_REQUEST['nonce'])) ? "" : $_REQUEST['nonce']; if (! wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce') || empty($_REQUEST['subaction'])) die('Security check'); if (isset($_REQUEST['subaction']) && 'lastlog' == $_REQUEST['subaction']) { echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '('.__('Nothing yet logged', 'updraftplus').')')); } elseif (isset($_GET['subaction']) && 'activejobs_list' == $_GET['subaction']) { $download_status = array(); if (!empty($_GET['downloaders'])) { foreach(explode(':', $_GET['downloaders']) as $downloader) { # prefix, timestamp, entity, index if (preg_match('/^([^,]+),(\d+),([a-z]+),(\d+)$/', $downloader, $matches)) { $updraftplus->nonce = $matches[2]; $status = $this->download_status($matches[2], $matches[3], $matches[4]); if (is_array($status)) { $status['base'] = $matches[1]; $status['timestamp'] = $matches[2]; $status['what'] = $matches[3]; $status['findex'] = (empty($matches[4])) ? '0' : $matches[4]; $download_status[] = $status; } } } } if (!empty($_GET['oneshot'])) { $job_id = get_site_option('updraft_oneshotnonce', false); $active_jobs = (false === $job_id) ? '' : $this->print_active_job($job_id, true); } else { $active_jobs = $this->print_active_jobs(); } echo json_encode(array( 'l' => htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '('.__('Nothing yet logged', 'updraftplus').')')), 'j' => $active_jobs, 'ds' => $download_status )); } elseif (isset($_REQUEST['subaction']) && 'dismissautobackup' == $_REQUEST['subaction']) { UpdraftPlus_Options::update_updraft_option('updraftplus_dismissedautobackup', time() + 84*86400); } elseif (isset($_REQUEST['subaction']) && 'dismissexpiry' == $_REQUEST['subaction']) { UpdraftPlus_Options::update_updraft_option('updraftplus_dismissedexpiry', time() + 14*86400); } elseif (isset($_GET['subaction']) && 'restore_alldownloaded' == $_GET['subaction'] && isset($_GET['restoreopts']) && isset($_GET['timestamp'])) { $backups = $updraftplus->get_backup_history(); $updraft_dir = $updraftplus->backups_dir_location(); $timestamp = (int)$_GET['timestamp']; if (!isset($backups[$timestamp])) { echo json_encode(array('m' => '', 'w' => '', 'e' => __('No such backup set exists', 'updraftplus'))); die; } $mess = array(); parse_str($_GET['restoreopts'], $res); if (isset($res['updraft_restore'])) { set_error_handler(array($this, 'get_php_errors'), E_ALL & ~E_STRICT); $elements = array_flip($res['updraft_restore']); $warn = array(); $err = array(); @set_time_limit(900); $max_execution_time = (int)@ini_get('max_execution_time'); if ($max_execution_time>0 && $max_execution_time<61) { $warn[] = __('The PHP setup on this webserver allows only %s seconds for PHP to run, and does not allow this limit to be raised. If you have a lot of data to import, and if the restore operation times out, then you will need to ask your web hosting company for ways to raise this limit (or attempt the restoration piece-by-piece).', 'updraftplus'); } if (isset($elements['db'])) { // Analyse the header of the database file + display results list ($mess2, $warn2, $err2) = $this->analyse_db_file($_GET['timestamp'], $res); $mess = array_merge($mess, $mess2); $warn = array_merge($warn, $warn2); $err = array_merge($err, $err2); } $backupable_entities = $updraftplus->get_backupable_file_entities(true, true); $backupable_plus_db = $backupable_entities; $backupable_plus_db['db'] = array('path' => 'path-unused', 'description' => __('Database', 'updraftplus')); foreach ($backupable_plus_db as $type => $info) { if (!isset($elements[$type])) continue; $whatwegot = $backups[$timestamp][$type]; if (is_string($whatwegot)) $whatwegot = array($whatwegot); $expected_index = 0; $missing = ''; ksort($whatwegot); $outof = false; foreach ($whatwegot as $index => $file) { if (preg_match('/\d+of(\d+)\.zip/', $file, $omatch)) { $outof = max($matches[1], 1); } if ($index != $expected_index) { $missing .= ($missing == '') ? (1+$expected_index) : ",".(1+$expected_index); } if (!file_exists($updraft_dir.'/'.$file)) { $err[] = sprintf(__('File not found (you need to upload it): %s', 'updraftplus'), $updraft_dir.'/'.$file); } elseif (filesize($updraft_dir.'/'.$file) == 0) { $err[] = sprintf(__('File was found, but is zero-sized (you need to re-upload it): %s', 'updraftplus'), $file); } else { $itext = (0 == $index) ? '' : $index; if (!empty($backups[$timestamp][$type.$itext.'-size']) && $backups[$timestamp][$type.$itext.'-size'] != filesize($updraft_dir.'/'.$file)) { if (empty($warn['doublecompressfixed'])) { $warn[] = sprintf(__('File (%s) was found, but has a different size (%s) from what was expected (%s) - it may be corrupt.', 'updraftplus'), $file, filesize($updraft_dir.'/'.$file), $backups[$timestamp][$type.$itext.'-size']); } } do_action_ref_array("updraftplus_checkzip_$type", array($updraft_dir.'/'.$file, &$mess, &$warn, &$err)); } $expected_index++; } do_action_ref_array("updraftplus_checkzip_end_$type", array(&$mess, &$warn, &$err)); # Detect missing archives where they are missing from the end of the set if ($outof>0 && $expected_index < $outof) { for ($j = $expected_index; $j<$outof; $j++) { $missing .= ($missing == '') ? (1+$j) : ",".(1+$j); } } if ('' != $missing) { $warn[] = sprintf(__("This multi-archive backup set appears to have the following archives missing: %s", 'updraftplus'), $missing.' ('.$info['description'].')'); } } if (0 == count($err) && 0 == count($warn)) { $mess_first = __('The backup archive files have been successfully processed. Now press Restore again to proceed.', 'updraftplus'); } elseif (0 == count($err)) { $mess_first = __('The backup archive files have been processed, but with some warnings. If all is well, then now press Restore again to proceed. Otherwise, cancel and correct any problems first.', 'updraftplus'); } else { $mess_first = __('The backup archive files have been processed, but with some errors. You will need to cancel and correct any problems before retrying.', 'updraftplus'); } if (count($this->logged) >0) { foreach ($this->logged as $lwarn) $warn[] = $lwarn; } restore_error_handler(); echo json_encode(array('m' => '

'.$mess_first.'

'.implode('
', $mess), 'w' => implode('
', $warn), 'e' => implode('
', $err))); } } elseif (isset($_POST['backup_timestamp']) && 'deleteset' == $_REQUEST['subaction']) { $backups = $updraftplus->get_backup_history(); $timestamp = $_POST['backup_timestamp']; if (!isset($backups[$timestamp])) { echo json_encode(array('result' => 'error', 'message' => __('Backup set not found', 'updraftplus'))); die; } // You need a nonce before you can set job data. And we certainly don't yet have one. $updraftplus->backup_time_nonce(); // Set the job type before logging, as there can be different logging destinations $updraftplus->jobdata_set('job_type', 'delete'); $updraftplus->jobdata_set('job_time_ms', $updraftplus->job_time_ms); if (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) { $updraftplus->logfile_open($updraftplus->nonce); set_error_handler(array($updraftplus, 'php_error'), E_ALL & ~E_STRICT); } $updraft_dir = $updraftplus->backups_dir_location(); $backupable_entities = $updraftplus->get_backupable_file_entities(true, true); $nonce = isset($backups[$timestamp]['nonce']) ? $backups[$timestamp]['nonce'] : ''; $delete_from_service = array(); if (isset($_POST['delete_remote']) && 1==$_POST['delete_remote']) { // Locate backup set if (isset($backups[$timestamp]['service'])) { $services = is_string($backups[$timestamp]['service']) ? array($backups[$timestamp]['service']) : $backups[$timestamp]['service']; if (is_array($services)) { foreach ($services as $service) { if ($service != 'none') $delete_from_service[] = $service; } } } } $files_to_delete = array(); foreach ($backupable_entities as $key => $ent) { if (isset($backups[$timestamp][$key])) { $files_to_delete[$key] = $backups[$timestamp][$key]; } } // Delete DB if (isset($backups[$timestamp]['db'])) $files_to_delete['db'] = $backups[$timestamp]['db']; // Also delete the log if ($nonce && !UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) { $files_to_delete['log'] = "log.$nonce.txt"; } unset($backups[$timestamp]); UpdraftPlus_Options::update_updraft_option('updraft_backup_history', $backups); $message = ''; $local_deleted = 0; $remote_deleted = 0; foreach ($files_to_delete as $key => $files) { # Local deletion if (is_string($files)) $files=array($files); foreach ($files as $file) { if (is_file($updraft_dir.'/'.$file)) { if (@unlink($updraft_dir.'/'.$file)) $local_deleted++; } } if ('log' != $key && count($delete_from_service) > 0) { foreach ($delete_from_service as $service) { if ('email' == $service) continue; if (file_exists(UPDRAFTPLUS_DIR."/methods/$service.php")) require_once(UPDRAFTPLUS_DIR."/methods/$service.php"); $objname = "UpdraftPlus_BackupModule_".$service; $deleted = -1; if (class_exists($objname)) { # TODO: Re-use the object (i.e. prevent repeated connection setup/teardown) $remote_obj = new $objname; $deleted = $remote_obj->delete($files); } if ($deleted === -1) { //echo __('Did not know how to delete from this cloud service.', 'updraftplus'); } elseif ($deleted !== false) { $remote_deleted = $remote_deleted + count($files); } else { // Do nothing } } } } $message .= __('The backup set has been removed.', 'updraftplus')."\n"; $message .= sprintf(__('Local archives deleted: %d', 'updraftplus'),$local_deleted)."\n"; $message .= sprintf(__('Remote archives deleted: %d', 'updraftplus'),$remote_deleted)."\n"; $updraftplus->log("Local archives deleted: ".$local_deleted); $updraftplus->log("Remote archives deleted: ".$remote_deleted); print json_encode(array('result' => 'success', 'message' => $message)); if (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) { restore_error_handler(); } } elseif ('rawbackuphistory' == $_REQUEST['subaction']) { echo '

'.__('Known backups (raw)', 'updraftplus').'

';
			var_dump($updraftplus->get_backup_history());
			echo '
'; echo '

Files

';
			$updraft_dir = $updraftplus->backups_dir_location();
			$raw_output = array();
			$d = dir($updraft_dir);
			while (false !== ($entry = $d->read())) {
				$fp = $updraft_dir.'/'.$entry;
				$mtime = filemtime($fp);
				if (is_dir($fp)) {
					$size = '       d';
				} elseif (is_link($fp)) {
					$size = '       l';
				} elseif (is_file($fp)) {
					$size = sprintf("%8.1f", round(filesize($fp)/1024, 1)).' '.gmdate('r', $mtime);
				} else {
					$size = '       ?';
				}
				if (preg_match('/^log\.(.*)\.txt$/', $entry, $lmatch)) $entry = ''.$entry.'';
				$raw_output[$mtime] = empty($raw_output[$mtime]) ? sprintf("%s %s\n", $size, $entry) : $raw_output[$mtime].sprintf("%s %s\n", $size, $entry);
			}
			@$d->close();
			krsort($raw_output, SORT_NUMERIC);
			foreach ($raw_output as $line) echo $line;
			echo '
'; echo '

'.__('Options (raw)', 'updraftplus').'

'; $opts = $this->get_settings_keys(); asort($opts); // '.__('Key','updraftplus').''.__('Value','updraftplus').' echo ''; foreach ($opts as $opt) { echo ''; } echo '
'.htmlspecialchars($opt).''.htmlspecialchars(print_r(UpdraftPlus_Options::get_updraft_option($opt), true)).'
'; } elseif ('countbackups' == $_REQUEST['subaction']) { $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history'); $backup_history = (is_array($backup_history))?$backup_history:array(); echo sprintf(__('%d set(s) available', 'updraftplus'), count($backup_history)); } elseif ('ping' == $_REQUEST['subaction']) { // The purpose of this is to detect brokenness caused by extra line feeds in plugins/themes - before it breaks other AJAX operations and leads to support requests echo 'pong'; } elseif ('delete_old_dirs' == $_REQUEST['subaction']) { $this->delete_old_dirs_go(false); } elseif ('phpinfo' == $_REQUEST['subaction']) { phpinfo(INFO_ALL ^ (INFO_CREDITS | INFO_LICENSE)); echo '

'.__('Constants', 'updraftplus').'

'; $opts = @get_defined_constants(); ksort($opts); // '.__('Key','updraftplus').''.__('Value','updraftplus').' echo ''; foreach ($opts as $key => $opt) { echo ''; } echo '
'.htmlspecialchars($key).''.htmlspecialchars(print_r($opt, true)).'
'; } elseif ('doaction' == $_REQUEST['subaction'] && !empty($_REQUEST['subsubaction']) && 'updraft_' == substr($_REQUEST['subsubaction'], 0, 8)) { do_action($_REQUEST['subsubaction']); } elseif ('backupnow' == $_REQUEST['subaction']) { echo '',__('Schedule backup','updraftplus').': '; $backupnow_nocloud = (empty($_REQUEST['backupnow_nocloud'])) ? false : true; $event = (!empty($_REQUEST['backupnow_nofiles'])) ? 'updraft_backupnow_backup_database' : ((!empty($_REQUEST['backupnow_nodb'])) ? 'updraft_backupnow_backup' : 'updraft_backupnow_backup_all'); if (wp_schedule_single_event(time()+5, $event, array($backupnow_nocloud)) === false) { $updraftplus->log("A backup run failed to schedule"); echo __("Failed.",'updraftplus').""; } else { echo htmlspecialchars(__('OK. You should soon see activity in the "Last log message" field below.','updraftplus'))."
".__('Nothing happening? Follow this link for help.','updraftplus')."
"; $updraftplus->log("A backup run has been scheduled"); } } elseif (isset($_GET['subaction']) && 'lastbackup' == $_GET['subaction']) { echo $this->last_backup_html(); } elseif (isset($_GET['subaction']) && 'activejobs_delete' == $_GET['subaction'] && isset($_GET['jobid'])) { $cron = get_option('cron'); $found_it = 0; foreach ($cron as $time => $job) { if (isset($job['updraft_backup_resume'])) { foreach ($job['updraft_backup_resume'] as $hook => $info) { if (isset($info['args'][1]) && $info['args'][1] == $_GET['jobid']) { $args = $cron[$time]['updraft_backup_resume'][$hook]['args']; wp_unschedule_event($time, 'updraft_backup_resume', $args); if (!$found_it) echo json_encode(array('ok' => 'Y', 'm' => __('Job deleted', 'updraftplus'))); $found_it = 1; } } } } if (!$found_it) echo json_encode(array('ok' => 'N', 'm' => __('Could not find that job - perhaps it has already finished?', 'updraftplus'))); } elseif (isset($_GET['subaction']) && 'diskspaceused' == $_GET['subaction'] && isset($_GET['entity'])) { if ('updraft' == $_GET['entity']) { echo $this->recursive_directory_size($updraftplus->backups_dir_location()); } else { $backupable_entities = $updraftplus->get_backupable_file_entities(true, false); if (!empty($backupable_entities[$_GET['entity']])) { # Might be an array $basedir = $backupable_entities[$_GET['entity']]; $dirs = apply_filters('updraftplus_dirlist_'.$_GET['entity'], $basedir); echo $this->recursive_directory_size($dirs, $updraftplus->get_exclude($_GET['entity']), $basedir); } else { _e('Error', 'updraftplus'); } } } elseif (isset($_GET['subaction']) && 'historystatus' == $_GET['subaction']) { $rescan = (isset($_GET['rescan']) && $_GET['rescan'] == 1); if ($rescan) $this->rebuild_backup_history(); $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history'); $backup_history = (is_array($backup_history))?$backup_history:array(); echo json_encode(array('n' => sprintf(__('%d set(s) available', 'updraftplus'), count($backup_history)), 't' => $this->existing_backup_table($backup_history))); } elseif (isset($_GET['subaction']) && 'downloadstatus' == $_GET['subaction'] && isset($_GET['timestamp']) && isset($_GET['type'])) { $findex = (isset($_GET['findex'])) ? $_GET['findex'] : '0'; if (empty($findex)) $findex = '0'; $updraftplus->nonce = $_GET['timestamp']; echo json_encode($this->download_status($_GET['timestamp'], $_GET['type'], $findex)); } elseif (isset($_POST['subaction']) && $_POST['subaction'] == 'credentials_test') { $method = (preg_match("/^[a-z0-9]+$/", $_POST['method'])) ? $_POST['method'] : ""; // Test the credentials, return a code require_once(UPDRAFTPLUS_DIR."/methods/$method.php"); $objname = "UpdraftPlus_BackupModule_${method}"; $this->logged = array(); set_error_handler(array($this, 'get_php_errors'), E_ALL & ~E_STRICT); if (method_exists($objname, "credentials_test")) { $obj = new $objname; $obj->credentials_test(); } if (count($this->logged) >0) { echo "\n\n".__('Messages:', 'updraftplus')."\n"; foreach ($this->logged as $err) { echo "* $err\n"; } } restore_error_handler(); } die; } public function get_php_errors($errno, $errstr, $errfile, $errline) { global $updraftplus; if (0 == error_reporting()) return true; $logline = $updraftplus->php_error_to_logline($errno, $errstr, $errfile, $errline); $this->logged[] = $logline; # Don't pass it up the chain (since it's going to be output to the user always) return true; } function download_status($timestamp, $type, $findex) { global $updraftplus; $response = array( 'm' => $updraftplus->jobdata_get('dlmessage_'.$timestamp.'_'.$type.'_'.$findex).'
' ); if ($file = $updraftplus->jobdata_get('dlfile_'.$timestamp.'_'.$type.'_'.$findex)) { if ('failed' == $file) { $response['e'] = __('Download failed','updraftplus').'
'; $errs = $updraftplus->jobdata_get('dlerrors_'.$timestamp.'_'.$type.'_'.$findex); if (is_array($errs) && !empty($errs)) { $response['e'] .= ''; } } elseif (preg_match('/^downloaded:(\d+):(.*)$/', $file, $matches) && file_exists($matches[2])) { $response['p'] = 100; $response['f'] = $matches[2]; $response['s'] = (int)$matches[1]; $response['t'] = (int)$matches[1]; $response['m'] = __('File ready.', 'updraftplus'); } elseif (preg_match('/^downloading:(\d+):(.*)$/', $file, $matches) && file_exists($matches[2])) { // Convert to bytes $response['f'] = $matches[2]; $total_size = (int)max($matches[1], 1); $cur_size = filesize($matches[2]); $response['s'] = $cur_size; $response['t'] = $total_size; $response['m'] .= __("Download in progress", 'updraftplus').' ('.round($cur_size/1024).' / '.round(($total_size/1024)).' Kb)'; $response['p'] = round(100*$cur_size/$total_size); } else { $response['m'] .= __('No local copy present.', 'updraftplus'); $response['p'] = 0; $response['s'] = 0; $response['t'] = 1; } } return $response; } function analyse_db_file($timestamp, $res) { $mess = array(); $warn = array(); $err = array(); global $updraftplus, $wp_version; include(ABSPATH.'wp-includes/version.php'); # This attempts to raise the maximum packet size. This can't be done within the session, only globally. Therefore, it has to be done before the session starts; in our case, during the pre-analysis. $updraftplus->get_max_packet_size(); $backup = $updraftplus->get_backup_history($timestamp); if (!isset($backup['nonce']) || !isset($backup['db'])) return array($mess, $warn, $err); $updraft_dir = $updraftplus->backups_dir_location(); $db_file = (is_string($backup['db'])) ? $updraft_dir.'/'.$backup['db'] : $updraft_dir.'/'.$backup['db'][0]; if (!is_readable($db_file)) return array($mess, $warn, $err); // Encrypted - decrypt it if ($updraftplus->is_db_encrypted($db_file)) { $encryption = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase'); if (!$encryption) { $err[] = sprintf(__('Error: %s', 'updraftplus'), __('Decryption failed. The database file is encrypted, but you have no encryption key entered.', 'updraftplus')); return array($mess, $warn, $err); } $ciphertext = $updraftplus->decrypt($db_file, $encryption); if ($ciphertext) { $new_db_file = $updraft_dir.'/'.basename($db_file, '.crypt'); if (!file_put_contents($new_db_file, $ciphertext)) { $err[] = __('Failed to write out the decrypted database to the filesystem.','updraftplus'); return array($mess, $warn, $err); } $db_file = $new_db_file; } else { $err[] = __('Decryption failed. The most likely cause is that you used the wrong key.','updraftplus'); return array($mess, $warn, $err); } } # Even the empty schema when gzipped comes to 1565 bytes; a blank WP 3.6 install at 5158. But we go low, in case someone wants to share single tables. if (filesize($db_file) < 1000) { $err[] = sprintf(__('The database is too small to be a valid WordPress database (size: %s Kb).','updraftplus'), round(filesize($db_file)/1024, 1)); return array($mess, $warn, $err); } $dbhandle = $this->gzopen_for_read($db_file, $warn, $err); if (!is_resource($dbhandle)) { $err[] = __('Failed to open database file.','updraftplus'); return array($mess, $warn, $err); } # Analyse the file, print the results. $line = 0; $old_siteurl = ''; $old_home = ''; $old_table_prefix = ''; $old_siteinfo = array(); $gathering_siteinfo = true; $old_wp_version = ''; $tables_found = array(); // TODO: If the backup is the right size/checksum, then we could restore the $line <= 100 in the 'while' condition and not bother scanning the whole thing? Or better: sort the core tables to be first so that this usually terminates early $wanted_tables = array('terms', 'term_taxonomy', 'term_relationships', 'commentmeta', 'comments', 'links', 'options', 'postmeta', 'posts', 'users', 'usermeta'); $migration_warning = false; # Don't set too high - we want a timely response returned to the browser @set_time_limit(90); while (!gzeof($dbhandle) && ($line<100 || count($wanted_tables)>0)) { $line++; // Up to 1Mb $buffer = rtrim(gzgets($dbhandle, 1048576)); // Comments are what we are interested in if (substr($buffer, 0, 1) == '#') { if ('' == $old_siteurl && preg_match('/^\# Backup of: (http(.*))$/', $buffer, $matches)) { $old_siteurl = untrailingslashit($matches[1]); $mess[] = __('Backup of:', 'updraftplus').' '.htmlspecialchars($old_siteurl).((!empty($old_wp_version)) ? ' '.sprintf(__('(version: %s)', 'updraftplus'), $old_wp_version) : ''); // Check for should-be migration if (!$migration_warning && $old_siteurl != untrailingslashit(site_url())) { $migration_warning = true; $powarn = apply_filters('updraftplus_dbscan_urlchange', sprintf(__('Warning: %s', 'updraftplus'), ''.__('This backup set is from a different site - this is not a restoration, but a migration. You need the Migrator add-on in order to make this work.', 'updraftplus').''), $old_siteurl, $res); if (!empty($powarn)) $warn[] = $powarn; } } elseif ('' == $old_home && preg_match('/^\# Home URL: (http(.*))$/', $buffer, $matches)) { $old_home = untrailingslashit($matches[1]); // Check for should-be migration if (!$migration_warning && $old_home != home_url()) { $migration_warning = true; $powarn = apply_filters('updraftplus_dbscan_urlchange', sprintf(__('Warning: %s', 'updraftplus'), ''.__('This backup set is from a different site - this is not a restoration, but a migration. You need the Migrator add-on in order to make this work.', 'updraftplus').''), $old_home, $res); if (!empty($powarn)) $warn[] = $powarn; } } elseif ('' == $old_wp_version && preg_match('/^\# WordPress Version: ([0-9]+(\.[0-9]+)+)/', $buffer, $matches)) { $old_wp_version = $matches[1]; if (version_compare($old_wp_version, $wp_version, '>')) { //$mess[] = sprintf(__('%s version: %s', 'updraftplus'), 'WordPress', $old_wp_version); $warn[] = sprintf(__('You are importing from a newer version of WordPress (%s) into an older one (%s). There are no guarantees that WordPress can handle this.', 'updraftplus'), $old_wp_version, $wp_version); } } elseif ('' == $old_table_prefix && preg_match('/^\# Table prefix: (\S+)$/', $buffer, $matches)) { $old_table_prefix = $matches[1]; // echo ''.__('Old table prefix:', 'updraftplus').' '.htmlspecialchars($old_table_prefix).'
'; } elseif ($gathering_siteinfo && preg_match('/^\# Site info: (\S+)$/', $buffer, $matches)) { if ('end' == $matches[1]) { $gathering_siteinfo = false; // Sanity checks if (isset($old_siteinfo['multisite']) && !$old_siteinfo['multisite'] && is_multisite()) { // Just need to check that you're crazy if (!defined('UPDRAFTPLUS_EXPERIMENTAL_IMPORTINTOMULTISITE') || UPDRAFTPLUS_EXPERIMENTAL_IMPORTINTOMULTISITE != true) { $err[] = sprintf(__('Error: %s', 'updraftplus'), __('You are running on WordPress multisite - but your backup is not of a multisite site.', 'updraftplus')); return array($mess, $warn, $err); } // Got the needed code? if (!class_exists('UpdraftPlusAddOn_MultiSite') || !class_exists('UpdraftPlus_Addons_Migrator')) { $err[] = sprintf(__('Error: %s', 'updraftplus'), __('To import an ordinary WordPress site into a multisite installation requires both the multisite and migrator add-ons.', 'updraftplus')); return array($mess, $warn, $err); } } } elseif (preg_match('/^([^=]+)=(.*)$/', $matches[1], $kvmatches)) { $key = $kvmatches[1]; $val = $kvmatches[2]; if ('multisite' == $key && $val) { $mess[] = ''.__('Site information:','updraftplus').''.' is a WordPress Network'; } $old_siteinfo[$key]=$val; } } } elseif (preg_match('/^\s*create table \`?([^\`\(]*)\`?\s*\(/i', $buffer, $matches)) { $table = $matches[1]; $tables_found[] = $table; if ($old_table_prefix) { // Remove prefix $table = $updraftplus->str_replace_once($old_table_prefix, '', $table); if (in_array($table, $wanted_tables)) { $wanted_tables = array_diff($wanted_tables, array($table)); } } } } @gzclose($dbhandle); /* $blog_tables = "CREATE TABLE $wpdb->terms ( CREATE TABLE $wpdb->term_taxonomy ( CREATE TABLE $wpdb->term_relationships ( CREATE TABLE $wpdb->commentmeta ( CREATE TABLE $wpdb->comments ( CREATE TABLE $wpdb->links ( CREATE TABLE $wpdb->options ( CREATE TABLE $wpdb->postmeta ( CREATE TABLE $wpdb->posts ( $users_single_table = "CREATE TABLE $wpdb->users ( $users_multi_table = "CREATE TABLE $wpdb->users ( $usermeta_table = "CREATE TABLE $wpdb->usermeta ( $ms_global_tables = "CREATE TABLE $wpdb->blogs ( CREATE TABLE $wpdb->blog_versions ( CREATE TABLE $wpdb->registration_log ( CREATE TABLE $wpdb->site ( CREATE TABLE $wpdb->sitemeta ( CREATE TABLE $wpdb->signups ( */ $missing_tables = array(); if ($old_table_prefix) { foreach ($wanted_tables as $table) { if (!in_array($old_table_prefix.$table, $tables_found)) { $missing_tables[] = $table; } } if (count($missing_tables)>0) { $warn[] = sprintf(__('This database backup is missing core WordPress tables: %s', 'updraftplus'), implode(', ', $missing_tables)); } } else { $warn[] = __('UpdraftPlus was unable to find the table prefix when scanning the database backup.', 'updraftplus'); } return array($mess, $warn, $err); } private function gzopen_for_read($file, &$warn, &$err) { if (false === ($dbhandle = gzopen($file, 'r'))) return false; if (false === ($bytes = gzread($dbhandle, 3))) return false; # Double-gzipped? if ('H4sI' != base64_encode($bytes)) { if (0 === gzseek($dbhandle, 0)) { return $dbhandle; } else { @gzclose($dbhandle); return gzopen($file, 'r'); } } # Yes, it's double-gzipped $what_to_return = false; $mess = __('The database file appears to have been compressed twice - probably the website you downloaded it from had a mis-configured webserver.', 'updraftplus'); $messkey = 'doublecompress'; $err_msg = ''; if (false === ($fnew = fopen($file.".tmp", 'w')) || !is_resource($fnew)) { @gzclose($dbhandle); $err_msg = __('The attempt to undo the double-compression failed.', 'updraftplus'); } else { @fwrite($fnew, $bytes); $emptimes = 0; while (!gzeof($dbhandle)) { $bytes = @gzread($dbhandle, 131072); if (empty($bytes)) { global $updraftplus; $emptimes++; $updraftplus->log("Got empty gzread ($emptimes times)"); if ($emptimes>2) break; } else { @fwrite($fnew, $bytes); } } gzclose($dbhandle); fclose($fnew); # On some systems (all Windows?) you can't rename a gz file whilst it's gzopened if (!rename($file.".tmp", $file)) { $err_msg = __('The attempt to undo the double-compression failed.', 'updraftplus'); } else { $mess .= ' '.__('The attempt to undo the double-compression succeeded.', 'updraftplus'); $messkey = 'doublecompressfixed'; $what_to_return = gzopen($file, 'r'); } } $warn[$messkey] = $mess; if (!empty($err_msg)) $err[] = $err_msg; return $what_to_return; } public function upload_dir($uploads) { global $updraftplus; $updraft_dir = $updraftplus->backups_dir_location(); if (is_writable($updraft_dir)) $uploads['path'] = $updraft_dir; return $uploads; } // We do actually want to over-write public function unique_filename_callback($dir, $name, $ext) { return $name.$ext; } public function sanitize_file_name($filename) { // WordPress 3.4.2 on multisite (at least) adds in an unwanted underscore return preg_replace('/-db\.gz_\.crypt$/', '-db.gz.crypt', $filename); } public function plupload_action() { // check ajax nonce global $updraftplus; @set_time_limit(900); check_ajax_referer('updraft-uploader'); $updraft_dir = $updraftplus->backups_dir_location(); if (!is_writable($updraft_dir)) exit; add_filter('upload_dir', array($this, 'upload_dir')); add_filter('sanitize_file_name', array($this, 'sanitize_file_name')); // handle file upload $farray = array( 'test_form' => true, 'action' => 'plupload_action' ); $farray['test_type'] = false; $farray['ext'] = 'x-gzip'; $farray['type'] = 'application/octet-stream'; if (isset($_POST['chunks'])) { } else { $farray['unique_filename_callback'] = array($this, 'unique_filename_callback'); } $status = wp_handle_upload( $_FILES['async-upload'], $farray ); remove_filter('upload_dir', array($this, 'upload_dir')); remove_filter('sanitize_file_name', array($this, 'sanitize_file_name')); if (isset($status['error'])) { echo 'ERROR:'.$status['error']; exit; } // If this was the chunk, then we should instead be concatenating onto the final file if (isset($_POST['chunks']) && isset($_POST['chunk']) && preg_match('/^[0-9]+$/',$_POST['chunk'])) { $final_file = $_POST['name']; rename($status['file'], $updraft_dir.'/'.$final_file.'.'.$_POST['chunk'].'.zip.tmp'); $status['file'] = $updraft_dir.'/'.$final_file.'.'.$_POST['chunk'].'.zip.tmp'; // Final chunk? If so, then stich it all back together if ($_POST['chunk'] == $_POST['chunks']-1) { if ($wh = fopen($updraft_dir.'/'.$final_file, 'wb')) { for ($i=0 ; $i<$_POST['chunks']; $i++) { $rf = $updraft_dir.'/'.$final_file.'.'.$i.'.zip.tmp'; if ($rh = fopen($rf, 'rb')) { while ($line = fread($rh, 32768)) fwrite($wh, $line); fclose($rh); @unlink($rf); } } fclose($wh); $status['file'] = $updraft_dir.'/'.$final_file; } } } if (!isset($_POST['chunks']) || (isset($_POST['chunk']) && $_POST['chunk'] == $_POST['chunks']-1)) { $file = basename($status['file']); if (!preg_match('/^log\.[a-f0-9]{12}\.txt/', $file) && !preg_match('/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-([\-a-z]+)([0-9]+(of[0-9]+)?)?\.(zip|gz|gz\.crypt)$/i', $file, $matches)) { @unlink($status['file']); echo sprintf(__('Error: %s', 'updraftplus'),__('Bad filename format - this does not look like a file created by UpdraftPlus','updraftplus')); exit; } else { $backupable_entities = $updraftplus->get_backupable_file_entities(true); $type = $matches[3]; if ('db' != $type && !isset($backupable_entities[$type]) && !preg_match('/^log\.[a-f0-9]{12}\.txt/', $file)) { @unlink($status['file']); echo sprintf(__('Error: %s', 'updraftplus'),sprintf(__('This looks like a file created by UpdraftPlus, but this install does not know about this type of object: %s. Perhaps you need to install an add-on?','updraftplus'), htmlspecialchars($type))); exit; } } } // send the uploaded file url in response echo 'OK:'.$status['url']; exit; } public function plupload_action2() { @set_time_limit(900); global $updraftplus; // check ajax nonce check_ajax_referer('updraft-uploader'); $updraft_dir = $updraftplus->backups_dir_location(); if (!is_writable($updraft_dir)) exit; add_filter('upload_dir', array($this, 'upload_dir')); add_filter('sanitize_file_name', array($this, 'sanitize_file_name')); // handle file upload $farray = array( 'test_form' => true, 'action' => 'plupload_action2' ); $farray['test_type'] = false; $farray['ext'] = 'crypt'; $farray['type'] = 'application/octet-stream'; if (isset($_POST['chunks'])) { // $farray['ext'] = 'zip'; // $farray['type'] = 'application/zip'; } else { $farray['unique_filename_callback'] = array($this, 'unique_filename_callback'); } $status = wp_handle_upload( $_FILES['async-upload'], $farray ); remove_filter('upload_dir', array($this, 'upload_dir')); remove_filter('sanitize_file_name', array($this, 'sanitize_file_name')); if (isset($status['error'])) { echo 'ERROR:'.$status['error']; exit; } // If this was the chunk, then we should instead be concatenating onto the final file if (isset($_POST['chunks']) && isset($_POST['chunk']) && preg_match('/^[0-9]+$/',$_POST['chunk'])) { $final_file = $_POST['name']; rename($status['file'], $updraft_dir.'/'.$final_file.'.'.$_POST['chunk'].'.zip.tmp'); $status['file'] = $updraft_dir.'/'.$final_file.'.'.$_POST['chunk'].'.zip.tmp'; // Final chunk? If so, then stich it all back together if ($_POST['chunk'] == $_POST['chunks']-1) { if ($wh = fopen($updraft_dir.'/'.$final_file, 'wb')) { for ($i=0 ; $i<$_POST['chunks']; $i++) { $rf = $updraft_dir.'/'.$final_file.'.'.$i.'.zip.tmp'; if ($rh = fopen($rf, 'rb')) { while ($line = fread($rh, 32768)) fwrite($wh, $line); fclose($rh); @unlink($rf); } } fclose($wh); $status['file'] = $updraft_dir.'/'.$final_file; } } } if (!isset($_POST['chunks']) || (isset($_POST['chunk']) && $_POST['chunk'] == $_POST['chunks']-1)) { $file = basename($status['file']); if (!preg_match('/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-[\-a-z]+\.(gz\.crypt)$/i', $file)) { @unlink($status['file']); echo 'ERROR:'.__('Bad filename format - this does not look like an encrypted database file created by UpdraftPlus','updraftplus'); exit; } } // send the uploaded file url in response // echo 'OK:'.$status['url']; echo 'OK:'.$file; exit; } public function settings_output() { global $updraftplus; wp_enqueue_style('jquery-ui', UPDRAFTPLUS_URL.'/includes/jquery-ui-1.8.22.custom.css'); /* we use request here because the initial restore is triggered by a POSTed form. we then may need to obtain credentials for the WP_Filesystem. to do this WP outputs a form, but we don't pass our parameters via that. So the values are passed back in as GET parameters. REQUEST covers both GET and POST so this logic works. */ if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'updraft_restore' && isset($_REQUEST['backup_timestamp'])) { $backup_success = $this->restore_backup($_REQUEST['backup_timestamp']); if(empty($updraftplus->errors) && $backup_success === true) { // If we restored the database, then that will have out-of-date information which may confuse the user - so automatically re-scan for them. $this->rebuild_backup_history(); echo '

'; $updraftplus->log_e('Restore successful!'); echo '

'; $updraftplus->log("Restore successful"); echo ''.__('Actions','updraftplus').': '.__('Return to UpdraftPlus Configuration','updraftplus').''; return; } elseif (is_wp_error($backup_success)) { echo '

'; $updraftplus->log_e('Restore failed...'); echo '

'; $updraftplus->log_wp_error($backup_success); $updraftplus->log("Restore failed"); $updraftplus->list_errors(); echo ''.__('Actions','updraftplus').': '.__('Return to UpdraftPlus Configuration','updraftplus').''; return; } elseif (false === $backup_success) { # This means, "not yet - but stay on the page because we may be able to do it later, e.g. if the user types in the requested information" return; } } if(isset($_REQUEST['action']) && 'updraft_delete_old_dirs' == $_REQUEST['action']) { $nonce = (empty($_REQUEST['_wpnonce'])) ? "" : $_REQUEST['_wpnonce']; if (!wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce')) die('Security check'); $this->delete_old_dirs_go(); return; } if(isset($_GET['error'])) $this->show_admin_warning(htmlspecialchars($_GET['error']), 'error'); if(isset($_GET['message'])) $this->show_admin_warning(htmlspecialchars($_GET['message'])); if(isset($_GET['action']) && $_GET['action'] == 'updraft_create_backup_dir' && isset($_GET['nonce']) && wp_verify_nonce($_GET['nonce'], 'create_backup_dir')) { $created = $this->create_backup_dir(); if(is_wp_error($created)) { echo '

'.__('Backup directory could not be created','updraftplus').'...
'; echo '

'; } elseif ($created !== false) { echo '

'.__('Backup directory successfully created.','updraftplus').'


'; } echo ''.__('Actions','updraftplus').': '.__('Return to UpdraftPlus Configuration','updraftplus').''; return; } do_action('updraftplus_settings_page_init'); echo ''; // updraft_file_ids is not deleted if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_all') { $updraftplus->boot_backup(true,true); } elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_db') { $updraftplus->boot_backup(false, true, false, true); // global $updraftplus_backup; // if (!is_a($updraftplus_backup, 'UpdraftPlus_Backup')) require_once(UPDRAFTPLUS_DIR.'/backup.php'); // $updraftplus_backup->backup_db(); } elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_wipesettings') { $settings = $this->get_settings_keys(); foreach ($settings as $s) UpdraftPlus_Options::delete_updraft_option($s); # These aren't in get_settings_keys() because they are always in the options table, regardless of context global $wpdb; $wpdb->query("DELETE FROM $wpdb->options WHERE ( option_name LIKE 'updraftplus_unlocked_%' OR option_name LIKE 'updraftplus_locked_%' OR option_name LIKE 'updraftplus_last_lock_time_%' OR option_name LIKE 'updraftplus_semaphore_%')"); $site_options = array('updraft_oneshotnonce'); foreach ($site_options as $s) delete_site_option($s); $this->show_admin_warning(__("Your settings have been wiped.",'updraftplus')); } ?>

plugin_title; ?>

( UpdraftPlus.Com | | | | | WordShell - WordPress command line | | FAQs | ) : version; ?>

".__('Your backup has been restored.','updraftplus').' '.__('If your restore included files, then your old (themes, uploads, plugins, whatever) directories have been retained with "-old" appended to their name. Remove them when you are satisfied that the backup worked properly.')."
"; } $ws_advert = $updraftplus->wordshell_random_advert(1); if ($ws_advert) { echo '
'.$ws_advert.'
'; } if(!$updraftplus->memory_check(64)) {?>
memory_check_current(); ?> Mb
scan_old_dirs()) $this->print_delete_old_dirs_form(); if(!empty($updraftplus->errors)) { echo '
'; $updraftplus->list_errors(); echo '
'; } ?>

backups_dir_location(); // UNIX timestamp $next_scheduled_backup = wp_next_scheduled('updraft_backup'); if ($next_scheduled_backup) { // Convert to GMT $next_scheduled_backup_gmt = gmdate('Y-m-d H:i:s', $next_scheduled_backup); // Convert to blog time zone $next_scheduled_backup = get_date_from_gmt($next_scheduled_backup_gmt, 'D, F j, Y H:i'); } else { $next_scheduled_backup = __('Nothing currently scheduled','updraftplus'); } $next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database'); if (UpdraftPlus_Options::get_updraft_option('updraft_interval_database',UpdraftPlus_Options::get_updraft_option('updraft_interval')) == UpdraftPlus_Options::get_updraft_option('updraft_interval')) { $next_scheduled_backup_database = ('Nothing currently scheduled' == $next_scheduled_backup) ? $next_scheduled_backup : __("At the same time as the files backup", 'updraftplus'); } else { if ($next_scheduled_backup_database) { // Convert to GMT $next_scheduled_backup_database_gmt = gmdate('Y-m-d H:i:s', $next_scheduled_backup_database); // Convert to blog time zone $next_scheduled_backup_database = get_date_from_gmt($next_scheduled_backup_database_gmt, 'D, F j, Y H:i'); } else { $next_scheduled_backup_database = __('Nothing currently scheduled','updraftplus'); } } $current_time = get_date_from_gmt(gmdate('Y-m-d H:i:s'), 'D, F j, Y H:i'); $backup_disabled = ($updraftplus->really_is_writable($updraft_dir)) ? '' : 'disabled="disabled"'; $last_backup_html = $this->last_backup_html(); ?>
:
:
:
:
:
px;">
rebuild_backup_history(); $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history'); } $backup_history = (is_array($backup_history))?$backup_history:array(); ?>

print_active_jobs();?>
:
:
Blah blah blah. Move to right-hand col?
 


:

:

detect_safe_mode()) { echo "

".__('Your web server has PHP\'s so-called safe_mode active.','updraftplus').' '.__('This makes time-outs much more likely. You are recommended to turn safe_mode off, or to restore only one entity at a time, or to restore manually.', 'updraftplus')."


"; } $backupable_entities = $updraftplus->get_backupable_file_entities(true, true); foreach ($backupable_entities as $type => $info) { if (!isset($info['restorable']) || $info['restorable'] == true) { echo '

'; do_action("updraftplus_restore_form_$type"); echo '
'; } else { $sdescrip = isset($info['shortdescription']) ? $info['shortdescription'] : $info['description']; echo "
".htmlspecialchars(sprintf(__('The following entity cannot be restored automatically: "%s".', 'updraftplus'), $sdescrip))." ".__('You will need to restore it manually.', 'updraftplus')."
".'
'; } } ?>

'.str_replace('"', """, __('Migration of data from another site happens through the "Restore" button. A "migration" is ultimately the same as a restoration - but using backup archives that you import from another site. UpdraftPlus modifies the restoration operation appropriately, to fit the backup data to the new site.', 'updraftplus')).' '.sprintf(__('Read this article to see step-by-step how it\'s done.', 'updraftplus'),'http://updraftplus.com/faqs/how-do-i-migrate-to-a-new-site-location/'); } else { echo '

'.__('Do you want to migrate or clone/duplicate a site?', 'updraftplus').'

'.__('Then, try out our "Migrator" add-on. After using it once, you\'ll have saved the purchase price compared to the time needed to copy a site by hand.', 'updraftplus').'

'.__('Get it here.', 'updraftplus').''; } ?>



UpdraftPlus

'. __('Please check out UpdraftPlus Premium, or the stand-alone Multisite add-on.','updraftplus');?>.

settings_formcontents($last_backup_html); ?>

'; } function print_active_jobs() { $cron = get_option('cron'); if (!is_array($cron)) $cron = array(); // $found_jobs = 0; $ret = ''; foreach ($cron as $time => $job) { if (isset($job['updraft_backup_resume'])) { foreach ($job['updraft_backup_resume'] as $hook => $info) { if (isset($info['args'][1])) { // $found_jobs++; $job_id = $info['args'][1]; $ret .= $this->print_active_job($job_id, false, $time, $info['args'][0]); } } } } // if (0 == $found_jobs) { // $ret .= '

'.__('(None)', 'updraftplus').'

'; // } return $ret; } function print_active_job($job_id, $is_oneshot = false, $time = false, $next_resumption = false) { $ret = ''; global $updraftplus; $backupable_entities = $updraftplus->get_backupable_file_entities(true, true); $jobdata = $updraftplus->jobdata_getarray($job_id); #if (!is_array($jobdata)) $jobdata = array(); if (!isset($jobdata['backup_time'])) return ''; $began_at = (isset($jobdata['backup_time'])) ? get_date_from_gmt(gmdate('Y-m-d H:i:s', (int)$jobdata['backup_time']), 'D, F j, Y H:i') : '?'; $jobstatus = empty($jobdata['jobstatus']) ? 'unknown' : $jobdata['jobstatus']; $stage = 0; switch ($jobstatus) { # Stage 0 case 'begun': $curstage = __('Backup begun', 'updraftplus'); break; # Stage 1 case 'filescreating': $stage = 1; $curstage = __('Creating file backup zips', 'updraftplus'); if (!empty($jobdata['filecreating_substatus']) && isset($backupable_entities[$jobdata['filecreating_substatus']['e']]['description'])) { $sdescrip = preg_replace('/ \(.*\)$/', '', $backupable_entities[$jobdata['filecreating_substatus']['e']]['description']); if (strlen($sdescrip) > 20 && isset($jobdata['filecreating_substatus']['e']) && is_array($jobdata['filecreating_substatus']['e']) && isset($backupable_entities[$jobdata['filecreating_substatus']['e']]['shortdescription'])) $sdescrip = $backupable_entities[$jobdata['filecreating_substatus']['e']]['shortdescription']; $curstage .= ' ('.$sdescrip.')'; if (isset($jobdata['filecreating_substatus']['i']) && isset($jobdata['filecreating_substatus']['t'])) { $stage = min(2, 1 + ($jobdata['filecreating_substatus']['i']/max($jobdata['filecreating_substatus']['t'],1))); } } break; case 'filescreated': $stage = 2; $curstage = __('Created file backup zips', 'updraftplus'); break; # Stage 2 case 'dbcreating': $stage = 2; $curstage = __('Creating database backup', 'updraftplus'); if (!empty($jobdata['dbcreating_substatus']['t'])) { $curstage .= ' ('.sprintf(__('table: %s', 'updraftplus'), $jobdata['dbcreating_substatus']['t']).')'; if (!empty($jobdata['dbcreating_substatus']['i']) && !empty($jobdata['dbcreating_substatus']['a'])) { $stage = min(3, 2 + ($jobdata['dbcreating_substatus']['i'] / max($jobdata['dbcreating_substatus']['a'],1))); } } break; case 'dbcreated': $stage = 3; $curstage = __('Created database backup', 'updraftplus'); break; # Stage 3 case 'dbencrypting': $stage = 3; $curstage = __('Encrypting database', 'updraftplus'); break; case 'dbencrypted': $stage = 3; $curstage = __('Encrypted database', 'updraftplus'); break; # Stage 4 case 'clouduploading': $stage = 4; $curstage = __('Uploading files to remote storage', 'updraftplus'); if (isset($jobdata['uploading_substatus']['t']) && isset($jobdata['uploading_substatus']['i'])) { $t = max((int)$jobdata['uploading_substatus']['t'], 1); $i = min($jobdata['uploading_substatus']['i']/$t, 1); $p = min($jobdata['uploading_substatus']['p'], 1); $pd = $i + $p/$t; $stage = 4 + $pd; $curstage .= ' '.sprintf(__('(%s%%, file %s of %s)', 'updraftplus'), floor(100*$pd), $jobdata['uploading_substatus']['i']+1, $t); } break; case 'pruning': $stage = 5; $curstage = __('Pruning old backup sets', 'updraftplus'); break; case 'resumingforerrors': $stage = -1; $curstage = __('Waiting until scheduled time to retry because of errors', 'updraftplus'); break; # Stage 6 case 'finished': $stage = 6; $curstage = __('Backup finished', 'updraftplus'); break; default: $curstage = __('Unknown', 'updraftplus'); } $runs_started = (empty($jobdata['runs_started'])) ? array() : $jobdata['runs_started']; $time_passed = (empty($jobdata['run_times'])) ? array() : $jobdata['run_times']; $last_checkin_ago = -1; if (is_array($time_passed)) { foreach ($time_passed as $run => $passed) { if (isset($runs_started[$run])) { $time_ago = microtime(true) - ($runs_started[$run] + $time_passed[$run]); if ($time_ago < $last_checkin_ago || $last_checkin_ago == -1) $last_checkin_ago = $time_ago; } } } $next_res_after = $time-time(); $next_res_txt = ($is_oneshot) ? '' : ' - '.sprintf(__("next resumption: %d (after %ss)", 'updraftplus'), $next_resumption, $next_res_after). ' '; $last_activity_txt = ($last_checkin_ago >= 0) ? ' - '.sprintf(__('last activity: %ss ago', 'updraftplus'), floor($last_checkin_ago)).' ' : ''; if (($last_checkin_ago < 50 && $next_res_after>30) || $is_oneshot) { $show_inline_info = $last_activity_txt; $title_info = $next_res_txt; } else { $show_inline_info = $next_res_txt; $title_info = $last_activity_txt; } $ret .= '
'.$began_at.' '; $ret .= $show_inline_info; $ret .= '- '.__('show log', 'updraftplus').''; if (!$is_oneshot) $ret .=' - '.__('delete schedule', 'updraftplus').''; if (!empty($jobdata['warnings']) && is_array($jobdata['warnings'])) { $ret .= ''; } $ret .= '
'; $ret .= htmlspecialchars($curstage); $ret .= '
'; $ret .= '
'; $ret .= '
'; return $ret; } function delete_old_dirs_go($show_return = true) { echo ($show_return) ? '

UpdraftPlus - '.__('Remove old directories', 'updraftplus').'

' : '

'.__('Remove old directories', 'updraftplus').'

'; if($this->delete_old_dirs()) { echo '

'.__('Old directories successfully removed.','updraftplus').'


'; } else { echo '

',__('Old directory removal failed for some reason. You may want to do this manually.','updraftplus').'


'; } if ($show_return) echo ''.__('Actions','updraftplus').': '.__('Return to UpdraftPlus Configuration','updraftplus').''; } //deletes the -old directories that are created when a backup is restored. function delete_old_dirs() { global $wp_filesystem, $updraftplus; $credentials = request_filesystem_credentials(wp_nonce_url(UpdraftPlus_Options::admin_page_url()."?page=updraftplus&action=updraft_delete_old_dirs", 'updraftplus-credentialtest-nonce')); WP_Filesystem($credentials); if ($wp_filesystem->errors->get_error_code()) { foreach ($wp_filesystem->errors->get_error_messages() as $message) show_message($message); exit; } // From WP_CONTENT_DIR - which contains 'themes' $ret = $this->delete_old_dirs_dir($wp_filesystem->wp_content_dir()); $updraft_dir = $updraftplus->backups_dir_location(); if ($updraft_dir) { $ret4 = ($updraft_dir) ? $this->delete_old_dirs_dir($updraft_dir, false) : true; } else { $ret4 = true; } // $ret2 = $this->delete_old_dirs_dir($wp_filesystem->abspath()); $plugs = untrailingslashit($wp_filesystem->wp_plugins_dir()); if ($wp_filesystem->is_dir($plugs.'-old')) { print "".__('Delete','updraftplus').": plugins-old: "; if(!$wp_filesystem->delete($plugs.'-old', true)) { $ret3 = false; print "".__('Failed', 'updraftplus')."
"; } else { $ret3 = true; print "".__('OK', 'updraftplus')."
"; } } else { $ret3 = true; } return $ret && $ret3 && $ret4; } function delete_old_dirs_dir($dir, $wpfs = true) { $dir = trailingslashit($dir); global $wp_filesystem, $updraftplus; if ($wpfs) { $list = $wp_filesystem->dirlist($dir); } else { $list = scandir($dir); } if (!is_array($list)) return false; $ret = true; foreach ($list as $item) { $name = (is_array($item)) ? $item['name'] : $item; if ("-old" == substr($name, -4, 4)) { //recursively delete print "".__('Delete','updraftplus').": ".htmlspecialchars($name).": "; if ($wpfs) { if(!$wp_filesystem->delete($dir.$name, true)) { $ret = false; echo "".__('Failed', 'updraftplus')."
"; } else { echo "".__('OK', 'updraftplus')."
"; } } else { if ($updraftplus->remove_local_directory($dir.$name)) { echo "".__('OK', 'updraftplus')."
"; } else { $ret = false; echo "".__('Failed', 'updraftplus')."
"; } } } } return $ret; } // The aim is to get a directory that is writable by the webserver, because that's the only way we can create zip files function create_backup_dir() { global $wp_filesystem, $updraftplus; if (false === ($credentials = request_filesystem_credentials(UpdraftPlus_Options::admin_page().'?page=updraftplus&action=updraft_create_backup_dir&nonce='.wp_create_nonce('create_backup_dir')))) { return false; } if ( ! WP_Filesystem($credentials) ) { // our credentials were no good, ask the user for them again request_filesystem_credentials(UpdraftPlus_Options::admin_page().'?page=updraftplus&action=updraft_create_backup_dir&nonce='.wp_create_nonce('create_backup_dir'), '', true); return false; } $updraft_dir = $updraftplus->backups_dir_location(); $default_backup_dir = $wp_filesystem->find_folder(dirname($updraft_dir)).basename($updraft_dir); $updraft_dir = ($updraft_dir) ? $wp_filesystem->find_folder(dirname($updraft_dir)).basename($updraft_dir) : $default_backup_dir; if (!$wp_filesystem->is_dir($default_backup_dir) && !$wp_filesystem->mkdir($default_backup_dir, 0775)) { $wperr = new WP_Error; if ( $wp_filesystem->errors->get_error_code() ) { foreach ( $wp_filesystem->errors->get_error_messages() as $message ) { $wperr->add('mkdir_error', $message); } return $wperr; } else { return new WP_Error('mkdir_error', __('The request to the filesystem to create the directory failed.', 'updraftplus')); } } if ($wp_filesystem->is_dir($default_backup_dir)) { if ($updraftplus->really_is_writable($updraft_dir)) return true; @$wp_filesystem->chmod($default_backup_dir, 0775); if ($updraftplus->really_is_writable($updraft_dir)) return true; @$wp_filesystem->chmod($default_backup_dir, 0777); if ($updraftplus->really_is_writable($updraft_dir)) { echo '

'.__('The folder was created, but we had to change its file permissions to 777 (world-writable) to be able to write to it. You should check with your hosting provider that this will not cause any problems', 'updraftplus').'

'; return true; } else { @$wp_filesystem->chmod($default_backup_dir, 0775); return new WP_Error('writable_error', __('The folder exists, but your webserver does not have permission to write to it.', 'updraftplus').' '.__('You will need to consult with your web hosting provider to find out to set permissions for a WordPress plugin to write to the directory.', 'updraftplus')); } } return true; } //scans the content dir to see if any -old dirs are present function scan_old_dirs() { global $updraftplus; $dirs = scandir(untrailingslashit(WP_CONTENT_DIR)); if (!is_array($dirs)) $dirs = array(); $dirs_u = @scandir($updraftplus->backups_dir_location()); if (!is_array($dirs_u)) $dirs_u = array(); foreach (array_merge($dirs, $dirs_u) as $dir) { if (preg_match('/-old$/', $dir)) return true; } # No need to scan ABSPATH - we don't backup there if (is_dir(untrailingslashit(WP_PLUGIN_DIR).'-old')) return true; return false; } function last_backup_html() { global $updraftplus; $updraft_last_backup = UpdraftPlus_Options::get_updraft_option('updraft_last_backup'); if($updraft_last_backup) { // Convert to GMT, then to blog time $last_backup_text = "".get_date_from_gmt(gmdate('Y-m-d H:i:s', (int)$updraft_last_backup['backup_time']), 'D, F j, Y H:i').'
'; if (is_array($updraft_last_backup['errors'])) { foreach ($updraft_last_backup['errors'] as $err) { $level = (is_array($err)) ? $err['level'] : 'error'; $message = (is_array($err)) ? $err['message'] : $err; $last_backup_text .= ('warning' == $level) ? "" : ""; if ('warning' == $level) { $message = sprintf(__("Warning: %s", 'updraftplus'), make_clickable(htmlspecialchars($message))); } else { $message = htmlspecialchars($message); } $last_backup_text .= $message; $last_backup_text .= '
'; } } if (!empty($updraft_last_backup['backup_nonce'])) { $updraft_dir = $updraftplus->backups_dir_location(); $potential_log_file = $updraft_dir."/log.".$updraft_last_backup['backup_nonce'].".txt"; if (is_readable($potential_log_file)) $last_backup_text .= "".__('Download log file','updraftplus').""; } } else { $last_backup_text = "".__('No backup has been completed.','updraftplus').""; } return $last_backup_text; } function settings_formcontents($last_backup_html) { global $updraftplus; $updraft_dir = $updraftplus->backups_dir_location(); ?>
: '); ?> 0) ? $updraft_retain : 1; ?>
: '); ?> 0) ? $updraft_retain_db : 1; ?>

'.__('To fix the time at which a backup should take place,','updraftplus').' ('.__('e.g. if your server is busy at day and you want to run overnight','updraftplus').'), '.htmlspecialchars(__('use the "Fix Time" add-on','updraftplus')).'

'); ?>
: get_backupable_file_entities(true, true); # The true (default value if non-existent) here has the effect of forcing a default of on. foreach ($backupable_entities as $key => $info) { $included = (UpdraftPlus_Options::get_updraft_option("updraft_include_$key", apply_filters("updraftplus_defaultoption_include_".$key, true))) ? 'checked="checked"' : ""; if ('others' == $key || 'uploads' == $key) { $include_exclude = UpdraftPlus_Options::get_updraft_option('updraft_include_'.$key.'_exclude', ('others' == $key) ? UPDRAFT_DEFAULT_OTHERS_EXCLUDE : UPDRAFT_DEFAULT_UPLOADS_EXCLUDE); ?> />
"; echo ''; echo ''; echo '
'; echo ''; } else { echo "
"; do_action("updraftplus_config_option_include_$key"); } } ?>

'.htmlspecialchars(__('See also the "More Files" add-on from our shop.', 'updraftplus'))); ?>

('.__('Use WordShell for automatic backup, version control and patching', 'updraftplus').').

';?>
:

Do make a separate record of it and do not lose it, or all your backups will be useless. Presently, only the database file is encrypted. This is also the key used to decrypt backups from this admin interface (so if you change it, then automatic decryption will not work until you change it back).','updraftplus');?> have_addons < 10) { if ($updraft_encryptionphrase) echo ''; echo ' '.__("A future release of UpdraftPlus will move the encryption feature into an add-on, and add the capability to encrypt files also.", 'updraftplus'); if ($updraft_encryptionphrase) echo ''; } ?>

: >
'.__('For more reporting features, use the Reporting add-on.', 'updraftplus').''; ?>

backup_methods as $method => $description) { do_action('updraftplus_config_print_before_storage', $method); require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php'); $call_method = 'UpdraftPlus_BackupModule_'.$method; $method_objects[$method] = new $call_method; $method_objects[$method]->config_print(); do_action('updraftplus_config_print_after_storage', $method); } ?>
: just_one($active_service); ?> '.htmlspecialchars(__('You can send a backup to more than one destination with an add-on.','updraftplus')).'

'; ?>

: />
: -
wordshell_random_advert(1); if ($ws_ad) { ?>

= UPDRAFTPLUS_SPLIT_MIN) $value = UPDRAFTPLUS_SPLIT_MIN; return $value; } function curl_check($service, $has_fallback = false, $extraclass = '') { // Check requirements if (!function_exists("curl_init") || !function_exists('curl_exec')) { $this->show_double_warning(''.__('Warning','updraftplus').': '.sprintf(__('Your web server\'s PHP installation does not included a required (for %s) module (%s). Please contact your web hosting provider\'s support and ask for them to enable it.', 'updraftplus'), $service, 'Curl').' '.sprintf(__("Your options are 1) Install/enable %s or 2) Change web hosting companies - %s is a standard PHP component, and required by all cloud backup plugins that we know of.",'updraftplus'), 'Curl', 'Curl'), $extraclass); } else { $curl_version = curl_version(); $curl_ssl_supported= ($curl_version['features'] & CURL_VERSION_SSL); if (!$curl_ssl_supported) { if ($has_fallback) { ?>

:

show_double_warning('

'.__('Warning','updraftplus').': '.sprintf(__("Your web server's PHP/Curl installation does not support https access. We cannot access %s without this support. Please contact your web hosting provider's support. %s requires Curl+https. Please do not file any support requests; there is no alternative.",'updraftplus'),$service).'

', $extraclass); } } else { ?>

$basedir) { $directories = $directorieses[$ind]; if (!is_array($directories)) $directories=array($directories); foreach ($directories as $dir) { if (is_file($dir)) { $size += @filesize($dir); } else { $suffix = ('' != $basedir) ? ((0 === strpos($dir, $basedir.'/')) ? substr($dir, 1+strlen($basedir)) : '') : ''; $size += $this->recursive_directory_size_raw($basedir, $exclude, $suffix); } } } if ($size > 1073741824) { return round($size / 1073741824, 1).' Gb'; } elseif ($size > 1048576) { return round($size / 1048576, 1).' Mb'; } elseif ($size > 1024) { return round($size / 1024, 1).' Kb'; } else { return round($size, 1).' b'; } } function recursive_directory_size_raw($prefix_directory, &$exclude = array(), $suffix_directory = '') { $directory = $prefix_directory.('' == $suffix_directory ? '' : '/'.$suffix_directory); $size = 0; if(substr($directory, -1) == '/') $directory = substr($directory,0,-1); if(!file_exists($directory) || !is_dir($directory) || !is_readable($directory)) return -1; if($handle = opendir($directory)) { while (($file = readdir($handle)) !== false) { if ($file != '.' && $file != '..') { $spath = ('' == $suffix_directory) ? $file : $suffix_directory.'/'.$file; if (false !== ($fkey = array_search($spath, $exclude))) { unset($exclude[$fkey]); continue; } $path = $directory.'/'.$file; if(is_file($path)) { $size += filesize($path); } elseif(is_dir($path)) { $handlesize = $this->recursive_directory_size_raw($prefix_directory, $exclude, $suffix_directory.('' == $suffix_directory ? '' : '/').$file); if($handlesize >= 0) { $size += $handlesize; }# else { return -1; } } } } closedir($handle); } return $size; } function existing_backup_table($backup_history = false) { global $updraftplus; $ret = ''; // Fetch it if it was not passed if ($backup_history === false) $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history'); if (!is_array($backup_history)) $backup_history=array(); $updraft_dir = $updraftplus->backups_dir_location(); $backupable_entities = $updraftplus->get_backupable_file_entities(true, true); $ret .= ''; krsort($backup_history); foreach($backup_history as $key=>$backup) { # https://core.trac.wordpress.org/ticket/25331 # $pretty_date = date_i18n('Y-m-d G:i',$key); // Convert to blog time zone $pretty_date = get_date_from_gmt(gmdate('Y-m-d H:i:s', (int)$key), 'Y-m-d G:i'); $esc_pretty_date=esc_attr($pretty_date); $entities = ''; $sval = ((isset($backup['service']) && $backup['service'] != 'email' && $backup['service'] != 'none')) ? '1' : '0'; $title = __('Delete this backup set', 'updraftplus'); $non=$backup['nonce']; $ret .= << \n"; // Now go through each of the file entities foreach ($backupable_entities as $type => $info) { $ret .= ''; }; $ret .= ' ENDHERE; } $ret .= '
$pretty_date ENDHERE; $jobdata = $updraftplus->jobdata_getarray($non); if (is_array($jobdata) && !empty($jobdata['resume_interval']) && (empty($jobdata['jobstatus']) || 'finished' != $jobdata['jobstatus'])) { $ret .= "
".__('(Not finished)', 'updraftplus').''; } $ret .= "
"; if (isset($backup['db'])) { $entities .= '/db=0/'; $sdescrip = preg_replace('/ \(.*\)$/', '', __('Database','updraftplus')); $nf = wp_nonce_field('updraftplus_download', '_wpnonce', true, false); $dbt = __('Database','updraftplus'); $ret .= << $nf ENDHERE; } else { $ret .= sprintf(_x('(No %s)','Message shown when no such object is available','updraftplus'), __('database', 'updraftplus')); } $ret .="'; $sdescrip = preg_replace('/ \(.*\)$/', '', $info['description']); if (strlen($sdescrip) > 20 && isset($info['shortdescription'])) $sdescrip = $info['shortdescription']; if (isset($backup[$type])) { if (!is_array($backup[$type])) $backup[$type]=array($backup[$type]); $nf = wp_nonce_field('updraftplus_download', '_wpnonce', true, false); $howmanyinset = count($backup[$type]); $expected_index = 0; $index_missing = false; $set_contents = ''; $entities .= "/$type="; $whatfiles = $backup[$type]; ksort($whatfiles); foreach ($whatfiles as $findex => $bfile) { $set_contents .= ($set_contents == '') ? $findex : ",$findex"; if ($findex != $expected_index) $index_missing = true; $expected_index++; } $entities .= $set_contents.'/'; $first_printed = true; foreach ($whatfiles as $findex => $bfile) { $ide = __('Press here to download','updraftplus').' '.strtolower($info['description']); $pdescrip = ($findex > 0) ? $sdescrip.' ('.($findex+1).')' : $sdescrip; if (!$first_printed) { $ret .= '
'; } if (count($backup[$type]) >0) { $ide .= ' '.sprintf(__('(%d archive(s) in set).', 'updraftplus'), $howmanyinset); } if ($index_missing) { $ide .= ' '.__('You appear to be missing one or more archives from this multi-archive set.', 'updraftplus'); } $ret .= << $nf ENDHERE; if (!$first_printed) { $ret .= '
'; } else { $first_printed = false; } } } else { $ret .= sprintf(_x('(No %s)','Message shown when no such object is available','updraftplus'), preg_replace('/\s\(.{12,}\)/', '', strtolower($sdescrip))); } $ret .= '
'; if (isset($backup['nonce']) && preg_match("/^[0-9a-f]{12}$/",$backup['nonce']) && is_readable($updraft_dir.'/log.'.$backup['nonce'].'.txt')) { $nval = $backup['nonce']; $lt = __('Backup Log','updraftplus'); $url = UpdraftPlus_Options::admin_page(); $ret .= << ENDHERE; } else { $ret .= "(No backup log)"; } $ret .= <<
ENDHERE; if ($entities) { $ret .= ''; } $ret .= <<
'; return $ret; } // This function examines inside the updraft directory to see if any new archives have been uploaded. If so, it adds them to the backup set. (Non-present items are also removed, only if the service is 'none'). function rebuild_backup_history() { global $updraftplus; $known_files = array(); $known_nonces = array(); $changes = false; $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history'); if (!is_array($backup_history)) $backup_history = array(); $updraft_dir = $updraftplus->backups_dir_location(); if (!is_dir($updraft_dir)) return; // Accumulate a list of known files foreach ($backup_history as $btime => $bdata) { $found_file = false; foreach ($bdata as $key => $values) { // Record which set this file is found in if (!is_array($values)) $values=array($values); foreach ($values as $val) { if (is_string($val) && preg_match('/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-[\-a-z]+([0-9]+(of[0-9]+)?)?+\.(zip|gz|gz\.crypt)$/i', $val, $matches)) { $nonce = $matches[2]; if (isset($bdata['service']) && $bdata['service'] == 'none' && !is_file($updraft_dir.'/'.$val)) { # File no longer present } else { $found_file = true; $known_files[$val] = $nonce; $known_nonces[$nonce] = $btime; } } } } if (!$found_file) { unset($backup_history[$btime]); $changes = true; } } if (!$handle = opendir($updraft_dir)) return; while (false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { if (preg_match('/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-([\-a-z]+)([0-9]+(of[0-9]+)?)?\.(zip|gz|gz\.crypt)$/i', $entry, $matches)) { $btime = strtotime($matches[1]); if ($btime > 100) { if (!isset($known_files[$entry])) { $changes = true; $nonce = $matches[2]; $type = $matches[3]; $index = (empty($matches[4])) ? '0' : (max((int)$matches[4]-1,0)); $itext = ($index == 0) ? '' : $index; // The time from the filename does not include seconds. Need to identify the seconds to get the right time if (isset($known_nonces[$nonce])) $btime = $known_nonces[$nonce]; // No cloud backup known of this file if (!isset($backup_history[$btime])) $backup_history[$btime] = array('service' => 'none' ); $backup_history[$btime][$type][$index] = $entry; $fs = @filesize($updraft_dir.'/'.$entry); if (false !== $fs) $backup_history[$btime][$type.$itext.'-size'] = $fs; $backup_history[$btime]['nonce'] = $nonce; } } } } } if ($changes) UpdraftPlus_Options::update_updraft_option('updraft_backup_history', $backup_history); } // Return values: false = 'not yet' (not necessarily terminal); WP_Error = terminal failure; true = success function restore_backup($timestamp) { @set_time_limit(900); global $wp_filesystem, $updraftplus; $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history'); if(!is_array($backup_history[$timestamp])) { echo '

'.__('This backup does not exist in the backup history - restoration aborted. Timestamp:','updraftplus')." $timestamp


"; return new WP_Error('does_not_exist', __('Backup does not exist in the backup history', 'updraftplus')); } // request_filesystem_credentials passes on fields just via hidden name/value pairs. // Build array of parameters to be passed via this $extra_fields = array(); if (isset($_POST['updraft_restore']) && is_array($_POST['updraft_restore'])) { foreach ($_POST['updraft_restore'] as $entity) { $_POST['updraft_restore_'.$entity] = 1; $extra_fields[] = 'updraft_restore_'.$entity; } } // Now make sure that updraft_restorer_ option fields get passed along to request_filesystem_credentials foreach ($_POST as $key => $value) { if (0 === strpos($key, 'updraft_restorer_')) $extra_fields[] = $key; } $credentials = request_filesystem_credentials(UpdraftPlus_Options::admin_page()."?page=updraftplus&action=updraft_restore&backup_timestamp=$timestamp", '', false, false, $extra_fields); WP_Filesystem($credentials); if ( $wp_filesystem->errors->get_error_code() ) { foreach ( $wp_filesystem->errors->get_error_messages() as $message ) show_message($message); exit; } # Set up logging $updraftplus->backup_time_nonce(); $updraftplus->jobdata_set('job_type', 'restore'); $updraftplus->jobdata_set('job_time_ms', $updraftplus->job_time_ms); $updraftplus->logfile_open($updraftplus->nonce); # Provide download link for the log file #echo '

'.__('Follow this link to download the log file for this restoration.', 'updraftplus').'

'; # TODO: Automatic purging of old log files # TODO: Provide option to auto-email the log file //if we make it this far then WP_Filesystem has been instantiated and is functional (tested with ftpext, what about suPHP and other situations where direct may work?) echo '

'.__('UpdraftPlus Restoration: Progress', 'updraftplus').'

'; $this->show_admin_warning(''.__('Follow this link to download the log file for this restoration (needed for any support requests).', 'updraftplus').''); $updraft_dir = trailingslashit($updraftplus->backups_dir_location()); $service = (isset($backup_history[$timestamp]['service'])) ? $backup_history[$timestamp]['service'] : false; if (!is_array($service)) $service = array($service); // Now, need to turn any updraft_restore_ fields (that came from a potential WP_Filesystem form) back into parts of the _POST array (which we want to use) if (empty($_POST['updraft_restore']) || (!is_array($_POST['updraft_restore']))) $_POST['updraft_restore'] = array(); $entities_to_restore = array_flip($_POST['updraft_restore']); foreach ($_POST as $key => $value) { if (strpos($key, 'updraft_restore_') === 0 ) { $nkey = substr($key, 16); if (!isset($entities_to_restore[$nkey])) { $_POST['updraft_restore'][] = $nkey; $entities_to_restore[$nkey] = 1; } } } $updraftplus->log("Restore job started. Entities to restore: ".implode(', ', array_flip($entities_to_restore))); if (0 == count($_POST['updraft_restore'])) { echo '

'.__('ABORT: Could not find the information on which entities to restore.', 'updraftplus').'

'; echo '

'.__('If making a request for support, please include this information:','updraftplus').' '.count($_POST).' : '.htmlspecialchars(serialize($_POST)).'

'; return new WP_Error('missing_info', 'Backup information not found'); } set_error_handler(array($updraftplus, 'php_error'), E_ALL & ~E_STRICT); /* $_POST['updraft_restore'] is typically something like: array( 0=>'db', 1=>'plugins', 2=>'themes'), etc. i.e. array ( 'db', 'plugins', themes') */ $backupable_entities = $updraftplus->get_backupable_file_entities(true, true); $backup_set = $backup_history[$timestamp]; uksort($backup_set, array($this, 'sort_restoration_entities')); // We use a single object for each entity, because we want to store information about the backup set require_once(UPDRAFTPLUS_DIR.'/restorer.php'); global $updraftplus_restorer; $updraftplus_restorer = new Updraft_Restorer(new Updraft_Restorer_Skin); $second_loop = array(); echo "

".__('Final checks', 'updraftplus').'

'; // First loop: make sure that files are present + readable; and populate array for second loop foreach ($backup_set as $type => $files) { // All restorable entities must be given explicitly, as we can store other arbitrary data in the history array if (!isset($backupable_entities[$type]) && 'db' != $type) continue; if (isset($backupable_entities[$type]['restorable']) && $backupable_entities[$type]['restorable'] == false) continue; if (!isset($entities_to_restore[$type])) continue; if ($type == 'wpcore' && is_multisite() && 0 === $updraftplus_restorer->ud_backup_is_multisite) { echo "

$type: "; echo __('Skipping restoration of WordPress core when importing a single site into a multisite installation. If you had anything necessary in your WordPress directory then you will need to re-add it manually from the zip file.', 'updraftplus'); #TODO #$updraftplus->log_e('Skipping restoration of WordPress core when importing a single site into a multisite installation. If you had anything necessary in your WordPress directory then you will need to re-add it manually from the zip file.'); echo "

"; continue; } if (is_string($files)) $files=array($files); foreach ($files as $ind => $file) { $fullpath = $updraft_dir.$file; echo sprintf(__("Looking for %s archive: file name: %s", 'updraftplus'), $type, htmlspecialchars($file))."
"; foreach ($service as $serv) { if(!is_readable($fullpath)) { $sd = (empty($updraftplus->backup_methods[$serv])) ? $serv : $updraftplus->backup_methods[$serv]; echo __("File is not locally present - needs retrieving from remote storage",'updraftplus')." ($sd)"; $this->download_file($file, $serv); echo ": "; if (!is_readable($fullpath)) { echo __("Error", 'updraftplus'); } else { echo __("OK", 'updraftplus'); } echo '
'; } } $index = ($ind == 0) ? '' : $ind; // If a file size is stored in the backup data, then verify correctness of the local file if (isset($backup_history[$timestamp][$type.$index.'-size'])) { $fs = $backup_history[$timestamp][$type.$index.'-size']; echo __("Archive is expected to be size:",'updraftplus')." ".round($fs/1024, 1)." Kb: "; $as = @filesize($fullpath); if ($as == $fs) { echo __('OK','updraftplus').'
'; } else { echo "".__('Error:','updraftplus')." ".__('file is size:', 'updraftplus')." ".round($as/1024)." ($fs, $as)
"; } } else { echo __("The backup records do not contain information about the proper size of this file.",'updraftplus')."
"; } if (!is_readable($fullpath)) { echo __('Could not find one of the files for restoration', 'updraftplus')." ($file)
"; $updraftplus->log("$file: ".__('Could not find one of the files for restoration', 'updraftplus'), 'error'); echo '
'; restore_error_handler(); return false; } } $info = (isset($backupable_entities[$type])) ? $backupable_entities[$type] : array(); $val = $updraftplus_restorer->pre_restore_backup($files, $type, $info); if (is_wp_error($val)) { $updraftplus->log_wp_error($val); foreach ($val->get_error_messages() as $msg) { echo ''.__('Error:', 'updraftplus').' '.htmlspecialchars($msg).'
'; } foreach ($val->get_error_codes() as $code) { if ('already_exists' == $code) $this->print_delete_old_dirs_form(false); } echo ''; //close the updraft_restore_progress div even if we error restore_error_handler(); return $val; } elseif (false === $val) { echo ''; //close the updraft_restore_progress div even if we error restore_error_handler(); return false; } $second_loop[$type] = $files; } $updraftplus_restorer->delete = (UpdraftPlus_Options::get_updraft_option('updraft_delete_local')) ? true : false; if ('none' === $service || 'email' === $service || empty($service) || (is_array($service) && 1 == count($service) && (in_array('none', $service) || in_array('', $service) || in_array('email', $service)))) { if ($updraftplus_restorer->delete) $updraftplus->log_e('Will not delete any archives after unpacking them, because there was no cloud storage for this backup'); $updraftplus_restorer->delete = false; } // Second loop: now actually do the restoration uksort($second_loop, array($this, 'sort_restoration_entities')); foreach ($second_loop as $type => $files) { # Types: uploads, themes, plugins, others, db $info = (isset($backupable_entities[$type])) ? $backupable_entities[$type] : array(); echo ('db' == $type) ? "

".__('Database','updraftplus')."

" : "

".$info['description']."

"; $updraftplus->log("Entity: ".$type); if (is_string($files)) $files = array($files); foreach ($files as $file) { $val = $updraftplus_restorer->restore_backup($file, $type, $info); if(is_wp_error($val)) { $updraftplus->log_e($val); foreach ($val->get_error_messages() as $msg) { echo ''.__('Error message', 'updraftplus').': '.htmlspecialchars($msg).'
'; } $codes = $val->get_error_codes(); if (is_array($codes)) { foreach ($codes as $code) { $data = $val->get_error_data($code); if (!empty($data)) { $pdata = (is_string($data)) ? $data : serialize($data); echo ''.__('Error data:', 'updraftplus').' '.htmlspecialchars($pdata).'
'; } } } echo ''; //close the updraft_restore_progress div even if we error restore_error_handler(); return $val; } elseif (false === $val) { echo ''; //close the updraft_restore_progress div even if we error restore_error_handler(); return false; } } } foreach (array('template', 'stylesheet', 'template_root', 'stylesheet_root') as $opt) { add_filter('pre_option_'.$opt, array($this, 'option_filter_'.$opt)); } if (!function_exists('validate_current_theme')) require_once(ABSPATH.'wp-includes/themes'); if (!validate_current_theme()) { global $updraftplus; echo ''; $updraftplus->log_e("The current theme was not found; to prevent this stopping the site from loading, your theme has been reverted to the default theme"); echo ''; } #foreach (array('template', 'stylesheet', 'template_root', 'stylesheet_root') as $opt) { # remove_filter('pre_option_'.$opt, array($this, 'option_filter_'.$opt)); #} echo ''; //close the updraft_restore_progress div restore_error_handler(); return true; } function option_filter_template($val) { global $updraftplus; return $updraftplus->option_filter_get('template'); } function option_filter_stylesheet($val) { global $updraftplus; return $updraftplus->option_filter_get('stylesheet'); } function option_filter_template_root($val) { global $updraftplus; return $updraftplus->option_filter_get('template_root'); } function option_filter_stylesheet_root($val) { global $updraftplus; return $updraftplus->option_filter_get('stylesheet_root'); } function sort_restoration_entities($a, $b) { if ($a == $b) return 0; # Put the database first if ('db' == $a) return -1; if ('db' == $b) return 1; return strcmp($a, $b); } function return_array($input) { if (!is_array($input)) $input = array(); return $input; } private function get_settings_keys() { return array('updraft_autobackup_default', 'updraftplus_tmp_googledrive_access_token', 'updraftplus_dismissedautobackup', 'updraftplus_dismissedexpiry', 'updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', 'updraft_googledrive_clientid', 'updraft_googledrive_secret', 'updraft_googledrive_remotepath', 'updraft_ftp_login', 'updraft_ftp_pass', 'updraft_ftp_remote_path', 'updraft_server_address', 'updraft_dir', 'updraft_email', 'updraft_delete_local', 'updraft_debug_mode', 'updraft_include_plugins', 'updraft_include_themes', 'updraft_include_uploads', 'updraft_include_others', 'updraft_include_wpcore', 'updraft_include_wpcore_exclude', 'updraft_include_more', 'updraft_include_blogs', 'updraft_include_mu-plugins', 'updraft_include_others_exclude', 'updraft_include_uploads_exclude', 'updraft_lastmessage', 'updraft_googledrive_token', 'updraft_dropboxtk_request_token', 'updraft_dropboxtk_access_token', 'updraft_dropbox_folder', 'updraft_last_backup', 'updraft_starttime_files', 'updraft_starttime_db', 'updraft_startday_db', 'updraft_startday_files', 'updraft_sftp_settings', 'updraft_s3', 'updraft_s3generic', 'updraft_dreamhost', 'updraft_s3generic_login', 'updraft_s3generic_pass', 'updraft_s3generic_remote_path', 'updraft_s3generic_endpoint', 'updraft_webdav_settings', 'updraft_disable_ping', 'updraft_cloudfiles', 'updraft_cloudfiles_user', 'updraft_cloudfiles_apikey', 'updraft_cloudfiles_path', 'updraft_cloudfiles_authurl', 'updraft_ssl_useservercerts', 'updraft_ssl_disableverify', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dreamobjects_login', 'updraft_dreamobjects_pass', 'updraft_dreamobjects_remote_path', 'updraft_report_warningsonly', 'updraft_report_wholebackup', 'updraft_log_syslog'); } } ?>