Add upstream
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
class UpdraftPlus_Temporary_Clone_Auto_Login {
|
||||
|
||||
/**
|
||||
* Constructor for the class.
|
||||
*/
|
||||
public function __construct() {
|
||||
if (!empty($_REQUEST['uc_auto_login'])) add_action('wp_loaded', array($this, 'handle_url_actions'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Log in the indicated user, if no user is currently logged in. Do verification before calling this function.
|
||||
*
|
||||
* @param WP_User $user - WP user object
|
||||
*/
|
||||
public function autologin_user($user) {
|
||||
if (is_user_logged_in()) return;
|
||||
if (!is_object($user) || !is_a($user, 'WP_User')) return;
|
||||
delete_user_meta($user->ID, 'uc_allow_auto_login');
|
||||
wp_set_current_user($user->ID, $user->user_login);
|
||||
wp_set_auth_cookie($user->ID);
|
||||
try {
|
||||
// WooCommerce (3.4.4) dies here. We catch and carry on to avoid confusing the user about something that nothing can be done about / is a one-time issue.
|
||||
do_action('wp_login', $user->user_login);
|
||||
if (wp_redirect(admin_url())) exit;
|
||||
} catch (Exception $e) {
|
||||
$log_message = 'Exception ('.get_class($e).') occurred during the wp_login action call: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
||||
error_log($log_message);
|
||||
// @codingStandardsIgnoreLine
|
||||
} catch (Error $e) {
|
||||
$log_message = 'PHP Fatal error ('.get_class($e).') occurred during the wp_login action call. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
||||
error_log($log_message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass in a WP_User object to get a login hash. The caller should/must first check that this user is aloud to autologin
|
||||
*
|
||||
* @param WP_User $user - WordPress user object
|
||||
* @param boolean|integer $use_time - false or a timestamp
|
||||
*
|
||||
* @return string - a hash to log the user in
|
||||
*/
|
||||
public static function get_autologin_key($user, $use_time = false) {
|
||||
if (false === $use_time) $use_time = time();
|
||||
// Start of day
|
||||
$use_time = $use_time - ($use_time % 86400);
|
||||
if (!defined('UPDRAFTPLUS_UNIQUE_TOKEN')) return;
|
||||
$hash_it = $user->ID.'_'.$use_time.'_'.UPDRAFTPLUS_UNIQUE_TOKEN;
|
||||
$hash = hash('sha256', $hash_it);
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called upon the WP action wp_loaded
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle_url_actions() {
|
||||
|
||||
if (!isset($_SERVER['REQUEST_METHOD']) || 'GET' != $_SERVER['REQUEST_METHOD'] || !isset($_REQUEST['uc_auto_login'])) return;
|
||||
|
||||
if (0 == ($user_id = get_current_user_id())) {
|
||||
|
||||
if (isset($_REQUEST['uc_login']) && '' !== $_REQUEST['uc_login'] && !empty($_REQUEST['uc_lkey'])) {
|
||||
|
||||
if ($this->auto_login_key_matches($_REQUEST['uc_lkey'], $_REQUEST['uc_login'])) {
|
||||
$login_user = get_user_by('login', $_REQUEST['uc_login']);
|
||||
$allow_autolink = get_user_meta($login_user->ID, 'uc_allow_auto_login');
|
||||
|
||||
if ($allow_autolink) {
|
||||
$this->autologin_user($login_user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an auto-login key. This does not perform any checks on the user - the caller should do these (e.g. do not allow for privileged users)
|
||||
*
|
||||
* @param String $check_key - the key to check for validity
|
||||
* @param String $user_login - login for the user renewing his licences
|
||||
*
|
||||
* @return boolean - indicates if the check was successful or not
|
||||
*/
|
||||
private function auto_login_key_matches($check_key, $user_login) {
|
||||
|
||||
$login_user = get_user_by('login', $user_login);
|
||||
if (is_a($login_user, 'WP_User')) {
|
||||
$time_now = time();
|
||||
for ($i=0; $i <= apply_filters('uc_autologinexpirydays', 3); $i++) {
|
||||
$key = $this->get_autologin_key($login_user, $time_now - 86400*$i);
|
||||
if ($key && $key == $check_key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined('UPDRAFTPLUS_THIS_IS_CLONE')) {
|
||||
$updraftplus_temporary_clone_auto_login = new UpdraftPlus_Temporary_Clone_Auto_Login();
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
class UpdraftPlus_Temporary_Clone_Dash_Notice {
|
||||
|
||||
/**
|
||||
* Constructor for the class.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('updraftplus_temporary_clone_refresh_connection', array($this, 'refresh_connection'));
|
||||
add_action('wp_ajax_updraftplus_dash_notice_ajax', array($this, 'updraftplus_dash_notice_ajax'));
|
||||
add_action('all_admin_notices', array($this, 'all_admin_notices_dashboard_notice'));
|
||||
|
||||
if (!wp_next_scheduled('updraftplus_temporary_clone_refresh_connection')) {
|
||||
wp_schedule_event(time(), 'twicedaily', 'updraftplus_temporary_clone_refresh_connection');
|
||||
}
|
||||
|
||||
if ('' == get_site_option('updraftplus_clone_scheduled_removal', '')) {
|
||||
$this->refresh_connection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will add a dashboard notice to every page, that shows the user when their clone will expire and directs them to UpdraftPlus.com to extend their clones life.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function all_admin_notices_dashboard_notice() {
|
||||
$date = strtotime(get_site_option('updraftplus_clone_scheduled_removal', ''));
|
||||
if ('' == $date) {
|
||||
$pretty_date = __('Unable to get renew date', 'updraftplus');
|
||||
} else {
|
||||
$pretty_date = get_date_from_gmt(gmdate('Y-m-d H:i:s', (int) $date), 'M d, Y G:i');
|
||||
}
|
||||
?>
|
||||
<div id="updraftplus_temporary_clone-dashnotice" class="updated">
|
||||
<div style="float:right;"><a href="#" onclick="jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', {action: 'updraftplus_dash_notice_ajax', subaction: 'refresh_connection', nonce: '<?php echo wp_create_nonce('updraftplus_refresh_connection');?>' }, function() { location.reload(); });"><?php _e('Refresh connection', 'updraftplus'); ?></a></div>
|
||||
<h1><?php _e('Welcome to your UpdraftClone (temporary clone)', 'updraftplus'); ?></h1>
|
||||
<p>
|
||||
<?php echo __('Your clone will renew on:', 'updraftplus') . ' ' . $pretty_date; ?>.
|
||||
<?php _e('Each time your clone renews it costs 1 token, which lasts for 1 week. You can shut this clone down at the following link:', 'updraftplus'); ?> <a target="_blank" href="https://updraftplus.com/my-account/clones/"><?php _e('Manage your clones', 'updraftplus'); ?></p></a>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will perform security checks before allowing the ajax calls for the UpdraftPlus clone VPS mu-plugin be processed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updraftplus_dash_notice_ajax() {
|
||||
|
||||
if (is_user_logged_in() && current_user_can('manage_options')) {
|
||||
$this->process_dash_notice_ajax();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will handle the ajax calls for the UpdraftPlus clone notice mu-plugin.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process_dash_notice_ajax() {
|
||||
$return = array('code' => 'fail', 'data' => '');
|
||||
|
||||
if (!isset($_POST['subaction'])) {
|
||||
$return['code'] = 'error';
|
||||
$return['data'] = 'Missing subaction';
|
||||
echo json_encode($return);
|
||||
die();
|
||||
}
|
||||
|
||||
if ('refresh_connection' === $_POST['subaction']) {
|
||||
check_ajax_referer('updraftplus_refresh_connection', 'nonce');
|
||||
|
||||
$result = $this->refresh_connection();
|
||||
|
||||
if ($result) {
|
||||
$return['code'] = 'success';
|
||||
$return['data'] = $result;
|
||||
} else {
|
||||
$return['code'] = 'error';
|
||||
$return['data'] = $result;
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
die();
|
||||
} else {
|
||||
$return['code'] = 'error';
|
||||
$return['data'] = 'Unknown action';
|
||||
echo json_encode($return);
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will refresh the stored clones expire date by calling UpdraftPlus.com and getting the latest value.
|
||||
* Note this function needs three defines to work UPDRAFTPLUS_USER_ID and UPDRAFTPLUS_VPS_ID and UPDRAFTPLUS_UNIQUE_TOKEN.
|
||||
*
|
||||
* @return array - that contains the updated expire data or error information
|
||||
*/
|
||||
public function refresh_connection() {
|
||||
global $updraftplus;
|
||||
|
||||
if (!defined('UPDRAFTPLUS_USER_ID') || !is_numeric(UPDRAFTPLUS_USER_ID) || !defined('UPDRAFTPLUS_VPS_ID') || !is_numeric(UPDRAFTPLUS_VPS_ID)) {
|
||||
return array('code' => 'error', 'data' => 'No user or VPS ID found');
|
||||
}
|
||||
|
||||
if (!defined('UPDRAFTPLUS_UNIQUE_TOKEN')) return array('code' => 'error', 'data' => 'No unique token found');
|
||||
|
||||
$user_id = UPDRAFTPLUS_USER_ID;
|
||||
$vps_id = UPDRAFTPLUS_VPS_ID;
|
||||
$token = UPDRAFTPLUS_UNIQUE_TOKEN;
|
||||
|
||||
$data = array('user_id' => $user_id, 'vps_id' => $vps_id, 'token' => $token);
|
||||
$result = $updraftplus->get_updraftplus_clone()->clone_status($data);
|
||||
|
||||
$vps_info = $result['data'];
|
||||
|
||||
if (empty($vps_info['scheduled_removal'])) return array('code' => 'error', 'data' => 'No scheduled removal date found');
|
||||
|
||||
update_site_option('updraftplus_clone_scheduled_removal', $vps_info['scheduled_removal']);
|
||||
|
||||
return array('code' => 'success', 'data' => $vps_info['scheduled_removal']);
|
||||
}
|
||||
}
|
||||
|
||||
if (defined('UPDRAFTPLUS_THIS_IS_CLONE')) {
|
||||
$updraftplus_temporary_clone_dash_notice = new UpdraftPlus_Temporary_Clone_Dash_Notice();
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
class UpdraftPlus_Temporary_Clone_Restore {
|
||||
|
||||
/**
|
||||
* Constructor for the class.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('updraftplus_temporary_clone_ready_for_restore', array($this, 'clone_ready_for_restore'));
|
||||
add_action('updraftplus_restored_db', array($this, 'remove_maintenance_file'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will add a ready_for_restore file in the updraft backup directory to indicate that we are ready to restore the received backup set
|
||||
*
|
||||
* @param String|Null $job_id - the job that is ready to restore, if known.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clone_ready_for_restore($job_id = null) {
|
||||
global $updraftplus, $wp_filesystem;
|
||||
|
||||
$state_file = trailingslashit($updraftplus->backups_dir_location()). 'ready_for_restore';
|
||||
|
||||
error_log("UpdraftPlus_Temporary_Clone_Restore::clone_ready_for_restore($job_id): touching flag file");
|
||||
|
||||
if ($job_id) {
|
||||
file_put_contents($state_file, $job_id);
|
||||
} else {
|
||||
touch($state_file);
|
||||
}
|
||||
|
||||
if (!function_exists('WP_Filesystem')) require_once ABSPATH.'wp-admin/includes/file.php';
|
||||
WP_Filesystem();
|
||||
|
||||
// Create maintenance file with current clone status contents
|
||||
if (!$wp_filesystem->exists(trailingslashit(WP_CONTENT_DIR).'maintenance.php')) {
|
||||
ob_start();
|
||||
if (!class_exists('UpdraftPlus_Temporary_Clone_Status')) {
|
||||
include_once trailingslashit(plugin_dir_path(__FILE__)).'temporary-clone-status.php';
|
||||
}
|
||||
$updraftplus_temporary_clone_status = new UpdraftPlus_Temporary_Clone_Status();
|
||||
$updraftplus_temporary_clone_status->output_status_page(false);
|
||||
$contents = ob_get_clean();
|
||||
$wp_filesystem->put_contents(
|
||||
trailingslashit(WP_CONTENT_DIR).'maintenance.php',
|
||||
$contents,
|
||||
FS_CHMOD_FILE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove maintenance file created before the DB restoration.
|
||||
*/
|
||||
public function remove_maintenance_file() {
|
||||
global $updraftplus, $wp_filesystem;
|
||||
|
||||
$updraft_dir = trailingslashit($updraftplus->backups_dir_location());
|
||||
|
||||
if (!file_exists($updraft_dir . 'ready_for_restore')) return;
|
||||
|
||||
if (!function_exists('WP_Filesystem')) require_once ABSPATH.'wp-admin/includes/file.php';
|
||||
WP_Filesystem();
|
||||
|
||||
$wp_filesystem->delete(trailingslashit(WP_CONTENT_DIR).'maintenance.php');
|
||||
}
|
||||
}
|
||||
|
||||
if (defined('UPDRAFTPLUS_THIS_IS_CLONE') && UPDRAFTPLUS_THIS_IS_CLONE) {
|
||||
$updraftplus_temporary_clone_restore = new UpdraftPlus_Temporary_Clone_Restore();
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
class UpdraftPlus_Temporary_Clone_Status {
|
||||
|
||||
/**
|
||||
* WP is Installed
|
||||
*/
|
||||
const INSTALLED = 1;
|
||||
|
||||
/**
|
||||
* Data is uploading
|
||||
*/
|
||||
const UPLOADING = 2;
|
||||
|
||||
/**
|
||||
* Data is uploaded and is restoring
|
||||
*/
|
||||
const RESTORING = 3;
|
||||
|
||||
/**
|
||||
* The current status number
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $current_status;
|
||||
|
||||
/**
|
||||
* Constructor for the class.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('init', array($this, 'init'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called via the WordPress init action, it will check if the page is not the admin backend and output the clone status
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
if (is_admin() || (defined('WP_CLI') && WP_CLI) || 'GET' != $_SERVER['REQUEST_METHOD']) return;
|
||||
|
||||
$this->output_status_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the clone status
|
||||
*
|
||||
* @param bool $die - Defines if should die at the end
|
||||
* @return void
|
||||
*/
|
||||
public function output_status_page($die = true) {
|
||||
$this->current_status = $this->get_status();
|
||||
$this->page_start();
|
||||
echo '<div class="updraftclone_content_container">';
|
||||
|
||||
echo '<img class="updraftclone_logo" alt="UpdraftClone Logo" src="'.trailingslashit(UPDRAFTPLUS_URL).'images/updraftclone_logo_white.png">';
|
||||
echo $this->get_content();
|
||||
?>
|
||||
<div class="status-box">
|
||||
<section class="progress">
|
||||
<div class="progress-item <?php echo $this->get_progress_item_class(self::INSTALLED); ?>">
|
||||
<div class="progress-item__bar"></div>
|
||||
<span class="icon"><?php echo $this->get_progress_item_icon(self::INSTALLED); ?></span>
|
||||
<?php _e('WordPress installed', 'updraftplus'); ?>
|
||||
</div>
|
||||
<div class="progress-item <?php echo $this->get_progress_item_class(self::UPLOADING); ?>">
|
||||
<div class="progress-item__bar"></div>
|
||||
<span class="icon"><?php echo $this->get_progress_item_icon(self::UPLOADING); ?></span>
|
||||
<?php
|
||||
if (self::UPLOADING >= $this->current_status) {
|
||||
_e('Receiving site data', 'updraftplus');
|
||||
} else {
|
||||
_e('Site data received', 'updraftplus');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="progress-item <?php echo $this->get_progress_item_class(self::RESTORING); ?>">
|
||||
<div class="progress-item__bar"></div>
|
||||
<span class="icon"><?php echo $this->get_progress_item_icon(self::RESTORING); ?></span>
|
||||
<?php
|
||||
if (self::RESTORING >= $this->current_status) {
|
||||
_e('Deploying site data', 'updraftplus');
|
||||
} else {
|
||||
_e('Site data has been deployed', 'updraftplus');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="progress-item">
|
||||
<div class="progress-item__bar"></div>
|
||||
<span class="icon"><?php echo $this->get_progress_item_icon(); ?></span>
|
||||
<?php
|
||||
_e('Clone ready', 'updraftplus');
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php echo '<p class="status-description">' . $this->get_status_description() . '</p>'; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
echo '</div>';
|
||||
$this->page_end();
|
||||
if ($die) die();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will output the start of the updraftclone status page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function page_start() {
|
||||
echo '<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="wp-toolbar" lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="refresh" content="60">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>UpdraftClone</title>
|
||||
<style>
|
||||
|
||||
@-webkit-keyframes rotateIcon {
|
||||
|
||||
from {
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@keyframes rotateIcon {
|
||||
|
||||
from {
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #EDEDED;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
p {
|
||||
padding: 0;
|
||||
margin: 15px 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
body:before {
|
||||
content: \' \';
|
||||
position: absolute;
|
||||
background: #db6939;
|
||||
display: block;
|
||||
height: 477px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
a {
|
||||
color: #ffceb9;
|
||||
}
|
||||
.updraftclone_content_container {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
margin:auto;
|
||||
margin-top:40px;
|
||||
width:80%;
|
||||
max-width: 520px;
|
||||
text-align:center;
|
||||
color: #ffffff;
|
||||
font-family: Source Sans Pro, Helvetica, Arial, Lucida, sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
}
|
||||
.updraftclone_logo {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.status-box {
|
||||
max-width: 520px;
|
||||
margin: 0 auto;
|
||||
background: #FFF;
|
||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
|
||||
color: #43322B;
|
||||
}
|
||||
section.progress {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-item {
|
||||
-webkit-box-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.progress-item.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.progress-item__bar {
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.done .progress-item__bar {
|
||||
background: #43322B;
|
||||
}
|
||||
|
||||
.active .progress-item__bar {
|
||||
background: #43322B;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.active .progress-item__bar:before {
|
||||
content: \' \';
|
||||
display: block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
background: #43322B;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border-top: 10px solid #FFF;
|
||||
border-right: 10px solid #FFF;
|
||||
-webkit-transform: translateY(-5px) translateX(10px) rotate(45deg);
|
||||
transform: translateY(-5px) translateX(10px) rotate(45deg);
|
||||
}
|
||||
|
||||
section.progress:before {
|
||||
content: \' \';
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: 10px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.21);
|
||||
}
|
||||
span.icon {
|
||||
display: block;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
span.icon svg {
|
||||
display: inline-block;
|
||||
max-width: 28px;
|
||||
fill: #C4C4C4;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.done span.icon svg {
|
||||
fill: green;
|
||||
}
|
||||
|
||||
.active span.icon svg {
|
||||
fill: #43322B;
|
||||
-webkit-animation-name: rotateIcon;
|
||||
animation-name: rotateIcon;
|
||||
-webkit-animation-duration: 1.8s;
|
||||
animation-duration: 1.8s;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
animation-iteration-count: infinite;
|
||||
-webkit-animation-timing-function: linear;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
|
||||
.progress-item:not(.done):not(.active) {
|
||||
color: #C4C4C4;
|
||||
}
|
||||
.done {
|
||||
color: green;
|
||||
}
|
||||
|
||||
p.status-description {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
border-top: 1px solid #EBEBEB;
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.progress-item:not(.active) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>';
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will output the end of the updraftclone status page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function page_end() {
|
||||
?>
|
||||
<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol viewBox="0 0 20 20" id="yes-alt"><title>yes-alt</title><g><path d="M10 2c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm-.615 12.66h-1.34l-3.24-4.54 1.34-1.25 2.57 2.4 5.14-5.93 1.34.94-5.81 8.38z"/></g></symbol>
|
||||
<symbol viewBox="0 0 20 20" id="yes"><title>yes</title><g><path d="M14.83 4.89l1.34.94-5.81 8.38H9.02L5.78 9.67l1.34-1.25 2.57 2.4z"/></g></symbol>
|
||||
<symbol viewBox="0 0 20 20" id="update"><title>update</title><g><path d="M10.2 3.28c3.53 0 6.43 2.61 6.92 6h2.08l-3.5 4-3.5-4h2.32c-.45-1.97-2.21-3.45-4.32-3.45-1.45 0-2.73.71-3.54 1.78L4.95 5.66C6.23 4.2 8.11 3.28 10.2 3.28zm-.4 13.44c-3.52 0-6.43-2.61-6.92-6H.8l3.5-4c1.17 1.33 2.33 2.67 3.5 4H5.48c.45 1.97 2.21 3.45 4.32 3.45 1.45 0 2.73-.71 3.54-1.78l1.71 1.95c-1.28 1.46-3.15 2.38-5.25 2.38z"/></g></symbol>
|
||||
<symbol viewBox="0 0 20 20" id="clock"><title>clock</title><g><path d="M10 2c4.42 0 8 3.58 8 8s-3.58 8-8 8-8-3.58-8-8 3.58-8 8-8zm0 14c3.31 0 6-2.69 6-6s-2.69-6-6-6-6 2.69-6 6 2.69 6 6 6zm-.71-5.29c.07.05.14.1.23.15l-.02.02L14 13l-3.03-3.19L10 5l-.97 4.81h.01c0 .02-.01.05-.02.09S9 9.97 9 10c0 .28.1.52.29.71z"/></g></symbol>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get and return the clone status title ready to be displayed on the page
|
||||
*
|
||||
* @return string - the clone status title
|
||||
*/
|
||||
public function get_status_title() {
|
||||
|
||||
$code = "";
|
||||
|
||||
switch ($this->current_status) {
|
||||
case self::INSTALLED:
|
||||
$code = __("WordPress installed", "updraftplus");
|
||||
break;
|
||||
case self::UPLOADING:
|
||||
$code = __("Receiving site data", "updraftplus");
|
||||
break;
|
||||
case self::RESTORING:
|
||||
$code = __("Deploying site data", "updraftplus");
|
||||
break;
|
||||
default:
|
||||
$code = "";
|
||||
break;
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get and return the clone status description ready to be displayed on the page
|
||||
*
|
||||
* @return string - the clone status description
|
||||
*/
|
||||
public function get_status_description() {
|
||||
global $updraftplus;
|
||||
|
||||
$description = "";
|
||||
|
||||
switch ($this->current_status) {
|
||||
case self::INSTALLED:
|
||||
$description = __('WordPress installed; now awaiting the site data to be sent.', 'updraftplus');
|
||||
break;
|
||||
case self::UPLOADING:
|
||||
$backup_details = $this->get_backup_details();
|
||||
$description = sprintf(__('The sending of the site data has begun. So far %s data archives totalling %s have been received', 'updraftplus'), '<strong>'.$backup_details['sets'].'</strong>', '<strong>'.round($backup_details['uploaded'], 2).' MB</strong>');
|
||||
break;
|
||||
case self::RESTORING:
|
||||
UpdraftPlus_Backup_History::rebuild();
|
||||
$backup_details = $this->get_backup_details();
|
||||
$description = __('The site data has all been received, and its import has begun.', 'updraftplus').' '.sprintf(__('%s archives remain', 'updraftplus'), '<strong>'.$backup_details['sets'].'</strong>');
|
||||
break;
|
||||
default:
|
||||
$description = "(?)";
|
||||
break;
|
||||
}
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return information about the backup such as the amount of sets and the size of the backup set
|
||||
*
|
||||
* @return array - an array with backup information
|
||||
*/
|
||||
public function get_backup_details() {
|
||||
global $updraftplus;
|
||||
|
||||
$backup_history = UpdraftPlus_Backup_History::get_history();
|
||||
$backupable_entities = $updraftplus->get_backupable_file_entities();
|
||||
$sets = 0;
|
||||
$uploaded = 0;
|
||||
|
||||
foreach ($backupable_entities as $key => $info) {
|
||||
foreach ($backup_history as $timestamp => $backup) {
|
||||
if (isset($backup[$key]) && isset($backup[$key.'-size'])) {
|
||||
$sets += count($backup[$key]);
|
||||
$uploaded += $backup[$key.'-size'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$uploaded = round($uploaded / 1048576, 1);
|
||||
|
||||
return array('uploaded' => $uploaded, 'sets' => $sets);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get and return the clone content ready to be displayed on the page
|
||||
*
|
||||
* @return string - the clone content
|
||||
*/
|
||||
public function get_content() {
|
||||
$content = '<p>'.__('Your UpdraftClone is still setting up.', 'updraftplus').' '.sprintf(__('You can check the progress here or in %s', 'updraftplus'), '<a href="https://updraftplus.com/my-account/clones/" target="_blank">'.__('your UpdraftPlus.com account', 'updraftplus')).'</a></p>';
|
||||
$content .= '<p><a href="https://updraftplus.com/faq-category/updraftclone/" target="_blank">'.__('To read FAQs/documentation about UpdraftClone, go here.', 'updraftplus').'</a></p>';
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will work out what stage the clone is in and return the correct status code
|
||||
*
|
||||
* @return int - the clone status code
|
||||
*/
|
||||
public function get_status() {
|
||||
global $updraftplus;
|
||||
|
||||
$backup_history = UpdraftPlus_Backup_History::get_history();
|
||||
|
||||
if (empty($backup_history)) return self::INSTALLED;
|
||||
|
||||
$updraft_dir = trailingslashit($updraftplus->backups_dir_location());
|
||||
|
||||
if (file_exists($updraft_dir.'ready_for_restore')) return self::RESTORING;
|
||||
|
||||
return self::UPLOADING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the progress item class
|
||||
*
|
||||
* @param int $number The status number
|
||||
* @return string
|
||||
*/
|
||||
private function get_progress_item_class($number) {
|
||||
return ($number === $this->current_status) ? 'active' : (($number < $this->current_status) ? 'done' : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the progress item icon
|
||||
*
|
||||
* @param int $number The status number
|
||||
* @return string
|
||||
*/
|
||||
private function get_progress_item_icon($number = 1000) {
|
||||
$icon = '<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">';
|
||||
$icon .= '<use href="#'.(($number === $this->current_status) ? 'update' : (($number < $this->current_status) ? 'yes' : 'clock')).'" />';
|
||||
$icon .= '</svg>';
|
||||
return $icon;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined('UPDRAFTPLUS_THIS_IS_CLONE') && 1 == UPDRAFTPLUS_THIS_IS_CLONE) {
|
||||
$updraftplus_temporary_clone_status = new UpdraftPlus_Temporary_Clone_Status();
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
class UpdraftPlus_Temporary_Clone_User_Notice {
|
||||
|
||||
/**
|
||||
* Constructor for the class.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_filter('wp_authenticate_user', array($this, 'wp_authenticate_user'));
|
||||
add_action('wp_ajax_updraftplus_user_notice_ajax', array($this, 'updraftplus_user_notice_ajax'));
|
||||
add_action('all_admin_notices', array($this, 'all_admin_notices_users_notice'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will add a dashboard notice to the users page, that gives the user the option to enable admin only logins to the clone.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function all_admin_notices_users_notice() {
|
||||
global $pagenow;
|
||||
|
||||
if ('users.php' != $pagenow) return;
|
||||
|
||||
$admin_login = get_site_option('updraftplus_clone_admin_only_login');
|
||||
|
||||
?>
|
||||
<div id="updraftplus_temporary_clone-usernotice" class="updated">
|
||||
<h1><?php _e('UpdraftPlus temporary clone user login settings:', 'updraftplus'); ?></h1>
|
||||
<p><?php _e('You can forbid non-admins logins to this cloned site by checking the checkbox below', 'updraftplus'); ?></p>
|
||||
<input type="checkbox" name="updraftplus_clone_admin_only" value="1" <?php if ($admin_login) echo 'checked="checked"'; ?> onclick="jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', {action: 'updraftplus_user_notice_ajax', subaction: 'admin_only_login', nonce: '<?php echo wp_create_nonce('updraftplus_admin_only_login');?>', admin_only_login: jQuery(this).is(':checked') });"> <?php _e('Allow only administrators to log in', 'updraftplus'); ?><br>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will check if the user trying to login is an admin and if non admin logins have been disabled. If non admin logins are disabled and the user logging in is not a admin then it will stop the login and return an error.
|
||||
* Runs upon the WP filter wp_authenticate_user
|
||||
*
|
||||
* @param object $user - the user login object
|
||||
*
|
||||
* @return object|WP_Error - retruns the logged in user or a WP_Error stopping non admin logins
|
||||
*/
|
||||
public function wp_authenticate_user($user) {
|
||||
// The WP_User object does not exist in WP 3.2, so we don't check for that
|
||||
if (is_wp_error($user) || !is_object($user) || empty($user->ID)) return $user;
|
||||
|
||||
$admin_login = get_site_option('updraftplus_clone_admin_only_login');
|
||||
$user_is_admin = user_can($user->ID, 'manage_options');
|
||||
|
||||
if (!$user_is_admin && $admin_login) {
|
||||
return new WP_Error('user_login_disabled', '<strong>ERROR</strong>: This user account is not allowed to login.');
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will perform security checks before allowing the ajax calls for the UpdraftPlus clone VPS mu-plugin be processed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updraftplus_user_notice_ajax() {
|
||||
|
||||
if (is_user_logged_in() && current_user_can('manage_options')) {
|
||||
$this->process_user_notice_ajax();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will handle the ajax calls for the UpdraftPlus clone user notice mu-plugin.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process_user_notice_ajax() {
|
||||
$return = array('code' => 'fail', 'data' => '');
|
||||
|
||||
if (!isset($_POST['subaction'])) {
|
||||
$return['code'] = 'error';
|
||||
$return['data'] = 'Missing subaction';
|
||||
echo json_encode($return);
|
||||
die();
|
||||
}
|
||||
|
||||
if ('admin_only_login' == $_POST['subaction']) {
|
||||
check_ajax_referer('updraftplus_admin_only_login', 'nonce');
|
||||
|
||||
if (!isset($_POST['admin_only_login'])) {
|
||||
$return['code'] = 'error';
|
||||
$return['data'] = 'Missing parameter';
|
||||
echo json_encode($return);
|
||||
die();
|
||||
}
|
||||
|
||||
$admin_only = ('true' === $_POST['admin_only_login']);
|
||||
|
||||
update_site_option('updraftplus_clone_admin_only_login', $admin_only);
|
||||
|
||||
$return['code'] = 'success';
|
||||
$return['data'] = 'Option updated';
|
||||
echo json_encode($return);
|
||||
die();
|
||||
} else {
|
||||
$return['code'] = 'error';
|
||||
$return['data'] = 'Unknown action';
|
||||
echo json_encode($return);
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defined('UPDRAFTPLUS_THIS_IS_CLONE')) {
|
||||
$updraftplus_temporary_clone_user_notice = new UpdraftPlus_Temporary_Clone_User_Notice();
|
||||
}
|
||||
Reference in New Issue
Block a user