public static function change_path($file) { $opts = UpdraftPlus_Options::get_updraft_option('updraft_dropbox'); $folder = empty($opts['folder']) ? '' : $opts['folder']; $dropbox_folder = trailingslashit($folder); return $dropbox_folder == '/' || $dropbox_folder == './' ? $file : $dropbox_folder . $file; }
public function get_login_url($redirect_to, $extra_info) { if (is_array($extra_info) && !empty($extra_info['user_id']) && is_numeric($extra_info['user_id'])) { $user_id = $extra_info['user_id']; if (false == ($login_key = $this->_get_autologin_key($user_id))) { return $this->_generic_error_response('user_key_failure'); } // Default value $redirect_url = network_admin_url(); if (is_array($redirect_to) && !empty($redirect_to['module'])) { switch ($redirect_to['module']) { case 'updraftplus': if ('initiate_restore' == $redirect_to['action'] && class_exists('UpdraftPlus_Options')) { $redirect_url = UpdraftPlus_Options::admin_page_url() . '?page=updraftplus&udaction=initiate_restore&entities=' . urlencode($redirect_to['data']['entities']) . '&showdata=' . urlencode($redirect_to['data']['showdata']) . '&backup_timestamp=' . (int) $redirect_to['data']['backup_timestamp']; } elseif ('download_file' == $redirect_to['action']) { $findex = empty($redirect_to['data']['findex']) ? 0 : (int) $redirect_to['data']['findex']; // e.g. ?udcentral_action=dl&action=updraftplus_spool_file&backup_timestamp=1455101696&findex=0&what=plugins $redirect_url = site_url() . '?udcentral_action=spool_file&action=updraftplus_spool_file&findex=' . $findex . '&what=' . urlencode($redirect_to['data']['what']) . '&backup_timestamp=' . (int) $redirect_to['data']['backup_timestamp']; } break; case 'direct_url': $redirect_url = $redirect_to['url']; break; } } $login_key = apply_filters('updraftplus_remotecontrol_login_key', array('key' => $login_key, 'created' => time(), 'redirect_url' => $redirect_url), $redirect_to, $extra_info); // Over-write any previous value - only one can be valid at a time) update_user_meta($user_id, 'updraftcentral_login_key', $login_key); return $this->_response(array('login_url' => network_site_url('?udcentral_action=login&login_id=' . $user_id . '&login_key=' . $login_key['key']))); } else { return $this->_generic_error_response('user_unknown'); } }
public function get_service($opts, $useservercerts = false, $disablesslverify = null) { $user = $opts['user']; $apikey = $opts['apikey']; $authurl = $opts['authurl']; $region = !empty($opts['region']) ? $opts['region'] : null; require_once UPDRAFTPLUS_DIR . '/vendor/autoload.php'; global $updraftplus; # The new authentication APIs don't match the values we were storing before $new_authurl = 'https://lon.auth.api.rackspacecloud.com' == $authurl || 'uk' == $authurl ? Rackspace::UK_IDENTITY_ENDPOINT : Rackspace::US_IDENTITY_ENDPOINT; if (null === $disablesslverify) { $disablesslverify = UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify'); } if (empty($user) || empty($apikey)) { throw new Exception(__('Authorisation failed (check your credentials)', 'updraftplus')); } $updraftplus->log("Cloud Files authentication URL: " . $new_authurl); $client = new Rackspace($new_authurl, array('username' => $user, 'apiKey' => $apikey)); $this->client = $client; if ($disablesslverify) { $client->setSslVerification(false); } else { if ($useservercerts) { $client->setConfig(array($client::SSL_CERT_AUTHORITY, 'system')); } else { $client->setSslVerification(UPDRAFTPLUS_DIR . '/includes/cacert.pem', true, 2); } } return $client->objectStoreService('cloudFiles', $region); }
public function get_service($opts, $useservercerts = false, $disablesslverify = null) { # 'tenant', 'user', 'password', 'authurl', 'path', (optional) 'region' extract($opts); if (null === $disablesslverify) { $disablesslverify = UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify'); } if (empty($user) || empty($password) || empty($authurl)) { throw new Exception(__('Authorisation failed (check your credentials)', 'updraftplus')); } require_once UPDRAFTPLUS_DIR . '/oc/autoload.php'; global $updraftplus; $updraftplus->log("OpenStack authentication URL: " . $authurl); $client = new OpenStack($authurl, array('username' => $user, 'password' => $password, 'tenantName' => $tenant)); $this->client = $client; if ($disablesslverify) { $client->setSslVerification(false); } else { if ($useservercerts) { $client->setConfig(array($client::SSL_CERT_AUTHORITY => false)); } else { $client->setSslVerification(UPDRAFTPLUS_DIR . '/includes/cacert.pem', true, 2); } } $client->authenticate(); if (empty($region)) { $catalog = $client->getCatalog(); if (!empty($catalog)) { $items = $catalog->getItems(); if (is_array($items)) { foreach ($items as $item) { $name = $item->getName(); $type = $item->getType(); if ('swift' != $name || 'object-store' != $type) { continue; } $eps = $item->getEndpoints(); if (!is_array($eps)) { continue; } foreach ($eps as $ep) { if (is_object($ep) && !empty($ep->region)) { $region = $ep->region; } } } } } } $this->region = $region; return $client->objectStoreService('swift', $region); }
function backup($backup_array) { global $updraftplus; $updraft_dir = $updraftplus->backups_dir_location() . '/'; foreach ($backup_array as $type => $file) { $fullpath = $updraft_dir . $file; foreach (explode(',', UpdraftPlus_Options::get_updraft_option('updraft_email')) as $sendmail_addr) { wp_mail(trim($sendmail_addr), __("WordPress Backup", 'updraftplus') . " " . date('Y-m-d H:i', $updraftplus->backup_time), __("Backup is of:", 'updraftplus') . " " . $type . ". " . __('Be wary; email backups may fail because of file size limitations on mail servers.', 'updraftplus'), null, array($fullpath)); } $updraftplus->uploaded_file($file); } $updraftplus->prune_retained_backups("email", null, null); }
/** * Obtain user authorisation * The user will be redirected to Dropbox' web endpoint * @link http://tools.ietf.org/html/rfc5849#section-2.2 * @return void */ private function authorise() { // Only redirect if using CLI if (PHP_SAPI !== 'cli' && (!defined('DOING_CRON') || !DOING_CRON)) { $url = $this->getAuthoriseUrl(); header('Location: ' . $url); exit; } global $updraftplus; $updraftplus->log('Dropbox reauthorisation needed; but we are running from cron or the CLI, so this is not possible'); UpdraftPlus_Options::update_updraft_option("updraft_dropboxtk_request_token", ''); $updraftplus->log(sprintf(__('You need to re-authenticate with %s, as your existing credentials are not working.', 'updraftplus'), 'Dropbox'), 'error'); exit; }
public function backup($backup_array) { global $updraftplus, $updraftplus_backup; $updraft_dir = trailingslashit($updraftplus->backups_dir_location()); $email = $updraftplus->just_one_email(UpdraftPlus_Options::get_updraft_option('updraft_email'), true); if (!is_array($email)) { $email = array($email); } foreach ($backup_array as $type => $file) { $descrip_type = preg_match('/^(.*)\\d+$/', $type, $matches) ? $matches[1] : $type; $fullpath = $updraft_dir . $file; if (file_exists($fullpath) && filesize($fullpath) > UPDRAFTPLUS_WARN_EMAIL_SIZE) { $size_in_mb_of_big_file = round(filesize($fullpath) / 1048576, 1); $toobig_hash = md5($file); $updraftplus->log($file . ': ' . sprintf(__('This backup archive is %s Mb in size - the attempt to send this via email is likely to fail (few email servers allow attachments of this size). If so, you should switch to using a different remote storage method.', 'updraftplus'), $size_in_mb_of_big_file), 'warning', 'toobigforemail_' . $toobig_hash); } $any_attempted = false; $any_sent = false; foreach ($email as $ind => $addr) { if (!apply_filters('updraftplus_email_wholebackup', true, $addr, $ind, $type)) { continue; } foreach (explode(',', $addr) as $sendmail_addr) { $send_short = strlen($sendmail_addr) > 5 ? substr($sendmail_addr, 0, 5) . '...' : $sendmail_addr; $updraftplus->log("{$file}: email to: {$send_short}"); $any_attempted = true; $subject = __("WordPress Backup", 'updraftplus') . ': ' . get_bloginfo('name') . ' (UpdraftPlus ' . $updraftplus->version . ') ' . get_date_from_gmt(gmdate('Y-m-d H:i:s', $updraftplus->backup_time), 'Y-m-d H:i'); $sent = wp_mail(trim($sendmail_addr), $subject, sprintf(__("Backup is of: %s.", 'updraftplus'), site_url() . ' (' . $descrip_type . ')'), null, array($fullpath)); if ($sent) { $any_sent = true; } } } if ($any_sent) { if (isset($toobig_hash)) { $updraftplus->log_removewarning('toobigforemail_' . $toobig_hash); // Don't leave it still set for the next archive unset($toobig_hash); } $updraftplus->uploaded_file($file); } elseif ($any_attempted) { $updraftplus->log('Mails were not sent successfully'); $updraftplus->log(__('The attempt to send the backup via email failed (probably the backup was too large for this method)', 'updraftplus'), 'error'); } else { $updraftplus->log('No email addresses were configured to send to'); } } return null; }
public function getBackupsData() { $backup_list = UpdraftPlus_Options::get_updraft_option('updraft_backup_history'); if (empty($backup_list)) { return; } $backups = array(); foreach ($backup_list as $timestamp => $backups_info) { $time_mm = strtotime("-{$this->last_months} month"); // If date more than 1 month - skip it if (date('Y-m-d', $timestamp) < date('Y-m-d', $time_mm)) { continue; } $this->backups_size = 0; $this->backup_files = array(); $destinations = array(); if (is_array($backups_info)) { if ($this->viewTypes && is_array($this->viewTypes)) { foreach ($this->viewTypes as $type) { $this->_addBackupElement($backups_info, $type); } } if (isset($backups_info['service']) && !empty($backups_info['service'])) { if (is_array($backups_info['service'])) { foreach ($backups_info['service'] as $service) { if ($service == 'none') { $service = 'local'; } $destinations[] = $service; } } else { if ($backups_info['service'] == 'none') { $backups_info['service'] = 'local'; } $destinations[] = $backups_info['service']; } } if (isset($this->backup_files) && is_array($this->backup_files) && !empty($this->backup_files)) { $backups[date('Y-m-d', $timestamp)][] = array('timestamp' => $timestamp, 'file' => $this->backup_files, 'dest' => $destinations, 'source' => null, 'size' => $this->backups_size, 'links' => array()); } } } return $backups; }
public function backup($backup_array) { global $updraftplus, $updraftplus_backup; $updraft_dir = trailingslashit($updraftplus->backups_dir_location()); $email = $updraftplus->just_one_email(UpdraftPlus_Options::get_updraft_option('updraft_email'), true); if (!is_array($email)) { $email = array($email); } foreach ($backup_array as $type => $file) { $descrip_type = preg_match('/^(.*)\\d+$/', $type, $matches) ? $matches[1] : $type; $fullpath = $updraft_dir . $file; #if (file_exists($fullpath) && filesize($fullpath) > ... $any_attempted = false; $any_sent = false; foreach ($email as $ind => $addr) { if (!apply_filters('updraftplus_email_wholebackup', true, $addr, $ind, $type)) { continue; } foreach (explode(',', $addr) as $sendmail_addr) { $send_short = strlen($sendmail_addr) > 5 ? substr($sendmail_addr, 0, 5) . '...' : $sendmail_addr; $updraftplus->log("{$file}: email to: {$send_short}"); $any_attempted = true; $subject = __("WordPress Backup", 'updraftplus') . ': ' . get_bloginfo('name') . ' (UpdraftPlus ' . $updraftplus->version . ') ' . get_date_from_gmt(gmdate('Y-m-d H:i:s', $updraftplus->backup_time), 'Y-m-d H:i'); $sent = wp_mail(trim($sendmail_addr), $subject, sprintf(__("Backup is of: %s.", 'updraftplus'), site_url() . ' (' . $descrip_type . ')'), null, array($fullpath)); if ($sent) { $any_sent = true; } } } if ($any_sent) { $updraftplus->uploaded_file($file); } elseif ($any_attempted) { $updraftplus->log('Mails were not sent successfully'); $updraftplus->log(__('The attempt to send the backup via email failed (probably the backup was too large for this method)', 'updraftplus'), 'error'); } else { $updraftplus->log('No email addresses were configured to send to'); } } return null; }
function unpack_package($package, $delete_package = true) { global $wp_filesystem, $updraftplus; $updraft_dir = $updraftplus->backups_dir_location(); // If not database, then it is a zip - unpack in the usual way #if (!preg_match('/db\.gz(\.crypt)?$/i', $package)) return parent::unpack_package($updraft_dir.'/'.$package, $delete_package); if (!preg_match('/db\\.gz(\\.crypt)?$/i', $package)) { return $this->unpack_package_zip($updraft_dir . '/' . $package, $delete_package); } $backup_dir = $wp_filesystem->find_folder($updraft_dir); // Unpack a database. The general shape of the following is copied from class-wp-upgrader.php @set_time_limit(1800); $this->skin->feedback('unpack_package'); $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/'; @$wp_filesystem->mkdir($upgrade_folder, octdec($this->calculate_additive_chmod_oct(FS_CHMOD_DIR, 0775))); //Clean up contents of upgrade directory beforehand. $upgrade_files = $wp_filesystem->dirlist($upgrade_folder); if (!empty($upgrade_files)) { foreach ($upgrade_files as $file) { $wp_filesystem->delete($upgrade_folder . $file['name'], true); } } //We need a working directory $working_dir = $upgrade_folder . basename($package, '.crypt'); # $working_dir_localpath = WP_CONTENT_DIR.'/upgrade/'. basename($package, '.crypt'); // Clean up working directory if ($wp_filesystem->is_dir($working_dir)) { $wp_filesystem->delete($working_dir, true); } if (!$wp_filesystem->mkdir($working_dir, octdec($this->calculate_additive_chmod_oct(FS_CHMOD_DIR, 0775)))) { return new WP_Error('mkdir_failed', __('Failed to create a temporary directory', 'updraftplus') . ' (' . $working_dir . ')'); } // Unpack package to working directory if ($updraftplus->is_db_encrypted($package)) { $this->skin->feedback('decrypt_database'); $encryption = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase'); if (!$encryption) { return new WP_Error('no_encryption_key', __('Decryption failed. The database file is encrypted, but you have no encryption key entered.', 'updraftplus')); } $plaintext = $updraftplus->decrypt(false, $encryption, $wp_filesystem->get_contents($backup_dir . $package)); if ($plaintext) { $this->skin->feedback('decrypted_database'); if (!$wp_filesystem->put_contents($working_dir . '/backup.db.gz', $plaintext)) { return new WP_Error('write_failed', __('Failed to write out the decrypted database to the filesystem', 'updraftplus')); } } else { return new WP_Error('decryption_failed', __('Decryption failed. The most likely cause is that you used the wrong key.', 'updraftplus')); } } else { if (!$wp_filesystem->copy($backup_dir . $package, $working_dir . '/backup.db.gz')) { if ($wp_filesystem->errors->get_error_code()) { foreach ($wp_filesystem->errors->get_error_messages() as $message) { show_message($message); } } return new WP_Error('copy_failed', $this->strings['copy_failed']); } } // Once extracted, delete the package if required (non-recursive, is a file) if ($delete_package) { $wp_filesystem->delete($backup_dir . $package, false, true); } return $working_dir; }
public function options_printpage() { if (!UpdraftPlus_Options::user_can_manage()) { wp_die(__('You do not have sufficient permissions to access this page.')); } $options = $this->options->get_option(UDADDONS2_SLUG . '_options'); $user_and_pass_at_top = empty($options['email']) ? true : false; $title = htmlspecialchars($this->title); $mother = $this->mother; echo <<<ENDHERE \t<div class="wrap"> \t\t ENDHERE; $enter_credentials_begin = UpdraftPlus_Options::options_form_begin('', false); if (is_multisite()) { $enter_credentials_begin .= '<input type="hidden" name="action" value="update">'; } $interested = htmlspecialchars(__('Interested in knowing about your UpdraftPlus.Com password security? Read about it here.', 'updraftplus')); $connect = htmlspecialchars(__('Connect', 'updraftplus')); $enter_credentials_end = <<<ENDHERE \t\t\t<p style="margin-left: 258px;"> \t\t\t\t<input id="ud_connectsubmit" type="submit" class="button-primary" value="{$connect}" /> \t\t\t</p> \t\t\t<p style="margin-left: 258px; font-size: 70%"><em><a href="http://updraftplus.com/faqs/tell-me-about-my-updraftplus-com-account/">{$interested}</a></em></p> \t\t</form> ENDHERE; global $updraftplus_addons2; // $this->connected = (!empty($options['email']) && !empty($options['password'])) ? $updraftplus_addons2->connection_status() : false; $this->connected = !empty($options['email']) ? $updraftplus_addons2->connection_status() : false; if (true !== $this->connected) { if (is_wp_error($this->connected)) { $connection_errors = array(); foreach ($this->connected->get_error_messages() as $key => $msg) { $connection_errors[] = $msg; } } else { if (!empty($options['email']) && !empty($options['password'])) { $connection_errors = array(__('An unknown error occurred when trying to connect to UpdraftPlus.Com', 'updraftplus')); } } $this->connected = false; } if ($this->connected) { echo '<p style="clear: both; float: left;">' . __('You are presently <strong>connected</strong> to an UpdraftPlus.Com account.', 'updraftplus'); echo ' <a href="#" onclick="jQuery(\'#ud_connectsubmit\').click();">' . __('If you bought new add-ons, then follow this link to refresh your connection', 'updraftplus') . '</a>.'; if (!empty($options['password'])) { echo ' ' . __("Note that after you have claimed your add-ons, you can remove your password (but not the email address) from the settings below, without affecting this site's access to updates.", 'updraftplus'); } } else { // $oval = is_object($this->plug_updatechecker) ? get_site_option($this->plug_updatechecker->optionName, null) : null; // // Detect the case where the password has been removed // if (is_object($oval) && !empty($oval->lastCheck) && time()-$oval->lastCheck < 86400*8) { // } else { echo "<p>" . __('You are presently <strong>not connected</strong> to an UpdraftPlus.Com account.', 'updraftplus'); // } } echo '</p>'; if (isset($connection_errors)) { echo '<div class="error"><p><strong>' . __('Errors occurred when trying to connect to UpdraftPlus.Com:', 'updraftplus') . '</strong></p><ul>'; foreach ($connection_errors as $err) { echo '<li style="list-style:disc inside;">' . $err . '</li>'; } echo '</ul></div>'; } global $updraftplus_addons2; $sid = $updraftplus_addons2->siteid(); $home_url = home_url(); // Enumerate possible unclaimed/re-claimable purchases, and what should be active on this site $unclaimed_available = array(); $assigned = array(); $have_all = false; if ($this->connected && isset($updraftplus_addons2->user_addons) && is_array($updraftplus_addons2->user_addons)) { foreach ($updraftplus_addons2->user_addons as $akey => $addon) { // Keys: site, sitedescription, key, status if (isset($addon['status']) && 'active' == $addon['status'] && isset($addon['site']) && ('unclaimed' == $addon['site'] || 'unlimited' == $addon['site'])) { $key = $addon['key']; $unclaimed_available[$key] = array('eid' => $akey, 'status' => 'available'); } elseif (isset($addon['status']) && 'active' == $addon['status'] && isset($addon['site']) && $addon['site'] == $sid) { $key = $addon['key']; $assigned[$key] = $akey; if ('all' == $key) { $have_all = true; } } elseif (isset($addon['sitedescription']) && ($home_url === $addon['sitedescription'] || 0 === strpos($addon['sitedescription'], $home_url . ' - '))) { # Is assigned to a site with the same URL as this one - allow a reclaim $key = $addon['key']; $unclaimed_available[$key] = array('eid' => $akey, 'status' => 'reclaimable'); } } } if (!$this->connected) { $this->show_credentials_form($enter_credentials_begin, $enter_credentials_end); } $email = isset($options['email']) ? $options['email'] : ''; $pass = isset($options['password']) ? base64_encode($options['password']) : ''; $sn = base64_encode(get_bloginfo('name')); $su = base64_encode($home_url); $ourpageslug = UDADDONS2_PAGESLUG; $mother = $this->mother; //$href = (is_multisite()) ? 'settings.php' : 'options-general.php'; $href = UpdraftPlus_Options::admin_page_url(); if (count($unclaimed_available) > 0) { $nonce = wp_create_nonce('udmanager-nonce'); $pleasewait = htmlspecialchars(__('Please wait whilst we make the claim...', 'updraftplus')); $notgranted = esc_js(__('Claim not granted - perhaps you have already used this purchase somewhere else?', 'updraftplus')); $notgrantedlogin = esc_js(__('Claim not granted - your account login details were wrong', 'updraftplus')); $ukresponse = esc_js(__('An unknown response was received. Response was:', 'updraftplus')); echo <<<ENDHERE \t\t<div id="udm_pleasewait" class="updated" style="border: 1px solid; padding: 10px; margin-top: 10px; margin-bottom: 10px; clear: both; float: left; display:none;"><strong>{$pleasewait}</strong></div> \t\t<script type="text/javascript"> \t\t\tfunction udm_claim(key) { \t\t\t\tvar data = { \t\t\t\t\t\taction: 'udaddons_claimaddon', \t\t\t\t\t\tnonce: '{$nonce}', \t\t\t\t\t\tkey: key \t\t\t\t}; \t\t\t\tjQuery('#udm_pleasewait').fadeIn(); \t\t\t\tjQuery.post(ajaxurl, data, function(response) { \t\t\t\t\tif ('ERR' == response) { \t\t\t\t\t\talert("{$notgranted}"); \t\t\t\t\t} else if (response == 'OK') { \t\t\t\t\t\twindow.location.href = '{$href}?page={$ourpageslug}&udm_refresh=1&udm_clearcred=1&tab=addons'; \t\t\t\t\t} else if (response == 'BADAUTH') { \t\t\t\t\t\talert("{$notgrantedlogin}"); \t\t\t\t\t} else { \t\t\t\t\t\talert("{$ukresponse} "+response); \t\t\t\t\t} \t\t\t\t\tjQuery('#udm_pleasewait').fadeOut(); \t\t\t\t}); \t\t\t} \t\t</script> ENDHERE; } $this->update_js = ''; echo '<h3 style="clear:left; margin-top: 10px;">' . __('UpdraftPlus Addons', 'updraftplus') . '</h3><div>'; $addons = $updraftplus_addons2->get_available_addons(); $this->plugin_update_url = 'update-core.php'; # Can we get a direct update URL? $updates_available = get_site_transient('update_plugins'); if (is_object($updates_available) && isset($updates_available->response) && isset($updraftplus_addons2->plug_updatechecker) && isset($updraftplus_addons2->plug_updatechecker->pluginFile) && isset($updates_available->response[$updraftplus_addons2->plug_updatechecker->pluginFile])) { $file = $updraftplus_addons2->plug_updatechecker->pluginFile; $this->plugin_update_url = wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&updraftplus_noautobackup=1&plugin=') . $file, 'upgrade-plugin_' . $file); $this->update_js = '<script>jQuery(document).ready(function() { jQuery(\'#updraftaddons_updatewarning\').html(\'' . __('An update containing your addons is available for UpdraftPlus - please follow this link to get it.', 'updraftplus') . '\') });</script>'; } $first = ''; $second = ''; $third = ''; if (is_array($addons)) { foreach ($addons as $key => $addon) { extract($addon); if (empty($addon['latestversion'])) { $latestversion = false; } if (empty($addon['installedversion'])) { $installedversion = false; } if (empty($addon['installed']) && $installedversion == false) { $installed = false; } $unclaimed = isset($unclaimed_available[$key]) ? $unclaimed_available[$key] : false; $is_assigned = isset($assigned[$key]) ? $assigned[$key] : false; $box = $this->addonbox($key, $name, $shopurl, $description, trim($installedversion), trim($latestversion), $installed, $unclaimed, $is_assigned, $have_all); if ($is_assigned) { $first .= $box; } elseif (!empty($unclaimed)) { $second .= $box; } else { $third .= $box; } } } else { echo "<em>" . __('An error occurred when trying to retrieve your add-ons.', 'updraftplus') . "</em>"; } echo $first . $second . $third; echo <<<ENDHERE \t\t</div> ENDHERE; echo $this->update_js; // TODO: Show their support package, if any - ? if (is_array($updraftplus_addons2->user_support)) { // Keys: } echo '<h3>' . __('UpdraftPlus Support', 'updraftplus') . '</h3> <ul> <li style="list-style:disc inside;">' . __('Need to get support?', 'updraftplus') . ' <a href="' . $mother . '/support/">' . __('Go here', 'updraftplus') . "</a>.</li>\n</ul>"; if ($this->connected) { echo "<hr>"; $this->show_credentials_form($enter_credentials_begin, $enter_credentials_end); } echo '</div>'; }
public function save_settings($settings) { global $updraftplus; // Make sure that settings filters are registered UpdraftPlus_Options::admin_init(); $return_array = array('saved' => true, 'changed' => array()); $add_to_post_keys = array('updraft_interval', 'updraft_interval_database', 'updraft_starttime_files', 'updraft_starttime_db', 'updraft_startday_files', 'updraft_startday_db'); //If database and files are on same schedule, override the db day/time settings if (isset($settings['updraft_interval_database']) && isset($settings['updraft_interval_database']) && $settings['updraft_interval_database'] == $settings['updraft_interval'] && isset($settings['updraft_starttime_files'])) { $settings['updraft_starttime_db'] = $settings['updraft_starttime_files']; $settings['updraft_startday_db'] = $settings['updraft_startday_files']; } foreach ($add_to_post_keys as $key) { // For add-ons that look at $_POST to find saved settings, add the relevant keys to $_POST so that they find them there if (isset($settings[$key])) { $_POST[$key] = $settings[$key]; } } // Wipe the extra retention rules, as they are not saved correctly if the last one is deleted UpdraftPlus_Options::update_updraft_option('updraft_retain_extrarules', array()); UpdraftPlus_Options::update_updraft_option('updraft_email', array()); UpdraftPlus_Options::update_updraft_option('updraft_report_warningsonly', array()); UpdraftPlus_Options::update_updraft_option('updraft_report_wholebackup', array()); UpdraftPlus_Options::update_updraft_option('updraft_extradbs', array()); UpdraftPlus_Options::update_updraft_option('updraft_include_more_path', array()); $relevant_keys = $updraftplus->get_settings_keys(); if (method_exists('UpdraftPlus_Options', 'mass_options_update')) { $settings = UpdraftPlus_Options::mass_options_update($settings); $mass_updated = true; } foreach ($settings as $key => $value) { // $exclude_keys = array('option_page', 'action', '_wpnonce', '_wp_http_referer'); // if (!in_array($key, $exclude_keys)) { if (in_array($key, $relevant_keys)) { if ($key == "updraft_service" && is_array($value)) { foreach ($value as $subkey => $subvalue) { if ($subvalue == '0') { unset($value[$subkey]); } } } $updated = empty($mass_updated) ? UpdraftPlus_Options::update_updraft_option($key, $value) : true; // Add information on what has changed to array to loop through to update links etc. if ($updated) { $return_array['changed'][$key] = $value; } elseif (empty($mass_updated) && $key == 'updraft_interval') { //To schedule a database when the interval is not changed. $updraftplus->schedule_backup($value); } elseif (empty($mass_updated) && $key == 'updraft_interval_database') { $updraftplus->schedule_backup_database($value); } } else { // When last active, it was catching: option_page, action, _wpnonce, _wp_http_referer, updraft_s3_endpoint, updraft_dreamobjects_endpoint. The latter two are empty; probably don't need to be in the page at all. //error_log("Non-UD key when saving from POSTed data: ".$key); } } // Checking for various possible messages $updraft_dir = $updraftplus->backups_dir_location(false); $really_is_writable = $updraftplus->really_is_writable($updraft_dir); $dir_info = $this->really_writable_message($really_is_writable, $updraft_dir); $button_title = esc_attr(__('This button is disabled because your backup directory is not writable (see the settings).', 'updraftplus')); $return_array['backup_now_message'] = $this->backup_now_remote_message(); $return_array['backup_dir'] = array('writable' => $really_is_writable, 'message' => $dir_info, 'button_title' => $button_title); //Because of the single AJAX call, we need to remove the existing UD messages from the 'all_admin_notices' action remove_all_actions('all_admin_notices'); //Moving from 2 to 1 ajax call ob_start(); $service = UpdraftPlus_Options::get_updraft_option('updraft_service'); $this->setup_all_admin_notices_global($service); $this->setup_all_admin_notices_udonly($service); do_action('all_admin_notices'); if (!$really_is_writable) { //Check if writable $this->show_admin_warning_unwritable(); } if ($return_array['saved'] == true) { // $this->show_admin_warning(__('Your settings have been saved.', 'updraftplus'), 'updated fade'); } $messages_output = ob_get_contents(); ob_clean(); // Backup schedule output $this->next_scheduled_backups_output(); $scheduled_output = ob_get_clean(); $return_array['messages'] = $messages_output; $return_array['scheduled'] = $scheduled_output; return $return_array; }
public function backup_wpcore_dirlist($whichdir, $logit = false) { // Need to properly analyse the plugins, themes, uploads, content paths in order to strip them out (they may have various non-default manual values) global $updraftplus; if (false !== ($wpcore_dirlist = apply_filters('updraftplus_dirlist_wpcore_override', false, $whichdir))) { return $wpcore_dirlist; } $possible_backups = $updraftplus->get_backupable_file_entities(false); # We don't want to exclude the very thing we are backing up unset($possible_backups['wpcore']); # We do want to exclude everything in wp-content $possible_backups['wp-content'] = WP_CONTENT_DIR; foreach ($possible_backups as $key => $dir) { if (is_array($dir)) { foreach ($dir as $ind => $rdir) { if (!empty($rdir)) { $possible_backups_dirs[$rdir] = $key . $ind; } } } else { if (!empty($dir)) { $possible_backups_dirs[$dir] = $key; } } } # Create an array of directories to be skipped $exclude = UpdraftPlus_Options::get_updraft_option('updraft_include_wpcore_exclude', ''); if ($logit) { $updraftplus->log("Exclusion option setting (wpcore): " . $exclude); } # Make the values into the keys $wpcore_skip = array_flip(preg_split("/,/", $exclude)); $wpcore_skip['wp_content'] = 0; // Removing the slash is important (though ought to be redundant by here); otherwise path matching does not work $wpcore_dirlist = $updraftplus->compile_folder_list_for_backup(untrailingslashit($whichdir), $possible_backups_dirs, $wpcore_skip); // This is not required to be a perfect test. The point is to make sure we do get WP core. // Not using this approach for now. // if (true == apply_filters('updraftplus_backup_wpcore_dirlist_strict', false)) { // $wpcore_valid = array('wp-admin', 'wp-includes', 'index.php', 'xmlrpc.php'); // foreach ($wpcore_dirlist as $dir) { // // } // } return $wpcore_dirlist; }
private function vault_connect($email, $password) { // Username and password set up? if (empty($email) || empty($password)) { return new WP_Error('blank_details', __('You need to supply both an email address and a password', 'updraftplus')); } global $updraftplus; // Use SSL to prevent snooping $result = wp_remote_post($this->vault_mothership . '/?udm_action=vault_connect', array('timeout' => 20, 'body' => array('e' => $email, 'p' => base64_encode($password), 'sid' => $updraftplus->siteid(), 'su' => base64_encode(home_url())))); if (is_wp_error($result) || false === $result) { return $result; } $response = json_decode($result['body'], true); if (!is_array($response) || !isset($response['mothership']) || !isset($response['loggedin'])) { if (preg_match('/has banned your IP address \\(([\\.:0-9a-f]+)\\)/', $result['body'], $matches)) { return new WP_Error('banned_ip', sprintf(__("UpdraftPlus.com has responded with 'Access Denied'.", 'updraftplus') . '<br>' . __("It appears that your web server's IP Address (%s) is blocked.", 'updraftplus') . ' ' . __('This most likely means that you share a webserver with a hacked website that has been used in previous attacks.', 'updraftplus') . '<br> <a href="https://updraftplus.com/unblock-ip-address/" target="_blank">' . __('To remove the block, please go here.', 'updraftplus') . '</a> ', $matches[1])); } else { return new WP_Error('unknown_response', sprintf(__('UpdraftPlus.Com returned a response which we could not understand (data: %s)', 'updraftplus'), $result['body'])); } } switch ($response['loggedin']) { case 'connected': if (!empty($response['token'])) { // Store it $vault_settings = UpdraftPlus_Options::get_updraft_option('updraft_updraftvault'); if (!is_array($vault_settings)) { $vault_settings = array(); } $vault_settings['email'] = $email; $vault_settings['token'] = (string) $response['token']; $vault_settings['quota'] = -1; unset($vault_settings['last_config']); if (isset($response['quota'])) { $vault_settings['quota'] = $response['quota']; } UpdraftPlus_Options::update_updraft_option('updraft_updraftvault', $vault_settings); if (!empty($response['config']) && is_array($response['config']) && !empty($response['config']['accesskey'])) { $this->vault_set_config($response['config']); } } elseif (isset($response['quota']) && !$response['quota']) { return new WP_Error('no_quota', __('You do not currently have any UpdraftPlus Vault quota', 'updraftplus')); } else { return new WP_Error('unknown_response', __('UpdraftPlus.Com returned a response, but we could not understand it', 'updraftplus')); } break; case 'authfailed': if (!empty($response['authproblem'])) { if ('invalidpassword' == $response['authproblem']) { $authfail_error = new WP_Error('authfailed', __('Your email address was valid, but your password was not recognised by UpdraftPlus.Com.', 'updraftplus') . ' <a href="https://updraftplus.com/my-account/lost-password/">' . __('If you have forgotten your password, then go here to change your password on updraftplus.com.', 'updraftplus') . '</a>'); return $authfail_error; } elseif ('invaliduser' == $response['authproblem']) { return new WP_Error('authfailed', __('You entered an email address that was not recognised by UpdraftPlus.Com', 'updraftplus')); } } return new WP_Error('authfailed', __('Your email address and password were not recognised by UpdraftPlus.Com', 'updraftplus')); break; default: return new WP_Error('unknown_response', __('UpdraftPlus.Com returned a response, but we could not understand it', 'updraftplus')); break; } return true; }
private 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 '<p>' . __('This backup does not exist in the backup history - restoration aborted. Timestamp:', 'updraftplus') . " {$timestamp}</p><br/>"; 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()) { echo '<p><em><a href="http://updraftplus.com/faqs/asked-ftp-details-upon-restorationmigration-updates/">' . __('Why am I seeing this?', 'updraftplus') . '</a></em></p>'; 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 '<p><a target="_new" href="?action=downloadlog&page=updraftplus&updraftplus_backup_nonce='.htmlspecialchars($updraftplus->nonce).'">'.__('Follow this link to download the log file for this restoration.', 'updraftplus').'</a></p>'; # 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 '<h1>' . __('UpdraftPlus Restoration: Progress', 'updraftplus') . '</h1><div id="updraft-restore-progress">'; $this->show_admin_warning('<a target="_new" href="?action=downloadlog&page=updraftplus&updraftplus_backup_nonce=' . htmlspecialchars($updraftplus->nonce) . '">' . __('Follow this link to download the log file for this restoration (needed for any support requests).', 'updraftplus') . '</a>'); $updraft_dir = trailingslashit($updraftplus->backups_dir_location()); $foreign_known = apply_filters('updraftplus_accept_archivename', array()); $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_<entity> 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(); } $backup_set = $backup_history[$timestamp]; $entities_to_restore = array(); foreach ($_POST['updraft_restore'] as $entity) { if (empty($backup_set['meta_foreign'])) { $entities_to_restore[$entity] = $entity; } else { if ('db' == $entity && !empty($foreign_known[$backup_set['meta_foreign']]) && !empty($foreign_known[$backup_set['meta_foreign']]['separatedb'])) { $entities_to_restore[$entity] = 'db'; } else { $entities_to_restore[$entity] = 'wpcore'; } } } foreach ($_POST as $key => $value) { if (0 === strpos($key, 'updraft_restore_')) { $nkey = substr($key, 16); if (!isset($entities_to_restore[$nkey])) { $_POST['updraft_restore'][] = $nkey; if (empty($backup_set['meta_foreign'])) { $entities_to_restore[$nkey] = $nkey; } else { if ('db' == $entity && !empty($foreign_known[$backup_set['meta_foreign']]['separatedb'])) { $entities_to_restore[$nkey] = 'db'; } else { $entities_to_restore[$nkey] = 'wpcore'; } } } } } if (0 == count($_POST['updraft_restore'])) { echo '<p>' . __('ABORT: Could not find the information on which entities to restore.', 'updraftplus') . '</p>'; echo '<p>' . __('If making a request for support, please include this information:', 'updraftplus') . ' ' . count($_POST) . ' : ' . htmlspecialchars(serialize($_POST)) . '</p>'; return new WP_Error('missing_info', 'Backup information not found'); } $updraftplus->log("Restore job started. Entities to restore: " . implode(', ', array_flip($entities_to_restore))); $this->entities_to_restore = $entities_to_restore; 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); 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(), $backup_set); $second_loop = array(); echo "<h2>" . __('Final checks', 'updraftplus') . '</h2>'; if (empty($backup_set['meta_foreign'])) { $entities_to_download = $entities_to_restore; } else { if (!empty($foreign_known[$backup_set['meta_foreign']]['separatedb'])) { $entities_to_download = array(); if (in_array('db', $entities_to_restore)) { $entities_to_download['db'] = 1; } if (count($entities_to_restore) > 1 || !in_array('db', $entities_to_restore)) { $entities_to_download['wpcore'] = 1; } } else { $entities_to_download = array('wpcore' => 1); } } // 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_download[$type])) { continue; } if ('wpcore' == $type && is_multisite() && 0 === $updraftplus_restorer->ud_backup_is_multisite) { echo "<p>{$type}: <strong>"; 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 "</strong></p>"; 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)) . "<br>"; add_action('http_request_args', array($updraftplus, 'modify_http_options')); 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 '<br>'; } } remove_action('http_request_args', array($updraftplus, 'modify_http_options')); $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') . '<br>'; } else { echo "<strong>" . __('Error:', 'updraftplus') . "</strong> " . __('file is size:', 'updraftplus') . " " . round($as / 1024) . " ({$fs}, {$as})<br>"; } } else { echo __("The backup records do not contain information about the proper size of this file.", 'updraftplus') . "<br>"; } if (!is_readable($fullpath)) { echo __('Could not find one of the files for restoration', 'updraftplus') . " ({$file})<br>"; $updraftplus->log("{$file}: " . __('Could not find one of the files for restoration', 'updraftplus'), 'error'); echo '</div>'; restore_error_handler(); return false; } } if (empty($updraftplus_restorer->ud_foreign)) { $types = array($type); } else { if ('db' != $type || empty($foreign_known[$updraftplus_restorer->ud_foreign]['separatedb'])) { $types = array('wpcore'); } else { $types = array('db'); } } foreach ($types as $check_type) { $info = isset($backupable_entities[$check_type]) ? $backupable_entities[$check_type] : array(); $val = $updraftplus_restorer->pre_restore_backup($files, $check_type, $info); if (is_wp_error($val)) { $updraftplus->log_wp_error($val); foreach ($val->get_error_messages() as $msg) { echo '<strong>' . __('Error:', 'updraftplus') . '</strong> ' . htmlspecialchars($msg) . '<br>'; } foreach ($val->get_error_codes() as $code) { if ('already_exists' == $code) { $this->print_delete_old_dirs_form(false); } } echo '</div>'; //close the updraft_restore_progress div even if we error restore_error_handler(); return $val; } elseif (false === $val) { echo '</div>'; //close the updraft_restore_progress div even if we error restore_error_handler(); return false; } } foreach ($entities_to_restore as $entity => $via) { if ($via == $type) { $second_loop[$entity] = $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)) || !empty($updraftplus_restorer->ud_foreign)) { 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; } if (!empty($updraftplus_restorer->ud_foreign)) { $updraftplus->log("Foreign backup; created by: " . $updraftplus_restorer->ud_foreign); } // 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 ? "<h2>" . __('Database', 'updraftplus') . "</h2>" : "<h2>" . $info['description'] . "</h2>"; $updraftplus->log("Entity: " . $type); if (is_string($files)) { $files = array($files); } foreach ($files as $fkey => $file) { $last_one = 1 == count($second_loop) && 1 == count($files); $val = $updraftplus_restorer->restore_backup($file, $type, $info, $last_one); if (is_wp_error($val)) { $updraftplus->log_e($val); foreach ($val->get_error_messages() as $msg) { echo '<strong>' . __('Error message', 'updraftplus') . ':</strong> ' . htmlspecialchars($msg) . '<br>'; } $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 '<strong>' . __('Error data:', 'updraftplus') . '</strong> ' . htmlspecialchars($pdata) . '<br>'; if (false !== strpos($pdata, 'PCLZIP_ERR_BAD_FORMAT (-10)')) { echo '<a href="http://updraftplus.com/faqs/error-message-pclzip_err_bad_format-10-invalid-archive-structure-mean/"><strong>' . __('Please consult this FAQ for help on what to do about it.', 'updraftplus') . '</strong></a><br>'; } } } } echo '</div>'; //close the updraft_restore_progress div even if we error restore_error_handler(); return $val; } elseif (false === $val) { echo '</div>'; //close the updraft_restore_progress div even if we error restore_error_handler(); return false; } unset($files[$fkey]); } unset($second_loop[$type]); } foreach (array('template', 'stylesheet', 'template_root', 'stylesheet_root') as $opt) { add_filter('pre_option_' . $opt, array($this, 'option_filter_' . $opt)); } # Clear any cached pages after the restore $updraftplus_restorer->clear_cache(); if (!function_exists('validate_current_theme')) { require_once ABSPATH . WPINC . '/themes'; } # Have seen a case where the current theme in the DB began with a capital, but not on disk - and this breaks migrating from Windows to a case-sensitive system $template = get_option('template'); if (!empty($template) && $template != WP_DEFAULT_THEME && $template != strtolower($template)) { $theme_root = get_theme_root($template); $theme_root2 = get_theme_root(strtolower($template)); if (!file_exists("{$theme_root}/{$template}/style.css") && file_exists("{$theme_root}/" . strtolower($template) . "/style.css")) { $updraftplus->log_e("Theme directory (%s) not found, but lower-case version exists; updating database option accordingly", $template); update_option('template', strtolower($template)); } } if (!validate_current_theme()) { global $updraftplus; echo '<strong>'; $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 '</strong>'; } #foreach (array('template', 'stylesheet', 'template_root', 'stylesheet_root') as $opt) { # remove_filter('pre_option_'.$opt, array($this, 'option_filter_'.$opt)); #} echo '</div>'; //close the updraft_restore_progress div restore_error_handler(); return true; }
public function config_print() { $opts = $this->get_opts(); ?> <tr class="updraftplusmethod googledrive"> <td></td> <td> <img src="https://developers.google.com/drive/images/drive_logo.png" alt="<?php _e('Google Drive', 'updraftplus'); ?> "> <p><em><?php printf(__('%s is a great choice, because UpdraftPlus supports chunked uploads - no matter how big your site is, UpdraftPlus can upload it a little at a time, and not get thwarted by timeouts.', 'updraftplus'), 'Google Drive'); ?> </em></p> </td> </tr> <tr class="updraftplusmethod googledrive"> <th></th> <td> <?php $admin_page_url = UpdraftPlus_Options::admin_page_url(); # This is advisory - so the fact it doesn't match IPv6 addresses isn't important if (preg_match('#^(https?://(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))/#', $admin_page_url, $matches)) { echo '<p><strong>' . htmlspecialchars(sprintf(__("%s does not allow authorisation of sites hosted on direct IP addresses. You will need to change your site's address (%s) before you can use %s for storage.", 'updraftplus'), __('Google Drive', 'updraftplus'), $matches[1], __('Google Drive', 'updraftplus'))) . '</strong></p>'; } else { ?> <p><a href="https://updraftplus.com/support/configuring-google-drive-api-access-in-updraftplus/"><strong><?php _e('For longer help, including screenshots, follow this link. The description below is sufficient for more expert users.', 'updraftplus'); ?> </strong></a></p> <p><a href="https://console.developers.google.com"><?php _e('Follow this link to your Google API Console, and there activate the Drive API and create a Client ID in the API Access section.', 'updraftplus'); ?> </a> <?php _e("Select 'Web Application' as the application type.", 'updraftplus'); ?> </p><p><?php echo htmlspecialchars(__('You must add the following as the authorised redirect URI (under "More Options") when asked', 'updraftplus')); ?> : <kbd><?php echo UpdraftPlus_Options::admin_page_url() . '?action=updraftmethod-googledrive-auth'; ?> </kbd> <?php _e('N.B. If you install UpdraftPlus on several WordPress sites, then you cannot re-use your project; you must create a new one from your Google API console for each site.', 'updraftplus'); ?> </p> <?php } ?> </td> </tr> <tr class="updraftplusmethod googledrive"> <th><?php echo __('Google Drive', 'updraftplus') . ' ' . __('Client ID', 'updraftplus'); ?> :</th> <td><input type="text" autocomplete="off" style="width:442px" name="updraft_googledrive[clientid]" value="<?php echo htmlspecialchars($opts['clientid']); ?> " /><br><em><?php _e('If Google later shows you the message "invalid_client", then you did not enter a valid client ID here.', 'updraftplus'); ?> </em></td> </tr> <tr class="updraftplusmethod googledrive"> <th><?php echo __('Google Drive', 'updraftplus') . ' ' . __('Client Secret', 'updraftplus'); ?> :</th> <td><input type="<?php echo apply_filters('updraftplus_admin_secret_field_type', 'password'); ?> " style="width:442px" name="updraft_googledrive[secret]" value="<?php echo htmlspecialchars($opts['secret']); ?> " /></td> </tr> <?php # Legacy configuration if (isset($opts['parentid'])) { $parentid = is_array($opts['parentid']) ? $opts['parentid']['id'] : $opts['parentid']; $showparent = is_array($opts['parentid']) && !empty($opts['parentid']['name']) ? $opts['parentid']['name'] : $parentid; $folder_opts = '<tr class="updraftplusmethod googledrive"> <th>' . __('Google Drive', 'updraftplus') . ' ' . __('Folder', 'updraftplus') . ':</th> <td><input type="hidden" name="updraft_googledrive[parentid][id]" value="' . htmlspecialchars($parentid) . '"> <input type="text" title="' . esc_attr($parentid) . '" readonly="readonly" style="width:442px" value="' . htmlspecialchars($showparent) . '">'; if (!empty($parentid) && (!is_array($opts['parentid']) || empty($opts['parentid']['name']))) { $folder_opts .= '<em>' . __("<strong>This is NOT a folder name</strong>.", 'updraftplus') . ' ' . __('It is an ID number internal to Google Drive', 'updraftplus') . '</em>'; } else { $folder_opts .= '<input type="hidden" name="updraft_googledrive[parentid][name]" value="' . htmlspecialchars($opts['parentid']['name']) . '">'; } } else { $folder_opts = '<tr class="updraftplusmethod googledrive"> <th>' . __('Google Drive', 'updraftplus') . ' ' . __('Folder', 'updraftplus') . ':</th> <td><input type="text" readonly="readonly" style="width:442px" name="updraft_googledrive[folder]" value="UpdraftPlus" />'; } $folder_opts .= '<br><em><a href="https://updraftplus.com/shop/updraftplus-premium/">' . __('To be able to set a custom folder name, use UpdraftPlus Premium.', 'updraftplus') . '</em></a>'; $folder_opts .= '</td></tr>'; echo apply_filters('updraftplus_options_googledrive_others', $folder_opts, $opts); ?> <tr class="updraftplusmethod googledrive"> <th><?php _e('Authenticate with Google'); ?> :</th> <td><p><?php if (!empty($opts['token'])) { echo __("<strong>(You appear to be already authenticated,</strong> though you can authenticate again to refresh your access if you've had a problem).", 'updraftplus'); } ?> <?php if (!empty($opts['token']) && !empty($opts['ownername'])) { echo '<br>' . sprintf(__("Account holder's name: %s.", 'updraftplus'), htmlspecialchars($opts['ownername'])) . ' '; } ?> </p> <p> <a href="<?php echo UpdraftPlus_Options::admin_page_url(); ?> ?action=updraftmethod-googledrive-auth&page=updraftplus&updraftplus_googleauth=doit"><?php print __('<strong>After</strong> you have saved your settings (by clicking \'Save Changes\' below), then come back here once and click this link to complete authentication with Google.', 'updraftplus'); ?> </a> </p> </td> </tr> <?php }
public function analyse_db_file($timestamp, $res, $db_file = false, $header_only = false) { $mess = array(); $warn = array(); $err = array(); $info = array(); global $wp_version; include ABSPATH . WPINC . '/version.php'; $updraft_dir = $this->backups_dir_location(); if (false === $db_file) { # 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. $this->get_max_packet_size(); $backup = $this->get_backup_history($timestamp); if (!isset($backup['nonce']) || !isset($backup['db'])) { return array($mess, $warn, $err, $info); } $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, $info); } // Encrypted - decrypt it if ($this->is_db_encrypted($db_file)) { $encryption = empty($res['updraft_encryptionphrase']) ? UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase') : $res['updraft_encryptionphrase']; if (!$encryption) { if (class_exists('UpdraftPlus_Addon_MoreDatabase')) { $err[] = sprintf(__('Error: %s', 'updraftplus'), __('Decryption failed. The database file is encrypted, but you have no encryption key entered.', 'updraftplus')); } else { $err[] = sprintf(__('Error: %s', 'updraftplus'), __('Decryption failed. The database file is encrypted.', 'updraftplus')); } return array($mess, $warn, $err, $info); } $ciphertext = $this->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, $info); } $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, $info); } } # 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, $info); } $is_plain = '.gz' == substr($db_file, -3, 3) ? false : true; $dbhandle = $is_plain ? fopen($db_file, 'r') : $this->gzopen_for_read($db_file, $warn, $err); if (!is_resource($dbhandle)) { $err[] = __('Failed to open database file.', 'updraftplus'); return array($mess, $warn, $err, $info); } # Analyse the file, print the results. $line = 0; $old_siteurl = ''; $old_home = ''; $old_table_prefix = ''; $old_siteinfo = array(); $gathering_siteinfo = true; $old_wp_version = ''; $old_php_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 // Until April 2015, this was always 90. But we've seen a few people with ~1Gb databases (uncompressed), and 90s is not enough. Note that we don't bother checking here if it's compressed - having a too-large timeout when unexpected is harmless, as it won't be hit. On very large dbs, they're expecting it to take a while. // "120 or 240" is a first attempt at something more useful than just fixed at 90 - but should be sufficient (as 90 was for everyone without ~1Gb databases) $default_dbscan_timeout = filesize($db_file) < 31457280 ? 120 : 240; $dbscan_timeout = defined('UPDRAFTPLUS_DBSCAN_TIMEOUT') && is_numeric(UPDRAFTPLUS_DBSCAN_TIMEOUT) ? UPDRAFTPLUS_DBSCAN_TIMEOUT : $default_dbscan_timeout; @set_time_limit($dbscan_timeout); while (($is_plain && !feof($dbhandle) || !$is_plain && !gzeof($dbhandle)) && ($line < 100 || !$header_only && count($wanted_tables) > 0)) { $line++; // Up to 1Mb $buffer = $is_plain ? rtrim(fgets($dbhandle, 1048576)) : 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'), '<a href="https://updraftplus.com/shop/migrator/">' . __('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') . '</a>'), $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'), '<a href="https://updraftplus.com/shop/migrator/">' . __('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') . '</a>'), $old_home, $res); if (!empty($powarn)) { $warn[] = $powarn; } } } elseif ('' == $old_wp_version && preg_match('/^\\# WordPress Version: ([0-9]+(\\.[0-9]+)+)(-[-a-z0-9]+,)?(.*)$/', $buffer, $matches)) { $old_wp_version = $matches[1]; if (!empty($matches[3])) { $old_wp_version .= substr($matches[3], 0, strlen($matches[3]) - 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); } if (preg_match('/running on PHP ([0-9]+\\.[0-9]+)(\\s|\\.)/', $matches[4], $nmatches) && preg_match('/^([0-9]+\\.[0-9]+)(\\s|\\.)/', PHP_VERSION, $cmatches)) { $old_php_version = $nmatches[1]; $current_php_version = $cmatches[1]; if (version_compare($old_php_version, $current_php_version, '>')) { //$mess[] = sprintf(__('%s version: %s', 'updraftplus'), 'WordPress', $old_wp_version); $warn[] = sprintf(__('The site in this backup was running on a webserver with version %s of %s. ', 'updraftplus'), $old_php_version, 'PHP') . ' ' . sprintf(__('This is significantly newer than the server which you are now restoring onto (version %s).', 'updraftplus'), PHP_VERSION) . ' ' . sprintf(__('You should only proceed if you cannot update the current server and are confident (or willing to risk) that your plugins/themes/etc. are compatible with the older %s version.', 'updraftplus'), 'PHP') . ' ' . sprintf(__('Any support requests to do with %s should be raised with your web hosting company.', 'updraftplus'), 'PHP'); } } } elseif ('' == $old_table_prefix && (preg_match('/^\\# Table prefix: (\\S+)$/', $buffer, $matches) || preg_match('/^-- Table prefix: (\\S+)$/i', $buffer, $matches))) { $old_table_prefix = $matches[1]; // echo '<strong>'.__('Old table prefix:', 'updraftplus').'</strong> '.htmlspecialchars($old_table_prefix).'<br>'; } elseif (empty($info['label']) && preg_match('/^\\# Label: (.*)$/', $buffer, $matches)) { $info['label'] = $matches[1]; $mess[] = __('Backup label:', 'updraftplus') . ' ' . htmlspecialchars($info['label']); } 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, $info); } // 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, $info); } } elseif (isset($old_siteinfo['multisite']) && $old_siteinfo['multisite'] && !is_multisite()) { $warn[] = __('Warning:', 'updraftplus') . ' ' . __('Your backup is of a WordPress multisite install; but this site is not. Only the first site of the network will be accessible.', 'updraftplus') . ' <a href="http://codex.wordpress.org/Create_A_Network">' . __('If you want to restore a multisite backup, you should first set up your WordPress installation as a multisite.', 'updraftplus') . '</a>'; } } elseif (preg_match('/^([^=]+)=(.*)$/', $matches[1], $kvmatches)) { $key = $kvmatches[1]; $val = $kvmatches[2]; if ('multisite' == $key && $val) { $mess[] = '<strong>' . __('Site information:', 'updraftplus') . '</strong>' . ' 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 = $this->str_replace_once($old_table_prefix, '', $table); if (in_array($table, $wanted_tables)) { $wanted_tables = array_diff($wanted_tables, array($table)); } } } } if ($is_plain) { @fclose($dbhandle); } else { @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) { if (!$header_only) { 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 { if (empty($backup['meta_foreign'])) { $warn[] = __('UpdraftPlus was unable to find the table prefix when scanning the database backup.', 'updraftplus'); } } return array($mess, $warn, $err, $info); }
/** * Execute an API call * @todo Improve error handling * @param string $method The HTTP method * @param string $url The API endpoint * @param string $call The API method to call * @param array $additional Additional parameters * @return string|object stdClass */ public function fetch($method, $url, $call, array $additional = array()) { // Get the signed request URL $request = $this->getSignedRequest($method, $url, $call, $additional); // Initialise and execute a cURL request $handle = curl_init($request['url']); // Get the default options array $options = $this->defaultOptions; if (!UpdraftPlus_Options::get_updraft_option('updraft_ssl_useservercerts')) { $options[CURLOPT_CAINFO] = UPDRAFTPLUS_DIR . '/includes/cacert.pem'; } if (UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify')) { $options[CURLOPT_SSL_VERIFYPEER] = false; } else { $options[CURLOPT_SSL_VERIFYPEER] = true; } if ($method == 'GET' && $this->outFile) { // GET $options[CURLOPT_RETURNTRANSFER] = false; $options[CURLOPT_HEADER] = false; $options[CURLOPT_FILE] = $this->outFile; $options[CURLOPT_BINARYTRANSFER] = true; if (isset($additional['headers'])) { $options[CURLOPT_HTTPHEADER] = $additional['headers']; } $this->outFile = null; } elseif ($method == 'POST') { // POST $options[CURLOPT_POST] = true; $options[CURLOPT_POSTFIELDS] = $request['postfields']; } elseif ($method == 'PUT' && $this->inFile) { // PUT $options[CURLOPT_PUT] = true; $options[CURLOPT_INFILE] = $this->inFile; // @todo Update so the data is not loaded into memory to get its size $options[CURLOPT_INFILESIZE] = strlen(stream_get_contents($this->inFile)); fseek($this->inFile, 0); $this->inFile = null; } // Set the cURL options at once curl_setopt_array($handle, $options); // Execute, get any error and close $response = curl_exec($handle); $error = curl_error($handle); curl_close($handle); //Check if a cURL error has occured if ($response === false) { throw new Dropbox_CurlException($error); } else { // Parse the response if it is a string if (is_string($response)) { $response = $this->parse($response); } // Set the last response $this->lastResponse = $response; // The API doesn't return an error message for the 304 status code... // 304's are only returned when the path supplied during metadata calls has not been modified if ($response['code'] == 304) { $response['body'] = new \stdClass(); $response['body']->error = 'The folder contents have not changed'; } // Check if an error occurred and throw an Exception if (!empty($response['body']->error)) { // Dropbox returns error messages inconsistently... if ($response['body']->error instanceof \stdClass) { $array = array_values((array) $response['body']->error); $message = $array[0]; } else { $message = $response['body']->error; } // Throw an Exception with the appropriate with the appropriate message and code switch ($response['code']) { case 304: throw new Dropbox_NotModifiedException($message, 304); case 400: throw new Dropbox_BadRequestException($message, 400); case 404: throw new Dropbox_NotFoundException($message, 404); case 406: throw new Dropbox_NotAcceptableException($message, 406); case 415: throw new Dropbox_UnsupportedMediaTypeException($message, 415); default: throw new Dropbox_Exception($message, $response['code']); } } return $response; } }
public function bootstrap() { if (!empty($this->dropbox_object) && !is_wp_error($this->dropbox_object)) { return $this->dropbox_object; } require_once UPDRAFTPLUS_DIR . '/includes/Dropbox/API.php'; require_once UPDRAFTPLUS_DIR . '/includes/Dropbox/Exception.php'; require_once UPDRAFTPLUS_DIR . '/includes/Dropbox/OAuth/Consumer/ConsumerAbstract.php'; require_once UPDRAFTPLUS_DIR . '/includes/Dropbox/OAuth/Storage/StorageInterface.php'; require_once UPDRAFTPLUS_DIR . '/includes/Dropbox/OAuth/Storage/Encrypter.php'; require_once UPDRAFTPLUS_DIR . '/includes/Dropbox/OAuth/Storage/WordPress.php'; require_once UPDRAFTPLUS_DIR . '/includes/Dropbox/OAuth/Consumer/Curl.php'; // require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Consumer/WordPress.php'); $opts = $this->get_opts(); $key = empty($opts['secret']) ? '' : $opts['secret']; $sec = empty($opts['appkey']) ? '' : $opts['appkey']; // Set the callback URL $callback = UpdraftPlus_Options::admin_page_url() . '?page=updraftplus&action=updraftmethod-dropbox-auth'; // Instantiate the Encrypter and storage objects $encrypter = new Dropbox_Encrypter('ThisOneDoesNotMatterBeyondLength'); // Instantiate the storage $storage = new Dropbox_WordPress($encrypter, "tk_", 'updraft_dropbox'); // WordPress consumer does not yet work // $OAuth = new Dropbox_ConsumerWordPress($sec, $key, $storage, $callback); // Get the DropBox API access details list($d2, $d1) = $this->defaults(); if (empty($sec)) { $sec = base64_decode($d1); } if (empty($key)) { $key = base64_decode($d2); } $root = 'sandbox'; if ('dropbox:' == substr($sec, 0, 8)) { $sec = substr($sec, 8); $root = 'dropbox'; } try { $OAuth = new Dropbox_Curl($sec, $key, $storage, $callback); } catch (Exception $e) { global $updraftplus; $updraftplus->log("Dropbox Curl error: " . $e->getMessage()); $updraftplus->log(sprintf(__("%s error: %s", 'updraftplus'), "Dropbox/Curl", $e->getMessage()), 'error'); return false; } $this->dropbox_object = new UpdraftPlus_Dropbox_API($OAuth, $root); return $this->dropbox_object; }
<?php if (!defined('UPDRAFTPLUS_DIR')) { die('No direct access allowed.'); } # Converted to array options: yes # Converted to job_options: yes # Migrate options to new-style storage - May 2014 if (!is_array(UpdraftPlus_Options::get_updraft_option('updraft_ftp')) && '' != UpdraftPlus_Options::get_updraft_option('updraft_server_address', '')) { $opts = array('user' => UpdraftPlus_Options::get_updraft_option('updraft_ftp_login'), 'pass' => UpdraftPlus_Options::get_updraft_option('updraft_ftp_pass'), 'host' => UpdraftPlus_Options::get_updraft_option('updraft_server_address'), 'path' => UpdraftPlus_Options::get_updraft_option('updraft_ftp_remote_path'), 'passive' => true); UpdraftPlus_Options::update_updraft_option('updraft_ftp', $opts); UpdraftPlus_Options::delete_updraft_option('updraft_server_address'); UpdraftPlus_Options::delete_updraft_option('updraft_ftp_pass'); UpdraftPlus_Options::delete_updraft_option('updraft_ftp_remote_path'); UpdraftPlus_Options::delete_updraft_option('updraft_ftp_login'); } class UpdraftPlus_BackupModule_ftp { // Get FTP object with parameters set private function getFTP($server, $user, $pass, $disable_ssl = false, $disable_verify = true, $use_server_certs = false, $passive = true) { if ('' == trim($server) || '' == trim($user) || '' == trim($pass)) { return new WP_Error('no_settings', sprintf(__('No %s settings were found', 'updraftplus'), 'FTP')); } if (!class_exists('UpdraftPlus_ftp_wrapper')) { require_once UPDRAFTPLUS_DIR . '/includes/ftp.class.php'; } $port = 21; if (preg_match('/^(.*):(\\d+)$/', $server, $matches)) { $server = $matches[1]; $port = $matches[2];
function get_config() { return array('login' => UpdraftPlus_Options::get_updraft_option('updraft_s3generic_login'), 'pass' => UpdraftPlus_Options::get_updraft_option('updraft_s3generic_pass'), 'remote_path' => UpdraftPlus_Options::get_updraft_option('updraft_s3generic_remote_path'), 'whoweare' => 'S3', 'whoweare_long' => __('S3 (Compatible)', 'updraftplus'), 'key' => 's3generic', 'endpoint' => UpdraftPlus_Options::get_updraft_option('updraft_s3generic_endpoint')); }
private function list_our_keys($our_keys = false) { if (false === $our_keys) { $our_keys = UpdraftPlus_Options::get_updraft_option('updraft_migrator_localkeys'); } if (empty($our_keys)) { return '<em>' . __('No keys to allow remote sites to connect have yet been created.', 'updraftplus') . '</em>'; } $ret = ''; $first_one = true; foreach ($our_keys as $k => $key) { if (!is_array($key)) { continue; } if ($first_one) { $first_one = false; $ret .= '<p><strong>' . __('Existing keys', 'updraftplus') . '</strong><br>'; } $ret .= htmlspecialchars($key['name']); $ret .= ' - <a href="#" class="updraft_migrate_local_key_delete" data-keyid="' . esc_attr($k) . '">' . __('Delete', 'updraftplus') . '</a>'; $ret .= '<br>'; } if ($ret) { $ret .= '</p>'; } return $ret; }
public function admin_init() { if (empty($_POST['updraft_unlockadmin_session_length']) && empty($_POST['updraft_unlockadmin_password']) || empty($_POST['nonce'])) { return; } if (!wp_verify_nonce($_POST['nonce'], 'updraftplus-unlockadmin-nonce')) { return; } $user = wp_get_current_user(); if (!is_a($user, 'WP_User')) { return; } $this->get_opts(); if (!empty($_POST['updraft_unlockadmin_session_length']) && isset($_POST['updraft_unlockadmin_oldpassword']) && $_POST['updraft_unlockadmin_oldpassword'] == $this->opts['password']) { $this->old_password = $this->opts['password']; $this->opts['password'] = $_POST['updraft_unlockadmin_password']; $this->opts['support_url'] = $_POST['updraft_unlockadmin_support_url']; $this->opts['session_length'] = (int) $_POST['updraft_unlockadmin_session_length']; UpdraftPlus_Options::update_updraft_option('updraft_adminlocking', $this->opts); $this->password_length = strlen($this->opts['password']); add_action('all_admin_notices', array($this, 'show_admin_warning_passwordset')); } // Note: this code also fires when the user sets a new password (because we don't want to immediately lock them) $password = $this->opts['password']; if ($password === (string) $_POST['updraft_unlockadmin_password']) { $session_length = (int) $this->opts['session_length']; if ($session_length < 1) { $session_length = 86400; } // The cookie relies on the user ID, password and session time. So, someone stealing the cookie can't use it forever. They need the password to generate valid cookies. $time_now = time(); $expire = $time_now + $session_length; $cookie_session_began = $time_now - $time_now % $session_length; $correct_hash = hash('sha256', $user->ID . '-' . $password . '-' . $cookie_session_began); $secure = apply_filters('secure_auth_cookie', is_ssl(), $user->ID); setcookie('updraft_unlockadmin', $cookie_session_began . ':' . $correct_hash, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); $this->correct_password_supplied = true; } else { $this->correct_password_supplied = false; } }
<?php if (!defined('UPDRAFTPLUS_DIR')) { die('No direct access allowed.'); } require_once UPDRAFTPLUS_DIR . '/methods/s3.php'; # Migrate options to new-style storage - Jan 2014 if (!is_array(UpdraftPlus_Options::get_updraft_option('updraft_dreamobjects')) && '' != UpdraftPlus_Options::get_updraft_option('updraft_dreamobjects_login', '')) { $opts = array('accesskey' => UpdraftPlus_Options::get_updraft_option('updraft_dreamobjects_login'), 'secretkey' => UpdraftPlus_Options::get_updraft_option('updraft_dreamobjects_pass'), 'path' => UpdraftPlus_Options::get_updraft_option('updraft_dreamobjects_remote_path')); UpdraftPlus_Options::update_updraft_option('updraft_dreamobjects', $opts); UpdraftPlus_Options::delete_updraft_option('updraft_dreamobjects_login'); UpdraftPlus_Options::delete_updraft_option('updraft_dreamobjects_pass'); UpdraftPlus_Options::delete_updraft_option('updraft_dreamobjects_remote_path'); } class UpdraftPlus_BackupModule_dreamobjects extends UpdraftPlus_BackupModule_s3 { protected function set_region($obj, $region, $bucket_name = '') { $config = $this->get_config(); global $updraftplus; $updraftplus->log("Set endpoint: " . $config['endpoint']); $obj->setEndpoint($config['endpoint']); } public function get_credentials() { return array('updraft_dreamobjects'); } protected function get_config() { global $updraftplus; $opts = $updraftplus->get_job_option('updraft_dreamobjects');
public function encrypt_file($file) { global $updraftplus; $encryption = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase'); if (strlen($encryption) > 0) { $updraftplus->log("Attempting to encrypt backup file"); $result = apply_filters('updraft_encrypt_file', null, $file, $encryption, $this->whichdb, $this->whichdb_suffix); if (null === $result) { // $updraftplus->log(sprintf(__("As previously warned (see: %s), encryption is no longer a feature of the free edition of UpdraftPlus", 'updraftplus'), 'https://updraftplus.com/next-updraftplus-release-ready-testing/ + https://updraftplus.com/shop/updraftplus-premium/'), 'warning', 'needpremiumforcrypt'); // UpdraftPlus_Options::update_updraft_option('updraft_encryptionphrase', ''); return basename($file); } return $result; } else { return basename($file); } }
public static function config_print() { ?> <tr class="updraftplusmethod ftp"> <td></td> <td><p><em><?php printf(__('%s is a great choice, because UpdraftPlus supports chunked uploads - no matter how big your site is, UpdraftPlus can upload it a little at a time, and not get thwarted by timeouts.', 'updraftplus'), 'FTP'); ?> </em></p></td> </tr> <tr class="updraftplusmethod ftp"> <th></th> <td><em><?php echo apply_filters('updraft_sftp_ftps_notice', '<strong>' . htmlspecialchars(__('Only non-encrypted FTP is supported by regular UpdraftPlus.')) . '</strong> <a href="http://updraftplus.com/shop/sftp/">' . __('If you want encryption (e.g. you are storing sensitive business data), then an add-on is available.', 'updraftplus')) . '</a>'; ?> </em></td> </tr> <tr class="updraftplusmethod ftp"> <th><?php _e('FTP Server', 'updraftplus'); ?> :</th> <td><input type="text" size="40" id="updraft_server_address" name="updraft_server_address" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_server_address')); ?> " /></td> </tr> <tr class="updraftplusmethod ftp"> <th><?php _e('FTP Login', 'updraftplus'); ?> :</th> <td><input type="text" size="40" id="updraft_ftp_login" name="updraft_ftp_login" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_login')); ?> " /></td> </tr> <tr class="updraftplusmethod ftp"> <th><?php _e('FTP Password', 'updraftplus'); ?> :</th> <td><input type="<?php echo apply_filters('updraftplus_admin_secret_field_type', 'text'); ?> " size="40" id="updraft_ftp_pass" name="updraft_ftp_pass" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_pass')); ?> " /></td> </tr> <tr class="updraftplusmethod ftp"> <th><?php _e('Remote Path', 'updraftplus'); ?> :</th> <td><input type="text" size="64" id="updraft_ftp_remote_path" name="updraft_ftp_remote_path" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_remote_path')); ?> " /> <em><?php _e('Needs to already exist', 'updraftplus'); ?> </em></td> </tr> <tr class="updraftplusmethod ftp"> <th></th> <td><p><button id="updraft-ftp-test" type="button" class="button-primary" style="font-size:18px !important"><?php echo sprintf(__('Test %s Settings', 'updraftplus'), 'FTP'); ?> </button></p></td> </tr> <?php }
<?php if (!defined('UPDRAFTPLUS_DIR')) { die('No direct access allowed.'); } require_once UPDRAFTPLUS_DIR . '/methods/s3.php'; # Migrate options to new-style storage - Jan 2014 if (!is_array(UpdraftPlus_Options::get_updraft_option('updraft_s3generic')) && '' != UpdraftPlus_Options::get_updraft_option('updraft_s3generic_login', '')) { $opts = array('accesskey' => UpdraftPlus_Options::get_updraft_option('updraft_s3generic_login'), 'secretkey' => UpdraftPlus_Options::get_updraft_option('updraft_s3generic_pass'), 'path' => UpdraftPlus_Options::get_updraft_option('updraft_s3generic_remote_path'), 'endpoint' => UpdraftPlus_Options::get_updraft_option('updraft_s3generic_endpoint')); UpdraftPlus_Options::update_updraft_option('updraft_s3generic', $opts); UpdraftPlus_Options::delete_updraft_option('updraft_s3generic_login'); UpdraftPlus_Options::delete_updraft_option('updraft_s3generic_pass'); UpdraftPlus_Options::delete_updraft_option('updraft_s3generic_remote_path'); UpdraftPlus_Options::delete_updraft_option('updraft_s3generic_endpoint'); } class UpdraftPlus_BackupModule_s3generic extends UpdraftPlus_BackupModule_s3 { protected function set_region($obj, $region = '') { $config = $this->get_config(); $endpoint = $region != '' && $region != 'n/a' ? $region : $config['endpoint']; global $updraftplus; $updraftplus->log("Set endpoint: {$endpoint}"); $obj->setEndpoint($endpoint); } public function get_credentials() { return array('updraft_s3generic'); } function get_config() {
public function connect() { // Implicit SSL - not handled via PHP's native ftp_ functions, so we use curl instead if ($this->port == 990 || defined('UPDRAFTPLUS_FTP_USECURL') && UPDRAFTPLUS_FTP_USECURL) { if ($this->ssl == false) { $this->port = 21; } else { $this->curl_handle = curl_init(); if (!$this->curl_handle) { $this->port = 21; } else { $options = array(CURLOPT_USERPWD => $this->username . ':' . $this->password, CURLOPT_PORT => $this->port, CURLOPT_CONNECTTIMEOUT => 20, CURLOPT_FTP_CREATE_MISSING_DIRS => true); $options[CURLOPT_FTP_SSL] = CURLFTPSSL_TRY; //CURLFTPSSL_ALL, // require SSL For both control and data connections if (990 == $this->port) { $options[CURLOPT_FTPSSLAUTH] = CURLFTPAUTH_SSL; // CURLFTPAUTH_DEFAULT, // let cURL choose the FTP authentication method (either SSL or TLS) } else { $options[CURLOPT_FTPSSLAUTH] = CURLFTPAUTH_DEFAULT; // let cURL choose the FTP authentication method (either SSL or TLS) } // Prints to STDERR by default - noisy if (defined('WP_DEBUG') && WP_DEBUG == true && UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) { $options[CURLOPT_VERBOSE] = true; } if ($this->disable_verify) { $options[CURLOPT_SSL_VERIFYPEER] = false; $options[CURLOPT_SSL_VERIFYHOST] = 0; } else { $options[CURLOPT_SSL_VERIFYPEER] = true; } if (!$this->use_server_certs) { $options[CURLOPT_CAINFO] = UPDRAFTPLUS_DIR . '/includes/cacert.pem'; } if ($this->passive != true) { $options[CURLOPT_FTPPORT] = '-'; } foreach ($options as $option_name => $option_value) { if (!curl_setopt($this->curl_handle, $option_name, $option_value)) { // throw new Exception( sprintf( 'Could not set cURL option: %s', $option_name ) ); global $updraftplus; if (is_a($updraftplus, 'UpdraftPlus')) { $updraftplus->log("Curl exception: will revert to normal FTP"); } $this->port = 21; $this->curl_handle = false; } } } // All done - leave if ($this->curl_handle) { $this->login_type = 'encrypted (implicit, port 990)'; return true; } } } $time_start = time(); if (function_exists('ftp_ssl_connect') && $this->ssl !== false) { $this->conn_id = ftp_ssl_connect($this->host, $this->port, 15); $attempting_ssl = true; } if ($this->conn_id) { $this->login_type = 'encrypted'; $this->ssl = true; } else { $this->conn_id = ftp_connect($this->host, $this->port, 15); } if ($this->conn_id) { $result = ftp_login($this->conn_id, $this->username, $this->password); } if (!empty($result)) { ftp_set_option($this->conn_id, FTP_TIMEOUT_SEC, $this->timeout); ftp_pasv($this->conn_id, $this->passive); $this->system_type = ftp_systype($this->conn_id); return true; } elseif (!empty($attempting_ssl)) { global $updraftplus_admin; if (isset($updraftplus_admin->logged) && is_array($updraftplus_admin->logged)) { # Clear the previous PHP messages, so that we only show the user messages from the method that worked (or from both if both fail) $save_array = $updraftplus_admin->logged; $updraftplus_admin->logged = array(); #trigger_error(__('Encrypted login failed; trying non-encrypted', 'updraftplus'), E_USER_NOTICE); } $this->ssl = false; $this->login_type = 'non-encrypted'; $time_start = time(); $this->conn_id = ftp_connect($this->host, $this->port, 15); if ($this->conn_id) { $result = ftp_login($this->conn_id, $this->username, $this->password); } if (!empty($result)) { ftp_set_option($this->conn_id, FTP_TIMEOUT_SEC, $this->timeout); ftp_pasv($this->conn_id, $this->passive); $this->system_type = ftp_systype($this->conn_id); return true; } else { # Add back the previous PHP messages if (isset($save_array)) { $updraftplus_admin->logged = array_merge($save_array, $updraftplus_admin->logged); } } } # If we got here, then we failed if (time() - $time_start > 14) { global $updraftplus_admin; if (isset($updraftplus_admin->logged) && is_array($updraftplus_admin->logged)) { $updraftplus_admin->logged[] = sprintf(__('The %s connection timed out; if you entered the server correctly, then this is usually caused by a firewall blocking the connection - you should check with your web hosting company.', 'updraftplus'), 'FTP'); } else { global $updraftplus; $updraftplus->log(sprintf(__('The %s connection timed out; if you entered the server correctly, then this is usually caused by a firewall blocking the connection - you should check with your web hosting company.', 'updraftplus'), 'FTP'), 'error'); } } return false; }
private function restored_table($table, $import_table_prefix, $old_table_prefix) { global $wpdb, $updraftplus; if ($table == $import_table_prefix . UpdraftPlus_Options::options_table()) { $this->restore_configuration_bundle($table); } if (preg_match('/^([\\d+]_)?options$/', substr($table, strlen($import_table_prefix)), $matches)) { if ($this->is_multisite && !empty($matches[1]) || !$this->is_multisite && $table == $import_table_prefix . 'options') { $mprefix = empty($matches[1]) ? '' : $matches[1]; $new_table_name = $import_table_prefix . $mprefix . "options"; // WordPress has an option name predicated upon the table prefix. Yuk. if ($import_table_prefix != $old_table_prefix) { $updraftplus->log("Table prefix has changed: changing options table field(s) accordingly (" . $mprefix . "options)"); echo sprintf(__('Table prefix has changed: changing %s table field(s) accordingly:', 'updraftplus'), 'option') . ' '; if (false === $wpdb->query("UPDATE {$new_table_name} SET option_name='{$import_table_prefix}" . $mprefix . "user_roles' WHERE option_name='{$old_table_prefix}" . $mprefix . "user_roles' LIMIT 1")) { echo __('Error', 'updraftplus'); $updraftplus->log("Error when changing options table fields: " . $wpdb->last_error); } else { $updraftplus->log("Options table fields changed OK"); echo __('OK', 'updraftplus'); } echo '<br>'; } // Now deal with the situation where the imported database sets a new over-ride upload_path that is absolute - which may not be wanted $new_upload_path = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM {$import_table_prefix}" . $mprefix . "options WHERE option_name = %s LIMIT 1", 'upload_path')); $new_upload_path = is_object($new_upload_path) ? $new_upload_path->option_value : ''; // The danger situation is absolute and points somewhere that is now perhaps not accessible at all if (!empty($new_upload_path) && $new_upload_path != $this->prior_upload_path && strpos($new_upload_path, '/') === 0 || preg_match('#^[A-Za-z]:[/\\\\]#', $new_upload_path)) { // $this->old_siteurl != untrailingslashit(site_url()) is not a perfect proxy for "is a migration" (other possibilities exist), but since the upload_path option should not exist since WP 3.5 anyway, the chances of other possibilities are vanishingly small if (!file_exists($new_upload_path) || $this->old_siteurl != $this->our_siteurl) { if (!file_exists($new_upload_path)) { $updraftplus->log_e("Uploads path (%s) does not exist - resetting (%s)", $new_upload_path, $this->prior_upload_path); } else { $updraftplus->log_e("Uploads path (%s) has changed during a migration - resetting (to: %s)", $new_upload_path, $this->prior_upload_path); } if (false === $wpdb->query("UPDATE {$import_table_prefix}" . $mprefix . "options SET option_value='" . esc_sql($this->prior_upload_path) . "' WHERE option_name='upload_path' LIMIT 1")) { echo __('Error', 'updraftplus'); $updraftplus->log("Error when changing upload path: " . $wpdb->last_error); $updraftplus->log("Failed"); } #update_option('upload_path', $this->prior_upload_path); } } # TODO:Do on all WPMU tables if ($table == $import_table_prefix . 'options') { # Bad plugin that hard-codes path references - https://wordpress.org/plugins/custom-content-type-manager/ $cctm_data = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM {$new_table_name} WHERE option_name = %s LIMIT 1", 'cctm_data')); if (!empty($cctm_data->option_value)) { $cctm_data = maybe_unserialize($cctm_data->option_value); if (is_array($cctm_data) && !empty($cctm_data['cache']) && is_array($cctm_data['cache'])) { $cctm_data['cache'] = array(); $updraftplus->log_e("Custom content type manager plugin data detected: clearing option cache"); update_option('cctm_data', $cctm_data); } } # Another - http://www.elegantthemes.com/gallery/elegant-builder/ $elegant_data = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM {$new_table_name} WHERE option_name = %s LIMIT 1", 'et_images_temp_folder')); if (!empty($elegant_data->option_value)) { $dbase = basename($elegant_data->option_value); $wp_upload_dir = wp_upload_dir(); $edir = $wp_upload_dir['basedir']; if (!is_dir($edir . '/' . $dbase)) { @mkdir($edir . '/' . $dbase); } $updraftplus->log_e("Elegant themes theme builder plugin data detected: resetting temporary folder"); update_option('et_images_temp_folder', $edir . '/' . $dbase); } } # The gantry menu plugin sometimes uses too-long transient names, causing the timeout option to be missing; and hence the transient becomes permanent. # WP 3.4 onwards has $wpdb->delete(). But we support 3.2 onwards. $wpdb->query("DELETE FROM {$new_table_name} WHERE option_name LIKE '_transient_gantry-menu%' OR option_name LIKE '_transient_timeout_gantry-menu%'"); # Jetpack: see: https://wordpress.org/support/topic/issues-with-dev-site if ($this->old_siteurl != $this->our_siteurl) { $wpdb->query("DELETE FROM {$new_table_name} WHERE option_name = 'jetpack_options'"); } } } elseif ($import_table_prefix != $old_table_prefix && preg_match('/^([\\d+]_)?usermeta$/', substr($table, strlen($import_table_prefix)), $matches)) { # This table is not a per-site table, but per-install $updraftplus->log("Table prefix has changed: changing usermeta table field(s) accordingly"); echo sprintf(__('Table prefix has changed: changing %s table field(s) accordingly:', 'updraftplus'), 'usermeta') . ' '; $errors_occurred = false; if (false === strpos($old_table_prefix, '_')) { // Old, slow way: do it row-by-row // By Jul 2015, doing this on the updraftplus.com database took 20 minutes on a slow test machine $old_prefix_length = strlen($old_table_prefix); $um_sql = "SELECT umeta_id, meta_key \n\t\t\t\t\tFROM {$import_table_prefix}usermeta \n\t\t\t\t\tWHERE meta_key \n\t\t\t\t\tLIKE '" . str_replace('_', '\\_', $old_table_prefix) . "%'"; $meta_keys = $wpdb->get_results($um_sql); foreach ($meta_keys as $meta_key) { //Create new meta key $new_meta_key = $import_table_prefix . substr($meta_key->meta_key, $old_prefix_length); $query = "UPDATE " . $import_table_prefix . "usermeta \n\t\t\t\t\t\tSET meta_key='" . $new_meta_key . "' \n\t\t\t\t\t\tWHERE umeta_id=" . $meta_key->umeta_id; if (false === $wpdb->query($query)) { $errors_occurred = true; } } } else { // New, fast way: do it in a single query $sql = "UPDATE {$import_table_prefix}usermeta SET meta_key = REPLACE(meta_key, '{$old_table_prefix}', '{$import_table_prefix}') WHERE meta_key LIKE '" . str_replace('_', '\\_', $old_table_prefix) . "%';"; if (false === $wpdb->query($sql)) { $errors_occurred = true; } } if ($errors_occurred) { $updraftplus->log("Error when changing usermeta table fields"); echo __('Error', 'updraftplus'); } else { $updraftplus->log("Usermeta table fields changed OK"); echo __('OK', 'updraftplus'); } echo "<br>"; } do_action('updraftplus_restored_db_table', $table, $import_table_prefix); // Re-generate permalinks. Do this last - i.e. make sure everything else is fixed up first. if ($table == $import_table_prefix . 'options') { $this->flush_rewrite_rules(); } }
public function download($file) { global $updraftplus; $config = $this->get_config(); $whoweare = $config['whoweare']; $s3 = $this->getS3($config['accesskey'], $config['secretkey'], UpdraftPlus_Options::get_updraft_option('updraft_ssl_useservercerts'), UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify'), UpdraftPlus_Options::get_updraft_option('updraft_ssl_nossl')); if (is_wp_error($s3)) { return $updraftplus->log_wp_error($s3, false, true); } $bucket_name = untrailingslashit($config['path']); $bucket_path = ""; if (preg_match("#^([^/]+)/(.*)\$#", $bucket_name, $bmatches)) { $bucket_name = $bmatches[1]; $bucket_path = $bmatches[2] . "/"; } $region = $config['key'] == 'dreamobjects' || $config['key'] == 's3generic' ? 'n/a' : @$s3->getBucketLocation($bucket_name); if (empty($region) && 's3' == $config['key']) { # Final thing to attempt - see if it was just the location request that failed $s3 = $this->use_dns_bucket_name($s3, $bucket_name); if (false !== ($gb = @$s3->getBucket($bucket_name, null, null, 1))) { $keep_going = true; } } if (!empty($region) || !empty($keep_going)) { $this->set_region($s3, $region); $fullpath = $updraftplus->backups_dir_location() . '/' . $file; if (!$s3->getObject($bucket_name, $bucket_path . $file, $fullpath, true)) { $updraftplus->log("{$whoweare} Error: Failed to download {$file}. Check your permissions and credentials."); $updraftplus->log(sprintf(__('%s Error: Failed to download %s. Check your permissions and credentials.', 'updraftplus'), $whoweare, $file), 'error'); return false; } } else { $updraftplus->log("{$whoweare} Error: Failed to access bucket {$bucket_name}. Check your permissions and credentials."); $updraftplus->log(sprintf(__('%s Error: Failed to access bucket %s. Check your permissions and credentials.', 'updraftplus'), $whoweare, $bucket_name), 'error'); return false; } return true; }