✏️ 编辑:restore.js
路径:
/home/boguraj1/craftandcreation.xyz/wp-content/plugins/backup/public/js/restore.js
大小:8.56 KB · 修改:2025-10-23 15:51:45 · 权限:0644 · 可写
← 返回目录
👁 查看
⬇ 下载
var Restore = function(options) { this.init(options); }; const QUEUE_STATUS_PENDING = 1; const QUEUE_STATUS_STARTED = 2; const QUEUE_STATUS_PREPARING = 3; const QUEUE_STATUS_DONE = 100; const QUEUE_STATUS_PARTIALLY = 101; const QUEUE_STATUS_FAILED = 102; const QUEUE_STATUS_ABORTED = 103; const QUEUE_STATUS_NEVER_FINISHED = 104; const logBuffer = []; let updateScheduled = false; const maxLogLines = 500; function appendLogEntry(entry) { const container = document.getElementById("log-container"); const newEntry = document.createElement("div"); newEntry.className = "log-entry"; newEntry.textContent = entry; container.appendChild(newEntry); while (container.children.length > maxLogLines) { container.removeChild(container.firstChild); } container.scrollTop = container.scrollHeight; } // Buffered version to avoid frequent DOM updates function bufferedLog(entry) { logBuffer.push(entry); if (!updateScheduled) { updateScheduled = true; setTimeout(() => { flushLog(); updateScheduled = false; }, 300); // throttle interval } } function flushLog() { for (const entry of logBuffer) { appendLogEntry(entry); } logBuffer.length = 0; } Restore.prototype = { _queueId: '', _interval: null, _intervalTime: 3000, _completed: false, _restoreErrorCount: {}, _updateProgressBar: function (id, progress) { if (isNaN(progress) || progress < 0) progress = 0; // Default to 0 if the percentage is invalid else if (progress > 100) progress = 100; // Cap at 100 if percentage exceeds 100 const elm = document.getElementById(id); elm.style.width = progress + '%'; elm.innerText = progress + '%'; }, _ajax: function (options, name) { if(this._restoreErrorCount[name] === undefined) this._restoreErrorCount[name] = 0; if (options.data === undefined || typeof options.data != 'object') options.data = {}; if (options.success === undefined || typeof options.success != 'function') options.success = function(){}; if (options.fail === undefined || typeof options.fail != 'function') options.fail = function(){}; options.data.id = this._queueId; const xhr = new XMLHttpRequest(); xhr.open("POST", location.protocol + '//' + location.host + location.pathname, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.onreadystatechange = () => { if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.status === 200) { try { const response = JSON.parse(xhr.response); if (response.success) { this._restoreErrorCount[name] = 0; // Reset error count on success options.success(response.message, response.data); } else { this._restoreErrorCount[name]++; this._logError(`Error ${xhr.status}: ${response.message} (Attempt ${this._restoreErrorCount[name]}/10)`); if (this._restoreErrorCount[name] >= 10) { options.fail(xhr.status, response.message); } else { setTimeout(() => this._ajax(options, name), 3000); // Retry after 3 seconds } } } catch (e) { this._restoreErrorCount[name]++; this._logError(`Error ${xhr.status}: Invalid JSON response (Attempt ${this._restoreErrorCount[name]}/10)`); if (this._restoreErrorCount[name] >= 10) { options.fail(xhr.status, "Invalid response received from the server"); } else { setTimeout(() => this._ajax(options, name), 3000); // Retry after 3 seconds } } } else { this._restoreErrorCount[name]++; this._logError(`HTTP Error ${xhr.status}: Attempt ${this._restoreErrorCount[name]}/10`); if (this._restoreErrorCount[name] >= 10) { options.fail(xhr.status, xhr.response); } else { setTimeout(() => this._ajax(options, name), 3000); // Retry after 3 seconds } } } }; xhr.send(new URLSearchParams(options.data).toString()); }, _logError: function (message) { const currentLogEntries = data.log_entries.length; if (!self._lastLogCount) self._lastLogCount = 0; // Append only new entries if (currentLogEntries > self._lastLogCount) { const newEntries = data.log_entries.slice(self._lastLogCount); newEntries.forEach(entry => bufferedLog(entry)); self._lastLogCount = currentLogEntries; } }, _redirect: function () { setTimeout(function () { let pathArray = window.location.pathname.split('/'); let wpIndex = pathArray.indexOf('wp-content'); if (wpIndex !== -1) { pathArray = pathArray.slice(0, wpIndex); } else { pathArray.pop(); } let basePath = pathArray.join('/'); window.location.href = window.location.origin + basePath + '/wp-admin'; }, 3000); }, cancel: function () { this.stop(); this._ajax({ data: { action: 'cancel' }, success: () => { // Arrow function ensures 'this' remains in scope this._success('Restore has been canceled. Redirecting...'); this._redirect(); }, fail: (status, message) => { this._error(message); } }, 'cancel'); }, refresh: function () { window.location.reload(); }, completed: function () { this._ajax({ data: { action: 'completed' }, success: () => { this._success('Restore is completed! Redirecting to your website...'); this._redirect(); }, fail: (status, message) => { this._error(message); } }, 'completed'); }, _success: function (message) { document.getElementById('success-message').innerText = message; document.getElementById('success-alert').style.display = 'block'; }, _error: function (message) { document.getElementById('error-message').innerText = message; document.getElementById('error-alert').style.display = 'block'; }, closeSuccess: function () { document.getElementById('success-alert').style.display = 'none'; }, closeError: function () { document.getElementById('error-alert').style.display = 'none'; }, stop: function () { if(this._interval !== null) { this._interval.clearInterval(); this._interval = null; } }, _checkStatus: function () { const self = this; this._ajax({ data: { action: 'status' }, success: function (message, data) { // Update progress bars self._updateProgressBar('progress', data.progress.percentage); self._updateProgressBar('subprogress', data.progress.sub_percentage); document.getElementById('subprogress-title').innerText = data.progress.message + ':'; document.getElementById('subprogress-container').style.display = 'block'; // Handle log updates efficiently const log = document.getElementById('log-container'); const currentLogEntries = data.log_entries.length; // Store last log entry count to prevent unnecessary updates if (!self._lastLogCount || self._lastLogCount !== currentLogEntries) { self._lastLogCount = currentLogEntries; // Update log count const logFragment = document.createDocumentFragment(); data.log_entries.forEach(entry => { const logEntry = document.createElement("div"); logEntry.classList.add("log-entry"); logEntry.innerText = entry; logFragment.appendChild(logEntry); }); // Append new logs only if there’s a change log.innerHTML = ''; // Clear previous log only when updating log.appendChild(logFragment); setTimeout(() => { log.scrollTop = log.scrollHeight; }, 50); } // Recheck status if the process is ongoing if (data.status < QUEUE_STATUS_DONE) { setTimeout(function () { self._checkStatus(); }, self._intervalTime); } else { if (data.status > QUEUE_STATUS_DONE) { if (data.status === QUEUE_STATUS_PARTIALLY) self._error("Restore partially completed"); else if (data.status === QUEUE_STATUS_FAILED) self._error("Error occurred during restore, please review the logs"); else if (data.status === QUEUE_STATUS_ABORTED) self._error("Restore aborted"); else if (data.status === QUEUE_STATUS_NEVER_FINISHED) self._error("Restore never finished"); } else { self._success("Restore is completed!"); document.getElementById('finalize-btn').style.display = 'inline-block'; } } }, fail: function (status, message) { self._error(message); } }, '_checkStatus'); }, start: function () { const self = this; setTimeout(function () { self._checkStatus(); }, 1000); this._restore(); }, _restore: function () { const self = this; this._ajax({ data: { action: 'restore' }, success: function(message, data) { if(!self._completed && data.status < QUEUE_STATUS_DONE) self._restore(); }, fail: function (status, message) { self._error(message); } }, '_restore'); }, init: function (options) { this._queueId = options.queue_id if(options.interval !== undefined) this._intervalTime = options.interval; } };
💾 保存
取消
保存为 UTF-8,换行统一为 LF