tour-1-26-4.min.js
3 weeks ago
tour.js
2 years ago
updraft-admin-restore-1-26-4.min.js
3 weeks ago
updraft-admin-restore.js
1 month ago
updraftplus-deactivation-1-26-4.min.js
3 weeks ago
updraftplus-deactivation.js
2 months ago
updraft-admin-restore.js
347 lines
| 1 | var updraft_restore_screen = true; |
| 2 | jQuery(function($) { |
| 3 | |
| 4 | var job_id = $('#updraftplus_ajax_restore_job_id').val(); |
| 5 | var action = $('#updraftplus_ajax_restore_action').val(); |
| 6 | var updraft_restore_update_timer; |
| 7 | var last_received = 0; |
| 8 | var $output = $('#updraftplus_ajax_restore_output'); |
| 9 | var $steps_list = $('.updraft_restore_components_list'); |
| 10 | var previous_stage; |
| 11 | var current_stage; |
| 12 | var logged_out = false; |
| 13 | var auto_resume_count = 0; |
| 14 | var server_500_count = 0; |
| 15 | |
| 16 | $('#updraft-restore-hidethis').remove(); |
| 17 | |
| 18 | updraft_restore_command(job_id, action); |
| 19 | |
| 20 | /** |
| 21 | * This function will start the restore over ajax for the passed in job_id. |
| 22 | * |
| 23 | * @param {string} job_id - the restore job id |
| 24 | * @param {string} action - the restore action |
| 25 | */ |
| 26 | function updraft_restore_command(job_id, action) { |
| 27 | |
| 28 | var xhttp = new XMLHttpRequest(); |
| 29 | var xhttp_data = 'action=' + action + '&updraftplus_ajax_restore=do_ajax_restore&job_id=' + job_id; |
| 30 | if ('updraft_ajaxrestore' === action) xhttp_data += '&nonce=' + updraft_credentialtest_nonce; |
| 31 | var previous_data_length = 0; |
| 32 | var show_alert = true; |
| 33 | var debug = $('#updraftplus_ajax_restore_debug').length; |
| 34 | |
| 35 | xhttp.open("POST", ajaxurl, true); |
| 36 | xhttp.onprogress = function(response) { |
| 37 | if (response.currentTarget.status >= 200 && response.currentTarget.status < 300) { |
| 38 | if (-1 !== response.currentTarget.responseText.indexOf('<html')) { |
| 39 | if (show_alert) { |
| 40 | show_alert = false; |
| 41 | alert("UpdraftPlus " + updraftlion.ajax_restore_error + ' ' + updraftlion.ajax_restore_invalid_response); |
| 42 | } |
| 43 | $output.append("UpdraftPlus " + updraftlion.ajax_restore_error + ' ' + updraftlion.ajax_restore_invalid_response); |
| 44 | console.log("UpdraftPlus restore error: HTML detected in response could be a copy of the WordPress front page caused by mod_security"); |
| 45 | console.log(response.currentTarget.responseText); |
| 46 | return; |
| 47 | } |
| 48 | |
| 49 | if (previous_data_length == response.currentTarget.responseText.length) return; |
| 50 | |
| 51 | last_received = Math.round(Date.now() / 1000); |
| 52 | |
| 53 | var responseText = response.currentTarget.responseText.substr(previous_data_length); |
| 54 | |
| 55 | previous_data_length = response.currentTarget.responseText.length; |
| 56 | |
| 57 | var i = 0; |
| 58 | var end_of_json = 0; |
| 59 | |
| 60 | // Check if there is restore information json in the response if so process it and remove it from the response so that it does not make it to page |
| 61 | while (i < responseText.length) { |
| 62 | var buffer = responseText.substr(i, 7); |
| 63 | if ('RINFO:{' == buffer) { |
| 64 | // Output what precedes the RINFO: |
| 65 | $output |
| 66 | .append(responseText.substring(end_of_json, i).trim()) // add the text to the activity log |
| 67 | .scrollTop($output[0].scrollHeight); // Scroll to the bottom of the box |
| 68 | // Grab what follows RINFO: |
| 69 | var analyse_it = ud_parse_json(responseText.substr(i), true); |
| 70 | |
| 71 | if (1 == debug) { console.log(analyse_it); } |
| 72 | |
| 73 | updraft_restore_process_data(analyse_it.parsed); |
| 74 | |
| 75 | // move the for loop counter to the end of the json |
| 76 | end_of_json = i + analyse_it.json_last_pos - analyse_it.json_start_pos + 6; |
| 77 | // When the for loop goes round again, it will start with the end of the JSON |
| 78 | i = end_of_json; |
| 79 | } else { |
| 80 | i++; |
| 81 | } |
| 82 | } |
| 83 | $output.append(responseText.substr(end_of_json).trim()).scrollTop($output[0].scrollHeight); |
| 84 | // check if the fylesystem form is displayed |
| 85 | if ($output.find('input[name=connection_type]').length && $output.find('#upgrade').length) { |
| 86 | updraft_restore_setup_filesystem_form(); |
| 87 | } |
| 88 | } else { |
| 89 | if (0 == response.currentTarget.status) { |
| 90 | $output.append("UpdraftPlus " + updraftlion.ajax_restore_error + ' ' + updraftlion.ajax_restore_contact_failed); |
| 91 | } else { |
| 92 | $output.append("UpdraftPlus " + updraftlion.ajax_restore_error + ' ' + response.currentTarget.status + ' ' + response.currentTarget.statusText); |
| 93 | } |
| 94 | console.log("UpdraftPlus restore error: " + response.currentTarget.status + ' ' + response.currentTarget.statusText); |
| 95 | console.log(response.currentTarget); |
| 96 | } |
| 97 | } |
| 98 | xhttp.onload = function() { |
| 99 | var $result = $output.find('.updraft_restore_successful, .updraft_restore_error'); |
| 100 | |
| 101 | // if we don't find the result, exit |
| 102 | if (!$result.length) return; |
| 103 | |
| 104 | var $result_output = $('.updraft_restore_result'); |
| 105 | $result_output.slideDown(); |
| 106 | $steps_list.slideUp(); |
| 107 | $steps_list.siblings('h2').slideUp(); |
| 108 | |
| 109 | if ($result.is('.updraft_restore_successful')) { |
| 110 | $result_output.find('.dashicons').addClass('dashicons-yes'); |
| 111 | $result_output.find('.updraft_restore_result--text').text($result.text()); |
| 112 | $result_output.addClass('restore-success'); |
| 113 | } else if ($result.is('.updraft_restore_error')) { |
| 114 | $result_output.find('.dashicons').addClass('dashicons-no-alt'); |
| 115 | $result_output.find('.updraft_restore_result--text').text($result.text()); |
| 116 | $result_output.addClass('restore-error'); |
| 117 | } |
| 118 | // scroll log to the bottom |
| 119 | setTimeout(function() { |
| 120 | $output.scrollTop($output[0].scrollHeight); |
| 121 | }, 500); |
| 122 | } |
| 123 | xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); |
| 124 | xhttp.send(xhttp_data); |
| 125 | } |
| 126 | |
| 127 | /** |
| 128 | * This function will process the parsed restore data and make updates to the front end |
| 129 | * |
| 130 | * @param {object} restore_data - the restore data object contains information on the restore progress to update the front end |
| 131 | */ |
| 132 | function updraft_restore_process_data(restore_data) { |
| 133 | |
| 134 | // If the stage is started then we want to start our restore timer as the restore has now actually began |
| 135 | if ('started' == restore_data.stage) { |
| 136 | updraft_restore_update_timer = setInterval(function () { |
| 137 | updraft_restore_update(); |
| 138 | }, 5000); |
| 139 | } |
| 140 | |
| 141 | // If the stage is finished then we want to remove our timer and clean up the UI |
| 142 | if ('finished' == restore_data.stage && updraft_restore_update_timer) { |
| 143 | clearInterval(updraft_restore_update_timer); |
| 144 | $('#updraftplus_ajax_restore_last_activity').html(''); |
| 145 | } |
| 146 | |
| 147 | if (restore_data) { |
| 148 | if ('state' == restore_data.type || 'state_change' == restore_data.type) { |
| 149 | console.log(restore_data.stage, restore_data.data); |
| 150 | if ('files' == restore_data.stage) { |
| 151 | current_stage = restore_data.data.entity; |
| 152 | } else { |
| 153 | current_stage = restore_data.stage; |
| 154 | } |
| 155 | |
| 156 | var $current = $steps_list.find('[data-component='+current_stage+']'); |
| 157 | |
| 158 | // show simplified activity log next to the component's label |
| 159 | if ('files' == restore_data.stage) { |
| 160 | $current.find('.updraft_component--progress').html(' — '+updraftlion.restore_files_progress.replace('%1$s', '<strong>'+(restore_data.data.fileindex)+'</strong>').replace('%2$s', '<strong>'+restore_data.data.total_files+'</strong>')); |
| 161 | } |
| 162 | |
| 163 | if ('db' == restore_data.stage) { |
| 164 | if (restore_data.data.hasOwnProperty('stage')) { |
| 165 | if ('table' == restore_data.data.stage) { |
| 166 | $current.find('.updraft_component--progress').html(' — '+updraftlion.restore_db_table_progress.replace('%s', '<strong>'+(restore_data.data.table)+'</strong>')); |
| 167 | } else if ('stored_routine' == restore_data.data.stage) { |
| 168 | $current.find('.updraft_component--progress').html(' — '+updraftlion.restore_db_stored_routine_progress.replace('%s', '<strong>'+(restore_data.data.routine_name)+'</strong>')); |
| 169 | } else if ('finished' == restore_data.data.stage) { |
| 170 | $current.find('.updraft_component--progress').html(' — '+updraftlion.finished); |
| 171 | } else if ('begun' == restore_data.data.stage) { |
| 172 | $current.find('.updraft_component--progress').html(' — '+updraftlion.begun+'...'); |
| 173 | } |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | if (previous_stage !== current_stage) { |
| 178 | if (previous_stage) { |
| 179 | var $prev = $steps_list.find('[data-component='+previous_stage+']'); |
| 180 | // empty the line's status |
| 181 | $prev.find('.updraft_component--progress').html(''); |
| 182 | $prev.removeClass('active').addClass('done'); |
| 183 | } |
| 184 | if ('finished' == current_stage) { |
| 185 | $current.addClass('done'); |
| 186 | $steps_list.find('[data-component]').each(function(index, el) { |
| 187 | $el = $(el); |
| 188 | if (!$el.is('.done')) { |
| 189 | $el.addClass('error'); |
| 190 | } |
| 191 | }); |
| 192 | if (restore_data.data.hasOwnProperty('actions') && 'object' == typeof restore_data.data.actions) { |
| 193 | updraft_restore_get_pages(restore_data.data.urls, function(pages_found) { |
| 194 | if (!$.isEmptyObject(pages_found)) { |
| 195 | $('.updraft_restore_result').before(updraftlion.ajax_restore_404_detected); |
| 196 | $.each(pages_found, function(index, url) { |
| 197 | $('.updraft_missing_pages').append('<li>'+url+'</li>'); |
| 198 | }); |
| 199 | } |
| 200 | }); |
| 201 | |
| 202 | $.each(restore_data.data.actions, function(index, item) { |
| 203 | $steps_list.after('<a href="'+item+'" class="button button-primary">'+index+'</a>'); |
| 204 | }); |
| 205 | } |
| 206 | |
| 207 | } else { |
| 208 | $current.addClass('active'); |
| 209 | } |
| 210 | } |
| 211 | previous_stage = current_stage; |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | } |
| 216 | |
| 217 | /** |
| 218 | * This function will update the time in the front end that we last received data, after 120 seconds call the resume restore notice |
| 219 | */ |
| 220 | function updraft_restore_update() { |
| 221 | var current_time = Math.round(Date.now() / 1000); |
| 222 | var last_activity = current_time - last_received; |
| 223 | if (60 > last_activity) { |
| 224 | $('#updraftplus_ajax_restore_last_activity').html(updraftlion.last_activity.replace('%d', last_activity)); |
| 225 | } else { |
| 226 | var resume_in = 120 - last_activity; |
| 227 | if (0 < resume_in) { |
| 228 | $('#updraftplus_ajax_restore_last_activity').html(updraftlion.no_recent_activity.replace('%d', resume_in)); |
| 229 | } else { |
| 230 | $('#updraftplus_ajax_restore_last_activity').html(''); |
| 231 | updraft_restore_resume_notice(); |
| 232 | } |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | /** |
| 237 | * This will move the filesystem form to take all the required space |
| 238 | */ |
| 239 | function updraft_restore_setup_filesystem_form() { |
| 240 | // Hiding things is handled via CSS |
| 241 | $('.updraft_restore_main').addClass('show-credentials-form'); |
| 242 | if ($('#message').length) { |
| 243 | $('.restore-credential-errors .restore-credential-errors--list').appendTo($('#message')); |
| 244 | $('.restore-credential-errors .restore-credential-errors--link').appendTo($('#message')); |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | /** |
| 249 | * This function will make a call to the backend to get the resume restore notice so the user can resume the timed out restore from the same page |
| 250 | */ |
| 251 | function updraft_restore_resume_notice() { |
| 252 | updraft_send_command('get_restore_resume_notice', { job_id: job_id }, function(response) { |
| 253 | if (response.hasOwnProperty('status') && 'success' == response.status && response.hasOwnProperty('html')) { |
| 254 | if (updraft_restore_update_timer) clearInterval(updraft_restore_update_timer); |
| 255 | if ('plugins' != current_stage && 'db' != current_stage && 5 > auto_resume_count) { |
| 256 | auto_resume_count++; |
| 257 | updraft_restore_command(job_id, 'updraft_ajaxrestore_continue'); |
| 258 | } else { |
| 259 | $('.updraft_restore_main--components').prepend(response.html); |
| 260 | } |
| 261 | } else if (response.hasOwnProperty('error_code') && response.hasOwnProperty('error_message')) { |
| 262 | if (updraft_restore_update_timer) clearInterval(updraft_restore_update_timer); |
| 263 | alert(response.error_code + ': ' + response.error_message); |
| 264 | console.log(response.error_code + ': ' + response.error_message); |
| 265 | } |
| 266 | }, { |
| 267 | error_callback: function (response, status, error_code, resp) { |
| 268 | if (500 == response.status && 3 > server_500_count) { |
| 269 | server_500_count++; |
| 270 | updraft_restore_command(job_id, 'updraft_ajaxrestore_continue'); |
| 271 | } else { |
| 272 | updraft_restore_process_data({stage: 'finished', type: 'state_change'}) |
| 273 | var error_message = "updraft_send_command: error: " + status + " (" + error_code + ")"; |
| 274 | alert(error_message); |
| 275 | console.log(error_message); |
| 276 | console.log(response); |
| 277 | } |
| 278 | } |
| 279 | }); |
| 280 | } |
| 281 | |
| 282 | /** |
| 283 | * This function will make a call to the passed in urls and check if the response code is a 404 if it is then add it to the array of urls that are not found and return it via a callback |
| 284 | * |
| 285 | * @param {array} urls - the urls we want to test |
| 286 | * @param {Function} callback - will be called with the array of urls not found |
| 287 | */ |
| 288 | function updraft_restore_get_pages(urls, callback) { |
| 289 | var urls_not_found = []; |
| 290 | var ajax_requests = []; |
| 291 | |
| 292 | $.each(urls, function(index, url) { |
| 293 | var d = $.Deferred(); |
| 294 | ajax_requests.push(d.promise()); |
| 295 | |
| 296 | var xhttp = new XMLHttpRequest(); |
| 297 | xhttp.onreadystatechange = function() { |
| 298 | if (4 == this.readyState) { |
| 299 | if (404 == this.status) urls_not_found.push(url); |
| 300 | d.resolve(); |
| 301 | } |
| 302 | }; |
| 303 | xhttp.open('GET', url, true); |
| 304 | xhttp.send(null); |
| 305 | }); |
| 306 | |
| 307 | $.when.apply($, ajax_requests).done(function() { |
| 308 | callback(urls_not_found); |
| 309 | }); |
| 310 | } |
| 311 | |
| 312 | $('#updraftplus_ajax_restore_progress').on('click', '#updraft_restore_resume', function(e) { |
| 313 | e.preventDefault(); |
| 314 | $("#updraftplus_ajax_restore_progress").slideUp(1000, function () { |
| 315 | $(this).remove(); |
| 316 | }); |
| 317 | updraft_restore_command(job_id, 'updraft_ajaxrestore_continue'); |
| 318 | }); |
| 319 | |
| 320 | $(document).on('heartbeat-tick', function (event, heartbeat_data) { |
| 321 | |
| 322 | if (!heartbeat_data.hasOwnProperty('wp-auth-check')) return; |
| 323 | |
| 324 | // check if we are logged out |
| 325 | if (!heartbeat_data["wp-auth-check"]) { |
| 326 | logged_out = true; |
| 327 | return; |
| 328 | } |
| 329 | |
| 330 | // if we were previously logged out but are now logged in retry the restore |
| 331 | if (logged_out && heartbeat_data["wp-auth-check"]) { |
| 332 | last_received = Math.round(Date.now() / 1000); |
| 333 | logged_out = false; |
| 334 | } |
| 335 | |
| 336 | if (!heartbeat_data.hasOwnProperty('updraftplus')) return; |
| 337 | |
| 338 | var updraftplus_data = heartbeat_data.updraftplus; |
| 339 | |
| 340 | // if we are logged in, check if theres a new nonce |
| 341 | if (updraftplus_data.hasOwnProperty('updraft_credentialtest_nonce')) { |
| 342 | updraft_credentialtest_nonce = updraftplus_data.updraft_credentialtest_nonce; |
| 343 | last_received = Math.round(Date.now() / 1000); |
| 344 | } |
| 345 | }); |
| 346 | }); |
| 347 |