/**
* Send an action over AJAX. A wrapper around jQuery.ajax. In future, all consumers can be reviewed to simplify some of the options, where there is historical cruft.
* N.B. updraft_iframe_modal() below uses the AJAX URL for the iframe's src attribute
*
* @param {string} action - the action to send
* @param {*} data - data to send
* @param {Function} callback - will be called with the results
* @param {object} options -further options. Relevant properties include:
* - [json_parse=true] - whether to JSON parse the results
* - [alert_on_error=true] - whether to show an alert box if there was a problem (otherwise, suppress it)
* - [action='updraft_ajax'] - what to send as the action parameter on the AJAX request (N.B. action parameter to this function goes as the 'subaction' parameter on the AJAX request)
* - [nonce=updraft_credentialtest_nonce] - the nonce value to send.
* - [nonce_key='nonce'] - the key value for the nonce field
* - [timeout=null] - set a timeout after this number of seconds (or if null, none is set)
* - [async=true] - control whether the request is asynchronous (almost always wanted) or blocking (would need to have a specific reason)
* - [type='POST'] - GET or POST
*/
function updraft_send_command(action, data, callback, options) {
default_options = {
json_parse: true,
alert_on_error: true,
action: 'updraft_ajax',
nonce: updraft_credentialtest_nonce,
nonce_key: 'nonce',
timeout: null,
async: true,
type: 'POST'
}
if ('undefined' === typeof options) options = {};
for (var opt in default_options) {
if (!options.hasOwnProperty(opt)) { options[opt] = default_options[opt]; }
}
var ajax_data = {
action: options.action,
subaction: action,
};
ajax_data[options.nonce_key] = options.nonce;
// TODO: Once all calls are routed through here, change the listener in admin.php to always take the data from the 'data' attribute, instead of in the naked $_POST/$_GET
if (typeof data == 'object') {
for (var attrname in data) { ajax_data[attrname] = data[attrname]; }
} else {
ajax_data.action_data = data;
}
var ajax_opts = {
type: options.type,
url: ajaxurl,
data: ajax_data,
success: function(response, status) {
if (options.json_parse) {
try {
var resp = ud_parse_json(response);
} catch (e) {
if ('function' == typeof options.error_callback) {
return options.error_callback(response, e, 502, resp);
} else {
console.log(e);
console.log(response);
if (options.alert_on_error) { alert(updraftlion.unexpectedresponse+' '+response); }
return;
}
}
if (resp.hasOwnProperty('fatal_error')) {
if ('function' == typeof options.error_callback) {
// 500 is internal server error code
return options.error_callback(response, status, 500, resp);
} else {
console.error(resp.fatal_error_message);
if (options.alert_on_error) { alert(resp.fatal_error_message); }
return false;
}
}
if ('function' == typeof callback) callback(resp, status, response);
} else {
if ('function' == typeof callback) callback(response, status);
}
},
error: function(response, status, error_code) {
if ('function' == typeof options.error_callback) {
options.error_callback(response, status, error_code);
} else {
console.log("updraft_send_command: error: "+status+" ("+error_code+")");
console.log(response);
}
},
dataType: 'text',
async: options.async
};
if (null != options.timeout) { ajax_opts.timeout = options.timeout; }
jQuery.ajax(ajax_opts);
}
/**
* Opens the dialog box for confirmation of whether to delete a backup, plus options if relevant
*
* @param {string} key - The UNIX timestamp of the backup
* @param {string} nonce - The backup job ID
* @param {boolean} showremote - Whether or not to show the "also delete from remote storage?" checkbox
*/
function updraft_delete(key, nonce, showremote) {
jQuery('#updraft_delete_timestamp').val(key);
jQuery('#updraft_delete_nonce').val(nonce);
if (showremote) {
jQuery('#updraft-delete-remote-section, #updraft_delete_remote').prop('disabled', false).show();
} else {
jQuery('#updraft-delete-remote-section, #updraft_delete_remote').hide().attr('disabled','disabled');
}
if (key.indexOf(',') > -1) {
jQuery('#updraft_delete_question_singular').hide();
jQuery('#updraft_delete_question_plural').show();
} else {
jQuery('#updraft_delete_question_plural').hide();
jQuery('#updraft_delete_question_singular').show();
}
jQuery('#updraft-delete-modal').dialog('open');
}
function updraft_remote_storage_tab_activation(the_method){
jQuery('.updraftplusmethod').hide();
jQuery('.remote-tab').data('active', false);
jQuery('.remote-tab').removeClass('nav-tab-active');
jQuery('.updraftplusmethod.'+the_method).show();
jQuery('.remote-tab-'+the_method).data('active', true);
jQuery('.remote-tab-'+the_method).addClass('nav-tab-active');
}
/**
* Set the email report's setting to a different interface when email storage is selected
*
* @param {boolean} value True to set the email report setting to another interface, false otherwise
*/
function set_email_report_storage_interface(value) {
jQuery('#cb_not_email_storage_label').css('display', true === value ? 'none' : 'inline');
jQuery('#cb_email_storage_label').css('display', true === value ? 'inline' : 'none');
if (true === value) {
jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon input#updraft_email').on('click', function(e) {
return false;
});
} else {
jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon input#updraft_email').prop("onclick", null).off("click");
}
if (!jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon input#updraft_email').is(':checked')) {
jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon input#updraft_email').prop('checked', value);
}
jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon input#updraft_email').prop('disabled', value);
var updraft_email = jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon input#updraft_email').val();
jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon label.email_report input[type="hidden"]').remove();
if (true === value) {
jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon label.email_report input#updraft_email').after('');
}
}
/**
* Check how many cron jobs are overdue, and display a message if it is several (as determined by the back-end)
*/
function updraft_check_overduecrons() {
updraft_send_command('check_overdue_crons', null, function(response) {
if (response && response.hasOwnProperty('m') && Array.isArray(response.m)) {
for (var i in response.m) {
jQuery('#updraft-insert-admin-warning').append(response.m[i]);
}
}
}, { alert_on_error: false });
}
function updraft_remote_storage_tabs_setup() {
var anychecked = 0;
var set = jQuery('.updraft_servicecheckbox:checked');
jQuery(set).each(function(ind, obj) {
var ser = jQuery(obj).val();
if (jQuery(obj).attr('id') != 'updraft_servicecheckbox_none') {
anychecked++;
}
jQuery('.remote-tab-'+ser).show();
if (ind == jQuery(set).length-1) {
updraft_remote_storage_tab_activation(ser);
}
});
if (anychecked > 0) {
jQuery('.updraftplusmethod.none').hide();
jQuery('#remote_storage_tabs').show();
} else {
jQuery('#remote_storage_tabs').hide();
}
// To allow labelauty remote storage buttons to be used with keyboard
jQuery(document).on('keyup', function(event) {
if (32 === event.keyCode || 13 === event.keyCode) {
if (jQuery(document.activeElement).is("input.labelauty + label")) {
var for_box = jQuery(document.activeElement).attr("for");
if (for_box) {
jQuery("#"+for_box).trigger('change');
}
}
}
});
jQuery('.updraft_servicecheckbox').on('change', function() {
var sclass = jQuery(this).attr('id');
if ('updraft_servicecheckbox_' == sclass.substring(0,24)) {
var serv = sclass.substring(24);
if (null != serv && '' != serv) {
if (jQuery(this).is(':checked')) {
anychecked++;
jQuery('.remote-tab-'+serv).fadeIn();
updraft_remote_storage_tab_activation(serv);
if (jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon').length && 'email' === serv) set_email_report_storage_interface(true);
} else {
anychecked--;
jQuery('.remote-tab-'+serv).hide();
// Check if this was the active tab, if yes, switch to another
if (jQuery('.remote-tab-'+serv).data('active') == true) {
updraft_remote_storage_tab_activation(jQuery('.remote-tab:visible').last().attr('name'));
}
if (jQuery('#updraft-navtab-settings-content #updraft_report_row_no_addon').length && 'email' === serv) set_email_report_storage_interface(false);
}
}
}
if (anychecked <= 0) {
jQuery('.updraftplusmethod.none').fadeIn();
jQuery('#remote_storage_tabs').hide();
} else {
jQuery('.updraftplusmethod.none').hide();
jQuery('#remote_storage_tabs').show();
}
});
// Add stuff for free version
jQuery('.updraft_servicecheckbox:not(.multi)').on('change', function() {
set_email_report_storage_interface(false);
var svalue = jQuery(this).attr('value');
if (jQuery(this).is(':not(:checked)')) {
jQuery('.updraftplusmethod.'+svalue).hide();
jQuery('.updraftplusmethod.none').fadeIn();
} else {
jQuery('.updraft_servicecheckbox').not(this).prop('checked', false);
if ('email' === svalue) {
set_email_report_storage_interface(true);
}
}
});
var servicecheckbox = jQuery('.updraft_servicecheckbox');
if (typeof servicecheckbox.labelauty === 'function') {
servicecheckbox.labelauty();
var $vault_label = jQuery('label[for=updraft_servicecheckbox_updraftvault]');
var $vault_info = jQuery('
?
'+updraftlion.updraftvault_info+'
');
$vault_label.append($vault_info);
}
}
/**
* Carries out a remote storage test
*
* @param {string} method - The identifier for the remote storage
* @param {callback} result_callback - A callback function to be called with the result
* @param {string} instance_id - The particular instance (if any) of the remote storage to be tested (for methods supporting multiple instances)
*/
function updraft_remote_storage_test(method, result_callback, instance_id) {
var $the_button;
var settings_selector;
if (instance_id) {
$the_button = jQuery('#updraft-'+method+'-test-'+instance_id);
settings_selector = '.updraftplusmethod.'+method+'-'+instance_id;
} else {
$the_button = jQuery('#updraft-'+method+'-test');
settings_selector = '.updraftplusmethod.'+method;
}
var method_label = $the_button.data('method_label');
$the_button.html(updraftlion.testing_settings.replace('%s', method_label));
var data = {
method: method
};
// Add the other items to the data object. The expert mode settings are for the generic SSL options.
jQuery('#updraft-navtab-settings-content '+settings_selector+' input[data-updraft_settings_test], #updraft-navtab-settings-content .expertmode input[data-updraft_settings_test]').each(function(index, item) {
var item_key = jQuery(item).data('updraft_settings_test');
var input_type = jQuery(item).attr('type');
if (!item_key) { return; }
if (!input_type) {
console.log("UpdraftPlus: settings test input item with no type found");
console.log(item);
// A default
input_type = 'text';
}
var value = null;
if ('checkbox' == input_type) {
value = jQuery(item).is(':checked') ? 1 : 0;
} else if ('text' == input_type || 'password' == input_type || 'hidden' == input_type) {
value = jQuery(item).val();
} else {
console.log("UpdraftPlus: settings test input item with unrecognised type ("+input_type+") found");
console.log(item);
}
data[item_key] = value;
});
// Data from any text areas or select drop-downs
jQuery('#updraft-navtab-settings-content '+settings_selector+' textarea[data-updraft_settings_test], #updraft-navtab-settings-content '+settings_selector+' select[data-updraft_settings_test]').each(function(index, item) {
var item_key = jQuery(item).data('updraft_settings_test');
data[item_key] = jQuery(item).val();
});
updraft_send_command('test_storage_settings', data, function(response, status) {
$the_button.html(updraftlion.test_settings.replace('%s', method_label));
if ('undefined' !== typeof result_callback && false != result_callback) {
result_callback = result_callback.call(this, response, status, data);
}
if ('undefined' !== typeof result_callback && false === result_callback) {
alert(updraftlion.settings_test_result.replace('%s', method_label)+' '+response.output);
if (response.hasOwnProperty('data')) {
console.log(response.data);
}
}
}, { error_callback: function(response, status, error_code, resp) {
$the_button.html(updraftlion.test_settings.replace('%s', method_label));
if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) {
console.error(resp.fatal_error_message);
alert(resp.fatal_error_message);
} else {
var error_message = "updraft_send_command: error: "+status+" ("+error_code+")";
console.log(error_message);
alert(error_message);
console.log(response);
}
}
});
}
function backupnow_whichfiles_checked(onlythesefileentities){
jQuery('#backupnow_includefiles_moreoptions input[type="checkbox"]').each(function(index) {
if (!jQuery(this).is(':checked')) { return; }
var name = jQuery(this).attr('name');
if (name.substring(0, 16) != 'updraft_include_') { return; }
var entity = name.substring(16);
if (onlythesefileentities != '') { onlythesefileentities += ','; }
onlythesefileentities += entity;
});
// console.log(onlythesefileentities);
return onlythesefileentities;
}
/**
* A method to get all the selected table values from the backup now modal
*
* @param {string} onlythesetableentities an empty string to append values to
*
* @return {string} a string that contains the values of all selected table entities and the database the belong to
*/
function backupnow_whichtables_checked(onlythesetableentities){
var send_list = false;
jQuery('#backupnow_database_moreoptions .updraft_db_entity').each(function(index) {
if (!jQuery(this).is(':checked')) { send_list = true; return; }
if (jQuery(this).is(':checked') && jQuery(this).data('non_wp_table')) { send_list = true; return; }
});
onlythesetableentities = jQuery("input[name^='updraft_include_tables_']").serializeArray();
if (send_list) {
return onlythesetableentities;
} else {
return true;
}
}
function updraft_deleteallselected() {
var howmany = 0;
var remote_exists = 0;
var key_all = '';
var nonce_all = '';
var remote_all = 0;
jQuery('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected').each(function(index) {
howmany++;
var nonce = jQuery(this).data('nonce');
if (nonce_all) { nonce_all += ','; }
nonce_all += nonce;
var key = jQuery(this).data('key');
if (key_all) { key_all += ','; }
key_all += key;
var has_remote = jQuery(this).find('.updraftplus-remove').data('hasremote');
if (has_remote) remote_all++;
});
updraft_delete(key_all, nonce_all, remote_all);
}
/**
* Open main tab which is given as argument
*
* @param {string} active_tab_key A tab key which you would like to open
*/
function updraft_open_main_tab(active_tab_key) {
updraftlion.main_tabs_keys.forEach(function(tab_key) {
if (active_tab_key == tab_key) {
jQuery('#updraft-navtab-' + tab_key + '-content').show();
jQuery('#updraft-navtab-' + tab_key).addClass('nav-tab-active');
} else {
jQuery('#updraft-navtab-' + tab_key + '-content').hide();
jQuery('#updraft-navtab-' + tab_key).removeClass('nav-tab-active');
}
updraft_console_focussed_tab = active_tab_key;
});
}
/**
* Open an existing backups tab
*
* @param {Boolean} toggly Whether switch on updraft_historytimer or not
*/
function updraft_openrestorepanel(toggly) {
// jQuery('.download-backups').slideDown(); updraft_historytimertoggle(1); jQuery('html,body').animate({scrollTop: jQuery('#updraft_lastlogcontainer').offset().top},'slow');
updraft_historytimertoggle(toggly);
updraft_open_main_tab('backups');
}
function updraft_delete_old_dirs() {
return true;
}
function updraft_initiate_restore(whichset) {
jQuery('#updraft-navtab-backups-content .updraft_existing_backups button[data-backup_timestamp="'+whichset+'"]').trigger('click');
}
function updraft_restore_setoptions(entities) {
var howmany = 0;
jQuery('input[name="updraft_restore[]"]').each(function(x,y) {
var entity = jQuery(y).val();
var epat = entity+'=([0-9,]+)';
var eregex = new RegExp(epat);
var ematch = entities.match(eregex);
if (ematch) {
jQuery(y).prop('disabled', false).data('howmany', ematch[1]).parent().show();
howmany++;
if ('db' == entity) { howmany += 4.5;}
if (jQuery(y).is(':checked')) {
// This element may or may not exist. The purpose of explicitly calling show() is that Firefox, when reloading (including via forwards/backwards navigation) will remember checkbox states, but not which DOM elements were showing/hidden - which can result in some being hidden when they should be shown, and the user not seeing the options that are/are not checked.
jQuery('#updraft_restorer_'+entity+'options').show();
}
} else {
jQuery(y).attr('disabled','disabled').parent().hide();
}
});
var cryptmatch = entities.match(/dbcrypted=1/);
if (cryptmatch) {
jQuery('#updraft_restore_db').data('encrypted', 1);
jQuery('.updraft_restore_crypteddb').show();
} else {
jQuery('#updraft_restore_db').data('encrypted', 0);
jQuery('.updraft_restore_crypteddb').hide();
}
jQuery('#updraft_restore_db').trigger('change');
var dmatch = entities.match(/meta_foreign=([12])/);
if (dmatch) {
jQuery('#updraft_restore_meta_foreign').val(dmatch[1]);
} else {
jQuery('#updraft_restore_meta_foreign').val('0');
}
}
/**
* Open the 'Backup Now' dialog box
*
* @param {string} type - the backup type; either "new" or "incremental"
*/
function updraft_backup_dialog_open(type) {
type = ('undefined' === typeof type) ? 'new' : type;
if (0 == jQuery('#updraftplus_incremental_backup_link').data('incremental') && 'incremental' == type) {
jQuery('#updraft-backupnow-modal .incremental-free-only').show();
type = 'new';
} else {
jQuery('#updraft-backupnow-modal .incremental-backups-only, #updraft-backupnow-modal .incremental-free-only').hide();
}
jQuery('#backupnow_includefiles_moreoptions').hide();
if (!updraft_settings_form_changed || window.confirm(updraftlion.unsavedsettingsbackup)) {
jQuery('#backupnow_label').val('');
if ('incremental' == type) {
update_file_entities_checkboxes(true, impossible_increment_entities);
jQuery('#backupnow_includedb').prop('checked', false);
jQuery('#backupnow_includefiles').prop('checked', true);
jQuery('#backupnow_includefiles_label').text(updraftlion.files_incremental_backup);
jQuery('#updraft-backupnow-modal .new-backups-only').hide();
jQuery('#updraft-backupnow-modal .incremental-backups-only').show();
} else {
update_file_entities_checkboxes(false, impossible_increment_entities);
jQuery('#backupnow_includedb').prop('checked', true);
jQuery('#backupnow_includefiles_label').text(updraftlion.files_new_backup);
jQuery('#updraft-backupnow-modal .new-backups-only').show();
jQuery('#updraft-backupnow-modal .incremental-backups-only').hide();
}
jQuery('#updraft-backupnow-modal').data('backup-type', type);
jQuery('#updraft-backupnow-modal').dialog('open');
}
}
/**
* Open the 'Backup Now' dialog box
*
* @param {string} type - the backup type; either "new" or "incremental"
*/
/**
* This function will enable and disable the file entity options depending on what entities increments can be added to and if this is a new backup or not.
*
* @param {boolean} incremental - a boolean to indicate if this is an incremental backup or not
* @param {array} entities - an array of entities to disable
*/
function update_file_entities_checkboxes(incremental, entities) {
if (incremental) {
jQuery(entities).each(function (index, entity) {
jQuery('#backupnow_files_updraft_include_' + entity).prop('checked', false);
jQuery('#backupnow_files_updraft_include_' + entity).prop('disabled', true);
});
} else {
jQuery('#backupnow_includefiles_moreoptions input[type="checkbox"]').each(function (index) {
var name = jQuery(this).attr('name');
if (name.substring(0, 16) != 'updraft_include_') { return; }
var entity = name.substring(16);
jQuery('#backupnow_files_updraft_include_' + entity).prop('disabled', false);
if (jQuery('#updraft_include_' + entity).is(':checked')) {
jQuery('#backupnow_files_updraft_include_' + entity).prop('checked', true);
}
});
}
}
var onlythesefileentities = backupnow_whichfiles_checked('');
if ('' == onlythesefileentities) {
jQuery("#backupnow_includefiles_moreoptions").show();
} else {
jQuery("#backupnow_includefiles_moreoptions").hide();
}
var impossible_increment_entities;
var updraft_restore_stage = 1;
var lastlog_lastmessage = "";
var lastlog_lastdata = "";
var lastlog_jobs = "";
// var lastlog_sdata = { action: 'updraft_ajax', subaction: 'lastlog' };
var updraft_activejobs_nextupdate = (new Date).getTime() + 1000;
// Bits: main tab displayed (1); restore dialog open (uses downloader) (2); tab not visible (4)
var updraft_page_is_visible = 1;
var updraft_console_focussed_tab = updraftlion.tab;
var php_max_input_vars = 0;
var skipped_db_scan = 0;
var updraft_settings_form_changed = false;
window.onbeforeunload = function(e) {
if (updraft_settings_form_changed) return updraftlion.unsavedsettings;
}
/**
* N.B. This function works on both the UD settings page and elsewhere
*
* @param {boolean} firstload Check if this is first load
*/
function updraft_check_page_visibility(firstload) {
if ('hidden' == document["visibilityState"]) {
updraft_page_is_visible = 0;
} else {
updraft_page_is_visible = 1;
if (1 !== firstload) {
if (jQuery('#updraft-navtab-backups-content').length) {
updraft_activejobs_update(true);
}
}
};
}
// See http://caniuse.com/#feat=pagevisibility for compatibility (we don't bother with prefixes)
if (typeof document.hidden !== "undefined") {
document.addEventListener('visibilitychange', function() {
updraft_check_page_visibility(0);}, false);
}
updraft_check_page_visibility(1);
var updraft_poplog_log_nonce;
var updraft_poplog_log_pointer = 0;
var updraft_poplog_lastscroll = -1;
var updraft_last_forced_jobid = -1;
var updraft_last_forced_resumption = -1;
var updraft_last_forced_when = -1;
var updraft_backupnow_nonce = '';
var updraft_activejobslist_backupnownonce_only = 0;
var updraft_inpage_hasbegun = 0;
var updraft_activejobs_update_timer;
var updraft_aborted_jobs = [];
var updraft_clone_jobs = [];
var temporary_clone_timeout;
// Manage backups table selection
var updraft_backups_selection = {};
// @codingStandardsIgnoreStart - to keep the doc blocks, as they're considered block comments by phpcs
(function($) {
/**
* Toggle row seletion
*
* @param {HTMLDomElement|jQuery} el - row element
*/
updraft_backups_selection.toggle = function(el) {
var $el = $(el);
if ($el.is('.backuprowselected')) {
this.deselect(el);
} else {
this.select(el);
}
};
/**
* Select row
*
* @param {HTMLDomElement|jQuery} el - row element
*/
updraft_backups_selection.select = function(el) {
$(el).addClass('backuprowselected');
$(el).find('.backup-select input').prop('checked', true);
this.checkSelectionStatus();
};
/**
* Deselect row
*
* @param {HTMLDomElement|jQuery} el - row element
*/
updraft_backups_selection.deselect = function(el) {
$(el).removeClass('backuprowselected');
$(el).find('.backup-select input').prop('checked', false);
this.checkSelectionStatus();
};
/**
* Select all rows
*/
updraft_backups_selection.selectAll = function() {
$('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row').each(function(index, el) {
updraft_backups_selection.select(el);
})
};
/**
* Deselect all rows
*/
updraft_backups_selection.deselectAll = function() {
$('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row').each(function(index, el) {
updraft_backups_selection.deselect(el);
})
};
/**
* Actions after a row selection/deselection
*/
updraft_backups_selection.checkSelectionStatus = function() {
var num_rows = $('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row').length;
var num_selected = $('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected').length;
// toggles actions upon seleted items
if (num_selected > 0) {
$('#ud_massactions').addClass('active');
$('.js--deselect-all-backups, .js--delete-selected-backups').prop('disabled', false);
} else {
$('#ud_massactions').removeClass('active');
$('.js--deselect-all-backups, .js--delete-selected-backups').prop('disabled', true);
}
// if all rows are selected, check the headind's checkbox
if (num_rows === num_selected) {
$('#cb-select-all').prop('checked', true);
} else {
$('#cb-select-all').prop('checked', false);
}
// if no backups, hide massaction
if (!num_rows) {
$('#ud_massactions').hide();
} else {
$('#ud_massactions').show();
}
}
/**
* Multiple range selection
*
* @param {HTMLDomElement|jQuery} el - row element
*/
updraft_backups_selection.selectAllInBetween = function(el) {
var idx_start = this.firstMultipleSelectionIndex, idx_end = el.rowIndex-1;
if (this.firstMultipleSelectionIndex > el.rowIndex-1) {
idx_start = el.rowIndex-1; idx_end = this.firstMultipleSelectionIndex;
}
for (var i=idx_start; i<=idx_end; i++) {
this.select($('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row').eq(i));
}
}
/**
* Multiple range selection event handler that gets executed when hovering the mouse over the row of existing backups. This function highlights the rows with color
*/
updraft_backups_selection.hightlight_backup_rows = function() {
if ("undefined" === typeof updraft_backups_selection.firstMultipleSelectionIndex) return;
if (!$(this).hasClass('range-selection') && !$(this).hasClass('backuprowselected')) $(this).addClass('range-selection');
$(this).siblings().removeClass('range-selection');
if (updraft_backups_selection.firstMultipleSelectionIndex+1 > this.rowIndex) {
$(this).nextUntil('.updraft_existing_backups_row.range-selection-start').addClass('range-selection');
} else if (updraft_backups_selection.firstMultipleSelectionIndex+1 < this.rowIndex) {
$(this).prevUntil('.updraft_existing_backups_row.range-selection-start').addClass('range-selection');
}
}
/**
* Multiple range selection event handler that gets executed when the user releases the ctrl+shift button, it also gets executed when the mouse pointer is moved out from the browser page
* This function clears all the highlighted rows and removes hover and mouseleave event handlers
*/
updraft_backups_selection.unregister_highlight_mode = function() {
if ("undefined" === typeof updraft_backups_selection.firstMultipleSelectionIndex) return;
delete updraft_backups_selection.firstMultipleSelectionIndex;
$('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row').removeClass('range-selection range-selection-start');
$('#updraft-navtab-backups-content').off('mouseenter', '.updraft_existing_backups .updraft_existing_backups_row', this.hightlight_backup_rows);
$('#updraft-navtab-backups-content').off('mouseleave', '.updraft_existing_backups .updraft_existing_backups_row', this.hightlight_backup_rows);
$(document).off('mouseleave', this.unregister_highlight_mode);
}
/**
* Register mouseleave and hover event handlers for highlighting purposes
*/
updraft_backups_selection.register_highlight_mode = function() {
$(document).on('mouseleave', updraft_backups_selection.unregister_highlight_mode);
$('#updraft-navtab-backups-content').on('mouseenter', '.updraft_existing_backups .updraft_existing_backups_row', updraft_backups_selection.hightlight_backup_rows);
$('#updraft-navtab-backups-content').on('mouseleave', '.updraft_existing_backups .updraft_existing_backups_row', updraft_backups_selection.hightlight_backup_rows);
}
})(jQuery);
// @codingStandardsIgnoreEnd
/**
* Setup migration sections
*/
function setup_migrate_tabs() {
// sets up the section buttons
jQuery('#updraft_migrate .updraft_migrate_widget_module_content').each(function(ind, el) {
var title = jQuery(el).find('h3').first().html();
var intro_container = jQuery('.updraft_migrate_intro');
var button = jQuery('').html(title).appendTo(intro_container);
button.on('click', function(e) {
e.preventDefault();
jQuery(el).show();
intro_container.hide();
});
});
}
/**
* Run a backup with show modal with progress.
*
* @param {Function} success_callback callback function after backup
* @param {String} onlythisfileentity csv list of file entities to be backed up
* @param {Array} extradata any extra data to be added
* @param {Integer} backupnow_nodb Indicate whether the database should be backed up. Valid values: 0, 1
* @param {Integer} backupnow_nofiles Indicate whether any files should be backed up. Valid values: 0, 1
* @param {Integer} backupnow_nocloud Indicate whether the backup should be uploaded to cloud storage. Valid values: 0, 1
* @param {String} label An optional label to be added to a backup
*/
function updraft_backupnow_inpage_go(success_callback, onlythisfileentity, extradata, backupnow_nodb, backupnow_nofiles, backupnow_nocloud, label) {
backupnow_nodb = ('undefined' === typeof backupnow_nodb) ? 0 : backupnow_nodb;
backupnow_nofiles = ('undefined' === typeof backupnow_nofiles) ? 0 : backupnow_nofiles;
backupnow_nocloud = ('undefined' === typeof backupnow_nocloud) ? 0 : backupnow_nocloud;
label = ('undefined' === typeof label) ? updraftlion.automaticbackupbeforeupdate : label;
// N.B. This function should never be called on the UpdraftPlus settings page - it is assumed we are elsewhere. So, it is safe to fake the console-focussing parameter.
updraft_console_focussed_tab = 'backups';
updraft_inpage_success_callback = success_callback;
updraft_activejobs_update_timer = setInterval(function () {
updraft_activejobs_update(false);
}, 1250);
var updraft_inpage_modal_buttons = {};
var inpage_modal_exists = jQuery('#updraft-backupnow-inpage-modal').length;
if (inpage_modal_exists) {
jQuery('#updraft-backupnow-inpage-modal').dialog('option', 'buttons', updraft_inpage_modal_buttons);
}
jQuery('#updraft_inpage_prebackup').hide();
if (inpage_modal_exists) {
jQuery('#updraft-backupnow-inpage-modal').dialog('open');
}
jQuery('#updraft_inpage_backup').show();
updraft_activejobslist_backupnownonce_only = 1;
updraft_inpage_hasbegun = 0;
updraft_backupnow_go(backupnow_nodb, backupnow_nofiles, backupnow_nocloud, onlythisfileentity, extradata, label, '');
}
function updraft_get_downloaders() {
var downloaders = '';
jQuery('.ud_downloadstatus .updraftplus_downloader, #ud_downloadstatus2 .updraftplus_downloader, #ud_downloadstatus3 .updraftplus_downloader').each(function(x,y) {
var dat = jQuery(y).data('downloaderfor');
if (typeof dat == 'object') {
if (downloaders != '') { downloaders = downloaders + ':'; }
downloaders = downloaders + dat.base + ',' + dat.nonce + ',' + dat.what + ',' + dat.index;
}
});
return downloaders;
}
function updraft_poll_get_parameters() {
var gdata = {
downloaders: updraft_get_downloaders()
}
try {
if (jQuery('#updraft-poplog').dialog('isOpen')) {
gdata.log_fetch = 1;
gdata.log_nonce = updraft_poplog_log_nonce;
gdata.log_pointer = updraft_poplog_log_pointer
}
} catch (err) {
console.log(err);
}
if (updraft_activejobslist_backupnownonce_only && typeof updraft_backupnow_nonce !== 'undefined' && '' != updraft_backupnow_nonce) {
gdata.thisjobonly = updraft_backupnow_nonce;
}
if (0 !== jQuery('#updraftplus_ajax_restore_job_id').length) gdata.updraft_credentialtest_nonce = updraft_credentialtest_nonce;
return gdata;
}
var updraftplus_activejobs_list_fatal_error_alert = true;
function updraft_activejobs_update(force) {
var $ = jQuery;
var timenow = (new Date).getTime();
if (false == force && timenow < updraft_activejobs_nextupdate) { return; }
updraft_activejobs_nextupdate = timenow + 5500;
var gdata = updraft_poll_get_parameters();
updraft_send_command('activejobs_list', gdata, function(resp, status, response_raw) {
updraft_process_status_check(resp, response_raw, gdata);
}, {
type: 'GET',
error_callback: function(response, status, error_code, resp) {
if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) {
console.error(resp.fatal_error_message);
if (true === updraftplus_activejobs_list_fatal_error_alert) {
updraftplus_activejobs_list_fatal_error_alert = false;
alert(this.alert_done + ' ' +resp.fatal_error_message);
}
} else {
var msg = (status == error_code) ? error_code : error_code+" ("+status+")";
console.error(msg);
console.log(response);
}
return false;
}
});
}
/**
* Shows a modal on success
*
* @param {string|obj} args The message to display or an object of parameters
*/
function updraft_show_success_modal(args) {
if ('string' == typeof args) {
args = {
message: args
};
}
var data = jQuery.extend(
{
icon: 'yes',
close: updraftlion.close,
message: '',
classes: 'success'
},
args
);
jQuery.blockUI({
css: {
width: '300px',
border: 'none',
'border-radius': '10px',
left: 'calc(50% - 150px)'
},
message: '
'+data.message+'
'
});
// close success popup
setTimeout(jQuery.unblockUI, 5000);
jQuery('.blockUI .updraft-close-overlay').on('click', function() {
jQuery.unblockUI();
})
}
/**
* Opens a dialog window showing the requested (or latest) log file, plus an option to download it
*
* @param {string} backup_nonce - the nonce of the log to display, or empty for the latest one
*/
function updraft_popuplog(backup_nonce) {
var loading_message = updraftlion.loading_log_file;
if (backup_nonce) { loading_message += ' (log.'+backup_nonce+'.txt)'; }
jQuery('#updraft-poplog').dialog("option", "title", loading_message);
jQuery('#updraft-poplog-content').html(''+loading_message+' ... ');
jQuery('#updraft-poplog').dialog("open");
updraft_send_command('get_log', backup_nonce, function(resp) {
updraft_poplog_log_pointer = resp.pointer;
updraft_poplog_log_nonce = resp.nonce;
var download_url = '?page=updraftplus&action=downloadlog&force_download=1&updraftplus_backup_nonce='+resp.nonce;
jQuery('#updraft-poplog-content').html(resp.log);
var log_popup_buttons = {};
log_popup_buttons[updraftlion.downloadlogfile] = function() {
window.location.href = download_url; };
log_popup_buttons[updraftlion.close] = function() {
jQuery(this).dialog("close"); };
// Set the dialog buttons: Download log, Close log
jQuery('#updraft-poplog').dialog("option", "buttons", log_popup_buttons);
jQuery('#updraft-poplog').dialog("option", "title", 'log.'+resp.nonce+'.txt');
updraft_poplog_lastscroll = -1;
}, { type: 'GET', timeout: 60000, error_callback: function(response, status, error_code, resp) {
if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) {
console.error(resp.fatal_error_message);
jQuery('#updraft-poplog-content').append(resp.fatal_error_message);
} else {
var msg = (status == error_code) ? error_code : error_code+" ("+status+")";
jQuery('#updraft-poplog-content').append(msg);
console.log(response);
}
}
});
}
function updraft_showlastbackup() {
updraft_send_command('get_fragment', 'last_backup_html', function(resp) {
response = resp.output;
if (lastbackup_laststatus == response) {
setTimeout(function() {
updraft_showlastbackup(); }, 7000);
} else {
jQuery('#updraft_last_backup').html(response);
}
lastbackup_laststatus = response;
}, { type: 'GET' });
}
var updraft_historytimer = 0;
var calculated_diskspace = 0;
var updraft_historytimer_notbefore = 0;
var updraft_history_lastchecksum = false;
function updraft_historytimertoggle(forceon) {
if (!updraft_historytimer || forceon == 1) {
updraft_updatehistory(0, 0);
updraft_historytimer = setInterval(function() {
updraft_updatehistory(0, 0);}, 30000);
if (!calculated_diskspace) {
updraftplus_diskspace();
calculated_diskspace = 1;
}
} else {
clearTimeout(updraft_historytimer);
updraft_historytimer = 0;
}
}
/**
* Update the HTML for the 'existing backups' table; optionally, after local/remote re-scanning.
* Nothing is returned; any update necessary is performed directly on the DOM.
*
* @param {Integer} rescan - first, re-scan the local storage (0 or 1)
* @param {Integer} remotescan - first, re-scan the remote storage (you must also set rescan to 1 to use this)
* @param {Integer} debug - if 1, then also request debugging information and log it to the console
* @param {Integer} backup_count - the amount of backups we want to display
*/
function updraft_updatehistory(rescan, remotescan, debug, backup_count) {
if ('undefined' != typeof updraft_restore_screen && updraft_restore_screen) return;
if ('undefined' === typeof debug) {
debug = jQuery('#updraft_debug_mode').is(':checked') ? 1 : 0;
}
var unixtime = Math.round(new Date().getTime() / 1000);
if (1 == rescan || 1 == remotescan) {
updraft_historytimer_notbefore = unixtime + 30;
} else {
if (unixtime < updraft_historytimer_notbefore && 'undefined' === typeof backup_count) {
console.log("Update history skipped: "+unixtime.toString()+" < "+updraft_historytimer_notbefore.toString());
return;
}
}
if ('undefined' === typeof backup_count) {
backup_count = 0;
}
if (rescan == 1) {
if (remotescan == 1) {
updraft_history_lastchecksum = false;
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').html('
');
}
}
var what_op = remotescan ? 'remotescan' : (rescan ? 'rescan' : false);
var data = {
operation: what_op,
debug: debug,
backup_count: backup_count,
}
updraft_send_command('rescan', data, function(resp) {
if (resp.hasOwnProperty('logs_exist') && resp.logs_exist) {
// Show the "most recently modified log" link, in case it was previously hidden (if there were no logs until now)
jQuery('#updraft_lastlogmessagerow .updraft-log-link').show();
}
if (resp.hasOwnProperty('migrate_tab') && resp.migrate_tab) {
if (!jQuery('#updraft-navtab-migrate').hasClass('nav-tab-active')) {
jQuery('#updraft_migrate_tab_alt').html('');
jQuery('#updraft_migrate').replaceWith(jQuery(resp.migrate_tab).find('#updraft_migrate'));
setup_migrate_tabs();
}
}
if (resp.hasOwnProperty('web_server_disk_space')) {
if ('' == resp.web_server_disk_space) {
console.log("UpdraftPlus: web_server_disk_space is empty");
if (jQuery('#updraft-navtab-backups-content .updraft-server-disk-space').length) {
jQuery('#updraft-navtab-backups-content .updraft-server-disk-space').slideUp('slow', function() {
jQuery(this).remove();
});
}
} else {
if (jQuery('#updraft-navtab-backups-content .updraft-server-disk-space').length) {
jQuery('#updraft-navtab-backups-content .updraft-server-disk-space').replaceWith(resp.web_server_disk_space);
} else {
jQuery('#updraft-navtab-backups-content .updraft-disk-space-actions').prepend(resp.web_server_disk_space);
}
}
}
update_backupnow_modal(resp);
if (resp.hasOwnProperty('backupnow_file_entities')) {
impossible_increment_entities = resp.backupnow_file_entities;
}
if (resp.n != null) { jQuery('#updraft-existing-backups-heading').html(resp.n); }
if (resp.t != null) {
if (resp.cksum != null) {
if (resp.cksum == updraft_history_lastchecksum) {
// Avoid unnecessarily refreshing the HTML if the data is the same. This helps avoid resetting the DOM (annoying when debugging), and keeps user row selections.
return;
}
updraft_history_lastchecksum = resp.cksum;
}
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').html(resp.t);
updraft_backups_selection.checkSelectionStatus();
if (resp.data) {
console.log(resp.data);
}
}
});
}
/**
* This function will check if the passed in response contains content for the backup now modal that needs updating on page
*
* @param {array} response - an array that may contain backupnow_modal content that needs updating
*/
function update_backupnow_modal(response) {
if (response.hasOwnProperty('modal_afterfileoptions')) {
jQuery('.backupnow_modal_afterfileoptions').html(response.modal_afterfileoptions);
}
}
/**
* Exclude entities hidden input field update
*
* @param {string} include_entity_name - backup entity name
*/
function updraft_exclude_entity_update(include_entity_name) {
var exclude_entities = [];
jQuery('#updraft_include_'+include_entity_name+'_exclude_container .updraft_exclude_entity_wrapper .updraft_exclude_entity_field').each(function() {
var data_val = jQuery(this).data('val').toString().trim();
if ('' != data_val) {
exclude_entities.push(data_val);
}
});
jQuery('#updraft_include_'+include_entity_name+'_exclude').val(exclude_entities.join(','));
}
/**
* Check uniqueness of exclude rule in include_backup_file
*
* @param {string} exclude_rule - exclude rule
* @param {string} include_backup_file - the backup file type on which the exclude_rule will be applied
*
* @return {boolean} true if exclude_rule is unique otherwise false
*/
function updraft_is_unique_exclude_rule(exclude_rule, include_backup_file) {
existing_exclude_rules_str = jQuery('#updraft_include_'+include_backup_file+'_exclude').val();
existing_exclude_rules = existing_exclude_rules_str.split(',');
if (jQuery.inArray(exclude_rule, existing_exclude_rules) > -1) {
alert(updraftlion.duplicate_exclude_rule_error_msg)
return false;
} else {
return true;
}
}
var updraft_interval_week_val = false;
var updraft_interval_month_val = false;
function updraft_intervals_monthly_or_not(selector_id, now_showing) {
var selector = '#updraft-navtab-settings-content #'+selector_id;
var current_length = jQuery(selector+' option').length;
var is_monthly = ('monthly' == now_showing) ? true : false;
var existing_is_monthly = false;
if (current_length > 10) { existing_is_monthly = true; }
if (!is_monthly && !existing_is_monthly) {
return;
}
if (is_monthly && existing_is_monthly) {
if ('monthly' == now_showing) {
// existing_is_monthly does not mean the same as now_showing=='monthly'. existing_is_monthly refers to the drop-down, not whether the drop-down is being displayed. We may need to add these words back.
jQuery('.updraft_monthly_extra_words_'+selector_id).remove();
jQuery(selector).before(''+updraftlion.day+' ').after(' '+updraftlion.inthemonth+' ');
}
return;
}
jQuery('.updraft_monthly_extra_words_'+selector_id).remove();
if (is_monthly) {
// Save the old value
updraft_interval_week_val = jQuery(selector+' option:selected').val();
jQuery(selector).html(updraftlion.mdayselector).before(''+updraftlion.day+' ').after(' '+updraftlion.inthemonth+' ');
var select_mday = (updraft_interval_month_val === false) ? 1 : updraft_interval_month_val;
// Convert from day of the month (ordinal) to option index (starts at 0)
select_mday = select_mday - 1;
jQuery(selector+" option").eq(select_mday).prop('selected', true);
} else {
// Save the old value
updraft_interval_month_val = jQuery(selector+' option:selected').val();
jQuery(selector).html(updraftlion.dayselector);
var select_day = (updraft_interval_week_val === false) ? 1 : updraft_interval_week_val;
jQuery(selector+" option").eq(select_day).prop('selected', true);
}
}
function updraft_check_same_times() {
var dbmanual = 0;
var file_interval = jQuery('#updraft-navtab-settings-content .updraft_interval').val();
if (file_interval == 'manual') {
// jQuery('#updraft_files_timings').css('opacity', '0.25');
jQuery('#updraft-navtab-settings-content .updraft_files_timings').hide();
} else {
// jQuery('#updraft_files_timings').css('opacity', 1);
jQuery('#updraft-navtab-settings-content .updraft_files_timings').show();
}
if ('weekly' == file_interval || 'fortnightly' == file_interval || 'monthly' == file_interval) {
updraft_intervals_monthly_or_not('updraft_startday_files', file_interval);
jQuery('#updraft-navtab-settings-content #updraft_startday_files').show();
} else {
jQuery('.updraft_monthly_extra_words_updraft_startday_files').remove();
jQuery('#updraft-navtab-settings-content #updraft_startday_files').hide();
}
var db_interval = jQuery('#updraft-navtab-settings-content .updraft_interval_database').val();
if (db_interval == 'manual') {
dbmanual = 1;
// jQuery('#updraft_db_timings').css('opacity', '0.25');
jQuery('#updraft-navtab-settings-content .updraft_db_timings').hide();
}
if ('weekly' == db_interval || 'fortnightly' == db_interval || 'monthly' == db_interval) {
updraft_intervals_monthly_or_not('updraft_startday_db', db_interval);
jQuery('#updraft-navtab-settings-content #updraft_startday_db').show();
} else {
jQuery('.updraft_monthly_extra_words_updraft_startday_db').remove();
jQuery('#updraft-navtab-settings-content #updraft_startday_db').hide();
}
if (db_interval == file_interval) {
// jQuery('#updraft_db_timings').css('opacity','0.25');
jQuery('#updraft-navtab-settings-content .updraft_db_timings').hide();
// jQuery('#updraft_same_schedules_message').show();
if (0 == dbmanual) {
jQuery('#updraft-navtab-settings-content .updraft_same_schedules_message').show();
} else {
jQuery('#updraft-navtab-settings-content .updraft_same_schedules_message').hide();
}
} else {
jQuery('#updraft-navtab-settings-content .updraft_same_schedules_message').hide();
if (0 == dbmanual) {
// jQuery('#updraft_db_timings').css('opacity', '1');
jQuery('#updraft-navtab-settings-content .updraft_db_timings').show();
}
}
}
// Visit the site in the background every 3.5 minutes - ensures that backups can progress if you've got the UD settings page open
if ('undefined' !== typeof updraft_siteurl) {
setInterval(function() {
jQuery.get(updraft_siteurl+'/wp-cron.php');}, 210000);
}
function updraft_activejobs_delete(jobid) {
updraft_aborted_jobs[jobid] = 1;
jQuery('#updraft-jobid-'+jobid).closest('.updraft_row').addClass('deleting');
updraft_send_command('activejobs_delete', jobid, function(resp) {
var job_row = jQuery('#updraft-jobid-'+jobid).closest('.updraft_row');
job_row.addClass('deleting');
if (resp.ok == 'Y') {
jQuery('#updraft-jobid-'+jobid).html(resp.m);
job_row.remove();
// inpage backup - Close modal if canceling backup
if (jQuery('#updraft-backupnow-inpage-modal').dialog('isOpen')) jQuery('#updraft-backupnow-inpage-modal').dialog('close');
updraft_show_success_modal({
message: updraft_active_job_is_clone(jobid) ? updraftlion.clone_backup_aborted : updraftlion.backup_aborted,
icon: 'no-alt',
classes: 'warning'
});
} else if ('N' == resp.ok) {
job_row.removeClass('deleting');
alert(resp.m);
} else {
job_row.removeClass('deleting');
alert(updraftlion.unexpectedresponse);
console.log(resp);
}
});
}
function updraftplus_diskspace_entity(key) {
jQuery('#updraft_diskspaceused_'+key).html(''+updraftlion.calculating+'');
updraft_send_command('get_fragment', { fragment: 'disk_usage', data: key }, function(response) {
jQuery('#updraft_diskspaceused_'+key).html(response.output);
}, { type: 'GET' });
}
/**
* Checks if the specified job is a clone
*
* @param {string} job_id The job ID
*
* @return {int}
*/
function updraft_active_job_is_clone(job_id) {
return updraft_clone_jobs.filter(function(val) {
return val == job_id;
}).length;
}
/**
* Open a modal with content fetched from an iframe
*
* @param {String} getwhat - the subaction parameter to pass to UD's AJAX handler
* @param {String} title - the title for the modal
*/
function updraft_iframe_modal(getwhat, title) {
var width = 780;
var height = 500;
jQuery('#updraft-iframe-modal-innards').html('');
jQuery('#updraft-iframe-modal').dialog({
title: title, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false,
open: function(event, ui) {
jQuery(this).dialog('option', 'width', width),
jQuery(this).dialog('option', 'minHeight', 260);
if (jQuery(window).height() > height) {
jQuery(this).dialog('option', 'height', height);
} else {
jQuery(this).dialog('option', 'height', jQuery(window).height()-30);
}
}
}).dialog('open');
}
function updraft_html_modal(showwhat, title, width, height) {
jQuery('#updraft-iframe-modal-innards').html(showwhat);
var updraft_html_modal_buttons = {};
if (width < 450) {
updraft_html_modal_buttons[updraftlion.close] = function() {
jQuery(this).dialog("close"); };
}
jQuery('#updraft-iframe-modal').dialog({
title: title, buttons: updraft_html_modal_buttons, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false,
open: function(event, ui) {
jQuery(this).dialog('option', 'width', width),
jQuery(this).dialog('option', 'minHeight', 260);
if (jQuery(window).height() > height) {
jQuery(this).dialog('option', 'height', height);
} else {
jQuery(this).dialog('option', 'height', jQuery(window).height()-30);
}
}
}).dialog('open');
}
function updraftplus_diskspace() {
jQuery('#updraft-navtab-backups-content .updraft_diskspaceused').html(''+updraftlion.calculating+'');
updraft_send_command('get_fragment', { fragment: 'disk_usage', data: 'updraft' }, function(response) {
jQuery('#updraft-navtab-backups-content .updraft_diskspaceused').html(response.output);
}, { type: 'GET' });
}
var lastlog_lastmessage = "";
function updraftplus_deletefromserver(timestamp, type, findex) {
if (!findex) findex=0;
var pdata = {
stage: 'delete',
timestamp: timestamp,
type: type,
findex: findex
};
updraft_send_command('updraft_download_backup', pdata, null, { action: 'updraft_download_backup', nonce: updraft_download_nonce, nonce_key: '_wpnonce' });
}
function updraftplus_downloadstage2(timestamp, type, findex) {
location.href =ajaxurl+'?_wpnonce='+updraft_download_nonce+'×tamp='+timestamp+'&type='+type+'&stage=2&findex='+findex+'&action=updraft_download_backup';
}
function updraftplus_show_contents(timestamp, type, findex) {
var modal_content = '
' + updraftlion.zip_file_contents_info + ' -
'+updraftlion.browse_download_link+'
';
updraft_html_modal(modal_content, updraftlion.zip_file_contents, 780, 500);
zip_files_jstree('zipbrowser', timestamp, type, findex);
}
/**
* Creates the jstree and makes a call to the backend to dynamically get the tree nodes
*
* @param {string} entity Entity for the jstree
* @param {integer} timestamp Timestamp of the jstree
* @param {string} type Type of file to display in the JS tree
* @param {array} findex Index of Zip
*/
function zip_files_jstree(entity, timestamp, type, findex) {
jQuery('#updraft_zip_files_jstree').jstree({
"core": {
"multiple": false,
"data": function (nodeid, callback) {
updraft_send_command('get_jstree_directory_nodes', {entity:entity, node:nodeid, timestamp:timestamp, type:type, findex:findex}, function(response) {
if (response.hasOwnProperty('error')) {
alert(response.error);
} else {
callback.call(this, response.nodes);
}
}, { error_callback: function(response, status, error_code, resp) {
if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) {
console.error(resp.fatal_error_message);
jQuery('#updraft_zip_files_jstree').html('
');
console.log(error_message);
alert(error_message);
console.log(response);
}
}
});
},
"error": function(error) {
alert(error);
console.log(error);
},
},
"search": {
"show_only_matches": true
},
"plugins": ["search", "sort"],
});
// Update modal title once tree loads
jQuery('#updraft_zip_files_jstree').on('ready.jstree', function(e, data) {
jQuery('#updraft-iframe-modal').dialog('option', 'title', updraftlion.zip_file_contents + ': ' + data.instance.get_node('#').children[0])
});
// Search function for jstree, this will hide nodes that don't match the search
var timeout = false;
jQuery('#zip_files_jstree_search').on('keyup', function () {
if (timeout) { clearTimeout(timeout); }
timeout = setTimeout(function () {
var value = jQuery('#zip_files_jstree_search').val();
jQuery('#updraft_zip_files_jstree').jstree(true).search(value);
}, 250);
});
// Detect change on the tree and update the input that has been marked as editing
jQuery('#updraft_zip_files_jstree').on("changed.jstree", function (e, data) {
jQuery('#updraft_zip_path_text').text(data.node.li_attr.path);
if (data.node.li_attr.size) {
jQuery('#updraft_zip_size_text').text(data.node.li_attr.size);
jQuery('#updraft_zip_download_item').show();
} else {
jQuery('#updraft_zip_size_text').text('');
jQuery('#updraft_zip_download_item').hide();
}
});
jQuery('#updraft_zip_download_item').on('click', function(event) {
event.preventDefault();
var path = jQuery('#updraft_zip_path_text').text();
updraft_send_command('get_zipfile_download', {path:path, timestamp:timestamp, type:type, findex:findex}, function(response) {
if (response.hasOwnProperty('error')) {
alert(response.error);
} else if (response.hasOwnProperty('path')) {
location.href =ajaxurl+'?_wpnonce='+updraft_download_nonce+'×tamp='+timestamp+'&type='+type+'&stage=2&findex='+findex+'&filepath='+response.path+'&action=updraft_download_backup';
} else {
alert(updraftlion.download_timeout);
}
}, { error_callback: function(response, status, error_code, resp) {
if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) {
console.error(resp.fatal_error_message);
alert(resp.fatal_error_message);
} else {
var error_message = "updraft_send_command: error: "+status+" ("+error_code+")";
console.log(error_message);
alert(error_message);
console.log(response);
}
}
});
});
}
/**
* This function will clean up the updraft downloader UI
*
* @param {object} item - the object pressed in the UI
* @param {string} what - the file entity
*/
function remove_updraft_downloader(item, what) {
jQuery(item).closest('.updraftplus_downloader').fadeOut().remove();
if (0 == jQuery('.updraftplus_downloader_container_'+what+' .updraftplus_downloader').length) jQuery('.updraftplus_downloader_container_'+what).remove();
}
/**
* This function will prepare the downloader UI and kick of the request to download the file entities.
*
* @param {string} base - the base string for the id
* @param {integer} backup_timestamp - the backup timestamp
* @param {string} what - the file entity
* @param {string} whicharea - the area we want to append the downloader
* @param {string} set_contents - the contents we want to download
* @param {string} prettydate - the pretty backup date
* @param {boolean} async - boolean to indicate if this is a async request or not
*/
function updraft_downloader(base, backup_timestamp, what, whicharea, set_contents, prettydate, async) {
if (typeof set_contents !== "string") set_contents = set_contents.toString();
jQuery('.ud_downloadstatus').show();
var set_contents = set_contents.split(',');
var prdate = (prettydate) ? prettydate : backup_timestamp;
// Old-style, from when it was a form
// var data = jQuery('#updraft-navtab-backups-content .uddownloadform_'+what+'_'+backup_timestamp+'_'+set_contents[i]).serialize();
var nonce = jQuery('#updraft-navtab-backups-content .uddownloadform_'+what+'_'+backup_timestamp+'_'+set_contents[0]).data('wp_nonce').toString();
if (!jQuery('.updraftplus_downloader_container_'+what).length) {
jQuery(whicharea).append('');
jQuery('.updraftplus_downloader_container_' + what).append('' + updraftlion.download + ' ' + what + ' (' + prdate + '):');
}
for (var i = 0; i < set_contents.length; i++) {
// Create somewhere for the status to be found
var stid = base+backup_timestamp+'_'+what+'_'+set_contents[i];
var stid_selector = '.'+stid;
var show_index = parseInt(set_contents[i]); show_index++;
var itext = (0 == set_contents[i]) ? '' : ' ('+show_index+')';
if (!jQuery(stid_selector).length) {
jQuery('.updraftplus_downloader_container_'+what).append('
'+what+itext+':
'+updraftlion.begunlooking+'
');
jQuery(stid_selector).data('downloaderfor', { base: base, nonce: backup_timestamp, what: what, index: set_contents[i] });
setTimeout(function() {
updraft_activejobs_update(true);
},
1500);
}
jQuery(stid_selector).data('lasttimebegan', (new Date).getTime());
}
// Now send the actual request to kick it all off
async = async ? true : false;
var data = {
type: what,
timestamp: backup_timestamp,
findex: set_contents
};
var options = {
action: 'updraft_download_backup',
nonce_key: '_wpnonce',
nonce: nonce,
timeout: 10000,
async: async
}
updraft_send_command('updraft_download_backup', data, function (response) {}, options);
// We don't want the form to submit as that replaces the document
return false;
}
/**
* Parse JSON string, including automatically detecting unwanted extra input and skipping it
*
* @param {string} json_mix_str - JSON string which need to parse and convert to object
* @param {boolean} analyse - if true, then the return format will contain information on the parsing, and parsing will skip attempting to JSON.parse() the entire string (will begin with trying to locate the actual JSON)
*
* @throws SyntaxError|String (including passing on what JSON.parse may throw) if a parsing error occurs.
*
* @returns Mixed parsed JSON object. Will only return if parsing is successful (otherwise, will throw). If analyse is true, then will rather return an object with properties (mixed)parsed, (integer)json_start_pos and (integer)json_end_pos
*/
function ud_parse_json(json_mix_str, analyse) {
analyse = ('undefined' === typeof analyse) ? false : true;
// Just try it - i.e. the 'default' case where things work (which can include extra whitespace/line-feeds, and simple strings, etc.).
if (!analyse) {
try {
var result = JSON.parse(json_mix_str);
return result;
} catch (e) {
console.log('UpdraftPlus: Exception when trying to parse JSON (1) - will attempt to fix/re-parse based upon first/last curly brackets');
console.log(json_mix_str);
}
}
var json_start_pos = json_mix_str.indexOf('{');
var json_last_pos = json_mix_str.lastIndexOf('}');
// Case where some php notice may be added after or before json string
if (json_start_pos > -1 && json_last_pos > -1) {
var json_str = json_mix_str.slice(json_start_pos, json_last_pos + 1);
try {
var parsed = JSON.parse(json_str);
if (!analyse) { console.log('UpdraftPlus: JSON re-parse successful'); }
return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: json_last_pos + 1 } : parsed;
} catch (e) {
console.log('UpdraftPlus: Exception when trying to parse JSON (2) - will attempt to fix/re-parse based upon bracket counting');
var cursor = json_start_pos;
var open_count = 0;
var last_character = '';
var inside_string = false;
// Don't mistake this for a real JSON parser. Its aim is to improve the odds in real-world cases seen, not to arrive at universal perfection.
while ((open_count > 0 || cursor == json_start_pos) && cursor <= json_last_pos) {
var current_character = json_mix_str.charAt(cursor);
if (!inside_string && '{' == current_character) {
open_count++;
} else if (!inside_string && '}' == current_character) {
open_count--;
} else if ('"' == current_character && '\\' != last_character) {
inside_string = inside_string ? false : true;
}
last_character = current_character;
cursor++;
}
console.log("Started at cursor="+json_start_pos+", ended at cursor="+cursor+" with result following:");
console.log(json_mix_str.substring(json_start_pos, cursor));
try {
var parsed = JSON.parse(json_mix_str.substring(json_start_pos, cursor));
console.log('UpdraftPlus: JSON re-parse successful');
return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: cursor } : parsed;
} catch (e) {
// Throw it again, so that our function works just like JSON.parse() in its behaviour.
throw e;
}
}
}
throw "UpdraftPlus: could not parse the JSON";
}
// Catch HTTP errors if the download status check returns them
jQuery(document).ajaxError(function(event, jqxhr, settings, exception) {
if (exception == null || exception == '') return;
if (jqxhr.responseText == null || jqxhr.responseText == '') return;
console.log("Error caught by UpdraftPlus ajaxError handler (follows) for "+settings.url);
console.log(exception);
if (settings.url.search(ajaxurl) == 0) {
// TODO subaction=downloadstatus is no longer used. This should be adjusted to the current set-up.
if (settings.url.search('subaction=downloadstatus') >= 0) {
var timestamp = settings.url.match(/timestamp=\d+/);
var type = settings.url.match(/type=[a-z]+/);
var findex = settings.url.match(/findex=\d+/);
var base = settings.url.match(/base=[a-z_]+/);
findex = (findex instanceof Array) ? parseInt(findex[0].substr(7)) : 0;
type = (type instanceof Array) ? type[0].substr(5) : '';
base = (base instanceof Array) ? base[0].substr(5) : '';
timestamp = (timestamp instanceof Array) ? parseInt(timestamp[0].substr(10)) : 0;
if ('' != base && '' != type && timestamp >0) {
var stid = base+timestamp+'_'+type+'_'+findex;
jQuery('.'+stid+' .raw').html(''+updraftlion.error+' '+updraftlion.servererrorcode);
}
} else if (settings.url.search('subaction=restore_alldownloaded') >= 0) {
// var timestamp = settings.url.match(/timestamp=\d+/);
jQuery('#updraft-restore-modal-stage2a').append(' '+updraftlion.error+' '+updraftlion.servererrorcode+': '+exception);
}
}
});
function updraft_restorer_checkstage2(doalert) {
// How many left?
var stilldownloading = jQuery('#ud_downloadstatus2 .file').length;
if (stilldownloading > 0) {
if (doalert) { alert(updraftlion.stilldownloading); }
return;
}
// Allow pressing 'Restore' to proceed
jQuery('.updraft-restore--next-step').prop('disabled', true);
jQuery('#updraft-restore-modal-stage2a').html(' '+updraftlion.preparing_backup_files);
updraft_send_command('restore_alldownloaded', {
timestamp: jQuery('#updraft_restore_timestamp').val(),
restoreopts: jQuery('#updraft_restore_form').serialize()
}, function(resp, status, data) {
var info = null;
jQuery('#updraft_restorer_restore_options').val('');
jQuery('.updraft-restore--next-step').prop('disabled', false);
try {
// var resp = ud_parse_json(data);
if (null == resp) {
jQuery('#updraft-restore-modal-stage2a').html(updraftlion.emptyresponse);
return;
}
var report = resp.m;
if (resp.w != '') {
report = report + '
' + updraftlion.warnings +'
' + resp.w + '
';
}
if (resp.e != '') {
report = report + '
' + updraftlion.errors+'
' + resp.e + '
';
} else {
updraft_restore_stage = 3;
}
if (resp.hasOwnProperty('i')) {
// Store the information passed back from the backup scan
try {
info = ud_parse_json(resp.i);
// if (info.hasOwnProperty('multisite') && info.multisite && info.hasOwnProperty('same_url') && info.same_url) {
if (info.hasOwnProperty('addui')) {
console.log("Further UI options are being displayed");
var addui = info.addui;
report += '
'+addui+'
';
if (typeof JSON == 'object' && typeof JSON.stringify == 'function') {
// If possible, remove from the stored info, to prevent passing back potentially large amounts of unwanted data
delete info.addui;
resp.i = JSON.stringify(info);
}
}
if (info.hasOwnProperty('php_max_input_vars')) {
php_max_input_vars = parseInt(info.php_max_input_vars);
}
if (info.hasOwnProperty('skipped_db_scan')) {
skipped_db_scan = parseInt(info.skipped_db_scan);
}
} catch (err) {
console.log(err);
console.log(resp);
}
jQuery('#updraft_restorer_backup_info').val(resp.i);
} else {
jQuery('#updraft_restorer_backup_info').val();
}
jQuery('#updraft-restore-modal-stage2a').html(report);
jQuery('.updraft-restore--next-step').text(updraftlion.restore);
if (jQuery('#updraft-restore-modal-stage2a .updraft_select2').length > 0) {
jQuery('#updraft-restore-modal-stage2a .updraft_select2').select2();
}
} catch (err) {
console.log(data);
console.log(err);
jQuery('#updraft-restore-modal-stage2a').text(updraftlion.jsonnotunderstood+' '+updraftlion.errordata+": "+data).html();
}
}, { error_callback: function(response, status, error_code, resp) {
if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) {
console.error(resp.fatal_error_message);
jQuery('#updraft-restore-modal-stage2a').html('
'); // Removed (just before closing ) to make clearer it's complete.
jQuery('#' + file.id + " .fileprogress").width(file.percent + "%");
}
});
uploader.bind('Error', function(up, error) {
console.log(error);
var err_makesure;
if (error.code == "-200") {
err_makesure = '\n'+updraftlion.makesure2;
} else {
err_makesure = updraftlion.makesure;
}
var msg = updraftlion.uploaderr+' (code '+error.code+') : '+error.message;
if (error.hasOwnProperty('status') && error.status) {
msg += ' ('+updraftlion.http_code+' '+error.status+')';
}
if (error.hasOwnProperty('response')) {
console.log('UpdraftPlus: plupload error: '+error.response);
if (error.response.length < 100) msg += ' '+updraftlion.error+' '+error.response+'\n';
}
msg += ' '+err_makesure;
alert(msg);
});
// a file was uploaded
uploader.bind('FileUploaded', function(up, file, response) {
if (response.status == '200') {
// this is your ajax response, update the DOM with it or something...
try {
resp = ud_parse_json(response.response);
if (resp.e) {
alert(updraftlion.uploaderror+" "+resp.e);
} else if (resp.dm) {
alert(resp.dm);
updraft_updatehistory(1, 0);
} else if (resp.m) {
updraft_updatehistory(1, 0);
} else {
alert('Unknown server response: '+response.response);
}
} catch (err) {
console.log(response);
alert(updraftlion.jsonnotunderstood);
}
} else {
alert('Unknown server response status: '+response.code);
console.log(response);
}
});
}
// Functions in the debugging console
jQuery('#updraftplus_httpget_go').on('click', function(e) {
e.preventDefault();
updraftplus_httpget_go(0);
});
jQuery('#updraftplus_httpget_gocurl').on('click', function(e) {
e.preventDefault();
updraftplus_httpget_go(1);
});
jQuery('#updraftplus_callwpaction_go').on('click', function(e) {
e.preventDefault();
params = { wpaction: jQuery('#updraftplus_callwpaction').val() };
updraft_send_command('call_wordpress_action', params, function(response) {
if (response.e) {
alert(response.e);
} else if (response.s) {
// Silence
} else if (response.r) {
jQuery('#updraftplus_callwpaction_results').html(response.r);
} else {
console.log(response);
alert(updraftlion.jsonnotunderstood);
}
});
});
function updraftplus_httpget_go(curl) {
params = { uri: jQuery('#updraftplus_httpget_uri').val() };
params.curl = curl;
updraft_send_command('httpget', params, function(resp) {
if (resp.e) { alert(resp.e); }
if (resp.r) {
jQuery('#updraftplus_httpget_results').html('
'+resp.r+'
');
} else {
console.log(resp);
}
}, { type: 'GET' });
}
jQuery('#updraft_activejobs_table, #updraft-navtab-migrate-content').on('click', '.updraft_jobinfo_delete', function(e) {
e.preventDefault();
var job_id = jQuery(this).data('jobid');
if (job_id) {
$(this).addClass('disabled');
updraft_activejobs_delete(job_id);
} else {
console.log("UpdraftPlus: A stop job link was clicked, but the Job ID could not be found");
}
});
jQuery('#updraft_activejobs_table, #updraft-navtab-backups-content .updraft_existing_backups, #updraft-backupnow-inpage-modal, #updraft-navtab-migrate-content').on('click', '.updraft-log-link', function(e) {
e.preventDefault();
var file_id = jQuery(this).data('fileid');
var job_id = jQuery(this).data('jobid');
if (file_id) {
updraft_popuplog(file_id);
} else if (job_id) {
updraft_popuplog(job_id);
} else {
console.log("UpdraftPlus: A log link was clicked, but the Job ID could not be found");
}
});
function updraft_restore_setup(entities, key, show_data) {
updraft_restore_setoptions(entities);
jQuery('#updraft_restore_timestamp').val(key);
jQuery('.updraft_restore_date').html(show_data);
updraft_restore_stage = 1;
// jQuery('#updraft-restore-modal').dialog('open');
updraft_restore_modal.open();
updraft_activejobs_update(true);
}
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', 'button.choose-components-button', function(e) {
var entities = jQuery(this).data('entities');
var backup_timestamp = jQuery(this).data('backup_timestamp');
var show_data = jQuery(this).data('showdata');
updraft_restore_setup(entities, backup_timestamp, show_data);
});
/**
* Get the value of a named URL parameter - https://stackoverflow.com/questions/4548487/jquery-read-query-string
*
* @param {string} name - URL parameter to return the value of
*
* @returns {string}
*/
function get_parameter_by_name(name) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex_s = "[\\?&]"+name+"=([^]*)";
var regex = new RegExp(regex_s);
var results = regex.exec(window.location.href);
if (results == null) {
return '';
} else {
return decodeURIComponent(results[1].replace(/\+/g, ' '));
}
}
if (get_parameter_by_name('udaction') == 'initiate_restore') {
var entities = get_parameter_by_name('entities');
var backup_timestamp = get_parameter_by_name('backup_timestamp');
var show_data = get_parameter_by_name('showdata');
updraft_restore_setup(entities, backup_timestamp, show_data);
}
var updraft_upload_modal_buttons = {};
updraft_upload_modal_buttons[updraftlion.uploadbutton] = function () {
var key = jQuery('#updraft_upload_timestamp').val();
var nonce = jQuery('#updraft_upload_nonce').val();
var services = '';
var send_list = false;
jQuery('.updraft_remote_storage_destination').each(function (index) {
if (jQuery(this).is(':checked')) { send_list = true; }
});
if (!send_list) {
jQuery('#updraft-upload-modal-error').html(updraftlion.local_upload_error);
return;
} else {
services = jQuery("input[name^='updraft_remote_storage_destination_']").serializeArray();
}
jQuery(this).dialog("close");
alert(updraftlion.local_upload_started);
updraft_send_command('upload_local_backup', {
use_nonce: nonce,
use_timestamp: key,
services: services
}, function (response) {});
};
updraft_upload_modal_buttons[updraftlion.cancel] = function () {
jQuery(this).dialog("close");
};
jQuery("#updraft-upload-modal").dialog({
autoOpen: false, modal: true, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false,
open: function(event, ui) {
$(this).parent().trigger('focus');
$(this).dialog('option', 'width', 308);
if (jQuery(window).height() > 460) {
$(this).dialog('option', 'height', 318);
} else if (jQuery(window).height() > 250 && jQuery(window).height() < 461) {
$(this).dialog('option', 'height', 460);
} else {
$(this).dialog('option', 'height', jQuery(window).height() - 20);
}
},
buttons: updraft_upload_modal_buttons
});
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', 'button.updraft-upload-link', function (e) {
e.preventDefault();
var nonce = jQuery(this).data('nonce').toString();
var key = jQuery(this).data('key').toString();
var services = jQuery(this).data('services').toString();
if (nonce) {
updraft_upload(key, nonce, services);
} else {
console.log("UpdraftPlus: A upload link was clicked, but the Job ID could not be found");
}
});
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', '.updraft-load-more-backups', function (e) {
e.preventDefault();
var backup_count = parseInt(jQuery('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row').length) + parseInt(updraftlion.existing_backups_limit);
updraft_updatehistory(0, 0, 0, backup_count);
});
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', '.updraft-load-all-backups', function (e) {
e.preventDefault();
updraft_updatehistory(0, 0, 0, 9999999);
});
/**
* Opens the dialog box for confirmation of where to upload the backup
*
* @param {string} key - The UNIX timestamp of the backup
* @param {string} nonce - The backup job ID
* @param {string} services - A list of services that have not been uploaded to yet
*/
function updraft_upload(key, nonce, services) {
jQuery('#updraft_upload_timestamp').val(key);
jQuery('#updraft_upload_nonce').val(nonce);
var services_array = services.split(",");
jQuery('.updraft_remote_storage_destination').each(function (index) {
var name = jQuery(this).val();
if (jQuery.inArray(name, services_array) == -1) {
jQuery(this).prop('checked', false);
jQuery(this).prop('disabled', true);
var label = $(this).prop("labels");
jQuery(label).find('span').show();
}
});
jQuery('#updraft-upload-modal').dialog('open');
}
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', '.updraft-delete-link', function(e) {
e.preventDefault();
var hasremote = jQuery(this).data('hasremote');
var nonce = jQuery(this).data('nonce').toString();
var key = jQuery(this).data('key').toString();
if (nonce) {
updraft_delete(key, nonce, hasremote);
} else {
console.log("UpdraftPlus: A delete link was clicked, but the Job ID could not be found");
}
});
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', 'button.updraft_download_button', function(e) {
e.preventDefault();
var base = 'uddlstatus_';
var backup_timestamp = jQuery(this).data('backup_timestamp');
var what = jQuery(this).data('what');
var whicharea = '.ud_downloadstatus';
var set_contents = jQuery(this).data('set_contents');
var prettydate = jQuery(this).data('prettydate');
var async = true;
updraft_downloader(base, backup_timestamp, what, whicharea, set_contents, prettydate, async);
});
jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('dblclick', '.updraft_existingbackup_date', function (e) {
e.preventDefault();
var nonce = jQuery(this).data('nonce').toString();
var timestamp = jQuery(this).data('timestamp').toString();
updraft_send_command('rawbackup_history', { timestamp: timestamp, nonce: nonce }, function (response) {
if (response.hasOwnProperty('rawbackup')) {
var textArea = document.createElement('textarea');
textArea.innerHTML = response.rawbackup;
updraft_html_modal(textArea.value, updraftlion.raw, 780, 500);
} else {
updraft_html_modal(updraftlion.jsonnotunderstood, updraftlion.raw, 780, 500);
}
}, { type: 'POST' });
updraft_html_modal('
');
});
up.refresh();
up.start();
});
uploader.bind('UploadProgress', function(up, file) {
jQuery('#' + file.id + " .fileprogress").width(file.percent + "%");
jQuery('#' + file.id + " span").html(plupload.formatSize(parseInt(file.size * file.percent / 100)));
});
uploader.bind('Error', function(up, error) {
if ('-200' == error.code) {
err_makesure = '\n'+updraftlion.makesure2;
} else {
err_makesure = updraftlion.makesure;
}
alert(updraftlion.uploaderr+' (code '+error.code+") : "+error.message+" "+err_makesure);
});
// a file was uploaded
uploader.bind('FileUploaded', function(up, file, response) {
if (response.status == '200') {
// this is your ajax response, update the DOM with it or something...
if (response.response.substring(0,6) == 'ERROR:') {
alert(updraftlion.uploaderror+" "+response.response.substring(6));
} else if (response.response.substring(0,3) == 'OK:') {
bkey = response.response.substring(3);
jQuery('#' + file.id + " .fileprogress").hide();
jQuery('#' + file.id).append(updraftlion.uploaded+' '+updraftlion.followlink+' '+updraftlion.thiskey+' '+jQuery('#updraftplus_db_decrypt').val().replace(/&/g, "&").replace(//g, ">"));
} else {
alert(updraftlion.unknownresp+' '+response.response);
}
} else {
alert(updraftlion.ukrespstatus+' '+response.code);
}
});
}
jQuery('#updraft-hidethis').remove();
/*
* A Handlebarsjs helper function that is used to compare
* two values if they are equal. Please refer to the example below.
* Assuming "comment_status" contains the value of "spam".
*
* @param {mixed} a The first value to compare
* @param {mixed} b The second value to compare
*
* @example
* // returns "I am spam!", otherwise "I am not a spam!"
* {{#ifeq "spam" comment_status}}
* I am spam!
* {{else}}
* I am not a spam!
* {{/ifeq}}
*
* @return {string}
*/
Handlebars.registerHelper('ifeq', function (a, b, opts) {
if ('string' !== typeof a && 'undefined' !== typeof a && null !== a) a = a.toString();
if ('string' !== typeof b && 'undefined' !== typeof b && null !== b) b = b.toString();
if (a === b) {
return opts.fn(this);
} else {
return opts.inverse(this);
}
});
/*
* Handlebars helper function to replace all password chars into asterisk char
*
* @param {string} password Required. The plain-text password
*
* @return {string}
*/
Handlebars.registerHelper('maskPassword', function(password) {
return password.replace(/./gi,'*');
});
/*
* Handlebars helper function that wraps javascript encodeURIComponent so that it could encode the following characters: , / ? : @ & = + $ #
*
* @param {string} uri Required. The URI to be encoded
*/
Handlebars.registerHelper('encodeURIComponent', function(uri) {
return encodeURIComponent(uri);
});
/**
* Handlebars helper function to compare two values using a specifed operator
*
* @see https://stackoverflow.com/questions/8853396/logical-operator-in-a-handlebars-js-if-conditional#answer-16315366
*
* @param {mixed} v1 the first value to compare
* @param {mixed} v2 the second value to compare
*
* @return {boolean} true if the first value matched against the second value, false otherwise
*/
Handlebars.registerHelper('ifCond', function(v1, operator, v2, options) {
switch (operator) {
case '==':
return (v1 == v2) ? options.fn(this) : options.inverse(this);
case '===':
return (v1 === v2) ? options.fn(this) : options.inverse(this);
case '!=':
return (v1 != v2) ? options.fn(this) : options.inverse(this);
case '!==':
return (v1 !== v2) ? options.fn(this) : options.inverse(this);
case '<':
return (v1 < v2) ? options.fn(this) : options.inverse(this);
case '<=':
return (v1 <= v2) ? options.fn(this) : options.inverse(this);
case '>':
return (v1 > v2) ? options.fn(this) : options.inverse(this);
case '>=':
return (v1 >= v2) ? options.fn(this) : options.inverse(this);
case '&&':
return (v1 && v2) ? options.fn(this) : options.inverse(this);
case '||':
return (v1 || v2) ? options.fn(this) : options.inverse(this);
case 'typeof':
return (v1 === typeof v2) ? options.fn(this) : options.inverse(this);
case 'not_typeof':
return (v1 !== typeof v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
});
/**
* Handlebars helper function for looping through a block of code a specified number of times
*
* @param {mixed} from the start value
* @param {mixed} to the end value where the loop will stop
* @param {mixed} incr the increment number
*
* @return {mixed} the current processing number
*/
Handlebars.registerHelper('for', function(from, to, incr, block) {
var accum = '';
for (var i = from; i < to; i += incr)
accum += block.fn(i);
return accum;
});
/**
* Assign value into a variable
*
* @param {string} name the variable name
* @param {mixed} val the value
*/
Handlebars.registerHelper('set_var', function(name, val, options) {
if (!options.data.root) {
options.data.root = {};
}
options.data.root[name] = val;
});
/**
* Get length of an array/object
*
* @param {mixed} object the object
*/
Handlebars.registerHelper('get_length', function(object) {
if ("undefined" !== typeof object && false === object instanceof Array) {
return Object.keys(object).length;
} else if (true === object instanceof Array) {
return object.length;
} else {
return 0;
}
});
// Add remote methods html using handlebarjs
if ($('#remote-storage-holder').length) {
var html = '';
for (var method in updraftlion.remote_storage_templates) {
if ('undefined' != typeof updraftlion.remote_storage_options[method] && 1 < Object.keys(updraftlion.remote_storage_options[method]).length) {
var template = Handlebars.compile(updraftlion.remote_storage_templates[method]);
var first_instance = true;
var instance_count = 1;
for (var instance_id in updraftlion.remote_storage_options[method]) {
if ('default' === instance_id) continue;
var context = updraftlion.remote_storage_options[method][instance_id];
if ('undefined' == typeof context['instance_conditional_logic']) {
context['instance_conditional_logic'] = {
type: '', // always by default
rules: [],
};
}
context['instance_conditional_logic'].day_of_the_week_options = updraftlion.conditional_logic.day_of_the_week_options;
context['instance_conditional_logic'].logic_options = updraftlion.conditional_logic.logic_options;
context['instance_conditional_logic'].operand_options = updraftlion.conditional_logic.operand_options;
context['instance_conditional_logic'].operator_options = updraftlion.conditional_logic.operator_options;
context['first_instance'] = first_instance;
if ('undefined' == typeof context['instance_enabled']) {
context['instance_enabled'] = 1;
}
if ('undefined' == typeof context['instance_label'] || '' == context['instance_label']) {
var method_name = updraftlion.remote_storage_methods[method];
var instance_label = ' (' + instance_count + ')';
if (1 == instance_count) {
instance_label = '';
}
context['instance_label'] = method_name + instance_label;
}
html += template(context);
first_instance = false;
instance_count++;
}
} else {
html += updraftlion.remote_storage_templates[method];
}
}
$('#remote-storage-holder').append(html).ready(function () {
$('.updraftplusmethod').not('.none').hide();
updraft_remote_storage_tabs_setup();
// Displays warning to the user of their mistake if they try to enter a URL in the OneDrive settings and saved
$('#remote-storage-holder .updraftplus_onedrive_folder_input').trigger('keyup');
});
}
});
// Save/Export/Import settings via AJAX
jQuery(function($) {
// Pre-load the image so that it doesn't jerk when first used
var my_image = new Image();
my_image.src = updraftlion.ud_url+'/images/notices/updraft_logo.png';
// When inclusion options for file entities in the settings tab, reflect that in the "Backup Now" dialog, to prevent unexpected surprises
$('#updraft-navtab-settings-content input.updraft_include_entity').on('change', function(e) {
var event_target = $(this).attr('id');
var checked = $(this).is(':checked');
var backup_target = '#backupnow_files_'+event_target;
$(backup_target).prop('checked', checked);
});
$('#updraftplus-settings-save').on('click', function(e) {
e.preventDefault();
$.blockUI({
css: {
width: '300px',
border: 'none',
'border-radius': '10px',
left: 'calc(50% - 150px)',
padding: '20px',
},
message: '
'
});
var updraft_import_file_input = document.getElementById('import_settings');
if (updraft_import_file_input.files.length == 0) {
alert(updraftlion.import_select_file);
$.unblockUI();
return;
}
var updraft_import_file_file = updraft_import_file_input.files[0];
var updraft_import_file_reader = new FileReader();
updraft_import_file_reader.onload = function() {
import_settings(this.result);
};
updraft_import_file_reader.readAsText(updraft_import_file_file);
});
function export_settings() {
var form_data = gather_updraft_settings('object');
var date_now = new Date();
// The 'version' attribute indicates the last time the format changed - i.e. do not update this unless there is a format change
form_data = JSON.stringify({
version: '1.12.40',
epoch_date: date_now.getTime(),
local_date: date_now.toLocaleString(),
network_site_url: updraftlion.network_site_url,
data: form_data
});
// Attach this data to an anchor on page
var link = document.body.appendChild(document.createElement('a'));
link.setAttribute('download', updraftlion.export_settings_file_name);
link.setAttribute('style', "display:none;");
link.setAttribute('href', 'data:text/json' + ';charset=UTF-8,' + encodeURIComponent(form_data));
link.click();
}
function import_settings(updraft_file_result) {
var parsed;
try {
parsed = ud_parse_json(updraft_file_result);
} catch (e) {
$.unblockUI();
jQuery('#import_settings').val('');
console.log(updraft_file_result);
console.log(e);
alert(updraftlion.import_invalid_json_file);
return;
}
if (window.confirm(updraftlion.importing_data_from + ' ' + parsed['network_site_url'] + "\n" + updraftlion.exported_on + ' ' + parsed['local_date'] + "\n" + updraftlion.continue_import)) {
// GET the settings back to the AJAX handler
var stringified = JSON.stringify(parsed['data']);
updraft_send_command('importsettings', {
settings: stringified,
updraftplus_version: updraftlion.updraftplus_version,
}, function(decoded_response, status, response) {
var resp = updraft_handle_page_updates(decoded_response);
if (!resp.hasOwnProperty('saved') || resp.saved) {
// Prevent the user being told they have unsaved settings
updraft_settings_form_changed = false;
// Add page updates etc based on response
location.replace(updraftlion.updraft_settings_url);
} else {
$.unblockUI();
if (resp.hasOwnProperty('error_message') && resp.error_message) {
alert(resp.error_message);
}
}
}, { action: 'updraft_importsettings', nonce: updraftplus_settings_nonce, error_callback: function(response, status, error_code, resp) {
$.unblockUI();
if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) {
console.error(resp.fatal_error_message);
alert(resp.fatal_error_message);
} else {
var error_message = "updraft_send_command: error: "+status+" ("+error_code+")";
console.log(error_message);
console.log(response);
alert(error_message);
}
}
});
} else {
$.unblockUI();
}
}
/**
* Retrieve the current settings from the DOM
*
* @param {string} output_format - the output format; valid values are 'string' or 'object'
*
* @returns String|Object
*/
function gather_updraft_settings(output_format) {
var form_data = '';
var output_format = ('undefined' === typeof output_format) ? 'string' : output_format;
if ('object' == output_format) {
// Excluding the unnecessary 'action' input avoids triggering a very mis-conceived mod_security rule seen on one user's site
form_data = $("#updraft-navtab-settings-content form input[name!='action'][name!='option_page'][name!='_wpnonce'][name!='_wp_http_referer'], #updraft-navtab-settings-content form textarea, #updraft-navtab-settings-content form select, #updraft-navtab-settings-content form input[type=checkbox]").serializeJSON({checkboxUncheckedValue: '0', useIntKeysAsArrayIndex: true});
} else {
// Excluding the unnecessary 'action' input avoids triggering a very mis-conceived mod_security rule seen on one user's site
form_data = $("#updraft-navtab-settings-content form input[name!='action'], #updraft-navtab-settings-content form textarea, #updraft-navtab-settings-content form select").serialize();
// include unchecked checkboxes. user filter to only include unchecked boxes.
$.each($('#updraft-navtab-settings-content form input[type=checkbox]')
.filter(function(idx) {
return $(this).prop('checked') == false
}),
function(idx, el) {
// attach matched element names to the form_data with chosen value.
var empty_val = '0';
form_data += '&' + $(el).attr('name') + '=' + empty_val;
}
);
}
return form_data;
}
/**
* Method to parse the response from the backend and update the page with the returned content or display error messages if failed
*
* @param {array} resp - the JSON-decoded response containing information to update the settings page with
* @param {string} response - the JSON-encoded response containing information to update the settings page with
*
* @return {object} - the decoded response (empty if decoding was not successful)
*/
function updraft_handle_page_updates(resp, response) {
try {
var messages = resp.messages;
// var debug = resp.changed.updraft_debug_mode;
// If backup dir is not writable, change the text, and grey out the 'Backup Now' button
var backup_dir_writable = resp.backup_dir.writable;
var backup_dir_message = resp.backup_dir.message;
var backup_button_title = resp.backup_dir.button_title;
} catch (e) {
console.log(e);
console.log(response);
alert(updraftlion.jsonnotunderstood);
$.unblockUI();
return {};
}
if (resp.hasOwnProperty('changed')) {
console.log("UpdraftPlus: savesettings: some values were changed after being filtered");
console.log(resp.changed);
for (prop in resp.changed) {
if ('object' === typeof resp.changed[prop]) {
for (innerprop in resp.changed[prop]) {
if (!$("[name='"+innerprop+"']").is(':checkbox')) {
$("[name='"+prop+"["+innerprop+"]']").val(resp.changed[prop][innerprop]);
}
}
} else {
if (!$("[name='"+prop+"']").is(':checkbox')) {
$("[name='"+prop+"']").val(resp.changed[prop]);
}
}
}
}
$('#updraft_writable_mess').html(backup_dir_message);
if (false == backup_dir_writable) {
$('#updraft-backupnow-button').attr('disabled', 'disabled');
$('#updraft-backupnow-button').attr('title', backup_button_title);
$('.backupdirrow').css('display', 'table-row');
} else {
$('#updraft-backupnow-button').prop('disabled', false);
$('#updraft-backupnow-button').removeAttr('title');
// $('.backupdirrow').hide();
}
if (resp.hasOwnProperty('updraft_include_more_path')) {
$('#backupnow_includefiles_moreoptions').html(resp.updraft_include_more_path);
}
if (resp.hasOwnProperty('backup_now_message')) { $('#backupnow_remote_container').html(resp.backup_now_message); }
// Move from 2 to 1
$('.updraftmessage').remove();
$('#updraft_backup_started').before(resp.messages);
console.log(resp);
// $('#updraft-next-backup-inner').html(resp.scheduled);
$('#updraft-next-files-backup-inner').html(resp.files_scheduled);
$('#updraft-next-database-backup-inner').html(resp.database_scheduled);
return resp;
}
/**
* This function has the workings for checking if any cloud storage needs authentication
* If so, these are amended to the HTML and the popup is shown to the users.
*/
function check_cloud_authentication(){
var show_auth_modal = false;
jQuery('#updraft-authenticate-modal-innards').html('');
jQuery("div[class*=updraft_authenticate_] a.updraft_authlink").each(function () {
var pretext = jQuery(this).data('pretext');
if ('undefined' === typeof pretext) pretext = '';
jQuery("#updraft-authenticate-modal-innards").append(pretext+'