Download all files FTP

This commit is contained in:
2026-04-13 15:50:16 +02:00
parent d8382136b2
commit cb5b386424
6906 changed files with 1956223 additions and 40713 deletions

View File

@@ -0,0 +1,9 @@
<Files *.php>
Order Deny,Allow
Deny from all
</Files>
<Files index.php>
Order Allow,Deny
Allow from all
</Files>

View File

@@ -0,0 +1,33 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (!isset($tplData['tmpCleanUpSuccess'])) {
return;
}
$messageClasses = [
'notice',
'is-dismissible',
'dpro-diagnostic-action-tmp-cache',
'notice-success',
];
?>
<div id="message" class="<?php echo esc_attr(implode(' ', $messageClasses)); ?>">
<p>
<?php esc_html_e('Build cache removed.', 'duplicator-pro'); ?>
</p>
</div>

View File

@@ -0,0 +1,52 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (!isset($tplData['purgeOrphansSuccess'])) {
return;
}
$messageClasses = [
'notice',
'is-dismissible',
'dpro-diagnostic-action-purge-orphans',
($tplData['purgeOrphansSuccess'] ? 'notice-success' : 'notice-error'),
];
?>
<div id="message" class="<?php echo esc_attr(implode(' ', $messageClasses)); ?>">
<p>
<?php esc_html_e('Cleaned up orphaned package files!', 'duplicator-pro'); ?>
</p>
<?php
foreach ($tplData['purgeOrphansFiles'] as $path => $deleted) {
if ($deleted) {
?>
<div class='success'>
<i class='fa fa-check'></i> <?php echo esc_html($path); ?>
</div>
<?php } else { ?>
<div class='failed'>
<i class='fa fa-exclamation-triangle'></i> <?php echo esc_html($path); ?>
</div>
<?php
}
}
?>
<p>
<i>
<?php esc_html_e('If any orphaned files didn\'t get removed then delete them manually', 'duplicator-pro') ?>.
</i>
</p>
</div>

View File

@@ -0,0 +1,26 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<div class="wrap">
<h1>
<?php esc_html_e("Install package error", 'duplicator-pro'); ?>
</h1>
<p>
<?php esc_html_e("Error on package prepare, please go back and try again.", 'duplicator-pro'); ?>
</p>
</div>

View File

@@ -0,0 +1,65 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\ImportPageController;
use Duplicator\Package\Import\PackageImporter;
use Duplicator\Package\Recovery\RecoveryPackage;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var PackageImporter $importObj
*/
$importObj = $tplData['importObj'];
/** @var string $iframeSrc */
$iframeSrc = $tplData['iframeSrc'];
$importFailMessage = '';
if (!$importObj->isImportable($importFailMessage)) {
?>
<div class="wrap">
<h1>
<?php esc_html_e("Install package", 'duplicator-pro'); ?>
</h1>
<div class="dpro-pro-import-installer-content-wrapper" >
<p class="orangered">
<?php echo esc_html($importFailMessage); ?>
</p>
</div>
</div>
<?php } else { ?>
<div id="dpro-pro-import-installer-wrapper" >
<div id="dpro-pro-import-installer-top-bar" class="dup-pro-recovery-details-max-width-wrapper" >
<a href="<?php echo esc_url(ImportPageController::getImportPageLink()); ?>" class="button" >
<i class="fa fa-caret-left"></i> <?php esc_html_e("Back to Import", 'duplicator-pro'); ?>
</a>&nbsp;
<span class="link-style no-decoration recovery-copy-top-wrapper" >
<?php if (($recoverPackage = RecoveryPackage::getRecoverPackage()) !== false) { ?>
<span class="button"
data-tooltip-placement="right"
data-dup-copy-value="<?php echo esc_url($recoverPackage->getInstallLink()); ?>"
data-dup-copy-title="<?php esc_attr_e("Copy Recovery URL to clipboard", 'duplicator-pro'); ?>"
data-dup-copied-title="<?php esc_attr_e("Recovery URL copied to clipboard", 'duplicator-pro'); ?>" >
<?php esc_html_e("Copy Recovery URL", 'duplicator-pro'); ?>
</span>
<?php } else { ?>
<span class="button disabled">
<i class="fas fa-exclamation-circle"></i> <?php esc_html_e("Recovery Point Not Set", 'duplicator-pro'); ?>
</span>
<?php } ?>
</span>
</div>
<div id="dup-pro-import-installer-modal" class="no-display"></div>
<iframe id="dpro-pro-import-installer-iframe" src="<?php echo esc_url($iframeSrc); ?>" ></iframe>
</div>
<?php
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$importSettingsUrl = $ctrlMng->getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_IMPORT
);
?>
<div class="dup-pro-import-upload-message" >
<p class="import-upload-reset-message-error">
<i class="fa fa-exclamation-triangle"></i> <b><?php esc_html_e('UPLOAD FILE PROBLEM', 'duplicator-pro'); ?></b>
</p>
<p>
<?php esc_html_e('Error message:', 'duplicator-pro'); ?>&nbsp;
<b><span class="import-upload-error-message"><!-- here is set the message received from the server --></span></b>
</p>
<div><?php esc_html_e('Possible solutions:', 'duplicator-pro'); ?></div>
<ul class="dup-pro-simple-style-list" >
<li>
<?php esc_html_e('If you are using Server to Server transfer function make sure the URL is a valid URL', 'duplicator-pro'); ?>
</li>
<li>
<?php
printf(
esc_html_x(
'If you are using the upload function try to change the chunk size in %1$ssettings%2$s and try again',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . esc_url($importSettingsUrl) . '">',
'</a>'
);
?>
</li>
<li>
<?php
printf(
esc_html__('Upload the file via FTP/file manager to the "%s" folder and reload the page.', 'duplicator-pro'),
esc_html(DUPLICATOR_PRO_PATH_IMPORTS)
);
?>
</li>
</ul>
<p>
<b>
<?php
printf(
esc_html_x(
'For more information see %1$s[this FAQ item]%2$s',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-handle-import-install-upload-launch-issues') . '" target="_blank">',
'</a>'
);
?>
</b>
</p>
</div>

View File

@@ -0,0 +1,174 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Installer\Package\PComponents;
use Duplicator\Package\Create\BuildComponents;
use Duplicator\Package\Import\PackageImporter;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
/* passed values */
/** @var PackageImporter $importObj */
$importObj = $tplData['importObj'];
if (!$importObj instanceof PackageImporter) {
return;
}
?>
<div class="dup-pro-import-package-detail-content">
<?php
$errorMsg = '';
if (!$importObj->encryptCheck($errorMsg)) {
?>
<p class="maroon">
<b><i class="fas fa-exclamation-triangle"></i> <?php echo $errorMsg; ?></b>
</p>
<?php
} elseif (!$importObj->passwordCheck()) {
?>
<p class="maroon">
<b><i class="fas fa-exclamation-triangle"></i> <?php esc_html_e('Valid password required', 'duplicator-pro'); ?></b>
</p>
<div class="dup-import-archive-password-request" >
<input type="password" class="dup-import-archive-password" name="password" value="" >
<button type="button" class="dup-import-set-archive-password button" >
<?php esc_html_e('Submit', 'duplicator-pro'); ?>
</button>
</div>
<?php
} elseif (!$importObj->isImportable($importFailMessage)) {
?>
<p class="maroon">
<b><i class="fas fa-exclamation-triangle"></i> <?php echo $importFailMessage; ?></b>
</p>
<?php
} elseif ($importObj->haveImportWaring($importWarnMessage)) {
?>
<p class="gray">
<b><i class="fas fa-exclamation-triangle"></i> <?php echo $importWarnMessage; ?></b>
</p>
<?php
} else {
?>
<p class="green">
<b>
<i class="fas fa-check-circle"></i>
<?php esc_html_e('This package is ready to install, click the continue button to proceed.', 'duplicator-pro'); ?>
</b><br/>
<b><?php esc_html_e('The information below is related to the package and the source site where the package was created.', 'duplicator-pro'); ?></b>
</p>
<?php
}
if ($importObj->isValid()) {
?>
<ul>
<li>
<span class="label title"><?php esc_html_e('Site Details:', 'duplicator-pro'); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('URL', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html($importObj->getHomeUrl()); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('Path', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html($importObj->getHomePath()); ?></span>
</li>
<li>
<span class="label title"><?php esc_html_e('Versions:', 'duplicator-pro'); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('Duplicator', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html($importObj->getDupVersion()); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('WordPress', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html($importObj->getWPVersion()); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('PHP', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html($importObj->getPhpVersion()); ?></span>
</li>
<?php if ($importObj->getPackageComponents() !== false) { ?>
<li>
<span class="label title"><?php esc_html_e('Package components:', 'duplicator-pro'); ?></span>
</li>
<?php
$packComponents = $importObj->getPackageComponents();
foreach (BuildComponents::COMPONENTS_DEFAULT as $component) {
?>
<li>
<span class="label"><?php echo esc_html(BuildComponents::getLabel($component)); ?>:</span>
<span class="value">
<?php if (in_array($component, $packComponents)) { ?>
<i class="fas fa-check-circle green"></i> <?php esc_html_e('included', 'duplicator-pro'); ?>
<?php } else { ?>
<i class="fas fa-times-circle maroon"></i> <?php esc_html_e('excluded', 'duplicator-pro'); ?>
<?php } ?>
</span>
</li>
<?php } ?>
<?php } ?>
<li>
<span class="label title"><?php esc_html_e('Archive:', 'duplicator-pro'); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('Created', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html($importObj->getCreated()); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('Size', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html(DUP_PRO_U::byteSize($importObj->getSize())); ?></span>
</li>
<?php if (!$importObj->isLite()) { ?>
<li>
<span class="label"><?php esc_html_e('Folders', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html(number_format($importObj->getNumFolders())); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('Files', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html(number_format($importObj->getNumFiles())); ?></span>
</li>
<?php } ?>
<li>
<span class="label title"><?php esc_html_e('Database:', 'duplicator-pro'); ?></span>
</li>
<?php
if (
$importObj->getPackageComponents() === false ||
in_array(PComponents::COMP_DB, $importObj->getPackageComponents())
) {
?>
<li>
<span class="label"><?php esc_html_e('Size', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html($importObj->getDbSize()); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('Tables', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo $importObj->getNumTables(); ?></span>
</li>
<li>
<span class="label"><?php esc_html_e('Rows', 'duplicator-pro'); ?>:</span>
<span class="value"><?php echo esc_html(number_format($importObj->getNumRows())); ?></span>
</li>
<?php } else { ?>
<li>
<span class="label"><?php esc_html_e('Database', 'duplicator-pro'); ?>:</span>
<span class="value"><?php esc_html_e('Not Included', 'duplicator-pro'); ?></span>
</li>
<?php } ?>
</ul>
<?php } ?>
</div>

View File

@@ -0,0 +1,648 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\ImportPageController;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$packageDeteleConfirm = new DUP_PRO_UI_Dialog();
$packageDeteleConfirm->title = __('Delete Package?', 'duplicator-pro');
$packageDeteleConfirm->wrapperClassButtons = 'dpro-dlg-import-detete-package-btns';
$packageDeteleConfirm->progressOn = false;
$packageDeteleConfirm->closeOnConfirm = true;
$packageDeteleConfirm->message = __('Are you sure you want to delete the selected package?', 'duplicator-pro');
$packageDeteleConfirm->jsCallback = 'DupPro.ImportManager.removePackage()';
$packageDeteleConfirm->initConfirm();
$packageInvalidName = new DUP_PRO_UI_Messages(
__(
'<b>Invalid archive name:</b> The archive name must follow the Duplicator package name pattern
e.g. PACKAGE_NAME_[HASH]_[YYYYMMDDHHSS]_archive.zip (or with a .daf extension).
<br>Please make sure not to rename the archive after downloading it and try again!',
'duplicator-pro'
),
DUP_PRO_UI_Messages::ERROR
);
$packageInvalidName->hide_on_init = true;
$packageInvalidName->is_dismissible = true;
$packageInvalidName->auto_hide_delay = 10000;
$packageInvalidName->initMessage();
$packageAlreadyExists = new DUP_PRO_UI_Messages(
__('Archive file name already exists! <br>Please remove it and try again!', 'duplicator-pro'),
DUP_PRO_UI_Messages::ERROR
);
$packageAlreadyExists->hide_on_init = true;
$packageAlreadyExists->is_dismissible = true;
$packageAlreadyExists->auto_hide_delay = 5000;
$packageAlreadyExists->initMessage();
$packageUploaded = new DUP_PRO_UI_Messages(__('Package uploaded', 'duplicator-pro'), DUP_PRO_UI_Messages::NOTICE);
$packageUploaded->hide_on_init = true;
$packageUploaded->is_dismissible = true;
$packageUploaded->auto_hide_delay = 5000;
$packageUploaded->initMessage();
$packageCancelUpload = new DUP_PRO_UI_Messages(__('Package upload cancelled', 'duplicator-pro'), DUP_PRO_UI_Messages::ERROR);
$packageCancelUpload->hide_on_init = true;
$packageCancelUpload->is_dismissible = true;
$packageCancelUpload->auto_hide_delay = 5000;
$packageCancelUpload->initMessage();
$packageRemoved = new DUP_PRO_UI_Messages(__('Package removed', 'duplicator-pro'), DUP_PRO_UI_Messages::NOTICE);
$packageRemoved->hide_on_init = true;
$packageRemoved->is_dismissible = true;
$packageRemoved->auto_hide_delay = 5000;
$packageRemoved->initMessage();
$importChunkSize = ImportPageController::getChunkSize();
?><script>
jQuery(document).ready(function ($) {
var uploadFileMessageContent = <?php $tplMng->renderJson('admin_pages/import/import-message-upload-error'); ?>;
DupPro.ImportManager = {
uploaderWrapper: $('#dup-pro-import-upload-tabs-wrapper'),
uploaderDisabler: $('<div>'),
uploader: $('#dup-pro-import-upload-file'),
uploaderContent: $('#dup-pro-import-upload-file-content'),
packageRowTemplate: $('#dup-pro-import-row-template'),
packageRowNoFoundTemplate: $('#dup-pro-import-available-packages-templates .dup-pro-import-no-package-found'),
packagesAviable: $('#dpro-pro-import-available-packages'),
packagesList: $('#dpro-pro-import-available-packages .packages-list'),
packageRowUploading: null,
packageRowToDelete: null,
autoLaunchAfterUpload: false,
autoLaunchLink: false,
confirmLaunchLink: false,
startUpload: false,
lastUploadsTimes: [],
debug: true,
init: function () {
$('#dup-pro-import-instructions-toggle').click(function () {
$('#dup-pro-import-instructions-content').toggle(300);
})
DupPro.ImportManager.uploaderWrapper.css('position', 'relative');
DupPro.ImportManager.uploaderDisabler = $('<div>').css({
'position' : 'absolute',
'top' : 0,
'left' : 0,
'width' : '100%',
'height' : '100%',
'z-index' : '10',
'cursor' : 'not-allowed',
'display' : 'none'
});
DupPro.ImportManager.uploaderDisabler.appendTo(DupPro.ImportManager.uploaderWrapper);
DupPro.ImportManager.uploader.upload({
autoUpload: true,
multiple: false,
maxSize: <?php echo empty($importChunkSize) ? (int) wp_max_upload_size() : 10737418240; ?>, //100GB get value from upload_max_filesize
maxConcurrent: 1,
maxFiles: 1,
postData: {
action: 'duplicator_pro_import_upload',
nonce: <?php echo json_encode(wp_create_nonce('duplicator_pro_import_upload')); ?>
},
chunkSize: <?php echo (int) $importChunkSize; ?>, // This is in kb
action: <?php echo json_encode(get_admin_url(null, 'admin-ajax.php')); ?>,
chunked: <?php echo empty($importChunkSize) ? 'false' : 'true'; ?>,
label: DupPro.ImportManager.uploaderContent.parent().html(),
leave: '<?php echo esc_js(__('You have uploads pending, are you sure you want to leave this page?', 'duplicator-pro')); ?>'
})
.on("start.upload", DupPro.ImportManager.onStart)
.on("complete.upload", DupPro.ImportManager.onComplete)
.on("filestart.upload", DupPro.ImportManager.onFileStart)
.on("fileprogress.upload", DupPro.ImportManager.onFileProgress)
.on("filecomplete.upload", DupPro.ImportManager.onFileComplete)
.on("fileerror.upload", DupPro.ImportManager.onFileError)
.on("fileerror.chunkerror", DupPro.ImportManager.onChunkError);
DupPro.ImportManager.uploaderContent.remove();
DupPro.ImportManager.uploaderContent = $('#dup-pro-import-upload-file #dup-pro-import-upload-file-content');
DupPro.ImportManager.initPageButtons();
DupPro.ImportManager.checkMaxUploadedFiles();
DupPro.ImportManager.packagesList.on('click', '.dup-pro-import-action-remove', function (event) {
event.stopPropagation();
DupPro.ImportManager.packageRowToDelete = $(this).closest('.dup-pro-import-package');
<?php $packageDeteleConfirm->showConfirm(); ?>
return false;
});
DupPro.ImportManager.packagesList.on('click', '.dup-pro-import-action-package-detail-toggle', function (event) {
event.stopPropagation();
let button = $(this);
let details = button.closest('.dup-pro-import-package').find('.dup-pro-import-package-detail');
if (details.hasClass('no-display')) {
button.find('.fa').removeClass('fa-caret-down').addClass('fa-caret-up');
details.removeClass('no-display');
} else {
button.find('.fa').removeClass('fa-caret-up').addClass('fa-caret-down');
details.addClass('no-display');
}
return false;
});
DupPro.ImportManager.packagesList.on('click', '.dup-pro-import-action-cancel-upload', function (event) {
event.stopPropagation();
DupPro.ImportManager.abortUpload();
<?php $packageCancelUpload->showMessage(); ?>
return false;
});
DupPro.ImportManager.packagesList.on('click', '.dup-pro-import-action-install', function (event) {
event.stopPropagation();
DupPro.ImportManager.confirmLaunchLink = $(this).data('install-url');
$('#dup-pro-import-phase-one').addClass('no-display');
$('#dup-pro-import-phase-two').removeClass('no-display');
return false;
});
DupPro.ImportManager.packagesList.on('click', '.dup-import-set-archive-password', function (event) {
event.stopPropagation();
DupPro.ImportManager.setArchivePassword($(this));
return false;
});
DupPro.ImportManager.initRemoteUpload();
},
initRemoteUpload: function () {
$('#dup-pro-import-remote-upload').click(function () {
let uploadUrl = $('#dup-pro-import-remote-url').val();
let parsedUrl = null;
try {
parsedUrl = new URL(uploadUrl);
} catch (error) {
DupPro.addAdminMessage("Invalid URL", 'error');
}
let files = [
{
'name': parsedUrl.pathname.split('/').pop(),
'size': -1
}
];
if (DupPro.ImportManager.onStart(null, files) == false) {
DupPro.ImportManager.onComplete(null);
return false;
}
DupPro.ImportManager.onFileStart(null, files[0]);
DupPro.ImportManager.remoteUploadCall(uploadUrl, null);
});
},
remoteUploadCall: function (uploadUrl, restoreDownload) {
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_import_remote_download',
url: uploadUrl,
restoreDownload : (restoreDownload == null ? '' : JSON.stringify(restoreDownload)),
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_remote_download')); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
if (DupPro.ImportManager.packageRowUploading == null) {
// if row don't exitst the upload is aboted
DupPro.ImportManager.onComplete(null);
return '';
}
if (funcData.status == 'complete') {
DupPro.ImportManager.onFileComplete(null, uploadUrl, result);
DupPro.ImportManager.onComplete(null);
} else {
DupPro.ImportManager.updateProgress(funcData.remoteChunk.offset, funcData.remoteChunk.fullSize);
DupPro.ImportManager.remoteUploadCall(uploadUrl, funcData.remoteChunk);
}
return '';
},
function (result, data, funcData, textStatus, jqXHR) {
DupPro.ImportManager.uploadError(result.data.message);
DupPro.ImportManager.onComplete(null);
return '';
}
);
},
setArchivePassword: function (button) {
let row = button.closest('.dup-pro-import-package');
let archiveFile = row.data('path');
let password = row.find('.dup-import-archive-password-request .dup-import-archive-password').val();
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_import_set_archive_password',
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_import_set_archive_password')); ?>',
archive: archiveFile,
password: password
},
function (result, data, funcData, textStatus, jqXHR) {
DupPro.ImportManager.packageRowUploading = row;
DupPro.ImportManager.onFileComplete(null, archiveFile, result, false);
DupPro.ImportManager.onComplete(null);
return '';
},
function (result, data, funcData, textStatus, jqXHR) {
DupPro.addAdminMessage(data.message, 'error', {'hideDelay': 5000});
return '';
}
);
},
initPageButtons: function () {
$('.dup-pro-import-view-list').click(function (event) {
event.stopPropagation();
DupPro.ImportManager.updateViewMode('<?php echo esc_js(ImportPageController::VIEW_MODE_ADVANCED); ?>');
});
$('.dup-pro-import-view-single').click(function (event) {
event.stopPropagation();
DupPro.ImportManager.updateViewMode('<?php echo esc_js(ImportPageController::VIEW_MODE_BASIC); ?>');
});
$('.dup-pro-open-help-link').click(function (event) {
$('#contextual-help-link').show();
});
$('#dup-pro-import-launch-installer-confirm').click(function (event) {
event.stopPropagation();
DupPro.ImportManager.confirmLaunchInstaller();
});
$('#dup-pro-import-launch-installer-cancel').click(function (event) {
event.stopPropagation();
DupPro.ImportManager.confirmLaunchLink = false;
$('#dup-pro-import-phase-two').addClass('no-display');
$('#dup-pro-import-phase-one').removeClass('no-display');
return false;
});
$('.dup-pro-tabs-wrapper').each(function () {
let tabWrapper = $(this);
tabWrapper.find('[data-tab-target]').click(function () {
let targetId = $(this).data('tab-target');
tabWrapper.find('[data-tab-target]').removeClass('active');
tabWrapper.find('.tab-content').addClass('no-display');
$(this).addClass('active');
tabWrapper.find('#' + targetId).removeClass('no-display');
});
});
},
confirmLaunchInstaller: function () {
window.location.href = DupPro.ImportManager.confirmLaunchLink;
return false;
},
onStart: function (e, files)
{
DupPro.ImportManager.uploaderDisabler.show();
DupPro.ImportManager.startUpload = true;
DupPro.ImportManager.uploader.upload("disable");
DupPro.ImportManager.autoLaunchLink = false;
let isValidName = true;
let alreadyExists = false;
$.each(files, function (index, value) {
if (!DupPro.ImportManager.isValidFileName(value.name)) {
isValidName = false;
}
if (DupPro.ImportManager.isAlreadyExists(value.name)) {
alreadyExists = true;
}
});
/*if (!isValidName) {
<?php $packageInvalidName->showMessage(); ?>
DupPro.ImportManager.abortUpload();
return false;
}*/
if (alreadyExists) {
<?php $packageAlreadyExists->showMessage(); ?>
DupPro.ImportManager.abortUpload();
return false;
}
return true;
},
onComplete: function (e)
{
$('#dup-pro-import-remote-url').val('');
if (DupPro.ImportManager.autoLaunchAfterUpload && DupPro.ImportManager.autoLaunchLink) {
document.location.href = DupPro.ImportManager.autoLaunchLink;
}
DupPro.ImportManager.checkMaxUploadedFiles();
},
onFileStart: function (e, file)
{
DupPro.ImportManager.resetUploadTimes();
DupPro.ImportManager.packagesList.find('.dup-pro-import-no-package-found').remove();
DupPro.ImportManager.packageRowUploading = DupPro.ImportManager.packageRowTemplate.clone().prependTo(DupPro.ImportManager.packagesList);
DupPro.ImportManager.packageRowUploading.removeAttr('id');
DupPro.ImportManager.packageRowUploading.find('.name .text').text(file.name);
DupPro.ImportManager.packageRowUploading.find('.size').text(Duplicator.Util.humanFileSize(file.size));
DupPro.ImportManager.packageRowUploading.find('.created').html("<i><?php esc_html_e('loading...', 'duplicator-pro'); ?></i>");
let loader = DupPro.ImportManager.packageRowUploading.find('.funcs .dup-pro-loader').removeClass('no-display');
loader.find('.dup-pro-meter > span').css('width', '0%');
loader.find('.text').text('0%');
},
onFileProgress: function (e, file, percent, eventObj)
{
let position = 0;
if ('currentChunk' in file) {
position = file.currentChunk * file.chunkSize;
} else {
if (eventObj.lengthComputable) {
position = eventObj.loaded || eventObj.position;
} else {
position = false;
}
}
DupPro.ImportManager.updateProgress(position, file.size);
},
onFileComplete: function (e, file, response, showMessage = true)
{
let result = null;
if (typeof response === 'string' || response instanceof String) {
result = JSON.parse(response);
} else {
result = response;
}
DupPro.ImportManager.resetUploadTimes();
if (result.success == false) {
DupPro.ImportManager.uploadError(result.data.message);
return;
}
DupPro.ImportManager.packageRowUploading.data('path', result.data.funcData.archivePath);
if (result.data.funcData.isImportable) {
DupPro.ImportManager.packageRowUploading.addClass('is-importable');
DupPro.ImportManager.packageRowUploading
.find('.dup-pro-import-action-install')
.prop('disabled', false)
.data('install-url', result.data.funcData.installerPageLink);
DupPro.ImportManager.autoLaunchLink = result.data.funcData.installerPageLink;
} else {
DupPro.ImportManager.autoLaunchLink = false;
DupPro.ImportManager.packageRowUploading.find('.dup-pro-import-action-package-detail-toggle').trigger('click');
}
DupPro.ImportManager.packageRowUploading.find('.dup-pro-import-package-detail').html(result.data.funcData.htmlDetails);
DupPro.ImportManager.packageRowUploading.find('.size').text(Duplicator.Util.humanFileSize(result.data.funcData.archiveSize));
DupPro.ImportManager.packageRowUploading.find('.created').text(result.data.funcData.created);
DupPro.ImportManager.packageRowUploading.find('.funcs .dup-pro-loader').addClass('no-display');
DupPro.ImportManager.packageRowUploading.find('.funcs .actions').removeClass('no-display');
DupPro.ImportManager.packageRowUploading = null;
if (showMessage) {
<?php $packageUploaded->showMessage(); ?>
}
},
onFileError: function (e, file, error)
{
if (error === 'abort') {
// no message for abort
DupPro.ImportManager.uploadError(null);
} else if (error === 'size') {
DupPro.ImportManager.uploadError(<?php echo json_encode(__('The file size exceeds the maximum upload limit.', 'duplicator-pro')); ?>);
} else {
DupPro.ImportManager.uploadError(error);
}
},
getTimeLeft: function (sizeToFinish) {
if (DupPro.ImportManager.lastUploadsTimes.length < 2) {
return false;
}
let pos1 = DupPro.ImportManager.lastUploadsTimes[0].pos;
let time1 = DupPro.ImportManager.lastUploadsTimes[0].time;
let index = DupPro.ImportManager.lastUploadsTimes.length - 1
let pos2 = DupPro.ImportManager.lastUploadsTimes[index].pos;
let time2 = DupPro.ImportManager.lastUploadsTimes[index].time;
let deltaPos = pos2 - pos1;
let deltaTime = time2 - time1;
return deltaTime / deltaPos * sizeToFinish;
},
millisecToTime: function (s) {
if (s <= 0) {
return 'loading...';
}
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
let result = '';
if (hrs > 0) {
result += ' ' + hrs + ' hr';
}
if (mins > 0) {
result += ' ' + (mins + 1) + ' min';
return result;
}
return secs + ' sec';
},
resetUploadTimes: function() {
DupPro.ImportManager.lastUploadsTimes = [];
},
addUploadTime: function (postion) {
if (DupPro.ImportManager.lastUploadsTimes.length > 20) {
DupPro.ImportManager.lastUploadsTimes.shift();
}
DupPro.ImportManager.lastUploadsTimes.push({
'pos': postion,
'time': Date.now()
});
},
updateProgress: function (position, total) {
let percent = 0;
if (position !== false) {
DupPro.ImportManager.addUploadTime(position);
percent = Math.round((position / total) * 100 * 10) / 10;
percent = Number.isInteger(percent) ? percent + ".0" : percent;
}
DupPro.ImportManager.packageRowUploading.find('.size').text(Duplicator.Util.humanFileSize(total));
let timeLeft = DupPro.ImportManager.getTimeLeft(total - position);
let loader = DupPro.ImportManager.packageRowUploading.find('.funcs .dup-pro-loader');
loader.find('.dup-pro-meter > span').css("width", percent + "%");
loader.find('.text').text(percent + "% - " + DupPro.ImportManager.millisecToTime(timeLeft));
},
updateContentMessage: function (icon, line1, line2) {
DupPro.ImportManager.uploaderContent.find('.message').html('<i class="fas ' + icon + ' fa-sm"></i> ' + line1 + '<br>' + line2);
},
uploadError: function(message) {
DupPro.ImportManager.removeRow(DupPro.ImportManager.packageRowUploading);
DupPro.ImportManager.packageRowUploading = null;
if (message != null) {
DupPro.addAdminMessage(uploadFileMessageContent, 'error', {
'hideDelay': 60000,
'updateCallback': function (msgNode) {
msgNode.find('.import-upload-error-message').text(message);
}
});
}
},
isAlreadyExists: function (name) {
let alreadyExists = false;
DupPro.ImportManager.packagesList.find('tbody .name .text').each(function () {
if (name === $(this).text()) {
alreadyExists = true;
}
});
return alreadyExists;
},
isValidFileName: function (name) {
if (!name.match(<?php echo DUPLICATOR_PRO_ARCHIVE_REGEX_PATTERN; ?>)) {
return false;
}
return true;
},
abortUpload: function () {
try {
DupPro.ImportManager.uploader.upload("abort");
} catch (err) {
// prevent abort error
}
DupPro.ImportManager.removeRow(DupPro.ImportManager.packageRowUploading);
DupPro.ImportManager.packageRowUploading = null;
},
removePackage: function () {
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_import_package_delete',
path: DupPro.ImportManager.packageRowToDelete.data('path'),
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_import_package_delete')); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
DupPro.ImportManager.removeRow(DupPro.ImportManager.packageRowToDelete);
<?php $packageRemoved->showMessage(); ?>;
return '';
}
);
},
removeRow: function (row) {
if (!row) {
return;
}
row.fadeOut(
'fast',
function () {
row.remove();
if (DupPro.ImportManager.packagesList.find('.dup-pro-import-package').length === 0) {
DupPro.ImportManager.packageRowNoFoundTemplate.clone().appendTo(DupPro.ImportManager.packagesList);
}
DupPro.ImportManager.checkMaxUploadedFiles();
}
);
},
checkMaxUploadedFiles: function () {
let limit = 0; // 0 no limit
let numPackages = $('.packages-list .dup-pro-import-package').length;
if ($('#dpro-pro-import-available-packages').hasClass('view-single-item')) {
limit = 1;
}
if (limit > 0 && numPackages >= limit) {
DupPro.ImportManager.uploaderDisabler.show();
DupPro.ImportManager.uploader.upload("disable");
} else {
DupPro.ImportManager.uploaderDisabler.hide();
DupPro.ImportManager.uploader.upload("enable");
}
},
disableWrapper: function () {
DupPro.ImportManager.uploaderWrapper
},
updateViewMode: function (viewMode) {
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_import_set_view_mode',
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_import_set_view_mode')); ?>',
view_mode: viewMode
},
function (result, data, funcData, textStatus, jqXHR) {
switch (funcData) {
case '<?php echo esc_js(ImportPageController::VIEW_MODE_ADVANCED); ?>':
$('.dup-pro-import-view-single').removeClass('active');
$('.dup-pro-import-view-list').addClass('active');
$('#dup-pro-basic-mode-message').addClass('no-display');
DupPro.ImportManager.packagesAviable.removeClass('view-single-item').addClass('view-list-item');
break;
case '<?php echo esc_js(ImportPageController::VIEW_MODE_BASIC); ?>':
$('.dup-pro-import-view-list').removeClass('active');
$('.dup-pro-import-view-single').addClass('active');
$('#dup-pro-basic-mode-message').removeClass('no-display');
DupPro.ImportManager.packagesAviable.removeClass('view-list-item').addClass('view-single-item');
break;
default:
throw '<?php echo esc_js(__('Invalid view mode', 'duplicator-pro')); ?>';
}
DupPro.ImportManager.checkMaxUploadedFiles();
return '';
},
function (result, data, funcData, textStatus, jqXHR) {
DupPro.addAdminMessage(data.message, 'error', {'hideDelay': 5000});
return '';
}
);
},
console: function () {
if (this.debug) {
if (arguments.length > 1) {
console.log(arguments[0], arguments[1]);
} else {
console.log(arguments[0]);
}
}
}
};
// wait form stone init, it's not a great method but for now I haven't found a better one.
window.setTimeout(DupPro.ImportManager.init, 500);
$('.dup-pro-import-box.closable').each(function () {
let box = $(this);
let title = $(this).find('.box-title');
let content = $(this).find('.box-content');
title.click(function () {
if (box.hasClass('opened')) {
box.removeClass('opened').addClass('closed');
} else {
box.removeClass('closed').addClass('opened');
}
});
});
});
</script>

View File

@@ -0,0 +1,125 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\RecoveryController;
use Duplicator\Libs\Snap\SnapWP;
use Duplicator\Package\Recovery\RecoveryPackage;
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$postTypeCount = SnapWP::getPostTypesCount();
if (
($recoverPackage = RecoveryPackage::getRecoverPackage()) == false ||
$recoverPackage->isOutToDate()
) {
$badgeClass = 'badge-warn';
$badgeLabel = 'Notice';
} else {
$badgeClass = 'badge-pass';
$badgeLabel = 'Good';
}
?>
<div class="dup-pro-import-header" >
<h2 class="title">
<i class="fas fa-arrow-alt-circle-down"></i> <?php printf(esc_html__("Step %s of 2: Confirmation", 'duplicator-pro'), '<span class="red">2</span>'); ?>
</h2>
<hr />
</div>
<div class="dup-pro-recovery-details-max-width-wrapper" >
<div class="dup-pro-import-box closable opened" >
<div class="box-title" >
<?php esc_html_e('Disaster Recovery', 'duplicator-pro'); ?>
<div class="badge <?php echo esc_attr($badgeClass); ?> margin-right-1">
<?php echo esc_html($badgeLabel); ?>
</div>
</div>
<div class="box-content">
<div id="dup-pro-recovery-details-select-entry" class="dup-pro-recovery-info-set" >
<?php
RecoveryController::renderRecoveryWidged(array(
'selector' => true,
'subtitle' => '',
'copyLink' => true,
'copyButton' => true,
'launch' => false,
'download' => true,
'info' => true,
));
?>
</div>
<hr>
<div class="dup-pro-recovery-not-required">
<i class="far fa-arrow-alt-circle-right"></i>
<?php
esc_html_e(
'The Recovery Point is not mandatory to perform an import.
However, it can assist in restoring this site if there is a problem during install.
If you have no need to recover this site then you can continue without creating the Recovery Point.',
'duplicator-pro'
);
?>
</div>
</div>
</div><br/>
<div class="dup-pro-import-box closable opened" >
<div class="box-title" >
<?php esc_html_e('System Overview', 'duplicator-pro'); ?>
</div>
<div class="box-content">
<div id="dup-pro-recovery-details-overview" >
<div>
<?php esc_html_e("This site currently contains", 'duplicator-pro'); ?>:
</div>
<table class="margin-left-2" >
<?php foreach ($postTypeCount as $label => $count) { ?>
<tr>
<td><?php echo esc_html($label); ?></td>
<td class="text-right"><?php echo (int) $count; ?></td>
</tr>
<?php } ?>
</table>
<p>
<?php esc_html_e("This process will:", 'duplicator-pro') ?>
</p>
<ul>
<li>
<i class="far fa-check-circle"></i>&nbsp;
<?php esc_html_e("Launch the interactive installer wizard to install this new package.", 'duplicator-pro'); ?>
</li>
</ul>
</div>
</div>
</div>
<div class="dup-pro-import-confirm-buttons">
<input
id="dup-pro-import-launch-installer-cancel"
type="button" class="button button-large recovery-reset"
value="<?php esc_attr_e('Cancel', 'duplicator-pro'); ?>"
>&nbsp;
<button
id="dup-pro-import-launch-installer-confirm"
type="button"
class="button button-primary button-large"
onclick="DupPro.ImportManager.confirmLaunchInstaller();"
>
<i class="fa fa-bolt fa-sm"></i> <?php esc_html_e('Launch Installer', 'duplicator-pro'); ?>
</button>
</div>
</div>

View File

@@ -0,0 +1,43 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\ImportPageController;
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
switch ($tplData['viewMode']) {
case ImportPageController::VIEW_MODE_ADVANCED:
$viewModeClass = 'view-list-item';
break;
case ImportPageController::VIEW_MODE_BASIC:
default:
$viewModeClass = 'view-single-item';
break;
}
?>
<div class="dup-pro-tab-content-wrapper" >
<div id="dup-pro-import-phase-one" >
<?php $tplMng->render('admin_pages/import/step1/import-step1'); ?>
</div>
<div id="dup-pro-import-phase-two" class="no-display" >
<?php $tplMng->render('admin_pages/import/import-step2'); ?>
</div>
</div>
<?php
require_once DUPLICATOR____PATH . '/views/tools/recovery/widget/recovery-widget-scripts.php';
$tplMng->render('admin_pages/import/import-scripts');

View File

@@ -0,0 +1,143 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\ImportPageController;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (DUP_PRO_Global_Entity::getInstance()->import_chunk_size == 0) {
$footerChunkInfo = sprintf(__('<b>Chunk Size:</b> N/A &nbsp;|&nbsp; <b>Max Size:</b> %s', 'duplicator-pro'), size_format(wp_max_upload_size()));
$toolTipContent = __('If you need to upload a larger file, go to [Settings > Import] and set Upload Chunk Size', 'duplicator-pro');
} else {
$footerChunkInfo = sprintf(
__(
'<b>Chunk Size:</b> %s &nbsp;|&nbsp; <b>Max Size:</b> No Limit',
'duplicator-pro'
),
size_format(ImportPageController::getChunkSize() * 1024)
);
$toolTipContent = __(
'The max file size limit is ignored when chunk size is enabled.
Use a large chunk size with fast connections and a small size with slower connections.
You can change the chunk size by going to [Settings > Import].',
'duplicator-pro'
);
}
/** @var string */
$openTab = $tplData['defSubtab'];
$hlpUpload = __(
'Upload speeds can be affected by various server connections and setups.
Additionally, chunk size can influence the upload speed [Settings > Import].
If changing the chunk size is still slow, try uploading the archive manually with these steps:',
'duplicator-pro'
);
$hlpUpload .= '<ul>' .
'<li>' . __('1. Cancel current upload', 'duplicator-pro') . '</li>' .
'<li>' . __('2. Manually upload archive to:<br/> &nbsp; &nbsp; <i>/wp-content/backups-dup-pro/imports/</i>', 'duplicator-pro') . '</li>' .
'<li>' . __('3. Refresh the Import screen', 'duplicator-pro') . '</li>' .
'</ul>';
?>
<!-- ==============================
DRAG/DROP AREA -->
<div id="dup-pro-import-upload-tabs-wrapper" class="dup-pro-tabs-wrapper margin-bottom-2">
<div id="dup-pro-import-mode-tab-header" class="clearfix margin-bottom-2" >
<div
id="dup-pro-import-mode-upload-tab"
class="<?php echo ($openTab == ImportPageController::L2_TAB_UPLOAD ? 'active' : ''); ?>"
data-tab-target="dup-pro-import-upload-file-tab"
>
<i class="far fa-file-archive"></i> <?php esc_html_e('Import File', 'duplicator-pro'); ?>
</div>
<div
id="dup-pro-import-mode-remote-tab"
class="<?php echo ($openTab == ImportPageController::L2_TAB_REMOTE_URL ? 'active' : ''); ?>"
data-tab-target="dup-pro-import-remote-file-tab"
>
<i class="fas fa-link"></i> <?php esc_html_e('Import Link', 'duplicator-pro'); ?>
</div>
</div>
<div
id="dup-pro-import-upload-file-tab"
class="tab-content <?php echo ($openTab == ImportPageController::L2_TAB_UPLOAD ? '' : 'no-display'); ?>"
>
<div id="dup-pro-import-upload-file" class="dup-pro-import-upload-box" ></div>
<div class="no_display" >
<div id="dup-pro-import-upload-file-content" class="center-xy" >
<i class="fa fa-download fa-2x"></i>
<span class="dup-drag-drop-message" >
<?php esc_html_e("Drag & Drop Archive File Here", 'duplicator-pro'); ?>
</span>
<input
id="dup-import-dd-btn"
type="button"
class="button button-large button-default dup-import-button"
name="dpro-files"
value="<?php esc_attr_e("Select File...", 'duplicator-pro'); ?>"
>
</div>
</div>
<div id="dup-pro-import-upload-file-footer" >
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_html_e("Upload Chunk Size", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($toolTipContent); ?>"
></i>&nbsp;<?php echo $footerChunkInfo; ?>&nbsp;|&nbsp;
<span
class="pointer link-style"
data-tooltip-title="<?php esc_html_e("Improve Upload Speed", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($hlpUpload); ?>"
>
<i><?php esc_html_e('Slow Upload', 'duplicator-pro'); ?></i>&nbsp;<i class="fas fa-question-circle fa-sm" ></i>
</span>
</div>
</div>
<div
id="dup-pro-import-remote-file-tab"
class="tab-content <?php echo ($openTab == ImportPageController::L2_TAB_REMOTE_URL ? '' : 'no-display'); ?>"
>
<div class="dup-pro-import-upload-box">
<div class="center-xy" >
<i class="fa fa-download fa-2x"></i>
<span class="dup-drag-drop-message" >
<?php esc_html_e("Import From Link", 'duplicator-pro'); ?>
</span>
<input
type="text"
id="dup-pro-import-remote-url"
placeholder="<?php esc_attr_e('Enter Full URL to Archive', 'duplicator-pro'); ?>" />
<button id="dup-pro-import-remote-upload" type="button" class="button button-large button-default dup-import-button" >
<?php esc_html_e("Upload", 'duplicator-pro'); ?>
</button> <br/>
<small>
<?php
printf(
esc_html_x(
'For additional help visit the %1$sonline faq%2$s.',
'%1$s and %2$s are <a> tags',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-handle-import-install-upload-launch-issues')
. '" target="_blank">',
'</a>'
);
?>
</small>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,45 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $blur
*/
$blur = $tplData['blur'];
if ($tplData['adminMessageViewModeSwtich'] && !$blur) {
$tplMng->render('admin_pages/import/step1/message-view-mode-switch');
}
?>
<div class="dup-pro-import-header" >
<h2 class="title">
<i class="fas fa-arrow-alt-circle-down"></i>
<?php printf(esc_html__("Step %s of 2: Upload Archive", 'duplicator-pro'), '<span class="red">1</span>'); ?>
</h2>
<?php if (!$blur) { ?>
<div class="options" >
<?php $tplMng->render('admin_pages/import/step1/views-and-options'); ?>
</div>
<?php } ?>
<hr />
</div>
<div class="dup-import-header-content-wrapper <?php echo ($blur ? 'dup-mock-blur' : ''); ?>" >
<?php $tplMng->render('admin_pages/import/step1/add-file-area'); ?>
<?php $tplMng->render('admin_pages/import/step1/packages-list'); ?>
</div>

View File

@@ -0,0 +1,32 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?><div class="notice notice-success is-dismissible">
<p>
<?php
printf(
esc_html_x(
'The mode has %1$sswitched to advanced%2$s because more packages have been detected in the import folder.',
'%1$s and %2$s are opening and closing bold tags (<b> and </b>)',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</p>
</div>

View File

@@ -0,0 +1,31 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<tr class="dup-pro-import-no-package-found">
<td colspan="4" >
<div class="dup-pro-import-no-package-found-msg">
<b><?php esc_html_e("No archive files found!", 'duplicator-pro'); ?></b><br/><br/>
<?php esc_html_e("Please upload a Duplicator archive.zip/daf in the area above.", 'duplicator-pro'); ?><br/>
<?php esc_html_e("This will start the import process to overwrite the current site.", 'duplicator-pro'); ?>
<br/><br/>
<a href="javascript:void(0)" title="Get Help" onclick="jQuery('#contextual-help-link').trigger('click')">
<?php esc_html_e('How does this work?', 'duplicator-pro'); ?>
</a>
</div>
</td>
</tr>

View File

@@ -0,0 +1,102 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Package\Import\PackageImporter;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
/** @var PackageImporter $importObj */
$importObj = $tplData['importObj'];
if ($importObj instanceof PackageImporter) {
$name = $importObj->getName();
$size = $importObj->getSize();
$created = $importObj->getCreated();
$archivePath = $importObj->getFullPath();
$htmlDetails = $importObj->getHtmlDetails(false);
$installPakageUrl = $importObj->getInstallerPageLink();
$isImportable = $importObj->isImportable();
$funcsEnalbed = true;
} else {
$name = '';
$size = '';
$created = '';
$archivePath = '';
$htmlDetails = '';
$installPakageUrl = '';
$isImportable = false;
$funcsEnalbed = false;
}
$idHtml = strlen($tplData['idRow']) ? 'id="' . esc_attr($tplData['idRow']) . '" ' : '' ;
$rowClasses = array('dup-pro-import-package');
$installerActionClasses = array(
'dup-pro-import-action-install',
'button',
'button-primary',
);
if ($isImportable) {
$rowClasses[] = 'is-importable';
} else {
$installerActionClasses[] = 'disabled';
}
?>
<tr <?php echo $idHtml; ?> class="<?php echo esc_attr(implode(' ', $rowClasses)) ?>" data-path="<?php echo esc_attr($archivePath); ?>" >
<td class="name">
<span class="text"><?php echo esc_html($name); ?></span>
<div class="dup-pro-import-package-detail no-display" >
<?php echo $htmlDetails; ?>
</div>
</td>
<td class="size">
<span title="<?php printf(esc_attr__('Total %d bytes', 'duplicator-pro'), esc_attr($size)); ?>" >
<?php echo esc_html(DUP_PRO_U::byteSize($size)); ?>
</span>
</td>
<td class="created">
<?php echo esc_html($created); ?>
</td>
<td class="funcs">
<div class="actions <?php echo $funcsEnalbed ? '' : 'no-display'; ?>" >
<button type="button" class="button dup-pro-import-action-package-detail-toggle" >
<i class="fa fa-caret-down"></i> <?php esc_html_e('Details', 'duplicator-pro'); ?>
</button>
<span class="separator" ></span>
<button type="button" class="dup-pro-import-action-remove button button-secondary" >
<i class="fa fa-ban"></i> <?php esc_html_e('Remove', 'duplicator-pro'); ?>
</button>
<span class="separator" ></span>
<button type="button" class="dup-pro-import-action-install button button-primary"
data-install-url="<?php echo esc_url($installPakageUrl); ?>"
<?php echo $isImportable ? '' : 'disabled'; ?>>
<i class="fa fa-bolt fa-sm"></i> <?php esc_html_e('Continue', 'duplicator-pro'); ?>
</button>
</div>
<div class="invalid no-display" >
Package invalid
</div>
<div class="dup-pro-loader no-display" >
<div class="dup-pro-meter-wrapper" >
<div class="dup-pro-meter blue">
<span style="width: 0%"></span>
</div>
<span class="text">0%</span>
</div>
<a href="" class="dup-pro-import-action-cancel-upload button button-cancel" >
<i class="fa fa-ban"></i> <?php esc_html_e('Cancel', 'duplicator-pro'); ?>
</a>
</div>
</td>
</tr>

View File

@@ -0,0 +1,75 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\ImportPageController;
use Duplicator\Package\Import\PackageImporter;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
switch ($tplData['viewMode']) {
case ImportPageController::VIEW_MODE_ADVANCED:
$viewModeClass = 'view-list-item';
break;
case ImportPageController::VIEW_MODE_BASIC:
default:
$viewModeClass = 'view-single-item';
break;
}
?>
<div id="dpro-pro-import-available-packages" class="<?php echo esc_attr($viewModeClass); ?>" >
<table class="dup-import-avail-packs packages-list">
<thead>
<tr>
<th class="name"><?php esc_html_e("Archives", 'duplicator-pro'); ?></th>
<th class="size"><?php esc_html_e("Size", 'duplicator-pro'); ?></th>
<th class="created"><?php esc_html_e("Created", 'duplicator-pro'); ?></th>
<th class="funcs"><?php esc_html_e("Status", 'duplicator-pro'); ?></th>
</tr>
</thead>
<tbody>
<?php
$importObjs = PackageImporter::getArchiveObjects();
if (count($importObjs) === 0) {
$tplMng->render('admin_pages/import/step1/package-row-no-found');
} else {
foreach ($importObjs as $importObj) {
$tplMng->render(
'admin_pages/import/step1/package-row',
array(
'importObj' => $importObj,
'idRow' => '',
)
);
}
}
?>
</tbody>
</table>
<div class="no_display" >
<table id="dup-pro-import-available-packages-templates">
<?php
$tplMng->render(
'admin_pages/import/step1/package-row',
array(
'importObj' => null,
'idRow' => 'dup-pro-import-row-template',
)
);
$tplMng->render('admin_pages/import/step1/package-row-no-found');
?>
</table>
</div>
</div>

View File

@@ -0,0 +1,67 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\Controllers\ControllersManager;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$importSettingsUrl = $ctrlMng->getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_IMPORT
);
?>
<div id="dup-pro-import-vews-and-opt-wrapper" >
<ul class="dup-pro-toggle-sub-menu">
<li>
<span class="dup-pro-toggle" >
<span class="button" >
<i class="fas fa-bars fa-lg"></i><span class="screen-reader-text">Options</span>
</span>
</span>
<ul>
<li class="title"><?php esc_html_e('VIEWS', 'duplicator-pro'); ?></li>
<li>
<span class="link-style no-decoration dup-pro-import-view-list <?php echo $tplData['viewMode'] == 'list' ? 'active' : ''; ?>">
<?php _e('Advanced mode', 'duplicator-pro'); ?>
<span class="description">View multiple packages</span>
</span>
</li>
<li>
<span class="link-style no-decoration dup-pro-import-view-single <?php echo $tplData['viewMode'] == 'single' ? 'active' : ''; ?>">
Basic mode
<span class="description"><?php esc_html_e('View last uploaded package', 'duplicator-pro'); ?></span>
</span>
</li>
<li class="title separator"><?php esc_html_e('TOOLS', 'duplicator-pro'); ?></li>
<?php if (CapMng::can(CapMng::CAP_SETTINGS, false)) { ?>
<li>
<a class="no-decoration" href="<?php echo esc_url($importSettingsUrl); ?>" target="_blank">
<?php esc_html_e('Import Settings', 'duplicator-pro'); ?>
</a>&nbsp;
<i class="fas fa-external-link-alt fa-small" ></i>
</li>
<?php } ?>
<li>
<span class="link-style no-decoration dup-pro-open-help-link">
<?php esc_html_e('Quick Start', 'duplicator-pro'); ?>
</span>
</li>
</ul>
</li>
</ul>
</div>

View File

@@ -0,0 +1,975 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\StoragePageController;
use Duplicator\Core\CapMng;
use Duplicator\Installer\Package\ArchiveDescriptor;
use Duplicator\Libs\Snap\SnapJson;
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Package\Create\BuildComponents;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var DUP_PRO_Package $package
*/
$package = $tplData['package'];
$global = DUP_PRO_Global_Entity::getInstance();
$ui_css_general = (DUP_PRO_UI_ViewState::getValue('dup-package-dtl-general-panel') ? 'display:block' : 'display:none');
$ui_css_storage = (DUP_PRO_UI_ViewState::getValue('dup-package-dtl-storage-panel') ? 'display:block' : 'display:none');
$ui_css_archive = (DUP_PRO_UI_ViewState::getValue('dup-package-dtl-archive-panel') ? 'display:block' : 'display:none');
$ui_css_install = (DUP_PRO_UI_ViewState::getValue('dup-package-dtl-install-panel') ? 'display:block' : 'display:none');
$archiveDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Archive);
$logDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Log);
$installerDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Installer);
$showLinksDialogJson = SnapJson::jsonEncodeEscAttr(array(
"archive" => $archiveDownloadURL,
"log" => $logDownloadURL,
"installer" => $installerDownloadURL,
));
$lang_notset = __("- not set -", 'duplicator-pro');
$tplMng->render('admin_pages/packages/details/details_header');
?>
<div class="dup-package-details-wrapper">
<div class="toggle-box">
<a href="javascript:void(0)" onclick="DupPro.Pack.OpenAll()">
[<?php esc_html_e('open all', 'duplicator-pro'); ?>]
</a> &nbsp;
<a href="javascript:void(0)" onclick="DupPro.Pack.CloseAll()">
[<?php esc_html_e('close all', 'duplicator-pro'); ?>]
</a>
</div>
<!-- ===============================
GENERAL -->
<div class="dup-box dup-box-general">
<div class="dup-box-title">
<i class="fa fa-archive fa-sm"></i> <?php esc_html_e('General', 'duplicator-pro') ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('General', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dup-package-dtl-general-panel" style="<?php echo esc_attr($ui_css_general) ?>">
<table class='dup-dtl-data'>
<tr>
<td><?php esc_html_e("Name", 'duplicator-pro') ?>:</td>
<td>
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<a href="javascript:void(0);" onclick="jQuery(this).parent().find('.dup-link-data').toggle()" class="dup-toggle-name">
<?php echo esc_html($package->Name) ?>
</a>
<div class="dup-link-data">
<b><?php esc_html_e("ID", 'duplicator-pro') ?>:</b> <?php echo absint($package->ID); ?><br/>
<b><?php esc_html_e("Hash", 'duplicator-pro') ?>:</b> <?php echo esc_html($package->Hash); ?><br/>
<b><?php esc_html_e("Full Name", 'duplicator-pro') ?>:</b> <?php echo esc_html($package->NameHash); ?><br/>
</div>
<?php } else { ?>
<?php echo esc_html($package->Name) ?>
<?php } ?>
</td>
</tr>
<tr>
<td><?php esc_html_e("Notes", 'duplicator-pro') ?>:</td>
<td><?php echo strlen($package->notes) ? esc_html($package->notes) : esc_html__("- no notes -", 'duplicator-pro') ?></td>
</tr>
<tr>
<td><?php esc_html_e("Created", 'duplicator-pro') ?>:</td>
<td>
<?php if (strlen($package->getCreated())) : ?>
<a href="javascript:void(0);" onclick="jQuery(this).parent().find('.dup-link-data').toggle()" class="dup-toggle-created">
<?php echo esc_html(get_date_from_gmt($package->getCreated())) ?>
</a>
<div class="dup-link-data dup-link-data-created">
<?php
$datetime1 = new DateTime($package->getCreated());
$datetime2 = new DateTime(date("Y-m-d H:i:s"));
$diff = $datetime1->diff($datetime2);
$fulldate = $diff->y . __(' years, ', 'duplicator-pro') .
$diff->m . __(' months, ', 'duplicator-pro') . $diff->d . __(' days', 'duplicator-pro');
$fulldays = $diff->format('%a') . __(' days', 'duplicator-pro');
?>
<b><?php esc_html_e("Full Age", 'duplicator-pro'); ?>: </b> <?php echo esc_html($fulldate); ?> <br/>
<b><?php esc_html_e("Days Old", 'duplicator-pro'); ?>: </b> <?php echo esc_html($fulldays); ?> <br/>
</div>
<?php else : ?>
<?php esc_html_e("- not set in this version -", 'duplicator-pro'); ?>
<?php endif; ?>
</td>
</tr>
<tr>
<td><?php esc_html_e("Versions", 'duplicator-pro') ?>:</td>
<td>
<a href="javascript:void(0);" onclick="jQuery(this).parent().find('.dup-link-data').toggle()" class="dup-toggle-versions">
<?php echo esc_html($package->getVersion()) ?>
</a>
<div class="dup-link-data dup-link-data-versions">
<b><?php esc_html_e("WordPress", 'duplicator-pro') ?>:</b>
<?php echo strlen($package->VersionWP) ? esc_html($package->VersionWP) : esc_html__("- unknown -", 'duplicator-pro') ?><br/>
<b><?php esc_html_e("PHP", 'duplicator-pro') ?>:</b>
<?php echo strlen($package->VersionPHP) ? esc_html($package->VersionPHP) : esc_html__("- unknown -", 'duplicator-pro') ?><br/>
<b><?php esc_html_e("OS", 'duplicator-pro') ?>:</b>
<?php echo strlen($package->VersionOS) ? esc_html($package->VersionOS) : esc_html__("- unknown -", 'duplicator-pro') ?><br/>
<b><?php esc_html_e("Mysql", 'duplicator-pro') ?>:</b>
<?php echo strlen($package->VersionDB) ? esc_html($package->VersionDB) : esc_html__("- unknown -", 'duplicator-pro') ?> |
<?php
echo strlen($package->Database->Comments) ?
esc_html($package->Database->Comments) :
esc_html__('- unknown -', 'duplicator-pro');
?>
<br/>
</div>
</td>
</tr>
<tr>
<td><?php esc_html_e("Runtime", 'duplicator-pro') ?>:</td>
<td>
<?php
$search_types = array(
'sec.',
',',
);
$minute_view = trim(str_replace($search_types, '', $package->Runtime));
if (is_numeric($minute_view)) {
$minute_view = gmdate("H:i:s", (int) $minute_view);
}
echo strlen($package->Runtime) ?
esc_html($package->Runtime) . ' &nbsp; <i>(' . esc_html($minute_view) . ')</i>' :
esc_html__('error running', 'duplicator-pro');
?>
</td>
</tr>
<tr>
<td><?php esc_html_e("Type", 'duplicator-pro') ?>:</td>
<td><?php echo esc_html($package->get_type_string()); ?></td>
</tr>
<?php if (CapMng::can(CapMng::CAP_EXPORT, false)) { ?>
<tr>
<td><?php esc_html_e("Files", 'duplicator-pro') ?>:</td>
<td>
<div id="dpro-downloads-area">
<?php if ($package->Status != DUP_PRO_PackageStatus::ERROR) : ?>
<?php if ($package->haveLocalStorage()) : ?>
<button
class="button dup-downloads-installer"
onclick="DupPro.Pack.DownloadFile('<?php echo esc_attr($installerDownloadURL); ?>');return false;"
>
<i class="fa fa-bolt fa-sm"></i> Installer
</button>&nbsp;
<button
class="button dup-downloads-archive"
onclick="DupPro.Pack.DownloadFile('<?php echo esc_attr($archiveDownloadURL); ?>');return false;"
>
<i class="far fa-file-archive fa-sm"></i> Archive - <?php echo esc_html($package->ZipSize) ?>
</button>&nbsp;
<button
class="button thickbox dup-downloads-share-links"
onclick="DupPro.Pack.ShowLinksDialog(<?php echo esc_js($showLinksDialogJson); ?>);"
>
<i class="fas fa-share-alt fa-sm"></i>
<?php esc_html_e("Share File Links", 'duplicator-pro') ?>
</button>
<table class="dup-pack-dtls-sublist">
<tr>
<td><?php esc_html_e("Archive", 'duplicator-pro') ?>: </td>
<td>
<a
href="<?php echo esc_attr($archiveDownloadURL); ?>"
target="file_results" class="dup-link-archive"
download="<?php echo esc_attr($package->Archive->File) ?>"
>
<?php echo esc_html($package->Archive->File) ?>
</a>
</td>
</tr>
<tr>
<td><?php esc_html_e("Installer", 'duplicator-pro') ?>: </td>
<td>
<a class="dup-link-installer" href="<?php echo esc_url($installerDownloadURL); ?>">
<?php echo esc_html($package->Installer->getInstallerName()); ?>
</a>
</td>
</tr>
<tr>
<td><?php esc_html_e("Build Log", 'duplicator-pro') ?>: </td>
<td>
<a class="dup-link-build-log" href="<?php echo esc_attr($logDownloadURL); ?>" target="file_results">
<?php echo esc_html($package->get_log_filename()); ?>
</a>
</td>
</tr>
<tr>
<td class="sub-notes">
<i class="fas fa-download"></i> <?php esc_html_e("Click links to download", 'duplicator-pro') ?>
</td>
</tr>
</table>
<?php else : ?>
<!-- CLOUD ONLY FILES -->
<div id="dpro-downloads-msg">
<i class="fas fa-server"></i>
<?php
esc_html_e(
"The package files are in remote storage location(s). Please visit the storage provider to download.",
'duplicator-pro'
);
?>
</div> <br/>
<button class="button" disabled="true">
<i class="fa fa-exclamation-triangle fa-sm"></i> Installer - <?php echo esc_html(DUP_PRO_U::byteSize($package->Installer->Size)) ?>
</button>
<button class="button" disabled="true">
<i class="fa fa-exclamation-triangle fa-sm"></i> Archive - <?php echo esc_html($package->ZipSize) ?>
</button>
<div class="margin-top-1">
<b><?php esc_html_e("Build Log", 'duplicator-pro') ?>:</b>&nbsp;
<a href="<?php echo esc_url($logDownloadURL); ?>" target="file_results"><?php echo esc_html($package->get_log_filename()); ?></a>
</div>
<?php endif; ?>
<?php else : ?>
<div class="maroon">
<i class="fas fa-exclamation-circle"></i>
<?php esc_html_e("Package files were not created successfully. Please see the build log for more details.", 'duplicator-pro') ?>
</div><br/>
<b><?php esc_html_e("Build Log", 'duplicator-pro') ?>:</b>&nbsp;
<a href="<?php echo esc_attr($logDownloadURL); ?>" target="file_results"><?php echo esc_html($package->get_log_filename()); ?></a>
<?php endif; ?>
</div>
</td>
</tr>
<?php } ?>
</table>
</div>
</div>
<!-- ==========================================
DIALOG: SHARE LINKS -->
<?php add_thickbox(); ?>
<div id="dup-dlg-quick-path" title="<?php esc_attr_e('Download Links', 'duplicator-pro'); ?>" style="display:none">
<p class="maroon">
<i class="fa fa-lock fa-sm"></i>
<?php esc_html_e("The following links contain sensitive data. Please share with caution!", 'duplicator-pro'); ?>
</p>
<div style="padding: 0px 15px 15px 15px;">
<a
href="javascript:void(0)"
style="display:inline-block; text-align:right"
onclick="DupPro.Pack.GetLinksText()"
>
[<?php esc_html_e('Select & Copy', 'duplicator-pro'); ?>]
</a><br/>
<textarea id="dpro-dlg-quick-path-data" style='border:1px solid silver; border-radius:3px; width:99%; height:230px; font-size:11px'></textarea><br/>
<i style='font-size:11px'>
<?php
printf(
"%s <a href='" . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . "how-to-work-with-daf-files-and-the-duparchive-extraction-tool") .
"' target='_blank'>%s</a>",
esc_html__(
"An exact copy of the database SQL and installer file can both be found inside of the archive.zip/daf file.
Download and extract the archive file to get a copy of the installer which will be named 'installer-backup.php'.
For details on how to extract a archive.daf file please see: ",
"duplicator-pro"
),
esc_html__("How do I work with DAF files and the DupArchive extraction tool?", "duplicator-pro")
);
?>
</i>
</div>
</div>
<!-- ===============================
STORAGE -->
<div class="dup-box dup-box-storage">
<div class="dup-box-title">
<i class="fas fa-server fa-sm"></i> <?php esc_html_e('Storage', 'duplicator-pro') ?>
<button class="dup-box-arrow">
<span class="screen-reader-text">
<?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Storage Options', 'duplicator-pro') ?>
</span>
</button>
</div>
<div class="dup-box-panel" id="dup-package-dtl-storage-panel" style="<?php echo esc_attr($ui_css_storage) ?>">
<table class="widefat package-tbl">
<thead>
<tr>
<th style='width:175px'><?php esc_html_e('Type', 'duplicator-pro') ?></th>
<th style='width:275px'><?php esc_html_e('Name', 'duplicator-pro') ?></th>
<th style="white-space: nowrap"><?php esc_html_e('Location', 'duplicator-pro') ?></th>
</tr>
</thead>
<?php
$i = 0;
$latest_upload_infos = $package->get_latest_upload_infos();
foreach ($latest_upload_infos as $upload_info) :
if ($upload_info->has_completed(true) == false) {
// For now not displaying any cancelled or failed storages
continue;
}
if (($store = AbstractStorageEntity::getById($upload_info->getStorageId())) === false) {
continue;
}
$i++;
$store_type = $store->getStypeName();
$store_id = $store->getStypeName();
$store_location = $store->getLocationString();
$row_style = ($i % 2) ? 'alternate' : '';
?>
<tr class="package-row <?php echo esc_attr($row_style) ?>">
<td>
<?php
echo wp_kses(
$store->getSTypeIcon(),
[
'i' => [
'class' => [],
],
'img' => [
'src' => [],
'class' => [],
'alt' => [],
],
]
),
'&nbsp;',
esc_html($store->getName());
?>
</td>
<td>
<?php
if (CapMng::can(CapMng::CAP_STORAGE, false)) {
$editUrl = StoragePageController::getEditUrl($store)
?>
<a href="<?php echo esc_url($editUrl); ?>" target="_blank">
<?php echo esc_html($store->getName()); ?>
</a>
<?php } else {
echo esc_html($store->getName());
} ?>
</td>
<td>
<?php
echo wp_kses(
$store->getHtmlLocationLink(),
[
'a' => [
'href' => [],
'target' => [],
],
'span' => [],
]
);
?>
</td>
</tr>
<?php endforeach; ?>
<?php if ($i == 0) : ?>
<tr>
<td colspan="3" style="text-align: center">
<?php esc_html_e('- No storage locations associated with this package -', 'duplicator-pro'); ?>
</td>
</tr>
<?php endif; ?>
</table>
</div>
</div>
<!-- ===============================
ARCHIVE -->
<div class="dup-box dup-box-archive">
<div class="dup-box-title">
<i class="far fa-file-archive fa-sm"></i> <?php esc_html_e('Archive', 'duplicator-pro') ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Archive', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dup-package-dtl-archive-panel" style="<?php echo esc_attr($ui_css_archive) ?>">
<!-- FILES -->
<div class="section-hdr">
<i class="fas fa-folder-open fa-sm"></i>
<?php esc_html_e('FILES', 'duplicator-pro'); ?>
</div>
<table class='dup-dtl-data'>
<tr>
<td><?php esc_html_e("Engine", 'duplicator-pro') ?>: </td>
<td>
<?php
$zip_mode_string = __('Unknown', 'duplicator-pro');
if ($package->build_progress->current_build_mode == DUP_PRO_Archive_Build_Mode::ZipArchive) {
$zip_mode_string = __("ZipArchive", 'duplicator-pro');
if ($package->ziparchive_mode === DUP_PRO_ZipArchive_Mode::SingleThread) {
$zip_mode_string = __("ZipArchive ST", 'duplicator-pro');
}
} elseif ($package->build_progress->current_build_mode == DUP_PRO_Archive_Build_Mode::Shell_Exec) {
$zip_mode_string = __("Shell Exec", 'duplicator-pro');
} else {
$zip_mode_string = __("DupArchive", 'duplicator-pro');
}
echo esc_html($zip_mode_string);
?>
</td>
</tr>
<tr>
<td><?php esc_html_e("Filters", 'duplicator-pro') ?>: </td>
<td><?php echo $package->Archive->FilterOn == 1 ? 'On' : 'Off'; ?></td>
</tr>
<tr>
<td></td>
<td>
<div class="sub-filter-hdr">
<i class="far fa-folder-open"></i>
<?php esc_html_e("Directories", 'duplicator-pro') ?>
</div>
<div class="sub-filter-data sub-filter-data-directories">
<?php
//CUSTOM
$title = __("User defined filtered directories", 'duplicator-pro');
$count = count($package->Archive->FilterInfo->Dirs->Instance);
?>
<a
href="javascript:void(0)"
onclick="jQuery(this).parent().children('.filter-info').eq(0).toggle(200)"
title="<?php echo esc_attr($title) ?>"
>
<i class="fa fa-filter fa-fw fa-xs"></i><?php esc_html_e('User Defined', 'duplicator-pro') ?>
</a>
<sup>(<?php echo (int) $count ?>)</sup>
<br/>
<div class="filter-info">
<?php
if ($count == 0) {
esc_html_e('- filter type not found -', 'duplicator-pro');
} else {
foreach ($package->Archive->FilterInfo->Dirs->Instance as $dir) {
echo esc_html($dir) . ";<br/>";
}
}
?>
</div>
<?php
//UNREADABLE
$title = __("These paths are filtered because they are unreadable by the system", 'duplicator-pro');
$count = count($package->Archive->FilterInfo->Dirs->Unreadable);
?>
<a
href="javascript:void(0)"
onclick="jQuery(this).parent().children('.filter-info').eq(1).toggle(200)"
title="<?php esc_attr($title) ?>"
>
<i class="fa fa-filter fa-fw fa-xs"></i><?php esc_html_e('Unreadable', 'duplicator-pro') ?>
</a>
<sup>(<?php echo (int) $count ?>)</sup>
<br/>
<div class='filter-info'>
<?php
if ($count == 0) {
esc_html_e('- filter type not found -', 'duplicator-pro');
} else {
foreach ($package->Archive->FilterInfo->Dirs->Unreadable as $dir) {
echo esc_html($dir) . ";<br/>";
}
}
?>
</div>
</div>
</td>
</tr>
<tr>
<td></td>
<td>
<div class="sub-filter-hdr">
<i class="far fa-file"></i>
<?php esc_html_e("Files", 'duplicator-pro') ?>
</div>
<div class="sub-filter-data sub-filter-data-files">
<?php
//CUSTOM
$title = __("User defined filtered files", 'duplicator-pro');
$count = count($package->Archive->FilterInfo->Files->Instance);
?>
<a
href="javascript:void(0)"
onclick="jQuery(this).parent().children('.filter-info').eq(0).toggle(200)"
title="<?php echo esc_attr($title) ?>"
>
<i class="fa fa-filter fa-fw fa-xs"></i><?php esc_html_e('User Defined', 'duplicator-pro') ?>
</a>
<sup>(<?php echo (int) $count ?>)</sup>
<br/>
<div class="filter-info">
<?php
if ($count == 0) {
esc_html_e('- filter type not found -', 'duplicator-pro');
} else {
foreach ($package->Archive->FilterInfo->Files->Instance as $file) {
echo esc_html($file) . ";<br/>";
}
}
?>
</div>
<?php
//UNREADABLE
$title = __("These paths are filtered because they are unreadable by the system", 'duplicator-pro');
$count = count($package->Archive->FilterInfo->Files->Unreadable);
?>
<a
href="javascript:void(0)"
onclick="jQuery(this).parent().children('.filter-info').eq(1).toggle(200)"
title="<?php echo esc_attr($title) ?>"
>
<i class='fa fa-filter fa-fw fa-xs'></i><?php esc_html_e('Unreadable', 'duplicator-pro') ?>
</a>
<sup>(<?php echo (int) $count ?>)</sup>
<br/>
<div class="filter-info">
<?php
if ($count == 0) {
esc_html_e('- filter type not found -', 'duplicator-pro');
} else {
foreach ($package->Archive->FilterInfo->Files->Unreadable as $file) {
echo esc_html($file) . ";<br/>";
}
}
?>
</div>
</div>
</td>
</tr>
<tr>
<td></td>
<td>
<div class="sub-filter-hdr">
<i class="far fa-sticky-note"></i>
<?php esc_html_e("Extensions", 'duplicator-pro') ?>
</div>
<div class="sub-filter-data sub-filter-data-extensions">
<?php
if (count($package->Archive->FilterExtsAll) > 0) {
$filter_ext = implode(',', $package->Archive->FilterExtsAll);
echo esc_html($filter_ext);
} else {
esc_html_e('- no filters -', 'duplicator-pro');
}
?>
</div>
</td>
</tr>
<tr>
<td><?php esc_html_e('Components: ', 'duplicator-pro'); ?></td>
<td>
<?php
echo wp_kses(
BuildComponents::displayComponentsList($package->components, "</br>"),
[
'br' => [],
]
);
?>
</td>
</tr>
</table><br/>
<!-- DATABASE -->
<div class="section-hdr">
<i class="fas fa-database"></i>
<?php esc_html_e('DATABASE', 'duplicator-pro'); ?>
</div>
<?php if (!BuildComponents::isDBExcluded($package->components)) : ?>
<table class='dup-dtl-data'>
<tr>
<td><?php esc_html_e("Name", 'duplicator-pro') ?>: </td>
<td><?php echo esc_html($package->Database->info->name) ?></td>
</tr>
<tr>
<td><?php esc_html_e("Type", 'duplicator-pro') ?>: </td>
<td><?php echo esc_html($package->Database->Type) ?></td>
</tr>
<tr>
<td><?php esc_html_e("Engine", 'duplicator-pro') ?>: </td>
<td><?php echo esc_html($package->Database->info->dbEngine) ?></td>
</tr>
<tr>
<td><?php esc_html_e("SQL Mode", 'duplicator-pro') ?>: </td>
<td><?php echo esc_html($package->Database->DBMode) ?></td>
</tr>
<tr>
<td><?php esc_html_e("Filters", 'duplicator-pro') ?>: </td>
<td><?php echo $package->Database->FilterOn == 1 ? 'On' : 'Off'; ?></td>
</tr>
<tr>
<td> </td>
<td>
<?php
$title = __('User defined table filters.', 'duplicator-pro');
$count = (strlen($package->Database->FilterTables))
? count(explode(',', $package->Database->FilterTables))
: 0;
?>
<div class="sub-filter-hdr">
<i class="fas fa-table"></i>
<?php esc_html_e('Tables', 'duplicator-pro'); ?>
</div>
<div class="sub-filter-data sub-filter-data-tables">
<a
href='javascript:void(0)'
onclick="jQuery(this).parent().children('.filter-info').eq(0).toggle(200)" title="<?php echo esc_attr($title); ?>"
>
<i class='fa fa-filter fa-fw fa-xs'></i><?php esc_html_e('User Defined', 'duplicator-pro'); ?></a>
<sup>(<?php echo (int) $count; ?>)</sup>
<div id="dup-filter-tables" class="filter-info">
<?php
if (strlen($package->Database->FilterTables)) {
$filterTables = trim(str_replace(',', "<br/>", $package->Database->FilterTables));
echo wp_kses($filterTables, ['br' => []]);
} else {
esc_html_e('- no filters -', 'duplicator-pro');
}
?>
</div>
</div>
</td>
</tr>
<tr>
<td><?php esc_html_e('Size', 'duplicator-pro') ?>: </td>
<td><?php echo esc_html(DUP_PRO_U::byteSize($package->Database->info->tablesSizeOnDisk));?></td>
</tr>
<tr>
<td><?php esc_html_e('Collations', 'duplicator-pro') ?>: </td>
<td>
<?php
foreach ($package->Database->info->collationList as $collation) {
echo esc_html($collation) . "<br/>";
}
?>
</td>
</tr>
</table>
<?php else : ?>
<p>
<?php esc_html_e("The Database was excluded from the package.", "duplicator-pro"); ?>
</p>
<?php endif; ?>
<br/>
<!-- SETUP -->
<div class="section-hdr">
<i class="fas fa-sliders-h"></i>
<?php esc_html_e('SETUP', 'duplicator-pro'); ?>
</div>
<table class='dup-dtl-data'>
<tr>
<td><?php esc_html_e("Security", 'duplicator-pro'); ?>:</td>
<td>
<?php
switch ($package->Installer->OptsSecureOn) {
case ArchiveDescriptor::SECURE_MODE_NONE:
esc_html_e('None', 'duplicator-pro');
break;
case ArchiveDescriptor::SECURE_MODE_INST_PWD:
esc_html_e('Installer password', 'duplicator-pro');
break;
case ArchiveDescriptor::SECURE_MODE_ARC_ENCRYPT:
esc_html_e('Archive encryption', 'duplicator-pro');
break;
default:
throw new Exception('Invalid secure mode');
}
?>
</td>
</tr>
<tr>
<td></td>
<td class="sub-notes">
<?php
esc_html_e('Lost passwords cannot be recovered. A new archive will need to be created.', 'duplicator-pro');
?>
</td>
</tr>
</table>
</div>
</div>
<!-- ===============================
INSTALLER -->
<div class="dup-box dup-box-installer" style="margin-bottom: 50px">
<div class="dup-box-title">
<i class="fa fa-bolt fa-sm"></i> <?php esc_html_e('Installer', 'duplicator-pro') ?>
<?php if ($package->Installer->isSecure()) { ?>
<span id="dpro-install-secure-lock" title="<?php esc_attr_e('Installer password protection is on for this package.', 'duplicator-pro') ?>">
<i class="fa fa-lock fa-sm"></i>
</span>
<?php } else { ?>
<span id="dpro-install-secure-unlock" title="<?php esc_attr_e('Installer password protection is off for this package.', 'duplicator-pro') ?>">
<i class="fa fa-unlock-alt"></i>
</span>
<?php } ?>
<button class="dup-box-arrow">
<span class="screen-reader-text">
<?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Installer', 'duplicator-pro') ?>
</span>
</button>
</div>
<div class="dup-box-panel" id="dup-package-dtl-install-panel" style="<?php echo esc_attr($ui_css_install) ?>">
<br/>
<table class='dup-dtl-data'>
<tr>
<td colspan="2"><div class="dup-package-hdr-1"><?php esc_html_e("SETUP", 'duplicator-pro') ?></div></td>
</tr>
<?php if (License::can(License::CAPABILITY_BRAND)) : ?>
<tr>
<td><?php esc_html_e("Brand", 'duplicator-pro'); ?>:</td>
<td>
<span style="color:#AF5E52; font-weight: bold">
<?php echo esc_html($package->Brand) ?>
</span>
</td>
</tr>
<?php endif; ?>
<tr>
<td><?php esc_html_e("Security", 'duplicator-pro'); ?>:</td>
<td>
<?php echo $package->Installer->isSecure() ? esc_html__("On", 'duplicator-pro') : esc_html__("Off", 'duplicator-pro'); ?>
</td>
</tr>
</table><br/><br/>
<table style="width:100%">
<tr>
<td colspan="2"><div class="dup-package-hdr-1"><?php esc_html_e("PREFILLS", 'duplicator-pro') ?></div></td>
</tr>
</table>
<!-- ===================
STEP1 TABS -->
<div data-dpro-tabs="true">
<ul>
<li>&nbsp; <?php esc_html_e('Basic', 'duplicator-pro') ?> &nbsp;</li>
<li id="dpro-cpnl-tab-lbl"><?php esc_html_e('cPanel', 'duplicator-pro') ?></li>
</ul>
<!-- ===================
TAB1: Basic -->
<div>
<table class='dup-dtl-data dup-dtl-basic'>
<tr>
<td><?php esc_html_e("Host", 'duplicator-pro') ?>:</td>
<td><?php echo strlen($package->Installer->OptsDBHost) ? esc_html($package->Installer->OptsDBHost) : esc_html($lang_notset) ?></td>
</tr>
<tr>
<td><?php esc_html_e("Database", 'duplicator-pro') ?>:</td>
<td>
<?php
echo strlen($package->Installer->OptsDBName) ?
esc_html($package->Installer->OptsDBName) :
esc_html($lang_notset);
?>
</td>
</tr>
<tr>
<td><?php esc_html_e("User", 'duplicator-pro') ?>:</td>
<td><?php echo strlen($package->Installer->OptsDBUser) ? esc_html($package->Installer->OptsDBUser) : esc_html($lang_notset) ?></td>
</tr>
</table><br/>
</div>
<!-- ===================
TAB2: cPanel -->
<div style="max-height: 250px" class="dup-dtl-cpanel">
<table class='dup-dtl-data'>
<tr>
<td colspan="2" class="sub-section">&nbsp; <b><?php esc_html_e("cPanel Login", 'duplicator-pro') ?></b> &nbsp;</td>
</tr>
<tr class="sub-item">
<td><?php esc_html_e("Automation", 'duplicator-pro') ?>:</td>
<td><?php echo ($package->Installer->OptsCPNLEnable) ? 'On' : 'Off' ?></td>
</tr>
<tr class="sub-item">
<td><?php esc_html_e("Host", 'duplicator-pro') ?>:</td>
<td>
<?php
echo strlen($package->Installer->OptsCPNLHost) ?
esc_html($package->Installer->OptsCPNLHost) :
esc_html($lang_notset);
?>
</td>
</tr>
<tr class="sub-item">
<td><?php esc_html_e("User", 'duplicator-pro') ?>:</td>
<td>
<?php
echo strlen($package->Installer->OptsCPNLUser) ?
esc_html($package->Installer->OptsCPNLUser) :
esc_html($lang_notset);
?>
</td>
</tr>
<tr>
<td colspan="2" class="sub-section"><b><?php esc_html_e("MySQL Server", 'duplicator-pro') ?></b></td>
</tr>
<tr class="sub-item">
<td><?php esc_html_e("Action", 'duplicator-pro') ?>:</td>
<td>
<?php
echo ($package->Installer->OptsCPNLDBAction == 'create') ?
esc_html__("Create A New Database", 'duplicator-pro') :
esc_html__("Connect to Existing Database and Remove All Data", 'duplicator-pro');
?>
</td>
</tr>
<tr class="sub-item">
<td><?php esc_html_e("Host", 'duplicator-pro') ?>:</td>
<td>
<?php
echo strlen($package->Installer->OptsCPNLDBHost) ?
esc_html($package->Installer->OptsCPNLDBHost) :
esc_html($lang_notset);
?>
</td>
</tr>
<tr class="sub-item">
<td><?php esc_html_e("Database", 'duplicator-pro') ?>:</td>
<td>
<?php
echo strlen($package->Installer->OptsCPNLDBName) ?
esc_html($package->Installer->OptsCPNLDBName) :
esc_html($lang_notset);
?>
</td>
</tr>
<tr class="sub-item">
<td><?php esc_html_e("User", 'duplicator-pro') ?>:</td>
<td>
<?php
echo strlen($package->Installer->OptsCPNLDBUser) ?
esc_html($package->Installer->OptsCPNLDBUser) :
esc_html($lang_notset);
?>
</td>
</tr>
</table><br/>
</div>
</div><br/>
</div>
</div>
</div>
<script>
jQuery(document).ready(function ($)
{
/* Shows the Share 'Download Links' dialog
* @param json JSON containing all links
*/
DupPro.Pack.ShowLinksDialog = function(json)
{
var url = '#TB_inline?width=650&height=400&inlineId=dup-dlg-quick-path';
tb_show("<?php esc_html_e('Package File Links', 'duplicator-pro') ?>", url);
var msg = <?php printf(
'"%s" + "\n\n%s:\n" + json.archive + "\n\n%s:\n" + json.installer + "\n\n%s:\n" + json.log + "\n\n%s";',
'=========== SENSITIVE INFORMATION START ===========',
esc_html__("ARCHIVE", 'duplicator-pro'),
esc_html__("INSTALLER", 'duplicator-pro'),
esc_html__("LOG", 'duplicator-pro'),
'=========== SENSITIVE INFORMATION END ==========='
);
?>
$("#dpro-dlg-quick-path-data").val(msg);
return false;
}
/* Open all Panels */
DupPro.Pack.OpenAll = function () {
DupPro.UI.IsSaveViewState = false;
var states = [];
$("div.dup-box").each(function () {
var pan = $(this).find('div.dup-box-panel');
var panel_open = pan.is(':visible');
if (!panel_open)
$(this).find('div.dup-box-title').trigger("click");
states.push({
key: pan.attr('id'),
value: 1
});
});
DupPro.UI.SaveMulViewStatesByPost(states);
DupPro.UI.IsSaveViewState = true;
};
/* Close all Panels */
DupPro.Pack.CloseAll = function () {
DupPro.UI.IsSaveViewState = false;
var states = [];
$("div.dup-box").each(function () {
var pan = $(this).find('div.dup-box-panel');
var panel_open = pan.is(':visible');
if (panel_open)
$(this).find('div.dup-box-title').trigger("click");
states.push({
key: pan.attr('id'),
value: 0
});
});
DupPro.UI.SaveMulViewStatesByPost(states);
DupPro.UI.IsSaveViewState = true;
};
/**
* Submits the password for validation
*/
DupPro.togglePassword = function ()
{
var $input = $('#secure-pass');
var $button = $('#secure-btn');
if (($input).attr('type') == 'text') {
$input.attr('type', 'password');
$button.html('<i class="fas fa-eye fa-sm"></i>');
} else {
$input.attr('type', 'text');
$button.html('<i class="fas fa-eye-slash fa-sm"></i>');
}
}
/* Selects all text in share dialog */
DupPro.Pack.GetLinksText = function () {
$('#dpro-dlg-quick-path-data').select();
document.execCommand('copy');
};
});
</script>

View File

@@ -0,0 +1,88 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var DUP_PRO_Package $package
*/
$package = $tplData['package'];
/** @var string */
$innerPage = $tplData['currentInnerPage'];
$enable_transfer_tab = (
$package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Installer) !== false &&
$package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Archive) !== false
);
$packagesListUrl = PackagesPageController::getInstance()->getMenuLink();
$packgeDefailsUrl = PackagesPageController::getInstance()->getPackageDetailsUrl($package->ID);
$packgeTransferUrl = PackagesPageController::getInstance()->getPackageTransferUrl($package->ID);
?>
<h2 class="nav-tab-wrapper">
<a
href="<?php echo esc_url($packgeDefailsUrl); ?>"
class="nav-tab <?php echo ($innerPage == PackagesPageController::LIST_INNER_PAGE_DETAILS) ? 'nav-tab-active' : '' ?>"
>
<?php esc_html_e('Details', 'duplicator-pro'); ?>
</a>
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<a
href="<?php echo esc_url($packgeTransferUrl); ?>"
class="nav-tab <?php echo ($innerPage == PackagesPageController::LIST_INNER_PAGE_TRANSFER) ? 'nav-tab-active' : '' ?>"
<?php if ($enable_transfer_tab === false) { ?>
onclick="DupPro.Pack.TransferDisabled(); return false;"
<?php } ?>
>
<?php esc_html_e('Transfer', 'duplicator-pro'); ?>
</a>
<?php } ?>
</h2>
<div class="dup-details-packages-list">
<a href="<?php echo esc_url($packagesListUrl); ?>">[<?php esc_html_e('Packages', 'duplicator-pro'); ?>]</a>
</div>
<?php if ($package->Status == DUP_PRO_PackageStatus::ERROR) { ?>
<div id='dpro-error' class="error">
<p>
<b>
<?php
echo esc_html__('Error encountered building package, please review ', 'duplicator-pro') .
'<a target="_blank" href="' . esc_url($package->get_log_url()) . '">' . esc_html__('package log', 'duplicator-pro') . '</a>' .
esc_html__(' for details.', 'duplicator-pro');
?>
</b>
<br/>
<?php
echo esc_html__('For more help read the ', 'duplicator-pro') .
'<a target="_blank" href="' . esc_url(DUPLICATOR_PRO_TECH_FAQ_URL) . '">' . esc_html__('FAQ pages', 'duplicator-pro') . '</a>' .
esc_html__(' or submit a ', 'duplicator-pro') .
'<a target="_blank" href="' . esc_url(DUPLICATOR_PRO_BLOG_URL . 'my-account/support/') . '">' .
esc_html__('help ticket', 'duplicator-pro') . '</a>';
?>.
</p>
</div>
<?php
}
$alertTransferDisabled = new DUP_PRO_UI_Dialog();
$alertTransferDisabled->title = __('Transfer Error', 'duplicator-pro');
$alertTransferDisabled->message = __('No package in default location so transfer is disabled.', 'duplicator-pro');
$alertTransferDisabled->initAlert();
?>
<script>
DupPro.Pack.TransferDisabled = function() {
<?php $alertTransferDisabled->showAlert(); ?>
}
</script>

View File

@@ -0,0 +1,29 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<br/><br/>
<div id='dpro-error' class="error">
<p>
<?php echo sprintf(
esc_html__(
"Unable to find package id %d. The package does not exist or was deleted.",
'duplicator-pro'
),
esc_html($tplData['packageId'])
); ?>
<br/>
</p>
</div>

View File

@@ -0,0 +1,590 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\StoragePageController;
use Duplicator\Core\CapMng;
use Duplicator\Libs\Snap\SnapJson;
use Duplicator\Libs\Snap\SnapWP;
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Models\Storages\StoragesUtil;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $blur
*/
$blur = $tplData['blur'];
/** @var DUP_PRO_Package */
$package = $tplData['package'];
$storage_list = AbstractStorageEntity::getAll(0, 0, [StoragesUtil::class, 'sortByPriority']);
$newStorageEditUrl = StoragePageController::getEditUrl();
$transfer_occurring = (($package->Status >= DUP_PRO_PackageStatus::STORAGE_PROCESSING) && ($package->Status < DUP_PRO_PackageStatus::COMPLETE));
$view_state = DUP_PRO_UI_ViewState::getArray();
$ui_css_transfer_log = (isset($view_state['dup-transfer-transfer-log']) && $view_state['dup-transfer-transfer-log']) ? 'display:block' : 'display:none';
$installer_name = $package->Installer->getInstallerName();
$archive_name = (isset($package->Archive->File)) ? $package->Archive->File : __('Unable to locate file', 'duplicator-pro');
$tplMng->render('admin_pages/packages/details/details_header');
?>
<div class="transfer-panel <?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
<div class="transfer-hdr">
<h2 class="title">
<i class="fas fa-exchange-alt"></i> <?php esc_html_e('Manual Transfer', 'duplicator-pro'); ?>
<button id="dup-trans-ovr" type="button" class="dup-btn-borderless"
title="<?php esc_html_e('Show file details', 'duplicator-pro'); ?>"
onclick="DupPro.Pack.Transfer.toggleOverview()">
<i class="fas fa-chevron-left fa-fw fa-sm"></i> Details
</button>
</h2>
<hr/>
</div>
<!-- ===================
OVERVIEW -->
<div id="step1-ovr">
<h3><?php esc_html_e('File Overview', 'duplicator-pro'); ?></h3>
<small>
<?php esc_html_e('These files will be transferred to the selected storage locations. Links are sensitive. Keep them safe!', 'duplicator-pro'); ?>
</small>
<label>
<i class="far fa-file-archive fa-fw"></i>
<b><?php esc_html_e('Archive File', 'duplicator-pro'); ?></b>
<?php echo '&nbsp;(' . esc_html(DUP_PRO_U::byteSize($package->Archive->Size)) . ')'; ?><br/>
<input type="text" value="<?php echo esc_attr($archive_name) ?>" readonly="readonly" />
<span onclick="jQuery(this).parent().find('input').select();">
<span class="copy-button" data-dup-copy-value="<?php echo esc_attr($archive_name); ?>">
<i class='far fa-copy dup-cursor-pointer'></i> <?php esc_html_e('Copy Name', 'duplicator-pro'); ?>
</span>
</span>
</label>
<label>
<i class="fa fa-bolt fa-fw"></i>
<b><?php esc_html_e('Archive Installer', 'duplicator-pro'); ?></b>
<?php echo '&nbsp;(' . esc_html(DUP_PRO_U::byteSize($package->Installer->Size)) . ')'; ?><br/>
<input type="text" value="<?php echo esc_attr($installer_name) ?>" readonly="readonly" />
<span onclick="jQuery(this).parent().find('input').select();">
<span class="copy-button" data-dup-copy-value="<?php echo esc_attr($installer_name); ?>">
<i class='far fa-copy dup-cursor-pointer'></i> <?php esc_html_e('Copy Name', 'duplicator-pro'); ?>
</span>
</span>
</label>
</div>
<!-- ===================
STEP 1 -->
<div id="step2-section">
<div style="margin:0px 0 0px 0">
<h3><?php esc_html_e('Step 1: Choose Location', 'duplicator-pro') ?></h3>
<input style="display:none" type="radio" name="location" id="location-storage" checked="checked" onclick="DupPro.Pack.Transfer.ToggleLocation()" />
<label style="display:none" for="location-storage"><?php esc_html_e('Storage', 'duplicator-pro'); ?></label>
<input style="display:none" type="radio" name="location" id="location-quick" onclick="DupPro.Pack.Transfer.ToggleLocation()" />
<label style="display:none" for="location-quick"><?php esc_html_e('Quick FTP Connect', 'duplicator-pro'); ?></label>
</div>
<!-- STEP 1: STORAGE -->
<table id="location-storage-opts" class="widefat">
<thead>
<tr>
<th style='white-space: nowrap; width:10px;'></th>
<th style='width:175px'><?php esc_html_e('Type', 'duplicator-pro') ?></th>
<th style='width:275px'><?php esc_html_e('Name', 'duplicator-pro') ?></th>
<th style="white-space: nowrap"><?php esc_html_e('Location', 'duplicator-pro') ?></th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
$localStorageIds = array_map(function ($storage) {
return $storage->getId();
}, $package->getLocalStorages());
foreach ($storage_list as $storage) :
if ($storage->isDefault() || in_array($storage->getId(), $localStorageIds)) {
// Skip for default storage
continue;
}
$i++;
$is_valid = $storage->isValid();
$mincheck = ($i == 1) ? 'data-parsley-mincheck="1" data-parsley-required="true"' : '';
$row_style = ($i % 2) ? 'alternate' : '';
$row_style .= ($is_valid) ? '' : ' storage-missing';
$row_chkid = "dup-chkbox-{$storage->getId()}";
$storageEditUrl = StoragePageController::getEditUrl($storage);
?>
<tr class="package-row <?php echo esc_attr($row_style) ?>">
<td>
<input name="edit_id" type="hidden" value="<?php echo (int) $i ?>" />
<input class="duppro-storage-input"
<?php disabled($is_valid == false); ?>
id="<?php echo esc_attr($row_chkid); ?>"
name="_storage_ids[]"
data-parsley-errors-container="#storage_error_container" <?php echo esc_attr($mincheck); ?>
type="checkbox"
value="<?php echo (int) $storage->getId(); ?>"
<?php disabled($is_valid, false); ?>
>
</td>
<td>
<label for="<?php echo esc_attr($row_chkid); ?>" class="dup-store-lbl">
<?php
echo wp_kses(
$storage::getStypeIcon(),
[
'i' => [
'class' => [],
],
'img' => [
'src' => [],
'class' => [],
'alt' => [],
],
]
),
'&nbsp;',
esc_html($storage->getStypeName());
?>
</label>
</td>
<td>
<a href="<?php echo esc_url($storageEditUrl); ?>" target="_blank">
<?php
echo ($is_valid == false) ? '<i class="fa fa-exclamation-triangle fa-sm"></i>' : '';
echo "&nbsp;" . esc_html($storage->getName());
?>
</a>
</td>
<td>
<?php
echo wp_kses(
$storage->getHtmlLocationLink(),
[
'a' => [
'href' => [],
'target' => [],
],
]
);
?>
</td>
</tr>
<?php
endforeach; ?>
<?php if ($i == 0) : ?>
<tr class="package-row">
<td colspan="4" style="text-align: center">- <?php esc_html_e('No Storage Items Found', 'duplicator-pro') ?> -</td>
</tr>
<?php endif; ?>
</tbody>
<tr class="dup-choose-loc-new-pack">
<td colspan="4">
<?php if (CapMng::can(CapMng::CAP_STORAGE, false)) { ?>
<a href="<?php echo esc_url($newStorageEditUrl); ?>" target="_blank">
[<?php esc_html_e('Create New Storage', 'duplicator-pro') ?>]
</a>
<?php } else { ?>
&nbsp;
<?php } ?>
</td>
</tr>
</table>
</div>
<!-- ===================
STEP 2 -->
<div id="step3-section">
<h3>
<?php esc_html_e('Step 2: Transfer Files', 'duplicator-pro') ?>
<button style="<?php echo ($transfer_occurring ? 'none' : 'default'); ?>"
id="dup-pro-transfer-btn" type="button"
class="button button-large button-primary"
onclick="DupPro.Pack.Transfer.StartTransfer();">
<?php esc_attr_e('Start Transfer', 'duplicator-pro') ?> &nbsp; <i class="fas fa-upload"></i>
</button>
</h3>
<div style="width:700px; text-align: center; margin-left: auto; margin-right: auto" class="dpro-active-status-area">
<div style="display:none; font-size:20px; font-weight:bold" id="dpro-progress-bar-percent"></div>
<div style="font-size:14px" id="dpro-progress-bar-text"><?php esc_html_e('Processing', 'duplicator-pro') ?></div>
<div id="dpro-progress-bar-percent-help">
<small><?php esc_html_e('Full package percentage shown on packages screen', 'duplicator-pro'); ?></small>
</div>
</div>
<div class="dpro-progress-bar-container">
<div id="dpro-progress-bar-area" class="dpro-active-status-area">
<div class="dup-pro-meter-wrapper">
<div class="dup-pro-meter blue dup-pro-fullsize">
<span></span>
</div>
<span class="text"></span>
</div>
<button disabled id="dup-pro-stop-transfer-btn" type="button" class="button button-large button-primarybutton dpro-btn-stop" value=""
onclick="DupPro.Pack.Transfer.StopBuild();">
<i class="fa fa-times fa-sm"></i> &nbsp; <?php esc_html_e('Stop Transfer', 'duplicator-pro'); ?>
</button>
</div>
</div>
</div>
<!-- ===============================
TRANSFER LOG -->
<div class="dup-box">
<div class="dup-box-title">
<i class="fas fa-file-contract fa-fw fa-sm"></i>
<?php esc_html_e('Transfer Log', 'duplicator-pro') ?>
<button class="dup-box-arrow">
<span class="screen-reader-text">
<?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Transfer Log', 'duplicator-pro') ?>
</span>
</button>
</div>
<div class="dup-box-panel" id="dup-transfer-transfer-log" style="<?php echo esc_attr($ui_css_transfer_log) ?>">
<table class="widefat package-tbl">
<thead>
<tr>
<th style='width:150px'><?php esc_html_e('Started', 'duplicator-pro') ?></th>
<th style='width:150px'><?php esc_html_e('Stopped', 'duplicator-pro') ?></th>
<th style="white-space: nowrap"><?php esc_html_e('Status', 'duplicator-pro') ?></th>
<th style="white-space: nowrap"><?php esc_html_e('Type', 'duplicator-pro') ?></th>
<th style="width: 60%; white-space: nowrap"><?php esc_html_e('Description', 'duplicator-pro') ?></th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="5" id="dup-pack-details-trans-log-count"></td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<?php
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('Storage Warning!', 'duplicator-pro');
$alert1->message = __('At least one storage location must be checked.', 'duplicator-pro');
$alert1->initAlert();
$alert2 = new DUP_PRO_UI_Dialog();
$alert2->title = __('Transfer Failure!', 'duplicator-pro');
$alert2->message = __('Transfer failure when calling duplicator_pro_manual_transfer_storage.', 'duplicator-pro');
$alert2->initAlert();
$alert3 = new DUP_PRO_UI_Dialog();
$alert3->title = __('Build Error', 'duplicator-pro');
$alert3->message = __('Failed to stop build', 'duplicator-pro');
$alert3->initAlert();
$alert4 = new DUP_PRO_UI_Dialog();
$alert4->title = $alert3->title;
$alert4->message = __('Failed to stop build due to ajax error.', 'duplicator-pro');
$alert4->initAlert();
$alert5 = new DUP_PRO_UI_Dialog();
$alert5->title = 'INFO!';
$alert5->message = ''; // javascript inserted message
$alert5->initAlert();
$alert6 = new DUP_PRO_UI_Dialog();
$alert6->title = 'INFO!';
$alert6->message = ''; // javascript inserted message
$alert6->initAlert();
?>
<script>
DupPro.Pack.Transfer = {};
jQuery(document).ready(function ($) {
var transferRequestedTimestamp = 0;
var activePackageId = -1;
DupPro.Pack.Transfer.toggleOverview = function () {
$('div#step1-ovr').toggle();
var $i = $('#dup-trans-ovr i');
if ($($i).hasClass('fa-chevron-left')) {
$($i).removeClass('fa-chevron-left').addClass('fa-chevron-down');
} else {
$($i).removeClass('fa-chevron-down').addClass('fa-chevron-left');
}
}
DupPro.Pack.Transfer.GetTimeStamp = function () {
return Math.floor(Date.now() / 1000);
}
/* METHOD: Starts the data transfer */
DupPro.Pack.Transfer.StartTransfer = function () {
if (jQuery('#location-storage-opts input[type=checkbox]:checked').length == 0) {
<?php $alert1->showAlert(); ?>
} else {
$(".dpro-active-status-area").show(500);
var selected_storage_ids = $.map($(':checkbox[name=_storage_ids\\[\\]]:checked'), function (n, i) {
return n.value;
});
var data = {
action: 'duplicator_pro_manual_transfer_storage',
package_id: <?php echo (int) $package->ID; ?>,
storage_ids: selected_storage_ids,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_manual_transfer_storage')); ?>'
}
console.log("sending to selected storages " + selected_storage_ids);
transferRequestedTimestamp = DupPro.Pack.Transfer.GetTimeStamp();
$("#dpro-progress-bar-text").text("<?php echo esc_html__('Initiating transfer. Please wait.', 'duplicator-pro') ?>");
$("#dpro-progress-bar-percent").text('');
DupPro.Pack.Transfer.SetUIState(true);
$.ajax({
type: "POST",
url: ajaxurl,
cache: false,
timeout: 10000000,
data: data,
success: function (respData) {
try {
var parsedData = DupPro.parseJSON(respData);
} catch (err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
<?php $alert2->showAlert(); ?>
transferRequestedTimestamp = 0;
DupPro.Pack.Transfer.SetUIState(false);
console.log(respData);
return false;
}
if (!parsedData.success)
{
if (parsedData.message != '') {
<?php $alert5->showAlert(); ?>
$("#<?php echo esc_js($alert5->getID()); ?>_message").html(parsedData.message);
}
transferRequestedTimestamp = 0;
DupPro.Pack.Transfer.SetUIState(false);
DupPro.Pack.Transfer.GetPackageState();
}
},
error: function (respData) {
<?php $alert2->showAlert(); ?>
transferRequestedTimestamp = 0;
DupPro.Pack.Transfer.SetUIState(false);
console.log(respData);
}
});
}
};
/* METHOD: Starts the data transfer */
DupPro.Pack.Transfer.StopBuild = function () {
var data = {
action: 'duplicator_pro_package_stop_build',
package_id: activePackageId,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_package_stop_build')); ?>'
}
$("#dup-pro-stop-transfer-btn").prop("disabled", true);
$.ajax({
type: "POST",
url: ajaxurl,
timeout: 10000000,
data: data,
success: function (respData) {
try {
var parsedData = DupPro.parseJSON(respData);
} catch(err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
<?php $alert4->showAlert(); ?>
$("#dup-pro-stop-transfer-btn").prop("disabled", false);
return false;
}
if (!parsedData.success) {
<?php $alert3->showAlert(); ?>
$("#dup-pro-stop-transfer-btn").prop("disabled", false);
}
console.log(parsedData.message);
},
error: function (respData) {
<?php $alert4->showAlert(); ?>
$("#dup-pro-stop-transfer-btn").prop("disabled", false);
}
});
};
/* METHOD: Progress bar display state*/
DupPro.Pack.Transfer.SetUIState = function (activeProcessing) {
if (activeProcessing)
{
$(".dpro-active-status-area").show(500);
$("#dup-pro-transfer-btn").hide();
$("#location-storage input").prop("disabled", true);
$("#location-storage-opts input").prop("disabled", true);
} else {
$("#dup-pro-stop-transfer-btn").prop("disabled", true);
// Only allow to revert after enough time has past since the last transfer request
currentTimestamp = DupPro.Pack.Transfer.GetTimeStamp();
if ((currentTimestamp - transferRequestedTimestamp) > 10)
{
$("#location-storage input").prop("disabled", false);
$("#location-storage-opts input").prop("disabled", false);
$("#dup-pro-transfer-btn").show();
$(".dpro-active-status-area").hide();
}
}
}
/* METHOD: Retreive package state */
DupPro.Pack.Transfer.GetPackageState = function () {
var package_id = <?php echo (int) $package->ID; ?>;
var data = {
action: 'duplicator_pro_packages_details_transfer_get_package_vm',
package_id: package_id,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_packages_details_transfer_get_package_vm')); ?>'
};
$.ajax({
type: "POST",
url: ajaxurl,
timeout: 10000000,
data: data,
success: function (respData) {
try {
var parsedData = DupPro.parseJSON(respData);
} catch (err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
console.log("Transfer failure.");
DupPro.Pack.Transfer.SetUIState(false);
console.log(respData);
return false;
}
console.log(parsedData);
if (parsedData.success)
{
var vm = parsedData.vm;
// vm - view model for this screen
// vm.active_package_id: Active package id (-1 for none)
// vm.percent_text: Percent through the current transfer
// vm.text: Text to display
// vm.transfer_logs: array of transfer request vms (start, stop, status, message)
if (activePackageId != vm.active_package_id)
{
// Once we have an active package ID allow the stop button to be clicked
$("#dup-pro-stop-transfer-btn").prop("disabled", false);
}
activePackageId = vm.active_package_id;
if (vm.active_package_id == -1)
{
// No packages are running
DupPro.Pack.Transfer.SetUIState(false);
} else if (vm.active_package_id == package_id) {
// This package is running
if (vm.percent_text != '')
{
$("#dpro-progress-bar-percent").text(vm.percent_text);
} else
{
$("#dpro-progress-bar-percent").text('');
}
$("#dpro-progress-bar-text").html(vm.text);
DupPro.Pack.Transfer.SetUIState(true);
} else {
// A package other than this one is running
$("#dpro-progress-bar-text").html(vm.text);
DupPro.Pack.Transfer.SetUIState(true);
}
DupPro.Pack.Transfer.UpdateTransferLog(vm);
} else {
if (parsedData.message != '') {
<?php $alert6->showAlert(); ?>
$("#<?php echo esc_js($alert6->getID()); ?>_message").html(parsedData.message);
}
DupPro.Pack.Transfer.SetUIState(false);
console.log(data);
}
},
error: function (data) {
console.log("Transfer failure.");
DupPro.Pack.Transfer.SetUIState(false);
console.log(data);
}
});
};
/* METHOD: Updates the transfer log with the information from the view model */
DupPro.Pack.Transfer.UpdateTransferLog = function (vm) {
$("#dup-transfer-transfer-log table tbody").empty();
var row_style, row_html;
for (var i = 0; i < vm.transfer_logs.length; i++) {
var transfer_log = vm.transfer_logs[i];
console.log(transfer_log);
row_style = (i % 2) ? ' alternate' : '';
switch(transfer_log.status_text) {
case 'Pending': row_style += ' status-pending'; break;
case 'Running': row_style += ' status-running'; break;
case 'Failed': row_style += ' status-failed'; break;
default: row_style += ' status-normal'; break;
}
row_html =
`<tr class="package-row ${row_style}">
<td>${transfer_log.started}</td>
<td>${transfer_log.stopped}</td>
<td>${transfer_log.status_text}</td>
<td>${transfer_log.storage_type_text}</td>
<td>${transfer_log.message}</td>
</tr>`;
$("#dup-transfer-transfer-log table tbody").append(row_html);
$('#dup-pack-details-trans-log-count').html('<?php esc_html_e('Log Items:', 'duplicator-pro') ?> ' + (i + 1) );
}
if (i == 0)
{
var row_html = '<tr><td colspan="5" style="text-align:center">' +
'<?php esc_html_e('- No transactions found for this package -', 'duplicator-pro'); ?></td></tr>';
$("#dup-transfer-transfer-log table tbody").append(row_html);
}
};
//INIT
DupPro.Pack.Transfer.GetPackageState();
setInterval(DupPro.Pack.Transfer.GetPackageState, 8000);
});
</script>

View File

@@ -0,0 +1,41 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<tr class="dpro-nopackages">
<td colspan="11" class="dup-list-nopackages">
<br />
<i class="fa fa-archive fa-sm"></i>
<?php esc_html_e("No Packages Found", 'duplicator-pro'); ?><br />
<i><?php esc_html_e("Click 'Create New' to Archive Site", 'duplicator-pro'); ?></i>
<div class="dup-quick-start">
<b><?php esc_html_e("New to Duplicator?", 'duplicator-pro'); ?></b><br />
<span class="dup-open-details link-style" onclick="DupPro.Pack.openLinkDetails()">
<?php esc_html_e("Learn Duplicator in a few minutes!", 'duplicator-pro'); ?>
</span><br/>
<a
class="dup-quick-start-link"
href="<?php echo esc_url(DUPLICATOR_PRO_BLOG_URL . 'knowledge-base-article-categories/quick-start/'); ?>"
target="_blank">
<?php esc_html_e("Visit the 'Quick Start' guide!", 'duplicator-pro'); ?>
</a>
</div>
<div style="height:75px">&nbsp;</div>
</td>
</tr>

View File

@@ -0,0 +1,35 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
global $packagesViewData;
// If its in the pending cancels consider it stopped
if (in_array($package->ID, $packagesViewData['pending_cancelled_package_ids'])) {
$status = DUP_PRO_PackageStatus::PENDING_CANCEL;
} else {
$status = $package->Status;
}
if ($package->Status >= DUP_PRO_PackageStatus::COMPLETE) {
$tplMng->render('admin_pages/packages/package_row_complete', ['status' => $status]);
} else {
$tplMng->render('admin_pages/packages/package_row_incomplete', ['status' => $status]);
}
$tplMng->render('admin_pages/packages/package_row_building', ['status' => $status]);
$packagesViewData['rowCount']++;

View File

@@ -0,0 +1,83 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
/** @var int */
$status = $tplData['status'];
if ($status <= DUP_PRO_PackageStatus::PRE_PROCESS || $status >= DUP_PRO_PackageStatus::COMPLETE) {
return;
}
?>
<tr class="dup-row-progress">
<td colspan="11">
<div class="wp-filter dup-build-msg">
<?php if ($status < DUP_PRO_PackageStatus::STORAGE_PROCESSING) : ?>
<!-- BUILDING PROGRESS-->
<div id='dpro-progress-status-message-build'>
<div class='status-hdr'>
<?php esc_html_e('Building Package', 'duplicator-pro'); ?>&nbsp;
<i class="fa fa-cog fa-sm fa-spin"></i>&nbsp;
<span id="status-<?php echo (int) $package->ID; ?>"><?php echo (int) $status; ?></span>%
</div>
<small>
<?php esc_html_e('Please allow it to finish before creating another one.', 'duplicator-pro'); ?>
</small>
</div>
<?php else : ?>
<!-- TRANSFER PROGRESS -->
<div id='dpro-progress-status-message-transfer'>
<div class='status-hdr'>
<?php esc_html_e('Transferring Package', 'duplicator-pro'); ?>&nbsp;
<i class="fa fa-sync fa-sm fa-spin"></i>&nbsp;
<span id="status-progress-<?php echo (int) $package->ID; ?>">0</span>%
<span id="status-<?php echo (int) $package->ID; ?>" class="no-display" >
<?php echo (int) $status; ?>
</span>
</div>
<small id="dpro-progress-status-message-transfer-msg">
<?php esc_html_e('Getting Transfer State...', 'duplicator-pro'); ?>
</small>
</div>
<?php endif; ?>
<div id="dup-progress-bar-area">
<div class="dup-pro-meter-wrapper">
<div class="dup-pro-meter blue dup-pro-fullsize">
<span></span>
</div>
<span class="text"></span>
</div>
</div>
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<button onclick="DupPro.Pack.StopBuild(<?php echo (int) $package->ID; ?>); return false;" class="button button-large dup-build-stop-btn">
<i class="fa fa-times fa-sm"></i>&nbsp;
<?php
if ($status >= 75) {
esc_html_e('Stop Transfer', 'duplicator-pro');
} elseif ($status > 0) {
esc_html_e('Stop Build', 'duplicator-pro');
} else {
esc_html_e('Cancel Pending', 'duplicator-pro');
}
?>
</button>
<?php } ?>
</div>
</td>
</tr>

View File

@@ -0,0 +1,135 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\UserUIOptions;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
/** @var int */
$status = $tplData['status'];
if ($status < DUP_PRO_PackageStatus::COMPLETE) {
return;
}
$global = DUP_PRO_Global_Entity::getInstance();
global $packagesViewData;
$isRecoveable = RecoveryPackage::isPackageIdRecoveable($package->ID);
$isRecoverPoint = (RecoveryPackage::getRecoverPackageId() === $package->ID);
$pack_name = $package->Name;
$pack_archive_size = $package->Archive->Size;
$pack_dbonly = $package->isDBOnly();
$brand = $package->Brand;
//Links
$uniqueid = $package->NameHash;
$archive_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Archive) != false);
$installer_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Installer) != false);
$progress_error = '';
//ROW CSS
$rowClasses = array('');
$rowClasses[] = 'dup-row';
$rowClasses[] = 'dup-row-complete';
$rowClasses[] = ($packagesViewData['rowCount'] % 2 == 0) ? 'dup-row-alt-dark' : 'dup-row-alt-light';
$rowClasses[] = ($isRecoverPoint) ? 'dup-recovery-package' : '';
$rowCSS = trim(implode(' ', $rowClasses));
//ArchiveInfo
$archive_name = $package->Archive->File;
$archiveDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Archive);
$installerDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Installer);
$installerFullName = $package->Installer->getInstallerName();
//Lang Values
$txt_DatabaseOnly = __('Database Only', 'duplicator-pro');
switch ($package->Type) {
case DUP_PRO_PackageType::MANUAL:
$package_type_string = __('Manual', 'duplicator-pro');
break;
case DUP_PRO_PackageType::SCHEDULED:
$package_type_string = __('Schedule', 'duplicator-pro');
break;
case DUP_PRO_PackageType::RUN_NOW:
$lang_schedule = __('Schedule', 'duplicator-pro');
$lang_title = __('This package was started manually from the schedules page.', 'duplicator-pro');
$package_type_string = "{$lang_schedule}<span><sup>&nbsp;<i class='fas fa-cog fa-sm pointer' title='{$lang_title}'></i>&nbsp;</sup><span>";
break;
default:
$package_type_string = __('Unknown', 'duplicator-pro');
break;
}
$packageDetailsURL = PackagesPageController::getInstance()->getPackageDetailsURL($package->ID);
$createdFormat = UserUIOptions::getInstance()->get(UserUIOptions::VAL_CREATED_DATE_FORMAT);
?>
<tr
id="dup-row-pack-id-<?php echo (int) $package->ID; ?>"
data-package-id="<?php echo (int) $package->ID; ?>"
class="<?php echo esc_attr($rowCSS); ?>" >
<td class="dup-check-column dup-cell-chk">
<label for="<?php echo (int) $package->ID; ?>">
<input
name="delete_confirm"
type="checkbox"
id="<?php echo (int) $package->ID; ?>"
data-archive-name="<?php echo esc_attr($archive_name); ?>"
data-installer-name="<?php echo esc_attr($installerFullName); ?>" />
</label>
</td>
<td class="dup-name-column dup-cell-name">
<?php echo esc_html($pack_name); ?>
</td>
<td class="dup-note-column">
<?php echo esc_html($package->notes); ?>
</td>
<td class="dup-storages-column">
</td>
<td class="dup-flags-column">
<?php $tplMng->render('admin_pages/packages/row_parts/falgs_cell'); ?>
</td>
<td class="dup-created-column" >
<?php echo esc_html(DUP_PRO_Package::format_and_get_local_date_time($package->getCreated(), $createdFormat)); ?>
</td>
<td class="dup-age-column">
<?php echo esc_html($package->getPackageLife('human')); ?>
</td>
<td class="dup-size-column" >
<?php echo esc_html(DUP_PRO_U::byteSize($pack_archive_size)); ?>
</td>
<td class="dup-cell-btns dup-download-column">
<?php $tplMng->render('admin_pages/packages/row_parts/download_buttons'); ?>
</td>
<td class="dup-cell-btns dup-restore-column" >
<?php $tplMng->render('admin_pages/packages/row_parts/restore_backup_button'); ?>
</td>
<td class="dup-cell-btns dup-cell-toggle-btn dup-toggle-details dup-details-column">
<span class="button button-link">
<i class="fas fa-chevron-left"></i>
</span>
</td>
</tr>
<tr id="dup-row-pack-id-<?php echo (int) $package->ID; ?>-details" class="dup-row-details">
<?php $tplMng->render('admin_pages/packages/row_parts/details_package'); ?>
</tr>

View File

@@ -0,0 +1,159 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\UserUIOptions;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
$global = DUP_PRO_Global_Entity::getInstance();
/** @var int */
$status = $tplData['status'];
if ($status >= DUP_PRO_PackageStatus::COMPLETE) {
return;
}
global $packagesViewData;
$isRecoveable = RecoveryPackage::isPackageIdRecoveable($package->ID);
$isRecoverPoint = (RecoveryPackage::getRecoverPackageId() === $package->ID);
$pack_name = $package->Name;
$pack_archive_size = $package->Archive->Size;
$pack_namehash = $package->NameHash;
$pack_dbonly = $package->isDBOnly();
$brand = $package->Brand;
//Links
$uniqueid = $package->NameHash;
$archive_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Archive) != false);
$installer_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Installer) != false);
$progress_error = '';
//ROW CSS
$rowClasses = array('');
$rowClasses[] = 'dup-row';
$rowClasses[] = 'dup-row-incomplete';
$rowClasses[] = ($packagesViewData['rowCount'] % 2 == 0) ? 'dup-row-alt-dark' : 'dup-row-alt-light';
$rowClasses[] = ($isRecoverPoint) ? 'dup-recovery-package' : '';
$rowCSS = trim(implode(' ', $rowClasses));
//ArchiveInfo
$archive_name = $package->Archive->File;
$archiveDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Archive);
$installerDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Installer);
$installerFullName = $package->Installer->getInstallerName();
$createdFormat = UserUIOptions::getInstance()->get(UserUIOptions::VAL_CREATED_DATE_FORMAT);
//Lang Values
$txt_DatabaseOnly = __('Database Only', 'duplicator-pro');
$cellErrCSS = '';
if ($status < DUP_PRO_PackageStatus::COPIEDPACKAGE) {
// In the process of building
$size = 0;
$tmpSearch = glob(DUPLICATOR_PRO_SSDIR_PATH_TMP . "/{$pack_namehash}_*");
if (is_array($tmpSearch)) {
$result = @array_map('filesize', $tmpSearch);
$size = array_sum($result);
}
$pack_archive_size = $size;
}
$packageDetailsURL = PackagesPageController::getInstance()->getPackageDetailsURL($package->ID);
$progress_html = "<span style='display:none' id='status-{$package->ID}'>{$status}</span>";
$stop_button_text = __('Stop', 'duplicator-pro');
if ($status >= 0) {
if ($status >= 75) {
$stop_button_text = __('Stop Transfer', 'duplicator-pro');
$progress_html = "<i class='fa fa-sync fa-sm fa-spin'></i>&nbsp;<span id='status-progress-{$package->ID}'>0</span>%"
. "<span style='display:none' id='status-{$package->ID}'>{$status}</span>";
} elseif ($status > 0) {
$stop_button_text = __('Stop Build', 'duplicator-pro');
$progress_html = "<i class='fa fa-cog fa-sm fa-spin'></i>&nbsp;<span id='status-{$package->ID}'>{$status}</span>%";
} else {
// In a pending state
$stop_button_text = __('Cancel Pending', 'duplicator-pro');
$progress_html = "<span style='display:none' id='status-{$package->ID}'>{$status}</span>";
}
} else {
//FAILURES AND CANCELLATIONS
switch ($status) {
case DUP_PRO_PackageStatus::ERROR:
$cellErrCSS = 'dup-cell-err';
break;
case DUP_PRO_PackageStatus::BUILD_CANCELLED:
case DUP_PRO_PackageStatus::STORAGE_CANCELLED:
$cellErrCSS = 'dup-cell-cancelled';
break;
}
}
?>
<tr id="dup-row-pack-id-<?php echo (int) $package->ID; ?>" data-package-id="<?php echo (int) $package->ID; ?>" class="<?php echo esc_attr($rowCSS); ?>" >
<td class="dup-check-column dup-cell-chk">
<label for="<?php echo (int) $package->ID; ?>">
<input name="delete_confirm"
type="checkbox" id="<?php echo (int) $package->ID;?>"
<?php echo ($status >= DUP_PRO_PackageStatus::PRE_PROCESS) ? 'disabled="disabled"' : ''; ?> />
</label>
</td>
<td class="dup-name-column dup-cell-name">
<?php echo esc_html($pack_name); ?>
</td>
<td class="dup-note-column">
</td>
<td class="dup-storages-column">
</td>
<td class="dup-flags-column">
<?php $tplMng->render('admin_pages/packages/row_parts/falgs_cell'); ?>
</td>
<td class="dup-created-column" >
<?php echo esc_html(DUP_PRO_Package::format_and_get_local_date_time($package->getCreated(), $createdFormat)); ?>
</td>
<td class="dup-age-column">
<?php echo esc_html($package->getPackageLife('human')); ?>
</td>
<td class="dup-size-column" >
<?php if ($status >= DUP_PRO_PackageStatus::PRE_PROCESS) {
$package->get_display_size();
} else {
esc_html_e('N/A', 'duplicator-pro');
}?>
</td>
<td class="dup-cell-incomplete <?php echo esc_attr($cellErrCSS); ?> no-select" colspan="3">
<?php if ($status >= DUP_PRO_PackageStatus::PRE_PROCESS) { ?>
<i><?php esc_html_e('Building Package Files...', 'duplicator-pro'); ?></i>
<?php } else {
$tplMng->render(
'admin_pages/packages/row_parts/package_progress_error',
[
'package' => $package,
'status' => $status,
]
);
}?>
</td>
</tr>

View File

@@ -0,0 +1,702 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
/**
* Variables
*
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
defined("ABSPATH") or die("");
$lang_wppathinfo = __('This site\'s root path is:', 'duplicator-pro') . '<br/><i>' . duplicator_pro_get_home_path() . '</i>';
?>
<div class="dup-dlg-links-subtxt">
<?php esc_html_e("Learn how Duplicator works in just a few minutes...", 'duplicator-pro'); ?>
</div>
<div id="dup-ovr-hlp-tabs" class="dup-tabs-flat">
<div class="data-tabs">
<a href="javascript:void(0)" class="tab active"><i class="fas fa-archive fa-fw"></i> <?php esc_html_e('Create Backups', 'duplicator-pro'); ?></a>
<a href="javascript:void(0)" class="tab"><i class="fas fa-bolt fa-fw"></i> <?php esc_html_e('Install Backups', 'duplicator-pro'); ?></a>
</div>
<!-- =================
TAB1: OVERVIEW HELP -->
<div class="data-panels">
<div class="panel">
<div id="dup-link-spinner-1" class="dup-spinner">
<div class="area-left">
<i class="fas fa-chevron-circle-left area-arrow"></i>
</div>
<!-- DATA -->
<div class="area-data">
<!-- =====================
SPIN-1: INTRO -->
<div class="item active dup-spin-hlp">
<h3>
<i class="fab fa-wordpress-simple" style="font-weight: normal"></i>
<?php esc_html_e('Create Backups', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('Backups are the heart of Duplicator, and driven by these points!', 'duplicator-pro'); ?>
</div>
<ol>
<li>
<?php echo sprintf(
esc_html_x('In Duplicator Backups refer to %1$s Packages', 'Archive icon', 'duplicator-pro'),
'<i class="fas fa-archive fa-fw fa-sm"></i>'
); ?>.
</li>
<li><?php esc_html_e('Packages can be manually created or scheduled', 'duplicator-pro'); ?>.</li>
<li>
<?php
printf(
esc_html_x(
'Packages contain two files: %1$sThe Archive &amp; Installer%2$s',
'%1$s and %2$s are opening and closing italic tags (<i> and </i>)',
'duplicator-pro'
),
'<i>',
'</i>'
);
?>.
</li>
</ol>
</div>
<!-- =====================
SPIN-2: PACKAGE OVERVIEW -->
<div class="item dup-spin-hlp">
<h3>
<i class="fas fa-archive fa-fw"></i>
<?php esc_html_e('Package Overview', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('A package is a customizable backup of your site with these two files:', 'duplicator-pro'); ?>
</div>
<div class="title">
<i class="far fa-file-archive fa-fw"></i> <?php esc_html_e('Archive File', 'duplicator-pro'); ?>
<?php
$tipContent = __(
'Archive files can be created in either .zip or .daf file formats.',
'duplicator-pro'
) . ' ' .
__('The Duplicator archive format (daf) is a custom format designed for large sites on budget hosts', 'duplicator-pro');
?>
<i class="fas fa-question-circle"
data-tooltip-title="<?php esc_html_e("Archive File", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>">
</i>
</div>
<?php
printf(
esc_html_x(
' The %1$sarchive.zip/daf%2$s file contains your WordPress files and database',
'%1$s and %2$s are opening and closing italic tags (<i> and </i>)',
'duplicator-pro'
),
'<i>',
'</i>'
);
?>.
<br/><br/>
<div class="title">
<i class="fas fa-bolt fa-fw"></i> <?php esc_html_e('Installer File', 'duplicator-pro'); ?>
<?php
$tipContent = __(
'In case you lose this file an exact copy of this file is also stored inside the archive named installer-backup.php',
'duplicator-pro'
); ?>
<i class="fas fa-question-circle"
data-tooltip-title="<?php esc_html_e("Archive Installer", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>"></i>
</div>
<?php
printf(
esc_html_x(
'The %1$sinstaller.php%2$s file helps to deploy the contents of the archive file',
'%1$s and %2$s are opening and closing italic tags (<i> and </i>)',
'duplicator-pro'
),
'<i>',
'</i>'
);
?>.
</div>
<!-- =====================
SPIN-3: ARCHIVE FILE -->
<div class="item dup-spin-hlp">
<h3><i class="far fa-file-archive fa-fw"></i> <?php esc_html_e('Package: Archive File', 'duplicator-pro'); ?></h3>
<div class="sub-head">
<?php esc_html_e('An archive.zip/daf file contains your WordPress site with the following assets:', 'duplicator-pro'); ?>
</div>
<div class="title">
<i class="fas fa-folder-open fa-fw"></i> <?php esc_html_e('Site Files', 'duplicator-pro'); ?>
<i class="fas fa-question-circle"
data-tooltip-title="<?php esc_html_e("WordPress Site Info", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($lang_wppathinfo) ?>"></i>
</div>
<?php esc_html_e(
'All site files including the WordPress core files, plugins, themes and files starting at the WordPress root folder.',
'duplicator-pro'
); ?>
<br/><br/>
<div class="title">
<i class="fas fa-database fa-fw"></i> <?php esc_html_e('Database', 'duplicator-pro'); ?>
</div>
<?php esc_html_e('The database is stored in a single SQL file named database.sql.', 'duplicator-pro'); ?>
<br/><br/>
<small class="grey">
<?php esc_html_e('By default all files/database tables are included unless filters are set.', 'duplicator-pro'); ?>
</small>
</div>
<!-- =====================
SPIN-4: INSTALLER FILE -->
<div class="item dup-spin-hlp">
<h3><i class="fas fa-bolt fa-fw"></i> <?php esc_html_e('Package: Installer File', 'duplicator-pro'); ?></h3>
<div class="sub-head">
<?php esc_html_e('The installer.php is a PHP script that does the following:', 'duplicator-pro'); ?>
</div>
<div class="title">
<i class="fas fa-file-export fa-fw"></i> <?php esc_html_e('Extracts Archive', 'duplicator-pro'); ?>
</div>
<?php esc_html_e('Helps to restores your WordPress files at a location of your choice.', 'duplicator-pro'); ?>
<br/><br/>
<div class="title">
<i class="fas fa-database fa-fw"></i> <?php esc_html_e('Installs Database ', 'duplicator-pro'); ?>
</div>
<?php esc_html_e('Restores database and properly updates all URL/paths.', 'duplicator-pro'); ?>
<br/><br/>
<small class="grey">
<?php esc_html_e('The installer file is only used for classic &amp; overwrite standard install modes', 'duplicator-pro'); ?>.
</small>
</div>
<!-- =====================
SPIN-5: INSTALLER SECURE -->
<div class="item dup-spin-hlp">
<h3><i class="fas fa-bolt fa-fw"></i> <?php esc_html_e('Secure Installer', 'duplicator-pro'); ?></h3>
<div class="sub-head">
<?php esc_html_e('A secure installer keeps the location of your install process hidden.', 'duplicator-pro'); ?>
</div>
<ol>
<li>
<b><i class="fas fa-lock-open fa-fw"></i> <?php esc_html_e('Unsecured', 'duplicator-pro'); ?></b><br/>
<?php
esc_html_e(
'An unsecured installer is named "installer.php". This mode should only be used when outside users cannot access your server.',
'duplicator-pro'
); ?>
</li>
<li>
<b><i class="fas fa-lock fa-fw"></i> <?php esc_html_e('Secured', 'duplicator-pro'); ?></b><br/>
<?php
echo esc_html__(
'A secure installer is named "[name]_[hash]_[date]_installer.php" and is only known by you.',
'duplicator-pro'
) . ' ' .
esc_html__('This keeps it safe from outside threats.', 'duplicator-pro');
?>
</li>
</ol>
<br/><br/>
<div class="dup-ovr-continue">
<a href="javascript:void(0)" id="dup-ovr-next-exe">
<?php esc_html_e('Install Backups', 'duplicator-pro'); ?>
<i class="fas fa-chevron-circle-right"></i>
</a>
</div>
</div>
</div>
<div class="area-right">
<i class="fas fa-chevron-circle-right"></i>
</div>
<!-- Progress -->
<div class="area-nav">
<span class="num"></span>
<progress class="progress"></progress>
</div>
</div>
</div>
<!-- ******************************************************
TAB-2: INSTALLER RESOURCES -->
<div class="panel" data-panel="2">
<div id="dup-link-spinner-2" class="dup-spinner">
<div class="area-left">
<i class="fas fa-chevron-circle-left area-arrow"></i>
</div>
<!-- Data -->
<div class="area-data">
<!-- =====================
SPIN-1: INTRO -->
<div class="item dup-spin-hlp active">
<h3>
<i class="fab fa-wordpress-simple" style="font-weight: normal"></i>
<?php esc_html_e('Install Backups', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('With Duplicator there are several ways to restore/install a backup', 'duplicator-pro'); ?>
</div>
<ol>
<li>
<?php
printf(
esc_html_x(
'Install modes consist of two groups %1$sStandard &amp; Custom%2$s',
'%1$s and %2$s are opening and closing italic tags (<i> and </i>)',
'duplicator-pro'
),
'<i>',
'</i>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sStandard Modes include: %2$s %3$sImport, Overwrite &amp; Classic%4$s',
'%1$s and %2$s are bold tags and %3$s and %4$s are italic tags',
'duplicator-pro'
),
'<b>',
'</b>',
'<i>',
'</i>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sCustom Modes include: %2$s %3$sRecovery, Database, Two-Part%4$s',
'%1$s and %2$s are bold tags and %3$s and %4$s are italic tags',
'duplicator-pro'
),
'<b>',
'</b>',
'<i>',
'</i>'
);
?>
</li>
</ol>
</div>
<!-- =====================
SPIN-2: STANDARD INSTALL MODES -->
<div class="item dup-spin-hlp">
<h3>
<i class="fas fa-bolt fa-fw"></i>
<?php esc_html_e('Standard Install Modes', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('Standard install modes are the most popular and support these 3 modes.', 'duplicator-pro'); ?>
</div>
<div class="title">
<i class="fas fa-arrow-alt-circle-down fa-fw"></i>&nbsp;
<a href="<?php echo esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'import-install') ?>" target="_blank">
<b><?php esc_html_e('Import Install', 'duplicator-pro'); ?></b>
</a>
</div>
<?php esc_html_e('Drag-n-drop or link an archive file to any destination WordPress site', 'duplicator-pro'); ?>.
<br/><br/>
<div class="title">
<i class="far fa-window-close fa-fw"></i>&nbsp;
<a href="<?php echo esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'overwrite-install') ?>" target="_blank">
<b><?php esc_html_e('Overwrite Install', 'duplicator-pro'); ?></b>
</a>
</div>
<?php esc_html_e('Quickly overwrite an existing WordPress site in a few clicks', 'duplicator-pro'); ?>.
<br/><br/>
<div class="title">
<i class="far fa-save fa-fw"></i>&nbsp;
<a href="<?php echo esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'classic-install') ?>" target="_blank">
<b><?php esc_html_e('Classic Install', 'duplicator-pro'); ?></b>
</a>
</div>
<?php esc_html_e('Install to an empty server directory like a new WordPress install does', 'duplicator-pro'); ?>.<br/>
</div>
<!-- =====================
SPIN-3: STANDARD: IMPORT INSTALL -->
<div class="item dup-spin-hlp">
<h3>
<i class="fas fa-arrow-alt-circle-down"></i>
<?php esc_html_e('Standard: Import Install', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('Quick steps to import archive into an existing WordPress site and overwrite it.', 'duplicator-pro'); ?>
</div>
<div id="dup-ovr-hlp-vert-tabs-1" class="dup-tabs-vert">
<div class="data-tabs">
<div class="void"><i class="fab fa-wordpress-simple"></i> <?php esc_html_e('Source Site', 'duplicator-pro'); ?></div>
<div class="tab active">1. <?php esc_html_e('Create Package', 'duplicator-pro'); ?></div>
<div class="tab">2. <?php esc_html_e('Choose Import', 'duplicator-pro'); ?></div>
<div class="void"><i class="fab fa-wordpress-simple"></i> <?php esc_html_e('Destination Site', 'duplicator-pro'); ?></div>
<div class="tab">3. <?php esc_html_e('Check WordPress', 'duplicator-pro'); ?></div>
<div class="tab">4. <?php esc_html_e('Import Archive', 'duplicator-pro'); ?></div>
</div>
<div class="data-panels dup-tabvert-hlp">
<div class="panel">
<div class="title">
<i class="fas fa-archive fa-fw"></i> <?php esc_html_e('Create a Package', 'duplicator-pro'); ?><br/>
<small><?php esc_html_e('Pro Packages Create New', 'duplicator-pro'); ?></small>
</div>
<?php esc_html_e('On any WordPress site with Duplicator create a package', 'duplicator-pro'); ?>.
</div>
<div class="panel">
<div class="title">
<i class="fas fa-link fa-fw"></i> <?php esc_html_e('Choose An Import Method', 'duplicator-pro'); ?> <br/>
<small><?php esc_html_e('Pro Packages Package Overview', 'duplicator-pro'); ?></small>
</div>
<b><?php esc_html_e('URL Import', 'duplicator-pro'); ?></b> <br/>
<?php
esc_html_e('Use', 'duplicator-pro');
echo ' <i><i class="far fa-copy fa-xs"></i> ' . esc_html__('Copy Link', 'duplicator-pro') . '</i>&nbsp;';
esc_html_e('to run import link install', 'duplicator-pro');
?>.
<br/><br/>
<b><?php esc_html_e('File Import', 'duplicator-pro'); ?></b> <br/>
<?php
esc_html_e('Use', 'duplicator-pro');
echo ' <i><i class="fas fa-download fa-xs"></i> ' . esc_html__('Download', 'duplicator-pro') . '</i>&nbsp;';
esc_html_e('to run import file install', 'duplicator-pro');
?>.
</div>
<div class="panel">
<div class="title">
<?php esc_html_e('Install WordPress', 'duplicator-pro'); ?>
</div>
<?php esc_html_e('Install WordPress if not already installed', 'duplicator-pro'); ?>.<br/>
<small>
<?php esc_html_e(
'Most Hosting platforms have a one click WordPress install, this will be the quickest method to get WordPress on your host or have you host do it for you', // phpcs:ignore Generic.Files.LineLength
'duplicator-pro'
); ?>&nbsp;.
</small>
</div>
<div class="panel">
<div class="title">
<?php esc_html_e('Import Archive ', 'duplicator-pro'); ?><br/>
<small><?php esc_html_e('Pro Import ', 'duplicator-pro'); ?></small>
</div>
<b><?php esc_html_e('URL Import', 'duplicator-pro'); ?></b> <br/>
<i><i class="far fa-copy fa-xs"></i> <?php esc_html_e('Paste Link', 'duplicator-pro'); ?></i>
<?php esc_html_e('from source site', 'duplicator-pro'); ?>.
<br/><br/>
<b><?php esc_html_e('File Import', 'duplicator-pro'); ?></b> <br/>
<i><i class="fas fa-download fa-xs"></i> <?php esc_html_e('Drag-n-drop', 'duplicator-pro'); ?></i>
<?php esc_html_e('archive file from source site', 'duplicator-pro'); ?>.
</div>
</div>
</div>
</div>
<!-- =====================
SPIN-4: OVERWRITE INSTALL -->
<div class="item dup-spin-hlp">
<h3>
<i class="far fa-window-close fa-fw"></i>
<?php esc_html_e('Standard: Overwrite Install', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('Quick steps to overwrite an existing WordPress site.', 'duplicator-pro'); ?>
</div>
<ol>
<li>
<b><?php esc_html_e('Create package', 'duplicator-pro'); ?>:</b>
<?php esc_html_e(' Create package on source site', 'duplicator-pro'); ?>.
</li>
<li>
<b><?php esc_html_e('Transfer package', 'duplicator-pro'); ?>:</b>
<?php esc_html_e('Use FTP or cPanel to copy installer &amp; archive to destination WordPress site folder', 'duplicator-pro'); ?>.
</li>
<li>
<b><?php esc_html_e('Run Installer', 'duplicator-pro'); ?>:</b>
<?php esc_html_e(
'On destination server browse to URL of installer.php and follow install steps to overwrite site',
'duplicator-pro'
); ?>.
</li>
</ol>
<small>
<?php esc_html_e('Overwrite mode uses the existing wp-config.php to pre-fill database settings ', 'duplicator-pro'); ?>.
</small>
</div>
<!-- =====================
SPIN-5: CLASSIC INSTALL -->
<div class="item dup-spin-hlp">
<h3>
<i class="far fa-save fa-fw"></i>
<?php esc_html_e('Standard: Classic Install', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('Quick steps to install a WordPress site.', 'duplicator-pro'); ?>
</div>
<ol>
<li>
<b><?php esc_html_e('Create package', 'duplicator-pro'); ?>:</b>
<?php esc_html_e(' Create package on source site', 'duplicator-pro'); ?>.
</li>
<li>
<b><?php esc_html_e('Transfer package', 'duplicator-pro'); ?>:</b>
<?php
printf(
esc_html_x(
'Use FTP, cPanel or host utilities to copy installer &amp; archive to %1$sempty directory%2$s on destination server.',
'%1$s and %2$s are opening and closing underline tags (<u> and </u>)',
'duplicator-pro'
),
'<u>',
'</u>'
);
?>
</li>
<li>
<b><?php esc_html_e('Run Installer', 'duplicator-pro'); ?>:</b>
<?php esc_html_e(
'On destination server browse to URL of installer.php and follow the install steps',
'duplicator-pro'
); ?>.
</li>
</ol>
<small>
<?php esc_html_e('Classic install works simular to installing a brand new WordPress site', 'duplicator-pro'); ?>.
</small>
</div>
<!-- =====================
SPIN-6: CUSTOM INSTALL MODES -->
<div class="item dup-spin-hlp">
<h3>
<i class="fas fa-bolt fa-fw"></i>
<?php esc_html_e('Custom Install Modes', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('There are 3 custom install modes for site re-deployment.', 'duplicator-pro'); ?>
</div>
<div class="title">
<i class="fa fa-undo fa-fw"></i>&nbsp;
<a href="<?php echo esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'recover-a-backup') ?>" target="_blank">
<b><?php esc_html_e('Recovery Point', 'duplicator-pro'); ?></b>
</a>
</div>
<?php esc_html_e('Restore the current site to a specific snapshot in time.', 'duplicator-pro'); ?>
<br/><br/>
<div class="title">
<i class="fas fa-database fa-fw"></i>&nbsp;
<a href="<?php echo esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'database-install') ?>" target="_blank">
<b><?php esc_html_e('Database Install', 'duplicator-pro'); ?></b>
</a>
</div>
<?php esc_html_e('Backup and restore only the database', 'duplicator-pro'); ?>.
<br/><br/>
<div class="title">
<i class="fa fa-random fa-fw"></i>&nbsp;
<a href="<?php echo esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'two-part-install') ?>" target="_blank">
<b><?php esc_html_e('Two-Part', 'duplicator-pro'); ?></b>
</a>
</div>
<?php esc_html_e('Run the install process by manually moving some of the site files', 'duplicator-pro'); ?>.
<br/><br/>
<small>
<?php esc_html_e('Custom Install Modes are not shown in detail in this tutorial', 'duplicator-pro'); ?>.
</small>
</div>
<!-- =====================
SPIN-7: INSTALL RESOURCES -->
<div class="item dup-spin-hlp">
<h3>
<i class="fas fa-link fa-fw"></i>
<?php esc_html_e('Install Resources', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('Look for the Install Resources to aid with the install process.', 'duplicator-pro'); ?>
</div>
<div class="title">
<i class="far fa-file-archive fa-fw"></i>
<?php esc_html_e('Archive File', 'duplicator-pro'); ?>
<i class="fas fa-question-circle"
data-tooltip-title="<?php esc_attr_e("Archive File", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e(
'An import install only requires the archive file and can be from many different remote locations',
'duplicator-pro'
); ?>">
</i>
</div>
<ol style="margin-top:2px">
<li>
<?php
printf(
esc_html_x(
'Use %1$s%2$s Copy Link%3$s to run a remote import install.',
'%1$s and %3$s represent opening and closing bold (<b>) tags, %2$s represents an icon',
'duplicator-pro'
),
'<b>',
'<i class="far fa-copy fa-xs"></i>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'Use %1$s%2$s Download%3$s to run a import/overwrite/classic install.',
'%1$s and %3$s represent bold (<b>) tags, %2$s represents an icon',
'duplicator-pro'
),
'<b>',
'<i class="fas fa-download fa-xs"></i>',
'</b>'
);
?>
</li>
</ol>
<div class="title">
<i class="fas fa-bolt fa-fw"></i>
<?php esc_html_e('Archive Installer', 'duplicator-pro'); ?>
<i class="fas fa-question-circle"
data-tooltip-title="<?php esc_attr_e("Archive Installer", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e(
'Secure install names are complex, quickly copy the name to improve your workflow.',
'duplicator-pro'
); ?>">
</i>
</div>
<?php esc_html_e('The installer.php file can be used for overwrite/classic install modes.', 'duplicator-pro');?>
</div>
<!-- =====================
SPIN-8: MORE INFO -->
<div class="item dup-spin-hlp">
<h3>
<i class="fas fa-info-circle"></i>
<?php esc_html_e('More information', 'duplicator-pro'); ?>
</h3>
<div class="sub-head">
<?php esc_html_e('For additional detailed information checkout our online resources', 'duplicator-pro'); ?>.
</div>
<ul>
<li>
<i class="far fa-file-alt fa-fw"></i>
<?php $url = DUPLICATOR_PRO_BLOG_URL . 'knowledge-base-article-categories/quick-start';?>
<a href="<?php echo esc_attr($url); ?>" class='dup-knowledge-base' target='_sc-home'>
<?php esc_html_e('Quick Start', 'duplicator-pro'); ?>
</a>
</li>
<li>
<i class='fa fa-book fa-fw'></i>
<a href='<?php echo esc_url(DUPLICATOR_PRO_USER_GUIDE_URL); ?>' class='dup-full-guide' target='_sc-guide'>
<?php esc_html_e('Full User Guide', 'duplicator-pro'); ?>
</a>
</li>
<li>
<i class='far fa-file-code fa-fw'></i>
<a href='<?php echo esc_url(DUPLICATOR_PRO_TECH_FAQ_URL); ?>' class='dup-faqs' target='_sc-faq'>
<?php esc_html_e('Technical FAQs', 'duplicator-pro'); ?>
</a>
</li>
</ul>
</div>
</div>
<div class="area-right">
<i class="fas fa-chevron-circle-right"></i>
</div>
<!-- Progress -->
<div class="area-nav">
<span class="num"></span>
<progress class="progress"></progress>
</div>
</div>
</div>
</div>
</div>
<script>
jQuery(document).ready(function($) {
var spin1 = new Duplicator.UI.Ctrl.Spinner('dup-link-spinner-1');
var spin2 = new Duplicator.UI.Ctrl.Spinner('dup-link-spinner-2');
//INIT
$("a#dup-ovr-next-exe").on("click", function() {
$($('#dup-ovr-hlp-tabs div.data-tabs a.tab').get(1)).trigger("click");
spin2.setPanel(0);
});
Duplicator.UI.Ctrl.tabsFlat('dup-ovr-hlp-tabs');
Duplicator.UI.Ctrl.tabsVert('dup-ovr-hlp-vert-tabs-1');
// //DEBUG Package Overview Area & Dialog
// setTimeout(function(){
// DupPro.Pack.openLinkDetails();
// $($('div#dup-ovr-hlp-tabs a.tab').get(1)).trigger("click");
// $('div#dup-link-spinner-2 div.area-right').trigger("click");
// }, 1);
});
</script>

View File

@@ -0,0 +1,711 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Controllers\StoragePageController;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Libs\Snap\SnapJson;
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$perPage = $tplData['perPage'];
$offset = $tplData['offset'];
$currentPage = $tplData['currentPage'];
require_once DUPLICATOR____PATH . '/views/tools/recovery/widget/recovery-widget-scripts.php';
$transferBaseUrl = PackagesPageController::getInstance()->getPackageTransferUrl();
$reloadPackagesURL = $ctrlMng->getCurrentLink(
['paged' => $currentPage]
);
?>
<!-- ==========================================
THICK-BOX DIALOGS: -->
<?php
/* ------------------------------------------
* ALERT: Remote > Storage items */
$remoteDlg = new DUP_PRO_UI_Dialog();
$remoteDlg->width = 750;
$remoteDlg->height = 475;
$remoteDlg->title = __('Storage Locations', 'duplicator-pro');
$remoteDlg->message = __('Loading Please Wait...', 'duplicator-pro');
$remoteDlg->boxClass = 'dup-packs-remote-store-dlg';
$remoteDlg->initAlert();
/* ------------------------------------------
* ALERT: Bulk action > no selection */
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('Bulk Action Required', 'duplicator-pro');
$alert1->message = '<i class="fa fa-exclamation-triangle fa-sm"></i>&nbsp;';
$alert1->message .= __('No selections made! Please select an action from the "Bulk Actions" drop down menu!', 'duplicator-pro');
$alert1->initAlert();
/* ------------------------------------------
* ALERT: Bulk action > no package selected */
$alert2 = new DUP_PRO_UI_Dialog();
$alert2->title = __('Selection Required', 'duplicator-pro');
$alert2->wrapperClassButtons = 'dpro-dlg-nopackage-sel-bulk-action-btns';
$alert2->message = '<i class="fa fa-exclamation-triangle fa-sm"></i>&nbsp;';
$alert2->message .= __('No selections made! Please select at least one package to delete!', 'duplicator-pro');
$alert2->initAlert();
/* ------------------------------------------
* ALERT: Process > Error undefined */
$alert4 = new DUP_PRO_UI_Dialog();
$alert4->title = __('ERROR!', 'duplicator-pro');
$alert4->message = __('Got an error or a warning: undefined', 'duplicator-pro');
$alert4->initAlert();
/* ------------------------------------------
* ALERT: Process > Error no details */
$alert5 = new DUP_PRO_UI_Dialog();
$alert5->title = $alert4->title;
$alert5->message = __('Failed to get details.', 'duplicator-pro');
$alert5->initAlert();
/* ------------------------------------------
* ALERT: Download > No storage items */
$alert6 = new DUP_PRO_UI_Dialog();
$alert6->height = 350;
$alert6->width = 600;
$alert6->title = __('Download Status', 'duplicator-pro');
$alert6->message = sprintf(
'%s <br/><br/> <i class="fas fa-server fa-xs"></i>&nbsp;<b>%s:</b> %s <br/><br/> '
. '<i class="far fa-hdd"></i>&nbsp;<b>%s:</b> %s <br/><br/> <small><i>%s</i></small><br/>',
__('No package files found at the \'Default\' storage location on this server.', 'duplicator-pro'),
__('Remote', 'duplicator-pro'),
__('For packages stored remotely check the remote storage button next to the download button.', 'duplicator-pro'),
__('Local', 'duplicator-pro'),
__(
'To enable the direct download button be sure the local \'Default\' or a non-default, but \'Local\' storage type is enabled when creating a package.',
'duplicator-pro'
),
__(
"Note: If the Storage &#10095; Default &#10095; 'Max Packages' is set then packages will be removed but the entry will still be visible on the packages screen.", // phpcs:ignore Generic.Files.LineLength
'duplicator-pro'
)
);
$alert6->initAlert();
/* ------------------------------------------
* CONFIRM: Delete packages? */
$confirm1 = new DUP_PRO_UI_Dialog();
$confirm1->height = 280;
$confirm1->title = __('Delete Packages?', 'duplicator-pro');
$confirm1->wrapperClassButtons = 'dpro-dlg-detete-packages-btns';
$confirm1->message = __('Are you sure you want to delete the selected package(s)?', 'duplicator-pro');
$confirm1->message .= '<br/><br/>';
$confirm1->message .= '<small><i>' . __(
'Note: This action removes only packages located on this server. If a remote package was created then it will not be removed or affected.',
'duplicator-pro'
) . '</i></small>';
$confirm1->progressText = __('Removing Packages, Please Wait...', 'duplicator-pro');
$confirm1->jsCallback = 'DupPro.Pack.Delete()';
$confirm1->initConfirm();
/* ------------------------------------------
* ALERT: Recovery > toolbar button */
$toolBarRecoveryButtonInfo = new DUP_PRO_UI_Dialog();
$toolBarRecoveryButtonInfo->showButtons = false;
$toolBarRecoveryButtonInfo->height = 600;
$toolBarRecoveryButtonInfo->width = 600;
$toolBarRecoveryButtonInfo->title = __('Disaster Recovery', 'duplicator-pro');
$toolBarRecoveryButtonInfo->message = $tplMng->render('admin_pages/packages/recovery_info/info', array(), false);
$toolBarRecoveryButtonInfo->initAlert();
/* ------------------------------------------
* ALERT: Recovery */
$availableRecoveryBox = new DUP_PRO_UI_Dialog();
$availableRecoveryBox->title = __('Disaster Recovery Available', 'duplicator-pro');
$availableRecoveryBox->boxClass = 'dup-recovery-box-info';
$availableRecoveryBox->showButtons = false;
$availableRecoveryBox->width = 600;
$availableRecoveryBox->height = 400;
$availableRecoveryBox->message = '';
$availableRecoveryBox->initAlert();
$unavailableRecoveryBox = new DUP_PRO_UI_Dialog();
$unavailableRecoveryBox->title = __('Disaster Recovery Unavailable', 'duplicator-pro');
$unavailableRecoveryBox->boxClass = 'dup-recovery-box-info';
$unavailableRecoveryBox->showButtons = false;
$unavailableRecoveryBox->width = 600;
$unavailableRecoveryBox->height = 700;
$unavailableRecoveryBox->message = '';
$unavailableRecoveryBox->initAlert();
/* ------------------------------------------
* ALERT: Package overeview > Help */
$linkInfoDlg = new DUP_PRO_UI_Dialog();
$linkInfoDlg->width = 700;
$linkInfoDlg->height = 550;
$linkInfoDlg->title = __('Duplicator Pro Tutorial', 'duplicator-pro');
$linkInfoDlg->message = $tplMng->render('admin_pages/packages/packages_overview_help', array(), false);
$linkInfoDlg->initAlert();
$baseStorageEditURL = StoragePageController::getInstance()->getMenuLink(
null,
null,
[
ControllersManager::QUERY_STRING_INNER_PAGE => StoragePageController::INNER_PAGE_EDIT,
]
);
?>
<script>
jQuery(document).ready(function($) {
DupPro.Pack.RestorePackageId = null;
DupPro.PackagesTable = $('.dup-packtbl');
/**
* Click event to expands each row and show package details
*
* @returns void
*/
$('th#dup-header-chkall').on('click', function() {
var $this = $(this);
var $icon = $this.find('i');
if ($icon.hasClass('fa-chevron-left')) {
$icon.attr('class', 'fas fa-chevron-down');
$("tr.dup-row-complete").each(function() {
$icon = $(this).find('td.dup-cell-toggle-btn i');
$icon.attr('class', 'fas fa-chevron-down');
$(this).next('tr').show();
});
} else {
$icon.attr('class', 'fas fa-chevron-left');
$("tr.dup-row-complete").each(function() {
$icon = $(this).find('td.dup-cell-toggle-btn i');
$icon.attr('class', 'fas fa-chevron-left');
});
$('tr.dup-row-details').hide();
}
});
/**
* Click event to expands each row and show package details
*
* @returns void
*/
$('td.dup-cell-toggle-btn').on('click', function(e) {
var $this = $(this);
var $icon = $this.find('i');
if ($icon.hasClass('fa-chevron-left')) {
$icon.attr('class', 'fas fa-chevron-down');
$(this).parent().next('tr').show();
} else {
$icon.attr('class', 'fas fa-chevron-left');
$(this).parent().next('tr').hide();
}
});
$('.dup-pro-quick-fix-notice').on('click', '.dup-pro-quick-fix', function() {
var $this = $(this),
params = JSON.parse($this.attr('data-param')),
toggle = $this.attr('data-toggle'),
id = $this.attr('data-id'),
fix = $(toggle),
button = {
loading: function() {
$this.prop('disabled', true)
.addClass('disabled')
.html('<i class="fas fa-circle-notch fa-spin fa-fw"></i> <?php esc_html_e('Please Wait...', 'duplicator-pro') ?>');
},
reset: function() {
$this.prop('disabled', false)
.removeClass('disabled')
.html("<i class='fa fa-wrench' aria-hidden='true'></i>&nbsp; <?php esc_html_e('Resolve This', 'duplicator-pro') ?>");
}
},
error = {
message: function(text) {
fix.append(
"&nbsp; <span style='color:#cc0000' id='" +
toggle.replace('#', '') +
"-error'><i class='fa fa-exclamation-triangle'></i>&nbsp; " + text + "</span>"
);
},
remove: function() {
if ($(toggle + "-error"))
$(toggle + "-error").remove();
}
};
error.remove();
button.loading();
$.ajax({
type: "POST",
url: ajaxurl,
data: {
action: 'duplicator_pro_quick_fix',
setup: params,
id: id,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_quick_fix')); ?>'
}
}).done(function(respData, x) {
try {
var parsedData = DupPro.parseJSON(respData);
} catch (err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
button.reset();
error.message('<?php esc_html_e('Unexpected Error!', 'duplicator-pro') ?>');
console.log(respData);
console.log(x);
return false;
}
console.log(parsedData);
if (parsedData.success) {
fix.remove();
// If there is no fixes and notifications - remove container
if (typeof parsedData.recommended_fixes != 'undefined') {
if (parsedData.recommended_fixes == 0) {
$('.dup-pro-quick-fix-notice').remove();
}
}
} else {
button.reset();
error.message(parsedData.message);
}
}).fail(function(data, x) {
button.reset();
error.message('<?php esc_html_e('Unexpected Error!', 'duplicator-pro') ?>');
console.log(data);
console.log(x);
});
});
DupPro.Pack.DownloadNotice = function() {
<?php $alert6->showAlert(); ?>
return false;
};
$('.dpro-toolbar-recovery-info').click(function () {
if ($(this).hasClass('dup-recovery-unset')) {
<?php $toolBarRecoveryButtonInfo->showAlert(); ?>
} else {
let openUrl = <?php echo json_encode($ctrlMng->getMenuLink($ctrlMng::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_RECOVERY)); ?>;
window.open(openUrl,"_self");
}
});
//DOWNLOAD MENU
$('button.dup-dnload-btn').click(function(e) {
var $menu = $(this).parent().find('nav.dup-dnload-menu-items');
if ($menu.is(':visible')) {
$menu.hide();
} else {
$('nav.dup-dnload-menu-items').hide();
$menu.show(200);
}
return false;
});
$(document).click(function(e) {
var className = e.target.className;
if (className != 'dpro-menu-x') {
$('nav.dup-dnload-menu-items').hide();
}
});
$("nav.dup-dnload-menu-items button").each(function() {
$(this).addClass('dpro-menu-x');
});
$("nav.dup-dnload-menu-items button span").each(function() {
$(this).addClass('dpro-menu-x');
});
/* Creats a comma seperate list of all selected package ids */
DupPro.Pack.GetDeleteList = function() {
var arr = [];
$("input[name=delete_confirm]:checked").each(function() {
arr.push(this.id);
});
return arr;
}
DupPro.Pack.openLinkDetails = function() {
<?php $linkInfoDlg->showAlert(); ?>
}
DupPro.Pack.BackupRestore = function() {
Duplicator.Util.ajaxWrapper({
action: 'duplicator_pro_restore_backup_prepare',
packageId: DupPro.Pack.RestorePackageId,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_restore_backup_prepare')); ?>'
},
function(result, data, funcData, textStatus, jqXHR) {
window.location.href = data.funcData;
},
function(result, data, funcData, textStatus, jqXHR) {
alert('FAIL');
}
);
};
/* Provides the correct confirmation items when deleting packages */
DupPro.Pack.ConfirmDelete = function() {
$('#dpro-dlg-confirm-delete-btns input').removeAttr('disabled');
if ($("#dup-pack-bulk-actions").val() != "delete") {
<?php $alert1->showAlert(); ?>
return;
}
var list = DupPro.Pack.GetDeleteList();
if (list.length == 0) {
<?php $alert2->showAlert(); ?>
return;
}
<?php $confirm1->showConfirm(); ?>
}
/* Removes all selected package sets with ajax call */
DupPro.Pack.Delete = function() {
var packageIds = DupPro.Pack.GetDeleteList();
var pageCount = $('#current-page-selector').val();
var pageItems = $('input[name="delete_confirm"]');
var data = {
action: 'duplicator_pro_package_delete',
package_ids: packageIds,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_package_delete')); ?>'
};
$.ajax({
type: "POST",
url: ajaxurl,
data: data,
success: function(respData) {
try {
var parsedData = DupPro.parseJSON(respData);
} catch (err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
alert('Failed to delete package with AJAX resp: ' + respData);
return false;
}
if (parsedData.error.length > 0) {
alert("Ajax error: " + parsedData.error);
return false;
}
//Increment back a page-set if no items are left
if ($('#form-duplicator-nav').length) {
if (pageItems.length == packageIds.length)
$('#current-page-selector').val(pageCount - 1);
$('#form-duplicator-nav').submit();
} else {
$('#form-duplicator').submit();
}
}
});
}
/* Toogles the Bulk Action Check boxes */
DupPro.Pack.SetDeleteAll = function() {
var state = $('input#dup-chk-all').is(':checked') ? 1 : 0;
$("input[name=delete_confirm]").each(function() {
this.checked = (state) ? true : false;
});
}
/* Stops the build from running */
DupPro.Pack.StopBuild = function(packageID) {
$('#action').val('stop-build');
$('#action-parameter').val(packageID);
$('#form-duplicator').submit();
$('.dup-build-stop-btn').html('<?php esc_html_e("Cancelling...", 'duplicator-pro'); ?>');
$('.dup-build-stop-btn').prop('disabled', true);
}
/* Redirects to the packages detail screen using the package id */
DupPro.Pack.OpenPackTransfer = function(id) {
window.location.href = '<?php echo esc_url_raw(SnapJson::jsonEncode($transferBaseUrl)) ?>' + '&id=' + id;
}
/* Shows remote storage location dialogs */
DupPro.Pack.ShowRemote = function(package_id, name) {
<?php $remoteDlg->showAlert(); ?>
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_get_storage_details',
package_id: package_id,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_get_storage_details')); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
if (!funcData.success) {
var text = "<?php esc_html_e('Got an error or a warning', 'duplicator-pro'); ?>: " + funcData.message;
$('#TB_window .dpro-dlg-alert-txt').html(text);
return false;
}
var info = '<div class="dup-dlg-store-remote">';
for (storage_provider_key in funcData.storage_providers) {
var store = funcData.storage_providers[storage_provider_key];
info += store.infoHTML;
}
info += '</div>';
info += "<a href='" + funcData.logURL + "' class='dup-dlg-store-log-link' target='_blank'>" +
'<?php echo esc_html__('[Package Build Log]', 'duplicator-pro'); ?>' + "</a>";
$('#TB_window .dpro-dlg-alert-txt').html(info);
},
function(data) {
<?php $alert5->showAlert(); ?>
console.log(data);
return '';
}
);
return false;
};
$('.dup-restore-backup').click(function(event) {
event.preventDefault();
let packageId = $(this).data('package-id');
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_backup_redirect',
packageId: packageId,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_backup_redirect')); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
if (funcData.success) {
let box = new DuplicatorModalBox({
url: data.funcData.redirect_url,
openCallback: function (iframe, modalObj) {
let body = $(iframe.contentWindow.document.body);
// For old packages
body.find("#content").css('background-color', 'white');
body.on( "click", "#s1-deploy-btn", function() {
modalObj.disableClose();
});
}
});
box.open();
//window.location.href = data.funcData.redirect_url;
} else {
DupPro.addAdminMessage(funcData.message, 'error');
}
return '';
},
function(data) {
<?php $alert5->showAlert(); ?>
console.log(data);
return '';
}
);
return false;
});
/* Virtual states that UI uses for easier tracking of the three general states a package can be in*/
DupPro.Pack.ProcessingStats = {
PendingCancellation: -3,
Pending: 0,
Building: 1,
Storing: 2,
Finished: 3,
}
DupPro.Pack.setIntervalID = -1;
DupPro.Pack.SetUpdateInterval = function(period) {
if (DupPro.Pack.setIntervalID != -1) {
clearInterval(DupPro.Pack.setIntervalID);
DupPro.Pack.setIntervalID = -1
}
DupPro.Pack.setIntervalID = setInterval(DupPro.Pack.UpdateUnfinishedPackages, period * 1000);
}
DupPro.Pack.UpdateUnfinishedPackages = function() {
let packagesTables = $('.dup-packtbl');
var data = {
action: 'duplicator_pro_get_package_statii',
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_get_package_statii')); ?>',
offset: <?php echo (int) $offset; ?>,
limit: <?php echo (int) $perPage; ?>,
}
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "text",
timeout: 10000000,
data: data,
complete: function() {},
success: function(respData) {
try {
var data = DupPro.parseJSON(respData);
} catch (err) {
// console.error(err);
console.error('JSON parse failed for response data: ' + respData);
DupPro.Pack.SetUpdateInterval(60);
console.log(respData);
return false;
}
let currentFirstPackageId = -1;
let statiiFistPackageId = -1;
if (packagesTables.find('.dup-row').length) {
currentFirstPackageId = packagesTables.find('.dup-row').first().data('package-id');
}
if (data.length) {
statiiFistPackageId = data[0].ID;
}
if (currentFirstPackageId != statiiFistPackageId) {
window.location = <?php echo SnapJson::jsonEncode($reloadPackagesURL); ?>;
}
var activePackagePresent = false;
for (package_info_key in data) {
var package_info = data[package_info_key];
var statusSelector = '#status-' + package_info.ID;
var packageRowSelector = '#dup-row-pack-id-' + package_info.ID;
var packageSizeSelector = packageRowSelector + ' .dup-size-column';
var current_value_string = $(statusSelector).text();
var current_value = parseInt(current_value_string);
var currentProcessingState;
if (current_value == -3) {
currentProcessingState = DupPro.Pack.ProcessingStats.PendingCancellation;
} else if (current_value == 0) {
currentProcessingState = DupPro.Pack.ProcessingStats.Pending;
} else if ((current_value >= 0) && (current_value < 75)) {
currentProcessingState = DupPro.Pack.ProcessingStats.Building;
} else if ((current_value >= 75) && (current_value < 100)) {
currentProcessingState = DupPro.Pack.ProcessingStats.Storing;
} else {
// Has to be negative(error) or 100 - both mean complete
currentProcessingState = DupPro.Pack.ProcessingStats.Finished;
}
if (currentProcessingState == DupPro.Pack.ProcessingStats.Pending) {
if (package_info.status != 0) {
window.location = window.location.href;
}
} else if (currentProcessingState == DupPro.Pack.ProcessingStats.Building) {
if ((package_info.status >= 75) || (package_info.status < 0)) {
// Transitioned to storing so refresh
window.location = window.location.href;
break;
} else {
activePackagePresent = true;
$(statusSelector).text(package_info.status);
$(packageSizeSelector).hide().fadeIn(1000).text(package_info.size);
}
} else if (currentProcessingState == DupPro.Pack.ProcessingStats.Storing) {
if ((package_info.status == 100) || (package_info.status < 0)) {
// Transitioned to storing so refresh
window.location = window.location.href;
break;
} else {
activePackagePresent = true;
$('#dpro-progress-status-message-transfer-msg').html(package_info.status_progress_text);
var statusProgressSelector = '#status-progress-' + package_info.ID;
$(statusProgressSelector).text(package_info.status_progress);
console.log("status progress: " + package_info.status_progress);
}
} else if (currentProcessingState == DupPro.Pack.ProcessingStats.PendingCancellation) {
if ((package_info.status == -2) || (package_info.status == -4)) {
// refresh when its gone to cancelled
window.location = window.location.href;
} else {
activePackagePresent = true;
}
} else if (currentProcessingState == DupPro.Pack.ProcessingStats.Finished) {
// IF something caused the package to come out of finished refresh everything (has to be out of finished or error state)
if ((package_info.status != 100) && (package_info.status > 0)) {
// wait one miutes to prevent a realod loop
setTimeout(function() {
window.location = window.location.href;
}, 60000);
}
}
}
if (activePackagePresent) {
$('#dup-pro-create-new').addClass('disabled');
DupPro.Pack.SetUpdateInterval(10);
} else {
$('#dup-pro-create-new').removeClass('disabled');
// Kick refresh down to 60 seconds if nothing is being actively worked on
DupPro.Pack.SetUpdateInterval(60);
}
},
error: function(data) {
DupPro.Pack.SetUpdateInterval(60);
console.log(data);
}
});
};
//Init
DupPro.UI.Clock(DupPro._WordPressInitTime);
DupPro.Pack.UpdateUnfinishedPackages();
$('.dpro-btn-open-recovery-box').click(function(event) {
event.preventDefault();
let packageId = $(this).data('package-id');
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_get_recovery_box_content',
packageId: packageId,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_get_recovery_box_content')); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
if (funcData.success) {
let boxContent = funcData.content;
if (funcData.isRecoveable) {
<?php
$availableRecoveryBox->updateMessage('boxContent');
$availableRecoveryBox->showAlert();
?>
$('.dup-pro-recovery-download-launcher').off().click(function () {
DupPro.Pack.downloadLauncher();
});
} else {
<?php
$unavailableRecoveryBox->updateMessage('boxContent');
$unavailableRecoveryBox->showAlert();
?>
}
} else {
DupPro.addAdminMessage(funcData.message, 'error');
}
return '';
}
);
return false;
});
});
</script>

View File

@@ -0,0 +1,51 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\StoragesUtil;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = DUP_PRO_Global_Entity::getInstance();
$maxDefaultPackages = StoragesUtil::getDefaultStorage()->getMaxPackages();
$toolTipContent = sprintf(
esc_attr__(
'The number of packages to keep is set at [%d]. To change this setting go to
Duplicator Pro > Storage > Default > Max Packages and change the value, otherwise this note can be ignored.',
'duplicator-pro'
),
$maxDefaultPackages
);
?>
<tfoot>
<tr>
<th colspan="11">
<div class="dup-pack-status-info">
<?php if ($maxDefaultPackages < $tplData['totalElements'] && $maxDefaultPackages != 0) { ?>
<?php echo esc_html__("Note: max package retention enabled", 'duplicator-pro'); ?>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Storage Packages", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($toolTipContent); ?>"
>
</i>
<?php } else { ?>
&nbsp;
<?php } ?>
</div>
</th>
</tr>
</tfoot>

View File

@@ -0,0 +1,89 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Addons\ProBase\License\License;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = DUP_PRO_Global_Entity::getInstance();
if ($global->installer_name_mode == DUP_PRO_Global_Entity::INSTALLER_NAME_MODE_SIMPLE) {
$packageExeNameModeMsg = __(
"When clicking the Installer download button, the 'Save as' dialog is currently defaulting the name to 'installer.php'.
To improve the security and get more information, go to:
Settings > Packages Tab > Installer > Name option or click on the gear icon at the top of this page.",
'duplicator-pro'
);
} else {
$packageExeNameModeMsg = __(
"When clicking the Installer download button, the 'Save as' dialog is defaulting the name to '[name]_[hash]_[date]_installer.php'.
This is the secure and recommended option.
For more information, go to: Settings > Packages Tab > Installer > Name or click on the gear icon at the top of this page.<br/><br/>
To quickly copy the hashed installer name, to your clipboard use the copy icon link or click the installer name and manually copy the selected text.",
'duplicator-pro'
);
}
global $packagesViewData;
$tooltipContent = $tplMng->render('admin_pages/packages/packages_table_head_status_icons', [], false);
?>
<h2 class="screen-reader-text">Packages list</h2>
<thead>
<tr>
<th class="dup-check-column" style="width:10px;">
<input
type="checkbox"
id="dup-chk-all"
title="<?php esc_attr_e("Select all packages", 'duplicator-pro') ?>"
style="margin-left:15px" onclick="DupPro.Pack.SetDeleteAll()" />
</th>
<th class="dup-name-column" >
<?php esc_html_e("Backup Name", 'duplicator-pro') ?>
</th>
<th class="dup-note-column">
<?php esc_html_e("Note", 'duplicator-pro') ?>
</th>
<th class="dup-storages-column">
<?php esc_html_e("Storages", 'duplicator-pro') ?>
</th>
<th class="dup-flags-column">
<?php esc_html_e("Status", 'duplicator-pro') ?>&nbsp;
<i
class="fa-solid fa-circle-info"
data-tooltip-title="<?php esc_attr_e("Status Icons", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tooltipContent); ?>"
></i>
</th>
<th class="dup-created-column">
<?php esc_html_e("Created", 'duplicator-pro') ?>
</th>
<th class="dup-age-column">
<?php esc_html_e("Age", 'duplicator-pro') ?>
</th>
<th class="dup-size-column">
<?php esc_html_e("Size", 'duplicator-pro') ?>
</th>
<th class="dup-download-column" style="width:75px;"></th>
<th class="dup-restore-column" style="width:25px;"></th>
<th id="dup-header-chkall" class="dup-details-column" >
<?php if ($tplData['totalElements'] > 0) { ?>
<a href="javascript:void(0)" class="button button-link"><i class="fas fa-chevron-left"></i></a>
<?php } ?>
</th>
</tr>
</thead>

View File

@@ -0,0 +1,80 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<ul class="dup-status-icons-list" >
<li>
<span class="icon-wrapper" ><i class="fa-solid fa-hand" ></i></span>
<?php esc_html_e('Manual Backup', 'duplicator-pro'); ?>
</li>
<li>
<span class="icon-wrapper" ><i class="fa-solid fa-clock" ></i></span>
<?php esc_attr_e('Schedule Backup', 'duplicator-pro') ?>
</li>
<li>
<span class="icon-wrapper" ><i class="fa-solid fa-hard-drive"></i></span>
<?php
echo wp_kses(
__('The Backup is in a Local Storage <b>[clickable]</b>', 'duplicator-pro'),
ViewHelper::GEN_KSES_TAGS
);
?>
</li>
<li>
<span class="icon-wrapper" ><i class="fa-solid fa-cloud"></i></span>
<?php
echo wp_kses(
__('The Backup is in a Remote Storage <b>[clickable]</b>', 'duplicator-pro'),
ViewHelper::GEN_KSES_TAGS
);
?>
</li>
<li>
<span class="icon-wrapper" ><i class="fa-solid fa-database"></i></span>
<?php esc_attr_e('Database Only Backup', 'duplicator-pro') ?>
</li>
<li>
<span class="icon-wrapper" ><i class="fa-solid fa-images"></i></span>
<?php esc_attr_e('Media Only Backup', 'duplicator-pro') ?>
</li>
<li>
<span class="icon-wrapper" ><?php ViewHelper::disasterIcon(true, 'link-style no-decoration'); ?></span>
<?php
echo wp_kses(
__('This Backup is available for Disaster Recovery <b>[clickable]</b>', 'duplicator-pro'),
ViewHelper::GEN_KSES_TAGS
);
?>
</li>
<li>
<span class="icon-wrapper" ><?php ViewHelper::disasterIcon(true, 'green'); ?></span>
<?php
echo wp_kses(
__('Disaster Recovery URL is set on this Backup <b>[clickable]</b>', 'duplicator-pro'),
ViewHelper::GEN_KSES_TAGS
);
?>
</li>
<li>
<span class="icon-wrapper" ><i class="fa-solid fa-clock-rotate-left maroon"></i></span>
<?php esc_attr_e('This Backup is created after the Last Restored Backup', 'duplicator-pro') ?>
</li>
</ul>

View File

@@ -0,0 +1,41 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\RecoveryController;
use Duplicator\Package\Recovery\RecoveryPackage;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<div class="dup-pro-toolbar-recovery-info margin-bottom-1">
<?php
if (RecoveryPackage::getRecoverPackageId() === false) {
$tplMng->render('admin_pages/packages/recovery_info/no_recovery_set');
} else {
RecoveryController::renderRecoveryWidged(
array(
'selector' => false,
'subtitle' => '',
'copyLink' => true,
'copyButton' => true,
'launch' => true,
'download' => true,
'info' => true,
)
);
}
?>
</div>

View File

@@ -0,0 +1,88 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<h3 class="dup-title maroon">
<?php ViewHelper::disasterIcon(); ?>&nbsp;<?php esc_html_e('Disaster Recovery - None Set', 'duplicator-pro'); ?>
</h3>
<?php
esc_html_e(
'The recovery point can quickly restore a site to a prior state for any reason. To activate a recovery point follow these steps:',
'duplicator-pro'
);
?>
<ol>
<li>
<?php
printf(
esc_html__('Select a recovery package with the icon %s displayed*.', 'duplicator-pro'),
wp_kses(
ViewHelper::disasterIcon(false),
['i' => ['class' => []]]
)
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'Open details area %1$s and click the "Recover Package..." buttton.',
'%1$s represents an icon',
'duplicator-pro'
),
'<i class="fas fa-chevron-left fa-sm fa-fw"></i>'
);
?>
</li>
<li>
<?php esc_html_e('Follow the prompts and choose the action to perform.', 'duplicator-pro'); ?>
</li>
</ol>
<hr/>
<p>
<b><?php esc_html_e('Additional Details:', 'duplicator-pro'); ?></b>
<?php
esc_html_e(
'Once a recovery point is set you can save the "Recovery Key" URL in a safe place for restoration later in the event your site goes down, gets
hacked or basically any reason you need to restore a site. In the event you still have access to your site you can also launch the recover
wizard from the details menu.',
'duplicator-pro'
);
?>
</p>
<small>
<i>
<?php
printf(
esc_html__(
'*Note: If you do not see a recovery package %s icon in the packages list.
Then be sure to build a full package that does not exclude any of the core WordPress files or database tables.
These core files and tables are required to build a valid recovery point.',
'duplicator-pro'
),
wp_kses(
ViewHelper::disasterIcon(false),
['i' => ['class' => []]]
)
);
?>
</i>
</small>

View File

@@ -0,0 +1,62 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var \DUP_PRO_Package $package
*/
$package = $tplData['package'];
$isRecoveable = RecoveryPackage::isPackageIdRecoveable($package->ID);
if ($isRecoveable) {
$tplMng->render('admin_pages/packages/recovery_info/row_recovery_box_available');
} else {
$tplMng->render('admin_pages/packages/recovery_info/row_recovery_box_unavailable');
}
?>
<hr class="margin-top-1 margin-bottom-1" >
<small><i>
<?php
echo wp_kses(
__(
'The <b>Disaster Recovery</b> is a streamlined Restore Backup system used to rapidly restore your site from a disaster.
A functioning <b>WordPress backend is not required</b>, only the LINK or the Launcher provided with the Disaster Recovery
is needed to restore the Backup.',
'duplicator-pro'
),
ViewHelper::GEN_KSES_TAGS
);
?>
<br>
<?php
printf(
wp_kses(
_x(
'Backups that are not Disaster Recovery eligible will can to use the <b>Restore Backup button</b>
or %1$sstandard install modes%2$s for re-deployment.',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
ViewHelper::GEN_KSES_TAGS
),
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'recover-a-backup') . '" target="_blank">',
'</a>'
);
?>
</i></small>

View File

@@ -0,0 +1,81 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Controllers\RecoveryController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\ViewHelper;
/**
* Variables
*
* @var ControllersManager $ctrlMng
* @var TplMng $tplMng
* @var array<string, mixed> $tplData
* @var DUP_PRO_Package $package
*/
$package = $tplData['package'];
$isRecoverPoint = (RecoveryPackage::getRecoverPackageId() === $package->ID);
$colorClass = ($isRecoverPoint ? 'green' : '');
?>
<h3 class="dup-title margin-top-0">
<?php ViewHelper::disasterIcon(true, $colorClass); ?>&nbsp;
<?php
if ($isRecoverPoint) {
esc_html_e('Disaster Recovery - Is Set on this Backup', 'duplicator-pro');
} else {
esc_html_e('Disaster Recovery - Is Available for this Backup', 'duplicator-pro');
}
?>
</h3>
<?php $tplMng->render('parts/recovery/package_info_mini'); ?>
<hr class="margin-top-1 margin-bottom-1" >
<?php if ($isRecoverPoint) {
RecoveryController::renderRecoveryWidged([
'details' => false,
'selector' => false,
'subtitle' => '',
'copyLink' => false,
'copyButton' => true,
'launch' => false,
'download' => true,
'info' => true,
]);
} else {
$setRecoveryLink = PackagesPageController::getInstance()->getActionByKey(PackagesPageController::ACTION_SET_RECOVERY_POINT)->getUrl(
['recovery_package' => $package->ID]
);
?>
<div class="dup-pro-recovery-widget-wrapper" >
<div class="dup-pro-recovery-point-actions" >
<div class="dup-pro-recovery-buttons">
<a
href="<?php echo esc_url($setRecoveryLink); ?>"
class="button button-primary dpro-btn-set-recovery"
data-package-id="<?php echo (int) $package->ID; ?>"
>
<span><?php ViewHelper::disasterIcon(); ?>&nbsp;
<?php esc_html_e("Set Disaster Recovery", 'duplicator-pro'); ?></span>&nbsp;
<i
class="fas fa-question-circle fa-sm dup-base-color white"
data-tooltip-title="<?php esc_attr_e("Activate Recovery", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e("This action will set this package as the active Disaster Recovery Backup.", 'duplicator-pro'); ?>"
aria-expanded="false"
>
</i>
</a>
</div>
</div>
</div>
<?php }

View File

@@ -0,0 +1,49 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Package\Recovery\RecoveryStatus;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var \DUP_PRO_Package $package
*/
$package = $tplData['package'];
$tooltipContent = __('A package recovery point status is not required to be enabled and in some cases is desirable.', 'duplicator-pro') . ' ' .
__('For example you may want to backup only your database.', 'duplicator-pro') . ' ' .
__(
'In this case you can still run a database only install, however the ability to use the recovery point installer will be unavailable.',
'duplicator-pro'
);
?>
<h3 class="dup-title margin-top-0">
<?php ViewHelper::disasterIcon(true, 'maroon'); ?>&nbsp;
<?php esc_html_e('Disaster Recovery - Isn\'t Available for this Backup', 'duplicator-pro'); ?>
<sup>
<i class="fas fa-question-circle fa-xs"
data-tooltip-title="<?php esc_attr_e('Recovery', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tooltipContent); ?>">
</i>
</sup>
</h3>
<?php $tplMng->render('parts/recovery/package_info_mini'); ?>
<hr class="margin-top-1 margin-bottom-1" >
<?php
$recoverStatus = new RecoveryStatus($package);
$tplMng->render('parts/recovery/exclude_data_box', array('recoverStatus' => $recoverStatus));

View File

@@ -0,0 +1,206 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\ImportPageController;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Controllers\StoragePageController;
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$global = DUP_PRO_Global_Entity::getInstance();
$package = $tplData['package'];
$archive_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Archive) != false);
$installer_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Installer) != false);
$archiveDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Archive);
$installerDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Installer);
$defaultStorageUrl = StoragePageController::getEditDefaultUrl();
$txt_RequiresRemote = sprintf(
"%s <a href='{$defaultStorageUrl}' target='_blank'>%s <i class='far fa-hdd fa-fw fa-sm'></i></a>",
__('This option requires the package to use the built-in default', 'duplicator-pro'),
__('storage location', 'duplicator-pro')
);
?>
<div class="dup-ovr-ctrls-hdrs">
<i class="fas fa-link fa-fw"></i>
<b><?php esc_html_e('Install Resources', 'duplicator-pro');?> <br/></b>
<span class="dup-info-msg01">
<?php esc_html_e('Links are sensitive. Keep them safe!', 'duplicator-pro');?>
</span>
<?php if (CapMng::can(CapMng::CAP_STORAGE, false)) { ?>
<a class="dup-ovr-ref-links-more no-outline" href="javascript:void(0)"
onclick="DupPro.Pack.ShowRemote(<?php echo (int) $package->ID; ?>, '<?php echo esc_js($package->NameHash); ?>');">
<i class="fas fa-server fa-xs"></i>
<?php esc_html_e('Storages ...', 'duplicator-pro');?>
</a>
<?php } ?>
</div>
<!-- =======================
ARCHIVE FILE: -->
<div class="dup-ovr-copy-flex-box">
<div class="flex-item">
<i class="far fa-file-archive fa-fw"></i>
<b><?php esc_html_e('Archive File', 'duplicator-pro');?></b>
<sup>
<?php
$archiveFileToolTipTitle = sprintf(
__('This link is used with the <a href=\'%1$s\'>%2$s</a> %3$s', 'duplicator-pro'),
esc_url(ImportPageController::getInstance()->getMenuLink()),
__('Import Link Install', 'duplicator-pro'),
__(
'feature. Use the Copy Link button to copy this URL archive file link to import on another WordPress site.',
'duplicator-pro'
)
);?>
<i class="fas fa-question-circle fa-xs fa-fw dup-archive-help"
data-tooltip-title="<?php esc_attr_e("Archive File", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($archiveFileToolTipTitle);?>"></i>
</sup>
</div>
<div class="flex-item"></div>
</div>
<div class="dup-ovr-copy-flex-box dup-box-file">
<?php if ($archive_exists) : ?>
<div class="flex-item">
<input type="text" class="dup-ovr-ref-links" readonly="readonly"
value="<?php echo esc_attr($archiveDownloadURL); ?>"
title="<?php echo esc_attr($archiveDownloadURL); ?>"
onfocus="jQuery(this).select();" />
<span class="fas fa-arrow-alt-circle-down dup-ovr-ref-links-icon"
title="<?php esc_attr_e('Archive Import Link (URL)', 'duplicator-pro');?>"></span>
</div>
<div class="flex-item">
<span onclick="jQuery(this).parent().parent().find('.dup-ovr-ref-links').select();">
<span data-dup-copy-value="<?php echo esc_attr($archiveDownloadURL); ?>"
class="dup-ovr-ref-copy no-select">
<i class='far fa-copy dup-cursor-pointer'></i>
<?php esc_html_e('Copy Link', 'duplicator-pro');?>
</span>
</span>
<span class="dup-ovr-ref-dwnld"
aria-label="<?php esc_html_e("Download Archive", 'duplicator-pro') ?>"
onclick="DupPro.Pack.DownloadFile('<?php echo esc_attr($archiveDownloadURL); ?>',
'<?php echo esc_attr($package->get_archive_filename()); ?>');">
<i class="fas fa-download"></i> <?php esc_html_e('Download', 'duplicator-pro');?>
</span>
</div>
<?php else : ?>
<div class="flex-item maroon">
<?php
echo wp_kses(
$txt_RequiresRemote,
[
'a' => [
'href' => [],
'target' => [],
],
'i' => [
'class' => [],
],
]
);
?>.
</div>
<?php endif; ?>
</div><br/>
<!-- =======================
ARCHIVE INSTALLER: -->
<?php
switch ($global->installer_name_mode) {
case DUP_PRO_Global_Entity::INSTALLER_NAME_MODE_SIMPLE:
$settingsPackageUrl = SettingsPageController::getInstance()->getMenuLink(SettingsPageController::L2_SLUG_PACKAGE);
$lockIcon = 'fa-lock-open';
$installerToolTipTitle = sprintf(
__(
'Using standard installer name. To improve security, switch to hashed change in %1$sSettings%2$s',
'duplicator-pro'
),
'<a href="' . esc_url($settingsPackageUrl) . '" >',
'</a>'
);
break;
case DUP_PRO_Global_Entity::INSTALLER_NAME_MODE_WITH_HASH:
default:
$lockIcon = 'fa-lock';
$installerToolTipTitle = __('Using more secure, hashed installer name.', 'duplicator-pro');
break;
}
$installerName = $package->Installer->getDownloadName();
?>
<i class="fas fa-bolt fa-fw"></i>
<b><?php esc_html_e('Archive Installer', 'duplicator-pro');?></b>
<sup>
<i class="fas <?php echo esc_attr($lockIcon); ?> dup-cursor-pointer fa-fw fa-xs dup-installer-help"
style="padding-left:3px"
data-tooltip="<?php echo esc_html($installerToolTipTitle); ?>"></i>
</sup>
<div class="dup-ovr-copy-flex-box dup-box-installer">
<?php if ($installer_exists) : ?>
<div class="flex-item">
<input type="text" class="dup-ovr-ref-links" readonly="readonly"
value="<?php echo esc_attr($installerName); ?>"
title="<?php echo esc_attr($installerName); ?>"
onfocus="jQuery(this).select();" /><br/>
<span class="dup-info-msg01">
&nbsp;<?php esc_html_e('These links contain highly sensitive data. Share with extra caution!', 'duplicator-pro');?>
</span>
</div>
<div class="flex-item">
<span onclick="jQuery(this).parent().parent().find('.dup-ovr-ref-links').select();">
<span data-dup-copy-value="<?php echo esc_attr($installerName); ?>" class="dup-ovr-ref-copy no-select">
<i class='far fa-copy dup-cursor-pointer'></i>
<?php esc_html_e('Copy Name', 'duplicator-pro');?>
</span>
</span>
<span class="dup-ovr-ref-dwnld"
aria-label="<?php esc_html_e("Download Installer", 'duplicator-pro') ?>"
onclick="DupPro.Pack.DownloadFile('<?php echo esc_attr($installerDownloadURL); ?>');">
<i class="fas fa-download"></i> <?php esc_html_e('Download', 'duplicator-pro');?>
</span>
</div>
<?php else : ?>
<div class="flex-item maroon">
<?php
echo wp_kses(
$txt_RequiresRemote,
[
'a' => [
'href' => [],
'target' => [],
],
'i' => [
'class' => [],
],
]
);
?>.
</div>
<?php endif; ?>
</div>

View File

@@ -0,0 +1,120 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Core\CapMng;
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
$pack_dbonly = $package->isDBOnly();
$pack_format = strtolower($package->Archive->Format);
$packageDetailsURL = PackagesPageController::getInstance()->getPackageDetailsURL($package->ID);
$txt_DBOnly = __('DB Only', 'duplicator-pro');
$archive_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Archive) != false);
$isRecoveable = RecoveryPackage::isPackageIdRecoveable($package->ID);
?>
<td colspan="8">
<div class="dup-package-row-details-wrapper" >
<div class="dup-ovr-hdr">
<label onclick="DupPro.Pack.openLinkDetails()">
<i class="fas fa-archive"></i>
<?php esc_html_e('Package Overview', 'duplicator-pro'); ?>
</label>
</div>
<div class="dup-ovr-bar-flex-box">
<div class="divider">
<label><?php esc_html_e('WordPress', 'duplicator-pro');?></label><br/>
<?php echo esc_html($package->VersionWP); ?> &nbsp;
</div>
<div>
<label><?php esc_html_e('Format', 'duplicator-pro');?></label><br/>
<?php echo esc_html(strtoupper($pack_format)); ?>
</div>
<div>
<label><?php esc_html_e('Files', 'duplicator-pro');?></label><br/>
<?php echo ($pack_dbonly)
? '<i>' . esc_html($txt_DBOnly) . '</i>'
: number_format($package->Archive->FileCount); ?>
</div>
<div class="divider">
<label><?php esc_html_e('Folders', 'duplicator-pro');?></label><br/>
<?php echo ($pack_dbonly)
? '<i>' . esc_html($txt_DBOnly) . '</i>'
: number_format($package->Archive->DirCount) ?>
</div>
<div class="divider">
<label><?php esc_html_e('Tables', 'duplicator-pro');?></label><br/>
<?php echo (int) $package->Database->info->tablesFinalCount . 'of' . (int) $package->Database->info->tablesBaseCount; ?>
</div>
</div>
<div class="dup-ovr-ctrls-flex-box">
<div class="flex-item">
<?php
if (CapMng::can(CapMng::CAP_EXPORT, false)) {
$tplMng->render('admin_pages/packages/row_parts/details_download_block');
}
?>
</div>
<!-- OPTIONS -->
<div class="flex-item dup-ovr-opts">
<div class="dup-ovr-ctrls-hdrs">
<br/><b><?php esc_html_e('Options', 'duplicator-pro');?></b>
</div>
<a
aria-label="<?php esc_attr_e("Go to package details screen", 'duplicator-pro') ?>"
class="button dup-details"
href="<?php echo esc_url($packageDetailsURL); ?>"
>
<span><i class="fas fa-search"></i> <?php esc_html_e("View Details", 'duplicator-pro') ?></span>
</a>
<?php if (CapMng::can(CapMng::CAP_STORAGE, false)) { ?>
<?php if ($archive_exists) : ?>
<button class="button dup-transfer"
aria-label="<?php esc_attr_e('Go to package transfer screen', 'duplicator-pro') ?>"
onclick="DupPro.Pack.OpenPackTransfer(<?php echo (int) $package->ID; ?>); return false;">
<span><i class="fa fa-exchange-alt fa-fw"></i> <?php esc_html_e("Transfer Package", 'duplicator-pro') ?></span>
</button>
<?php else : ?>
<span title="<?php esc_attr_e('Transfer packages requires the use of built-in default storage!', 'duplicator-pro') ?>">
<button class="button disabled" >
<span><i class="fa fa-exchange-alt fa-fw"></i> <?php esc_html_e("Transfer Package", 'duplicator-pro') ?></span>
</button>
</span>
<?php endif; ?>
<?php } ?>
<?php if (CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) { ?>
<button
aria-label="<?php esc_attr_e("Recover this Package", 'duplicator-pro') ?>"
class="button dpro-btn-open-recovery-box <?php echo ($isRecoveable) ? '' : 'maroon'?>"
data-package-id="<?php echo (int) $package->ID; ?>"
>
<?php ViewHelper::disasterIcon(true); ?>
<?php esc_html_e("Disaster Recovery", 'duplicator-pro'); ?>
</button>
<?php } ?>
</div>
</div>
</div>
</td>

View File

@@ -0,0 +1,85 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
$archive_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Archive) != false);
$installer_exists = ($package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Installer) != false);
$archiveDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Archive);
$installerDownloadURL = $package->getLocalPackageFileURL(DUP_PRO_Package_File_Type::Installer);
$pack_format = strtolower($package->Archive->Format);
if (!CapMng::can(CapMng::CAP_EXPORT, false)) {
return;
}
if ($archive_exists) : ?>
<nav class="dup-dnload-menu">
<button
class="dup-dnload-btn button no-select"
type="button" aria-haspopup="true">
<i class="fa fa-download"></i>&nbsp;
<span><?php esc_html_e("Download", 'duplicator-pro'); ?></span>
</button>
<nav class="dup-dnload-menu-items">
<button
aria-label="<?php esc_html_e("Download Installer and Archive", 'duplicator-pro') ?>"
title="<?php echo ($installer_exists ? '' : esc_html__("Unable to locate both package files!", 'duplicator-pro')); ?>"
onclick="DupPro.Pack.DownloadFile('<?php echo esc_attr($archiveDownloadURL); ?>',
'<?php echo esc_attr($package->get_archive_filename()); ?>');
setTimeout(function () {DupPro.Pack.DownloadFile('<?php echo esc_attr($installerDownloadURL); ?>');}, 700);
jQuery(this).parent().hide();
return false;"
class="dup-dnload-both"
>
<i class="fa fa-fw <?php echo ($installer_exists ? 'fa-download' : 'fa-exclamation-triangle') ?>"></i>
&nbsp;<?php esc_html_e("Both Files", 'duplicator-pro') ?>
</button>
<button
aria-label="<?php esc_html_e("Download Installer", 'duplicator-pro') ?>"
title="<?php echo ($installer_exists) ? '' : esc_html__("Unable to locate installer package file!", 'duplicator-pro'); ?>"
onclick="DupPro.Pack.DownloadFile('<?php echo esc_attr($installerDownloadURL); ?>');
jQuery(this).parent().hide();
return false;"
class="dup-dnload-installer">
<i class="fa fa-fw <?php echo ($installer_exists ? 'fa-bolt' : 'fa-exclamation-triangle') ?>"></i>&nbsp;
<?php esc_html_e("Installer", 'duplicator-pro') ?>
</button>
<button
aria-label="<?php esc_html_e("Download Archive", 'duplicator-pro') ?>"
onclick="DupPro.Pack.DownloadFile('<?php echo esc_attr($archiveDownloadURL); ?>',
'<?php echo esc_attr($package->get_archive_filename()); ?>');
jQuery(this).parent().hide();
return false;"
class="dup-dnload-archive">
<i class="fa-fw far fa-file-archive"></i>&nbsp;
<?php echo esc_html__('Archive', 'duplicator-pro') . ' (' . esc_html($pack_format) . ')'; ?>
</button>
</nav>
</nav>
<?php else : ?>
<div
class="dup-dnload-btn-disabled"
title="<?php esc_attr_e("No local files found for this package!", 'duplicator-pro'); ?>"
onclick="DupPro.Pack.DownloadNotice()"
>
<i class="fas fa-download fa-fw"></i> <?php esc_html_e("Download", 'duplicator-pro'); ?>
</div>
<?php endif; ?>

View File

@@ -0,0 +1,89 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Core\CapMng;
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
?>
<div class="dup-package-flags" >
<?php if ($package->hasFlag(DUP_PRO_Package::FLAG_MANUAL) || $package->hasFlag(DUP_PRO_Package::FLAG_SCHEDULE_RUN_NOW)) { ?>
<span class="icon-wrapper" title="<?php esc_attr_e('Manual Backup', 'duplicator-pro') ?>" >
<i class="fa-solid fa-hand" ></i>
</span>
<?php } ?>
<?php if ($package->hasFlag(DUP_PRO_Package::FLAG_SCHEDULE)) { ?>
<span class="icon-wrapper" title="<?php esc_attr_e('Schedule Backup', 'duplicator-pro') ?>" >
<i class="fa-solid fa-clock" ></i>
</span>
<?php } ?>
<?php if ($package->hasFlag(DUP_PRO_Package::FLAG_HAVE_LOCAL)) { ?>
<span
class="icon-wrapper cursor-pointer"
title="<?php esc_attr_e('The Backup is in Local Storage', 'duplicator-pro') ?>"
onclick="DupPro.Pack.ShowRemote(<?php echo (int) $package->ID; ?>, '<?php echo esc_js($package->NameHash); ?>');"
>
<i class="fa-solid fa-hard-drive"></i>
</span>
<?php } ?>
<?php if ($package->hasFlag(DUP_PRO_Package::FLAG_HAVE_REMOTE)) { ?>
<span
class="icon-wrapper cursor-pointer"
title="<?php esc_attr_e('The Backup is in Remote Storage', 'duplicator-pro') ?>"
onclick="DupPro.Pack.ShowRemote(<?php echo (int) $package->ID; ?>, '<?php echo esc_js($package->NameHash); ?>');"
>
<i class="fa-solid fa-cloud"></i>
</span>
<?php } ?>
<?php if ($package->hasFlag(DUP_PRO_Package::FLAG_DB_ONLY)) { ?>
<span class="icon-wrapper" title="<?php esc_attr_e('Database Only Backup', 'duplicator-pro') ?>" >
<i class="fa-solid fa-database"></i>
</span>
<?php } ?>
<?php if ($package->hasFlag(DUP_PRO_Package::FLAG_MEDIA_ONLY)) { ?>
<span class="icon-wrapper" title="<?php esc_attr_e('Media Only Backup', 'duplicator-pro') ?>" >
<i class="fa-solid fa-images"></i>
</span>
<?php } ?>
<?php if (CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) { ?>
<?php if ($package->hasFlag(DUP_PRO_Package::FLAG_DISASTER_AVAIABLE) || $package->hasFlag(DUP_PRO_Package::FLAG_DISASTER_SET)) {
if ($package->hasFlag(DUP_PRO_Package::FLAG_DISASTER_SET)) {
$title = __("Disaster Recovery URL is set on this Backup", 'duplicator-pro');
$colorClass = 'green';
} else {
$colorClass = '';
$title = __('This Backup is available for Disaster Recovery', 'duplicator-pro');
}
?>
<span
class="dpro-btn-open-recovery-box icon-wrapper link-style no-decoration>"
aria-label="<?php echo esc_attr($title); ?>"
title="<?php echo esc_attr($title); ?>"
data-package-id="<?php echo (int) $package->ID; ?>"
>
<?php ViewHelper::disasterIcon(true, $colorClass); ?>
</span>
<?php } ?>
<?php } ?>
<?php if ($package->hasFlag(DUP_PRO_Package::FLAG_CREATED_AFTER_RESTORE)) { ?>
<span class="icon-wrapper" title="<?php esc_attr_e('This Backup is created after the Last Restored Backup', 'duplicator-pro') ?>" >
<i class="fa-solid fa-clock-rotate-left maroon"></i>
</span>
<?php } ?>
</div>

View File

@@ -0,0 +1,72 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\PackagesPageController;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
/** @var int */
$status = $tplData['status'];
?>
<div class="progress-error">
<?php
switch ($status) {
case DUP_PRO_PackageStatus::ERROR:
$packageDetailsURL = PackagesPageController::getInstance()->getPackageDetailsURL($package->ID);
?>
<a type="button" class="dup-cell-err-btn button" href="<?php echo esc_url($packageDetailsURL) ?>">
<i class="fa fa-exclamation-triangle fa-xs"></i>&nbsp;
<?php esc_html_e('Error Processing', 'duplicator-pro') ?>
</a>
<?php
break;
case DUP_PRO_PackageStatus::BUILD_CANCELLED:
?>
<i class="fas fa-info-circle fa-sm"></i>&nbsp;
<?php esc_html_e('Build Cancelled', 'duplicator-pro') ?>
<?php
break;
case DUP_PRO_PackageStatus::PENDING_CANCEL:
?>
<i class="fas fa-info-circle fa-sm"></i>
<?php esc_html_e('Cancelling Build', 'duplicator-pro') ?>
<?php
break;
case DUP_PRO_PackageStatus::STORAGE_CANCELLED:
?>
<i class="fas fa-info-circle fa-sm"></i>&nbsp;
<?php esc_html_e('Storage Cancelled', 'duplicator-pro') ?>
<?php
break;
case DUP_PRO_PackageStatus::REQUIREMENTS_FAILED:
$packageLogFile = dirname($package->StorePath) . '/' . $package->NameHash . '_log.txt';
if (file_exists($packageLogFile)) {
$link_log = $package->StoreURL . $package->NameHash . "_log.txt";
} else {
// .log is for backward compatibility
$link_log = $package->StoreURL . $package->NameHash . ".log";
}
?>
<a href="<?php echo esc_url($link_log) ?>" target="_blank">
<i class="fas fa-info-circle"></i> <?php esc_html_e('Requirements Failed', 'duplicator-pro') ?>
</a>
<?php
break;
default:
break;
}
?>
</div>
<span style='display:none' id='status-<?php echo (int) $package->ID ?>'><?php echo (int) $status ?></span>

View File

@@ -0,0 +1,38 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Core\CapMng;
use Duplicator\Package\Recovery\BackupPackage;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
$storage_problem = $package->transferWasInterrupted();
if (!CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) {
return;
}
?>
<button
type="button" class="button button-link dup-restore-backup"
data-package-id="<?php echo (int) $package->ID; ?>"
<?php disabled($package->haveLocalStorage(), false); ?>
aria-label="<?php esc_attr_e("Restore backup", 'duplicator-pro') ?>"
title="<?php esc_attr_e("Restore backup.", 'duplicator-pro') ?>"
>
<?php ViewHelper::restoreIcon(); ?> <?php esc_html_e("Restore", 'duplicator-pro'); ?>
</button>

View File

@@ -0,0 +1,49 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var ?DUP_PRO_Package $package
*/
$package = $tplData['package'];
$storage_problem = $package->transferWasInterrupted();
$remote_style = ($storage_problem) ? 'remote-data-fail' : '';
if (!CapMng::can(CapMng::CAP_STORAGE, false)) {
?>
<td></td>
<?php
return;
}
if ($storage_problem) { ?>
<td class="dup-cell-btns dup-cell-store-btn"
aria-label="<?php esc_attr_e("Remote Storages", 'duplicator-pro') ?>"
onclick="DupPro.Pack.ShowRemote(<?php echo (int) $package->ID; ?>, '<?php echo esc_js($package->NameHash); ?>');"
title="<?php esc_attr_e("Error during storage transfer.", 'duplicator-pro') ?>">
<span class="button button-link">
<i class="fas fa-server <?php echo esc_attr($remote_style); ?>"></i>
</span>
</td>
<?php } else { ?>
<td class="dup-cell-btns dup-cell-store-btn"
onclick="DupPro.Pack.ShowRemote(<?php echo (int) $package->ID; ?>, '<?php echo esc_js($package->NameHash); ?>');"
aria-label="<?php esc_attr_e("Remote Storages", 'duplicator-pro') ?>">
<span class="button button-link">
<i class="fas fa-server <?php echo esc_attr($remote_style); ?>"></i>
</span>
</td>
<?php } ?>
</td>

View File

@@ -0,0 +1,55 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<br>
<b><?php esc_html_e('Please Retry:', 'duplicator-pro'); ?></b><br>
<?php esc_html_e('Unable to perform a full scan and read JSON file, please try the following actions.', 'duplicator-pro'); ?><br>
<?php esc_html_e('1. Go back and create a root path directory filter to validate the site is scan-able.', 'duplicator-pro'); ?><br>
<?php esc_html_e('2. Continue to add/remove filters to isolate which path is causing issues.', 'duplicator-pro'); ?><br>
<?php esc_html_e('3. This message will go away once the correct filters are applied.', 'duplicator-pro'); ?><br>
<br>
<b><?php esc_html_e('Common Issues:', 'duplicator-pro'); ?></b><br>
<?php
esc_html_e(
'- On some budget hosts scanning over 30k files can lead to timeout/gateway issues.
Consider scanning only your main WordPress site and avoid trying to backup other external directories.',
'duplicator-pro'
);
?><br>
<?php
esc_html_e(
'- Symbolic link recursion can cause timeouts. Ask your server admin if any are present in the scan path.
If they are add the full path as a filter and try running the scan again.',
'duplicator-pro'
); ?><br>
<br>
<b><?php esc_html_e('Details:', 'duplicator-pro'); ?></b><br>
<?php esc_html_e('JSON Service:', 'duplicator-pro'); ?> /wp-admin/admin-ajax.php?action=duplicator_pro_package_scan<br>
<?php esc_html_e('Scan Path:', 'duplicator-pro'); ?> [<?php echo duplicator_pro_get_home_path(); ?>]<br><br>
<b><?php esc_html_e('More Information:', 'duplicator-pro'); ?></b><br>
<?php
printf(
__(
'Please see the online FAQ titled %1$s"How to resolve scanner warnings/errors and timeout issues?"%2$s',
'duplicator-pro'
),
'<a href="' . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-resolve-scanner-warnings-errors-and-timeout-issues" target="_blank">',
'</a>'
);

View File

@@ -0,0 +1,140 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Views\UserUIOptions;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$uiOpts = UserUIOptions::getInstance();
$perPage = $uiOpts->get(UserUIOptions::VAL_PACKAGES_PER_PAGE);
$dateFormat = $uiOpts->get(UserUIOptions::VAL_CREATED_DATE_FORMAT);
$showNote = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_NOTE);
$showSize = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_SIZE);
$showCreated = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_CREATED);
$showAge = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_AGE);
?>
<fieldset class="metabox-prefs">
<legend>Columns</legend>
<label>
<input
class="dup-hide-column-tog"
name="dup-note-hide"
type="checkbox"
id="dup-note-hide"
value="1"
<?php checked($showNote); ?>
data-target-colum="dup-note-column"
>
<?php esc_html_e('Note', 'duplicator-pro'); ?>
</label>
<label>
<input
class="dup-hide-column-tog"
name="dup-size-hide"
type="checkbox"
id="dup-size-hide"
value="1" <?php checked($showSize); ?>
data-target-colum="dup-size-column"
>
<?php esc_html_e('Size', 'duplicator-pro'); ?>
</label>
<label>
<input
class="dup-hide-column-tog"
name="dup-created-hide"
type="checkbox"
id="dup-created-hide"
value="1"
<?php checked($showCreated); ?>
data-target-colum="dup-created-column"
>
<?php esc_html_e('Created', 'duplicator-pro'); ?>
</label>
<label>
<input
class="dup-hide-column-tog"
name="dup-age-hide"
type="checkbox"
id="dup-age-hide"
value="1"
<?php checked($showAge); ?>
data-target-colum="dup-age-column"
>
<?php esc_html_e('Age', 'duplicator-pro'); ?>
</label>
</fieldset>
<fieldset class="screen-options" >
<legend>Pagination</legend>
<label for="duplicator_pro_opts_per_page">Packages Per Page</label>
<input
type="number"
step="1"
min="1"
max="999"
class="screen-per-page"
name="duplicator_pro_opts_per_page"
id="duplicator_pro_opts_per_page"
maxlength="3"
value="<?php echo esc_html($perPage); ?>"
>
</fieldset>
<fieldset class="screen-options">
<legend>Created Format</legend>
<div class="metabox-prefs">
<input type="hidden" name="wp_screen_options[option]" value="package_screen_options">
<input type="hidden" name="wp_screen_options[value]" value="val">
<div class="created-format-wrapper">
<select name="duplicator_pro_created_format">
<!-- YEAR -->
<optgroup label="By Year">
<option value="1" <?php selected($dateFormat, 1); ?> >Y-m-d H:i &nbsp; [2000-01-05 12:00]</option>
<option value="2" <?php selected($dateFormat, 2); ?> >Y-m-d H:i:s [2000-01-05 12:00:01]</option>
<option value="3" <?php selected($dateFormat, 3); ?> >y-m-d H:i &nbsp; [00-01-05 12:00]</option>
<option value="4" <?php selected($dateFormat, 4); ?> >y-m-d H:i:s [00-01-05 12:00:01]</option>
</optgroup>
<!-- MONTH -->
<optgroup label="By Month">
<option value="5" <?php selected($dateFormat, 5); ?> >m-d-Y H:i &nbsp; [01-05-2000 12:00]</option>
<option value="6" <?php selected($dateFormat, 6); ?> >m-d-Y H:i:s [01-05-2000 12:00:01]</option>
<option value="7" <?php selected($dateFormat, 7); ?> >m-d-y H:i &nbsp; [01-05-00 12:00]</option>
<option value="8" <?php selected($dateFormat, 8); ?> >m-d-y H:i:s [01-05-00 12:00:01]</option>
</optgroup>
<!-- DAY -->
<optgroup label="By Day">
<option value="9" <?php selected($dateFormat, 9); ?> > d-m-Y H:i &nbsp; [05-01-2000 12:00]</option>
<option value="10" <?php selected($dateFormat, 10); ?> >d-m-Y H:i:s [05-01-2000 12:00:01]</option>
<option value="11" <?php selected($dateFormat, 11); ?> >d-m-y H:i &nbsp; [05-01-00 12:00]</option>
<option value="12" <?php selected($dateFormat, 12); ?> >d-m-y H:i:s [05-01-00 12:00:01]</option>
</optgroup>
</select>
</div>
</div>
</fieldset>
<p class="submit">
<input type="submit" name="screen-options-apply" id="screen-options-apply" class="button button-primary" value="Apply">
</p>
<script>
jQuery(document).ready(function($) {
$('.dup-hide-column-tog').on('change', function() {
let node = $(this);
let columns = $('.' + node.data('target-colum'));
if (node.is(':checked')) {
columns.show();
} else {
columns.hide();
}
});
});
</script>

View File

@@ -0,0 +1,105 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\SettingsPageController;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$dbbuild_mode = DUP_PRO_DB::getBuildMode();
$settingsPackageUrl = SettingsPageController::getInstance()->getMenuLink(SettingsPageController::L2_SLUG_PACKAGE);
?>
<div class="filter-db-tab-content">
<?php $tplMng->render('parts/filters/tables_list_filter'); ?>
<br/><br/>
<div class="dup-package-hdr-1">
<?php esc_html_e("Configuration", 'duplicator-pro') ?>
</div>
<div class="dup-form-item">
<span class="title"><?php esc_html_e("SQL Mode", 'duplicator-pro') ?>:</span>
<span class="input">
<a href="<?php echo esc_url($settingsPackageUrl); ?>" target="settings">
<?php echo esc_html($dbbuild_mode); ?>
</a>
</span>
</div>
<div class="dup-form-item">
<span class="title">
<?php esc_html_e("Compatibility Mode", 'duplicator-pro') ?>:
<?php
$tipCont = __(
'This is an advanced database backwards compatibility feature that should ONLY be used if having problems installing packages.
If the database server version is lower than the version where the package was built then these options may help generate
a script that is more compliant with the older database server. It is recommended to try each option separately starting with mysql40.',
'duplicator-pro'
);
?>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Compatibility Mode", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipCont); ?>">
</i>
</span>
</div>
<?php
if ($dbbuild_mode == 'MYSQLDUMP') :?>
<?php
$modes = isset($Package) ? explode(',', $Package->Database->Compatible) : array();
$is_mysql40 = in_array('mysql40', $modes);
$is_no_table = in_array('no_table_options', $modes);
$is_no_key = in_array('no_key_options', $modes);
$is_no_field = in_array('no_field_options', $modes);
?>
<div class="dup-form-horiz-opts">
<span>
<input type="checkbox" name="dbcompat[]" id="dbcompat-mysql40" value="mysql40" <?php echo $is_mysql40 ? 'checked="true"' : ''; ?> >
<label for="dbcompat-mysql40"><?php esc_html_e("mysql40", 'duplicator-pro') ?></label>
</span>
<span>
<input
type="checkbox"
name="dbcompat[]"
id="dbcompat-no_table_options"
value="no_table_options"
<?php echo $is_no_table ? 'checked="true"' : ''; ?>
>
<label for="dbcompat-no_table_options"><?php esc_html_e("no_table_options", 'duplicator-pro') ?></label>
</span>
<span>
<input type="checkbox" name="dbcompat[]" id="dbcompat-no_key_options" value="no_key_options" <?php echo $is_no_key ? 'checked="true"' : ''; ?>>
<label for="dbcompat-no_key_options"><?php esc_html_e("no_key_options", 'duplicator-pro') ?></label>
</span>
<span>
<input
type="checkbox"
name="dbcompat[]"
id="dbcompat-no_field_options"
value="no_field_options"
<?php echo $is_no_field ? 'checked="true"' : ''; ?>
>
<label for="dbcompat-no_field_options"><?php esc_html_e("no_field_options", 'duplicator-pro') ?></label>
</span>
</div>
<div class="dup-tabs-opts-help">
<?php esc_html_e("Compatibility mode settings are not persistent. They must be enabled with every new build.", 'duplicator-pro'); ?>&nbsp;
<a href="<?php echo esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-fix-database-write-issues');?>" target="_blank">
[<?php esc_html_e('full overview', 'duplicator-pro'); ?>]
</a>
</div>
<?php else :?>
&nbsp; &nbsp; <i><?php esc_html_e("This option is only available with mysqldump mode.", 'duplicator-pro'); ?></i>
<?php endif; ?>
<br/>
</div>

View File

@@ -0,0 +1,27 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Libs\Snap\SnapIO;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<div class="filter-files-tab-content">
<?php
$uploads = wp_upload_dir();
$upload_dir = SnapIO::safePath($uploads['basedir']);
$content_path = defined('WP_CONTENT_DIR') ? SnapIO::safePath(WP_CONTENT_DIR) : '';
?>
<?php $tplMng->render('parts/filters/package_components'); ?>
</div>

View File

@@ -0,0 +1,118 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\License\License;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (!is_multisite()) {
return;
}
?>
<div class="filter-mu-tab-content <?php echo (License::can(License::CAPABILITY_MULTISITE_PLUS) ? '' : 'disabled');?>" >
<div style="max-width:900px">
<?php if (!License::can(License::CAPABILITY_MULTISITE_PLUS)) { ?>
<div class="dpro-panel-optional-txt alert-disabled" style="text-align: center">
<b><?php esc_html_e("Notice:", 'duplicator-pro'); ?></b>
<?php
printf(
esc_html__(
'This option isn\'t available at the %1$s license level.',
'duplicator-pro'
),
esc_html(License::getLicenseToString())
);
?>
<br>
<?php
printf(
esc_html_x(
'To enable this option %1$supgrade%2$s the License.',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . esc_url(License::getUpsellURL()) . '" target="_blank">',
'</a>'
);
?>
</div>
<?php } ?>
<?php
echo '<b>' . esc_html__("Overview:", 'duplicator-pro') . '</b><br/>';
esc_html_e(
"When you want to move a full multisite network or convert a subsite to a standalone site just
create a standard package like you would with a single site.
Then browse to the installer and choose either 'Restore entire multisite network' or 'Convert subsite into a standalone site'.
These options will be present on Step 1 of the installer when restoring a Multisite package.",
'duplicator-pro'
);
?>
</div>
<table class="mu-opts">
<tr>
<td>
<b><?php esc_html_e("Included Sub-Sites", 'duplicator-pro'); ?>:</b><br/>
<select name="mu-include[]" id="mu-include" multiple="true" class="mu-selector">
<?php
$subsites = License::can(License::CAPABILITY_MULTISITE_PLUS) ? DUP_PRO_MU::getSubsites() : array();
foreach ($subsites as $site) {
echo "<option value='" . (int) $site->id . "'>" . esc_html($site->domain . $site->path) . "</option>";
}
?>
</select>
</td>
<td>
<button type="button" id="mu-exclude-btn" class="mu-push-btn"><i class="fa fa-chevron-right"></i></button>
<br/>
<button type="button" id="mu-include-btn" class="mu-push-btn"><i class="fa fa-chevron-left"></i></button>
</td>
<td>
<b><?php esc_html_e("Excluded Sub-Sites", 'duplicator-pro'); ?>:</b><br/>
<select name="mu-exclude[]" id="mu-exclude" multiple="true" class="mu-selector"></select>
</td>
</tr>
</table>
<div class="dpro-panel-optional-txt" style="text-align: left">
<?php
echo wp_kses(
__(
"<u><b>Important:</b></u> Full network restoration is an installer option only if you include <b>all</b> subsites.
If any subsites are filtered then you may only restore individual subsites as standalones sites at install-time.",
'duplicator-pro'
),
array(
'b' => array(),
'u' => array(),
)
);
?>
<br/>
<br/>
<?php
esc_html_e(
"This section allows you to control which sub-sites of a multisite network you want to include within your package.
The 'Included Sub-Sites' will also be available to choose from at install time.",
'duplicator-pro'
);
?>
<br/>
<?php
esc_html_e(
"By default all packages are included. The ability to exclude sub-sites are intended to help shrink your package if needed.",
'duplicator-pro'
);
?>
</div>
</div>

View File

@@ -0,0 +1,163 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Installer\Package\ArchiveDescriptor;
use Duplicator\Package\SettingsUtils;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$secureOn = (isset($tplData['secureOn']) ? $tplData['secureOn'] : ArchiveDescriptor::SECURE_MODE_NONE);
$securePass = (isset($tplData['securePass']) ? $tplData['securePass'] : '');
$unavaliableMessage = '';
$encryptAvaliable = SettingsUtils::isArchiveEncryptionAvailable($unavaliableMessage);
?>
<div class="archive-setup-tab" >
<div class="dup-package-hdr-1">
<?php esc_html_e('Security', 'duplicator-pro'); ?>
</div>
<div class="dup-form-item">
<span class="title">
<?php esc_html_e('Mode', 'duplicator-pro') ?>:
</span>
<div class="input">
<span class="secure-on-input-wrapper">
<label class="margin-right-1" >
<input
type="radio"
name="secure-on"
id="secure-on-none"
onclick="DupPro.EnableInstallerPassword()"
required
value="<?php echo (int) ArchiveDescriptor::SECURE_MODE_NONE; ?>"
<?php checked($secureOn, ArchiveDescriptor::SECURE_MODE_NONE); ?>
data-parsley-multiple="secure-on-mltiple-error"
data-parsley-errors-container="#secure-on-parsely-error"
>
<?php esc_html_e('None', 'duplicator-pro') ?>
</label>
<label class="margin-right-1" >
<input
type="radio"
name="secure-on"
id="secure-on-inst-pwd"
value="<?php echo (int) ArchiveDescriptor::SECURE_MODE_INST_PWD; ?>"
<?php checked($secureOn, ArchiveDescriptor::SECURE_MODE_INST_PWD); ?>
onclick="DupPro.EnableInstallerPassword()"
data-parsley-multiple="secure-on-mltiple-error"
>
<?php esc_html_e('Installer password', 'duplicator-pro') ?>
</label>
<label <?php echo ($encryptAvaliable ? '' : 'class="silver"'); ?>>
<input
type="radio"
name="secure-on"
id="secure-on-arc-encrypt"
value="<?php echo (int) ArchiveDescriptor::SECURE_MODE_ARC_ENCRYPT; ?>"
<?php echo ($encryptAvaliable ? checked($secureOn, ArchiveDescriptor::SECURE_MODE_ARC_ENCRYPT, false) : ''); ?>
onclick="DupPro.EnableInstallerPassword()"
<?php disabled(!$encryptAvaliable); ?>
data-parsley-multiple="secure-on-mltiple-error"
>
<?php esc_html_e('Archive encryption', 'duplicator-pro') ?>
</label>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e('Security', 'duplicator-pro'); ?>"
data-tooltip="<?php $tplMng->renderEscAttr('admin_pages/packages/setup/security-tooltip-content'); ?>">
</i>
</span>
<div id="secure-on-parsely-error"></div>
</div>
</div>
<div class="dup-form-item">
<span class="title">
<?php esc_html_e('Password', 'duplicator-pro') ?>:
</span>
<div class="input">
<span class="dup-password-toggle">
<input
id="secure-pass"
type="password"
name="secure-pass"
required="required"
size="50"
maxlength="150"
value="<?php echo esc_attr($securePass); ?>"
>
<button type="button" >
<i class="fas fa-eye fa-sm"></i>
</button>
</span>
<div class="input dup-tabs-opts-help-secure-pass">
<?php
esc_html_e(
'Caution: Passwords are case-sensitive and if lost cannot be recovered. Please keep passwords in a safe place!',
'duplicator-pro'
);
echo '<br/>';
esc_html_e(
'If this password is lost then a new archive file will need to be created.',
'duplicator-pro'
);
?>
</div>
</div>
</div>
<?php if (!$encryptAvaliable) { ?>
<div class="dup-form-item">
<span class="title">
&nbsp;
</span>
<span class="input dup-tabs-opts-notice">
<i>
<i class="fas fa-exclamation-triangle fa-xs"></i>
<?php
echo esc_html__("The security mode 'Archive encryption' option above is currently disabled on this server.", 'duplicator-pro') . '<br>'
. esc_html($unavaliableMessage);
?>
</i>
</span>
</div>
<?php } ?>
</div>
<script>
jQuery(function($) {
DupPro.EnableInstallerPassword = function () {
let $button = $('#secure-btn');
let secureOnVal = $('.secure-on-input-wrapper input:checked').val();
if (secureOnVal == <?php echo json_encode(ArchiveDescriptor::SECURE_MODE_NONE); ?>) {
$('#secure-pass').removeAttr('required');
$('#secure-pass').attr('readonly', true);
$('#dpro-install-secure-lock').hide();
$button.prop('disabled', true);
} else {
$('#secure-pass').attr('readonly', false);
$('#secure-pass').attr('required', 'true').focus();
$('#dpro-install-secure-lock').show();
$button.prop('disabled', false);
}
};
$('#secure-on-none').parsley().on('field:error', function() {
$('.archive-setup-tab button').trigger('click');
$('html,body').animate({scrollTop: $(".archive-setup-tab").offset().top - 30},'slow');
});
});
</script>

View File

@@ -0,0 +1,60 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Installer\Core\Descriptors\ArchiveConfig;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
echo esc_html(
__('When enabled the archive file will be encrypted with a password that is required to open.', 'duplicator-pro') . ' ' .
__('The installer will also prompt for the password at install time.', 'duplicator-pro') . ' ' .
__('Encryption is a general deterrent and should not be substituted for properly keeping your files secure.', 'duplicator-pro') . ' ' .
__('Be sure to remove all installer files when the install process is completed.', 'duplicator-pro')
);
?>
<ul>
<li>
<b>
<?php esc_html_e('None:', 'duplicator-pro'); ?>
</b>
<?php esc_html_e(
"No protection system activated! The installer or archive files can be accessed by any resource that knows the full URL to either file.",
'duplicator-pro'
); ?>
</li>
<li>
<b>
<?php esc_html_e('Installer password:', 'duplicator-pro'); ?>
</b>
<?php esc_html_e(
'The archive is NOT encrypted. When the installer starts, it will prompt for a password to prevent anyone from running the installer.',
'duplicator-pro'
); ?>
</li>
<li>
<b>
<?php esc_html_e('Archive encryption:', 'duplicator-pro'); ?>
</b>
<?php
esc_html_e(
'The archive IS encrypted with a password, and the installer will ask for a password when started.',
'duplicator-pro'
);
esc_html_e(
'This option is the recommended maximum level of security.',
'duplicator-pro'
);
?>
</li>
</ul>

View File

@@ -0,0 +1,123 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\ImportPageController;
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$settingsUrl = esc_url($ctrlMng->getMenuLink($ctrlMng::SETTINGS_SUBMENU_SLUG, SettingsPageController::L2_SLUG_PACKAGE));
$templateUrl = esc_url($ctrlMng->getMenuLink($ctrlMng::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_TEMPLATE));
$recoveryUrl = esc_url($ctrlMng->getMenuLink($ctrlMng::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_RECOVERY));
?>
<input type="hidden" id="action" name="action" />
<input type="hidden" id="action-parameter" name="action-parameter" />
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar">
<tr>
<td>
<label for="dup-pack-bulk-actions" class="screen-reader-text">Select bulk action</label>
<select id="dup-pack-bulk-actions">
<option value="-1" selected="selected">
<?php esc_html_e("Bulk Actions", 'duplicator-pro') ?>
</option>
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<option value="delete" title="<?php esc_attr_e("Delete selected package(s)", 'duplicator-pro') ?>">
<?php esc_html_e("Delete", 'duplicator-pro') ?>
</option>
<?php } ?>
</select>
<input type="button" id="dup-pack-bulk-apply" class="button action"
value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>"
onclick="DupPro.Pack.ConfirmDelete()" />
<span class="btn-separator"></span>
<span class="button grey-icon dup-contextual-help"
title="<?php esc_attr_e("Tutorial", 'duplicator-pro') ?>"
onclick="DupPro.Pack.openLinkDetails()">
<i class="far fa-lightbulb fa-fw"></i>
</span>
<?php if (CapMng::can(CapMng::CAP_SETTINGS, false)) { ?>
<a href="<?php echo esc_url($settingsUrl); ?>"
class="button grey-icon dpro-toolbar-settings"
title="<?php esc_attr_e("Package Settings", 'duplicator-pro') ?>" >
<i class="fas fa-sliders-h fa-fw"></i>
</a>
<?php } ?>
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<a href="<?php echo esc_url($templateUrl); ?>"
class="button dpro-toolbar-templates"
title="<?php esc_attr_e("Templates", 'duplicator-pro') ?>" >
<i class="far fa-clone fa-fw"></i>
</a>
<?php } ?>
<span class="btn-separator"></span>
<?php if (CapMng::can(CapMng::CAP_IMPORT, false)) { ?>
<a href="<?php echo esc_url(ImportPageController::getImportPageLink()); ?>"
id="btn-logs-dialog"
class="button dpro-toolbar-import"
title="<?php esc_attr_e("Import", 'duplicator-pro') ?>">
<i class="fas fa-arrow-alt-circle-down fa-fw"></i>
</a>
<?php } ?>
<?php if (CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) { ?>
<span
class="dpro-toolbar-recovery-info button <?php echo (RecoveryPackage::getRecoverPackageId() === false ? 'dup-recovery-unset' : ''); ?>"
title="<?php esc_attr_e("Disaster Recovery", 'duplicator-pro') ?>"
>
<?php ViewHelper::disasterIcon(); ?>
</span>
<?php } ?>
</td>
<td>
<?php
if (CapMng::can(CapMng::CAP_CREATE, false)) {
$tipContent = __(
'This will create a new package. If a package is currently running then this button will be disabled.',
'duplicator-pro'
);
?>
<div class="btnnav">
<span
class="dup-new-package-wrapper"
data-tooltip-title="<?php esc_attr_e('Package creation', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>"
>
<a
href="<?php echo esc_url(PackagesPageController::getInstance()->getPackageBuildS1Url()); ?>"
id="dup-pro-create-new"
class="button <?php echo DUP_PRO_Package::isPackageRunning() ? 'disabled' : ''; ?>"
>
<?php esc_html_e('Create New', 'duplicator-pro'); ?>
</a>
</span>
</div>
<?php } ?>
</td>
</tr>
</table>

View File

@@ -0,0 +1,640 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\SchedulePageController;
use Duplicator\Controllers\StoragePageController;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Libs\Snap\SnapJson;
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Models\Storages\StoragesUtil;
use Duplicator\Views\ViewHelper;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var DUP_PRO_Schedule_Entity $schedule
* @var bool $blur
*/
$blur = $tplData['blur'];
$schedule = $tplData['schedule'];
$copyScheduleList = DUP_PRO_Schedule_Entity::getAll(
0,
0,
null,
function (DUP_PRO_Schedule_Entity $s) use ($schedule) {
return $s->getId() != $schedule->getId();
}
);
$templatesPageUrl = ToolsPageController::getInstance()->getMenuLink(ToolsPageController::L2_SLUG_TEMPLATE);
$schedulesListURL = ControllersManager::getMenuLink(
ControllersManager::SCHEDULES_SUBMENU_SLUG
);
$scheduleCopyBaseURL = SchedulePageController::getInstance()->getCopyActionUrl($schedule->getId());
$frequency_note = __(
'If you have a large site, it\'s recommended you schedule backups during lower traffic periods.
If you\'re on a shared host then be aware that running multiple schedules too close together
(i.e. every 10 minutes) may alert your host to a spike in system resource usage.
Be sure that your schedules do not overlap and give them plenty of time to run.',
'duplicator-pro'
);
$editTemplateUrl = ControllersManager::getMenuLink(
ControllersManager::TOOLS_SUBMENU_SLUG,
ToolsPageController::L2_SLUG_TEMPLATE,
null,
array(ControllersManager::QUERY_STRING_INNER_PAGE => 'edit')
);
$min_frequency = 0;
$max_frequency = (
License::can(License::CAPABILITY_SHEDULE_HOURLY) ?
DUP_PRO_Schedule_Entity::REPEAT_HOURLY :
DUP_PRO_Schedule_Entity::REPEAT_MONTHLY
);
$frequencyUpgradMsg = sprintf(
__(
'Hourly frequency isn\'t available at the <b>%1$s</b> license level.',
'duplicator-pro'
),
License::getLicenseToString()
) .
' <b>' .
sprintf(
_x(
'To enable this option %1$supgrade%2$s the License.',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . esc_url(License::getUpsellURL()) . '" target="_blank">',
'</a>'
) .
'</b>';
$langLocalDefaultMsg = __('Recovery Point Capable', 'duplicator-pro');
?>
<form
id="dup-schedule-form"
class="dup-monitored-form <?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>"
method="post"
data-parsley-ui-enabled="true"
>
<?php $tplData['actions'][SchedulePageController::ACTION_EDIT_SAVE]->getActionNonceFileds(); ?>
<input type="hidden" name="schedule_id" value="<?php echo esc_attr($schedule->getId()); ?>">
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar dup-schedule-edit-toolbar">
<tr>
<td>
<select id="dup-schedule-copy-select" name="duppro-source-schedule-id">
<option value="-1" selected="selected">
<?php esc_html_e('Copy From', 'duplicator-pro'); ?>
</option>
<?php foreach ($copyScheduleList as $copy_schedule) { ?>
<option value="<?php echo (int) $copy_schedule->getId(); ?>">
<?php echo esc_html($copy_schedule->name); ?>
</option>
<?php } ?>
</select>
<input
id="dup-schedule-copy-btn"
type="button"
class="button action"
value="<?php esc_html_e("Apply", 'duplicator-pro') ?>"
disabled
>
</td>
<td>
<div class="btnnav">
<a href="<?php echo esc_url($schedulesListURL); ?>" class="button dup-schedule-schedules">
<i class="far fa-clock fa-sm"></i> <?php esc_html_e('Schedules', 'duplicator-pro'); ?>
</a>
<?php if ($schedule->getId() != -1) : ?>
<a
href="<?php echo esc_url(SchedulePageController::getInstance()->getEditUrl()); ?>"
class="button"
>
<?php esc_html_e("Add New", 'duplicator-pro'); ?>
</a>
<?php endif; ?>
</div>
</td>
</tr>
</table>
<hr class="dpro-edit-toolbar-divider" />
<!-- ===============================
SETTINGS -->
<table class="form-table">
<tr valign="top">
<th scope="row"><label><?php esc_html_e('Schedule Name', 'duplicator-pro'); ?></label></th>
<td>
<input
type="text"
id="schedule-name"
name="name"
value="<?php echo esc_attr($schedule->name); ?>"
required data-parsley-group="standard"
autocomplete="off"
>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e('Package Template', 'duplicator-pro'); ?></label></th>
<td>
<table class="schedule-template">
<tr>
<td>
<select id="schedule-template-selector" name="template_id" required>
<?php
$templates = DUP_PRO_Package_Template_Entity::getAllWithoutManualMode();
if (count($templates) == 0) {
$no_templates = __('No Templates Found', 'duplicator-pro');
printf('<option value="">%1$s</option>', esc_html($no_templates));
} else {
echo "<option value='' selected='true'>" . esc_html__("&lt;Choose A Template&gt;", 'duplicator-pro') . "</option>";
foreach ($templates as $template) {
?>
<option
<?php selected($schedule->template_id, $template->getId()); ?>
value="<?php echo (int) $template->getId(); ?>"
>
<?php echo esc_html($template->name); ?>
</option>
<?php
}
}
?>
</select>
<br />
<small>
<a href="<?php echo esc_url($templatesPageUrl); ?>" target="edit-template">
[<?php esc_attr_e("Show All Templates", 'duplicator-pro') ?>]
</a>
</small>
</td>
<td>
<a
id="schedule-template-edit-btn"
href="javascript:void(0)"
onclick="DupPro.Schedule.EditTemplate()"
style="display:none"
class="pack-temp-btns button button-small"
title="<?php esc_attr_e("Edit Selected Template", 'duplicator-pro') ?>"
>
<i class="far fa-edit"></i>
</a>
<a
id="schedule-template-add-btn"
href="<?php echo esc_url($editTemplateUrl); ?>"
class="pack-temp-btns button button-small"
title="<?php esc_attr_e("Add New Template", 'duplicator-pro') ?>"
target="edit-template"
>
<i class="far fa-plus-square"></i>
</a>
<a
id="schedule-template-sync-btn"
href="javascript:window.location.reload()"
class="pack-temp-btns button button-small"
title="<?php esc_attr_e("Refresh Template List", 'duplicator-pro') ?>"
>
<i class="fas fa-sync-alt"></i>
</a>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Template Details", 'duplicator-pro'); ?>"
data-tooltip="<?php
esc_attr_e(
'The template specifies which files and database tables should be included in the archive.<br/><br/>
Choose from an existing template or create a new one by clicking the "Add New Template" button.
To edit a template, select it and then click the "Edit Selected Template" button.',
'duplicator-pro'
);
?>">
</i>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e('Storage', 'duplicator-pro'); ?></label></th>
<td>
<!-- ===============================
STORAGE -->
<table class="widefat package-tbl schedule-package-tbl">
<thead>
<tr>
<th style="width:125px;padding-left:45px"><?php esc_html_e('Type', 'duplicator-pro') ?></th>
<th style="width:275px;"><?php esc_html_e('Name', 'duplicator-pro') ?></th>
<th><?php esc_html_e('Location', 'duplicator-pro') ?></th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
$storages = AbstractStorageEntity::getAll(0, 0, [StoragesUtil::class, 'sortByPriority']);
foreach ($storages as $storage) :
//Sometime storage is authorized
// then server downgrade to lower php version
// For ex. When storage is added PHP CURL extension enabled
// But now It is disabled, It cause to fatal error
// in the Package creation step 1
if (!$storage->isSupported()) {
continue;
}
$i++;
$is_valid = $storage->isValid();
$is_checked = in_array($storage->getId(), $schedule->storage_ids);
$mincheck = ($i == 1) ? 'data-parsley-mincheck="1" data-parsley-required="true"' : '';
$lbl_id = "storage_chk_{$storage->getId()}";
$storageEditUrl = StoragePageController::getEditUrl($storage);
?>
<tr class="package-row <?php echo ($i % 2) ? 'alternate' : ''; ?>">
<td>
<input data-parsley-errors-container="#schedule_storage_error_container" <?php echo $mincheck ?>
id="<?php echo esc_attr($lbl_id); ?>" name="_storage_ids[]"
type="checkbox" value="<?php echo (int) $storage->getId(); ?>"
<?php checked($is_checked); ?> class="delete-chk" /> &nbsp; &nbsp;
<label for="<?php echo esc_attr($lbl_id); ?>">
<?php
echo $storage->getStypeIcon() . '&nbsp;' . esc_html($storage->getStypeName());
echo ($storage->isLocal())
? "<sup title='" . esc_attr($langLocalDefaultMsg) . "'>" . ViewHelper::disasterIcon(false, ['fa-fw', 'fa-sm'])
. "</sup>"
: '';
?>
</label>
</td>
<td>
<a href="<?php echo esc_url($storageEditUrl); ?>" target="_blank">
<?php
echo ($is_valid == false) ? '<i class="fa fa-exclamation-triangle fa-sm"></i> ' : '';
echo esc_html($storage->getName());
?>
</a>
</td>
<td><?php echo $storage->getHtmlLocationLink(); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div id="schedule_storage_error_container" class="duplicator-error-container"></div>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Repeats", 'duplicator-pro'); ?></label></th>
<td>
<select
id="change-mode"
name="repeat_type"
onchange="DupPro.Schedule.ChangeMode()"
data-parsley-range='<?php printf('[%1$s, %2$s]', (int) $min_frequency, (int) $max_frequency); ?>'
data-parsley-error-message="<?php echo esc_attr($frequencyUpgradMsg); ?>"
>
<option
value="<?php echo (int) DUP_PRO_Schedule_Entity::REPEAT_HOURLY; ?>"
<?php selected($schedule->repeat_type, DUP_PRO_Schedule_Entity::REPEAT_HOURLY) ?>
>
<?php esc_html_e("Hourly", 'duplicator-pro'); ?>
</option>
<option
value="<?php echo (int) DUP_PRO_Schedule_Entity::REPEAT_DAILY; ?>"
<?php selected($schedule->repeat_type, DUP_PRO_Schedule_Entity::REPEAT_DAILY) ?>
>
<?php esc_html_e("Daily", 'duplicator-pro'); ?>
</option>
<option
value="<?php echo (int) DUP_PRO_Schedule_Entity::REPEAT_WEEKLY; ?>"
<?php selected($schedule->repeat_type, DUP_PRO_Schedule_Entity::REPEAT_WEEKLY) ?>
>
<?php esc_html_e("Weekly", 'duplicator-pro'); ?>
</option>
<option
value="<?php echo (int) DUP_PRO_Schedule_Entity::REPEAT_MONTHLY; ?>"
<?php selected($schedule->repeat_type, DUP_PRO_Schedule_Entity::REPEAT_MONTHLY) ?>
>
<?php esc_html_e("Monthly", 'duplicator-pro'); ?>
</option>
</select>
</td>
</tr>
<tr>
<th></th>
<td style="padding-top:0px; padding-bottom:10px;">
<!-- ===============================
DAILY -->
<div id="repeat-hourly-area" class="repeater-area">
<?php
esc_html_e('Every', 'duplicator-pro');
$hour_intervals = array(
1,
2,
4,
6,
12,
);
?>
<select name="_run_every_hours" data-parsley-ui-enabled="false">
<?php foreach ($hour_intervals as $hour_interval) { ?>
<option <?php selected($hour_interval, (int) $schedule->run_every); ?> value="<?php echo (int) $hour_interval; ?>">
<?php echo (int) $hour_interval; ?>
</option>
<?php } ?>
</select>
<?php
esc_html_e('hours', 'duplicator-pro');
$tipContent = __('Package will build every x hours starting at 00:00.', 'duplicator-pro') . '<br/><br/>' . $frequency_note;
?>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Frequency Note", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>"
>
</i>
<br />
</div>
<!-- ===============================
DAILY -->
<div id="repeat-daily-area" class="repeater-area">
<?php esc_html_e('Every', 'duplicator-pro'); ?>
<select name="_run_every_days" data-parsley-ui-enabled="false">
<?php for ($i = 1; $i < 30; $i++) { ?>
<option <?php selected($i, (int) $schedule->run_every); ?> value="<?php echo (int) $i; ?>">
<?php echo (int) $i; ?>
</option>
<?php } ?>
</select>
<?php esc_html_e('days', 'duplicator-pro'); ?>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Frequency Note", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($frequency_note) ?>"
>
</i>
<br />
</div>
<!-- ===============================
WEEKLY -->
<div id="repeat-weekly-area" class="repeater-area">
<!-- RSR Cron does not support counting by week - just days and months so removing (for now?)-->
<div class="weekday-div">
<input
<?php checked($schedule->is_day_set('mon')); ?>
value="mon" name="weekday[]"
type="checkbox"
id="repeat-weekly-mon"
data-parsley-group="weekly" required data-parsley-class-handler="#repeat-weekly-area"
data-parsley-error-message="<?php esc_attr_e('At least one day must be checked.', 'duplicator-pro'); ?>"
data-parsley-no-focus data-parsley-errors-container="#weekday-errors"
>
<label for="repeat-weekly-mon"><?php esc_html_e('Monday', 'duplicator-pro'); ?></label>
</div>
<div class="weekday-div">
<input <?php checked($schedule->is_day_set('tue')); ?> value="tue" name="weekday[]" type="checkbox" id="repeat-weekly-tue" />
<label for="repeat-weekly-tue"><?php esc_html_e('Tuesday', 'duplicator-pro'); ?></label>
</div>
<div class="weekday-div">
<input <?php checked($schedule->is_day_set('wed')); ?> value="wed" name="weekday[]" type="checkbox" id="repeat-weekly-wed" />
<label for="repeat-weekly-wed"><?php esc_html_e('Wednesday', 'duplicator-pro'); ?></label>
</div>
<div class="weekday-div">
<input <?php checked($schedule->is_day_set('thu')); ?> value="thu" name="weekday[]" type="checkbox" id="repeat-weekly-thu" />
<label for="repeat-weekly-thu"><?php esc_html_e('Thursday', 'duplicator-pro'); ?></label>
</div>
<div class="weekday-div" style="clear:both">
<input <?php checked($schedule->is_day_set('fri')); ?> value="fri" name="weekday[]" type="checkbox" id="repeat-weekly-fri" />
<label for="repeat-weekly-fri"><?php esc_html_e('Friday', 'duplicator-pro'); ?></label>
</div>
<div class="weekday-div">
<input <?php checked($schedule->is_day_set('sat')); ?> value="sat" name="weekday[]" type="checkbox" id="repeat-weekly-sat" />
<label for="repeat-weekly-sat"><?php esc_html_e('Saturday', 'duplicator-pro'); ?></label>
</div>
<div class="weekday-div">
<input <?php checked($schedule->is_day_set('sun')); ?> value="sun" name="weekday[]" type="checkbox" id="repeat-weekly-sun" />
<label for="repeat-weekly-sun"><?php esc_html_e('Sunday', 'duplicator-pro'); ?></label>
</div>
</div>
<div style="padding-top:3px; clear:both;" id="weekday-errors"></div>
<!-- ===============================
MONTHLY -->
<div id="repeat-monthly-area" class="repeater-area">
<div style="float:left; margin-right:5px;"><?php esc_html_e('Day', 'duplicator-pro'); ?>
<select name="day_of_month">
<?php for ($i = 1; $i <= 31; $i++) { ?>
<option <?php selected($i, $schedule->day_of_month); ?> value="<?php echo (int) $i; ?>">
<?php echo (int) $i; ?>
</option>
<?php } ?>
</select>
</div>
<div style="display:inline-block">
<?php esc_html_e('of every', 'duplicator-pro'); ?>
<select name="_run_every_months" data-parsley-ui-enabled="false">
<?php for ($i = 1; $i <= 12; $i++) { ?>
<option <?php selected($i, $schedule->run_every); ?> value="<?php echo (int) $i; ?>">
<?php echo (int) $i; ?>
</option>
<?php } ?>
</select>
<?php esc_html_e('month(s)', 'duplicator-pro'); ?>
</div>
</div>
</td>
</tr>
<tr valign="top" id="start-time-row">
<th scope="row"><label><?php esc_html_e('Start Time', 'duplicator-pro'); ?></label></th>
<td>
<select name="_start_time" style="margin-top:-2px; height:27px">
<?php
$start_hour = $schedule->get_start_time_piece(0);
$start_min = $schedule->get_start_time_piece(1);
$mins = 0;
// Add setting to use 24 hour vs AM/PM
// the interval for hours is '1'
for ($hours = 0; $hours < 24; $hours++) {
?>
<option <?php selected($hours, $start_hour); ?> value="<?php echo (int) $hours; ?>">
<?php printf('%02d:%02d', (int) $hours, (int) $mins); ?>
</option>
<?php } ?>
</select>
<i class="dpro-edit-info">
<?php esc_html_e("Current Server Time Stamp is", 'duplicator-pro'); ?>&nbsp;
<?php echo esc_html(date_i18n('Y-m-d H:i:s')); ?>
</i>
</td>
</tr>
<tr>
<td>
</td>
<td>
<p class="description" style="width:800px">
<?php
printf(
esc_html_x(
'%1$sNote:%2$s Schedules require web site traffic in order to start a build.
If you set a start time of 06:00 daily but do not get any traffic till 10:00 then the build will not start until 10:00.
If you have low traffic consider setting up a cron job to periodically hit your site or
check out the free web monitoring tools found on our %3$spartners page%4$s.',
'%1$s and %2$s represent opening and closing bold tags, %3$s and %4$s represent opening and closing anchor tags',
'duplicator-pro'
),
'<b>',
'</b>',
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'what-services-and-products-complement-the-duplicator/')
. '" target="_blank">',
'</a>'
);
?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e('Recovery Status', 'duplicator-pro'); ?></label></th>
<td class="dup-recovery-template">
<?php
if (($template = $schedule->getTemplate()) !== false) {
$schedule->recoveableHtmlInfo();
} else {
esc_html_e('Unavailable', 'duplicator-pro');
?>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Recovery Status", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e('Status is unavailable. Please save the schedule to view recovery status', 'duplicator-pro');
?>"></i>
<?php } ?>
</td>
</tr>
<tr valign="top">
<th scope="row"><label for="schedule-active"><?php esc_html_e('Activated', 'duplicator-pro'); ?></label></th>
<td>
<input name="_active" id="schedule-active" type="checkbox" <?php checked($schedule->active); ?>>
<label for="schedule-active"><?php esc_html_e('Enable This Schedule', 'duplicator-pro'); ?></label><br />
<i class="dpro-edit-info"> <?php esc_html_e('When checked this schedule will run', 'duplicator-pro'); ?></i>
</td>
</tr>
</table><br />
<button
id="dup-pro-save-schedule"
class="button button-primary"
type="submit"
>
<?php esc_html_e('Save Schedule', 'duplicator-pro'); ?>
</button>
</form>
<script>
jQuery(document).ready(function ($) {
DupPro.Schedule.ChangeMode = function () {
var mode = $("#change-mode option:selected").val();
var animate = 400;
$('#repeat-hourly-area, #repeat-daily-area, #repeat-weekly-area, #repeat-monthly-area').hide();
n = $("#repeat-weekly-area input:checked").length;
if (n == 0) {
// Hack so parsely will ignore weekly if it isnt selected
$('#repeat-weekly-mon').prop("checked", true);
}
switch (mode) {
case "0":
$('#repeat-daily-area').show(animate);
$('#start-time-row').show(animate);
break;
case "1":
$('#repeat-weekly-area').show(animate);
$('#start-time-row').show(animate);
break;
case "2":
$('#repeat-monthly-area').show(animate);
$('#start-time-row').show(animate);
break;
case "3":
$('#repeat-hourly-area').show(animate);
$('#start-time-row').hide(animate);
break;
}
}
$('#dup-schedule-copy-select').on('change', function (e) {
let copyId = parseInt($(this).val());
$('#dup-schedule-copy-btn').prop('disabled', (copyId <= 0));
});
/*$('#dup-schedule-copy-select').change(function (evente) {
event.preventDefault();
alert('changed val ' + $(this).val());
$('#dup-schedule-copy-btn').prop('disabled', ($(this).val() > 0));
});*/
$('#dup-schedule-copy-btn').click(function (event) {
event.preventDefault();
let copyId = $('#dup-schedule-copy-select').val();
document.location.href = <?php echo json_encode($scheduleCopyBaseURL); ?> + '&duppro-source-schedule-id=' + copyId;
});
DupPro.Schedule.EditTemplate = function () {
var templateID = $('#schedule-template-selector').val();
var url = <?php echo SnapJson::jsonEncode($editTemplateUrl); ?> + '&package_template_id=' + templateID;
window.open(url, 'edit-template');
};
DupPro.Schedule.ToggleTemplateEditBtn = function () {
$('#schedule-template-edit-btn, #schedule-template-add-btn, #schedule-template-sync-btn').hide();
if ($("#schedule-template-selector").val() > 0) {
$('#schedule-template-edit-btn').show();
} else {
$('#schedule-template-add-btn, #schedule-template-sync-btn').show();
}
}
//INIT
$('#dup-schedule-form').parsley({
excluded: ':disabled'
});
$("#repeat-daily-date, #repeat-daily-on-date").datepicker({
showOn: "both",
buttonText: "<i class='fa fa-calendar'></i>"
});
DupPro.Schedule.ChangeMode();
jQuery('#schedule-name').focus().select();
DupPro.Schedule.ToggleTemplateEditBtn();
$("#schedule-template-selector").change(function () {
DupPro.Schedule.ToggleTemplateEditBtn()
});
});
</script>

View File

@@ -0,0 +1,617 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Ajax\ServicesSchedule;
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Controllers\SchedulePageController;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Libs\Snap\SnapJson;
use Duplicator\Models\Storages\AbstractStorageEntity;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $blur
*/
$blur = $tplData['blur'];
$active_schedules = DUP_PRO_Schedule_Entity::get_active();
$active_count = count($active_schedules);
$schedules = DUP_PRO_Schedule_Entity::getAll();
$schedule_count = DUP_PRO_Schedule_Entity::count();
$active_package = DUP_PRO_Package::get_next_active_package();
$active_schedule_id = -1;
if ($active_package != null) {
$active_schedule_id = $active_package->schedule_id;
}
$packagesPageUrl = PackagesPageController::getInstance()->getMenuLink();
$scheduleEditBaseURL = SchedulePageController::getInstance()->getEditBaseUrl();
$scheduleCopyBaseURL = SchedulePageController::getInstance()->getCopyActionUrl();
$settingsScheudleUrl = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_SCHEDULE
);
$templatesPageUrl = ToolsPageController::getInstance()->getMenuLink(ToolsPageController::L2_SLUG_TEMPLATE);
?>
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar <?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
<tr>
<td>
<select id="bulk_action">
<option value="-1" selected="selected">
<?php esc_html_e("Bulk Actions", 'duplicator-pro'); ?>
</option>
<option value="<?php echo (int) ServicesSchedule::SCHEDULE_BULK_ACTIVATE; ?>" title="Activate selected schedules(s)">
<?php esc_html_e("Activate", 'duplicator-pro'); ?>
</option>
<option value="<?php echo (int) ServicesSchedule::SCHEDULE_BULK_DEACTIVATE; ?>" title="Deactivate selected schedules(s)">
<?php esc_html_e("Deactivate", 'duplicator-pro'); ?>
</option>
<option value="<?php echo (int) ServicesSchedule::SCHEDULE_BULK_DELETE; ?>" title="Delete selected schedules(s)">
<?php esc_html_e("Delete", 'duplicator-pro'); ?>
</option>
</select>
<input
type="button"
id="dup-schedule-bulk-apply"
class="button action"
value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>"
onclick="DupPro.Schedule.BulkAction()"
>
<span class="btn-separator"></span>
<?php if (CapMng::can(CapMng::CAP_SETTINGS, false)) { ?>
<a
href="<?php echo esc_url($settingsScheudleUrl); ?>"
class="button grey-icon dup-schedule-settings"
title="<?php esc_attr_e("Settings", 'duplicator-pro') ?>"
>
<i class="fas fa-sliders-h fa-fw"></i>
</a>
<?php } ?>
<a
href="<?php echo esc_url($templatesPageUrl); ?>"
id="btn-logs-dialog"
class="button dup-schedule-templates"
title="<?php esc_attr_e("Templates", 'duplicator-pro') ?>"
>
<i class="far fa-clone"></i>
</a>
</td>
<td>
<div class="btnnav">
<a href="<?php echo esc_url($scheduleEditBaseURL); ?>" class="button dup-schedule-add-new">
<?php esc_attr_e("Add New", 'duplicator-pro'); ?>
</a>
</div>
</td>
</tr>
</table>
<form
id="dup-schedule-form"
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>"
method="post"
>
<input type="hidden" id="dup-schedule-form-action" name="action" value="" />
<input type="hidden" id="dup-schedule-selected-schedule" name="schedule_id" value="-1" />
<!-- ====================
LIST ALL SCHEDULES -->
<table class="widefat schedule-tbl">
<thead>
<tr>
<th style='width:10px;'><input type="checkbox" id="dpro-chk-all" title="Select all packages" onclick="DupPro.Schedule.SetDeleteAll(this)"></th>
<th style='width:255px;'><?php esc_html_e('Name', 'duplicator-pro'); ?></th>
<th><?php esc_html_e('Storage', 'duplicator-pro'); ?></th>
<th><?php esc_html_e('Runs Next', 'duplicator-pro'); ?></th>
<th><?php esc_html_e('Last Ran', 'duplicator-pro'); ?></th>
<th><?php esc_html_e('Active', 'duplicator-pro'); ?></th>
<th class="dup-col-recovery" ><?php esc_html_e('Recovery', 'duplicator-pro'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($schedule_count <= 0) : ?>
<tr>
<td colspan="7" class="dup-schedules-no-schedule">
<h2>
<i class="far fa-clock fa-sm"></i> <?php esc_html_e('No Schedules Found', 'duplicator-pro') ?> <br />
<a href="<?php echo esc_url($scheduleEditBaseURL); ?>">
[<?php esc_html_e('Create New Schedule', 'duplicator-pro') ?>]
</a>
</h2>
</td>
</tr>
<?php endif; ?>
<?php
$i = 0;
foreach ($schedules as $schedule) :
$i++;
$icon_display = (($schedule->getId() == $active_schedule_id) ? 'inline' : 'none');
?>
<tr class="schedule-row <?php echo ($i % 2) ? 'alternate' : ''; ?>">
<td>
<input name="selected_id[]" type="checkbox" value="<?php echo (int) $schedule->getId() ?>" class="item-chk" />
</td>
<td>
<i
id="<?php echo "icon-{" . (int) $schedule->getId() . "}-status"; ?>"
class="fas fa-cog fa-spin schedule-status-icon"
style="display:<?php echo esc_attr($icon_display); ?>; margin-right:4px;">
</i>
<a
id="<?php echo "text-{" . (int) $schedule->getId() . "}"; ?>"
href="javascript:void(0);"
onclick="DupPro.Schedule.Edit('<?php echo (int) $schedule->getId() ?>');"
class="name"
>
<?php echo esc_html($schedule->name); ?>
</a>
<div class="sub-menu">
<span class="link-style dup-schedule-quick-view" onclick="DupPro.Schedule.QuickView('<?php echo (int) $schedule->getId() ?>');">
<?php esc_html_e('Quick View', 'duplicator-pro'); ?>
</span> |
<span class="link-style dup-schedule-edit" onclick="DupPro.Schedule.Edit('<?php echo (int) $schedule->getId() ?>');">
<?php esc_html_e('Edit', 'duplicator-pro'); ?>
</span> |
<span class="link-style dup-schedule-copy" onclick="DupPro.Schedule.Copy('<?php echo (int) $schedule->getId(); ?>');">
<?php esc_html_e('Copy', 'duplicator-pro'); ?>
</span> |
<span class="link-style dup-schedule-delete" onclick="DupPro.Schedule.Delete('<?php echo (int) $schedule->getId(); ?>');">
<?php esc_html_e('Delete', 'duplicator-pro'); ?>
</span> |
<span class="link-style dup-schedule-run-now" onclick="DupPro.Schedule.RunNow('<?php echo (int) $schedule->getId(); ?>');">
<?php esc_html_e('Run Now', 'duplicator-pro'); ?>
</span>
</div>
</td>
<td>
<?php
if (count($schedule->storage_ids) > 0 && strlen(implode('', $schedule->storage_ids)) != 0) {
foreach ($schedule->storage_ids as $storage_id) {
if (($storage = AbstractStorageEntity::getById($storage_id)) === false) {
continue;
}
echo esc_html($storage->getName());
echo '<br/>';
}
} else {
$txt_DeleteStorage = __('No Storage', 'duplicator-pro');
echo "<a href='javascript:void(0)' onclick='DupPro.Schedule.showDeleteStorageMessage()'>"
. "<i class='fa fa-info-circle fa-fw fa-sm'></i>"
. "<u>" . esc_html($txt_DeleteStorage) . "</u></a>";
}
?>
</td>
<td>
<?php echo esc_html($schedule->get_next_run_time_string()); ?>
</td>
<td id="schedule-<?php echo (int) $schedule->getId() ?>-last-ran-string">
<?php echo esc_html($schedule->get_last_ran_string()); ?>
</td>
<td>
<b>
<?php if ($schedule->active) { ?>
<span class="green" ><?php esc_html_e('Yes', 'duplicator-pro'); ?></span>
<?php } else { ?>
<span class="maroon" ><?php esc_html_e('No', 'duplicator-pro'); ?></span>
<?php } ?>
</b>
</td>
<td class="dup-col-recovery" >
<?php $schedule->recoveableHtmlInfo(true); ?>
</td>
</tr>
<tr id='detail-<?php echo (int) $schedule->getId() ?>' class='<?php echo ($i % 2) ? 'alternate' : ''; ?> schedule-detail'>
<td colspan="5">
<?php
$template = DUP_PRO_Package_Template_Entity::getById($schedule->template_id);
?>
<table style="line-height: 15px">
<tr>
<td><b><?php esc_html_e('Package Template:', 'duplicator-pro'); ?></b></td>
<td colspan="3"><?php echo esc_html($template->name); ?></td>
</tr>
<tr>
<td><b><?php esc_html_e('Summary:', 'duplicator-pro'); ?></b></td>
<td colspan="3"><?php echo sprintf(esc_html__('Runs %1$s', 'duplicator-pro'), esc_html($schedule->get_repeat_text())); ?></td>
</tr>
<tr>
<td><b><?php esc_html_e('Last Ran:', 'duplicator-pro') ?></b></td>
<td><?php echo esc_html($schedule->get_last_ran_string()); ?></td>
</tr>
<tr>
<td><b><?php esc_html_e('Times Run:', 'duplicator-pro') ?></b></td>
<td><?php echo (int) $schedule->times_run; ?></td>
</tr>
</table>
</td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot>
<tr>
<th colspan="7" style="text-align:right; white-space: nowrap; font-size:12px">
<?php
printf(
esc_html_x(
'Total: %1$s | Active: %2$s | Time: %3$s',
'%1$s represents total schedules, %2$s represents active schedules, %3$s represents current time',
'duplicator-pro'
),
(int) $schedule_count,
(int) $active_count,
'<span id="dpro-clock-container"></span>'
);
?>
</th>
</tr>
</tfoot>
</table>
</form>
<?php
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('Bulk Action Required', 'duplicator-pro');
$alert1->message = __('Please select an action from the "Bulk Actions" drop down menu!', 'duplicator-pro');
$alert1->initAlert();
$alert2 = new DUP_PRO_UI_Dialog();
$alert2->title = __('Selection Required', 'duplicator-pro');
$alert2->wrapperClassButtons = 'dpro-dlg-noschedule-sel-bulk-action-btns';
$alert2->message = __('Please select at least one schedule to perform the action on!', 'duplicator-pro');
$alert2->initAlert();
$alert3 = new DUP_PRO_UI_Dialog();
$alert3->title = __('No Storage', 'duplicator-pro');
$alert3->message = __('All storage types associated with this schedule have been deleted.&nbsp;', 'duplicator-pro');
$alert3->message .= __('To enable this schedule please assign a valid storage type.', 'duplicator-pro');
$alert3->message .= '<br/><br/>';
$alert3->initAlert();
$confirm1 = new DUP_PRO_UI_Dialog();
$confirm1->title = __('Delete Schedule?', 'duplicator-pro');
$confirm1->wrapperClassButtons = 'dpro-dlg-delete-schedules-btns';
$confirm1->message = __('Are you sure you want to delete the selected schedule(s)?', 'duplicator-pro');
$confirm1->message .= '<br/>';
$confirm1->message .= '<small><i>' . __('Note: This action removes all schedules.', 'duplicator-pro') . '</i></small>';
$confirm1->progressText = __('Removing Schedules, Please Wait...', 'duplicator-pro');
$confirm1->jsCallback = 'DupPro.Schedule.BulkDelete()';
$confirm1->initConfirm();
$confirm4 = new DUP_PRO_UI_Dialog();
$confirm4->title = __('Activate Schedule?', 'duplicator-pro');
$confirm4->wrapperClassButtons = 'dpro-dlg-activate-schedules-btns';
$confirm4->message = __('Are you sure you want to activate the selected schedule(s)?', 'duplicator-pro');
$confirm4->message .= '<br/>';
$confirm4->message .= '<small><i>' . __('Note: This action activates all schedules.', 'duplicator-pro') . '</i></small>';
$confirm4->progressText = __('Activating Schedules, Please Wait...', 'duplicator-pro');
$confirm4->jsCallback = 'DupPro.Schedule.BulkActivate()';
$confirm4->initConfirm();
$confirm5 = new DUP_PRO_UI_Dialog();
$confirm5->title = __('Deactivate Schedule?', 'duplicator-pro');
$confirm5->wrapperClassButtons = 'dpro-dlg-deactivate-schedules-btns';
$confirm5->message = __('Are you sure you want to deactivate the selected schedule(s)?', 'duplicator-pro');
$confirm5->message .= '<br/>';
$confirm5->message .= '<small><i>' . __('Note: This action deactivates all schedules.', 'duplicator-pro') . '</i></small>';
$confirm5->progressText = __('Deactivating Schedules, Please Wait...', 'duplicator-pro');
$confirm5->jsCallback = 'DupPro.Schedule.BulkDeactivate()';
$confirm5->initConfirm();
$confirm2 = new DUP_PRO_UI_Dialog();
$confirm2->title = __('RUN SCHEDULE?', 'duplicator-pro');
$confirm2->message = __('Are you sure you want to run schedule now?', 'duplicator-pro');
$confirm2->progressText = __('Running Schedule, Please Wait...', 'duplicator-pro');
$confirm2->jsCallback = 'DupPro.Schedule.Run(this)';
$confirm2->initConfirm();
$confirm3 = new DUP_PRO_UI_Dialog();
$confirm3->title = $confirm1->title;
$confirm3->message = __('Are you sure you want to delete this schedule?', 'duplicator-pro');
$confirm3->progressText = $confirm1->progressText;
$confirm3->jsCallback = 'DupPro.Schedule.DeleteThis(this)';
$confirm3->initConfirm();
$schedule_bulk_action_nonce = wp_create_nonce('duplicator_pro_schedule_bulk_action');
?>
<script>
jQuery(document).ready(function ($) {
/*METHOD: Shows quick view summary */
DupPro.Schedule.QuickView = function (id) {
$('#detail-' + id).toggle();
};
/*METHOD: Run the schedule now and redirect to packages page */
DupPro.Schedule.RunNow = function (schedule_id) {
<?php $confirm2->showConfirm(); ?>
$("#<?php echo esc_js($confirm2->getID()); ?>-confirm").attr('data-id', schedule_id);
};
DupPro.Schedule.Run = function (e) {
var schedule_id = $(e).attr('data-id');
$('#icon-' + schedule_id + '-status').show();
$('#text-' + schedule_id).html("<?php esc_html_e('Queueing Now - Please Wait...', 'duplicator-pro') ?>");
var data = {
action: 'duplicator_pro_run_schedule_now',
schedule_id: schedule_id,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_run_schedule_now')); ?>'
}
$.ajax({
type: "POST",
url: ajaxurl,
timeout: 10000000,
data: data
}).done(function (respData) {
try {
var data = DupPro.parseJSON(respData);
} catch (err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
return false;
}
window.location.href = <?php echo SnapJson::jsonEncode($packagesPageUrl); ?>;
});
};
/*METHOD: Deletes a single schedule */
DupPro.Schedule.Delete = function (id) {
<?php $confirm3->showConfirm(); ?>
$("#<?php echo esc_js($confirm3->getID()); ?>-confirm").attr('data-id', id);
};
DupPro.Schedule.DeleteThis = function (e) {
var id = $(e).attr('data-id');
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_pro_schedule_bulk_action',
perform: <?php echo (int) ServicesSchedule::SCHEDULE_BULK_DELETE; ?>,
schedule_ids: [id],
nonce: '<?php echo esc_js($schedule_bulk_action_nonce); ?>'
},
}).done(function (data) {
$('#dup-schedule-form').submit();
});
};
// Creats a comma seperate list of all selected package ids
DupPro.Schedule.SelectedList = function () {
var arr = [];
$("input[name^='selected_id[]']").each(function () {
if ($(this).is(':checked')) {
arr.push($(this).val());
}
});
return arr;
};
// Bulk delete
DupPro.Schedule.BulkDelete = function () {
var list = DupPro.Schedule.SelectedList();
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_pro_schedule_bulk_action',
perform: <?php echo (int) ServicesSchedule::SCHEDULE_BULK_DELETE; ?>,
schedule_ids: list,
nonce: '<?php echo esc_js($schedule_bulk_action_nonce); ?>'
},
}).done(function (data) {
$('#dup-schedule-form').submit();
});
};
// Bulk activate
DupPro.Schedule.BulkActivate = function () {
var list = DupPro.Schedule.SelectedList();
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_pro_schedule_bulk_action',
perform: <?php echo (int) ServicesSchedule::SCHEDULE_BULK_ACTIVATE; ?>,
schedule_ids: list,
nonce: '<?php echo esc_js($schedule_bulk_action_nonce); ?>'
},
}).done(function (data) {
if (data.success) {
$('#dup-schedule-form').submit();
} else {
if (data.message.length > 0) {
$('#<?php echo esc_js($confirm4->getID()); ?>-progress').hide();
$('#<?php echo esc_js($confirm4->getMessageID()); ?>').html(data.message);
}
}
});
};
// Bulk deactivate
DupPro.Schedule.BulkDeactivate = function () {
var list = DupPro.Schedule.SelectedList();
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_pro_schedule_bulk_action',
perform: <?php echo (int) ServicesSchedule::SCHEDULE_BULK_DEACTIVATE; ?>,
schedule_ids: list,
nonce: '<?php echo esc_js($schedule_bulk_action_nonce); ?>'
},
}).done(function (data) {
$('#dup-schedule-form').submit();
});
};
/*METHOD: Bulk action response */
DupPro.Schedule.BulkAction = function () {
var list = DupPro.Schedule.SelectedList();
if (list.length == 0) {
<?php $alert2->showAlert(); ?>
return;
}
var action = $('#bulk_action').val(),
checked = ($('.item-chk:checked').length > 0);
if (action == -1 ) {
<?php $alert1->showAlert(); ?>
return;
}
if (checked) {
switch (action) {
case '<?php echo (int) ServicesSchedule::SCHEDULE_BULK_DELETE; ?>':
<?php $confirm1->showConfirm(); ?>
break;
case '<?php echo (int) ServicesSchedule::SCHEDULE_BULK_ACTIVATE; ?>':
<?php $confirm4->showConfirm(); ?>
break;
case '<?php echo (int) ServicesSchedule::SCHEDULE_BULK_DEACTIVATE; ?>':
<?php $confirm5->showConfirm(); ?>
break;
default:
<?php $alert2->showAlert(); ?>
break;
}
}
};
/*METHOD: Edit a single schedule */
DupPro.Schedule.Edit = function (id) {
document.location.href = <?php echo json_encode($scheduleEditBaseURL); ?> + '&schedule_id=' + id;
};
/*METHOD: Copy a schedule */
DupPro.Schedule.Copy = function (id) {
document.location.href = <?php echo json_encode($scheduleCopyBaseURL); ?> + '&duppro-source-schedule-id=' + id;
};
/*METHOD: Set delete all */
DupPro.Schedule.SetDeleteAll = function (chkbox) {
$('.item-chk').each(function () {
this.checked = chkbox.checked;
});
};
/*METHOD: Shows the delete storage message*/
DupPro.Schedule.showDeleteStorageMessage = function() {
<?php $alert3->showAlert(); ?>
};
/*METHOD: Enableds the update flag to track proccessing */
DupPro.Schedule.SetUpdateInterval = function (period) {
console.log('setting interval to ' + period);
if (DupPro.Schedule.setIntervalID != -1) {
clearInterval(DupPro.Schedule.setIntervalID);
DupPro.Schedule.setIntervalID = -1
}
DupPro.Schedule.setIntervalID = setInterval(DupPro.Schedule.UpdateSchedules, period * 1000);
};
/*METHOD: Checks the schedule status */
DupPro.Schedule.UpdateSchedules = function () {
var data = {
action: 'duplicator_pro_get_schedule_infos',
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_get_schedule_infos')); ?>'
};
$.ajax({
type: "POST",
url: ajaxurl,
data: data,
success: function (respData) {
try {
var schedule_infos = DupPro.parseJSON(respData);
} catch (err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
console.log("error");
console.log(data);
$(".schedule-status-icon").css('display', 'none');
DupPro.Schedule.SetUpdateInterval(60);
return false;
}
activeSchedulePresent = false;
for (schedule_info_key in schedule_infos) {
var schedule_info = schedule_infos[schedule_info_key];
var is_running_selector = "#icon-" + schedule_info.schedule_id + "-status";
var last_ran_selector = "#schedule-" + schedule_info.schedule_id + "-last-ran-string";
if (schedule_info.is_running) {
$(is_running_selector).show();
activeSchedulePresent = true;
} else {
$(is_running_selector).hide();
}
$(last_ran_selector).text(schedule_info.last_ran_string);
}
if (activeSchedulePresent) {
DupPro.Schedule.SetUpdateInterval(10);
} else {
DupPro.Schedule.SetUpdateInterval(60);
}
},
error: function (data) {
console.log("error");
console.log(data);
$(".schedule-status-icon").css('display', 'none');
DupPro.Schedule.SetUpdateInterval(60);
}
});
};
//INIT: startup items
$("tr.schedule-row").hover(
function () {
$(this).find(".sub-menu").show();
},
function () {
$(this).find(".sub-menu").hide();
}
);
DupPro.UI.Clock(DupPro._WordPressInitTime);
DupPro.Schedule.setIntervalID = -1;
DupPro.Schedule.UpdateSchedules();
});
</script>

View File

@@ -0,0 +1,195 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<form id="dup-capabilites-form" action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>" method="post" data-parsley-validate>
<?php $tplData['actions'][SettingsPageController::ACTION_CAPABILITIES_SAVE]->getActionNonceFileds(); ?>
<div class="dup-capabilities-selector-wrapper" >
<h3 class="title">
<?php esc_html_e('Roles and Permissions', 'duplicator-pro') ?>
</h3>
<hr size="1" />
<?php $tplMng->render('admin_pages/settings/capabilities/no_license_message'); ?>
<p>
<?php
esc_html_e(
'Select the user roles and/or users that are allowed to manage different aspects of Duplicator.',
'duplicator-pro'
); ?><br>
<?php
esc_html_e(
'By default, all permissions are provided only to administrator users.',
'duplicator-pro'
); ?><br>
<?php
esc_html_e(
'Some capabilities depend on others so if you select for example storage capability automatically the package read and package edit capabilities are assigned.', // phpcs:ignore Generic.Files.LineLength
'duplicator-pro'
);
?><br>
<b>
<?php esc_html_e('It is not possible to self remove the manage settings capabilities.', 'duplicator-pro'); ?>
</b>
</p>
<table class="form-table">
<tbody>
<?php
$capList = CapMng::getCapsInfo();
foreach ($capList as $cap => $capInfo) {
if ($cap === CapMng::CAP_LICENSE && !CapMng::can(CapMng::CAP_LICENSE, false)) {
continue;
}
$inputName = TplMng::getInputName('cap', $cap) . '[]';
$inputId = TplMng::getInputId('cap', $cap);
$tCont = $tplMng->render(
'admin_pages/settings/capabilities/capabilites_info_tooltip',
[
'info' => $capInfo,
'pLabel' => (strlen($capInfo['parent']) > 0 ? $capList[$capInfo['parent']]['label'] : ''),
],
false
);
$nParents = 0;
$pCeck = $capInfo;
while (strlen($pCeck['parent']) > 0) {
$nParents++;
$pCeck = $capList[$pCeck['parent']];
}
?>
<tr>
<th scope="row">
<label for="<?php echo esc_attr($inputId); ?>" >
<?php echo esc_html(str_repeat('-&nbsp;&nbsp;', $nParents)); ?>
<?php echo esc_html($capInfo['label']); ?>
</label>&nbsp;
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php echo esc_attr($capInfo['label']); ?>"
data-tooltip="<?php echo esc_attr($tCont); ?>"
data-tooltip-width="600"
>
</i>
</th>
<td>
<select
id="<?php echo esc_attr($inputId); ?>"
name="<?php echo esc_attr($inputName); ?>"
multiple
<?php disabled(License::can(License::CAPABILITY_CAPABILITIES_MNG), false); ?>
>
<?php
foreach (CapMng::getSelectableRoles() as $role => $roleName) {
if (!in_array($role, CapMng::getInstance()->getCapRoles($cap))) {
continue;
}
?>
<option
value="<?php echo esc_attr($role); ?>"
<?php selected(true); ?>
>
<?php echo esc_html($roleName); ?>
</option>
<?php
}
foreach (CapMng::getInstance()->getCapUsers($cap) as $userId) {
if (($user = get_user_by('id', $userId) ) == false) {
continue;
}
?>
<option
value="<?php echo (int) $user->ID; ?>"
<?php selected(true); ?>
>
<?php echo esc_html($user->user_email); ?>
</option>
<?php } ?>
</select>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<p>
<input
type="submit" name="submit" id="submit"
class="button-primary"
value="<?php esc_attr_e('Update Capabilities', 'duplicator-pro') ?>"
<?php disabled(License::can(License::CAPABILITY_CAPABILITIES_MNG), false); ?>
>
&nbsp;
<button
id="dup-capabilities-reset"
class="button-secondary"
>
<?php esc_html_e('Reset to Default', 'duplicator-pro'); ?>
</button>
</p>
</form>
<?php
//Delete Dialog
$dlgDelete = new DUP_PRO_UI_Dialog();
$dlgDelete->title = __('Are you sure do you want to reset the capabilities to default?', 'duplicator-pro');
$dlgDelete->message = '<p>' . __('This action will reassign all the capabilities of the Administrator role.', 'duplicator-pro') . '<p>';
$dlgDelete->jsCallback = 'DupPro.Settings.CapabilitesReset()';
$dlgDelete->initConfirm();
?>
<script>
jQuery(document).ready(function($) {
DupPro.Settings.CapabilitesReset = function () {
window.location.href = <?php echo json_encode($tplData['actions'][SettingsPageController::ACTION_CAPABILITIES_RESET]->getUrl()); ?>;
};
$('.dup-capabilities-selector-wrapper select').select2({
width: 'resolve',
ajax: {
type: "POST",
url: ajaxurl,
dataType: 'json',
delay: 250,
data: function (params) {
let query = {
search: params.term,
page: params.page || 1,
action: 'duplicator_settings_cap_users_list',
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_settings_cap_users_list')); ?>'
}
return query;
},
processResults: function (data) {
return data.data.funcData;
},
cache: true
},
placeholder: <?php echo json_encode(__('Search roles or users', 'duplicator-pro')); ?>,
minimumInputLength: <?php echo (License::can(License::CAPABILITY_CAPABILITIES_MNG_PLUS) ? 2 : 0); ?>
});
$('#dup-capabilities-reset').on('click', function(e) {
e.preventDefault();
<?php $dlgDelete->showConfirm(); ?>
});
});
</script>

View File

@@ -0,0 +1,27 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$info = $tplData['info'];
?>
<p>
<?php echo esc_html($info['desc']); ?>
</p>
<?php if (strlen($info['parent']) > 0) { ?>
<br>
<?php esc_html_e('Parent', 'duplicator-pro'); ?>: <b><?php echo esc_html($tplData['pLabel']); ?></b>
<?php } ?>

View File

@@ -0,0 +1,65 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Addons\ProBase\Models\LicenseData;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (License::can(License::CAPABILITY_CAPABILITIES_MNG)) {
return;
}
?>
<p id="dup-no-license-message" class="dup-border-left-red-notice" >
<b>
<?php
esc_html_e(
'The current license does not allow to manage the capabilities. ',
'duplicator-pro'
);
?>
</b>
<br>
<?php
if (License::getLicenseStatus() === LicenseData::STATUS_VALID) {
printf(
esc_html_x(
'If you want to manage the capabilities please %1$supgrade your license%2$s.',
'1: <a> tag, 2: </a> tag',
'duplicator-pro'
),
'<a href="' . esc_url(License::getUpsellURL()) . '" target="_blank">',
'</a>'
);
} else {
printf(
esc_html_x(
'If you want to manage the capabilities please %1$srenew your license%2$s.',
'1: <a> tag, 2: </a> tag',
'duplicator-pro'
),
'<a href="' . esc_url(License::getUpsellURL()) . '" target="_blank">',
'</a>'
);
}
?>
<br><br>
<?php
esc_html_e(
'It\'s possible to reset the capabilities to the default values with "Reset to default" button.',
'duplicator-pro'
);
?>
</p>

View File

@@ -0,0 +1,377 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Libs\Snap\SnapJson;
use Duplicator\Utils\ExpireOptions;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\PageAction;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = DUP_PRO_Global_Entity::getInstance();
/** @var PageAction */
$resetAction = $tplData['actions'][SettingsPageController::ACTION_RESET_SETTINGS];
$trace_log_enabled = (bool) get_option('duplicator_pro_trace_log_enabled');
$send_trace_to_error_log = (bool) get_option('duplicator_pro_send_trace_to_error_log');
if ($trace_log_enabled) {
$logging_mode = ($send_trace_to_error_log) ? 'enhanced' : 'on';
} else {
$logging_mode = 'off';
}
?>
<form id="dup-settings-form" action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>" method="post" data-parsley-validate>
<?php $tplData['actions'][SettingsPageController::ACTION_GENERAL_SAVE]->getActionNonceFileds(); ?>
<!-- =============================== PLUG-IN SETTINGS -->
<h3 class="title"><?php esc_html_e("Plugin", 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table">
<tr valign="top">
<th scope="row">
<label>
<?php
esc_html_e("Version", 'duplicator-pro');
?>
</label>
</th>
<td>
<?php
echo esc_html(DUPLICATOR_PRO_VERSION);
?>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Uninstall", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="uninstall_settings"
id="uninstall_settings"
value="1"
<?php checked($global->uninstall_settings); ?>
>
<label for="uninstall_settings"><?php esc_html_e("Delete plugin settings", 'duplicator-pro'); ?> </label><br />
<input
type="checkbox"
name="uninstall_packages"
id="uninstall_packages"
value="1"
<?php checked($global->uninstall_packages); ?>
>
<label for="uninstall_packages"><?php esc_html_e("Delete entire storage directory", 'duplicator-pro'); ?></label><br />
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Encrypt Settings", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="crypt"
id="crypt"
value="1"
<?php checked($global->crypt); ?>
>
<label for="crypt"><?php esc_html_e("Enable settings encryption", 'duplicator-pro'); ?> </label><br />
<p class="description">
<?php esc_html_e("Only uncheck if machine doesn't support PCrypt.", 'duplicator-pro'); ?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Usage statistics", 'duplicator-pro'); ?></label></th>
<td>
<?php if (DUPLICATOR_USTATS_DISALLOW) { // @phpstan-ignore-line ?>
<span class="maroon">
<?php esc_html_e('Usage statistics are hardcoded disallowed.', 'duplicator-pro'); ?>
</span>
<?php } else { ?>
<input
type="checkbox"
name="usage_tracking"
id="usage_tracking"
value="1"
<?php checked($global->getUsageTracking()); ?>
>
<label for="usage_tracking"><?php esc_html_e("Enable usage tracking", 'duplicator-pro'); ?> </label>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Usage Tracking", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tplMng->render('admin_pages/settings/general/usage_tracking_tooltip', [], false)); ?>"
data-tooltip-width="600"
>
</i>
<?php } ?>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Hide Announcements", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="dup_am_notices"
id="dup_am_notices"
value="1"
<?php checked(!$global->isAmNoticesEnabled()); ?>
>
<label for="dup_am_notices">
<?php esc_html_e("Check this option to hide plugin announcements and update details.", 'duplicator-pro'); ?>
</label>
</td>
</tr>
</table><br />
<?php TplMng::getInstance()->render('parts/settings/email_summary', []); ?>
<!-- ===============================
DEBUG SETTINGS -->
<h3 class="title"><?php esc_html_e('Debug', 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Trace Log", 'duplicator-pro'); ?></label></th>
<td>
<select name="_logging_mode">
<option value="off" <?php selected($logging_mode, 'off'); ?>>
<?php esc_html_e('Off', 'duplicator-pro'); ?>
</option>
<option value="on" <?php selected($logging_mode, 'on'); ?>>
<?php esc_html_e('On', 'duplicator-pro'); ?>
</option>
<option value="enhanced" <?php selected($logging_mode, 'enhanced'); ?>>
<?php esc_html_e('On (Enhanced)', 'duplicator-pro'); ?>
</option>
</select>
<p class="description">
<?php
esc_html_e("Turning on log initially clears it out. The enhanced setting writes to both trace and PHP error logs.", 'duplicator-pro');
echo "<br/>";
esc_html_e("WARNING: Only turn on this setting when asked to by support as tracing will impact performance.", 'duplicator-pro');
?>
</p><br />
<button class="button" <?php disabled(DUP_PRO_Log::traceFileExists(), false); ?> onclick="DupPro.Pack.DownloadTraceLog(); return false">
<i class="fa fa-download"></i>
<?php echo esc_html__('Download Trace Log', 'duplicator-pro') . ' (' . esc_html(DUP_PRO_Log::getTraceStatus()) . ')'; ?>
</button>
</td>
</tr>
</table><br />
<!-- ===============================
ADVANCED SETTINGS -->
<h3 class="title"><?php esc_html_e('Advanced', 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Settings", 'duplicator-pro'); ?></label></th>
<td>
<button id="dup-pro-reset-all" class="button" onclick="DupPro.Pack.ConfirmResetAll(); return false">
<i class="fas fa-redo fa-sm"></i> <?php esc_html_e('Reset All Settings', 'duplicator-pro'); ?>
</button>
<p class="description">
<?php
esc_html_e("Reset all settings to their defaults.", 'duplicator-pro');
$tContent = __(
'Resets standard settings to defaults. Does not affect capabilities, license key, storage or schedules.',
'duplicator-pro'
);
?>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Reset Settings", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tContent); ?>"
>
</i>
</p>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Packages", 'duplicator-pro'); ?></label></th>
<td>
<button class="button" onclick="DupPro.Pack.ConfirmResetPackages(); return false;">
<i class="fas fa-redo fa-sm"></i> <?php esc_attr_e('Reset Incomplete Packages', 'duplicator-pro'); ?>
</button>
<p class="description">
<?php esc_html_e("Reset all packages.", 'duplicator-pro'); ?>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Reset packages", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e('Delete all unfinished packages. So those with error and being created.', 'duplicator-pro'); ?>"
>
</i>
</p>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Foreign JavaScript", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="_unhook_third_party_js"
id="_unhook_third_party_js"
value="1"
<?php checked($global->unhook_third_party_js); ?>
>
<label for="_unhook_third_party_js"><?php esc_html_e("Disable", 'duplicator-pro'); ?></label> <br />
<p class="description">
<?php
esc_html_e("Check this option if JavaScript from the theme or other plugins conflicts with Duplicator Pro pages.", 'duplicator-pro');
?>
<br>
<?php
esc_html_e("Do not modify this setting unless you know the expected result or have talked to support.", 'duplicator-pro');
?>
</p>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Foreign CSS", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="_unhook_third_party_css"
id="unhook_third_party_css"
value="1"
<?php checked($global->unhook_third_party_css); ?>
>
<label for="unhook_third_party_css"><?php esc_html_e("Disable", 'duplicator-pro'); ?></label> <br />
<p class="description">
<?php
esc_html_e("Check this option if CSS from the theme or other plugins conflicts with Duplicator Pro pages.", 'duplicator-pro');
?>
<br>
<?php
esc_html_e("Do not modify this setting unless you know the expected result or have talked to support.", 'duplicator-pro');
?>
</p>
</td>
</tr>
</table>
<p>
<input
type="submit" name="submit" id="submit"
class="button-primary"
value="<?php esc_attr_e('Save General Settings', 'duplicator-pro') ?>"
>
</p>
</form>
<?php
$resetSettingsDialog = new DUP_PRO_UI_Dialog();
$resetSettingsDialog->title = __('Reset Settings?', 'duplicator-pro');
$resetSettingsDialog->message = __('Are you sure you want to reset settings to defaults?', 'duplicator-pro');
$resetSettingsDialog->progressText = __('Resetting settings, Please Wait...', 'duplicator-pro');
$resetSettingsDialog->jsCallback = 'DupPro.Pack.ResetAll()';
$resetSettingsDialog->progressOn = false;
$resetSettingsDialog->okText = __('Yes', 'duplicator-pro');
$resetSettingsDialog->cancelText = __('No', 'duplicator-pro');
$resetSettingsDialog->closeOnConfirm = true;
$resetSettingsDialog->initConfirm();
$resetPackagesDialog = new DUP_PRO_UI_Dialog();
$resetPackagesDialog->title = __('Reset Packages ?', 'duplicator-pro');
$resetPackagesDialog->message = __('This will clear and reset all of the current temporary packages. Would you like to continue?', 'duplicator-pro');
$resetPackagesDialog->progressText = __('Resetting settings, Please Wait...', 'duplicator-pro');
$resetPackagesDialog->jsCallback = 'DupPro.Pack.ResetPackages()';
$resetPackagesDialog->progressOn = false;
$resetPackagesDialog->okText = __('Yes', 'duplicator-pro');
$resetPackagesDialog->cancelText = __('No', 'duplicator-pro');
$resetPackagesDialog->closeOnConfirm = true;
$resetPackagesDialog->initConfirm();
$msg_ajax_error = new DUP_PRO_UI_Messages(
__('AJAX ERROR!', 'duplicator-pro') . '<br>' . __('Ajax request error', 'duplicator-pro'),
DUP_PRO_UI_Messages::ERROR
);
$msg_ajax_error->hide_on_init = true;
$msg_ajax_error->is_dismissible = true;
$msg_ajax_error->initMessage();
$msg_response_error = new DUP_PRO_UI_Messages(__('RESPONSE ERROR!', 'duplicator-pro'), DUP_PRO_UI_Messages::ERROR);
$msg_response_error->hide_on_init = true;
$msg_response_error->is_dismissible = true;
$msg_response_error->initMessage();
$msg_response_success = new DUP_PRO_UI_Messages('', DUP_PRO_UI_Messages::NOTICE);
$msg_response_success->hide_on_init = true;
$msg_response_success->is_dismissible = true;
$msg_response_success->initMessage();
?>
<script>
jQuery(document).ready(function($) {
// which: 0=installer, 1=archive, 2=sql file, 3=log
DupPro.Pack.DownloadTraceLog = function() {
var actionLocation = ajaxurl + '?action=duplicator_pro_get_trace_log&nonce='
+ '<?php echo esc_js(wp_create_nonce('duplicator_pro_get_trace_log')); ?>';
location.href = actionLocation;
};
DupPro.Pack.ConfirmResetAll = function() {
<?php $resetSettingsDialog->showConfirm(); ?>
};
DupPro.Pack.ConfirmResetPackages = function() {
<?php $resetPackagesDialog->showConfirm(); ?>
};
DupPro.Pack.ResetAll = function() {
let resetUrl = <?php echo SnapJson::jsonEncode($resetAction->getUrl()); ?>;
location.href = resetUrl;
};
DupPro.Pack.ResetPackages = function() {
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_pro_reset_packages',
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_reset_packages')); ?>'
},
success: function(result) {
if (result.success) {
var message = '<?php esc_html_e('Packages successfully reset', 'duplicator-pro'); ?>';
<?php
$msg_response_success->updateMessage('message');
$msg_response_success->showMessage();
?>
} else {
var message = '<?php esc_html_e('RESPONSE ERROR!', 'duplicator-pro'); ?>' + '<br><br>' + result.data.message;
<?php
$msg_response_error->updateMessage('message');
$msg_response_error->showMessage();
?>
}
},
error: function(result) {
<?php $msg_ajax_error->showMessage(); ?>
}
});
};
//Init
$("#_trace_log_enabled").click(function() {
$('#_send_trace_to_error_log').attr('disabled', !$(this).is(':checked'));
});
});
</script>

View File

@@ -0,0 +1,187 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") || exit;
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<div>
<b>
<?php esc_html_e('All information sent to the server is anonymous except the license key and email.', 'duplicator-pro'); ?><br>
<?php esc_html_e('No information about storage or package\'s content are sent.', 'duplicator-pro'); ?>
</b>
</div>
<br>
<div>
<?php
esc_html_e(
'Usage tracking for Duplicator helps us better understand our users and their website needs by looking
at a range of server and website environments.',
'duplicator-pro'
);
?>
<b>
<?php esc_html_e('This allows us to continuously improve our product as well as our Q&A / testing process.', 'duplicator-pro'); ?>
</b>
<?php esc_html_e('Below is the list of information that Duplicator collects as part of the usage tracking:', 'duplicator-pro'); ?>
</div>
<ul>
<li>
<?php
printf(
esc_html_x(
'%1$sPHP Version:%2$s so we know which PHP versions we have to test against (no one likes whitescreens or log files full of errors).',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sWordPress Version:%2$s so we know which WordPress versions to support and test against.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sMySQL Version:%2$s so we know which versions of MySQL to support and test against for our custom tables.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sDuplicator Version:%2$s so we know which versions of Duplicator are potentially responsible for issues when we get bug reports,
allowing us to identify issues and release solutions much faster.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sPlugins and Themes infos:%2$s so we can figure out which ones I can generate compatibility errors with Duplicator.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sSite info:%2$s General information about the site such as database, file size, number of users, and sites in case it is a multisite.
This is useful for us to understand the critical issues of package creation.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sPackages infos:%2$s Information about the packages created and the type of components included.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sStoragesd infos:%2$s Information about the type of storage used,
this data is useful for us to understand how to improve our support for external storages.(Only anonymized data is sent).',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sTemplates infos:%2$s Information about the template components.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sSchedules infos:%2$s Information on how schedules are used.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<?php
printf(
esc_html_x(
'%1$sLicense key and email and url:%2$s If you\'re an Duplicator customer, then we use this to determine if there\'s an issue
with your specific license key, and to link the profile of your site with the configuration of authentication to allow us to
determine if there\'s issues with your Duplicator authentication.',
'%1$s and %2$s are are opening and closing bold (<b></b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
</ul>

View File

@@ -0,0 +1,128 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
use Duplicator\Controllers\ImportPageController;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
$global = DUP_PRO_Global_Entity::getInstance();
?>
<form id="dup-settings-form" action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>" method="post" data-parsley-validate>
<?php $tplData['actions'][SettingsPageController::ACTION_IMPORT_SAVE_SETTINGS]->getActionNonceFileds(); ?>
<h3 id="duplicator-pro-import-settings" class="title"><?php esc_html_e("Import Settings", 'duplicator-pro'); ?></h3>
<hr size="1" />
<table class="form-table margin-top-1">
<tr>
<th scope="row">
<label for="input_import_chunk_size" ><?php esc_html_e("Upload Chunk Size", 'duplicator-pro'); ?></label>
</th>
<td >
<select name="import_chunk_size" id="input_import_chunk_size" class="postform">
<?php foreach (ImportPageController::getChunkSizes() as $size => $label) { ?>
<option value="<?php echo esc_attr($size); ?>" <?php selected($global->import_chunk_size, $size); ?>>
<?php echo esc_html($label); ?>
</option>
<?php } ?>
</select>
<p class="description">
<?php
esc_html_e(
"If you have issue uploading a package start with a lower size. The connection size is from slowest to fastest.",
'duplicator-pro'
);
?><br/>
<small>
<?php
esc_html_e("Note: This setting only applies to the 'Import File' option.", 'duplicator-pro');
?>
</small>
</p>
</td>
</tr>
<tr>
<th scope="row">
<label for="import_custom_path" ><?php esc_html_e("Import custom path", 'duplicator-pro'); ?></label>
</th>
<td >
<input
class="large"
type="text"
name="import_custom_path"
id="input_import_custom_path"
value="<?php echo esc_attr($global->import_custom_path); ?>"
placeholder=""
>
<p class="description">
<?php
esc_html_e(
"Setting a custom path does not change the folder where packages are uploaded but adds a folder to check for packages list.",
'duplicator-pro'
);
?>
<br>
<?php
esc_html_e(
"This can be useful when you want to manually upload packages to another location which can also be a local storage of current or other site.", // phpcs:ignore Generic.Files.LineLength
'duplicator-pro'
);
?>
</p>
</td>
</tr>
</table>
<h3 class="title"><?php esc_html_e('Recovery', 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table margin-top-1">
<tr>
<th scope="row">
<label for="input_recovery_custom_path" ><?php esc_html_e("Recovery custom path", 'duplicator-pro'); ?></label>
</th>
<td>
<input
class="large"
type="text"
name="recovery_custom_path"
id="input_recovery_custom_path"
value="<?php echo esc_attr($global->getRecoveryCustomPath()); ?>"
placeholder=""
>
<p class="description">
<?php
esc_html_e(
"Setting a custom path changes the location the recovery points are generated.",
'duplicator-pro'
);
?>
</p>
</td>
</tr>
</table>
<p class="submit dpro-save-submit">
<input
type="submit"
name="submit"
id="submit"
class="button-primary"
value="<?php esc_attr_e('Save Import Settings', 'duplicator-pro') ?>"
style="display: inline-block;"
>
</p>
</form>

View File

@@ -0,0 +1,360 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Libs\Snap\SnapIO;
$global = DUP_PRO_Global_Entity::getInstance();
$sglobal = DUP_PRO_Secure_Global_Entity::getInstance();
$max_execution_time = ini_get("max_execution_time");
$max_execution_time = empty($max_execution_time) ? 30 : $max_execution_time;
$max_worker_cap_in_sec = (int) (0.7 * (float) $max_execution_time);
if ($max_worker_cap_in_sec > 180) {
$max_worker_cap_in_sec = 180;
}
?>
<!-- ===============================
ADVANCED SETTINGS -->
<form id="dup-settings-form"
action="<?php echo esc_url(Duplicator\Core\Controllers\ControllersManager::getCurrentLink()); ?>"
method="post" data-parsley-validate
>
<?php $tplData['actions'][SettingsPageController::ACTION_PACKAGE_ADVANCED_SAVE]->getActionNonceFileds(); ?>
<p class="description" style="color:maroon">
<i class="fas fa-exclamation-circle"></i>
<?php esc_html_e("Do not modify advanced settings unless you know the expected result or have talked to support.", 'duplicator-pro'); ?>
</p>
<table class="form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Thread Lock", 'duplicator-pro'); ?></label></th>
<td>
<input
type="radio" name="lock_mode" id="lock_mode_flock" value="<?php echo (int) DUP_PRO_Thread_Lock_Mode::Flock; ?>"
<?php checked($global->lock_mode, DUP_PRO_Thread_Lock_Mode::Flock); ?>
>
<label for="lock_mode_flock"><?php esc_html_e("File", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio" name="lock_mode" id="lock_mode_sql" value="<?php echo (int) DUP_PRO_Thread_Lock_Mode::SQL_Lock; ?>"
<?php checked($global->lock_mode, DUP_PRO_Thread_Lock_Mode::SQL_Lock); ?>
>
<label for="lock_mode_sql"><?php esc_html_e("SQL", 'duplicator-pro'); ?></label> &nbsp;
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Max Worker Time", 'duplicator-pro'); ?></label></th>
<td>
<input
style="float:left;display:block;margin-right:6px;"
data-parsley-required data-parsley-errors-container="#php_max_worker_time_in_sec_error_container"
data-parsley-min="10" data-parsley-type="number" class="dup-narrow-input"
type="text" name="php_max_worker_time_in_sec"
id="php_max_worker_time_in_sec"
value="<?php echo (int) $global->php_max_worker_time_in_sec; ?>"
>
<p style="margin-left:4px;"><?php esc_html_e('Seconds', 'duplicator-pro'); ?></p>
<div id="php_max_worker_time_in_sec_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php
printf(
esc_html__('Lower is more reliable but slower. Recommended max is %1$s sec based on PHP setting %2$s.', 'duplicator-pro'),
(int) $max_worker_cap_in_sec,
esc_html($max_execution_time)
);
?><br/>
<?php esc_html_e("Try a low value (30 seconds or lower) if the build fails with the recommended setting.", 'duplicator-pro'); ?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e('Chunk Size', 'duplicator-pro'); ?></label></th>
<td>
<input type="number" name="_chunk_size" id="_chunk_size" value="<?php echo (int) $global->chunk_size; ?>" minlength="4" min="1024"
data-parsley-required
data-parsley-minlength="10"
data-parsley-errors-container="#chunk_size_error_container" />
<div id="chunk_size_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php esc_html_e('Archive upload chunk size', 'duplicator-pro'); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Ajax", 'duplicator-pro'); ?></label></th>
<td>
<input
type="radio" id="ajax_protocol_1" name="ajax_protocol" class="ajax_protocol" value="admin"
<?php checked($global->ajax_protocol, 'admin'); ?> />
<label for="ajax_protocol_1"><?php esc_html_e("Auto", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio" id="ajax_protocol_2" name="ajax_protocol" class="ajax_protocol"
value="http" <?php checked($global->ajax_protocol == 'http'); ?> />
<label for="ajax_protocol_2"><?php esc_html_e("HTTP", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio" id="ajax_protocol_3" name="ajax_protocol" class="ajax_protocol" value="https"
<?php checked($global->ajax_protocol == 'https'); ?> />
<label for="ajax_protocol_3"><?php esc_html_e("HTTPS", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio" id="ajax_protocol_4" name="ajax_protocol" class="ajax_protocol" value="custom"
<?php checked($global->ajax_protocol, 'custom'); ?> />
<label for="ajax_protocol_4"><?php esc_html_e("Custom URL", 'duplicator-pro'); ?></label> <br/>
<input
style="width:600px"
type="<?php echo ($global->ajax_protocol == 'custom' ? 'text' : 'hidden'); ?>"
id="custom_ajax_url" name="custom_ajax_url"
placeholder="<?php esc_attr_e('Consult support before changing.', 'duplicator-pro'); ?>"
value="<?php echo esc_url($global->custom_ajax_url); ?>"
>
<span id="custom_ajax_url_error" style="color: maroon; text-weight: bold; display: none"><?php esc_html_e("Bad URL!", 'duplicator-pro'); ?>
</span>
<p class="description">
<?php esc_html_e("Used to kick off build worker. Only change if packages get stuck at the start of a build.", 'duplicator-pro'); ?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row">
<label>Root path</label>
</th>
<td>
<input
type="checkbox" name="homepath_as_abspath" id="homepath_as_abspath"
<?php disabled(DUP_PRO_Archive::isAbspathHomepathEquivalent()); ?>
<?php checked($global->homepath_as_abspath); ?> value="1"
>
<label for="homepath_as_abspath">
<?php
printf(
esc_html_x(
'Use ABSPATH %s as root path.',
'%s represents the ABSPATH surrounded with bold (<b>) tags',
'duplicator-pro'
),
'<b>' . esc_html(DUP_PRO_Archive::getArchiveListPaths('abs')) . '</b>'
);
?>
<br>
</label>
<p class="description">
<?php
if (DUP_PRO_Archive::isAbspathHomepathEquivalent()) {
esc_html_e('Abspath and home path are equivalent so this option is disabled', 'duplicator-pro');
} else {
?>
<?php
printf(
esc_html_x(
'In this installation the default root path is %s.',
'%s represents the root path surrounded with bold (<b>) tags',
'duplicator-pro'
),
'<b>' . esc_html(SnapIO::safePathUntrailingslashit(get_home_path(), true)) . '</b>'
); ?><br>
<?php
esc_html_e(
'The path of the WordPress core is different. Activate this option if you want to consider ABSPATH as root path.',
'duplicator-pro'
);
}
?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e('Scan File Checks', 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox" name="_skip_archive_scan" id="_skip_archive_scan"
<?php checked($global->skip_archive_scan); ?>
>
<label for="_skip_archive_scan"><?php esc_html_e("Skip", 'duplicator-pro') ?> </label><br/>
<p class="description">
<?php
esc_html_e(
'If enabled all files check on scan will be skipped before package creation.
In some cases, this option can be beneficial if the scan process is having issues running or returning errors.',
'duplicator-pro'
);
?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e('Client-side Kickoff', 'duplicator-pro'); ?></label></th>
<td>
<input type="checkbox" name="_clientside_kickoff" id="_clientside_kickoff" <?php checked($global->clientside_kickoff); ?> />
<label for="_clientside_kickoff"><?php esc_html_e("Enabled", 'duplicator-pro') ?> </label><br/>
<p class="description">
<?php esc_html_e('Initiate package build from client. Only check this if instructed to by Duplicator support.', 'duplicator-pro'); ?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Basic Auth", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="_basic_auth_enabled"
id="_basic_auth_enabled"
value="1"
<?php checked($global->basic_auth_enabled); ?>
>
<label for="_basic_auth_enabled"><?php esc_html_e("Enabled", 'duplicator-pro') ?> </label><br/>
<input
style="margin-top:8px;width:200px;"
class="dup-wide-input" autocomplete="off"
placeholder="<?php esc_attr_e('User', 'duplicator-pro'); ?>"
type="text" name="basic_auth_user"
id="basic_auth_user"
value="<?php echo esc_attr($global->basic_auth_user); ?>"
>
<input
id='auth_password'
autocomplete="off"
style="width:200px;"
class="dup-wide-input"
placeholder="<?php esc_attr_e('Password', 'duplicator-pro'); ?>"
type="password"
name="basic_auth_password"
id="basic_auth_password"
value="<?php echo esc_attr($sglobal->basic_auth_password); ?>"
>
<label for="auth_password">
<i class="dpro-edit-info">
<input type="checkbox" onclick="DupPro.UI.TogglePasswordDisplay(this.checked, 'auth_password');" >&nbsp;
<?php esc_html_e('Show Password', 'duplicator-pro') ?>
</i>
</label>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e('Local Installer Name', 'duplicator-pro'); ?></label></th>
<td>
<input type="text" name="_installer_base_name" id="_installer_base_name" value="<?php echo esc_attr($global->installer_base_name); ?>"
data-parsley-required
data-parsley-minlength="10"
data-parsley-errors-container="#installer_base_name_error_container" />
<div id="installer_base_name_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php esc_html_e('The base name of the installer file. Only change if host prevents using installer.php', 'duplicator-pro'); ?>
</p>
</td>
</tr>
</table>
<p class="submit dpro-save-submit">
<input
type="submit" name="submit" id="submit" class="button-primary"
value="<?php esc_attr_e('Save Advanced Package Settings', 'duplicator-pro') ?>" style="display: inline-block;"
>
</p>
</form>
<script>
(function ($) {
var url_error = $('#custom_ajax_url_error');
// Check URL is valid
$.urlExists = function (url) {
var http = new XMLHttpRequest();
try {
http.open('HEAD', url, false);
http.send();
} catch (err) {
$('#custom_ajax_url_error').html(err.message);
return false;
}
return http.status != 404;
};
var debounce;
$('#custom_ajax_url').on('input keyup keydown change paste focus', function (e) {
clearTimeout(debounce);
var $this = $(this);
debounce = setTimeout(function () {
$this.css({'border': ''});
url_error.hide();
if (!$.urlExists($this.val()))
{
$this.css({'border': 'maroon 1px solid'});
url_error.show();
}
}, 500);
});
(function ($this) {
$this.css({'border': ''});
url_error.hide();
setTimeout(function () {
var isCustomAjaxUrl = $('#ajax_protocol_4').is(':checked');
if (isCustomAjaxUrl && !$.urlExists($this.val()))
{
$this.css({'border': 'maroon 1px solid'});
url_error.show();
}
if (isCustomAjaxUrl) {
$('#custom_ajax_url').attr('data-parsley-required', 'true');
} else {
$('#custom_ajax_url').removeAttr('data-parsley-required');
}
}, 0);
}($('#custom_ajax_url')))
/*
* DISPLAY OR HIDE CUSTOM_AJAX_URL
*/
$('.ajax_protocol').on('input click change select touchstart', function (e) {
// Setup and collect value
var $this = $(this),
value = $this.val(),
hideField = $('#custom_ajax_url'),
hideFieldState = hideField.attr('type'),
offset = 200;
url_error.hide();
if (value == 'custom')
{
// Display hidden field
if (hideFieldState == 'hidden')
{
hideField.hide().attr('type', 'text').fadeIn(offset).attr('data-parsley-required', 'true');
hideField.css({'border': ''});
url_error.hide();
if (!$.urlExists(hideField.val()))
{
hideField.css({'border': 'maroon 1px solid'});
url_error.show();
}
}
} else
{
// Hide field but keep it active for POST reading
if (hideFieldState == 'text')
{
var parsleyId = $('#custom_ajax_url').data('parsley-id');
var errorUlId = '#parsley-id-' + parsleyId;
if ($(errorUlId).length)
$(errorUlId).remove();
hideField.fadeOut(Math.round(offset / 2), function () {
$(this).attr('type', 'hidden').show();
}).removeAttr('data-parsley-required');
;
}
}
});
}(window.jQuery || jQuery))
</script>

View File

@@ -0,0 +1,712 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Libs\Shell\Shell;
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Libs\Snap\SnapUtil;
use Duplicator\Utils\ZipArchiveExtended;
$global = DUP_PRO_Global_Entity::getInstance();
$action_updated = null;
$action_response = __("Package Settings Saved", 'duplicator-pro');
$isZipArchiveAvailable = ZipArchiveExtended::isPhpZipAvailable();
$isShellZipAvailable = (DUP_PRO_Zip_U::getShellExecZipPath() != null);
$is_shellexec_on = Shell::test();
if (isset($_REQUEST['_package_mysqldump_path'])) {
$mysqldump_exe_file = SnapUtil::sanitizeNSCharsNewlineTrim($_REQUEST['_package_mysqldump_path']);
$mysqldump_exe_file = preg_match('/^([A-Za-z]\:)?[\/\\\\]/', $mysqldump_exe_file) ? $mysqldump_exe_file : '';
$mysqldump_exe_file = preg_replace('/[\'";]/m', '', $mysqldump_exe_file);
$_REQUEST['_package_mysqldump_path'] = SnapIO::safePathUntrailingslashit($mysqldump_exe_file);
}
$mysqlDumpPath = DUP_PRO_DB::getMySqlDumpPath();
$mysqlDumpFound = ($mysqlDumpPath) ? true : false;
$installerNameMode = $global->installer_name_mode;
?>
<form
id="dup-settings-form" class="dup-settings-pack-basic"
action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>"
method="post" data-parsley-validate
>
<?php $tplData['actions'][SettingsPageController::ACTION_PACKAGE_BASIC_SAVE]->getActionNonceFileds(); ?>
<!-- ===============================
DATABASE -->
<h3 class="title"><?php esc_html_e("Database", 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table">
<tr>
<th scope="row"><label><?php esc_html_e("SQL Mode", 'duplicator-pro'); ?></label></th>
<td>
<div class="engine-radio <?php echo ($is_shellexec_on) ? '' : 'engine-radio-disabled'; ?>">
<input
type="radio" name="_package_dbmode" value="mysql" id="package_mysqldump"
<?php checked($global->package_mysqldump); ?> onclick="DupPro.UI.SetDBEngineMode();"
>
<label for="package_mysqldump"><?php esc_html_e("Mysqldump", 'duplicator-pro'); ?> </label> &nbsp; &nbsp; &nbsp;
</div>
<div class="engine-radio">
<input
type="radio" name="_package_dbmode" id="package_phpdump" value="php"
<?php checked(!$global->package_mysqldump); ?> onclick="DupPro.UI.SetDBEngineMode();"
>
<label for="package_phpdump"><?php esc_html_e("PHP Code", 'duplicator-pro'); ?></label>
</div>
<br style="clear:both"/><br/>
<!-- SHELL EXEC -->
<div class="engine-sub-opts" id="dbengine-details-1" style="display:none">
<!-- MYSQLDUMP IN-ACTIVE -->
<?php if (!$is_shellexec_on) :
?>
<div class="dup-feature-notfound">
<?php
esc_html_e(
'In order to use Mysqldump, one of the PHP functions has to be enabled: popen/pclose, exec or shell_exec.',
'duplicator-pro'
);
echo ' ';
esc_html_e('Please contact your host or server admin to enable one or more these functions.', 'duplicator-pro');
echo ' ';
printf(
esc_html_x(
'For a list of approved providers that support these functions, %1$sclick here%2$s.',
'%1$s and %2$s are the opening and closing tags of a link.',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'what-host-providers-are-recommended-for-duplicator/')
. '" target="_blank">',
'</a>'
);
echo ' ';
esc_html_e('The "PHP Code" setting will be used until this issue is resolved by your hosting provider.', 'duplicator-pro');
?>
<p>
<?php
esc_html_e('Below is a list of possible functions to activate to solve the problem.', 'duplicator-pro');
echo ' ';
esc_html_e('If the problem persists, look at the log for a more thorough analysis.', 'duplicator-pro');
?>
</p>
<br/>
<b><?php esc_html_e('Disabled Functions:', 'duplicator-pro'); ?></b>
<code class="display-block margin-bottom-1">
<?php
foreach (['escapeshellarg', 'escapeshellcmd', 'extension_loaded', 'exec', 'popen', 'pclose', 'shell_exec'] as $func) {
if (Shell::hasDisabledFunctions($func)) {
echo esc_html($func);
echo '<br>';
}
}
?>
</code>
<?php
printf(
esc_html_x(
'FAQ: %1$sHow to enable disabled PHP functions.%2$s',
'%1$s and %2$s are the opening and closing tags of a link.',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-resolve-dependency-checks') . '" target="_blank">',
'</a>'
);
?>
</div>
<!-- MYSQLDUMP ACTIVE -->
<?php
else :
$tipContent = esc_attr__(
'Add a custom path if the path to mysqldump is not properly detected.
For all paths use a forward slash as the path seperator.
On Linux systems use mysqldump for Windows systems use mysqldump.exe.
If the path tried does not work please contact your hosting provider for details on the correct path.',
'duplicator-pro'
);
?>
<label><?php esc_html_e("Current Path:", 'duplicator-pro'); ?></label>
<?php
SettingsPageController::getMySQLDumpMessage(
$mysqlDumpFound,
(!empty($mysqlDumpPath) ? $mysqlDumpPath : $global->package_mysqldump_path)
); ?><br>
<label><?php esc_html_e("Custom Path:", 'duplicator-pro'); ?></label>
<input
class="dup-wide-input"
type="text"
name="_package_mysqldump_path"
id="_package_mysqldump_path"
value="<?php echo esc_attr($global->package_mysqldump_path); ?>"
placeholder="<?php esc_attr_e("/usr/bin/mypath/mysqldump", 'duplicator-pro'); ?>"
>&nbsp;
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("mysqldump", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>">
</i><br>
<label><?php esc_html_e("Switch-Options:", 'duplicator-pro'); ?></label>
<div class="dup-group-option-wrapper">
<?php
$mysqldumpOptions = $global->getMysqldumpOptions();
foreach ($mysqldumpOptions as $key => $option) {
?>
<div
class="dup-group-option-item"><input type="checkbox" name="<?php echo esc_attr($option->getInputName()); ?>"
id="<?php echo esc_attr($option->getInputName()); ?>"
<?php checked($option->getEnabled()); ?>
>
--<?php echo esc_html($option->getOptionName()); ?></div>
<?php } ?>
</div>
<?php
endif; ?>
</div>
<!-- PHP OPTION -->
<div class="engine-sub-opts" id="dbengine-details-2" style="display:none; line-height: 35px; margin-top:-5px">
<label><?php esc_html_e("Process Mode", 'duplicator-pro'); ?></label>
<select name="_phpdump_mode">
<option
<?php selected($global->package_phpdump_mode, DUP_PRO_DB::PHPDUMP_MODE_MULTI); ?>
value="<?php echo (int) DUP_PRO_DB::PHPDUMP_MODE_MULTI; ?>"
>
<?php esc_html_e("Multi-Threaded", 'duplicator-pro'); ?>
</option>
<option
<?php selected($global->package_phpdump_mode, DUP_PRO_DB::PHPDUMP_MODE_SINGLE); ?>
value="<?php echo (int) DUP_PRO_DB::PHPDUMP_MODE_SINGLE; ?>"
>
<?php esc_html_e("Single-Threaded", 'duplicator-pro'); ?>
</option>
</select>&nbsp;
<i style="margin-right:7px;" class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("PHP Code Mode", 'duplicator-pro'); ?>"
data-tooltip="<?php
esc_attr_e(
'Single-Threaded mode attempts to create the entire database script in one request.
Multi-Threaded mode allows the database script to be chunked over multiple requests.
Multi-Threaded mode is typically slower but much more reliable especially for larger databases.',
'duplicator-pro'
);
?>"></i>
</div>
</td>
</tr>
<tr>
<th scope="row"><label for="_package_mysqldump_qrylimit"><?php esc_html_e("Query Size", 'duplicator-pro'); ?></label></th>
<td>
<select name="_package_mysqldump_qrylimit" id="_package_mysqldump_qrylimit" style="width:70px">
<?php
foreach (DUP_PRO_Constants::getMysqlDumpChunkSizes() as $value => $label) {
echo '<option ' . selected($global->package_mysqldump_qrylimit, $value, false) . ' value="' . (int) $value . '">'
. esc_html($label) . '</option>';
}
?>
</select>&nbsp;
<?php $tipContent = __(
'A higher limit size will speed up the database build time, however it will use more memory.
If your host has memory caps start off low.',
'duplicator-pro'
); ?>
<i style="margin-right:7px" class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("MYSQL Query Limit Size", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>">
</i>
</td>
</tr>
</table>
<!-- ===========================
ARCHIVE -->
<h3 class="title"><?php esc_html_e("Archive", 'duplicator-pro') ?> </h3>
<hr size="1" />
<!-- ===========================
ARCHIVE ENGINE -->
<table class="form-table" id="archive-build-manual">
<tr>
<th scope="row">
<label><?php esc_html_e("Compression", 'duplicator-pro'); ?></label>
</th>
<td>
<input type="radio" name="archive_compression" id="archive_compression_off" value="0"
<?php checked($global->archive_compression, false); ?> />
<label for="archive_compression_off"><?php esc_html_e("Off", 'duplicator-pro'); ?></label> &nbsp;
<input type="radio" name="archive_compression" id="archive_compression_on" value="1"
<?php checked($global->archive_compression); ?> />
<label for="archive_compression_on"><?php esc_html_e("On", 'duplicator-pro'); ?></label>
<?php $tipContent = __(
'This setting controls archive compression. The setting apply to all Archive Engine formats.
For ZipArchive this setting only works on PHP 7.0 or higher.',
'duplicator-pro'
); ?>&nbsp;
<i style="margin-right:7px;" class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Archive Compression", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>">
</i>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Archive Engine", 'duplicator-pro'); ?></label></th>
<td>
<div class="engine-radio">
<input
onclick="DupPro.UI.SetArchiveOptionStates();"
type="radio"
name="archive_build_mode" id="archive_build_mode3"
value="<?php echo (int) DUP_PRO_Archive_Build_Mode::DupArchive; ?>"
<?php checked($global->getBuildMode() == DUP_PRO_Archive_Build_Mode::DupArchive); ?>
<?php disabled(!$global->isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::DupArchive)) ?>
>
<label for="archive_build_mode3"><?php esc_html_e("DupArchive", 'duplicator-pro'); ?></label> &nbsp; &nbsp;
</div>
<div class="engine-radio <?php echo ($isShellZipAvailable) ? '' : 'engine-radio-disabled'; ?>">
<input
onclick="DupPro.UI.SetArchiveOptionStates();"
type="radio"
name="archive_build_mode"
id="archive_build_mode1"
value="<?php echo (int) DUP_PRO_Archive_Build_Mode::Shell_Exec; ?>"
<?php checked($global->getBuildMode() == DUP_PRO_Archive_Build_Mode::Shell_Exec); ?>
<?php disabled(!$global->isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::Shell_Exec)) ?>
>
<label for="archive_build_mode1"><?php esc_html_e("Shell Zip", 'duplicator-pro'); ?></label>
</div>
<div class="engine-radio">
<input
onclick="DupPro.UI.SetArchiveOptionStates();"
type="radio"
name="archive_build_mode"
id="archive_build_mode2"
value="<?php echo (int) DUP_PRO_Archive_Build_Mode::ZipArchive; ?>"
<?php checked($global->getBuildMode() == DUP_PRO_Archive_Build_Mode::ZipArchive); ?>
<?php disabled(!$global->isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::ZipArchive)) ?>
>
<label for="archive_build_mode2"><?php esc_html_e("ZipArchive", 'duplicator-pro'); ?></label>
</div>
<br style="clear:both"/>
<!-- DUPARCHIVE -->
<div class="engine-sub-opts" id="engine-details-3" style="display:none">
<?php
esc_html_e('This option creates a custom Duplicator Archive Format (.daf) archive file.', 'duplicator-pro');
echo '<br/> ';
esc_html_e('This option is fully multi-threaded and recommended for large sites or throttled servers.', 'duplicator-pro');
echo '<br/> ';
printf(
'%s <a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-work-with-daf-files-and-the-duparchive-extraction-tool')
. '" target="_blank">%s</a> ',
esc_html__('For details on how to use and manually extract the DAF format please see the ', 'duplicator-pro'),
esc_html__('online documentation.', 'duplicator-pro')
);
?>
</div>
<!-- SHELL EXEC -->
<div class="engine-sub-opts" id="engine-details-1" style="display:none">
<?php
TplMng::getInstance()->render(
'parts/settings/shellZipMessage',
['hasShellZip' => $isShellZipAvailable]
);
?>
</div>
<!-- ZIP ARCHIVE -->
<div class="engine-sub-opts" id="engine-details-2" style="display:none;">
<label><?php esc_html_e("Process Mode", 'duplicator-pro'); ?></label>
<select name="ziparchive_mode" id="ziparchive_mode" onchange="DupPro.UI.setZipArchiveMode();">
<option <?php selected($global->ziparchive_mode, DUP_PRO_ZipArchive_Mode::Multithreaded); ?>
value="<?php echo (int) DUP_PRO_ZipArchive_Mode::Multithreaded ?>">
<?php esc_html_e("Multi-Threaded", 'duplicator-pro'); ?>
</option>
<option <?php selected($global->ziparchive_mode == DUP_PRO_ZipArchive_Mode::SingleThread); ?>
value="<?php echo (int) DUP_PRO_ZipArchive_Mode::SingleThread ?>">
<?php esc_html_e("Single-Threaded", 'duplicator-pro'); ?>
</option>
</select>&nbsp;
<i style="margin-right:7px;" class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("PHP ZipArchive Mode", 'duplicator-pro'); ?>"
data-tooltip="<?php
esc_attr_e(
'Single-Threaded mode attempts to create the entire archive in one request.
Multi-Threaded mode allows the archive to be chunked over multiple requests.
Multi-Threaded mode is typically slower but much more reliable especially for larger sites.',
'duplicator-pro'
);
?>"></i>
<div id="dpro-ziparchive-mode-st">
<input type="checkbox" id="ziparchive_validation" name="ziparchive_validation"
<?php checked($global->ziparchive_validation); ?>
>
<label for="ziparchive_validation">Enable file validation</label>
</div>
<div id="dpro-ziparchive-mode-mt">
<label><?php esc_html_e("Buffer Size", 'duplicator-pro'); ?></label>
<input style="width:84px;" maxlength="4"
data-parsley-required data-parsley-errors-container="#ziparchive_chunk_size_error_container"
data-parsley-min="5" data-parsley-type="number"
type="text" name="ziparchive_chunk_size_in_mb" id="ziparchive_chunk_size_in_mb"
value="<?php echo (int) $global->ziparchive_chunk_size_in_mb; ?>"
>
<?php esc_html_e('MB', 'duplicator-pro'); ?>
<?php
$toolTipContent = __(
'Buffer size only applies to multi-threaded requests and indicates how large an archive will get before a close is registered.
Higher values are faster but can be more unstable based on the hosts max_execution time.',
'duplicator-pro'
);
?>
<i style="margin-right:7px" class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("PHP ZipArchive Buffer", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($toolTipContent); ?>"
>
</i>
<div id="ziparchive_chunk_size_error_container" class="duplicator-error-container"></div>
</div>
</div>
</td>
</tr>
</table>
<!-- ===============================
PROCESSING -->
<h3 class="title"><?php esc_html_e("Processing", 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Server Throttle", 'duplicator-pro'); ?></label></th>
<td>
<input
type="radio" name="server_load_reduction" id="server_load_reduction_off"
value="<?php echo (int) DUP_PRO_Email_Build_Mode::No_Emails; ?>"
<?php checked($global->server_load_reduction, DUP_PRO_Server_Load_Reduction::None); ?>
>
<label for="server_load_reduction_off"><?php esc_html_e("Off", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio" name="server_load_reduction" id="server_load_reduction_low"
value="<?php echo (int) DUP_PRO_Server_Load_Reduction::A_Bit; ?>"
<?php checked($global->server_load_reduction, DUP_PRO_Server_Load_Reduction::A_Bit); ?> >
<label for="server_load_reduction_low"><?php esc_html_e("Low", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio" name="server_load_reduction" id="server_load_reduction_medium"
value="<?php echo (int) DUP_PRO_Server_Load_Reduction::More; ?>"
<?php checked($global->server_load_reduction, DUP_PRO_Server_Load_Reduction::More); ?>
>
<label for="server_load_reduction_medium"><?php esc_html_e("Medium", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio" name="server_load_reduction" id="server_load_reduction_high"
value="<?php echo (int) DUP_PRO_Server_Load_Reduction::A_Lot ?>"
<?php checked($global->server_load_reduction, DUP_PRO_Server_Load_Reduction::A_Lot); ?>
>
<label for="server_load_reduction_high"><?php esc_html_e("High", 'duplicator-pro'); ?></label> &nbsp;
<p class="description">
<?php esc_html_e(
"Throttle to prevent resource complaints on budget hosts. The higher the value the slower the backup.",
'duplicator-pro'
); ?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Max Build Time", 'duplicator-pro'); ?></label></th>
<td>
<input
style="float:left;display:block;margin-right:6px;"
data-parsley-required data-parsley-errors-container="#max_package_runtime_in_min_error_container"
data-parsley-min="0"
data-parsley-type="number"
class="dup-narrow-input"
type="text"
name="max_package_runtime_in_min"
id="max_package_runtime_in_min"
value="<?php echo (int) $global->max_package_runtime_in_min; ?>"
>
<p style="margin-left:4px;"><?php esc_html_e('Minutes', 'duplicator-pro'); ?></p>
<div id="max_package_runtime_in_min_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php esc_html_e('Max build and storage time until package is auto-cancelled. Set to 0 for no limit.', 'duplicator-pro'); ?>
</p>
</td>
</tr>
</table>
<!-- ===============================
INSTALLER SETTINGS -->
<h3 id="duplicator-pro-installer-settings" class="title"><?php esc_html_e("Installer Settings", 'duplicator-pro'); ?></h3>
<hr size="1" />
<table class="form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Name", 'duplicator-pro'); ?></label></th>
<td id="installer-name-mode-option" >
<b><?php esc_html_e("Default 'Save as' name:", 'duplicator-pro'); ?></b> <br/>
<label>
<i class='fas fa-lock lock-info fa-fw'></i>
<input type="radio" name="installer_name_mode"
value="<?php echo esc_attr(DUP_PRO_Global_Entity::INSTALLER_NAME_MODE_WITH_HASH); ?>"
<?php checked($installerNameMode === DUP_PRO_Global_Entity::INSTALLER_NAME_MODE_WITH_HASH); ?> />
[name]_[hash]_[date]_installer.php <i>(<?php esc_html_e("recommended", 'duplicator-pro'); ?>)</i>
</label><br>
<label>
<i class='fas fa-lock-open lock-info fa-fw'></i>
<input type="radio" name="installer_name_mode"
value="<?php echo esc_attr(DUP_PRO_Global_Entity::INSTALLER_NAME_MODE_SIMPLE); ?>"
<?php checked($installerNameMode === DUP_PRO_Global_Entity::INSTALLER_NAME_MODE_SIMPLE); ?> />
<?php echo esc_html(DUP_PRO_Installer::DEFAULT_INSTALLER_FILE_NAME_WITHOUT_HASH); ?>
</label>
<p class="description">
<?php esc_html_e("To understand the importance and usage of the installer name, please", 'duplicator-pro') ?>
<a href="javascript:void(0)" onclick="jQuery('#dup-pro-inst-mode-details').toggle()">
<?php esc_html_e("read this section", 'duplicator-pro') ?>
</a>.
</p>
<div id="dup-pro-inst-mode-details">
<p>
<i>
<?php esc_html_e(
'Using the full hashed format provides a higher level of security by helping to prevent the discovery of the installer file.',
'duplicator-pro'
); ?>
</i> <br/>
<b><?php esc_html_e('Hashed example', 'duplicator-pro'); ?>:</b> my-name_64fc6df76c17f2023225_19990101010101_installer.php
</p>
<p>
<?php
esc_html_e(
'The Installer \'Name\' setting specifies the name of the installer used at download-time.
It\'s recommended you choose the hashed name to better protect the installer file.
Independent of the value of this setting, you can always change the name in the \'Save as\' file dialog at download-time.
If you choose to use a custom name, use a filename that is known only to you. Installer filenames must end in \'.php\'.',
'duplicator-pro'
);
?>
</p>
<p>
<?php
esc_html_e(
'It\'s important not to leave the installer files on the destination server longer than necessary.
After installing the migrated or restored site, just logon as a WordPress administrator and
follow the prompts to have the plugin remove the files.
Alternatively, you can remove them manually.',
'duplicator-pro'
);
?>
</p>
<p>
<i class="fas fa-info-circle"></i>
<?php
esc_html_e(
'Tip: Each row on the packages screen includes a copy button that copies the installer name to the clipboard.
After clicking this button, paste the installer name into the URL you\'re using to install the destination site.
This feature is handy when using the hashed installer name.',
'duplicator-pro'
);
?>
</p>
</div>
</td>
</tr>
</table>
<!-- ===============================
Installer Cleanup -->
<h3 class="title"><?php esc_html_e("Installer Cleanup", 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Mode", 'duplicator-pro'); ?></label></th>
<td>
<input
type="radio"
name="cleanup_mode"
id="cleanup_mode_Cleanup_Off"
value="<?php echo (int) DUP_PRO_Global_Entity::CLEANUP_MODE_OFF; ?>"
<?php checked($global->cleanup_mode, DUP_PRO_Global_Entity::CLEANUP_MODE_OFF); ?>
>
<label for="cleanup_mode_Cleanup_Off"><?php esc_html_e("Off", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio"
name="cleanup_mode"
id="cleanup_mode_Email_Notice"
value="<?php echo (int) DUP_PRO_Global_Entity::CLEANUP_MODE_MAIL; ?>"
<?php checked($global->cleanup_mode, DUP_PRO_Global_Entity::CLEANUP_MODE_MAIL); ?>
>
<label for="cleanup_mode_Email_Notice"><?php esc_html_e("Email Notice", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio"
name="cleanup_mode"
id="cleanup_mode_Auto_Cleanup"
value="<?php echo (int) DUP_PRO_Global_Entity::CLEANUP_MODE_AUTO; ?>"
<?php checked($global->cleanup_mode, DUP_PRO_Global_Entity::CLEANUP_MODE_AUTO); ?>
>
<label for="cleanup_mode_Auto_Cleanup"><?php esc_html_e("Auto Cleanup", 'duplicator-pro'); ?></label> &nbsp;
<p class="description">
<?php esc_html_e("Email Notice: An email will be sent daily until the installer files are removed.", 'duplicator-pro'); ?>
</p>
<p class="description">
<?php esc_html_e("Auto Cleanup: Installer files will be cleaned up automatically based on setting below.", 'duplicator-pro'); ?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Auto Cleanup", 'duplicator-pro'); ?></label></th>
<td>
<input
data-parsley-required
data-parsley-errors-container="#auto_cleanup_hours_error_container"
data-parsley-min="1"
data-parsley-type="number"
class="dup-narrow-input"
type="text"
name="auto_cleanup_hours" id="auto_cleanup_hours"
value="<?php echo (int) $global->auto_cleanup_hours; ?>"
size="7"/>
<?php esc_html_e('Hours', 'duplicator-pro'); ?>
<div id="auto_cleanup_hours_error_container" class="duplicator-error-container"></div>
<p class="description"> <?php esc_html_e('Auto cleanup will run every N hours based on value above.', 'duplicator-pro'); ?> </p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Email Address", 'duplicator-pro'); ?></label></th>
<td>
<input
data-parsley-errors-container="#cleanup_email_error_container"
data-parsley-type="email"
type="email"
name="cleanup_email"
id="cleanup_email"
value="<?php echo esc_attr($global->cleanup_email); ?>"
size="75" />
<p class="description"><?php esc_html_e('WordPress administration email address will be used if empty.', 'duplicator-pro'); ?></p>
<div id="cleanup_email_error_container" class="duplicator-error-container"></div>
</td>
</tr>
</table>
<p class="submit dpro-save-submit">
<input
type="submit" name="submit" id="submit" class="button-primary"
value="<?php esc_attr_e('Save Basic Package Settings', 'duplicator-pro') ?>" style="display: inline-block;"
>
</p>
</form>
<script>
jQuery(document).ready(function ($)
{
DupPro.UI.SetDBEngineMode = function ()
{
var isMysqlDump = $('#package_mysqldump').is(':checked');
var isPHPMode = $('#package_phpdump').is(':checked');
var isPHPChunkMode = $('#package_phpchunkingdump').is(':checked');
$('#dbengine-details-1, #dbengine-details-2').hide();
switch (true) {
case isMysqlDump :
$('#dbengine-details-1').show();
break;
case isPHPMode :
case isPHPChunkMode :
$('#dbengine-details-2').show();
break;
}
}
DupPro.UI.setZipArchiveMode = function ()
{
$('#dpro-ziparchive-mode-st, #dpro-ziparchive-mode-mt').hide();
if ($('#ziparchive_mode').val() == 0) {
$('#dpro-ziparchive-mode-mt').show();
} else {
$('#dpro-ziparchive-mode-st').show();
}
}
DupPro.UI.SetArchiveOptionStates = function ()
{
var php70 = <?php echo (version_compare(PHP_VERSION, '7', '>=') ? 'true' : 'false'); ?>;
var isShellZipSelected = $('#archive_build_mode1').is(':checked');
var isZipArchiveSelected = $('#archive_build_mode2').is(':checked');
var isDupArchiveSelected = $('#archive_build_mode3').is(':checked');
if (isShellZipSelected || isDupArchiveSelected) {
$("[name='archive_compression']").prop('disabled', false);
$("[name='ziparchive_mode']").prop('disabled', true);
} else {
$("[name='ziparchive_mode']").prop('disabled', false);
if (php70) {
$("[name='archive_compression']").prop('disabled', false);
} else {
$('#archive_compression_on').prop('checked', true);
$("[name='archive_compression']").prop('disabled', true);
}
}
$('#engine-details-1, #engine-details-2, #engine-details-3').hide();
switch (true) {
case isShellZipSelected :
$('#engine-details-1').show();
break;
case isZipArchiveSelected :
$('#engine-details-2').show();
break;
case isDupArchiveSelected :
$('#engine-details-3').show();
break;
}
DupPro.UI.setZipArchiveMode();
}
//INIT
DupPro.UI.SetArchiveOptionStates();
DupPro.UI.SetDBEngineMode();
DupPro.UI.cleanupModeRadioSwitched = function() {
if ($('#cleanup_mode_Cleanup_Off').is(":checked")){
$('#auto_cleanup_hours').attr('readonly','readonly');
$('#cleanup_email').attr('readonly','readonly');
} else if ($('#cleanup_mode_Email_Notice').is(":checked")) {
$('#auto_cleanup_hours').attr('readonly','readonly');
$("#cleanup_email").removeAttr('readonly');
} else if ($('#cleanup_mode_Auto_Cleanup').is(":checked")) {
$("#auto_cleanup_hours").removeAttr('readonly');
$("#cleanup_email").removeAttr('readonly');
}
}
$('input[type=radio][name=cleanup_mode]').change(function () {
DupPro.UI.cleanupModeRadioSwitched();
});
// We must call this also once in the beginning, after UI is loaded
DupPro.UI.cleanupModeRadioSwitched();
});
</script>

View File

@@ -0,0 +1,81 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Libs\Snap\SnapIO;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = DUP_PRO_Global_Entity::getInstance();
?>
<form
id="dup-settings-form"
action="<?php echo $ctrlMng->getCurrentLink(); ?>"
method="post"
data-parsley-validate
>
<?php $tplData['actions'][SettingsPageController::ACTION_SAVE_STORAGE_GENERAL]->getActionNonceFileds(); ?>
<table class="form-table">
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Storage", 'duplicator-pro'); ?></label></th>
<td>
<?php esc_html_e("Full Path", 'duplicator-pro'); ?>:
<?php echo SnapIO::safePath(DUPLICATOR_PRO_SSDIR_PATH); ?><br/><br/>
<input
type="checkbox"
name="_storage_htaccess_off"
id="_storage_htaccess_off"
value="1"
<?php checked($global->storage_htaccess_off); ?>
>
<label for="_storage_htaccess_off">
<?php esc_html_e("Disable .htaccess File In Storage Directory", 'duplicator-pro') ?>
</label>
<p class="description">
<?php esc_html_e("Disable if issues occur when downloading installer/archive files.", 'duplicator-pro'); ?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Max Retries", 'duplicator-pro'); ?></label></th>
<td>
<input
class="dup-narrow-input"
type="text"
name="max_storage_retries"
id="max_storage_retries"
data-parsley-required data-parsley-min="0"
data-parsley-type="number"
data-parsley-errors-container="#max_storage_retries_error_container"
value="<?php echo $global->max_storage_retries; ?>"
>
<div id="max_storage_retries_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php esc_html_e('Max upload/copy retries to attempt after failure encountered.', 'duplicator-pro'); ?>
</p>
</td>
</tr>
</table>
<p class="submit dpro-save-submit">
<input
type="submit"
name="submit"
id="submit"
class="button-primary"
value="<?php esc_attr_e('Save Storage Settings', 'duplicator-pro') ?>"
style="display: inline-block;"
>
</p>
</form>

View File

@@ -0,0 +1,102 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\SettingsPageController;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = DUP_PRO_Global_Entity::getInstance();
?>
<form
id="dup-settings-form"
action="<?php echo $ctrlMng->getCurrentLink(); ?>"
method="post"
data-parsley-validate
>
<?php $tplData['actions'][SettingsPageController::ACTION_SAVE_STORAGE_SSL]->getActionNonceFileds(); ?>
<p class="description" style="color:maroon">
<?php esc_html_e("Do not modify SSL settings unless you know the expected result or have talked to support.", 'duplicator-pro'); ?>
</p>
<table class="form-table">
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Use server's SSL certificates", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="ssl_useservercerts"
id="ssl_useservercerts"
value="1"
<?php checked($global->ssl_useservercerts); ?>
>
<p class="description">
<?php
esc_html_e(
"To use server's SSL certificates please enble it.
By default Duplicator Pro uses By default uses its own store of SSL certificates to verify the identity of remote storage sites.",
'duplicator-pro'
);
?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Disable verification of SSL certificates", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="ssl_disableverify"
id="ssl_disableverify"
value="1"
<?php checked($global->ssl_disableverify); ?>
>
<p class="description">
<?php
esc_html_e("To disable verification of a host and the peer's SSL certificate.", 'duplicator-pro');
?>
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Use IPv4 only", 'duplicator-pro'); ?></label></th>
<td>
<input
type="checkbox"
name="ipv4_only"
id="ipv4_only"
value="1"
<?php checked($global->ipv4_only); ?>
>
<p class="description">
<?php
esc_html_e(
"To use IPv4 only, which can help if your host has a broken IPv6 setup (currently only supported by Google Drive)",
'duplicator-pro'
);
?>
</p>
</td>
</tr>
</table>
<p class="submit dpro-save-submit">
<input
type="submit"
name="submit"
id="submit"
class="button-primary"
value="<?php esc_attr_e('Save Storage Settings', 'duplicator-pro') ?>"
style="display: inline-block;"
>
</p>
</form>

View File

@@ -0,0 +1,41 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Models\Storages\StoragesUtil;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<form
id="dup-settings-form"
action="<?php echo $ctrlMng::getCurrentLink(); ?>"
method="post" data-parsley-validate
>
<?php
$tplData['actions'][SettingsPageController::ACTION_SAVE_STORAGE_OPTIONS]->getActionNonceFileds();
StoragesUtil::renderGlobalOptions();
?>
<p class="submit dpro-save-submit">
<input
type="submit"
name="submit"
id="submit"
class="button-primary"
value="<?php esc_attr_e('Save Storage Settings', 'duplicator-pro') ?>"
style="display: inline-block;"
>
</p>
</form>

View File

@@ -0,0 +1,173 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\Local\LocalStorage;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var LocalStorage $storage
*/
$storage = $tplData["storage"];
/** @var int */
$maxPackages = $tplData["maxPackages"];
/** @var int */
$isFilderProtection = $tplData["isFilderProtection"];
/** @var string */
$storageFolder = $tplData["storageFolder"];
$tplMng->render('admin_pages/storages/parts/provider_head');
?>
<tr valign="top">
<th scope="row">
<?php $home_path = duplicator_pro_get_home_path(); ?>
<label onclick="jQuery('#_local_storage_folder').val('<?php echo esc_js($home_path); ?>')">
<?php esc_html_e("Storage Folder", 'duplicator-pro'); ?>
</label>
</th>
<td>
<input
data-parsley-errors-container="#_local_storage_folder_error_container"
data-parsley-required="true"
type="text"
id="_local_storage_folder"
class="dup-empty-field-on-submit"
name="_local_storage_folder"
data-parsley-pattern=".*"
data-parsley-not-core-paths="true"
value="<?php echo esc_attr($storageFolder); ?>"
>&nbsp;
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e('Server storage folder', 'duplicator-pro'); ?>"
data-tooltip="<?php $tplMng->renderEscAttr('admin_pages/storages/configs/local_storage_folder_tooltip'); ?>">
</i>
<div id="_local_storage_folder_error_container" class="duplicator-error-container"></div>
</td>
</tr>
<tr>
<th scope="row"><label for="local_filter_protection"><?php esc_html_e("Filter Protection", 'duplicator-pro'); ?></label></th>
<td>
<input
id="_local_filter_protection"
name="_local_filter_protection"
type="checkbox" <?php checked($isFilderProtection); ?>
onchange="DupPro.Storage.LocalFilterToggle()"
>&nbsp;
<label for="_local_filter_protection">
<?php esc_html_e("Filter the Storage Folder (recommended)", 'duplicator-pro'); ?>
</label>
<div style="padding-top:6px">
<i>
<?php
esc_html_e(
"When checked this will exclude the 'Storage Folder' and all of its content and sub-folders from package builds.",
'duplicator-pro'
); ?>
</i>
<div id="_local_filter_protection_message" style="display:none; color:maroon">
<i>
<?php
esc_html_e(
"Unchecking filter protection is not recommended. This setting helps to prevents packages from getting bundled in other packages.",
'duplicator-pro'
); ?>
</i>
</div>
</div>
</td>
</tr>
<tr>
<th scope="row"><label for=""><?php esc_html_e("Max Packages", 'duplicator-pro'); ?></label></th>
<td>
<label for="local_max_files">
<input
id="local_max_files"
name="local_max_files"
type="number"
value="<?php echo (int) $maxPackages; ?>"
min="0"
maxlength="4"
data-parsley-errors-container="#local_max_files_error_container"
data-parsley-required="true"
data-parsley-type="number"
data-parsley-min="0"
>
&nbsp;
<?php esc_html_e("Number of packages to keep in folder.", 'duplicator-pro'); ?><br/>
<i><?php esc_html_e("When this limit is exceeded, the oldest package will be deleted. Set to 0 for no limit.", 'duplicator-pro'); ?></i>
</label>
<div id="local_max_files_error_container" class="duplicator-error-container"></div>
</td>
</tr>
<?php $tplMng->render('admin_pages/storages/parts/provider_foot'); ?>
<script>
jQuery(document).ready(function ($) {
let validatorMsg = <?php
echo json_encode(
__(
'Storage Folder should not be root directory path, content directory path and upload directory path',
'duplicator-pro'
)
); ?>;
window.Parsley.addValidator('notCorePaths', {
requirementType: 'string',
validateString: function(value) {
<?php
$home_path = duplicator_pro_get_home_path();
$wp_upload_dir = wp_upload_dir();
$wp_upload_dir_basedir = str_replace('\\', '/', $wp_upload_dir['basedir']);
?>
var corePaths = [
'<?php echo esc_js($home_path);?>',
'<?php echo esc_js(untrailingslashit($home_path));?>',
'<?php echo esc_js($home_path . 'wp-content');?>',
'<?php echo esc_js($home_path . 'wp-content/');?>',
'<?php echo esc_js($home_path . 'wp-admin');?>',
'<?php echo esc_js($home_path . 'wp-admin/');?>',
'<?php echo esc_js($home_path . 'wp-includes');?>',
'<?php echo esc_js($home_path . 'wp-includes/');?>',
'<?php echo esc_js($wp_upload_dir_basedir);?>',
'<?php echo esc_js(trailingslashit($wp_upload_dir_basedir));?>'
];
// console.log(value);
for (var i = 0; i < corePaths.length; i++) {
if (value === corePaths[i]) {
return false;
}
}
return true;
},
messages: {
en: validatorMsg
}
});
DupPro.Storage.LocalFilterToggle = function ()
{
$("#_local_filter_protection").is(":checked")
? $("#_local_filter_protection_message").hide(400)
: $("#_local_filter_protection_message").show(400);
};
//Init
DupPro.Storage.LocalFilterToggle();
});
</script>

View File

@@ -0,0 +1,74 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\Local\LocalStorage;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var LocalStorage $storage
*/
$storage = $tplData["storage"];
/** @var int */
$maxPackages = $tplData["maxPackages"];
/** @var bool */
$purgePackages = $tplData["purgePackages"];
/** @var string */
$storageFolder = $tplData["storageFolder"];
$tplMng->render('admin_pages/storages/parts/provider_head');
?>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Location", 'duplicator-pro'); ?></label></th>
<td><?php echo esc_html($storageFolder); ?></td>
</tr>
<tr>
<th scope="row"><label for=""><?php esc_html_e("Max Packages", 'duplicator-pro'); ?></label></th>
<td>
<label for="max_default_store_files">
<input
data-parsley-errors-container="#max_default_store_files_error_container"
id="max_default_store_files"
name="max_default_store_files"
type="text"
data-parsley-type="number"
data-parsley-min="0"
data-parsley-required="true"
value="<?php echo intval($maxPackages); ?>"
maxlength="4"
>
&nbsp;<?php esc_html_e("Number of packages to keep in folder. ", 'duplicator-pro'); ?><br/>
<i><?php esc_html_e("When this limit is exceeded, the oldest package will be deleted. Set to 0 for no limit.", 'duplicator-pro'); ?></i>
</label>
<div id="max_default_store_files_error_container" class="duplicator-error-container"></div>
</td>
</tr>
<tr>
<th scope="row"><label for=""></label></th>
<td>
<label for="purge_default_package_record">
<input
name="purge_default_package_record"
<?php checked($purgePackages); ?>
class="checkbox"
value="1"
type="checkbox"
id="purge_default_package_record"
>
<i>
<?php esc_html_e("Delete associated package record when Max Packages limit is exceeded.", 'duplicator-pro'); ?></i>
</label>
</td>
</tr>
<?php $tplMng->render('admin_pages/storages/parts/provider_foot'); ?>

View File

@@ -0,0 +1,47 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\Local\LocalStorage;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var LocalStorage $storage
*/
$storage = $tplData["storage"];
/** @var int */
$maxPackages = $tplData["maxPackages"];
/** @var int */
$isFilderProtection = $tplData["isFilderProtection"];
/** @var string */
$storageFolder = $tplData["storageFolder"];
$tplMng->render('admin_pages/storages/parts/provider_head');
?>
<?php esc_html_e("Where to store on the server hosting this site.", 'duplicator-pro'); ?><br>
<?php
printf(
esc_html_x(
'The folder can be either a child of the home directory (%1$s) or be outside it as well..',
'%1$s represents the home directory path',
'duplicator-pro'
),
'<b>' . esc_html(duplicator_pro_get_home_path()) . '</b>'
); ?><br>
<?php esc_html_e("On Linux servers start with '/' (e.g. /mypath). On Windows use drive letters (e.g. E:/mypath).", 'duplicator-pro'); ?><br>
<?php esc_html_e("If you are unsure of the path, contact your hosting provider.", 'duplicator-pro'); ?><br>
<br>
<b><?php esc_html_e('Note: This will not store to your local computer unless that is where this web-site is hosted.', 'duplicator-pro'); ?></b><br>

View File

@@ -0,0 +1,36 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\UnknownStorage;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var UnknownStorage $storage
*/
$storage = $tplData["storage"];
$tplMng->render('admin_pages/storages/parts/provider_head');
?>
<tr valign="top">
<th scope="row">
<label>
<?php esc_html_e("Unknown Storage Type", 'duplicator-pro'); ?>
</label>
</th>
<td>
</td>
</tr>
<?php $tplMng->render('admin_pages/storages/parts/provider_foot');

View File

@@ -0,0 +1,119 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Models\Storages\Local\DefaultLocalStorage;
use Duplicator\Models\Storages\StoragesUtil;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var AbstractStorageEntity $storage
*/
$storage = $tplData["storage"];
/** @var int */
$storage_id = $tplData["storage_id"];
$storage_tab_url = ControllersManager::getMenuLink(
ControllersManager::STORAGE_SUBMENU_SLUG
);
$baseCopyUrl = ControllersManager::getMenuLink(
ControllersManager::STORAGE_SUBMENU_SLUG,
null,
null,
array(
ControllersManager::QUERY_STRING_INNER_PAGE => 'edit',
'action' => $tplData['actions']['copy-storage']->getKey(),
'_wpnonce' => $tplData['actions']['copy-storage']->getNonce(),
'storage_id' => $storage_id,
)
);
$newStorageUrl = ControllersManager::getMenuLink(
ControllersManager::STORAGE_SUBMENU_SLUG,
null,
null,
array(ControllersManager::QUERY_STRING_INNER_PAGE => 'edit')
);
if ($storage->getId() > 0) {
$storages = AbstractStorageEntity::getAllBySType($storage->getSType());
} else {
$storages = AbstractStorageEntity::getAll(0, 0, [StoragesUtil::class, 'sortByPriority']);
}
$storages = array_filter($storages, function (AbstractStorageEntity $s) use ($storage) {
if ($s->getId() == $storage->getId()) {
return false;
}
if ($s->getSType() == DefaultLocalStorage::getSType()) {
return false;
}
return true;
});
$storage_count = count($storages);
?>
<table class="dpro-edit-toolbar">
<tr>
<td>
<select
id="dup-copy-source-id-select"
name="duppro-source-storage-id"
<?php disabled($storage_count, 0); ?>
>
<option value="-1" selected="selected" disabled="true">
<?php esc_html_e('Copy From', 'duplicator-pro'); ?>
</option>
<?php foreach ($storages as $copy_storage) { ?>
<option value="<?php echo (int) $copy_storage->getId(); ?>">
<?php echo esc_html($copy_storage->getName()); ?> [<?php echo esc_html($copy_storage->getStypeName()); ?>]
</option>
<?php } ?>
</select>
<input
type="button"
class="button action"
value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>"
onclick="DupPro.Storage.Copy()"
<?php disabled($storage_count, 0); ?>
>
</td>
<td>
<div class="btnnav">
<a href="<?php echo esc_url($storage_tab_url); ?>" class="button">
<i class="fas fa-server fa-sm"></i> <?php esc_html_e('Providers', 'duplicator-pro'); ?>
</a>
<?php if ($storage_id != -1) : ?>
<a href="<?php echo esc_attr($newStorageUrl); ?>" class="button">
<?php esc_html_e("Add New", 'duplicator-pro'); ?>
</a>
<?php endif; ?>
</div>
</td>
</tr>
</table>
<hr class="dpro-edit-toolbar-divider"/>
<script>
jQuery(document).ready(function ($) {
// COMMON STORAGE RELATED METHODS
DupPro.Storage.Copy = function ()
{
document.location.href = <?php echo json_encode($baseCopyUrl); ?> +
'&duppro-source-storage-id=' + $("#dup-copy-source-id-select option:selected").val();
};
});
</script>

View File

@@ -0,0 +1,25 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\AbstractStorageEntity;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var AbstractStorageEntity $storage
*/
$storage = $tplData["storage"];
?>
</table>

View File

@@ -0,0 +1,24 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\AbstractStorageEntity;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var AbstractStorageEntity $storage
*/
$storage = $tplData["storage"];
?>
<table id="provider-<?php echo (int) $storage->getSType() ?>" class="provider form-table dup-remove-on-submit-if-hidden">

View File

@@ -0,0 +1,59 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\StoragePageController;
use Duplicator\Models\Storages\AbstractStorageEntity;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var AbstractStorageEntity $storage
*/
$storage = $tplData["storage"];
/** @var bool */
$failed = $tplData["failed"];
/** @var bool */
$cancelled = $tplData["cancelled"];
$containerClasses = ['dup-dlg-store-endpoint'];
if ($failed) {
$containerClasses[] = 'dup-dlg-store-endpoint-failed';
}
if ($cancelled) {
$containerClasses[] = 'dup-dlg-store-endpoint-cancelled';
}
?>
<div class="<?php echo esc_attr(implode(' ', $containerClasses)); ?>" >
<h4 class="dup-dlg-store-names">
<?php echo $storage->getStypeIcon(); ?>&nbsp;
<?php echo esc_html($storage->getStypeName()) ?>:&nbsp;
<span>
<?php echo esc_html($storage->getName()); ?>
<?php if ($failed) { ?>
&nbsp;<i>(<?php esc_html_e('failed', 'duplicator-pro'); ?>)</i>
<?php } ?>
<?php if ($cancelled) { ?>
&nbsp;<i>(<?php esc_html_e('cancelled', 'duplicator-pro'); ?>)</i>
<?php } ?>
</span>
</h4>
<div class="dup-dlg-store-links">
<?php echo $storage->getHtmlLocationLink(); ?>
</div>
<div class="dup-dlg-store-test">
<a href="<?php echo esc_url(StoragePageController::getEditUrl($storage)); ?>" target='_blank'>
[ <?php esc_html_e('Test Storage', 'duplicator-pro'); ?> ]
</a>
</div>
</div>

View File

@@ -0,0 +1,175 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Core\Addons\AddonsManager;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var AbstractStorageEntity $storage
*/
$storage = $tplData["storage"];
$sTypeSelected = ($storage->isSelectable() ? $storage->getSType() : -1);
$types = AbstractStorageEntity::getResisteredTypesByPriority();
if ($storage->getId() < 0) {
$supportedNotices = [];
?>
<select id="change-mode" name="storage_type" onchange="DupPro.Storage.ChangeMode()">
<?php foreach ($types as $type) {
$class = AbstractStorageEntity::getSTypePHPClass($type);
call_user_func([$class, 'isSelectable']);
if (!call_user_func([$class, 'isSelectable'])) {
continue;
}
if (!call_user_func([$class, 'isSupported'])) {
$supportedNotices[] = call_user_func([$class, 'getNotSupportedNotice']);
continue;
}
$name = call_user_func([$class, 'getStypeName']);
?>
<option value="<?php echo (int) $type; ?>" <?php selected($sTypeSelected, $type); ?>>
<?php echo esc_html($name) ?>
</option>
<?php } ?>
</select>
<?php
if (count($supportedNotices) > 0) { ?>
<div class="margin-top-1" >
<small class="dpro-store-type-notice"><b><?php esc_html_e('Unsupported storages: ', 'duplicator-pro'); ?></b></small><br>
<?php foreach ($supportedNotices as $notice) { ?>
<small class="dpro-store-type-notice">
<?php
echo '- ',
wp_kses(
$notice,
[
'a' => [
'href' => [],
'target' => [],
],
]
);
?>
</small>
<br>
<?php } ?>
</div>
<?php
}
} else {
?>
<span id="dup-storage-mode-fixed" data-storage-type="<?php echo (int) $storage->getSType(); ?>">
<?php echo $storage->getStypeIcon(); ?>&nbsp;<b><?php echo esc_html($storage->getStypeName()); ?></b>
</span>
<?php
} ?>
<script>
jQuery(document).ready(function ($) {
DupPro.Storage.BindParsley = function (node)
{
$('#dup-storage-form').parsley().destroy();
$('#dup-storage-form .provider input').attr('data-parsley-excluded', 'true');
$('#dup-storage-form .provider input').prop('disabled', true);
node.find('input').removeAttr('data-parsley-excluded');
node.find('input').prop('disabled', false);
$('#dup-storage-form').parsley();
};
DupPro.Storage.Autofill = function (mode) {
<?php if (AddonsManager::getInstance()->isAddonEnabled('AmazonS3Addon')) : ?>
switch (parseInt(mode)) {
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\BackblazeStorage::getSType(); ?>:
autoFillRegion(mode, 1);
break;
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\DreamStorage::getSType(); ?>:
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\VultrStorage::getSType(); ?>:
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\DigitalOceanStorage::getSType(); ?>:
autoFillRegion(mode, 0);
break;
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\WasabiStorage::getSType(); ?>:
let wasabiRegion = $("#s3_region_" + mode);
let wasabiEndpoint = $("#s3_endpoint_" + mode);
if (wasabiRegion.val().length > 0) {
wasabiEndpoint.val("s3." + wasabiRegion.val() + ".wasabisys.com");
}
wasabiRegion.change(function(e) {
let regionVal = $(this).val();
if (regionVal.length > 0) {
wasabiEndpoint.val("s3." + regionVal + ".wasabisys.com");
} else {
wasabiEndpoint.val("");
}
});
break;
}
function autoFillRegion(type, regionPos) {
let region = $("#s3_region_" + type);
let endpoint = $("#s3_endpoint_" + type);
bindEndpointToRegion(region, endpoint, regionPos);
endpoint.change(function(e) {
bindEndpointToRegion(region, endpoint, regionPos);
});
}
function bindEndpointToRegion(region, endpoint, pos) {
if (endpoint.val().length > 0) {
let regionStr = endpoint.val().replace(/.*:\/\//g,'').split(".")[pos];
region.val(regionStr);
} else {
region.val("");
}
}
<?php else : ?>
return;
<?php endif; ?>
}
// GENERAL STORAGE LOGIC
DupPro.Storage.ChangeMode = function (animateOverride) {
let mode = 0;
if ($('#dup-storage-mode-fixed').length > 0) {
mode = $('#dup-storage-mode-fixed').data('storage-type');
} else {
let optionSelected = $("#change-mode option:selected");
mode = optionSelected.val();
}
let animate = 400;
let providerConfigNode = $('#provider-' + mode);
if (arguments.length == 1) {
animate = animateOverride;
}
$('.provider').hide();
providerConfigNode.show(animate);
DupPro.Storage.BindParsley(providerConfigNode);
DupPro.Storage.Autofill(mode);
}
$('#dup-storage-form').parsley();
DupPro.Storage.ChangeMode(0);
});
</script>

View File

@@ -0,0 +1,120 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Models\Storages\AbstractStorageEntity;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var AbstractStorageEntity $storage
*/
$storage = $tplData["storage"];
$buttonDisabled = ($storage->getId() < 0 || $storage->isValid() == false);
?>
<table class="form-table">
<tr>
<th scope="row">
<label for=""><?php esc_html_e("Validation", 'duplicator-pro'); ?></label>
</th>
<td>
<button
id="button_file_test"
class="button button-large button_file_test"
type="button"
onclick="DupPro.Storage.Test(); return false;"
<?php disabled($buttonDisabled); ?>
>
<i class="fas fa-cloud-upload-alt fa-sm"></i> <?php esc_html_e('Test Storage', 'duplicator-pro'); ?>
</button>
<p>
<i><?php esc_html_e("Test creating and deleting a small file on storage.", 'duplicator-pro'); ?></i>
</p>
</td>
</tr>
</table>
<?php
$alertStorageStatus = new DUP_PRO_UI_Dialog();
$alertStorageStatus->title = __('Storage Status', 'duplicator-pro');
$alertStorageStatus->height = 185;
$alertStorageStatus->message = 'testings'; // javascript inserted message
$alertStorageStatus->initAlert();
$alertStorageStatusLong = new DUP_PRO_UI_Dialog();
$alertStorageStatusLong->title = __('Storage Status', 'duplicator-pro');
$alertStorageStatusLong->width = 800;
$alertStorageStatusLong->height = 520;
$alertStorageStatusLong->showTextArea = true;
$alertStorageStatusLong->textAreaRows = 15;
$alertStorageStatusLong->textAreaCols = 100;
$alertStorageStatusLong->message = ''; // javascript inserted message
$alertStorageStatusLong->initAlert();
?>
<script>
jQuery(document).ready(function ($) {
DupPro.Storage.Test = function ()
{
var $test_button = $('#button_file_test');
$test_button.html('<i class="fas fa-circle-notch fa-spin"></i> <?php esc_html_e('Attempting to test storage', 'duplicator-pro'); ?>');
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_storage_test',
storage_id: <?php echo (int) $storage->getId(); ?>,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_storage_test')); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
console.log('Func data',funcData);
if (funcData.success) {
if (funcData.status_msgs.length==0) {
<?php $alertStorageStatus->showAlert(); ?>
let alertMsg = "<span style='color:green'><b><input type='checkbox' class='checkbox' checked disabled='disabled'>" +
funcData.message+"</b></span>";
<?php $alertStorageStatus->updateMessage("alertMsg"); ?>
} else {
<?php $alertStorageStatusLong->showAlert(); ?>
<?php $alertStorageStatusLong->updateTextareaMessage("funcData.status_msgs"); ?>
let alertMsg = "<span style='color:green'><b><input type='checkbox' class='checkbox' checked disabled='disabled'>" +
funcData.message+"</b></span>";
<?php $alertStorageStatusLong->updateMessage("alertMsg"); ?>
}
} else {
if (funcData.status_msgs.length==0) {
<?php $alertStorageStatus->showAlert(); ?>
let alertMsg = "<i class='fas fa-exclamation-triangle'></i> "+funcData.message;
<?php $alertStorageStatus->updateMessage("alertMsg"); ?>
} else {
<?php $alertStorageStatusLong->showAlert(); ?>
<?php $alertStorageStatusLong->updateTextareaMessage("funcData.status_msgs"); ?>
let alertMsg = "<i class='fas fa-exclamation-triangle'></i> "+funcData.message;
<?php $alertStorageStatusLong->updateMessage("alertMsg"); ?>
}
}
$test_button.html('<i class="fas fa-cloud-upload-alt fa-sm"></i> <?php esc_html_e('Test Storage', 'duplicator-pro'); ?>');
return '';
},
function (result, data, funcData, textStatus, jqXHR) {
$test_button.html('<i class="fas fa-cloud-upload-alt fa-sm"></i> <?php esc_html_e('Test Storage', 'duplicator-pro'); ?>');
<?php $alertStorageStatus->showAlert(); ?>
let alertMsg = "<i class='fas fa-exclamation-triangle'></i> <?php esc_html_e('AJAX error while testing storage', 'duplicator-pro'); ?>";
<?php $alertStorageStatus->updateMessage("alertMsg"); ?>
console.log(parsedData);
return '';
}
);
}
});
</script>

View File

@@ -0,0 +1,246 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Views\AdminNotices;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $blur
*/
$blur = $tplData['blur'];
/** @var int */
$storage_id = $tplData["storage_id"];
/** @var Duplicator\Models\Storages\AbstractStorageEntity */
$storage = $tplData["storage"];
/** @var ?string */
$error_message = $tplData["error_message"];
/** @var ?string */
$success_message = $tplData["success_message"];
$relativeEditUrl = ControllersManager::getMenuLink(
ControllersManager::STORAGE_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_STORAGE,
null,
array(ControllersManager::QUERY_STRING_INNER_PAGE => 'edit')
);
$fullEditUrl = ControllersManager::getMenuLink(
ControllersManager::STORAGE_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_STORAGE,
null,
array(ControllersManager::QUERY_STRING_INNER_PAGE => 'edit'),
false
);
?>
<form
id="dup-storage-form"
class="dup-monitored-form <?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
action="<?php echo esc_url($relativeEditUrl); ?>"
method="post"
data-parsley-ui-enabled="true"
target="_self"
>
<?php $tplData['actions']['save']->getActionNonceFileds(); ?>
<input type="hidden" name="storage_id" id="storage_id" value="<?php echo (int) $storage->getId(); ?>">
<?php
$tplMng->render('admin_pages/storages/parts/edit_toolbar');
if (!is_null($error_message)) {
AdminNotices::displayGeneralAdminNotice($error_message, AdminNotices::GEN_ERROR_NOTICE, true);
} elseif (!is_null($success_message)) {
AdminNotices::displayGeneralAdminNotice($success_message, AdminNotices::GEN_SUCCESS_NOTICE, true);
}
?>
<table class="form-table top-entry">
<tr valign="top">
<th scope="row">
<label><?php esc_html_e("Name", 'duplicator-pro'); ?></label>
</th>
<td>
<?php if ($storage->isDefault()) {
esc_html_e('Default', 'duplicator-pro');
$tCont = __('The "Default" storage type is a built in type that cannot be removed.', 'duplicator-pro') . ' ' .
__(' This storage type is used by default should no other storage types be available.', 'duplicator-pro') . ' ' .
__('This storage type is always stored to the local server.', 'duplicator-pro');
?>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Default Storage Type", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tCont); ?>"
>
</i>
<?php } else { ?>
<input
data-parsley-errors-container="#name_error_container"
type="text"
id="name"
name="name"
value="<?php echo esc_attr($storage->getName()); ?>" autocomplete="off"
>
<?php } ?>
<div id="name_error_container" class="duplicator-error-container"></div>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Notes", 'duplicator-pro'); ?></label></th>
<td>
<textarea id="notes" name="notes" style="width:100%; max-width: 500px"><?php echo esc_html($storage->getNotes()); ?></textarea>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Type", 'duplicator-pro'); ?></label></th>
<td>
<?php $tplMng->render('admin_pages/storages/parts/storage_type_select'); ?>
</td>
</tr>
</table>
<hr size="1" />
<?php
if ($storage->getId() > 0) {
$storage->renderConfigFields();
} else {
$types = AbstractStorageEntity::getResisteredTypes();
foreach ($types as $type) {
AbstractStorageEntity::renderSTypeConfigFields($type);
}
}
$tplMng->render('admin_pages/storages/parts/test_button');
?>
<br style="clear:both" />
<button
id="button_save_provider"
class="button button-primary"
type="submit"
>
<?php esc_html_e('Save Provider', 'duplicator-pro'); ?>
</button>
</form>
<script>
jQuery(document).ready(function ($) {
let storageEditBaseUrl = <?php echo json_encode($fullEditUrl); ?>;
// Quick fix for submint/enter error
$(window).on('keyup keydown', function (e) {
if (!$(e.target).is('textarea'))
{
var keycode = (typeof e.keyCode != 'undefined' && e.keyCode > -1 ? e.keyCode : e.which);
if ((keycode === 13)) {
e.preventDefault();
return false;
}
}
});
// Removes the values of hidden input fields marked with class dup-empty-field-on-submit
DupPro.Storage.EmptyValues = function () {
$(':hidden .dup-empty-field-on-submit').val('');
}
// Removes tags marked with class dup-remove-on-submit-if-hidden, if they are hidden
DupPro.Storage.RemoveMarkedHiddenTags = function () {
$('.dup-remove-on-submit-if-hidden:hidden').each(function() {
$(this).remove();
});
}
DupPro.Storage.PrepareForSubmit = function () {
DupPro.Storage.EmptyValues();
if ($('#dup-storage-form').parsley().isValid()) {
// The form is about to be submitted.
DupPro.Storage.RemoveMarkedHiddenTags();
}
}
$('#dup-storage-form').submit(DupPro.Storage.PrepareForSubmit);
DupPro.Storage.AuthMessages = function () {
let reloadUrl = new URL(window.location.href);
let authMessage = reloadUrl.searchParams.get('dup-auth-message');
if (authMessage) {
DupPro.addAdminMessage(authMessage, 'notice');
}
let revokeMessage = reloadUrl.searchParams.get('dup-revoke-message');
if (revokeMessage) {
DupPro.addAdminMessage(revokeMessage, 'notice');
}
}
DupPro.Storage.RevokeAuth = function (storageId)
{
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_revoke_storage',
storage_id: storageId,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_pro_revoke_storage')); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
if (funcData.success) {
let reloadUrl = new URL(storageEditBaseUrl);
reloadUrl.searchParams.set('storage_id', storageId);
reloadUrl.searchParams.set('dup-revoke-message', funcData.message);
window.location.href = reloadUrl.href;
//location.reload();
} else {
DupPro.addAdminMessage(funcData.message, 'error');
}
return '';
}
);
}
DupPro.Storage.Authorize = function (storageId, storageType, extraData)
{
extraData.action = 'duplicator_pro_auth_storage';
extraData.storage_id = storageId;
extraData.storage_type = storageType;
extraData.nonce = '<?php echo esc_js(wp_create_nonce('duplicator_pro_auth_storage')); ?>';
Duplicator.Util.ajaxWrapper(
extraData,
function (result, data, funcData, textStatus, jqXHR) {
if (funcData.success) {
let reloadUrl = new URL(storageEditBaseUrl);
reloadUrl.searchParams.set('storage_id', funcData.storage_id);
reloadUrl.searchParams.set('dup-auth-message', funcData.message);
// set unsaved changes to false, not to trigger alert during finalization
DupPro.UI.hasUnsavedChanges = false;
window.location.href = reloadUrl.href;
} else {
DupPro.addAdminMessage(funcData.message, 'error');
}
return '';
}
);
return false;
}
// Toggles Save Provider button for existing Storages only
DupPro.UI.formOnChangeValues($('#dup-storage-form'), function() {
$('#button_file_test').prop('disabled', true);
});
//Init
DupPro.Storage.AuthMessages();
jQuery('#name').focus().select();
});
</script>

View File

@@ -0,0 +1,443 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Ajax\ServicesStorage;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Controllers\StoragePageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Models\Storages\StoragesUtil;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var DUP_PRO_Schedule_Entity $schedule
* @var bool $blur
*/
$blur = $tplData['blur'];
if (($storages = AbstractStorageEntity::getAll(0, 0, [StoragesUtil::class, 'sortDefaultFirst'])) === false) {
$storages = [];
}
$storage_count = count($storages);
$edit_storage_url = ControllersManager::getMenuLink(
ControllersManager::STORAGE_SUBMENU_SLUG,
null,
null,
array(
ControllersManager::QUERY_STRING_INNER_PAGE => StoragePageController::INNER_PAGE_EDIT,
)
);
$storage_tab_url = ControllersManager::getMenuLink(
ControllersManager::STORAGE_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_STORAGE
);
$settingsStorageUrl = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_STORAGE
);
$baseCopyUrl = ControllersManager::getMenuLink(
ControllersManager::STORAGE_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_STORAGE,
null,
array(
ControllersManager::QUERY_STRING_INNER_PAGE => 'edit',
'action' => $tplData['actions']['copy-storage']->getKey(),
'_wpnonce' => $tplData['actions']['copy-storage']->getNonce(),
)
);
?>
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar <?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
<tr>
<td>
<select id="bulk_action">
<option value="-1" ><?php esc_html_e('Bulk Actions', 'duplicator-pro'); ?></option>
<option value="<?php echo (int) ServicesStorage::STORAGE_BULK_DELETE; ?>" title="Delete selected storage endpoint(s)">
<?php esc_html_e('Delete', 'duplicator-pro'); ?>
</option>
</select>
<input type="button" class="button action" value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>" onclick="DupPro.Storage.BulkAction()">
<?php if (CapMng::can(CapMng::CAP_SETTINGS, false)) { ?>
<span class="btn-separator"></span>
<a href="<?php echo esc_attr($settingsStorageUrl); ?>" class="button grey-icon" title="<?php esc_attr_e("Settings", 'duplicator-pro') ?>">
<i class="fas fa-sliders-h fa-fw"></i>
</a>
<?php } ?>
</td>
<td>
<div class="btnnav">
<a href="<?php echo esc_url($edit_storage_url); ?>" id="duplicator-pro-add-new-storage" class="button">
<?php esc_html_e('Add New', 'duplicator-pro'); ?>
</a>
</div>
</td>
</tr>
</table>
<form
id="dup-storage-form"
action="<?php echo esc_url($storage_tab_url); ?>"
method="post"
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
>
<input type="hidden" id="dup-selected-storage" name="storage_id" value="null"/>
<!-- ====================
LIST ALL STORAGE -->
<table class="widefat storage-tbl">
<thead>
<tr>
<th style='width:10px;'>
<input type="checkbox" id="dpro-chk-all" title="Select all storage endpoints" onclick="DupPro.Storage.SetAll(this)">
</th>
<th style='width:275px;'>Name</th>
<th><?php esc_html_e('Type', 'duplicator-pro'); ?></th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
foreach ($storages as $storage) :
$i++;
$type_name = $storage->getStypeName();
$type_id = $storage->getSType();
?>
<tr id="main-view-<?php echo (int) $storage->getId() ?>"
class="storage-row <?php echo ($i % 2) ? 'alternate' : ''; ?>"
data-delete-view="<?php echo esc_attr($storage->getDeleteView(false)); ?>"
>
<td>
<?php if ($storage->isDefault()) : ?>
<input type="checkbox" disabled="disabled" />
<?php else : ?>
<input name="selected_id[]" type="checkbox" value="<?php echo (int) $storage->getId(); ?>" class="item-chk" />
<?php endif; ?>
</td>
<td>
<a href="javascript:void(0);" onclick="DupPro.Storage.Edit('<?php echo (int) $storage->getId(); ?>')">
<b><?php echo esc_html($storage->getName()); ?></b>
</a>
<div class="sub-menu">
<a href="javascript:void(0);" onclick="DupPro.Storage.Edit('<?php echo (int) $storage->getId(); ?>')">
<?php esc_html_e('Edit', 'duplicator-pro'); ?>
</a>
|
<a href="javascript:void(0);" onclick="DupPro.Storage.View('<?php echo (int) $storage->getId(); ?>');">
<?php esc_html_e('Quick View', 'duplicator-pro'); ?>
</a>
<?php if (!$storage->isDefault()) : ?>
|
<a href="javascript:void(0);" onclick="DupPro.Storage.CopyEdit('<?php echo (int) $storage->getId(); ?>');">
<?php esc_html_e('Copy', 'duplicator-pro'); ?>
</a>
|
<a href="javascript:void(0);" onclick="DupPro.Storage.deleteSingle('<?php echo (int) $storage->getId(); ?>');">
<?php esc_html_e('Delete', 'duplicator-pro'); ?>
</a>
<?php endif; ?>
</div>
</td>
<td>
<?php echo $storage->getStypeIcon() . '&nbsp;' . esc_html($storage->getStypeName()); ?>
</td>
</tr>
<?php
ob_start();
try { ?>
<tr id='quick-view-<?php echo (int) $storage->getId(); ?>' class='<?php echo ($i % 2) ? 'alternate' : ''; ?> storage-detail'>
<td colspan="3">
<b><?php esc_html_e('QUICK VIEW', 'duplicator-pro') ?></b> <br/>
<div>
<label><?php esc_html_e('Name', 'duplicator-pro') ?>:</label>
<?php echo esc_html($storage->getName()); ?>
</div>
<div>
<label><?php esc_html_e('Notes', 'duplicator-pro') ?>:</label>
<?php echo (strlen($storage->getNotes())) ? esc_html($storage->getNotes()) : esc_html__('(no notes)', 'duplicator-pro'); ?>
</div>
<div>
<label><?php esc_html_e('Type', 'duplicator-pro') ?>:</label>
<?php echo esc_html($storage->getStypeName()); ?>
</div>
<?php $storage->getListQuickView(); ?>
<button type="button" class="button" onclick="DupPro.Storage.View('<?php echo (int) $storage->getId(); ?>');">
<?php esc_html_e('Close', 'duplicator-pro') ?>
</button>
</td>
</tr>
<?php
} catch (Exception $e) {
ob_clean(); ?>
<tr id='quick-view-<?php echo intval($storage->getId()); ?>' class='<?php echo ($i % 2) ? 'alternate' : ''; ?>'>
<td colspan="3">
<?php
StoragePageController::getErrorMsg($e, true);
?>
<br><br>
<button type="button" class="button" onclick="DupPro.Storage.View('<?php echo intval($storage->getId()); ?>');">
<?php esc_html_e('Close', 'duplicator-pro') ?>
</button>
</td>
</tr>
<?php
}
$rowStr = ob_get_clean();
echo $rowStr;
endforeach; ?>
</tbody>
<tfoot>
<tr>
<th colspan="8" style="text-align:right; font-size:12px">
<?php echo esc_html__('Total', 'duplicator-pro') . ': ' . (int) $storage_count; ?>
</th>
</tr>
</tfoot>
</table>
</form>
<?php
//Select Action Alert
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('Bulk Action Required', 'duplicator-pro');
$alert1->message = __('Please select an action from the "Bulk Actions" drop down menu!', 'duplicator-pro');
$alert1->initAlert();
//Select Storage Alert
$alert2 = new DUP_PRO_UI_Dialog();
$alert2->title = __('Selection Required', 'duplicator-pro');
$alert2->message = __('Please select at least one storage to delete!', 'duplicator-pro');
$alert2->initAlert();
//Delete Dialog
$dlgDelete = new DUP_PRO_UI_Dialog();
$dlgDelete->height = 525;
$dlgDelete->title = __('Delete Storage(s)?', 'duplicator-pro');
$dlgDelete->progressText = __('Removing Storages, Please Wait...', 'duplicator-pro');
$dlgDelete->jsCallback = 'DupPro.Storage.deleteAjax()';
$dlgDelete->initConfirm();
$storage_bulk_action_nonce = wp_create_nonce("duplicator_pro_storage_bulk_actions");
?>
<script>
jQuery(document).ready(function($) {
//Shows detail view
DupPro.Storage.Edit = function (id) {
document.location.href = '<?php echo "$edit_storage_url&storage_id="; ?>' + id;
};
//Copy and edit
DupPro.Storage.CopyEdit = function (id) {
document.location.href = <?php echo json_encode($baseCopyUrl); ?> + '&duppro-source-storage-id=' + id;
};
//Shows detail view
DupPro.Storage.View = function (id) {
$('#quick-view-' + id).toggle();
$('#main-view-' + id).toggle();
};
//Select all checked items
DupPro.Storage.SelectedList = function () {
var arr = [];
$("input[name^='selected_id[]']").each(function () {
if ($(this).is(':checked')) {
arr.push($(this).val());
}
});
return arr;
};
//Sets all for deletion
DupPro.Storage.SetAll = function (chkbox) {
$('.item-chk').each(function () {
this.checked = chkbox.checked;
});
};
// Bulk action
DupPro.Storage.BulkAction = function () {
var list = DupPro.Storage.SelectedList();
var action = $('#bulk_action').val();
if (list.length === 0) {
<?php $alert2->showAlert(); ?>
return;
}
switch (action) {
case '<?php echo (int) ServicesStorage::STORAGE_BULK_DELETE; ?>':
DupPro.Storage.deleteConfirm(list);
break;
default:
<?php $alert1->showAlert(); ?>
break;
}
};
//Delete via the delete link
DupPro.Storage.deleteSingle = function(id) {
$('#dup-selected-storage').val(id);
DupPro.Storage.deleteConfirm([id]);
};
//Load the delete confirm dialog
DupPro.Storage.deleteConfirm = function(idList) {
var $rowData;
var name, id, typeName, html;
var storeCount = idList.length;
var isSingle = (storeCount == 1) ? true : false;
var dlgID = "<?php echo esc_js($dlgDelete->getID()); ?>";
var $content = $(`#${dlgID}_message`);
html = (isSingle)
? "<i><?php esc_html_e('Are you sure you want to delete this storage item?', 'duplicator-pro')?></i>"
: `<i><?php esc_html_e('Are you sure you want to delete these ${storeCount} storage items?', 'duplicator-pro')?></i>`;
// Build storage item html
html += '<div class="store-items">';
idList.forEach(v => {
html += $('#main-view-' + v).data('delete-view');
});
html += '</div>';
$content.html(html);
<?php $dlgDelete->showConfirm(); ?>
html = `<div class="schedule-area">
<b><?php esc_html_e('Linked Schedules', 'duplicator-pro')?>:</b><br/>
<small><?php esc_html_e("Schedules linked to the storage items above", 'duplicator-pro'); ?>:</small>
<div class="schedule-progress" id="${dlgID}-schedule-progress">
<i class="fas fa-circle-notch fa-spin"></i>
<?php esc_html_e('Finding Schedule Links... Please wait', 'duplicator-pro')?>
</div>
<small>
<?php
esc_html_e("To remove storage items and unlink schedules click OK. ", 'duplicator-pro');
printf(
esc_html_x(
'Schedules with asterisk%1$s will be deactivated if storage is removed.',
'%1$s is an asterisk symbol',
'duplicator-pro'
),
'<span class="maroon">*</span>'
);
?>
</small>
</div>`;
$content.append(html);
function loadSchedules(idList, dlgID){
let result = DupPro.Storage.getScheduleData(idList);
(result != null)
? $(`#${dlgID}-schedule-progress`).html(result)
: $(`#${dlgID}-schedule-progress`).html("<?php esc_html_e('- No linked schedules found -', 'duplicator-pro')?>");
}
setTimeout(loadSchedules, 100, idList, dlgID);
};
//Get the linked schedule data
DupPro.Storage.getScheduleData = function(storageIDs) {
var result = null;
var html;
$.ajax({
type: "POST",
url: ajaxurl,
async: false,
dataType: "json",
data: {
action: 'duplicator_pro_storage_bulk_actions',
perform: <?php echo (int) ServicesStorage::STORAGE_GET_SCHEDULES; ?>,
storage_ids: storageIDs,
nonce: '<?php echo esc_js($storage_bulk_action_nonce); ?>'
}
})
.done(function (data) {
//__sleepFor(1000); //Test delays
if (data.schedules !== undefined && data.schedules.length > 0) {
html = '';
data.schedules.forEach(function (schedule) {
let name = $("<div/>").text(schedule.name).html();
let asterisk = schedule.hasOneStorage ? "*" : "";
html += `<div class="schedule-item">
<i class="far fa-clock"></i> <a href="${schedule.editURL}">${name}</a> <span class="maroon">${asterisk}</span>
</div>`;
});
result = html;
}
})
.fail(function() {
result = '<i class="fas fa-exclamation-triangle"></i> <?php esc_html_e('Unable to get schedule data.', 'duplicator-pro')?>';
});
return result;
};
//Perform the delete via ajax
DupPro.Storage.deleteAjax = function () {
var dlgID = "<?php echo esc_js($dlgDelete->getID()); ?>";
var list = DupPro.Storage.SelectedList();
//Delete from the quick link
if (list.length == 0) {
var singleID = $('#dup-selected-storage').val();
list = (singleID > 0) ? [singleID] : null;
}
$(`#${dlgID}_message`).hide();
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_pro_storage_bulk_actions',
perform: <?php echo (int) ServicesStorage::STORAGE_BULK_DELETE; ?>,
storage_ids: list,
nonce: '<?php echo esc_js($storage_bulk_action_nonce); ?>'
}
})
.done(function() {$('#dup-storage-form').submit()})
.always(function() {$('#dup-selected-storage').val(null)});
};
//--------------------------
//INIT
//Name hover show menu
$("tr.storage-row").hover(
function () {
$(this).find(".sub-menu").show();
},
function () {
$(this).find(".sub-menu").hide();
}
);
});
//Used to test ajax delays
function __sleepFor(sleepDuration){
var now = new Date().getTime();
while(new Date().getTime() < now + sleepDuration){ /* Do nothing */ }
}
</script>

View File

@@ -0,0 +1,64 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\RecoveryController;
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $blur
*/
$blur = $tplData['blur'];
$recoverPackage = RecoveryPackage::getRecoverPackage();
$recoverPackageId = RecoveryPackage::getRecoverPackageId();
$recoveablePackages = RecoveryPackage::getRecoverablesPackages();
?>
<h2 class="margin-bottom-0">
<?php ViewHelper::disasterIcon(); ?>&nbsp;<?php esc_html_e("Disaster Recovery", 'duplicator-pro'); ?>
</h2>
<hr/>
<p class="margin-bottom-1">
<?php esc_html_e("Quickly restore this site to a specific Backup in time.", 'duplicator-pro'); ?>
<span class="link-style dup-pro-open-help-link">
<?php esc_html_e("Need more help?", 'duplicator-pro'); ?>
</span>
</p>
<div class="dup-pro-recovery-details-max-width-wrapper <?php echo ($blur ? 'dup-mock-blur' : ''); ?>" >
<?php if (RecoveryController::isDisallow()) { ?>
<p>
<?php esc_html_e("The import function is disabled", 'duplicator-pro'); ?>
</p>
<?php
return;
}
?>
<form id="dpro-recovery-form" method="post">
<?php
RecoveryController::renderRecoveryWidged(array(
'selector' => true,
'subtitle' => '',
'copyLink' => true,
'copyButton' => true,
'launch' => true,
'download' => true,
'info' => true,
));
?>
</form>
</div>
<?php
require_once DUPLICATOR____PATH . '/views/tools/recovery/widget/recovery-widget-scripts.php';

View File

@@ -0,0 +1,225 @@
<?php
/**
* Duplicator schedule success mail
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
use Duplicator\Utils\Email\EmailHelper;
use Duplicator\Utils\Email\EmailSummary;
/**
* Variables
*
* @var array<string, mixed> $tplData
*/
$scheduleStorageMsg = '';
if (count($tplData['schedules']) > 0 && count($tplData['storages']) > 0) {
$scheduleStorageMsg = __('There were new storages and schedules created!', 'duplicator-pro');
} elseif (count($tplData['schedules']) > 0) {
$scheduleStorageMsg = __('There were new schedules created!', 'duplicator-pro');
} elseif (count($tplData['storages']) > 0) {
$scheduleStorageMsg = __('There were new storages created!', 'duplicator-pro');
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width">
<title><?php esc_html_e('Duplicator Pro', 'duplicator-pro'); ?></title>
<style type="text/css">
a {
text-decoration: none;
}
@media only screen and (max-width: 599px) {
table.body .main-tbl {
width: 95% !important;
}
.header {
padding: 15px 15px 12px 15px !important;
}
.header img {
width: 200px !important;
height: auto !important;
}
.content {
padding: 30px 40px 20px 40px !important;
}
}
</style>
</head>
<body <?php EmailHelper::printStyle('body'); ?>>
<table <?php EmailHelper::printStyle('table body'); ?>>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<td <?php EmailHelper::printStyle('td'); ?>>
<table <?php EmailHelper::printStyle('table main-tbl'); ?>>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<td <?php EmailHelper::printStyle('td logo txt-center'); ?>>
<img
src="<?php echo esc_url(DUPLICATOR_PRO_PLUGIN_URL . 'assets/img/email-logo.png'); ?>"
alt="logo"
<?php EmailHelper::printStyle('img'); ?>
>
</td>
</tr>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<td <?php EmailHelper::printStyle('td content'); ?>>
<table <?php EmailHelper::printStyle('table main-tbl-child'); ?>>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<td <?php EmailHelper::printStyle('td'); ?>>
<h6 <?php EmailHelper::printStyle('h6'); ?>>Hi there!</h6>
<p <?php EmailHelper::printStyle('p subtitle'); ?>>
<?php
printf(
esc_html_x(
'Here\'s a quick overview of your backups in the past %s.',
'%s is the frequency of email summaries.',
'duplicator-pro'
),
esc_html(EmailSummary::getFrequencyText())
);
?>
</p>
<?php if (count($tplData['packages']) > 0) : ?>
<table <?php EmailHelper::printStyle('table stats-tbl'); ?>>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<th <?php EmailHelper::printStyle('th'); ?>>
<?php esc_html_e('By', 'duplicator-pro'); ?>
</th>
<th <?php EmailHelper::printStyle('th'); ?>>
<?php esc_html_e('Storage(s)', 'duplicator-pro'); ?>
</th>
<th <?php EmailHelper::printStyle('th stats-count-cell'); ?>>
<?php esc_html_e('Backups', 'duplicator-pro'); ?>
</th>
</tr>
<?php foreach ($tplData['packages'] as $id => $packageInfo) : ?>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<td <?php EmailHelper::printStyle('td stats-cell'); ?>>
<?php echo esc_html($packageInfo['name']); ?>
</td>
<td <?php EmailHelper::printStyle('td stats-cell'); ?>>
<?php echo esc_html($packageInfo['storages']); ?>
</td>
<td <?php EmailHelper::printStyle('td stats-cell stats-count-cell'); ?>>
<?php if ($id !== 'failed') : ?>
<span <?php EmailHelper::printStyle('txt-orange'); ?>>
<?php echo esc_html($packageInfo['count']); ?>
</span>
<?php else : ?>
<?php echo esc_html($packageInfo['count']); ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php else : ?>
<p <?php EmailHelper::printStyle('p'); ?>>
<?php esc_html_e('No backups were created in the past week.', 'duplicator-pro'); ?>
</p>
<?php endif; ?>
<?php if (strlen($scheduleStorageMsg) > 0) : ?>
<p <?php EmailHelper::printStyle('p subtitle'); ?>>
<?php echo esc_html($scheduleStorageMsg); ?>
</p>
<?php endif; ?>
<?php if (count($tplData['schedules']) > 0) : ?>
<p <?php EmailHelper::printStyle('p stats-title'); ?>>
<strong><?php esc_html_e('New Schedules:', 'duplicator-pro'); ?></strong>
</p>
<table <?php EmailHelper::printStyle('table stats-tbl'); ?>>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<th <?php EmailHelper::printStyle('th'); ?>>
<?php esc_html_e('Schedule Name', 'duplicator-pro'); ?>
</th>
<th <?php EmailHelper::printStyle('th'); ?>>
<?php esc_html_e('Storage(s)', 'duplicator-pro'); ?>
</th>
</tr>
<?php foreach ($tplData['schedules'] as $scheduleInfo) : ?>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<td <?php EmailHelper::printStyle('td stats-cell'); ?>>
<?php echo esc_html($scheduleInfo['name']); ?>
</td>
<td <?php EmailHelper::printStyle('td stats-cell'); ?>>
<?php echo esc_html($scheduleInfo['storages']); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<?php if (count($tplData['storages']) > 0) : ?>
<p <?php EmailHelper::printStyle('p stats-title'); ?>>
<strong><?php esc_html_e('New Storages:', 'duplicator-pro'); ?></strong>
</p>
<table <?php EmailHelper::printStyle('table stats-tbl'); ?>>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<th <?php EmailHelper::printStyle('th'); ?>>
<?php esc_html_e('Storage Name', 'duplicator-pro'); ?>
</th>
<th <?php EmailHelper::printStyle('th'); ?>>
<?php esc_html_e('Provider', 'duplicator-pro'); ?>
</th>
</tr>
<?php foreach ($tplData['storages'] as $storageInfo) : ?>
<tr <?php EmailHelper::printStyle('tr'); ?>>
<td <?php EmailHelper::printStyle('td stats-cell'); ?>>
<?php echo esc_html($storageInfo['name']); ?>
</td>
<td <?php EmailHelper::printStyle('td stats-cell'); ?>>
<?php echo esc_html($storageInfo['type']); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td <?php EmailHelper::printStyle('td unsubscribe'); ?>>
<?php
printf(
esc_html_x(
'This email was auto-generated and sent from %s.',
'%s is an <a> tag with a link to the current website.',
'duplicator-pro'
),
'<a href="' . esc_url(get_site_url()) . '" ' .
'style="' . esc_attr(EmailHelper::getStyle('footer-link')) . '">'
. esc_html(wp_specialchars_decode(get_bloginfo('name'))) . '</a>'
);
?>
<?php
printf(
esc_html_x(
'Learn %1$show to disable%2$s.',
'%1$s and %2$s are opening and closing link tags to the documentation.',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-disable-email-summaries/') .
'" style="' . esc_attr(EmailHelper::getStyle('footer-link')) . '">',
'</a>'
);
?>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,62 @@
<?php
/**
* Duplicator schedule success mail
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<p><?php echo esc_html($tplData['messageTitle']) ?></p>
<p>
<strong><?php esc_html_e('Package Name', 'duplicator-pro') ?>: </strong><?php echo esc_html($tplData['packageName']); ?><br/>
<strong><?php esc_html_e('Package ID', 'duplicator-pro') ?>: </strong><?php echo esc_html($tplData['packageID']); ?><br/>
<strong><?php esc_html_e('Date', 'duplicator-pro') ?>: </strong><?php echo esc_html(date_i18n('Y-m-d H:i:s')); ?><br/>
<strong><?php esc_html_e('Schedule', 'duplicator-pro') ?>: </strong><?php echo esc_html($tplData['scheduleName']); ?>
</p>
<?php if ($tplData['success']) : ?>
<p>
<strong><?php esc_html_e('Number of Files', 'duplicator-pro') ?>: </strong><?php echo esc_html($tplData['fileCount']); ?><br/>
<strong><?php esc_html_e('Package size', 'duplicator-pro') ?>: </strong><?php echo esc_html($tplData['packageSize']); ?>
</p>
<p>
<strong><?php esc_html_e('Number of tables', 'duplicator-pro') ?>: </strong><?php echo esc_html($tplData['tableCount']); ?><br/>
<strong><?php esc_html_e('DB dump size', 'duplicator-pro') ?>: </strong><?php echo esc_html($tplData['sqlSize']); ?>
</p>
<?php endif; ?>
<p>
<strong><?php esc_html_e('Storages', 'duplicator-pro') ?>: </strong>
<?php foreach ($tplData['storageNames'] as $storageName) : ?>
<br/> - <?php echo esc_html($storageName); ?>
<?php endforeach; ?>
</p>
<p>
<?php
printf(
esc_html_x(
'To go to the "Packages" screen %1$sclick here%2$s.',
'%1$s and %2$s represent the opening and closing anchor tags (<a> and </a>)',
'duplicator-pro'
),
'<a href="' . esc_url($tplData['packagesLink']) . '" target="_blank">',
'</a>'
);
?>
</p>
<?php if ($tplData['logExists']) : ?>
<p>
<?php esc_html_e('Log is attached.', 'duplicator-pro'); ?>
</p>
<?php endif; ?>

View File

@@ -0,0 +1,22 @@
<?php
/**
* Duplicator page header
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
</div>
<?php
require_once DUPLICATOR____PATH . '/views/parts/ajax-loader.php';

View File

@@ -0,0 +1,24 @@
<?php
/**
* Duplicator page header
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
require_once(DUPLICATOR____PATH . '/assets/js/javascript.php');
?>
<div class="wrap">
<?php
$tplMng->render('page/page_main_title');

View File

@@ -0,0 +1,22 @@
<?php
/**
* Duplicator page header
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<h1>
<?php echo esc_html($tplData['pageTitle']); ?>
</h1>

View File

@@ -0,0 +1,62 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$tooltipTitle = esc_attr__('Package creation', 'duplicator-pro');
$tooltipContent = esc_attr__(
'This will create a new package. If a package is currently running then this button will be disabled.',
'duplicator-pro'
);
?>
<div class="dup-section-package-create dup-flex-content">
<span>
<?php esc_html_e('Last backup:', 'duplicator-pro'); ?>
<span class="dup-last-backup-info">
<?php
echo wp_kses(
$tplData['lastBackupString'],
[
'b' => [],
'span' => [
'class' => [],
],
]
);
?>
</span>
</span>
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<span
class="dup-new-package-wrapper"
data-tooltip-title="<?php echo esc_attr($tooltipTitle); ?>"
data-tooltip="<?php echo esc_attr($tooltipContent); ?>"
>
<a
id="dup-pro-create-new"
class="button button-primary <?php echo DUP_PRO_Package::isPackageRunning() ? 'disabled' : ''; ?>"
href="<?php echo esc_url(PackagesPageController::getInstance()->getPackageBuildS1Url()); ?>"
>
<?php esc_html_e('Create New', 'duplicator-pro'); ?>
</a>
</span>
<?php } ?>
</div>

View File

@@ -0,0 +1,49 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\PackagesPageController;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var DUP_PRO_Package[] $packages
*/
$packages = $tplData['packages'];
?>
<hr class="separator" >
<div class="dup-section-last-packages">
<p>
<b><?php esc_html_e('Recently Packages', 'duplicator-pro'); ?></b>
</p>
<?php if (count($packages) > 0) { ?>
<ul>
<?php foreach ($packages as $package) {
$createdTime = strtotime($package->getCreated());
$createdDate = date(get_option('date_format'), $createdTime);
$createdHours = date(get_option('time_format'), $createdTime);
?>
<li>
<a href="<?php echo esc_url(PackagesPageController::getInstance()->getPackageDetailsURL($package->ID)); ?>">
<?php echo esc_html($package->Name); ?>
</a> - <i class="gary" ><?php echo esc_html($createdDate . ' ' . $createdHours); ?></i>
</li>
<?php } ?>
</ul>
<?php } ?>
<p class="dup-packages-counts">
<?php printf(esc_html__('Packages: %1$d, Failures: %2$d', 'duplicator-pro'), (int) $tplData['totalPackages'], (int) $tplData['totalFailures']); ?>
</p>
</div>

View File

@@ -0,0 +1,57 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var array{name: string,slug: string,more: string,pro: array{file: string}} $plugin
*/
$plugin = $tplData['plugin'];
/** @var string */
$installUrl = $tplData['installUrl'];
$moreUrl = $plugin['more'] . '?' . http_build_query([
'utm_medium' => 'link',
'utm_source' => 'duplicatorplugin',
'utm_campaign' => 'duplicatordashboardwidget',
]);
?>
<div class="dup-section-recommended">
<hr>
<div class="dup-flex-content" >
<div>
<span class="dup-recommended-label">
<?php esc_html_e('Recommended Plugin:', 'duplicator-pro'); ?>
</span>
<b><?php echo esc_html($plugin['name']); ?></b>
-
<span class="action-links">
<?php if (CapMng::can('install_plugins', false) && CapMng::can('activate_plugins', false)) { ?>
<a href="<?php echo esc_url($installUrl); ?>"><?php esc_html_e('Install', 'duplicator-pro'); ?></a>
<?php } ?>
<a href="<?php echo esc_url($moreUrl); ?>" target="_blank" ><?php
esc_html_e('Learn More', 'duplicator-pro');
?></a>
</span>
</div>
<div>
<button type="button" id="dup-dash-widget-section-recommended" title="<?php esc_html_e('Dismiss recommended plugin', 'duplicator-pro'); ?>">
<span class="dashicons dashicons-no-alt"></span>
</button>
</div>
</div>
</div>

View File

@@ -0,0 +1,132 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Package\Recovery\RecoveryPackage;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$templatesURL = ControllersManager::getMenuLink(
ControllersManager::TOOLS_SUBMENU_SLUG,
ToolsPageController::L2_SLUG_TEMPLATE
);
$recoveryURl = ControllersManager::getMenuLink(
ControllersManager::TOOLS_SUBMENU_SLUG,
ToolsPageController::L2_SLUG_RECOVERY
);
if (
!CapMng::can(CapMng::CAP_SCHEDULE, false) &&
!CapMng::can(CapMng::CAP_STORAGE, false) &&
!CapMng::can(CapMng::CAP_CREATE, false) &&
!CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)
) {
return;
}
?>
<hr class="separator" >
<div class="dup-section-sections">
<ul>
<?php if (CapMng::can(CapMng::CAP_SCHEDULE, false)) { ?>
<li class="dup-flex-content">
<span class="dup-section-label-fixed-width" >
<span class="dashicons dashicons-update gary"></span>
<a href="<?php echo esc_url(ControllersManager::getMenuLink(ControllersManager::SCHEDULES_SUBMENU_SLUG)); ?>"><?php
echo esc_html(sprintf(
_n(
'%s Schedule',
'%s Schedules',
$tplData['numSchedules'],
'duplicator-pro'
),
$tplData['numSchedules']
));
?></a>
</span>
<span>
<?php esc_html_e('Enabled', 'duplicator-pro'); ?>:
<b class="<?php echo ($tplData['numSchedulesEnabled'] ? 'green' : 'maroon'); ?>">
<?php echo (int) $tplData['numSchedulesEnabled']; ?>
</b>
<?php if (strlen($tplData['nextScheduleString'])) { ?>
- <?php esc_html_e('Next', 'duplicator-pro'); ?>: <b><?php echo esc_html($tplData['nextScheduleString']); ?></b>
<?php } ?>
</span>
</li>
<?php } ?>
<?php if (CapMng::can(CapMng::CAP_STORAGE, false)) { ?>
<li>
<span class="dup-section-label-fixed-width" >
<span class="dashicons dashicons-database gary"></span>
<a href="<?php echo esc_url(ControllersManager::getMenuLink(ControllersManager::STORAGE_SUBMENU_SLUG)); ?>"><?php
echo esc_html(sprintf(
_n(
'%s Storage',
'%s Storages',
$tplData['numStorages'],
'duplicator-pro'
),
$tplData['numStorages']
));
?>
</a>
</span>
</li>
<?php } ?>
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<li>
<span class="dup-section-label-fixed-width" >
<span class="dashicons dashicons-admin-settings gary"></span>
<a href="<?php echo esc_url($templatesURL); ?>"><?php
echo esc_html(sprintf(
_n(
'%s Template',
'%s Templates',
$tplData['numTemplates'],
'duplicator-pro'
),
$tplData['numTemplates']
));
?>
</a>
</span>
</li>
<?php } ?>
<?php if (CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) { ?>
<li class="dup-flex-content">
<span class="dup-section-label-fixed-width" >
<span class="dashicons dashicons-image-rotate gary"></span>
<a href="<?php echo esc_url($recoveryURl); ?>" ><?php
esc_html_e('Recovery Point', 'duplicator-pro');
?>
</a>
</span>
<span>
<?php if (RecoveryPackage::getRecoverPackageId() === false) { ?>
<span class="maroon"><b><?php esc_html_e('Not set', 'duplicator-pro'); ?></b></span>
<?php } else { ?>
<span class="green"><b><?php esc_html_e('Set On', 'duplicator-pro'); ?></b></span>&nbsp;
<b><?php echo esc_html($tplData['recoverDateString']); ?></b>
<?php } ?>
</span>
</li>
<?php } ?>
</ul>
</div>

View File

@@ -0,0 +1,45 @@
<?php
/**
* Admin Notifications template.
*
* Variables
*
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
defined('ABSPATH') || exit;
?>
<div id="dup-notifications">
<div class="dup-notifications-header">
<div class="dup-notifications-bell">
<img src="<?php echo esc_url(DUPLICATOR_PRO_PLUGIN_URL . 'assets/img/notification-bell.svg') ?>"/>
<span class="wp-ui-notification dup-notifications-circle"></span>
</div>
<div class="dup-notifications-title"><?php esc_html_e('Notifications', 'duplicator-pro'); ?></div>
</div>
<div class="dup-notifications-body">
<a class="dismiss" title="<?php esc_attr_e('Dismiss this message', 'duplicator-pro'); ?>"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
<?php if (count($tplData['notifications']) > 1) : ?>
<div class="navigation">
<a class="prev">
<span class="screen-reader-text"><?php esc_attr_e('Previous message', 'duplicator-pro'); ?></span>
<span aria-hidden="true">&lsaquo;</span>
</a>
<a class="next">
<span class="screen-reader-text"><?php esc_attr_e('Next message', 'duplicator-pro'); ?></span>
<span aria-hidden="true">&rsaquo;</span>
</a>
</div>
<?php endif; ?>
<div class="dup-notifications-messages">
<?php foreach ($tplData['notifications'] as $notification) {
$tplMng->render('parts/Notifications/single-message', $notification);
} ?>
</div>
</div>
</div>

View File

@@ -0,0 +1,26 @@
<?php
/**
* Admin Notifications content.
*
* Variables
*
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
defined('ABSPATH') || exit;
?>
<div class="dup-notifications-message" data-message-id="<?php echo esc_attr($tplData['id']); ?>;">
<h3 class="dup-notifications-title"><?php echo esc_html($tplData['title']); ?></h3>
<div class="dup-notifications-content">
<?php echo $tplData['content']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<?php foreach ($tplData['btns'] as $btn) : ?>
<a
href="<?php echo esc_attr($btn['url']); ?>"
class="button button-<?php echo esc_attr($btn['type']); ?>"
<?php echo $btn['target'] === '_blank' ? 'target="_blank"' : ''; ?>>
<?php echo esc_html($btn['text']); ?>
</a>
<?php endforeach; ?>
</div>

View File

@@ -0,0 +1,38 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Utils\Help\Help;
use Duplicator\Libs\Snap\SnapJson;
defined("ABSPATH") || exit;
/**
* Variables
*
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$helpPageUrl = SnapJson::jsonEncode(Help::getHelpPageUrl());
?>
<script>
jQuery(document).ready(function ($) {
$('.duplicator-pro-help-open').click(function () {
if (Duplicator.Help.isDataLoaded()) {
Duplicator.Help.Display();
} else {
Duplicator.Help.Load('<?php echo esc_url_raw($helpPageUrl); ?>');
}
});
});
</script>
<div id="dup-meta-screen"></div>
<div class="dup-header">
<img src="<?php echo esc_url(DUPLICATOR_PRO_PLUGIN_URL . 'assets/img/duplicator-header-logo.svg'); ?>" alt="Duplicator Logo" >
<button class="duplicator-pro-help-open">
<i class="fa-regular fa-question-circle"></i>
</button>
</div>

View File

@@ -0,0 +1,467 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Package\Create\BuildComponents;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$activeComponents = isset($tplData['components']) ? $tplData['components'] : [];
$archiveFilterOn = isset($tplData['archiveFilterOn']) ? $tplData['archiveFilterOn'] : false;
$archiveFilterDirs = isset($tplData['archiveFilterDirs']) ? $tplData['archiveFilterDirs'] : '';
$archiveFilterFiles = isset($tplData['archiveFilterFiles']) ? $tplData['archiveFilterFiles'] : '';
$archiveFilterPaths = strlen($archiveFilterDirs) > 0 && strlen($archiveFilterFiles) > 0
? $archiveFilterDirs . ';' . $archiveFilterFiles : $archiveFilterDirs . $archiveFilterFiles;
$archiveFilterPaths = str_replace(';', ";\n", $archiveFilterPaths);
$archiveFilterExtensions = isset($tplData['archiveFilterExtensions']) ? $tplData['archiveFilterExtensions'] : '';
$licenseDisabledClass = License::can(License::CAPABILITY_PACKAGE_COMPONENTS_PLUS) ? '' : 'disabled';
$pathFiltersTooltip = __('File filters allow you to exclude files and folders from the package.', 'duplicator-pro') . ' ' .
__('To enable path and extension filters check the checkbox.', 'duplicator-pro') . ' ' .
__('Enter the full path of the files and folders you want to exclude from the package as a semicolon (;) seperated list.', 'duplicator-pro');
$extensionFilterTooltip = __(
"File extension filters allow you to exclude files with certain file extensions from the package e.g. zip;rar;pdf etc.",
'duplicator-pro'
) . ' ' . __("Enter the file extensions you want to exclude from the package as a semicolon (;) seperated list.", 'duplicator-pro');
?>
<div class="dup-package-components">
<div class="component-section">
<div class="section-title">
<span>
<?php esc_html_e('Components', 'duplicator-pro'); ?>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e('Package Components', 'duplicator-pro'); ?>"
data-tooltip="<?php $tplMng->render('parts/filters/package_components_tootip'); ?>"
aria-expanded="false"></i>
</span>
</div>
<div class="components-shortcut-select">
<div class="dup-radio-button-group-wrapper" >
<?php foreach (BuildComponents::COMPONENTS_ACTIONS as $action) {
$inputId = 'dup-component-shortcut-action-' . $action;
?>
<input
type="radio"
id="<?php echo esc_attr($inputId); ?>"
name="auto-select-components"
class="dup-components-shortcut-radio"
value="<?php echo esc_html($action); ?>"
<?php checked($action === BuildComponents::getActionFromComponents($activeComponents)); ?>
>
<label
<?php echo in_array($action, BuildComponents::COMPONENTS_PLUS_ACTIONS) ? 'class="' . esc_attr($licenseDisabledClass) . '"' : ''; ?>
for="<?php echo esc_attr($inputId); ?>"
>
<?php echo esc_html(BuildComponents::getActionLabel($action)); ?>
</label>
<?php } ?>
</div>
</div>
<ul class="custom-components-select">
<?php foreach (BuildComponents::COMPONENTS as $component) { ?>
<li>
<label class="<?php echo in_array($component, BuildComponents::SUB_OPTIONS) ? 'secondary license-disabled' : 'license-disabled' ?>">
<input
type="checkbox"
<?php echo !in_array($component, BuildComponents::SUB_OPTIONS) ? 'data-parsley-multiple="package_components"' : '' ?>
name="<?php echo esc_attr($component) ?>"
id="<?php echo esc_attr($component) ?>"
class="dup-components-checkbox"
<?php checked(in_array($component, $activeComponents)); ?>
> <?php echo esc_html(BuildComponents::getLabel($component)); ?>
</label>
</li>
<?php } ?>
</ul>
<span id="components_error_container" class="duplicator-error-container" ></span>
</div>
<div class="filter-section">
<div class="filters">
<div class="section-title">
<span><?php esc_html_e('Filters', 'duplicator-pro'); ?> (&nbsp;<label>
<input id="filter-on"
name="filter-on"
type="checkbox" <?php checked($archiveFilterOn); ?>
> Enable
</label>&nbsp;)
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e('File Filters', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($pathFiltersTooltip); ?>""
aria-expanded="false"
>
</i>
</span>
<div class="filter-links">
<a href="#" data-filter-path="<?php echo esc_attr(SnapIO::trailingslashit(DUP_PRO_Archive::getOriginalPaths('home'))); ?>">
[root path]
</a>
<a href="#" data-filter-path="<?php echo esc_attr(SnapIO::trailingslashit(DUP_PRO_Archive::getOriginalPaths('wpcontent'))); ?>">
[wp-content]
</a>
<a href="#" data-filter-path="<?php echo esc_attr(SnapIO::trailingslashit(DUP_PRO_Archive::getOriginalPaths('uploads'))); ?>">
[wp-uploads]
</a>
<a href="#" data-filter-path="<?php echo esc_attr(SnapIO::trailingslashit(DUP_PRO_Archive::getOriginalPaths('wpcontent')) . 'cache/'); ?>">
[cache]
</a>
<a href="#" id="clear-path-filters">(clear)</a>
</div>
</div>
<textarea
id="filter-paths"
name="filter-paths"
placeholder="/full_path/dir/;&#10;/full_path/file;"
readonly><?php echo esc_html($archiveFilterPaths); ?></textarea>
<div class="section-title">
<span>
<?php esc_html_e('File Extensions', 'duplicator-pro'); ?>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e('File Extensions', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($extensionFilterTooltip); ?>"
aria-expanded="false"></i>
</span>
<div class="filter-links">
<a href="#" data-filter-exts="avi;mov;mp4;mpeg;mpg;swf;wmv;aac;m3u;mp3;mpa;wav;wma">[media]</a>
<a href="#" data-filter-exts="zip;rar;tar;gz;bz2;7z">[archive]</a>
<a href="#" id="clear-extension-filters">(clear)</a>
</div>
</div>
<textarea id="filter-exts" name="filter-exts" placeholder="ext1;ext2;ext3;" readonly><?php echo esc_html($archiveFilterExtensions); ?></textarea>
</div>
<div class="db-only-message">
<?php
echo wp_kses(
__(
"<b>Overview:</b><br> This advanced option excludes all files from the archive.
Only the database and a copy of the installer.php will be included in the archive.zip file.
The option can be used for backing up and moving only the database.",
'duplicator-pro'
),
array(
'b' => array(),
'br' => array(),
)
);
echo '<br/><br/>';
echo wp_kses(
__(
"<b><i class='fa fa-exclamation-circle'></i> Notice:</b><br/>
Installing only the database over an existing site may have unintended consequences.
Be sure to know the state of your system before installing the database without the associated files.",
'duplicator-pro'
),
array(
'b' => array(),
'i' => array('class'),
'br' => array(),
)
);
echo ' ';
esc_html_e(
"For example, if you have WordPress 5.6 on this site and you copy this site's database to a host that has WordPress 5.8 files
then the source code of the files will not be in sync with the database causing possible errors.
This can also be true of plugins and themes.
When moving only the database be sure to know the database will be compatible with ALL source code files.
Please use this advanced feature with caution!",
'duplicator-pro'
);
echo '<br/><br/>';
echo wp_kses(
__("<b>Install Time:</b><br> When installing a database only package please visit the ", 'duplicator-pro'),
array(
'b' => array(),
'br' => array(),
)
);
?>
<a href="<?php echo esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'database-install') ?>" target="_blank">
<?php esc_html_e('database only quick start', 'duplicator-pro'); ?>
</a>
</div>
</div>
</div>
<div class="dup-tabs-opts-help">
<?php
esc_html_e("The directories, extensions and files above will be be exclude from the archive file if enable is checked.", "duplicator-pro");
echo "<br/>";
esc_html_e("Use full path for directories or specific files.", "duplicator-pro");
echo " <b>";
esc_html_e("Use filenames without paths to filter same-named files across multiple directories.", "duplicator-pro");
echo "</b>";
echo "<br/>";
esc_html_e("Use semicolons to separate all items. Use # to comment a line.", "duplicator-pro");
if (!License::can(License::CAPABILITY_PACKAGE_COMPONENTS_PLUS)) { ?>
<div id="dup-upgrade-license-info" class="margin-top-1" >
<?php
printf(
esc_html_x(
'The %1$s and %2$s options are not included in your license plan.',
'%1$s and %2$s are the options not included in the license.',
'duplicator-pro'
),
'<b>' . esc_html(BuildComponents::getActionLabel(BuildComponents::COMP_ACTION_MEDIA)) . '</b>',
'<b>' . esc_html(BuildComponents::getActionLabel(BuildComponents::COMP_ACTION_CUSTOM)) . '</b>'
);
?>
<br>
<?php
printf(
esc_html_x(
'To enable advanced options please %1$supgrade your license%2$s.',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link.',
'duplicator-pro'
),
'<a href="' . esc_url(License::getUpsellURL()) . '" target="_blank">',
'</a>'
);
?>
</div>
<?php } ?>
</div>
<script>
jQuery(document).ready(function($)
{
$('#package_component_db').attr('data-parsley-required', 'true');
$('#package_component_db').attr('data-parsley-mincheck', '1');
$('#package_component_db').attr('data-parsley-errors-container', '#components_error_container');
$('#package_component_db')
.attr('data-parsley-required-message', '<?php echo esc_js(__("Please select at least one component.", "duplicator-pro")); ?>');
$('.dup-package-components .component-section input[type=checkbox]').on('change', function () {
$('#package_component_db').parsley().validate();
});
DupPro.Pack.ToggleFileFilters = function ()
{
if ($("#filter-on").is(':checked')) {
$('#dup-archive-filter-file').show();
$('#filter-exts, #filter-paths').prop('readonly', false);
} else {
$('#dup-archive-filter-file').hide();
$('#filter-exts, #filter-paths').prop('readonly', true);
}
};
DupPro.Pack.ToggleDBExcluded = function () {
if (!$('#package_component_db').is(":checked")) {
$('.filter-db-tab').hide()
} else {
$('.filter-db-tab').show()
}
}
DupPro.Pack.ToggleDBOnly = function () {
let allComponentCheckboxes = $('.dup-package-components .component-section input[type=checkbox]');
if (allComponentCheckboxes.filter(':checked').length === 1 && $('#package_component_db').is(":checked")) {
$("#dup-archive-db-only").show();
$('.filters').hide();
$('.db-only-message').show();
} else {
$("#dup-archive-db-only").hide();
$('.filters').show();
$('.db-only-message').hide();
}
}
DupPro.Pack.ToggleMediaOnly = function () {
let allComponentCheckboxes = $('.dup-package-components .component-section input[type=checkbox]');
if (allComponentCheckboxes.filter(':checked').length === 1 && $('#package_component_uploads').is(":checked")) {
$("#dup-archive-media-only").show();
} else {
$("#dup-archive-media-only").hide();
}
}
DupPro.Pack.SetDBOnly = function () {
$('.dup-components-checkbox').prop('checked', false);
$('.custom-components-select label').addClass('disabled');
$('#package_component_db').prop('checked', true);
}
DupPro.Pack.SetMediaOnly = function () {
$('.dup-components-checkbox').prop('checked', false);
$('.custom-components-select label').addClass('disabled');
$('#package_component_uploads').prop('checked', true);
}
DupPro.Pack.SetDefault = function () {
$('.dup-components-checkbox').prop('checked', false);
$('label:not(.secondary) .dup-components-checkbox').prop('checked', true);
$('.custom-components-select label').addClass('disabled');
}
DupPro.Pack.SetCustom = function () {
$('.custom-components-select label').removeClass('disabled');
}
DupPro.Pack.ToggleComponentsSelect = function () {
let checkedSelect = $('.dup-components-shortcut-radio:checked').val();
console.log(checkedSelect);
switch (checkedSelect) {
case 'all':
DupPro.Pack.SetDefault();
break;
case 'database':
DupPro.Pack.SetDBOnly();
break;
case 'media':
DupPro.Pack.SetMediaOnly();
break;
case 'custom':
DupPro.Pack.SetCustom();
break;
}
$('.dup-components-checkbox').trigger('change');
}
DupPro.Pack.SetComponentsSelect = function () {
let allComponentCheckboxes = $('.dup-components-checkbox');
let checkedComponentsCount = allComponentCheckboxes.filter(':checked').length;
let activeOnlyDisabled = (!$('#package_component_plugins_active').is(":checked") && !$('#package_component_themes_active').is(":checked"));
if ( checkedComponentsCount === (allComponentCheckboxes.length - 2) && activeOnlyDisabled) {
$('#dup-component-shortcut-action-all').prop('checked', true);
} else if (checkedComponentsCount === 1 && $('#package_component_db').is(":checked")) {
$('#dup-component-shortcut-action-database').prop('checked', true);
} else if (checkedComponentsCount === 1 && $('#package_component_uploads').is(":checked")) {
$('#dup-component-shortcut-action-media').prop('checked', true);
} else {
$('#dup-component-shortcut-action-custom').prop('checked', true);
}
DupPro.Pack.ToggleComponentsSelect();
}
DupPro.Pack.ToggleActivePlugins = function () {
let activePluginsInput = $('#package_component_plugins_active');
if (activePluginsInput.parent().hasClass('disabled')) {
activePluginsInput.prop('disabled', true);
return;
}
if (!$('#package_component_plugins').is(':checked')) {
activePluginsInput.prop('disabled', true);
activePluginsInput.prop('checked', false);
} else {
activePluginsInput.prop('disabled', false);
}
}
DupPro.Pack.ToggleActiveThemes = function () {
let activeThemesInput = $('#package_component_themes_active');
if (activeThemesInput.parent().hasClass('disabled')) {
activeThemesInput.prop('disabled', true);
return;
}
if (!$('#package_component_themes').is(':checked')) {
activeThemesInput.prop('disabled', true);
activeThemesInput.prop('checked', false);
} else {
activeThemesInput.prop('disabled', false);
}
}
DupPro.Pack.ToggleFileFilters();
DupPro.Pack.ToggleActiveThemes();
DupPro.Pack.ToggleActivePlugins();
DupPro.Pack.ToggleDBExcluded();
DupPro.Pack.ToggleDBOnly()
DupPro.Pack.SetComponentsSelect();
$('a[data-filter-path]').click(function (e) {
e.preventDefault()
if ($('#filter-paths').is("[readonly]")) {
return;
}
let currentVal = $('#filter-paths').val()
let newVal = currentVal.length > 0 ? currentVal + ";\n" + $(this).data('filter-path') : $(this).data('filter-path')
$('#filter-paths').val(newVal)
})
$('#clear-path-filters').click(function (e) {
e.preventDefault()
if ($('#filter-paths').is("[readonly]")) {
return;
}
$('#filter-paths').val('')
})
$('a[data-filter-exts]').click(function (e) {
e.preventDefault()
if ($('#filter-exts').is("[readonly]")) {
return;
}
let currentVal = $('#filter-exts').val()
let newVal = currentVal.length > 0 ? currentVal + ";" + $(this).data('filter-exts') : $(this).data('filter-exts')
$('#filter-exts').val(newVal)
})
$('#clear-extension-filters').click(function (e) {
e.preventDefault()
if ($('#filter-exts').is("[readonly]")) {
return;
}
$('#filter-exts').val('')
})
$('#filter-on').change(DupPro.Pack.ToggleFileFilters)
$('#package_component_db').change(function () {
DupPro.Pack.ToggleDBExcluded();
})
$('.dup-components-shortcut-radio').change(function () {
DupPro.Pack.ToggleComponentsSelect();
})
$('.dup-components-checkbox').change(function(){
DupPro.Pack.ToggleDBOnly()
DupPro.Pack.ToggleMediaOnly()
})
$('#package_component_plugins').change(function () {
DupPro.Pack.ToggleActivePlugins();
});
$('#package_component_themes').change(function () {
DupPro.Pack.ToggleActiveThemes();
});
});
</script>

View File

@@ -0,0 +1,70 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Package\Create\BuildComponents;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<p>
<?php esc_html_e('Package components allow you to include/exclude differents part of your WordPress installation in the package.', 'duplicator-pro'); ?>
</p>
<ul>
<li>
<b><?php echo esc_html(BuildComponents::getLabel(BuildComponents::COMP_DB)); ?></b>:
<?php esc_html_e('Include the database in the package.', 'duplicator-pro'); ?>
</li>
<li>
<b><?php echo esc_html(BuildComponents::getLabel(BuildComponents::COMP_CORE)); ?></b>:
<?php esc_html_e('Includes WordPress core files in the package (e.g. wp-include, wp-admin wp-login.php and other.', 'duplicator-pro'); ?>
</li>
<li>
<b><?php echo esc_html(BuildComponents::getLabel(BuildComponents::COMP_PLUGINS)); ?></b>:
<?php
printf(
esc_html_x(
'Include the plugins in the package. With the %1$sactive only%2$s option enabled, only active plugins will be included in the package.',
'%1$s and %2$s represent opening and closing bold (<b> and </b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<b><?php echo esc_html(BuildComponents::getLabel(BuildComponents::COMP_THEMES)); ?></b>:
<?php
printf(
esc_html_x(
'Include the themes in the package. With the %1$sactive only%2$s option enabled, only active themes will be included in the package.',
'%1$s and %2$s represent opening and closing bold (<b> and </b>) tags',
'duplicator-pro'
),
'<b>',
'</b>'
);
?>
</li>
<li>
<b><?php echo esc_html(BuildComponents::getLabel(BuildComponents::COMP_UPLOADS)); ?></b>:
<?php esc_html_e('Include the \'uploads\' folder.', 'duplicator-pro'); ?>
</li>
<li>
<b><?php echo esc_html(BuildComponents::getLabel(BuildComponents::COMP_OTHER)); ?></b>:
<?php esc_html_e('Include non-WordPress files and folders in the root directory.', 'duplicator-pro'); ?>
</li>
</ul>

View File

@@ -0,0 +1,325 @@
<?php
/**
* Duplicator package row in table packages list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Libs\Snap\SnapWP;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var \wpdb $wpdb
*/
$dbFilterOn = isset($tplData['dbFilterOn']) ? $tplData['dbFilterOn'] : false;
$dbPrefixFilter = isset($tplData['dbPrefixFilter']) ? $tplData['dbPrefixFilter'] : false;
$dbPrefixSubFilter = isset($tplData['dbPrefixSubFilter']) ? $tplData['dbPrefixSubFilter'] : false;
$tSelected = isset($tplData['tablesSlected']) ? $tplData['tablesSlected'] : array();
$dbTableCount = 1;
global $wpdb;
$toolTipPrefixFilterContent = sprintf(
__(
'By enabling this option all tables that do not start with the prefix <b>"%s"</b> are excluded from the package.',
'duplicator-pro'
),
esc_html($wpdb->prefix)
) . ' ' .
__(
'This option is useful for multiple WordPress installs in the same database or if several applications are installed in the same database.',
'duplicator-pro'
);
$toolTipSubsiteFilterContent =
__('Enabling this option excludes all tables associated with deleted sites from the package.', 'duplicator-pro') . '<br><br>' .
__(
'When deleting a site in a multisite; WordPress deletes the tables of items related to the core, however it is not assumed that the tables of third party plugins are removed.', // phpcs:ignore Generic.Files.LineLength
'duplicator-pro'
) . ' ' .
__('With a multisite with a large number of deleted sites the database may be full of unused tables.', 'duplicator-pro') . ' ' .
__('With this option only the tables of currently existing sites will be included in the backup.', 'duplicator-pro');
?>
<div class="dup-package-hdr-1">
<?php esc_html_e("Filters", 'duplicator-pro') ?>
</div>
<div class="dup-form-item">
<span class="title">
<?php esc_html_e("Enable Filters", 'duplicator-pro') ?>:
</span>
<span class="input">
<label>
<input type="checkbox" id="dbfilter-on" name="dbfilter-on" <?php checked($dbFilterOn); ?> >
<?php esc_html_e("Allow database tables to be excluded", 'duplicator-pro') ?>
</label>
<?php
$tipCont = __(
'Table filters allow you to ignore specific tables from a database.
When creating a package only include the data you want and need.
This helps to speed up the build process and keep your backups simple and clean.
Tables that are checked will be excluded.
Tables with an * in red are core WordPress tables and should typically not be excluded.',
'duplicator-pro'
);
?>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Database Table Filters", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipCont); ?>"
>
</i>
</span>
</div>
<div class="dup-form-item">
<span class="title">
<?php esc_html_e("Table Prefixes", 'duplicator-pro') ?>:
</span>
<span class="input">
<label>
<input
type="checkbox"
id="db-prefix-filter"
name="db-prefix-filter"
<?php checked($dbPrefixFilter); ?>
<?php disabled(!$dbFilterOn); ?>
data-prefix-value="<?php echo esc_attr($wpdb->prefix); ?>" />
<?php
esc_html_e('Filter tables without current WordPress prefix', 'duplicator-pro');
echo isset($wpdb->prefix) ? '&nbsp;<i>(' . esc_html($wpdb->prefix) . ')</i>&nbsp;' : '';
?>
</label>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("WordPress Prefix Filters", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($toolTipPrefixFilterContent); ?>"> <br/>
</i>
</span>
</div>
<?php if (is_multisite()) { ?>
<div class="dup-form-item">
<span class="title">
<?php esc_html_e("Subsites", 'duplicator-pro') ?>:
</span>
<span class="input">
<label>
<input
type="checkbox"
id="db-prefix-sub-filter"
name="db-prefix-sub-filter"
<?php checked($dbPrefixSubFilter); ?>
<?php disabled(!$dbFilterOn); ?>
>
<?php esc_html_e("Filter/Hide Tables of Deleted Multisite-Subsites", 'duplicator-pro') ?>
</label>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Multisite-Subsite Filters", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($toolTipSubsiteFilterContent); ?>">
</i>
</span>
</div>
<?php } ?>
<div id="dup-db-filter-items" >
<div class="dup-db-filter-buttons" >
<span id="dbnone" class="link-style dup-db-filter-none">
<i class="far fa-minus-square fa-lg" title="<?php esc_html_e('Uncheck All Checkboxes', 'duplicator-pro'); ?>"></i>
</span>&nbsp;
<span id="dball" class="link-style dup-db-filter-all">
<i class="far fa-check-square fa-lg" title="<?php esc_html_e('Check All Checkboxes', 'duplicator-pro'); ?>"></i>
</span>
</div>
<div id="dup-db-tables-exclude-wrapper" >
<div id="dup-db-tables-exclude" >
<input type="hidden" id="dup-db-tables-lists" name="dbtables-list" value="" >
<?php
$substesIds = SnapWP::getSitesIds();
foreach (DUP_PRO_DB::getTablesList() as $table) {
$info = SnapWP::getTableInfoByName($table, $wpdb->prefix);
$classes = array('table-item');
if ($info['isCore']) {
$classes[] = 'core-table';
$core_note = '*';
if ($info['subsiteId'] > 0) {
$classes[] = ' subcore-table-' . ($info['subsiteId'] % 2);
}
} else {
$core_note = '';
}
$dbTableCount++;
$cboxClasses = array('dup-pseudo-checkbox');
$checked = in_array($table, $tSelected);
if ($info['subsiteId'] > 1 && !in_array($info['subsiteId'], $substesIds)) {
$classes[] = 'no-subsite-exists';
if ($dbPrefixSubFilter) {
$cboxClasses[] = 'disabled';
$checked = true;
}
}
if ($info['havePrefix'] == false) {
$classes[] = 'no-prefix-table';
if ($dbPrefixFilter) {
$cboxClasses[] = 'disabled';
$checked = true;
}
}
if ($checked) {
$cboxClasses[] = 'checked';
}
?>
<label class="<?php echo esc_attr(implode(' ', $classes)); ?>">
<span
class="<?php echo esc_attr(implode(' ', $cboxClasses)); ?>"
aria-checked="<?php echo $checked ? "true" : "false";?>"
role="checkbox"
data-value="<?php echo esc_attr($table); ?>">
</span>
&nbsp;<span><?php echo esc_html($table . $core_note); ?></span>
</label>
<?php } ?>
</div>
<div id="dup-db-filter-items-no-filters">
<div>
<?php esc_html_e('- Table Filters Disabled -', 'duplicator-pro'); ?><br>
<?php printf(esc_html_x('All %d tables will be included in this build.', '%d = number of tables', 'duplicator-pro'), (int) $dbTableCount); ?>
</div>
</div>
</div>
<div class="dup-tabs-opts-help">
<?php
echo wp_kses(__("Checked tables will be <u>excluded</u> from the database script. ", 'duplicator-pro'), array('u' => array()));
esc_html_e("Excluding certain tables can cause your site or plugins to not work correctly after install!", 'duplicator-pro');
echo '<br>';
echo '<i class="core-table-info"> ';
esc_html_e(
"Use caution when excluding tables! It is highly recommended to not exclude WordPress core tables in red with an *,
unless you know the impact.",
'duplicator-pro'
);
echo '</i>';
?>
</div>
</div>
<script>
jQuery(function($)
{
/* METHOD: Toggle Database table filter red icon */
DupPro.Pack.ToggleDBFiltersRedIcon = function() {
if (
$("#dbfilter-on").is(':checked')
) {
$('#dup-archive-filter-db').show();
$('#db-prefix-filter').prop('disabled', false);
$('#db-prefix-sub-filter').prop('disabled', false);
} else {
$('#dup-archive-filter-db').hide();
$('#db-prefix-filter').prop('disabled', true);
$('#db-prefix-sub-filter').prop('disabled', true);
}
}
DupPro.Pack.ToggleDBFilters = function ()
{
var filterItems = $('#dup-db-filter-items');
if (
$("#dbfilter-on").is(':checked')
) {
filterItems.removeClass('disabled');
$('#dup-db-filter-items-no-filters').hide();
} else {
filterItems.addClass('disabled');
$('#dup-db-filter-items-no-filters').show();
}
DupPro.Pack.ToggleDBFiltersRedIcon();
};
DupPro.Pack.FillExcludeTablesList = function () {
let values = $("#dup-db-tables-exclude .dup-pseudo-checkbox.checked")
.map(function() {
return this.getAttribute('data-value');
})
.get()
.join();
$('#dup-db-tables-lists').val(values);
};
DupPro.Pack.ToggleNoPrefixTables = function (removeCheckOnEnable = true) {
let checkNode = $('#db-prefix-filter');
let display = !checkNode.is(":checked");
$("#dup-db-tables-exclude .no-prefix-table").each(function() {
let checkBox = $(this).find(".dup-pseudo-checkbox").first();
if (display) {
checkBox.removeClass('disabled');
if(removeCheckOnEnable) {
checkBox.removeClass("checked");
}
} else {
checkBox
.addClass('disabled')
.addClass("checked");
}
});
DupPro.Pack.ToggleDBFiltersRedIcon();
}
DupPro.Pack.ToggleNoSubsiteExistsTables = function (removeCheckOnEnable = true) {
let checkNode = $('#db-prefix-sub-filter');
let display = !checkNode.is(":checked");
$("#dup-db-tables-exclude .no-subsite-exists").each(function() {
let checkBox = $(this).find(".dup-pseudo-checkbox").first();
if (display) {
checkBox.removeClass('disabled');
if(removeCheckOnEnable) {
checkBox.removeClass("checked");
}
} else {
checkBox
.addClass('disabled')
.addClass("checked");
}
});
DupPro.Pack.ToggleDBFiltersRedIcon();
}
});
jQuery(document).ready(function($)
{
let tablesToExclude = $("#dup-db-tables-exclude");
$('.dup-db-filter-none').click(function () {
tablesToExclude.find(".dup-pseudo-checkbox.checked").removeClass("checked");
});
$('.dup-db-filter-all').click(function () {
tablesToExclude.find(".dup-pseudo-checkbox:not(.checked)").addClass("checked");
});
$('#db-prefix-sub-filter').change(DupPro.Pack.ToggleNoSubsiteExistsTables);
$('#db-prefix-filter').change(DupPro.Pack.ToggleNoPrefixTables);
$('#dbfilter-on').change(DupPro.Pack.ToggleDBFilters);
DupPro.Pack.ToggleDBFilters();
});
</script>

View File

@@ -0,0 +1,33 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Utils\Help\Article;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
/** @var Article[] $articles p*/
$articles = $tplData['articles'];
$listClass = isset($tplData['list_class']) ? 'class="' . $tplData['list_class'] . '"' : '';
?>
<?php if (count($articles) > 0) : ?>
<ul <?php echo $listClass; ?>>
<?php foreach ($articles as $article) : ?>
<li class="duplicator-pro-help-article" data-id="<?php echo (int) $article->getId(); ?>">
<i aria-hidden="true" class="fa fa-file-alt"></i>
<a href="<?php echo esc_url($article->getLink()); ?>" target="_blank"><?php echo esc_html($article->getTitle()); ?></a>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>

View File

@@ -0,0 +1,61 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Utils\Help\Category;
use Duplicator\Utils\Help\Help;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
/** @var Category[] $categories */
$categories = $tplData['categories'];
if (empty($categories)) : ?>
<p>
<?php
printf(
esc_html_x(
'Could not fetch help information. Please try again later or visit the %1$sonline docs%2$s.',
'%1$s and %2$s are the opening and closing tags for the link to the online docs.',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_PRO_BLOG_URL . 'docs') . '" target="_blank">',
'</a>'
);
?>
</p>
<?php else : ?>
<ul class="duplicator-pro-help-category-list">
<?php foreach ($categories as $category) : ?>
<li class="duplicator-pro-help-category">
<header>
<i class="fa fa-folder-open"></i>
<span><?php echo esc_html($category->getName()); ?></span>
<i class="fa fa-angle-right"></i>
</header>
<?php if (count($category->getChildren()) > 0) { ?>
<?php $tplMng->render('parts/help/category-list', ['categories' => $category->getChildren()]);
} ?>
<?php if ($category->getArticleCount() > 0) : ?>
<?php $tplMng->render(
'parts/help/article-list',
[
'articles' => Help::getInstance()->getArticlesByCategory($category->getId()),
'list_class' => 'duplicator-pro-help-article-list',
]
); ?>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>

View File

@@ -0,0 +1,245 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Utils\Help\Help;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<style>
/* Dynamic Help Style */
#duplicator-pro-help-wrapper {
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: #fff;
overflow-y: auto;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
-webkit-font-smoothing: antialiased !important;
-moz-osx-font-smoothing: grayscale !important;
}
#duplicator-pro-help-header {
position: fixed;
display: flex;
flex-direction: row;
justify-content: space-between;
width: 90%;
top: 30px;
left: 5%;
}
#duplicator-pro-help-content {
width: 700px;
margin: 150px auto 50px;
}
@media only screen and (max-width: 700px) {
#duplicator-pro-help-content {
width: 90%;
}
}
#duplicator-pro-help-search {
margin-bottom: 30px;
}
#duplicator-pro-help-search-results-empty {
display: none;
}
#duplicator-pro-help-search-results,
#duplicator-pro-help-search-results-empty {
margin-top: 50px;
}
#duplicator-pro-help-search input {
border: 1px solid #999999;
border-radius: 25px;
color: #444444;
font-size: 20px;
letter-spacing: 0;
line-height: 20px;
min-height: 48px;
padding: 10px 10px 10px 25px;
text-align: left;
width: 100%;
}
#duplicator-pro-help-categories > ul > li ul {
display: none;
margin-left: 30px;
}
#duplicator-pro-help-categories > ul > li .duplicator-pro-help-category:last-of-type {
border-bottom: 0;
}
.duplicator-pro-help-category {
border-top: 1px solid #dddddd;
margin: 0;
width: 100%;
}
.duplicator-pro-help-category:last-of-type {
border-bottom: 1px solid #dddddd;
}
.duplicator-pro-help-category header {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
cursor: pointer;
padding: 20px 0;
}
.duplicator-pro-help-category header span {
color: #444444;
font-size: 16px;
font-weight: 600;
}
.duplicator-pro-help-category header .fa-folder-open {
color: #999999;
font-size: 21px;
margin-right: 10px;
}
.duplicator-pro-help-category header .fa-angle-right {
color: #cccccc;
font-size: 24px;
margin-left: auto;
transition-property: transform;
transition-duration: 0.25s;
transition-timing-function: ease-out;
}
.duplicator-pro-help-article-list {
display: none;
margin-top: 20px;
}
.duplicator-pro-help-article {
margin: 0;
padding: 0 0 14px 4px;
}
.duplicator-pro-help-article .fa-file-alt {
color: #b6b6b6;
font-size: 16px;
margin: 0 14px 0 0;
}
.duplicator-pro-help-article a {
border-bottom: 1px solid transparent;
color: #666;
font-size: 15px;
text-decoration: none;
}
#duplicator-pro-help-footer {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: 50px;
}
.duplicator-pro-help-footer-block {
border: 1px solid #ddd;
border-radius: 6px;
box-sizing: border-box;
max-width: 340px;
padding: 25px;
text-align: center;
}
.duplicator-pro-help-footer-block i {
color: #999;
font-size: 48px;
margin: 0 0 20px 0;
}
.duplicator-pro-help-footer-block h3 {
color: #444;
font-size: 16px;
margin: 0 0 10px 0;
font-weight: bold;
}
.duplicator-pro-help-footer-block p {
color: #777777;
font-size: 14px;
margin: 0 0 20px 0;
}
.duplicator-pro-help-footer-block .button {
border: 1px solid #af9ca6 !important;
color: #4f394d !important;
background: transparent !important;
font-size: 15px !important;
}
</style>
<div id="duplicator-pro-help-wrapper">
<div id="duplicator-pro-help-header">
<img src="<?php echo esc_url(DUPLICATOR_PRO_PLUGIN_URL . 'assets/img/duplicator-header-logo.svg'); ?>" />
</div>
<div id="duplicator-pro-help-content">
<div id="duplicator-pro-help-search">
<input type="text" placeholder="<?php esc_attr_e("Search", "duplicator-pro"); ?>" />
<ul id="duplicator-pro-help-search-results"></ul>
<div id="duplicator-pro-help-search-results-empty"><?php esc_html_e("No results found", "duplicator-pro"); ?></div>
</div>
<div id="duplicator-pro-context-articles">
<?php if (count(Help::getInstance()->getArticlesByTag($tplData['tag'])) > 0) : ?>
<h2><?php esc_html_e("Related Articles", "duplicator-pro"); ?></h2>
<?php $tplMng->render('parts/help/article-list', ['articles' => Help::getInstance()->getArticlesByTag($tplData['tag'])]); ?>
<?php endif; ?>
</div>
<div id="duplicator-pro-help-categories">
<?php $tplMng->render('parts/help/category-list', ['categories' => Help::getInstance()->getTopLevelCategories()]); ?>
</div>
<div id="duplicator-pro-help-footer">
<div class="duplicator-pro-help-footer-block">
<i aria-hidden="true" class="fa fa-file-alt"></i>
<h3><?php esc_html_e("View Documentation", "duplicator-pro"); ?></h3>
<p>
<?php esc_html_e("Browse documentation, reference material, and tutorials for Duplicator.", "duplicator-pro"); ?>
</p>
<a
href="<?php echo esc_url(DUPLICATOR_PRO_BLOG_URL . 'docs'); ?>"
rel="noopener noreferrer"
target="_blank"
class="button">
<?php esc_html_e("View All Documentation", "duplicator-pro"); ?>
</a>
</div>
<div class="duplicator-pro-help-footer-block">
<i aria-hidden="true" class="fa fa-life-ring"></i>
<h3><?php esc_html_e("Get Support", "duplicator-pro"); ?></h3>
<p><?php esc_html_e("You can access our world-class support below.", "duplicator-pro"); ?></p>
<a
href="<?php echo esc_url(DUPLICATOR_PRO_BLOG_URL . 'my-account/support/'); ?>"
rel="noopener noreferrer"
target="_blank"
class="button">
<?php esc_html_e("Get Support", "duplicator-pro"); ?>
</a>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,56 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Views\AdminNotices;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<div class="dup-messages-section" >
<?php
if (isset($tplData['errorMessage']) && strlen($tplData['errorMessage']) > 0) {
AdminNotices::displayGeneralAdminNotice(
$tplData['errorMessage'],
AdminNotices::GEN_ERROR_NOTICE,
true
);
}
if (DUPLICATOR_PRO_DEBUG_TPL_OUTPUT_INVALID && isset($tplData['invalidOutput']) && strlen($tplData['invalidOutput']) > 0) { // @phpstan-ignore-line
AdminNotices::displayGeneralAdminNotice(
'<b>Invalid output on actions execution</b><hr>' . $tplData['invalidOutput'],
AdminNotices::GEN_ERROR_NOTICE,
true
);
}
if (isset($tplData['successMessage']) && strlen($tplData['successMessage']) > 0) {
AdminNotices::displayGeneralAdminNotice(
$tplData['successMessage'],
AdminNotices::GEN_SUCCESS_NOTICE,
true
);
}
?>
</div>
<?php
if (DUPLICATOR_PRO_DEBUG_TPL_DATA) { // @phpstan-ignore-line
?>
<pre style="font-size: 12px; max-height: 300px; overflow: auto; border: 1px solid black; padding: 10px;"><?php
var_dump($tplData);
?></pre>
<?php
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\MigrationMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$safeMsg = MigrationMng::getSaveModeWarning();
$url = $ctrlMng->getMenuLink(ControllersManager::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_DISAGNOSTIC);
;
?>
<div class="notice notice-success dpro-admin-notice dup-migration-pass-wrapper" >
<p>
<b><?php
if (MigrationMng::getMigrationData()->restoreBackupMode) {
esc_html_e('Restore Backup Almost Complete!', 'duplicator-pro');
} else {
esc_html_e('Migration Almost Complete!', 'duplicator-pro');
}
?></b>
</p>
<p>
<?php
esc_html_e(
'Reserved Duplicator Pro installation files have been detected in the root directory.
Please delete these installation files to avoid security issues.',
'duplicator-pro'
);
?>
<br/>
<?php esc_html_e('Go to: Tools > General > Information > Stored Data > and click the "Remove Installation Files" button', 'duplicator-pro'); ?><br>
<a id="dpro-notice-action-general-site-page" href="<?php echo esc_url($url); ?>">
<?php esc_html_e('Take me there now!', 'duplicator-pro'); ?>
</a>
</p>
<?php if (strlen($safeMsg) > 0) { ?>
<div class="notice-safemode">
<?php echo esc_html($safeMsg); ?>
</div>
<?php } ?>
<p class="sub-note">
<i><?php
esc_html_e(
'If an archive.zip/daf file was intentially added to the root directory
to perform an overwrite install of this site then you can ignore this message.',
'duplicator-pro'
);
?>
</i>
</p>
<?php echo apply_filters(MigrationMng::HOOK_BOTTOM_MIGRATION_MESSAGE, ''); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>

View File

@@ -0,0 +1,113 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$fileRemoved = $tplData['installerCleanupFiles'];
$removeError = $tplData['installerCleanupError'];
$purgeCaches = $tplData['installerCleanupPurge'];
?>
<div class="dpro-diagnostic-action-installer">
<p>
<b><?php esc_html_e('Installation cleanup ran!', 'duplicator-pro'); ?></b>
</p>
<?php
if (count($fileRemoved) === 0) {
?>
<p>
<b><?php esc_html_e('No Duplicator files were found on this WordPress Site.', 'duplicator-pro'); ?></b>
</p> <?php
} else {
foreach ($fileRemoved as $path => $success) {
if ($success) {
?><div class="success">
<i class="fa fa-check"></i> <?php esc_html_e("Removed", 'duplicator-pro'); ?> - <?php echo esc_html($path); ?>
</div><?php
} else {
?><div class="failed">
<i class='fa fa-exclamation-triangle'></i> <?php esc_html_e("Found", 'duplicator-pro'); ?> - <?php echo esc_html($path); ?>
</div>
<?php
}
}
}
foreach ($purgeCaches as $message) {
?><div class="success">
<i class="fa fa-check"></i> <?php echo wp_kses($message, ViewHelper::GEN_KSES_TAGS); ?>
</div>
<?php
}
if ($removeError) {
?>
<p>
<?php esc_html_e('Some of the installer files did not get removed, ', 'duplicator-pro'); ?>
<span class="link-style" onclick="DupPro.Tools.removeInstallerFiles();">
<?php esc_html_e('please retry the installer cleanup process', 'duplicator-pro'); ?>
</span><br>
<?php esc_html_e(' If this process continues please see the previous FAQ link.', 'duplicator-pro'); ?>
</p>
<?php
}
?>
<div style="font-style: italic; max-width:900px; padding:10px 0 25px 0;">
<p>
<b><i class="fa fa-shield-alt"></i> <?php esc_html_e('Security Notes', 'duplicator-pro'); ?>:</b>
<?php
esc_html_e(
'If the installer files do not successfully get removed with this action,
then they WILL need to be removed manually through your hosts control panel or FTP.
Please remove all installer files to avoid any security issues on this site.',
'duplicator-pro'
);
?><br>
<?php
printf(
esc_html_x(
'For more details please visit the FAQ link %1$sWhich files need to be removed after an install?%2$s',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'which-files-need-to-be-removed-after-an-install') . '" target="_blank">',
'</a>'
);
?>
</p>
<p>
<b><i class="fa fa-thumbs-up"></i> <?php esc_html_e('Help Support Duplicator', 'duplicator-pro'); ?>:</b>
<?php
esc_html_e(
'The Duplicator team has worked many years to make moving a WordPress site a much easier process. ',
'duplicator-pro'
);
?>
<br>
<?php
printf(
esc_html_x(
'Show your support with a %1$s5 star review%2$s! We would be thrilled if you could!',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="https://wordpress.org/support/plugin/duplicator/reviews/?filter=5" target="_blank">',
'</a>'
);
?>
</p>
</div>
</div>

View File

@@ -0,0 +1,111 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Core\MigrationMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (!isset($tplData['isMigrationSuccessNotice']) || !$tplData['isMigrationSuccessNotice']) {
$tplMng->render('parts/migration/tool-cleanup-installer-files');
return;
}
$safeMsg = MigrationMng::getSaveModeWarning();
$cleanupReport = MigrationMng::getCleanupReport();
?>
<div class="notice notice-success dpro-admin-notice dup-migration-pass-wrapper">
<div class="dup-migration-pass-title">
<i class="fa fa-check-circle"></i> <?php
if (MigrationMng::getMigrationData()->restoreBackupMode) {
esc_html_e('This site has been successfully restored!', 'duplicator-pro');
} else {
esc_html_e('This site has been successfully migrated!', 'duplicator-pro');
}
?>
</div>
<p>
<?php
printf(
esc_html__(
'The following installation files are stored in the folder %s',
'duplicator-pro'
),
'<b>' . esc_html(DUPLICATOR_PRO_SSDIR_PATH_INSTALLER) . '</b>'
);
?>
</p>
<ul class="dup-stored-minstallation-files">
<?php foreach (MigrationMng::getStoredMigrationLists() as $path => $label) { ?>
<li>
- <?php echo esc_html($label); ?>
</li>
<?php } ?>
</ul>
<?php
if (isset($tplData['isInstallerCleanup']) && $tplData['isInstallerCleanup']) {
$tplMng->render('parts/migration/clean-installation-files');
} else {
if (count($cleanupReport['instFile']) > 0) { ?>
<p>
<?php esc_html_e('Security actions:', 'duplicator-pro'); ?>
</p>
<ul class="dup-stored-minstallation-files">
<?php
foreach ($cleanupReport['instFile'] as $html) { ?>
<li>
<?php echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</li>
<?php } ?>
</ul>
<?php } ?>
<p>
<b><?php esc_html_e('Final step:', 'duplicator-pro'); ?></b><br>
<span id="dpro-notice-action-remove-installer-files" class="link-style" onclick="DupPro.Tools.removeInstallerFiles();">
<?php esc_html_e('Remove Installation Files Now!', 'duplicator-pro'); ?>
</span>
</p>
<?php if (strlen($safeMsg) > 0) { ?>
<div class="notice-safemode">
<?php echo esc_html($safeMsg); ?>
</div>
<?php } ?>
<p class="sub-note">
<i><?php
esc_html_e(
'Note: This message will be removed after all installer files are removed.
Installer files must be removed to maintain a secure site.
Click the link above to remove all installer files and complete the migration.',
'duplicator-pro'
);
?><br>
<i class="fas fa-info-circle"></i>
<?php
esc_html_e(
'If an archive.zip/daf file was intentially added to the root directory to perform an overwrite install
of this site then you can ignore this message.',
'duplicator-pro'
)
?>
</i>
</p>
<?php
}
echo apply_filters(MigrationMng::HOOK_BOTTOM_MIGRATION_MESSAGE, ''); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
</div>

View File

@@ -0,0 +1,24 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
*/
if (!isset($tplData['isInstallerCleanup']) || !$tplData['isInstallerCleanup']) {
return;
}
?>
<div id="message" class="notice notice-success">
<?php $tplMng->render('parts/migration/clean-installation-files'); ?>
</div>

Some files were not shown because too many files have changed in this diff Show More