first commit

This commit is contained in:
Roman Pyrih
2026-04-21 15:48:41 +02:00
commit 7483681901
10216 changed files with 3236626 additions and 0 deletions

View File

@@ -0,0 +1,413 @@
<?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\Models\GlobalEntity;
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Libs\Snap\SnapUtil;
use Duplicator\Models\DynamicGlobalEntity;
use Duplicator\Utils\LockUtil;
use Duplicator\Libs\WpUtils\WpArchiveUtils;
$global = GlobalEntity::getInstance();
$dGlobal = DynamicGlobalEntity::getInstance();
$max_execution_time = (int) SnapUtil::phpIniGet("max_execution_time", 0);
$max_execution_time = $max_execution_time < 0 ? PHP_INT_MAX : $max_execution_time;
$max_execution_time = empty($max_execution_time) ? 30 : $max_execution_time;
$workerTimeCapRange = [
10,
min(180, max(30, (int) (0.7 * (float) $max_execution_time))),
];
$workerTimeValue = (int) max($workerTimeCapRange[0], min((int) $global->php_max_worker_time_in_sec, $workerTimeCapRange[1]));
?>
<div class="dup-accordion-wrapper display-separators close">
<div class="accordion-header">
<h3 class="title">
<?php esc_html_e("Advanced", 'duplicator-pro'); ?>
</h3>
</div>
<div class="accordion-content">
<label class="lbl-larger">
<?php esc_html_e("Thread Lock", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="radio"
name="lock_mode"
id="lock_mode_flock"
class="margin-0"
value="<?php echo (int) LockUtil::LOCK_MODE_FILE; ?>"
<?php checked($global->lock_mode, LockUtil::LOCK_MODE_FILE); ?>>
<label for="lock_mode_flock">
<?php esc_html_e("File", 'duplicator-pro'); ?>
</label>&nbsp;
<input
type="radio"
name="lock_mode"
id="lock_mode_sql"
class="margin-0"
value="<?php echo (int) LockUtil::LOCK_MODE_SQL; ?>"
<?php checked($global->lock_mode, LockUtil::LOCK_MODE_SQL); ?>>
<label for="lock_mode_sql">
<?php esc_html_e("SQL", 'duplicator-pro'); ?>
</label>&nbsp;
</div>
<label class="lbl-larger">
<?php esc_html_e("Max Worker Time", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
data-parsley-required
data-parsley-errors-container="#php_max_worker_time_in_sec_error_container"
data-parsley-range="<?php echo esc_attr(wp_json_encode($workerTimeCapRange)); ?>"
data-parsley-type="number"
class="width-small inline-display margin-0"
type="text"
name="php_max_worker_time_in_sec"
id="php_max_worker_time_in_sec"
value="<?php echo (int) $workerTimeValue; ?>">&nbsp;
<span>
<?php esc_html_e('Seconds', 'duplicator-pro'); ?>
</span>
<div id="php_max_worker_time_in_sec_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php
esc_html_e(
'This setting controls how long each processing chunk can run. A lower value makes the process more reliable but slower.',
'duplicator-pro'
);
?><br />
<?php
esc_html_e(
"Try a low value (30 seconds or lower) if the build fails with the recommended setting.",
'duplicator-pro'
); ?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e("Ajax", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="radio"
id="ajax_protocol_1"
name="ajax_protocol"
class="ajax_protocol margin-0"
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 margin-0"
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 margin-0"
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 margin-0"
value="custom"
<?php checked($global->ajax_protocol, 'custom'); ?>>
<label for="ajax_protocol_4">
<?php esc_html_e("Custom URL", 'duplicator-pro'); ?>
</label> <br />
<input
type="<?php echo ($global->ajax_protocol == 'custom' ? 'text' : 'hidden'); ?>"
id="custom_ajax_url"
name="custom_ajax_url"
class="width-xlarge"
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" class="alert-color">
<?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 Backups get stuck at the start of a build.", 'duplicator-pro'); ?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e('Root path', 'duplicator-pro') ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="homepath_as_abspath"
id="homepath_as_abspath"
class="margin-0"
<?php disabled(WpArchiveUtils::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(WpArchiveUtils::getArchiveListPaths('abs')) . '</b>'
);
?>
<br>
</label>
<p class="description">
<?php
if (WpArchiveUtils::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>
</div>
<label class="lbl-larger">
<?php esc_html_e('Scan File Checks', 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="_skip_archive_scan"
id="_skip_archive_scan"
class="margin-0"
<?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 Backup creation.
In some cases, this option can be beneficial if the scan process is having issues running or returning errors.',
'duplicator-pro'
);
?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e('Client-side Kickoff', 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="_clientside_kickoff"
id="_clientside_kickoff"
class="margin-0"
<?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 Backup build from client. Only check this if instructed to by Duplicator support.', 'duplicator-pro'); ?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e("Password-Protected Access", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="_basic_auth_enabled"
id="_basic_auth_enabled"
value="1"
class="margin-0"
<?php checked($dGlobal->getValBool('basic_auth_enabled')); ?>>
<label for="_basic_auth_enabled">
<?php esc_html_e("Enabled", 'duplicator-pro') ?>
</label>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e("HTTP Basic authentication", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e(
"When HTTP Basic authentication is applied Duplicator needs to attach the login credentials to each request to the server.
This is required for the build process to work properly. If you see a browser popup login window when accessing the admin area,
then basic authentication should be enabled. If you are not sure, please consult your hosting provider.",
'duplicator-pro'
); ?>"></i>
<div id="dup-basic-auth-login-wrapper">
<input
autocomplete="off"
placeholder="<?php esc_attr_e('User', 'duplicator-pro'); ?>"
type="text"
name="basic_auth_user"
id="basic_auth_user"
class="margin-0"
value="<?php echo esc_attr($dGlobal->getValString('basic_auth_user')); ?>"
<?php disabled(!$dGlobal->getValBool('basic_auth_enabled')); ?>>
<span class="dup-password-toggle">
<input
id="auth_password"
autocomplete="off"
placeholder="<?php esc_attr_e('Password', 'duplicator-pro'); ?>"
type="password"
name="basic_auth_password"
id="basic_auth_password"
class="margin-0"
value="<?php echo esc_attr($dGlobal->getValString('basic_auth_password')); ?>"
<?php disabled(!$dGlobal->getValBool('basic_auth_enabled')); ?>>
<button type="button">
<i class="fas fa-eye fa-sm"></i>
</button>
</span>
</div>
<p class="description">
<?php esc_html_e(
'Enable this function and provide username and password in case Backup creation error.
Essential for making authorized HTTP requests in a server protected folder.',
'duplicator-pro'
); ?>
</p>
</div>
</div>
</div>
<script>
(function($) {
$('#_basic_auth_enabled').on('change', function() {
if ($(this).is(':checked')) {
$('#dup-basic-auth-login-wrapper input').prop('disabled', false);
} else {
$('#dup-basic-auth-login-wrapper input').prop('disabled', true);
}
});
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,191 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Libs\Shell\ShellZipUtils;
use Duplicator\Models\GlobalEntity;
use Duplicator\Package\Archive\PackageArchive;
use Duplicator\Utils\ZipArchiveExtended;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
$isZipArchiveAvailable = ZipArchiveExtended::isPhpZipAvailable();
$isShellZipAvailable = (ShellZipUtils::getShellExecZipPath() != null);
?>
<h3 class="title">
<?php esc_html_e("Archive", 'duplicator-pro') ?>
</h3>
<hr size="1" />
<label class="lbl-larger">
<?php esc_html_e("Compression", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="radio"
name="archive_compression"
id="archive_compression_off"
value="0"
class="margin-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"
class="margin-0"
<?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="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e("Archive Compression", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>">
</i>
</div>
<label class="lbl-larger">
<?php esc_html_e("Archive Engine", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<div class="engine-radio">
<input
onclick="DupliJs.UI.SetArchiveOptionStates();"
type="radio"
name="archive_build_mode" id="archive_build_mode3"
class="margin-0"
value="<?php echo (int) PackageArchive::BUILD_MODE_DUP_ARCHIVE; ?>"
<?php checked($global->getBuildMode() == PackageArchive::BUILD_MODE_DUP_ARCHIVE); ?>
<?php disabled(!$global->isBuildModeAvailable(PackageArchive::BUILD_MODE_DUP_ARCHIVE)) ?>>
<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="DupliJs.UI.SetArchiveOptionStates();"
type="radio"
name="archive_build_mode"
id="archive_build_mode1"
class="margin-0"
value="<?php echo (int) PackageArchive::BUILD_MODE_SHELL_EXEC; ?>"
<?php checked($global->getBuildMode() == PackageArchive::BUILD_MODE_SHELL_EXEC); ?>
<?php disabled(!$global->isBuildModeAvailable(PackageArchive::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="DupliJs.UI.SetArchiveOptionStates();"
type="radio"
name="archive_build_mode"
id="archive_build_mode2"
class="margin-0"
value="<?php echo (int) PackageArchive::BUILD_MODE_ZIP_ARCHIVE; ?>"
<?php checked($global->getBuildMode() == PackageArchive::BUILD_MODE_ZIP_ARCHIVE); ?>
<?php disabled(!$global->isBuildModeAvailable(PackageArchive::BUILD_MODE_ZIP_ARCHIVE)) ?>>
<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_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->render(
'parts/settings/shellZipMessage',
['hasShellZip' => $isShellZipAvailable]
);
?>
</div>
<!-- ZIP ARCHIVE -->
<div class="engine-sub-opts" id="engine-details-2" style="display:none;">
<div class="margin-bottom-1">
<span><?php esc_html_e("Process Mode", 'duplicator-pro'); ?></span>&nbsp;
<select name="ziparchive_mode" id="ziparchive_mode" onchange="DupliJs.UI.setZipArchiveMode();" class="inline-display width-medium margin-0">
<option <?php selected($global->ziparchive_mode, PackageArchive::ZIP_MODE_MULTI_THREAD); ?>
value="<?php echo (int) PackageArchive::ZIP_MODE_MULTI_THREAD ?>">
<?php esc_html_e("Multi-Threaded", 'duplicator-pro'); ?>
</option>
<option <?php selected($global->ziparchive_mode == PackageArchive::ZIP_MODE_SINGLE_THREAD); ?>
value="<?php echo (int) PackageArchive::ZIP_MODE_SINGLE_THREAD ?>">
<?php esc_html_e("Single-Threaded", 'duplicator-pro'); ?>
</option>
</select>&nbsp;
<i style="margin-right:7px;" class="fa-solid fa-question-circle fa-sm dark-gray-color"
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>
<div id="dupli-ziparchive-mode-st">
<input type="checkbox" id="ziparchive_validation" name="ziparchive_validation" class="margin-0"
<?php checked($global->ziparchive_validation); ?>>
<label for="ziparchive_validation">Enable file validation</label>
</div>
<div id="dupli-ziparchive-mode-mt">
<span><?php esc_html_e("Buffer Size", 'duplicator-pro'); ?></span>&nbsp;
<input
maxlength="4"
class="inline-display width-small margin-0"
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="fa-solid fa-question-circle fa-sm dark-gray-color"
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>
</div>

View File

@@ -0,0 +1,137 @@
<?php
/**
* @package Duplicator
*/
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
*/
?>
<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(); ?>
<div class="dup-settings-wrapper margin-bottom-1">
<?php $tplMng->render('admin_pages/settings/backup/database_settings'); ?>
<?php $tplMng->render('admin_pages/settings/backup/archive_settings'); ?>
<?php $tplMng->render('admin_pages/settings/backup/processing_settings'); ?>
<?php $tplMng->render('admin_pages/settings/backup/installer_settings'); ?>
<?php $tplMng->render('admin_pages/settings/backup/advanced_settings'); ?>
</div>
<p class="submit dupli-save-submit">
<input
type="submit"
name="submit"
id="submit"
class="button primary small"
value="<?php esc_attr_e('Save Settings', 'duplicator-pro') ?>" style="display: inline-block;"
>
</p>
</form>
<script>
jQuery(document).ready(function ($)
{
DupliJs.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;
}
}
DupliJs.UI.setZipArchiveMode = function ()
{
$('#dupli-ziparchive-mode-st, #dupli-ziparchive-mode-mt').hide();
if ($('#ziparchive_mode').val() == 0) {
$('#dupli-ziparchive-mode-mt').show();
} else {
$('#dupli-ziparchive-mode-st').show();
}
}
DupliJs.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;
}
DupliJs.UI.setZipArchiveMode();
}
//INIT
DupliJs.UI.SetArchiveOptionStates();
DupliJs.UI.SetDBEngineMode();
DupliJs.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 () {
DupliJs.UI.cleanupModeRadioSwitched();
});
// We must call this also once in the beginning, after UI is loaded
DupliJs.UI.cleanupModeRadioSwitched();
});
</script>

View File

@@ -0,0 +1,220 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Models\GlobalEntity;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Constants;
use Duplicator\Libs\Shell\Shell;
use Duplicator\Libs\WpUtils\WpDbUtils;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
$is_shellexec_on = Shell::test();
$mysqlDumpPath = WpDbUtils::getMySqlDumpPath();
$mysqlDumpFound = (bool) $mysqlDumpPath;
?>
<h3 class="title">
<?php esc_html_e("Database", 'duplicator-pro') ?>
</h3>
<hr size="1" />
<label class="lbl-larger">
<?php esc_html_e("SQL Mode", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<div class="margin-bottom-1">
<div class="engine-radio <?php echo ($is_shellexec_on) ? '' : 'engine-radio-disabled'; ?> inline-display">
<input
type="radio"
name="_package_dbmode"
value="mysql"
id="package_mysqldump"
class="margin-0"
<?php checked($global->package_mysqldump); ?> onclick="DupliJs.UI.SetDBEngineMode();">
<label for="package_mysqldump"><?php esc_html_e("Mysqldump", 'duplicator-pro'); ?> </label> &nbsp; &nbsp; &nbsp;
</div>
<div class="engine-radio inline-display">
<input
type="radio"
name="_package_dbmode"
id="package_phpdump"
value="php"
class="margin-0"
<?php checked(!$global->package_mysqldump); ?> onclick="DupliJs.UI.SetDBEngineMode();">
<label for="package_phpdump"><?php esc_html_e("PHP Code", 'duplicator-pro'); ?></label>
</div>
</div>
<!-- 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, the PHP function popen/pclose must be enabled.',
'duplicator-pro'
);
echo ' ';
esc_html_e('Please contact your host or server admin to enable this function.', 'duplicator-pro');
echo ' ';
printf(
esc_html_x(
'For a list of approved providers that support this function, %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_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', 'popen', 'pclose'] 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_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'
);
?>
<span><?php esc_html_e("Current Path:", 'duplicator-pro'); ?></span>&nbsp;
<?php
SettingsPageController::getMySQLDumpMessage(
$mysqlDumpFound,
(!empty($mysqlDumpPath) ? $mysqlDumpPath : $global->package_mysqldump_path)
); ?><br><br>
<span><?php esc_html_e("Custom Path:", 'duplicator-pro'); ?></span>&nbsp;
<input
class="width-large inline-display"
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="fa-solid fa-question-circle fa-sm dark-gray-color"
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()); ?>"
class="margin-0"
<?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">
<span><?php esc_html_e("Process Mode", 'duplicator-pro'); ?></span>&nbsp;
<select name="_phpdump_mode" class="width-medium inline-display margin-0">
<option
<?php selected($global->package_phpdump_mode, WpDbUtils::PHPDUMP_MODE_MULTI); ?>
value="<?php echo (int) WpDbUtils::PHPDUMP_MODE_MULTI; ?>">
<?php esc_html_e("Multi-Threaded", 'duplicator-pro'); ?>
</option>
<option
<?php selected($global->package_phpdump_mode, WpDbUtils::PHPDUMP_MODE_SINGLE); ?>
value="<?php echo (int) WpDbUtils::PHPDUMP_MODE_SINGLE; ?>">
<?php esc_html_e("Single-Threaded", 'duplicator-pro'); ?>
</option>
</select>&nbsp;
<i style="margin-right:7px;" class="fa-solid fa-question-circle fa-sm dark-gray-color"
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>
</div>
<label class="lbl-larger" for="_package_mysqldump_qrylimit">
<?php esc_html_e("Query Size", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<select name="_package_mysqldump_qrylimit" id="_package_mysqldump_qrylimit" class="width-small inline-display margin-0">
<?php
foreach (Constants::MYSQL_DUMP_CHUNK_SIZES 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="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e("MYSQL Query Limit Size", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>">
</i>
</div>

View File

@@ -0,0 +1,172 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Models\GlobalEntity;
use Duplicator\Package\Create\PackInstaller;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
$installerNameMode = $global->installer_name_mode;
?>
<h3 class="title">
<?php esc_html_e("Installer Settings", 'duplicator-pro'); ?>
</h3>
<hr size="1" />
<label class="lbl-larger">
<?php esc_html_e("Name", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<b><?php esc_html_e("Default 'Save as' name:", 'duplicator-pro'); ?></b> <br />
<label>
<i class='fas fa-lock lock-info fa-fw'></i>&nbsp;
<input
type="radio"
name="installer_name_mode"
class="margin-0"
value="<?php echo esc_attr(GlobalEntity::INSTALLER_NAME_MODE_WITH_HASH); ?>"
<?php checked($installerNameMode === GlobalEntity::INSTALLER_NAME_MODE_WITH_HASH); ?>>&nbsp;
[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>&nbsp;
<input
type="radio"
name="installer_name_mode"
class="margin-0"
value="<?php echo esc_attr(GlobalEntity::INSTALLER_NAME_MODE_SIMPLE); ?>"
<?php checked($installerNameMode === GlobalEntity::INSTALLER_NAME_MODE_SIMPLE); ?>>&nbsp;
<?php echo esc_html(PackInstaller::DEFAULT_INSTALLER_FILE_NAME_WITHOUT_HASH); ?>
</label>
<p class="description">
<?php
printf(
esc_html_x(
'To understand the importance and usage of the installer name, please %1$sread this section%2$s.',
'1 and 2 are opening and closing anchor or link tags',
'duplicator-pro'
),
'<a href="javascript:void(0)" onclick="jQuery(\'#dupli-inst-mode-details\').toggle()">',
'</a>'
);
?>
</p>
<div id="dupli-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 Backups 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>
</div>
<h3 class="title">
<?php esc_html_e("Installer Cleanup", 'duplicator-pro') ?>
</h3>
<hr size="1" />
<label class="lbl-larger">
<?php esc_html_e("Mode", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="radio"
name="cleanup_mode"
id="cleanup_mode_Cleanup_Off"
class="margin-0"
value="<?php echo (int) GlobalEntity::CLEANUP_MODE_OFF; ?>"
<?php checked($global->cleanup_mode, GlobalEntity::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"
class="margin-0"
value="<?php echo (int) GlobalEntity::CLEANUP_MODE_MAIL; ?>"
<?php checked($global->cleanup_mode, GlobalEntity::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"
class="margin-0"
value="<?php echo (int) GlobalEntity::CLEANUP_MODE_AUTO; ?>"
<?php checked($global->cleanup_mode, GlobalEntity::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>
</div>
<label class="lbl-larger">
<?php esc_html_e("Auto Cleanup", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
data-parsley-required
data-parsley-errors-container="#auto_cleanup_hours_error_container"
data-parsley-min="1"
data-parsley-type="number"
class="inline-display width-small margin-0"
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>
</div>

View File

@@ -0,0 +1,119 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Models\GlobalEntity;
use Duplicator\Utils\Settings\ServerThrottle;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
?>
<h3 class="title">
<?php esc_html_e("Processing", 'duplicator-pro') ?>
</h3>
<hr size="1" />
<label class="lbl-larger">
<?php esc_html_e("Server Throttle", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="radio"
name="server_load_reduction"
id="server_load_reduction_off"
value="<?php echo (int) ServerThrottle::NONE; ?>"
class="margin-0"
<?php checked($global->server_load_reduction, ServerThrottle::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) ServerThrottle::A_BIT; ?>"
class="margin-0"
<?php checked($global->server_load_reduction, ServerThrottle::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) ServerThrottle::MORE; ?>"
class="margin-0"
<?php checked($global->server_load_reduction, ServerThrottle::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) ServerThrottle::A_LOT ?>"
class="margin-0"
<?php checked($global->server_load_reduction, ServerThrottle::A_LOT); ?>>
<label for="server_load_reduction_high">
<?php esc_html_e("High", 'duplicator-pro'); ?>
</label>
<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>
</div>
<label class="lbl-larger">
<?php esc_html_e("Max Build Time", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
data-parsley-required data-parsley-errors-container="#max_package_runtime_in_min_error_container"
data-parsley-min="0"
data-parsley-type="number"
class="inline-display width-small margin-0"
type="text"
name="max_package_runtime_in_min"
id="max_package_runtime_in_min"
value="<?php echo (int) $global->max_package_runtime_in_min; ?>">
<span>&nbsp;<?php esc_html_e('Minutes', 'duplicator-pro'); ?></span>
<div id="max_package_runtime_in_min_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php esc_html_e('Max build time until Backup is auto-cancelled. Set to 0 for no limit.', 'duplicator-pro'); ?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e("Max Transfer Time", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
data-parsley-required data-parsley-errors-container="#max_package_transfer_time_in_min_error_container"
data-parsley-min="1"
data-parsley-type="number"
class="inline-display width-small margin-0"
type="text"
name="max_package_transfer_time_in_min"
id="max_package_transfer_time_in_min"
value="<?php echo (int) $global->max_package_transfer_time_in_min; ?>">
<span>&nbsp;<?php esc_html_e('Minutes', 'duplicator-pro'); ?></span>
<div id="max_package_transfer_time_in_min_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php esc_html_e('Max Backup transfer time in minutes until the transfer is auto-cancelled.', 'duplicator-pro'); ?>
</p>
</div>

View File

@@ -0,0 +1,45 @@
<?php
/**
* Duplicator Backup row in table Backups list
*
* @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
*/
$brandNewUrl = ControllersManager::getCurrentLink(
[
ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_EDIT,
'action' => 'new',
]
);
$tipContent = __(
'Create a new Brand.',
'duplicator-pro'
);
?>
<span
data-tooltip="<?php echo esc_attr($tipContent); ?>"
>
<a
href="<?php echo esc_url($brandNewUrl); ?>"
id="dupli-create-new"
class="button primary small font-bold margin-0"
>
<?php esc_html_e('Add New', 'duplicator-pro'); ?>
</a>
</span>

View File

@@ -0,0 +1,324 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Views\UI\UiDialog;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var Duplicator\Core\Controllers\PageAction[] $tplData['actions']
* @var Duplicator\Models\BrandEntity $brand
*/
$brand = $tplData['brand'];
$brand_list_url = ControllersManager::getCurrentLink([ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_LIST]);
$brand_edit_url = ControllersManager::getCurrentLink([ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_EDIT]);
// Let's make impossible - do TinyMCE textarea required
add_action('the_editor', function ($editorMarkup) {
if (stripos($editorMarkup, 'required') !== false) {
$editorMarkup = str_replace('<textarea', '<textarea required="true"', $editorMarkup);
}
return $editorMarkup;
});
?>
<div class="dup-toolbar">
<a href="<?php echo esc_url($brand_list_url); ?>" class="button secondary hollow small ">
<i class="far fa-image"></i> <?php esc_html_e('Brands', 'duplicator-pro'); ?>
</a>
</div>
<hr class="dup-toolbar-divider" />
<form
id="dupli-package-brand-form"
class="dup-monitored-form"
action="<?php echo esc_url($brand_edit_url); ?>" method="post" data-parsley-ui-enabled="true">
<?php $tplData['actions'][SettingsPageController::ACTION_BRAND_SAVE]->getActionNonceFileds(); ?>
<input type="hidden" name="id" id="brand-id" value="<?php echo (int) $brand->getId(); ?>" />
<input type="hidden" name="attachments" id="brand-attachments" value="<?php echo esc_attr(join(";", $brand->attachments)); ?>" />
<div class="dup-settings-wrapper margin-bottom-1">
<?php
if ($brand->isDefault()) {
$tplMng->render('admin_pages/settings/brand/brand_edit_default', ['brand' => $brand]);
} else {
$tplMng->render('admin_pages/settings/brand/brand_edit_new', ['brand' => $brand]);
}
?>
</div>
<h2><?php esc_html_e('Preview Area:', 'duplicator-pro'); ?></h2>
<div class="preview-area">
<div class="preview-box">
<div class="preview-header">
<div class="preview-title">
<div id="preview-logo">
<?php echo $brand->logo; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
</div>
<div class="preview-version">
<?php
esc_html_e("version: ", 'duplicator-pro');
echo esc_html(DUPLICATOR_VERSION);
?> <br />
» <a href="javascript:void(0)">
<?php esc_html_e("info", 'duplicator-pro'); ?>
</a> » <a href="javascript:void(0)">
<?php esc_html_e("help", 'duplicator-pro'); ?>
</a> <i class="fa-solid fa-question-circle fa-sm dark-gray-color"></i>
</div>
</div>
</div>
<div class="preview-content">
<div class="preview-mode"><?php esc_html_e("Mode: Standard Install", 'duplicator-pro'); ?></div>
<div class="preview-steps">
<?php esc_html_e("Step 1 of 4: Deployment", 'duplicator-pro'); ?>
</div>
</div>
</div>
<div class="preview-notes">
<?php esc_html_e("Note: Be sure to validate the final results in the installer.php file.", 'duplicator-pro'); ?>
</div>
</div>
<br style="clear:both" />
<button
id="dup-save-brand-button"
class="button primary small" type="button"
onclick="return DupliJs.Settings.Brand.Save();"
<?php disabled($brand->isDefault()); ?>>
<?php esc_html_e('Save Brand', 'duplicator-pro'); ?>
</button>
</form>
<!-- ==========================================
THICK-BOX DIALOGS: -->
<?php
$alert1 = new UiDialog();
$alert1->title = __('Branding Guide', 'duplicator-pro');
$alert1->templatePath = 'parts/dialogs/contents/branding-guide';
$alert1->width = 650;
$alert1->height = 400;
$alert1->initAlert();
$alert2 = new UiDialog();
$alert2->title = __('Brand Name', 'duplicator-pro');
$alert2->message = __("WARNING: Brand name cannot be named like <strong>Default</strong> because is a reserved name.", 'duplicator-pro');
$alert2->initAlert();
$alert3 = new UiDialog();
$alert3->title = __('Brand Logo', 'duplicator-pro');
$alert3->message = __("WARNING: Brand logo have a wrong URL.", 'duplicator-pro');
$alert3->initAlert();
?>
<script>
DupliJs.Brand = new Object();
/* Shows the style Guide */
DupliJs.Brand.ShowStyleGuide = function() {
<?php $alert1->showAlert(); ?>
return;
}
jQuery(document).ready(function($) {
/*
* CHECK IS IMAGE
* @url: https://github.com/CreativForm/CreativeTools
*/
$.isImage = function(string) {
if (null === string || false === string)
return false;
return (string.match(/\.(jpeg|jpg|gif|png|bmp|svg|tiff|jfif|exif|ppm|pgm|pbm|pnm|webp|hdr|hif|bpg|img|pam|tga|psd|psp|xcf|cpt|vicar)$/) != null ?
true : false);
};
/*
* CHECK IF IMAGE EXISTS
* @url: https://github.com/CreativForm/CreativeTools
*/
$.imageExists = function(string, callback) {
if ($.isImage(string)) {
var img = new Image(10, 10);
img.src = string;
img.onload = function() {
if (typeof callback == 'function') {
callback(true);
img = null;
}
};
img.onerror = function() {
if (typeof callback == 'function') {
callback(false);
img = null;
}
};
} else {
if (typeof callback == 'function') {
callback(false);
img = null;
}
}
};
var strip_tags = function(input, allowed) {
// discuss at: http://phpjs.org/functions/strip_tags/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Luke Godfrey
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// input by: Pul
// input by: Alex
// input by: Marc Palau
// input by: Brett Zamir (http://brett-zamir.me)
// input by: Bobby Drake
// input by: Evertjan Garretsen
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Onno Marsman
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Eric Nagel
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Tomasz Wesolowski
// revised by: Rafał Kukawski (http://blog.kukawski.pl/)
// example 1: strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i><b>');
// returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
// example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
// returns 2: '<p>Kevin van Zonneveld</p>'
// example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
// returns 3: "<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>"
// example 4: strip_tags('1 < 5 5 > 1');
// returns 4: '1 < 5 5 > 1'
// example 5: strip_tags('1 <br/> 1');
// returns 5: '1 1'
// example 6: strip_tags('1 <br/> 1', '<br>');
// returns 6: '1 <br/> 1'
// example 7: strip_tags('1 <br/> 1', '<br><br/>');
// returns 7: '1 <br/> 1'
var allowed = (((allowed || '') + '')
.toLowerCase()
.match(/<[a-z][a-z0-9]*>/g) || [])
.join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
let tags = '/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi';
let commentsAndPhpTags = '/<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi';
return input.replace(commentsAndPhpTags, '').replace(
tags,
function($0, $1) {
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
});
}
DupliJs.Settings.Debounce;
DupliJs.Settings.Brand.Save = function(e) {
clearTimeout(DupliJs.Settings.Debounce);
if ($('#dupli-package-brand-form').parsley().validate()) {
var $logo = $("#brand-logo");
$('#brand-action').val('save');
$logo.removeClass('parsley-error');
var image_valid = true;
// Check is images valid
var images = $('<div />').html($logo.val()).children('img').map(function() {
var image = $(this).attr('src');
return image;
}).get();
for (var i = 0; i < images.length; i++) {
$.imageExists(images[i], function(r) {
if (!r) {
image_valid = false;
$logo.removeClass('parsley-success').addClass('parsley-error');
}
});
}
DupliJs.Settings.Debounce = setTimeout(function() {
// Check is brand name reserved
if ($('#brand-name') && $.trim($('#brand-name').val()).toLowerCase() == 'default') {
<?php $alert2->showAlert(); ?>
e.preventDefault();
} else if (!image_valid) {
<?php $alert3->showAlert(); ?>
e.preventDefault();
} else {
DupliJs.UI.hasUnsavedChanges = false;
$('#dupli-package-brand-form').submit();
}
}, 200);
}
}
<?php if (!$brand->isDefault()) : ?>
//INIT
$('#dupli-package-brand-form #brand-name').focus();
// Let's automate this things
DupliJs.Settings.Automatization = function(e) {
if (e.originalEvent !== undefined) {
clearTimeout(DupliJs.Settings.Debounce);
var $this = $("#dupli-package-brand-form #brand-logo"),
$debounce = 800;
// Smart debounce
if (e.currentTarget) {
if ($(e.currentTarget).hasClass('button')) $debounce = 5;
if ($(e.currentTarget).hasClass('preview-area')) $debounce = 200;
}
DupliJs.Settings.Debounce = setTimeout(function() {
var $value = $this.val();
$this.val(strip_tags($value, '<a><i><b><u><em><ins><div><img><span><strong>'));
// Do preview
$("#dupli-package-brand-form #preview-logo").html($value);
// Now we must made array for path of all images (if the are on server) We don't need remote images (CDN is cool thing)
// Let's first collect all images
var images = $('<div />').html($value).children('img').map(function() {
return $(this).attr('src')
}).get();
images = $.unique(images);
$("#dupli-package-brand-form #brand-attachments").val('');
// New magic trick is to determinate is CDN or uploaded image
// - CDN will not be return like path
// - Server side images will be returned like image real path
if (images.length > 0) {
var path = images.map(function(src) {
var hostname = <?php echo wp_json_encode(plugins_url()); ?>.replace(/https?|\:\/\/|\/wp-content\/plugins/gi, '');
if (new RegExp('(https?:)?//' + hostname, 'ig').test(src)) {
return src.replace(new RegExp('(https?:)?//' + hostname + '/wp-content|/uploads', 'ig'), '');
}
});
if (path.length > 0) $("#dupli-package-brand-form #brand-attachments").val(path.join(';'));
}
}, $debounce);
}
};
// On textarea change
$(document).on(
'change keyup paste input mouseout mouseover propertychange',
"#dupli-package-brand-form #brand-logo",
DupliJs.Settings.Automatization
);
// On other boxes
$(document).on('mouseover', "#dupli-package-brand-form .preview-area", DupliJs.Settings.Automatization);
<?php endif; ?>
});
</script>

View File

@@ -0,0 +1,60 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Models\BrandEntity;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var Duplicator\Models\BrandEntity $brand
*/
$brand = $tplData['brand'];
?>
<label class="lbl-larger" >
<?php esc_html_e("Name", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1" >
<?php echo esc_html($brand->name); ?>
</div>
<label class="lbl-larger" >
<?php esc_html_e("Notes", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1" >
<?php echo esc_html($brand->notes); ?>
</div>
<label class="lbl-larger" >
<?php esc_html_e("Logo", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1" >
<div class="width-xlarge" >
<div class="style-guide-link float-right">
<a href="javascript:void(0)" class="button secondary hollow small" onclick="DupliJs.Brand.ShowStyleGuide();">
<?php esc_html_e("Style Guide", 'duplicator-pro'); ?>
</a>
</div>
<textarea id="brand-default-logo" readonly="true"><?php echo esc_html($brand->logo); ?></textarea>
</div>
</div>
<label class="lbl-larger" >
<?php esc_html_e("Activation", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1 width-xlarge" >
<?php esc_html_e(
"This brand can be activated by using the installer brand drop-down during the Backup creation process.
It can also be set via a template.",
'duplicator-pro'
); ?>
</div>
<i><?php esc_html_e("The default brand cannot be changed", 'duplicator-pro'); ?></i>

View File

@@ -0,0 +1,81 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Models\BrandEntity;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var Duplicator\Models\BrandEntity $brand
*/
$brand = $tplData['brand'];
?>
<label class="lbl-larger" >
<?php esc_html_e("Name", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1" >
<input type="text" name="name" id="brand-name" value="<?php echo esc_attr($brand->name); ?>" data-parsley-required>
<p class="description"><?php esc_html_e("Displayed as the page title of the installer.", 'duplicator-pro'); ?></p>
</div>
<label class="lbl-larger" >
<?php esc_html_e("Notes", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1" >
<textarea name="notes" id="brand-notes"><?php echo esc_html($brand->notes); ?></textarea>
</div>
<label class="lbl-larger" >
<?php esc_html_e("Logo", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1" >
<div class="width-xlarge" >
<div class="style-guide-link">
<a href="javascript:void(0)" class="button secondary hollow small" onclick="DupliJs.Brand.ShowStyleGuide();">
<?php esc_html_e("Style Guide", 'duplicator-pro'); ?>
</a>
</div>
<div class="brand-logo-editor">
<?php
wp_editor(
$brand->logo,
'brand-logo',
[
'wpautop' => true,
'media_buttons' => true,
'textarea_name' => 'logo',
'textarea_rows' => 50,
'tabindex' => '',
'tabfocus_elements' => ':prev,:next',
'editor_css' => '',
'editor_class' => 'required',
'teeny' => false,
'dfw' => false,
'tinymce' => false,
'quicktags' => ['buttons' => 'strong,em,i,ins,close,img,link'],
]
);
?>
</div>
</div>
</div>
<label class="lbl-larger" >
<?php esc_html_e("Activation", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1 width-xlarge" >
<?php esc_html_e(
"This brand can be activated by using the installer brand drop-down during the Backup creation process.
It can also be set via a template.",
'duplicator-pro'
); ?>
</div>

View File

@@ -0,0 +1,332 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Models\BrandEntity;
use Duplicator\Views\UI\UiDialog;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$brand_list_url = ControllersManager::getCurrentLink([ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_LIST]);
$brand_edit_url = ControllersManager::getCurrentLink([ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_EDIT]);
$brands = BrandEntity::getAllWithDefault();
$brand_count = count($brands);
?>
<h3 class="title">
<?php esc_html_e('Installer Branding', 'duplicator-pro'); ?>
</h3>
<hr>
<?php
if (!License::can(License::CAPABILITY_BRAND)) {
$tplMng->render('admin_pages/settings/brand/no_capability_list');
return;
}
?>
<div class="dup-toolbar">
<label for="bulk_action" class="screen-reader-text">Select bulk action</label>
<select id="bulk_action" class="small">
<option value="-1" selected="selected">
<?php esc_html_e('Bulk Actions', 'duplicator-pro'); ?>
</option>
<option value="delete" title="<?php esc_attr_e('Delete selected brand endpoint(s)', 'duplicator-pro'); ?>">
<?php esc_html_e('Delete', 'duplicator-pro'); ?>
</option>
</select>
<input
type="button"
class="button hollow secondary small action"
value="<?php esc_html_e("Apply", 'duplicator-pro') ?>"
onclick="DupliJs.Settings.Brand.BulkAction()">
<span class="separator"></span>
<?php $tplMng->render('admin_pages/settings/brand/brand_create_button'); ?>
</div>
<form id="dup-brand-form" action="<?php echo esc_attr($brand_list_url); ?>" method="post">
<?php $tplData['actions'][SettingsPageController::ACTION_BRAND_DELETE]->getActionNonceFileds(); ?>
<table class="widefat brand-tbl dup-table-list valign-top">
<thead>
<tr>
<th style='width:10px;'>
<input type="checkbox" id="dupli-chk-all" title="Select all brand endpoints" onclick="DupliJs.Settings.Brand.SetAll(this)">
</th>
<th style='width:100%;'><?php esc_html_e('Name', 'duplicator-pro'); ?></th>
</tr>
</thead>
<tbody>
<tr id='main-view-<?php echo (int) $brands[0]->getId(); ?>' class="brand-row row">
<td>
<input type="checkbox" disabled="disabled" />
</td>
<td>
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.Edit(0)"><b><?php esc_html_e('Default', 'duplicator-pro'); ?></b></a>
<div class="sub-menu">
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.Edit(0)"><?php esc_html_e('View', 'duplicator-pro'); ?></a> |
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.View('<?php echo (int) $brands[0]->getId(); ?>');">
<?php esc_html_e('Quick View', 'duplicator-pro'); ?>
</a>
</div>
</td>
</tr>
<tr id="quick-view-<?php echo (int) $brands[0]->getId() ?>" class="brand-detail row-details">
<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($brands[0]->name) ?>
</div>
<div>
<label><?php esc_html_e('Notes', 'duplicator-pro') ?>:</label>
<?php echo (strlen($brands[0]->notes)) ? esc_html($brands[0]->notes) : esc_html__('(no notes)', 'duplicator-pro'); ?>
</div>
<div>
<label><?php esc_html_e('Logo', 'duplicator-pro') ?>:</label>
<?php
echo $brands[0]->logo // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
</div>
<button
type="button"
class="button hollow secondary small"
onclick="DupliJs.Settings.Brand.View('<?php echo (int) $brands[0]->getId(); ?>');">
<?php esc_html_e('Close', 'duplicator-pro') ?>
</button>
</td>
</tr>
<?php
$i = 0;
foreach ($brands as $x => $brand) :
if ($x === 0) {
continue; // remove default item in list because is defined out of loop below
}
$i++;
//$brand_type = $brand->getModeText();
?>
<tr id='main-view-<?php echo (int) $brand->getId() ?>' class="row brand-row<?php echo ($i % 2) ? ' alternate' : ''; ?>">
<td>
<?php if ($brand->editable) : ?>
<input name="selected_id[]" type="checkbox" value="<?php echo (int) $brand->getId(); ?>" class="item-chk" />
<?php else : ?>
<input type="checkbox" disabled="disabled" />
<?php endif; ?>
</td>
<td>
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.Edit('<?php echo (int) $brand->getId(); ?>')">
<b><?php echo esc_html($brand->name); ?></b>
</a>
<?php if ($brand->editable) : ?>
<div class="sub-menu">
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.Edit('<?php echo (int) $brand->getId(); ?>')">
<?php esc_html_e('Edit', 'duplicator-pro') ?>
</a> |
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.View('<?php echo (int) $brand->getId(); ?>');">
<?php esc_html_e('Quick View', 'duplicator-pro') ?>
</a> |
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.Delete('<?php echo (int) $brand->getId(); ?>');">
<?php esc_html_e('Delete', 'duplicator-pro') ?>
</a>
</div>
<?php else : ?>
<div class="sub-menu">
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.Edit(0)">
<?php esc_html_e('View', 'duplicator-pro') ?>
</a> |
<a href="javascript:void(0);" onclick="DupliJs.Settings.Brand.View('<?php echo (int) $brand->getId(); ?>');">
<?php esc_html_e('Quick View', 'duplicator-pro') ?>
</a>
</div>
<?php endif; ?>
</td>
</tr>
<tr id='quick-view-<?php echo (int) $brand->getId() ?>' class='<?php echo ($i % 2) ? 'alternate ' : ''; ?>brand-detail row-details'>
<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($brand->name); ?>
</div>
<div>
<label><?php esc_html_e('Notes', 'duplicator-pro') ?>:</label>
<?php echo (strlen($brand->notes)) ? esc_html($brand->notes) : esc_html__('(no notes)', 'duplicator-pro'); ?>
</div>
<div>
<label><?php esc_html_e('Logo', 'duplicator-pro') ?>:</label>
<?php
echo $brand->logo; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
</div>
<button
type="button"
class="button hollow secondary small"
onclick="DupliJs.Settings.Brand.View('<?php echo (int) $brand->getId(); ?>');">
<?php esc_html_e('Close', 'duplicator-pro') ?>
</button>
</td>
</tr>
<?php
endforeach;
?>
</tbody>
<tfoot>
<tr>
<th colspan="8" style="text-align:right; font-size:12px">
<?php echo esc_html__('Total', 'duplicator-pro') . ': ' . (int) $brand_count; ?>
</th>
</tr>
</tfoot>
</table>
</form>
<!-- ==========================================
THICK-BOX DIALOGS: -->
<?php
$alert1 = new UiDialog();
$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 UiDialog();
$alert2->title = __('Selection Required', 'duplicator-pro');
$alert2->message = __('Please select at least one brand to delete!', 'duplicator-pro');
$alert2->initAlert();
$confirm1 = new UiDialog();
$confirm1->title = __('Delete Brand?', 'duplicator-pro');
$confirm1->message = __('Are you sure you want to delete the selected brand(s)?', 'duplicator-pro');
$confirm1->message .= '<br/>';
$confirm1->message .= '<small><i>' . __('Note: This action removes all brands.', 'duplicator-pro') . '</i></small>';
$confirm1->progressText = __('Removing Brands, Please Wait...', 'duplicator-pro');
$confirm1->jsCallback = 'DupliJs.Settings.Brand.BulkDelete()';
$confirm1->initConfirm();
$confirm2 = new UiDialog();
$confirm2->title = __('Delete Brand?', 'duplicator-pro');
$confirm2->message = __('Are you sure you want to delete the selected brand(s)?', 'duplicator-pro');
$confirm2->progressText = __('Removing Brands, Please Wait...', 'duplicator-pro');
$confirm2->jsCallback = 'DupliJs.Settings.Brand.DeleteThis(this)';
$confirm2->initConfirm();
$delete_nonce = wp_create_nonce('duplicator_brand_delete');
?>
<script>
jQuery(document).ready(function($) {
//Shows detail view
DupliJs.Settings.Brand.AddNew = function() {
document.location.href = <?php echo wp_json_encode("{$brand_edit_url}&action=new"); ?>;
}
DupliJs.Settings.Brand.Edit = function(id) {
if (id == 0) {
document.location.href = <?php echo wp_json_encode("{$brand_edit_url}&action=default&id="); ?> + id;
} else {
document.location.href = <?php echo wp_json_encode("{$brand_edit_url}&action=edit&id="); ?> + id;
}
}
//Shows detail view
DupliJs.Settings.Brand.View = function(id) {
$('#quick-view-' + id).toggle();
$('#main-view-' + id).toggle();
}
//Delets a single record
DupliJs.Settings.Brand.Delete = function(id) {
<?php $confirm2->showConfirm(); ?>
$("#<?php echo esc_js($confirm2->getID()); ?>-confirm").attr('data-id', id);
}
DupliJs.Settings.Brand.DeleteThis = function(e) {
var id = $(e).attr('data-id');
$("input[name^='selected_id[]'][value='" + id + "']").prop('checked', true);
$("#dup-brand-form").submit()
}
// Creats a comma seperate list of all selected Backup ids
DupliJs.Settings.Brand.DeleteList = function() {
var arr = [];
$("input[name^='selected_id[]']").each(function(i, index) {
var $this = $(index);
if ($this.is(':checked') == true) {
arr[i] = $this.val();
}
});
return arr;
}
// Bulk delete
DupliJs.Settings.Brand.BulkDelete = function() {
var list = DupliJs.Settings.Brand.DeleteList();
var pageCount = $('#current-page-selector').val();
var pageItems = $("input[name^='selected_id[]']");
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_brand_delete',
brand_ids: list,
nonce: <?php echo wp_json_encode($delete_nonce); ?>
},
}).done(function(data) {
$('#dup-brand-form').submit();
});
}
// Confirm bulk action
DupliJs.Settings.Brand.BulkAction = function() {
var list = DupliJs.Settings.Brand.DeleteList();
if (list.length == 0) {
<?php $alert2->showAlert(); ?>
return;
}
var action = $('#bulk_action').val();
var checked = ($('.item-chk:checked').length > 0);
if (action != "delete") {
<?php $alert1->showAlert(); ?>
return;
}
if (checked) {
switch (action) {
default:
<?php $alert2->showAlert(); ?>
break;
case 'delete':
<?php $confirm1->showConfirm(); ?>
break;
}
}
}
//Sets all for deletion
DupliJs.Settings.Brand.SetAll = function(chkbox) {
$('.item-chk').each(function() {
this.checked = chkbox.checked;
});
}
});
</script>

View File

@@ -0,0 +1,63 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Views\ViewHelper;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (License::can(License::CAPABILITY_BRAND)) {
return;
}
?>
<div class="width-xlarge" >
<?php
esc_html_e(
"Create your own WordPress distribution by adding a custom name and logo to the installer!
Installer branding lets you create multiple brands for your installers and then choose
which one you want when the Backup is built (example shown below).",
'duplicator-pro'
);
?>
<br/><br/>
<?php
printf(
wp_kses(
__(
'This option isn\'t available at the <b>%1$s</b> license level.',
'duplicator-pro'
),
ViewHelper::GEN_KSES_TAGS
),
esc_html(License::getLicenseToString())
);
?>
<b>
<?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>'
);
?>
</b>
</div>
<div style="border:0px solid #999; padding: 5px; margin: 5px; border-radius: 5px; width:700px">
<img src="<?php echo esc_attr(DUPLICATOR_IMG_URL . '/dupli-brand.png'); ?>" >
</div>

View File

@@ -0,0 +1,197 @@
<?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;
use Duplicator\Views\UI\UiDialog;
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>
<?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 if (!is_multisite()) {
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 Backup read and Backup 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>
<?php if (is_multisite()) { ?>
<p>
<i class="fa-solid fa-info-circle fa-lg dark-gray-color"></i>&nbsp;
<b>
<?php esc_html_e(
'In multisite installations, only Super Admin users can be granted access of any type. By default, all
Super Admin users are granted all permissions.',
'duplicator-pro'
); ?>
</b>
</p>
<?php } ?>
<hr size="1" />
<div class="dup-settings-wrapper margin-bottom-1">
<?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']];
}
?>
<label class="lbl-larger" for="<?php echo esc_attr($inputId); ?>">
<?php echo esc_html(str_repeat('-&nbsp;&nbsp;', $nParents)); ?>
<?php echo esc_html($capInfo['label']); ?>&nbsp;
<i
class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php echo esc_attr($capInfo['label']); ?>"
data-tooltip="<?php echo esc_attr($tCont); ?>"
data-tooltip-width="600">
</i>
</label>
<div class="margin-bottom-1">
<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>
</div>
<?php } ?>
</div>
</div>
<hr>
<p>
<input
type="submit" name="submit" id="submit"
class="button primary small"
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 hollow small">
<?php esc_html_e('Reset to Default', 'duplicator-pro'); ?>
</button>
</p>
</form>
<?php
//Delete Dialog
$dlgDelete = new UiDialog();
$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 = 'DupliJs.Settings.CapabilitesReset()';
$dlgDelete->initConfirm();
?>
<script>
jQuery(document).ready(function($) {
DupliJs.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,148 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Ajax\ServicesActivityLog;
use Duplicator\Models\ActivityLog\LogUtils;
use Duplicator\Models\DynamicGlobalEntity;
use Duplicator\Models\GlobalEntity;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
$dGlobal = DynamicGlobalEntity::getInstance();
$retentionMonths = $dGlobal->getValInt('activity_log_retention', LogUtils::DEFAULT_RETENTION_MONTHS) / MONTH_IN_SECONDS;
?>
<div class="dup-accordion-wrapper display-separators close">
<div class="accordion-header">
<h3 class="title" id="advanced-section-header">
<?php esc_html_e('Advanced', 'duplicator-pro') ?>
</h3>
</div>
<div class="accordion-content">
<label class="lbl-larger">
<?php esc_html_e('Settings', 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<button
id="dupli-reset-all"
class="button secondary hollow small margin-0"
onclick="DupliJs.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="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e("Reset Settings", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tContent); ?>">
</i>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e("Foreign JavaScript", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="_unhook_third_party_js"
id="_unhook_third_party_js"
value="1"
class="margin-0"
<?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>
</div>
<label class="lbl-larger">
<?php esc_html_e("Foreign CSS", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="_unhook_third_party_css"
id="unhook_third_party_css"
value="1"
class="margin-0"
<?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>
</div>
<label class="lbl-larger">
<?php esc_html_e("Activity Log Retention", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="number"
class="width-small inline-display margin-0"
name="activity_log_retention_months"
id="activity_log_retention_months"
value="<?php echo (int) $retentionMonths; ?>"
min="0"
step="1">
&nbsp;<span class="inline-display"><?php esc_html_e("months", 'duplicator-pro'); ?></span>
<p class="description">
<?php
esc_html_e("Set how many months to keep activity log entries. Enter 0 to keep all logs permanently.", 'duplicator-pro');
?>
<br>
<?php
esc_html_e("Activity logs older than the specified number of months will be automatically deleted.", 'duplicator-pro');
?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e("Delete Activity Logs", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<button
type="button"
id="dup-delete-activity-logs"
class="button secondary hollow small margin-0"
data-nonce="<?php echo esc_attr(wp_create_nonce(ServicesActivityLog::NONCE_DELETE_ALL)); ?>"
onclick="DupliJs.Settings.ConfirmDeleteActivityLogs(); return false;">
<i class="fas fa-trash fa-sm"></i> <?php esc_html_e('Delete All Logs', 'duplicator-pro'); ?>
</button>
<p class="description">
<?php esc_html_e("Permanently delete all activity log entries. This action cannot be undone.", 'duplicator-pro'); ?>
</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,115 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Models\StaticGlobal;
use Duplicator\Utils\Logging\DupLog;
use Duplicator\Utils\Logging\TraceLogMng;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$trace_log_enabled = StaticGlobal::getTraceLogEnabledOption();
$send_trace_to_error_log = StaticGlobal::getSendTraceToErrorLogOption();
if ($trace_log_enabled) {
$logging_mode = ($send_trace_to_error_log) ? 'enhanced' : 'on';
} else {
$logging_mode = 'off';
}
?>
<div class="dup-accordion-wrapper display-separators close">
<div class="accordion-header">
<h3 class="title">
<?php esc_html_e('Debug', 'duplicator-pro') ?>
</h3>
</div>
<div class="accordion-content">
<label class="lbl-larger">
<?php esc_html_e('Trace Log', 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<select
name="_logging_mode"
class="margin-0 width-medium">
<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>
</div>
<label class="lbl-larger">
<?php esc_html_e('Trace Log Max Size', 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<?php
$maxSizeMB = TraceLogMng::getInstance()->getMaxTotalSize() / MB_IN_BYTES;
?>
<input
data-parsley-required data-parsley-errors-container="#trace_max_size_error_container"
data-parsley-min="0"
data-parsley-type="number"
class="inline-display width-small margin-0"
type="number"
name="trace_max_size"
id="trace_max_size"
value="<?php echo (int) $maxSizeMB; ?>">
<span>&nbsp;<?php esc_html_e('MB', 'duplicator-pro'); ?></span>
<div id="trace_max_size_error_container" class="duplicator-error-container"></div>
<p class="description">
<?php
wp_kses(
__(
"Maximum total size for all trace log files.<br/>
When an individual log file reaches its size limit, it is archived and a new file is created. <br/>
This process continues until the total size of all log files reaches this limit, at which point the oldest logs are deleted. <br/>
Setting this to 0 means unlimited size (logs will never be automatically deleted). <br/>
<b>Caution:</b> leaving trace logging enabled with unlimited size for extended periods can consume
significant disk space and require manual cleanup.",
'duplicator-pro'
),
[
'br' => [],
'b' => [],
]
); ?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e('Download Trace Log', 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<button
class="button secondary hollow small margin-0"
<?php disabled(DupLog::traceFileExists(), false); ?>
onclick="DupliJs.Pack.DownloadTraceLog(); return false">
<i class="fa fa-download"></i>
<?php echo esc_html__('Trace Log', 'duplicator-pro') . ' (' . esc_html(DupLog::getTraceStatus()) . ')'; ?>
</button>
</div>
</div>
</div>

View File

@@ -0,0 +1,93 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Models\GlobalEntity;
use Duplicator\Utils\Email\EmailSummary;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
?>
<h3 class="title">
<?php esc_html_e('Email Summary', 'duplicator-pro') ?>
</h3>
<hr size="1" />
<label class="lbl-larger">
<?php esc_html_e('Frequency', 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<select
id="email-summary-frequency"
name="_email_summary_frequency"
class="margin-0 width-xlarge">
<?php foreach (EmailSummary::getAllFrequencyOptions() as $key => $label) : ?>
<option value="<?php echo esc_attr((string) $key); ?>" <?php selected($global->getEmailSummaryFrequency(), $key); ?>>
<?php echo esc_html($label); ?>
</option>
<?php endforeach; ?>
</select>
<p class="description">
<?php
printf(
esc_html_x(
'You can view the email summary example %1$shere%2$s.',
'%1$s and %2$s are the opening and close <a> tags to the summary preview link',
'duplicator-pro'
),
'<a href="' . esc_url(EmailSummary::getPreviewLink()) . '" target="_blank">',
'</a>'
);
?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e('Recipients', 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<select
id="email-summary-recipients"
name="_email_summary_recipients[]" m
multiple
class="margin-0 width-xlarge">
<?php foreach ($global->getEmailSummaryRecipients() as $email) : ?>
<option value="<?php echo esc_attr($email); ?>" selected><?php echo esc_html($email); ?></option>
<?php endforeach; ?>
<?php foreach (EmailSummary::getRecipientSuggestions() as $email) : ?>
<option value="<?php echo esc_attr($email); ?>"><?php echo esc_html($email); ?></option>
<?php endforeach; ?>
</select>
<?php if (count($global->getEmailSummaryRecipients()) === 0) : ?>
<p class="descriptionred">
<em>
<span class="maroon">
<?php esc_html_e('No recipients entered. Email summary won\'t be send.', 'duplicator-pro') ?>
</span>
</em>
</p>
<?php endif; ?>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#email-summary-recipients').select2({
tags: true,
tokenSeparators: [',', ' '],
placeholder: '<?php esc_attr_e('Enter email addresses', 'duplicator-pro'); ?>',
minimumInputLength: 3,
});
});
</script>

View File

@@ -0,0 +1,135 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Models\GlobalEntity;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\PageAction;
use Duplicator\Views\UI\UiDialog;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
/** @var PageAction */
$resetAction = $tplData['actions'][SettingsPageController::ACTION_RESET_SETTINGS];
?>
<?php do_action('duplicator_settings_general_before'); ?>
<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(); ?>
<div class="dup-settings-wrapper margin-bottom-1">
<?php $tplMng->render('admin_pages/settings/general/plugin_settings'); ?>
<hr>
<?php TplMng::getInstance()->render('admin_pages/settings/general/email_summary'); ?>
<?php TplMng::getInstance()->render('admin_pages/settings/general/debug_settings'); ?>
<?php TplMng::getInstance()->render('admin_pages/settings/general/advanced_settings'); ?>
</div>
<p>
<input
type="submit" name="submit" id="submit"
class="button primary small"
value="<?php esc_attr_e('Save Settings', 'duplicator-pro') ?>">
</p>
</form>
<?php
$resetSettingsDialog = new UiDialog();
$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 = 'DupliJs.Pack.ResetAll()';
$resetSettingsDialog->progressOn = false;
$resetSettingsDialog->okText = __('Yes', 'duplicator-pro');
$resetSettingsDialog->cancelText = __('No', 'duplicator-pro');
$resetSettingsDialog->closeOnConfirm = true;
$resetSettingsDialog->initConfirm();
$deleteLogsDialog = new UiDialog();
$deleteLogsDialog->title = __('Delete Activity Logs?', 'duplicator-pro');
$deleteLogsDialog->message = __('Are you sure you want to delete all activity logs? This action cannot be undone.', 'duplicator-pro');
$deleteLogsDialog->progressText = __('Deleting logs, Please Wait...', 'duplicator-pro');
$deleteLogsDialog->jsCallback = 'DupliJs.Settings.DeleteActivityLogs()';
$deleteLogsDialog->progressOn = false;
$deleteLogsDialog->okText = __('Yes', 'duplicator-pro');
$deleteLogsDialog->cancelText = __('No', 'duplicator-pro');
$deleteLogsDialog->closeOnConfirm = true;
$deleteLogsDialog->initConfirm();
?>
<script>
jQuery(document).ready(function($) {
// which: 0=installer, 1=archive, 2=sql file, 3=log
DupliJs.Pack.DownloadTraceLog = function() {
var actionLocation = ajaxurl + '?action=duplicator_get_trace_log&nonce=' +
'<?php echo esc_js(wp_create_nonce('duplicator_get_trace_log')); ?>';
location.href = actionLocation;
};
DupliJs.Pack.ConfirmResetAll = function() {
<?php $resetSettingsDialog->showConfirm(); ?>
};
DupliJs.Pack.ResetAll = function() {
let resetUrl = <?php echo wp_json_encode($resetAction->getUrl()); ?>;
location.href = resetUrl;
};
DupliJs.Settings.ConfirmDeleteActivityLogs = function() {
<?php $deleteLogsDialog->showConfirm(); ?>
};
DupliJs.Settings.DeleteActivityLogs = function() {
var $button = $('#dup-delete-activity-logs');
var nonce = $button.data('nonce');
$button.prop('disabled', true);
$.ajax({
type: 'POST',
url: ajaxurl,
data: {
action: 'duplicator_activity_log_delete_all',
nonce: nonce
},
success: function(response) {
var funcData = response.data && response.data.funcData ? response.data.funcData : {};
if (response.success && funcData.success) {
DupliJs.addAdminMessage(funcData.message, 'notice');
} else {
var errorMsg = funcData.message
? funcData.message
: '<?php echo esc_js(__('An error occurred while deleting activity logs.', 'duplicator-pro')); ?>';
DupliJs.addAdminMessage(errorMsg, 'error');
}
$button.prop('disabled', false);
},
error: function() {
DupliJs.addAdminMessage('<?php echo esc_js(__('An error occurred while deleting activity logs.', 'duplicator-pro')); ?>', 'error');
$button.prop('disabled', false);
}
});
};
//Init
$("#_trace_log_enabled").click(function() {
$('#_send_trace_to_error_log').attr('disabled', !$(this).is(':checked'));
});
});
</script>

View File

@@ -0,0 +1,128 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Models\GlobalEntity;
use Duplicator\Models\StaticGlobal;
use Duplicator\Utils\Crypt\CryptBlowfish;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
?>
<h3 class="title">
<?php esc_html_e("Plugin", 'duplicator-pro') ?>
</h3>
<hr size="1" />
<label class="lbl-larger">
<?php esc_html_e("Version", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<?php echo esc_html(DUPLICATOR_VERSION); ?>
</div>
<label class="lbl-larger">
<?php esc_html_e("Uninstall", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="uninstall_settings"
id="uninstall_settings"
value="1"
class="margin-0"
<?php checked(StaticGlobal::getUninstallSettingsOption()); ?>>
<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"
class="margin-0"
<?php checked(StaticGlobal::getUninstallPackageOption()); ?>>
<label for="uninstall_packages"><?php esc_html_e("Delete entire storage directory", 'duplicator-pro'); ?></label><br />
</div>
<label class="lbl-larger">
<?php esc_html_e("Encrypt Settings", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="crypt"
id="crypt"
value="1"
class="margin-0"
<?php checked(StaticGlobal::getCryptOption()); ?>>
<label for="crypt"><?php esc_html_e("Enable settings encryption", 'duplicator-pro'); ?> </label><br />
<p class="description">
<?php if (CryptBlowfish::isEncryptAvailable()) { ?>
<?php esc_html_e(
"When this option is enabled, all sensitive data (such as passwords, storage data, and license data)
will be saved encrypted in the database. Disable this option only in case of problems in saving data.",
'duplicator-pro'
); ?>
<?php } else { ?>
<span class="maroon">
<?php esc_html_e('Encryption is not available on this server.', 'duplicator-pro'); ?>
</span>
<?php } ?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e("Usage statistics", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<?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"
class="margin-0"
<?php checked($global->getUsageTracking()); ?>>
<label for="usage_tracking"><?php esc_html_e("Enable usage tracking", 'duplicator-pro'); ?> </label>
<i
class="fa-solid fa-question-circle fa-sm dark-gray-color"
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 } ?>
</div>
<label class="lbl-larger">
<?php esc_html_e("Hide Announcements", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="dup_am_notices"
id="dup_am_notices"
value="1"
class="margin-0"
<?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>
</div>

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 Backup\'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 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 Backup 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$sBackups infos:%2$s Information about the Backups 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$sStorage 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$sTemplate 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$sSchedule 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 a 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 are 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,120 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Controllers\ImportPageController;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Models\GlobalEntity;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
?>
<form id="dup-settings-form" action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>" method="post" data-parsley-validate>
<?php $tplMng->getAction(SettingsPageController::ACTION_IMPORT_SAVE_SETTINGS)->getActionNonceFileds(); ?>
<h3 id="dupli-import-settings" class="title">
<?php esc_html_e("Import Settings", 'duplicator-pro'); ?>
</h3>
<hr size="1" />
<div class="dup-settings-wrapper margin-bottom-1">
<label class="lbl-larger" for="input_import_chunk_size">
<?php esc_html_e("Upload Chunk Size", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<select name="import_chunk_size" id="input_import_chunk_size" class="postform width-medium margin-bottom-0">
<?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 Backup start with a lower size. The upload chunk size is ordered 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>
</div>
<label class="lbl-larger" for="import_custom_path">
<?php esc_html_e("Import custom path", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
class="width-xxlarge margin-bottom-0"
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 Backups are uploaded but adds a folder to check for Backups list.",
'duplicator-pro'
);
?>
<br>
<?php
esc_html_e(
"This can be useful when you want to manually upload Backups to another location which can also be a local storage of current or other site.", // phpcs:ignore Generic.Files.LineLength
'duplicator-pro'
);
?>
</p>
</div>
<h3 class="title"><?php esc_html_e('Recovery', 'duplicator-pro') ?> </h3>
<hr size="1" />
<label class="lbl-larger" for="input_recovery_custom_path">
<?php esc_html_e("Recovery custom path", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
class="width-xxlarge margin-bottom-0"
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>
</div>
</div>
<hr>
<p class="submit dupli-save-submit">
<input
type="submit"
name="submit"
id="submit"
class="button primary small"
value="<?php esc_attr_e('Save Settings', 'duplicator-pro') ?>">
</p>
</form>

View File

@@ -0,0 +1,86 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Views\UI\UiDialog;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$nonce = wp_create_nonce('duplicator_export_settings');
?>
<form id="dup-tools-form-export" method="post">
<input type="hidden" name="action" value="dupli-export">
<div class="dup-settings-wrapper margin-bottom-1">
<h3 class="title">
<?php esc_html_e("Export Duplicator Settings", 'duplicator-pro') ?>
</h3>
<hr size="1" />
<p class="width-xxlarge">
<?php
esc_html_e(
'Exports all schedules, storage locations, templates and settings from this Duplicator Pro instance into a downloadable export file.
The export file can then be used to import data settings from this instance of Duplicator Pro into another plugin instance of Duplicator Pro.',
'duplicator-pro'
);
?>
</p>
<label class="lbl-larger">
<?php esc_html_e("Export Settings File", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="button"
class="button secondary small margin-0"
value="<?php esc_attr_e("Export Data", 'duplicator-pro'); ?>"
onclick="return DupliJs.Tools.ExportDialog();">
</div>
</div>
</form>
<div id="modal-window-export" style="display:none;">
<p>
<?php esc_html_e("This process will:", 'duplicator-pro') ?><br />
<i class="far fa-check-circle"></i>
<?php esc_html_e("Export schedules, storage and templates to a file for import into another Duplicator instance.", 'duplicator-pro'); ?> <br />
<span class="alert-color">
<i class="fas fa-exclamation-triangle fa-sm"></i>
<?php esc_html_e("For security purposes, restrict access to this file and delete after use.", 'duplicator-pro'); ?>
</span>
</p>
<div class="float-right">
<input
type="button"
class="button secondary hollow small"
value="<?php esc_attr_e("Cancel", 'duplicator-pro') ?>"
onclick="tb_remove();">&nbsp;
<input
type="button"
class="button primary small"
value="<?php esc_attr_e("Run Export", 'duplicator-pro') ?>"
onclick="DupliJs.Tools.ExportProcess();setTimeout(function() { tb_remove(); }, 4000);"
title="<?php esc_attr_e("Generate and Download the Export File.", 'duplicator-pro') ?>">
</div>
</div>
<script>
DupliJs.Tools.ExportProcess = function() {
var actionLocation = ajaxurl + '?action=duplicator_export_settings' + '&nonce=' + '<?php echo esc_js($nonce); ?>';
location.href = actionLocation;
}
DupliJs.Tools.ExportDialog = function() {
var url = "#TB_inline?width=610&height=250&inlineId=modal-window-export";
tb_show("<?php esc_html_e("Export Duplicator Pro Data ?", 'duplicator-pro') ?>", url);
jQuery('#TB_window').addClass(<?php echo json_encode(UiDialog::TB_WINDOW_CLASS); ?>);
return false;
}
</script>

View File

@@ -0,0 +1,186 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Views\UI\UiDialog;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var Duplicator\Core\Controllers\PageAction[] $tplData
*/
?>
<form
enctype="multipart/form-data"
id="dup-tools-form-import"
action="<?php echo esc_url($ctrlMng->getCurrentLink()); ?>"
method="post" data-parsley-validate data-parsley-ui-enabled="true">
<?php $tplData['actions'][SettingsPageController::ACTION_IMPORT_SETTINGS]->getActionNonceFileds(); ?>
<div class="dup-settings-wrapper margin-bottom-1">
<h3 class="title">
<?php esc_html_e("Import Duplicator Settings", 'duplicator-pro') ?>
</h3>
<hr size="1" />
<p class="width-xxlarge">
<?php
esc_html_e(
'Import settings from another Duplicator Pro plugin into this instance of Duplicator Pro.
Schedule, storage and template data will be appended to current data, while existing settings will be replaced.
For security reasons, capabilities, license data and license visibility will not be imported.
Schedules depend on storage and templates so importing schedules will require that storage and templates be checked.',
'duplicator-pro'
);
?>
</p>
<label class="lbl-larger">
<?php esc_html_e("Import Settings File", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input type="file" accept=".dup" name="import-file" id="import-file" required="true" class="margin-0">
</div>
<label class="lbl-larger">
<?php esc_html_e("Include in Import", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<table class="dupli-check-tbl margin-bottom-1">
<tr>
<td>
<input
onclick="DupliJs.Tools.ChangeImportButtonState();DupliJs.Tools.SchedulesClicked();"
type="checkbox"
name="import-opts[]"
id="import-schedules" value="schedules"
class="margin-0">
<label for="import-schedules">
<?php esc_html_e("Schedules", 'duplicator-pro'); ?>
</label>
</td>
<td>
<input
onclick="DupliJs.Tools.ChangeImportButtonState();"
type="checkbox"
name="import-opts[]"
id="import-storages" value="storages"
class="margin-0">
<label for="import-storages">
<?php esc_html_e("Storage", 'duplicator-pro'); ?>
</label>
</td>
<td>
<input
onclick="DupliJs.Tools.ChangeImportButtonState();"
type="checkbox"
name="import-opts[]"
id="import-templates" value="templates"
class="margin-0">
<label for="import-templates">
<?php esc_html_e("Templates", 'duplicator-pro'); ?>
</label>
</td>
</tr>
<tr>
<td colspan="3">
<input
onclick="DupliJs.Tools.ChangeImportButtonState();"
type="checkbox"
name="import-opts[]"
id="import-settings"
value="settings"
class="margin-0">
<label for="import-settings">
<?php esc_html_e("Settings", 'duplicator-pro'); ?>
</label>
</td>
</tr>
</table>
<input
id="import-button"
type="button"
class="button primary small"
value="<?php esc_attr_e("Import Data", 'duplicator-pro'); ?>"
onclick="return DupliJs.Tools.ImportDialog();" disabled>
</div>
</div>
</form>
<div id="modal-window-import" style="display:none;">
<p>
<?php esc_html_e("This process will:", 'duplicator-pro') ?><br />
<i class="far fa-check-circle"></i>
<?php esc_html_e("Append schedules, storage and templates if those options are checked.", 'duplicator-pro'); ?> <br />
<i class="far fa-check-circle"></i>
<?php esc_html_e("Overwrite current settings data if the settings option is checked.", 'duplicator-pro'); ?> <br />
<span style="color:#BB1506">
<i class="fas fa-exclamation-triangle fa-sm"></i>
<?php esc_html_e("Review templates and local storages after import to ensure correct path values.", 'duplicator-pro'); ?>
</span>
</p>
<div class="float-right">
<input
type="button"
class="button secondary hollow small"
value="<?php esc_attr_e("Cancel", 'duplicator-pro') ?>"
onclick="tb_remove();">&nbsp;
<input
type="button"
class="button primary small"
value="<?php esc_attr_e("Run Import", 'duplicator-pro') ?>"
onclick="DupliJs.Tools.ImportProcess();"
title="<?php esc_attr_e("Process the Import File.", 'duplicator-pro') ?>">
</div>
</div>
<script>
DupliJs.Tools.ImportProcess = function() {
jQuery('#dup-tools-form-import').submit();
}
DupliJs.Tools.ImportDialog = function() {
var url = "#TB_inline?width=610&height=300&inlineId=modal-window-import";
tb_show("<?php esc_html_e("Import Duplicator Pro Data?", 'duplicator-pro') ?>", url);
jQuery('#TB_window').addClass(<?php echo json_encode(UiDialog::TB_WINDOW_CLASS); ?>);
return false;
}
//PAGE INIT
jQuery(document).ready(function($) {
DupliJs.Tools.ChangeImportButtonState = function() {
var filename = $('#import-file').val();
var disabled = (filename == '');
disabled = disabled ||
(
!document.getElementById('import-templates').checked &&
!document.getElementById('import-storages').checked &&
!document.getElementById('import-schedules').checked &&
!document.getElementById('import-settings').checked
);
$('#import-button').prop('disabled', disabled);
}
DupliJs.Tools.SchedulesClicked = function() {
if (document.getElementById('import-schedules').checked) {
document.getElementById('import-templates').checked = true;
document.getElementById('import-storages').checked = true;
document.getElementById('import-templates').disabled = true;
document.getElementById('import-storages').disabled = true;
} else {
document.getElementById('import-templates').disabled = false;
document.getElementById('import-storages').disabled = false;
}
}
$("#dupli-tools-import-panel").on("change", "#import-file", function() {
DupliJs.Tools.ChangeImportButtonState();
});
});
</script>

View File

@@ -0,0 +1,31 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
/* FOR PERSONAL LICENSE JUST SHOW MESSAGE */
if (!License::can(License::CAPABILITY_IMPORT_SETTINGS)) {
$tplMng->render('admin_pages/settings/migrate_settings/no_capatibily');
return;
}
?>
<?php $tplMng->render('admin_pages/settings/migrate_settings/export'); ?>
<hr size="1" />
<?php $tplMng->render('admin_pages/settings/migrate_settings/import'); ?>
<?php add_thickbox();

View File

@@ -0,0 +1,65 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Views\ViewHelper;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<div class="width-large" >
<p>
<?php esc_html_e(
"The migrate settings screen allows you to import or export Duplicator Pro settings from one site to another.",
'duplicator-pro'
); ?>
</p>
<p>
<?php esc_html_e(
"For example, if you have several storage locations that you use on multiple WordPress sites such as Google Drive or
Dropbox and you simply want to copy the profiles from this instance of Duplicator Pro to another instance then simply
export the data here and import it on the other instance of Duplicator Pro.",
'duplicator-pro'
); ?>
</p>
<p>
<?php
echo wp_kses(
sprintf(
__(
'This option isn\'t available at the <b>%1$s</b> license level.',
'duplicator-pro'
),
esc_html(License::getLicenseToString())
),
ViewHelper::GEN_KSES_TAGS
);
?>
<b>
<?php
echo wp_kses(
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>'
),
ViewHelper::GEN_KSES_TAGS
);
?>
</b>
</p>
</div>

View File

@@ -0,0 +1,94 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Models\GlobalEntity;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var Duplicator\Core\Controllers\PageAction[] $tplData['actions']
*/
$global = GlobalEntity::getInstance();
?>
<form
id="dup-settings-form"
action="<?php echo esc_attr(ControllersManager::getCurrentLink()); ?>"
method="post" data-parsley-validate>
<?php $tplData['actions'][SettingsPageController::ACTION_SAVE_SCHEDULE]->getActionNonceFileds(); ?>
<h3 class="title"><?php esc_html_e("Schedule Notifications", 'duplicator-pro'); ?></h3>
<hr size="1" />
<div class="dup-settings-wrapper margin-bottom-1">
<label class="lbl-larger" for="send_email_on_build_mode">
<?php esc_html_e("Send Build Email", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="radio"
name="send_email_on_build_mode"
id="send_email_on_build_mode_never"
class="margin-0"
value="<?php echo (int) GlobalEntity::EMAIL_BUILD_MODE_NEVER; ?>"
<?php checked($global->send_email_on_build_mode, GlobalEntity::EMAIL_BUILD_MODE_NEVER); ?>>
<label for="send_email_on_build_mode_never"><?php esc_attr_e("Never", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio"
name="send_email_on_build_mode"
id="send_email_on_build_mode_failure"
class="margin-0"
value="<?php echo (int) GlobalEntity::EMAIL_BUILD_MODE_FAILURE; ?>"
<?php checked($global->send_email_on_build_mode, GlobalEntity::EMAIL_BUILD_MODE_FAILURE); ?>>
<label for="send_email_on_build_mode_failure"><?php esc_attr_e("On Failure", 'duplicator-pro'); ?></label> &nbsp;
<input
type="radio"
name="send_email_on_build_mode"
id="send_email_on_build_mode_always"
class="margin-0"
value="<?php echo (int) GlobalEntity::EMAIL_BUILD_MODE_ALL; ?>"
<?php checked($global->send_email_on_build_mode, GlobalEntity::EMAIL_BUILD_MODE_ALL); ?>>
<label for="send_email_on_build_mode_always"><?php esc_attr_e("Always", 'duplicator-pro'); ?></label> &nbsp;
<p class="description">
<?php
esc_html_e("When to send emails after a scheduled build.", 'duplicator-pro');
?>
</p>
</div>
<label class="lbl-larger" for="notification_email_address">
<?php esc_html_e("Email Address", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
data-parsley-errors-container="#notification_email_address_error_container"
data-parsley-type="email"
type="email"
name="notification_email_address"
id="notification_email_address"
class="width-large margin-bottom-0"
value="<?php echo esc_attr($global->notification_email_address); ?>">
<p class="description">
<?php esc_html_e('Admininstrator default email will be used if empty.', 'duplicator-pro'); ?>
</p>
<div id="notification_email_address_error_container" class="duplicator-error-container"></div>
</div>
</div>
<hr>
<p class="submit dupli-save-submit">
<input
type="submit"
name="submit"
id="submit"
class="button primary small"
value="<?php esc_attr_e('Save Settings', 'duplicator-pro') ?>">
</p>
</form>

View File

@@ -0,0 +1,36 @@
<?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
*/
?>
<p>
<?php esc_html_e("This option determines the logic of backup record handling (in the \"Backups\" screen)
in case the archive file is deleted from a storage due to the \"Max Backups\" limit being reached.", 'duplicator-pro'); ?>
</p>
<ul>
<li>
<?php esc_html_e("The first option will delete the record after the backup archive is removed from ALL storages.", 'duplicator-pro'); ?>
</li>
<li>
<?php esc_html_e(
"The second option will delete the record when the backup archive is removed from the Default Local Storage
even if it still exists in other storages.",
'duplicator-pro'
); ?>
</li>
<li>
<?php esc_html_e("The third option will never delete the record.", 'duplicator-pro'); ?>
</li>
</ul>

View File

@@ -0,0 +1,108 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Models\GlobalEntity;
use Duplicator\Models\Storages\AbstractStorageEntity;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
?>
<h3 class="title">
<?php esc_html_e("Storage Settings", 'duplicator-pro'); ?>
</h3>
<hr>
<label class="lbl-larger">
<?php esc_html_e("Storage", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<p>
<?php esc_html_e("Default Local Storage Path", 'duplicator-pro'); ?>:
<b>
<?php echo esc_html(SnapIO::safePath(DUPLICATOR_SSDIR_PATH)); ?>
</b>
</p>
<input
type="checkbox"
name="_storage_htaccess_off"
id="_storage_htaccess_off"
value="1"
class="margin-0"
<?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>
</div>
<label class="lbl-larger">
<?php esc_html_e("Max Retries", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
class="width-small margin-0"
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 (int) $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>
</div>
<label class="lbl-larger">
<?php esc_html_e("Delete Backup Records", 'duplicator-pro'); ?>
<i
class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e('Delete Backup Records', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tplMng->render('admin_pages/settings/storage/backup_record_delete_tooltip', [], true)); ?>">
</i>
</label>
<div class="margin-bottom-1">
<select
class="width-large margin-0"
name="purge_backup_records"
id="purge_backup_records"
data-parsley-required data-parsley-min="0"
data-parsley-errors-container="#purge_backup_records_error_container"
value="<?php echo (int) $global->getPurgeBackupRecords(); ?>">
<option
value="<?php echo (int) AbstractStorageEntity::BACKUP_RECORDS_REMOVE_ALL; ?>"
<?php selected($global->getPurgeBackupRecords(), AbstractStorageEntity::BACKUP_RECORDS_REMOVE_ALL); ?>>
When the backup archive is removed from all storages
</option>
<option
value="<?php echo (int) AbstractStorageEntity::BACKUP_RECORDS_REMOVE_DEFAULT; ?>"
<?php selected($global->getPurgeBackupRecords(), AbstractStorageEntity::BACKUP_RECORDS_REMOVE_DEFAULT); ?>>
When maximum is reached for Default Local Storage
</option>
<option
value="<?php echo (int) AbstractStorageEntity::BACKUP_RECORDS_REMOVE_NEVER; ?>"
<?php selected($global->getPurgeBackupRecords(), AbstractStorageEntity::BACKUP_RECORDS_REMOVE_NEVER); ?>>
Never
</option>
</select>
<div id="purge_backup_records_error_container" class="duplicator-error-container"></div>
<p id="pruge_backup_records_desc_<?php echo (int) AbstractStorageEntity::BACKUP_RECORDS_REMOVE_ALL; ?>" class="description">
<?php esc_html_e("This option determines backup record handling in case the \"Max Backups\" limit is reached.", 'duplicator-pro'); ?>
</p>
</div>

View File

@@ -0,0 +1,44 @@
<?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
*/
?>
<form
id="dup-settings-form"
action="<?php echo esc_url($ctrlMng->getCurrentLink()); ?>"
method="post"
data-parsley-validate
>
<?php $tplData['actions'][SettingsPageController::ACTION_SAVE_STORAGE]->getActionNonceFileds(); ?>
<div class="dup-settings-wrapper margin-bottom-1">
<?php $tplMng->render('admin_pages/settings/storage/storage_general'); ?>
<hr>
<?php $tplMng->render('admin_pages/settings/storage/storage_ssl'); ?>
<?php $tplMng->render('admin_pages/settings/storage/storages_global_options'); ?>
</div>
<p class="submit dupli-save-submit">
<input
type="submit"
name="submit"
id="submit"
class="button primary small"
value="<?php esc_attr_e('Save Settings', 'duplicator-pro') ?>"
>
</p>
</form>

View File

@@ -0,0 +1,92 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Models\GlobalEntity;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = GlobalEntity::getInstance();
?>
<h3 class="title">
<?php esc_html_e("SSL", 'duplicator-pro'); ?>
</h3>
<hr>
<p class="description">
<?php esc_html_e("Do not modify SSL settings unless you know the expected result or have talked to support.", 'duplicator-pro'); ?>
</p>
<label class="lbl-larger">
<?php esc_html_e("SSL certificates", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="ssl_useservercerts"
id="ssl_useservercerts"
value="1"
class="margin-0"
<?php checked($global->ssl_useservercerts); ?>>
<label for="ssl_useservercerts">
<?php esc_html_e("Use server's SSL certificates", 'duplicator-pro'); ?>
</label>
<p class="description">
<?php
esc_html_e(
"To use server's SSL certificates please enable it.
By default Duplicator Pro uses its own store of SSL certificates to verify the identity of remote storage sites.",
'duplicator-pro'
);
?>
</p>
<input
type="checkbox"
name="ssl_disableverify"
id="ssl_disableverify"
value="1"
class="margin-0"
<?php checked($global->ssl_disableverify); ?>>
<label for="ssl_disableverify">
<?php esc_html_e("Disable verification of SSL certificates", 'duplicator-pro'); ?>
</label>
<p class="description">
<?php
esc_html_e("To disable verification of a host and the peer's SSL certificate.", 'duplicator-pro');
?>
</p>
</div>
<label class="lbl-larger">
<?php esc_html_e("Use IPv4 only", 'duplicator-pro'); ?>
</label>
<div class="margin-bottom-1">
<input
type="checkbox"
name="ipv4_only"
id="ipv4_only"
value="1"
class="margin-0"
<?php checked($global->ipv4_only); ?>>
<label for="ipv4_only">
<?php esc_html_e("Use IPv4 only", 'duplicator-pro'); ?>
</label>
<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>
</div>

View File

@@ -0,0 +1,20 @@
<?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
*/
StoragesUtil::renderGlobalOptions();