first commit

This commit is contained in:
Roman Pyrih
2026-04-03 10:22:35 +02:00
commit 5de35e358d
8424 changed files with 2907254 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,168 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\Views\TplMng;
use Duplicator\Core\Views\Notifications;
use Duplicator\Models\SystemGlobalEntity;
use Duplicator\Views\PackagesHelper;
require_once(DUPLICATOR____PATH . '/classes/class.package.pagination.php');
require_once(DUPLICATOR____PATH . '/classes/ui/class.ui.dialog.php');
global $packagesViewData;
$tplMng = TplMng::getInstance();
if (isset($_REQUEST['create_from_temp'])) {
//Takes temporary package and inserts it into the package table
$package = DUP_PRO_Package::get_temporary_package(false);
if ($package != null) {
$package->save();
}
unset($_REQUEST['create_from_temp']);
unset($package);
}
$system_global = SystemGlobalEntity::getInstance();
if (!empty($_REQUEST['action'])) {
if (CapMng::can(CapMng::CAP_CREATE, false) && $_REQUEST['action'] == 'stop-build') {
$package_id = (int) $_REQUEST['action-parameter'];
DUP_PRO_Log::trace("stop build of $package_id");
$action_package = DUP_PRO_Package::get_by_id($package_id);
if ($action_package != null) {
DUP_PRO_Log::trace("set $action_package->ID for cancel");
$action_package->set_for_cancel();
} else {
DUP_PRO_Log::trace(
"could not find package so attempting hard delete. "
. "Old files may end up sticking around although chances are there isnt much if we couldnt nicely cancel it."
);
$result = DUP_PRO_Package::force_delete($package_id);
($result) ? DUP_PRO_Log::trace("Hard delete success") : DUP_PRO_Log::trace("Hard delete failure");
}
unset($action_package);
} elseif ($_REQUEST['action'] == 'clear-messages') {
$system_global->clearFixes();
$system_global->save();
}
}
$packagesViewData = array(
'pending_cancelled_package_ids' => DUP_PRO_Package::get_pending_cancellations(),
'rowCount' => 0,
);
$totalElements = DUP_PRO_Package::getNumPackages();
$statusActive = DUP_PRO_Package::isPackageRunning();
$pager = new DUP_PRO_Package_Pagination();
$perPage = $pager->get_per_page();
$currentPage = ($statusActive >= 1) ? 1 : $pager->get_pagenum();
$offset = ($currentPage - 1) * $perPage;
$global = DUP_PRO_Global_Entity::getInstance();
$orphan_info = DUP_PRO_Server::getOrphanedPackageInfo();
$orphan_display_msg = $orphan_info['count'];
if ($orphan_display_msg) {
$toolOrpahnPurgeURL = ToolsPageController::getInstance()->getMenuLink(
ToolsPageController::L2_SLUG_DISAGNOSTIC,
null,
['orphanpurge' => 1 ] // Tools section opened
)
?>
<div id='dpro-error-orphans' class="error">
<p>
<?php
$orphan_msg = __(
'There are currently (%1$s) orphaned package files taking up %2$s of space.
These package files are no longer visible in the packages list below and are safe to remove.',
'duplicator-pro'
) . '<br/>';
$orphan_msg .= __('Go to: Tools > General > Information > Stored Data > look for the [Delete Package Orphans] button for more details.', 'duplicator-pro') . '<br/>';
$orphan_msg .= '<a href=' . esc_url($toolOrpahnPurgeURL) . '>' .
__('Take me there now!', 'duplicator-pro') .
'</a>';
printf($orphan_msg, $orphan_info['count'], DUP_PRO_U::byteSize($orphan_info['size']));
?>
<br />
</p>
</div>
<?php } ?>
<?php do_action(Notifications::DUPLICATOR_PRO_BEFORE_PACKAGES_HOOK); ?>
<form id="form-duplicator" method="post">
<?php wp_nonce_field('dpro_package_form_nonce'); ?>
<?php $tplMng->render('admin_pages/packages/toolbar'); ?>
<table class="widefat dup-packtbl striped" aria-label="Packages List">
<?php
$tplMng->render(
'admin_pages/packages/packages_table_head',
array('totalElements' => $totalElements)
);
if ($totalElements == 0) {
$tplMng->render('admin_pages/packages/no_elements_row');
} else {
DUP_PRO_Package::by_status_callback(
array(
PackagesHelper::class,
'tablePackageRow',
),
array(),
$perPage,
$offset,
'`id` DESC'
);
}
$tplMng->render(
'admin_pages/packages/packages_table_foot',
array('totalElements' => $totalElements)
); ?>
</table>
</form>
<?php if ($totalElements > $perPage) { ?>
<form id="form-duplicator-nav" method="post">
<?php wp_nonce_field('dpro_package_form_nonce'); ?>
<div class="dup-paged-nav tablenav">
<?php if ($statusActive > 0) : ?>
<div id="dpro-paged-progress" style="padding-right: 10px">
<i class="fas fa-circle-notch fa-spin fa-lg fa-fw"></i>
<i><?php esc_html_e('Paging disabled during build...', 'duplicator-pro'); ?></i>
</div>
<?php else : ?>
<div id="dpro-paged-buttons">
<?php $pager->display_pagination($totalElements, $perPage); ?>
</div>
<?php endif; ?>
</div>
</form>
<?php } else { ?>
<div style="float:right; padding:10px 5px">
<?php echo $totalElements . '&nbsp;' . __("items", 'duplicator-pro'); ?>
</div>
<?php
}
$tplMng->render(
'admin_pages/packages/packages_scripts',
[
'perPage' => $perPage,
'offset' => $offset,
'currentPage' => $currentPage,
]
);

View File

@@ -0,0 +1,424 @@
<?php
defined("ABSPATH") or die("");
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Views\TplMng;
use Duplicator\Libs\Snap\SnapJson;
use Duplicator\Libs\Snap\SnapWP;
global $wpdb;
//POST BACK
$action_updated = null;
if (!empty($_POST['action'])) {
switch ($_POST['action']) {
case 'duplicator_pro_package_active':
$action_response = __('Package settings have been reset.', 'duplicator-pro');
break;
}
}
$manual_template = DUP_PRO_Package_Template_Entity::get_manual_template();
$dup_tests = DUP_PRO_Server::getRequirments();
if ($dup_tests['Success'] != true) {
DUP_PRO_Log::traceObject('Requirements', $dup_tests);
}
$templates = DUP_PRO_Package_Template_Entity::getAll();
$default_name1 = DUP_PRO_Package::get_default_name();
$default_name2 = DUP_PRO_Package::get_default_name(false);
$default_notes = $manual_template->notes;
$dbbuild_mode = DUP_PRO_DB::getBuildMode();
/** @var bool */
$blur = TplMng::getInstance()->getGlobalValue('blurCreate');
$templatesUrl = ToolsPageController::getInstance()->getMenuLink(ToolsPageController::L2_SLUG_TEMPLATE);
$templateEditBaseUrl = ToolsPageController::getTemplateEditURL();
?>
<style>
/* -----------------------------
PACKAGE OPTS*/
form#dup-form-opts {margin-top:10px; font-size:14px}
form#dup-form-opts textarea, input[type="text"], input[type="password"] {width:100%}
input#package-name {padding:4px; height: 2em; line-height: 100%; width: 100%; margin: 0 0 3px;}
select#template_id {padding: 2px; height:2em; line-height: 130%; width: 100%; }
textarea#package-notes {height:75px;}
div.dup-notes-add {float:right; margin:0;}
div#dup-notes-area {display:none;}
select#template_id {width:100%; max-width: none; margin-bottom:4px}
div.dpro-general-area {line-height:27px; margin:0 0 5px 0}
div#dpro-template-specific-area table td:first-child {width:100px; font-weight: bold}
div.dup-box {margin:20px 0 0 0}
div#dpro-da-notice {padding:10px; line-height:20px; font-size: 14px}
div#dpro-da-notice-info {display:none; padding: 5px}
</style>
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar <?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
<tr>
<td>
<div id="dup-wiz">
<div id="dup-wiz-steps">
<div class="active-step"><a>1 <?php esc_html_e('Setup', 'duplicator-pro'); ?></a></div>
<div><a>2 <?php esc_html_e('Scan', 'duplicator-pro'); ?> </a></div>
<div><a>3 <?php esc_html_e('Build', 'duplicator-pro'); ?> </a></div>
</div>
<div id="dup-wiz-title" style="white-space: nowrap">
<?php esc_html_e('Step 1: Package Setup', 'duplicator-pro'); ?>
</div>
</div>
</td>
</tr>
</table>
<hr class="dpro-edit-toolbar-divider"/>
<?php if (! empty($action_response)) : ?>
<div id="message" class="notice notice-success"><p><?php echo $action_response; ?></p></div>
<?php
endif;
require_once(DUPLICATOR____PATH . '/views/packages/main/s1.setup1.reqs.php');
$form_action_url = PackagesPageController::getInstance()->getPackageBuildS2Url();
?>
<form
id="dup-form-opts"
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
method="post"
action="<?php echo $form_action_url;?>"
data-parsley-validate data-parsley-ui-enabled="true"
>
<input type="hidden" id="dup-form-opts-action" name="action" value="">
<div class="dpro-general-area">
<div>
<label for="package-name" class="lbl-larger"><span class="screen-reader-text"><?php esc_html_e('Package', 'duplicator-pro') ?></span>&nbsp;<?php esc_html_e('Name', 'duplicator-pro') ?>:</label>
<a href="javascript:void(0)" onClick="DupPro.Pack.ResetName()" title="<?php esc_attr_e('Toggle a default name', 'duplicator-pro') ?>"><i class="fas fa-random"></i></a>
<div class="dup-notes-add">
<button type="button" onClick="jQuery('#dup-notes-area').toggle()" class="dup-btn-borderless" title="<?php esc_attr_e('Add Notes', 'duplicator-pro') ?>">
<i class="far fa-edit"></i>
</button>
</div>
</div>
<div>
<input id="package-name" name="package-name" type="text" maxlength="40" required="true" data-regexp="^[0-9A-Za-z|_]+$" />
<div id="dup-notes-area">
<label class="lbl-larger">&nbsp;<?php esc_html_e('Notes', 'duplicator-pro') ?>:</label><br/>
<textarea id="package-notes" name="package-notes" maxlength="300" /></textarea>
</div>
</div>
<div>
<label for="template_id" class="lbl-larger">&nbsp;<?php esc_html_e('Template', 'duplicator-pro') ?>:</label>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Apply Template", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e('An optional template configuration that can be applied to this package setup. An [Unassigned] template will retain the settings from the last scan/build.', 'duplicator-pro'); ?>"></i>
<div style="float:right">
<a href="<?php echo esc_url($templatesUrl); ?>" class="dup-btn-borderless" title="<?php esc_attr_e("List All Templates", 'duplicator-pro') ?>">
<i class="far fa-clone"></i>
</a>
<button type="button" onclick="DupPro.Pack.EditTemplate()" class="dup-btn-borderless" title="<?php esc_attr_e("Edit Selected Template", 'duplicator-pro') ?>">
<i class="far fa-edit"></i>
</button>
</div>
</div>
<div>
<select data-parsley-ui-enabled="false" onChange="DupPro.Pack.EnableTemplate();" name="template_id" id="template_id" aria-label="Prefill option with selected template">
<option value="<?php echo intval($manual_template->getId()); ?>"><?php echo '[' . esc_html__('Unassigned', 'duplicator-pro') . ']' ?></option>
<?php
if (count($templates) == 0) {
$no_templates = __('No Templates', 'duplicator-pro');
echo "<option value='-1'>$no_templates</option>";
} else {
foreach ($templates as $template) {
if ($template->is_manual) {
continue;
}
echo "<option value='{$template->getId()}'>" . esc_html($template->name) . "</option>";
}
}
?>
</select>
</div>
</div>
<?php
require_once(DUPLICATOR____PATH . '/views/packages/main/s1.setup2.store.php');
require_once(DUPLICATOR____PATH . '/views/packages/main/s1.setup3.archive.php');
require_once(DUPLICATOR____PATH . '/views/packages/main/s1.setup4.install.php');
?>
<div class="dup-button-footer">
<input type="button" value="<?php esc_attr_e("Reset", 'duplicator-pro') ?>" class="button button-large" <?php echo ($dup_tests['Success']) ? '' : 'disabled="disabled"'; ?> onClick="DupPro.Pack.ResetSettings()" />
<input
id="button-next"
type="submit"
value="<?php esc_attr_e("Next", 'duplicator-pro') ?> &#9654;"
class="button button-primary button-large" <?php echo ($dup_tests['Success']) ? '' : 'disabled="disabled"'; ?>
>
</div>
</form>
<!-- CACHE PROTECTION: If the back-button is used from the scanner page then we need to
refresh page in-case any filters where set while on the scanner page -->
<form id="cache_detection">
<input type="hidden" id="cache_state" name="cache_state" value="" />
</form>
<?php
$confirm1 = new DUP_PRO_UI_Dialog();
$confirm1->title = __('Would you like to continue', 'duplicator-pro');
$confirm1->message = __('This will clear all of the current package settings.', 'duplicator-pro');
$confirm1->progressText = __('Please Wait...', 'duplicator-pro');
$confirm1->jsCallback = 'DupPro.Pack.ResetSettingsRun()';
$confirm1->initConfirm();
?>
<script>
jQuery(function($)
{
var packageTemplates = <?php echo DUP_PRO_Package_Template_Entity::getTemplatesFrontendListData(); ?>
DupPro.Pack.BeforeSubmit = function(e){
$('#mu-exclude option').each(function(){
$(this).prop('selected', true);
});
DupPro.Pack.FillExcludeTablesList();
return true;
};
$('#dup-form-opts').submit(function () {
return DupPro.Pack.BeforeSubmit();
})
// Template-specific Functions
DupPro.Pack.GetTemplateById = function (templateId)
{
for (var i = 0; i < packageTemplates.length; i++) {
var currentTemplate = packageTemplates[i];
if (currentTemplate.id == templateId) {
return currentTemplate;
}
}
return null;
};
$.fn.selectOption = function(val){
this.val(val)
.find('option')
.prop('selected', false)
.parent()
.find('option[value="'+ val +'"]')
.prop('selected', true)
.parent()
.trigger('change');
return this;
};
DupPro.Pack.PopulateCurrentTemplate = function ()
{
var selectedId = $('#template_id').val();
var selectedTemplate = DupPro.Pack.GetTemplateById(selectedId);
if (selectedTemplate != null)
{
var name = selectedTemplate.name;
if(selectedTemplate.is_manual) {
name = "<?php echo DUP_PRO_Package::get_default_name(); ?>";
}
$("#package-name").val(name);
$("#package-notes").val(selectedTemplate.notes);
$("#filter-on").prop("checked", selectedTemplate.archive_filter_on);
$("#filter-names").prop("checked", selectedTemplate.archive_filter_names);
//Add trailing slash to directories to differentiate between files and directories
let filterDirs = selectedTemplate.archive_filter_dirs.split(';').join(";\n");
let filterFiles = selectedTemplate.archive_filter_files.split(';').join(";\n")
let separator = filterDirs.length > 0 && filterFiles.length > 0 ? ";\n" : '';
$("#filter-paths").val(filterDirs + separator + filterFiles);
$("#filter-exts").val(selectedTemplate.archive_filter_exts);
$("#dbfilter-on").prop("checked", selectedTemplate.database_filter_on);
$("#db-prefix-filter").prop("checked", selectedTemplate.databasePrefixFilter);
$("#db-prefix-sub-filter").prop("checked", selectedTemplate.databasePrefixSubFilter);
$(".dup-components-checkbox").each(function (i, component) {
$(component).prop("checked", false);
});
selectedTemplate.components.forEach(function (component) {
$("#"+component).prop("checked", true);
});
DupPro.Pack.ToggleDBOnly()
DupPro.Pack.SetComponentsSelect();
if (typeof selectedTemplate.filter_sites != 'undefined' && selectedTemplate.filter_sites.length > 0) {
for(var i=0; i < selectedTemplate.filter_sites.length;i++){
var site_id = selectedTemplate.filter_sites[i];
var exclude_option = $('#mu-include').find("option[value="+site_id+"]").first();
console.log(exclude_option.html());
$("#mu-exclude").append(exclude_option.clone());
exclude_option.remove();
}
}
//-- cPanel
$("#cpnl-enable").prop("checked", selectedTemplate.installer_opts_cpnl_enable);
$("#cpnl-host").val(selectedTemplate.installer_opts_cpnl_host);
$("#cpnl-user").val(selectedTemplate.installer_opts_cpnl_user);
$('.secure-on-input-wrapper input').prop("checked", false);
$('.secure-on-input-wrapper input[value=' + selectedTemplate.installer_opts_secure_on + ']:enabled').prop("checked", true);
$("#skipscan").prop("checked", selectedTemplate.installer_opts_skip_scan);
$("#secure-pass").val(selectedTemplate.installerPassowrd);
$("#cpnl-dbaction").selectOption(selectedTemplate.installer_opts_cpnl_db_action);
$("#cpnl-dbhost").val(selectedTemplate.installer_opts_cpnl_db_host);
$("#cpnl-dbname").val(selectedTemplate.installer_opts_cpnl_db_name);
$("#cpnl-dbuser").val(selectedTemplate.installer_opts_cpnl_db_user);
//-- Brand
let installer_opts_brand = selectedTemplate.installer_opts_brand;
installer_opts_brand_id = [];
x = 0;
// most tricky thing - setup proper brand on emplate change
if (typeof selectedTemplate.installer_opts_brand != 'undefined') {
if(selectedTemplate.installer_opts_brand <= 0) {
installer_opts_brand = -1;
} else if(selectedTemplate.installer_opts_brand > 0) {
installer_opts_brand = Number(selectedTemplate.installer_opts_brand);
}
}
// find, fix deleted brands and setup default
for (var i = 0; i < packageTemplates.length; i++) {
if(
typeof packageTemplates[i].installer_opts_brand != 'undefined'
&& null != packageTemplates[i].installer_opts_brand
&& packageTemplates[i].installer_opts_brand != 0
) {
installer_opts_brand_id[x]=Number(packageTemplates[i].installer_opts_brand);
x++;
}
}
$("#brand").selectOption(installer_opts_brand);
//-- Database
if (selectedTemplate.database_filter_tables.length) {
let databaseFilterTables = selectedTemplate.database_filter_tables.split(",");
let tablesToExclude = $("#dup-db-tables-exclude");
tablesToExclude.find(".dup-pseudo-checkbox").each(function () {
let node = $(this);
if (databaseFilterTables.includes(node.data('value'))) {
node.addClass('checked');
} else {
node.removeClass('checked');
}
});
}
$("#dbhost").val(selectedTemplate.installer_opts_db_host);
$("#dbname").val(selectedTemplate.installer_opts_db_name);
$("#dbuser").val(selectedTemplate.installer_opts_db_user);
} else {
console.log("Template ID doesn't exist?? " + selectedId);
}
//Default to Installer cPanel tab if used
$('#cpnl-enable').is(":checked") ? $('#dpro-cpnl-tab-lbl').trigger("click") : $('#dpro-bsc-tab-lbl').trigger("click");
};
DupPro.Pack.ResetSettings = function ()
{
<?php $confirm1->showConfirm(); ?>
};
DupPro.Pack.ResetSettingsRun = function(){
$('#dup-form-opts')[0].reset();
setTimeout(function(){tb_remove();}, 800);
}
DupPro.Pack.EditTemplate = function ()
{
var manualTemplateID = <?php echo $manual_template->getId(); ?>;
var templateID = $('#template_id').val();
var url;
if (templateID <= 0 || templateID == manualTemplateID) {
url = <?php echo SnapJson::jsonEncode($templatesUrl); ?>
} else {
url = <?php echo SnapJson::jsonEncode($templateEditBaseUrl); ?> + '&package_template_id=' + templateID;
}
window.open(url, 'edit-template');
};
});
//INIT
jQuery(document).ready(function ($) {
var DPRO_NAME_LAST;
var DPRO_NAME_DEFAULT1 = '<?php echo esc_js($default_name1); ?>';
var DPRO_NAME_DEFAULT2 = '<?php echo esc_js($default_name2); ?>';
DupPro.Pack.checkPageCache = function()
{
var $state = $('#cache_state');
if( $state.val() == "" ) {
$state.val("fresh-load");
} else {
$state.val("cached");
<?php $redirect = PackagesPageController::getInstance()->getPackageBuildS1Url(); ?>
window.location.href = <?php echo SnapJson::jsonEncode($redirect); ?>;
}
}
DupPro.Pack.EnableTemplate = function ()
{
$("#dup-form-opts-action").val('template-create');
$('#dpro-template-specific-area').show(0);
DupPro.Pack.PopulateCurrentTemplate();
//DupPro.Pack.ToggleInstallerPassword();
DupPro.EnableInstallerPassword();
DupPro.Pack.ToggleFileFilters();
DupPro.Pack.ToggleDBFilters();
DupPro.Pack.ToggleActiveThemes();
DupPro.Pack.ToggleActivePlugins();
DupPro.Pack.ToggleDBExcluded();
DupPro.Pack.ToggleNoPrefixTables(false);
DupPro.Pack.ToggleNoSubsiteExistsTables(false);
}
DupPro.Pack.ResetName = function ()
{
var current = $('#package-name').val();
switch (current) {
case DPRO_NAME_LAST : $('#package-name').val(DPRO_NAME_DEFAULT2); break;
case DPRO_NAME_DEFAULT1 : $('#package-name').val(DPRO_NAME_LAST); break;
case DPRO_NAME_DEFAULT2 : $('#package-name').val(DPRO_NAME_DEFAULT1); break;
default: $('#package-name').val(DPRO_NAME_LAST);
}
};
DupPro.Pack.checkPageCache();
DupPro.Pack.EnableTemplate();
DPRO_NAME_LAST = $('#package-name').val();
$('input#package-name').focus().select();
});
</script>

View File

@@ -0,0 +1,245 @@
<?php
defined("ABSPATH") or die("");
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\MigrationMng;
use Duplicator\Libs\Snap\FunctionalityCheck;
$global = DUP_PRO_Global_Entity::getInstance();
$dup_tests = DUP_PRO_Server::getRequirments();
?>
<style>
/* -----------------------------
REQUIREMENTS*/
div.dup-sys-section {margin:1px 0px 5px 0px}
div.dup-sys-title {display:inline-block; width:250px; padding:1px; }
div.dup-sys-title div {display:inline-block;}
div.dup-sys-info {display:none; max-width: 98%; margin:4px 4px 12px 4px}
div.dup-sys-pass {display:inline-block; color:green;}
div.dup-sys-fail {display:inline-block; color:#AF0000;}
div.dup-sys-contact {padding:5px 0px 0px 10px; font-size:11px; font-style:italic}
span.dup-toggle {float:left; margin:0 2px 2px 0; }
table.dup-sys-info-results td:first-child {width:200px}
</style>
<!-- =========================================
SYSTEM REQUIREMENTS -->
<?php if (!$dup_tests['Success']) : ?>
<div class="dup-box">
<div class="dup-box-title">
<i class="far fa-check-circle"></i>
<?php esc_html_e("Requirements:", 'duplicator-pro'); ?> <div class="dup-sys-fail">Fail</div>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Requirements:', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel">
<div class="dup-sys-section">
<i><?php esc_html_e("System requirements must pass for the Duplicator to work properly. Click each link for details.", 'duplicator-pro'); ?></i>
</div>
<!-- PHP SUPPORT -->
<div class='dup-sys-req'>
<div class='dup-sys-title'>
<a><?php esc_html_e('PHP Support', 'duplicator-pro'); ?></a>
<div><?php echo $dup_tests['PHP']['ALL']; ?></div>
</div>
<div class="dup-sys-info dup-info-box">
<table class="dup-sys-info-results">
<tr>
<td><?php printf("%s [%s]", __("PHP Version", 'duplicator-pro'), phpversion()); ?></td>
<td><?php echo $dup_tests['PHP']['VERSION'] ?></td>
</tr>
<?php foreach (DUP_PRO_Server::getFunctionalitiesCheckList() as $func) { ?>
<tr>
<td>
<?php
switch ($func->getType()) {
case FunctionalityCheck::TYPE_FUNCTION:
esc_html_e('Function', 'duplicator-pro');
break;
case FunctionalityCheck::TYPE_CLASS:
esc_html_e('Class', 'duplicator-pro');
break;
default:
throw new Exception('Invalid item type');
}
?>
<a href="<?php echo esc_url($func->link); ?>" target="_blank">
<?php echo esc_html($func->getItemKey()); ?>
</a>
</td>
<td>
<?php
if ($func->check()) {
echo esc_html_e('Pass', 'duplicator-pro');
} elseif ($func->isRequired()) {
echo esc_html_e('Fail', 'duplicator-pro');
} else {
echo esc_html_e('Warning', 'duplicator-pro');
}
if (strlen($func->troubleshoot) > 0) {
echo ' &nbsp; ' . $func->troubleshoot;
}
?>
</td>
</tr>
<?php } ?>
</table>
<small>
<?php
printf(
esc_html__(
"PHP versions %s+ including the listed functions are required for the plugin to create a package.
For additional information see our online technical FAQs.",
'duplicator-pro'
),
DUPLICATOR_PRO_PHP_MINIMUM_VERSION
);
?>
</small>
</div>
</div>
<!-- PERMISSIONS -->
<div class='dup-sys-req'>
<div class='dup-sys-title'>
<a><?php esc_html_e('Permissions', 'duplicator-pro'); ?></a> <div><?php echo esc_html($dup_tests['IO']['ALL']); ?></div>
</div>
<div class="dup-sys-info dup-info-box">
<b><?php esc_html_e("Required Paths", 'duplicator-pro'); ?></b>
<div style="padding:3px 0px 0px 15px">
<?php
printf("<b>%s</b> &nbsp; [%s] <br/>", esc_html($dup_tests['IO']['WPROOT']), esc_html(DUP_PRO_Archive::getArchiveListPaths('home')));
printf("<b>%s</b> &nbsp; [%s] <br/>", esc_html($dup_tests['IO']['SSDIR']), esc_html(DUPLICATOR_PRO_SSDIR_PATH));
printf("<b>%s</b> &nbsp; [%s] <br/>", esc_html($dup_tests['IO']['SSTMP']), esc_html(DUPLICATOR_PRO_SSDIR_PATH_TMP));
?>
</div>
<small>
<?php
esc_html_e(
"Permissions can be difficult to resolve on some systems. If the plugin can not read the above paths here
are a few things to try. 1) Set the above paths to have permissions of 755 for directories and 644 for files.
You can temporarily try 777 however, be sure you dont leave them this way. 2) Check the owner/group settings for both files and directories.
The PHP script owner and the process owner are different. The script owner owns the PHP script but the process owner
is the user the script is running as, thus determining its capabilities/privileges in the file system.
For more details contact your host or server administrator or visit the 'Help' menu under Duplicator for additional online resources.",
'duplicator-pro'
);
?>
</small>
</div>
</div>
<!-- SERVER SUPPORT -->
<div class='dup-sys-req'>
<div class='dup-sys-title'>
<a><?php esc_html_e('Server Support', 'duplicator-pro'); ?></a>
<div><?php echo $dup_tests['SRV']['ALL']; ?></div>
</div>
<div class="dup-sys-info dup-info-box">
<table class="dup-sys-info-results">
<tr>
<td><?php printf("%s [%s]", esc_html__("MySQL Version", 'duplicator-pro'), esc_html(DUP_PRO_DB::getVersion())); ?></td>
<td><?php echo esc_html($dup_tests['SRV']['MYSQL_VER']); ?></td>
</tr>
</table>
<small>
<?php esc_html_e(
"MySQL version 5.0+ or better is required. Contact your server administrator and request MySQL Server 5.0+ be installed.",
'duplicator-pro'
); ?>
</small>
<hr>
<table class="dup-sys-info-results">
<tr>
<td><a href="https://www.php.net/manual/en/mysqli.real-escape-string.php" target="_blank">mysqli_real_escape_string</a></td>
<td><?php echo esc_html($dup_tests['SRV']['MYSQL_ESC']); ?></td>
</tr>
</table>
<small>
<?php esc_html_e(
"The function mysqli_real_escape_string is not working properly.
Please consult host support and ask them to switch to a different PHP version or configuration.",
'duplicator-pro'
); ?>
</small>
</div>
</div>
<!-- INSTALLATION FILES -->
<div class='dup-sys-req'>
<div class='dup-sys-title'>
<a><?php esc_html_e('Installation Files', 'duplicator-pro'); ?></a> <div><?php echo esc_html($dup_tests['RES']['INSTALL']); ?></div>
</div>
<div class="dup-sys-info dup-info-box">
<?php
if ($dup_tests['RES']['INSTALL'] == 'Pass') :
esc_html_e("No reserved installation files where found from a previous install. You are clear to create a new package.", 'duplicator-pro');
else :
?>
<form method="post" action="<?php echo esc_url(ToolsPageController::getInstance()->getCleanFilesAcrtionUrl()); ?>">
<?php
esc_html_e(
"An installer file(s) was found in the WordPress root directory.
To archive your data correctly please remove any of these files and try creating your package again.",
'duplicator-pro'
);
?><br/>
<b><?php _e('Installer file names include', 'duplicator-pro'); ?></b>
<ul>
<?php foreach (MigrationMng::checkInstallerFilesList() as $filePath) { ?>
<li>
<?php echo esc_html($filePath); ?>
</li>
<?php } ?>
</ul>
<input type='submit' class='button action' value='<?php esc_attr_e('Remove Files Now', 'duplicator-pro') ?>' style='font-size:10px; margin-top:5px;' />
</form>
<?php endif; ?>
</div>
</div>
<!-- ONLINE SUPPORT -->
<div class="dup-sys-contact">
<?php
printf(
"<i class='fa fa-question-circle'></i> %s <a href='" . DUPLICATOR_PRO_TECH_FAQ_URL . "' target='_blank'>[%s]</a>",
__("For additional help please see the ", 'duplicator-pro'),
__("online FAQs", 'duplicator-pro')
);
?>
</div>
</div>
</div>
<?php endif; ?>
<script>
//INIT
jQuery(document).ready(function ($)
{
DupPro.Pack.ToggleSystemDetails = function (anchor)
{
$(anchor).parent().siblings('.dup-sys-info').toggle();
}
//Init: Toogle for system requirment detial links
$('.dup-sys-title a').each(function () {
$(this).attr('href', 'javascript:void(0)');
$(this).click(function () {
DupPro.Pack.ToggleSystemDetails(this);
});
$(this).prepend("<span class='ui-icon ui-icon-triangle-1-e dup-toggle' />");
});
//Init: Color code Pass/Fail/Warn items
$('.dup-sys-title div').each(function () {
$(this).addClass(($(this).text() == 'Pass') ? 'dup-sys-pass' : 'dup-sys-fail');
});
});
</script>

View File

@@ -0,0 +1,140 @@
<?php
use Duplicator\Controllers\StoragePageController;
use Duplicator\Core\CapMng;
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Models\Storages\StoragesUtil;
defined("ABSPATH") or die("");
$global = DUP_PRO_Global_Entity::getInstance();
$storage_list = AbstractStorageEntity::getAll(0, 0, [StoragesUtil::class, 'sortByPriority']);
$langLocalDefaultMsg = __('Recovery Point Capable', 'duplicator-pro');
$ui_css_storage = (DUP_PRO_UI_ViewState::getValue('dup-pack-storage-panel') ? 'display:block' : 'display:none');
$newStorageUrl = StoragePageController::getEditUrl();
?>
<!-- ===================
META-BOX: STORAGE -->
<div class="dup-box" id="dup-pack-storage-panel-area">
<div class="dup-box-title" id="dpro-store-title">
<i class="fas fa-server fa-sm"></i> <?php esc_html_e('Storage', 'duplicator-pro') ?> <sup id="dpro-storage-title-count" class="dup-box-title-badge"></sup>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Storage Options', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dup-pack-storage-panel" style="<?php echo esc_attr($ui_css_storage); ?>">
<div style="padding:0 0 4px 0">
<?php esc_html_e('Choose the storage location(s) where the archive and installer files will be saved.', 'duplicator-pro') ?>
</div>
<table class="widefat pack-store-tbl">
<thead>
<tr>
<th style='white-space: nowrap; width:10px;'></th>
<th style='width:175px'><?php esc_html_e('Type', 'duplicator-pro') ?></th>
<th style='width:275px'><?php esc_html_e('Name', 'duplicator-pro') ?></th>
<th style="white-space: nowrap"><?php esc_html_e('Location', 'duplicator-pro') ?></th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
$selectedStorageIds = $global->getManualModeStorageIds();
foreach ($storage_list as $storage) {
try {
if (!$storage->isSupported()) {
continue;
}
$i++;
$is_valid = $storage->isValid();
$is_checked = in_array($storage->getId(), $selectedStorageIds) && $is_valid;
$mincheck = ($i == 1) ? 'data-parsley-mincheck="1" data-parsley-required="true"' : '';
$row_style = ($i % 2) ? 'alternate' : '';
$row_style .= ($is_valid) ? '' : ' storage-missing';
$row_chkid = "dup-chkbox-{$storage->getId()}";
$storageEditUrl = StoragePageController::getEditUrl($storage);
?>
<tr class="package-row <?php echo esc_attr($row_style); ?>">
<td>
<input name="edit_id" type="hidden" value="<?php echo intval($i); ?>" />
<input
class="duppro-storage-input"
id="<?php echo $row_chkid; ?>"
name="_storage_ids[]"
onclick="DupPro.Pack.UpdateStorageCount(); return true;"
data-parsley-errors-container="#storage_error_container" <?php echo $mincheck; ?>
type="checkbox"
value="<?php echo $storage->getId(); ?>"
<?php disabled($is_valid == false); ?>
<?php checked($is_checked); ?>
>
</td>
<td>
<label for="<?php echo $row_chkid; ?>" class="dup-store-lbl">
<?php
echo $storage->getStypeIcon() . '&nbsp;' . esc_html($storage->getStypeName());
echo ($storage->isLocal())
? "<sup title='{$langLocalDefaultMsg}'><i class='fas fa-house-fire fa-fw fa-sm'></i></sup>"
: '';
?>
</label>
</td>
<td>
<a href="<?php echo $storageEditUrl; ?>" target="_blank">
<?php
echo ($is_valid == false) ? '<i class="fa fa-exclamation-triangle fa-sm"></i> ' : '';
echo esc_html($storage->getName());
?>
</a>
</td>
<td>
<?php echo $storage->getHtmlLocationLink();?>
</td>
</tr>
<?php
} catch (Exception $e) {
echo "<tr><td colspan='5'><i>"
. __('Unable to load storage type. Please validate the setup.', 'duplicator-pro')
. "</i></td></tr>";
}
}
?>
</tbody>
</table>
<div style="text-align: right; margin:4px 4px -4px 0; padding:0; width: 100%">
<?php if (CapMng::can(CapMng::CAP_STORAGE, false)) { ?>
<a href="<?php echo esc_url($newStorageUrl); ?>" target="_blank">
[<?php esc_html_e('Add Storage', 'duplicator-pro') ?>]
</a>
<?php } else { ?>
&nbsp;
<?php } ?>
</div>
</div>
</div>
<div id="storage_error_container" class="duplicator-error-container"></div>
<script>
jQuery(function ($)
{
DupPro.Pack.UpdateStorageCount = function ()
{
var store_count = $('#dup-pack-storage-panel input[name="_storage_ids[]"]:checked').length;
$('#dpro-storage-title-count').html('(' + store_count + ')');
(store_count == 0)
? $('#dpro-storage-title-count').css({'color': 'red', 'font-weight': 'bold'})
: $('#dpro-storage-title-count').css({'color': '#444', 'font-weight': 'normal'});
}
});
//INIT
jQuery(document).ready(function ($)
{
DupPro.Pack.UpdateStorageCount();
});
</script>

View File

@@ -0,0 +1,118 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Core\Views\TplMng;
$tplMng = TplMng::getInstance();
$global = DUP_PRO_Global_Entity::getInstance();
$ui_css_archive = (DUP_PRO_UI_ViewState::getValue('dup-pack-archive-panel') ? 'display:block' : 'display:none');
$multisite_css = is_multisite() ? '' : 'display:none';
$archive_format = ($global->getBuildMode() == DUP_PRO_Archive_Build_Mode::DupArchive ? 'daf' : 'zip');
?>
<!-- ===================
META-BOX: ARCHIVE -->
<div class="dup-box dup-archive-filters-wrapper">
<div class="dup-box-title" >
<i class="far fa-file-archive fa-sm"></i> <?php esc_html_e('Archive', 'duplicator-pro') ?>
<sup class="dup-box-title-badge">
<?php echo esc_html($archive_format); ?>
</sup> &nbsp; &nbsp;
<span class="dup-archive-filters-icons">
<span id="dup-archive-filter-file" title="<?php esc_attr_e('Folder/File Filter Enabled', 'duplicator-pro') ?>">
<span class="btn-separator"></span>
<i class="fas fa-folder-open fa-fw"></i>
<sup><i class="fas fa-filter fa-xs"></i></sup>
</span>
<span id="dup-archive-filter-db" title="<?php esc_attr_e('Database Table Filter Enabled', 'duplicator-pro') ?>">
<span class="btn-separator"></span>
<i class="fas fa-table fa-fw"></i>
<sup><i class="fas fa-filter fa-xs"></i></sup>
</span>
<span id="dup-archive-db-only" title="<?php esc_attr_e('Archive Only the Database', 'duplicator-pro') ?>">
<span class="btn-separator"></span>
<i class="fas fa-database fa-fw"></i>
<?php esc_html_e('Database Only', 'duplicator-pro') ?>
</span>
<span id="dup-archive-media-only" title="<?php esc_attr_e('Archive Only Media files', 'duplicator-pro') ?>">
<span class="btn-separator"></span>
<i class="fas fa-file-image fa-fw"></i>
<?php esc_html_e('Media Only', 'duplicator-pro') ?>
</span>
<span id="dpro-install-secure-lock" title="<?php esc_attr_e('Archive password protection is on', 'duplicator-pro') ?>">
<span class="btn-separator"></span>
<i class="fas fa-lock fa-fw"></i>
<?php esc_html_e('Requires Password', 'duplicator-pro') ?>
</span>
</span>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Archive Settings', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dup-pack-archive-panel" style="<?php echo esc_attr($ui_css_archive); ?>">
<input type="hidden" name="archive-format" value="ZIP" />
<!-- ===================
NESTED TABS -->
<div data-dpro-tabs="true">
<ul>
<li class="filter-files-tab"><?php esc_html_e('Files', 'duplicator-pro') ?></li>
<li class="filter-db-tab"><?php esc_html_e('Database', 'duplicator-pro') ?></li>
<?php if (is_multisite()) { ?>
<li class="filter-mu-tab" style="<?php echo $multisite_css ?>"><?php esc_html_e('Multisite', 'duplicator-pro') ?></li>
<?php } ?>
<li class="archive-setup-tab"><?php esc_html_e('Security', 'duplicator-pro') ?></li>
</ul>
<?php
$tplMng->render('admin_pages/packages/setup/archive-filter-files-tab');
$tplMng->render('admin_pages/packages/setup/archive-filter-db-tab');
if (is_multisite()) {
$tplMng->render('admin_pages/packages/setup/archive-filter-mu-tab');
}
$tplMng->render('admin_pages/packages/setup/archive-setup-tab');
?>
</div>
</div>
</div>
<div class="duplicator-error-container"></div>
<?php
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('ERROR!', 'duplicator-pro');
$alert1->message = __('You can\'t exclude all sites.', 'duplicator-pro');
$alert1->initAlert();
?>
<script>
//INIT
jQuery(document).ready(function($)
{
//MU-Transfer buttons
$('#mu-include-btn').click(function() {
return !$('#mu-exclude option:selected').remove().appendTo('#mu-include');
});
$('#mu-exclude-btn').click(function() {
var include_all_count = $('#mu-include option').length;
var include_selected_count = $('#mu-include option:selected').length;
if(include_all_count > include_selected_count) {
return !$('#mu-include option:selected').remove().appendTo('#mu-exclude');
} else {
<?php $alert1->showAlert(); ?>
}
});
});
</script>

View File

@@ -0,0 +1,312 @@
<?php
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Models\BrandEntity;
defined("ABSPATH") or die("");
$ui_css_installer = (DUP_PRO_UI_ViewState::getValue('dpro-pack-installer-panel') ? 'display:block' : 'display:none');
?>
<style>
/*INSTALLER: Area */
label.chk-labels {display:inline-block; margin-top:1px}
table.dpro-install-tbl {width:98%;}
table.dpro-install-tbl td{padding:4px}
table.dpro-install-setup {width:100%}
table.dpro-install-setup tr{vertical-align: top}
div#dpro-pack-installer-panel div.tabs-panel{min-height:150px}
div.dpro-panel-optional-txt {color:maroon}
.disabled .dpro-panel-optional-txt:not(.maroon) {color:#777;}
.maroon {color:maroon;}
</style>
<!-- ===================
INSTALLER -->
<div class="dup-box">
<div class="dup-box-title">
<i class="fa fa-bolt fa-sm"></i> <?php esc_html_e('Installer', 'duplicator-pro') ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Installer Settings', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dpro-pack-installer-panel" style="<?php echo esc_attr($ui_css_installer); ?>">
<div class="dpro-panel-optional-txt">
<b><?php esc_html_e('All values in this section are', 'duplicator-pro'); ?> <u><?php esc_html_e('optional', 'duplicator-pro'); ?></u></b>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Setup/Prefills", 'duplicator-pro'); ?>"
data-tooltip="<?php
esc_attr_e(
'All values in this section are OPTIONAL! If you know ahead of time the database input fields the installer will use,
then you can optionally enter them here and they will be prefilled at install time.
Otherwise you can just enter them in at install time and ignore all these options in the Installer section.',
'duplicator-pro'
);
?>"></i>
</div>
<table class="dpro-install-setup" style="margin-top:-10px">
<tr>
<td colspan="2"><div class="dup-package-hdr-1"><?php esc_html_e("Setup", 'duplicator-pro') ?></div></td>
</tr>
<tr>
<td style="width:130px"><b><?php esc_html_e("Branding", 'duplicator-pro') ?>:</b></td>
<td>
<?php
if (License::can(License::CAPABILITY_BRAND)) :
$brands = BrandEntity::getAllWithDefault();
$active_brand_id = DUP_PRO_Package_Template_Entity::get_manual_template()->installer_opts_brand;
if ($active_brand_id < 0) {
$active_brand_id = -1; // for old brand version
}
?>
<select name="brand" id="brand">
<?php foreach ($brands as $i => $brand) { ?>
<option
value="<?php echo $brand->getId(); ?>"
title="<?php echo esc_attr($brand->notes); ?>"
<?php selected($brand->getId(), $active_brand_id); ?>
>
<?php echo esc_html($brand->name); ?>
</option>
<?php } ?>
</select>
<?php
if ($active_brand_id > 0) {
$preview_url = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND,
[
'view' => 'edit',
'action' => 'edit',
'id' => intval($active_brand_id),
]
);
} else {
$preview_url = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND,
[
'view' => 'edit',
'action' => 'default',
]
);
}
?>
<a href="<?php echo esc_url($preview_url); ?>" target="_blank" class="button" id="brand-preview">
<?php esc_html_e("Preview", 'duplicator-pro'); ?>
</a> &nbsp;
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Choose Brand", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e('This option changes the branding of the installer file. Click the preview button to see the selected style.', 'duplicator-pro'); ?>"
>
</i>
<?php else :
$link = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND
);
?>
<a href="<?php echo esc_url($link); ?>"><?php esc_html_e("Enable Branding", 'duplicator-pro'); ?></a>
<?php endif; ?>
<br/><br/>
</td>
</tr>
</table>
<br/>
<table style="width:100%">
<tr>
<td colspan="2"><div class="dup-package-hdr-1"><?php esc_html_e("Prefills", 'duplicator-pro') ?></div></td>
</tr>
</table>
<!-- ===================
BASIC/CPANEL TABS -->
<div data-dpro-tabs="true">
<ul>
<li id="dpro-bsc-tab-lbl"><?php esc_html_e('Basic', 'duplicator-pro') ?></li>
<li id="dpro-cpnl-tab-lbl"><?php esc_html_e('cPanel', 'duplicator-pro') ?></li>
</ul>
<!-- ===================
TAB1: Basic -->
<div>
<div class="dup-package-hdr-2">
<?php esc_html_e("MySQL Server", 'duplicator-pro') ?>
<div class="dup-package-hdr-usecurrent">
<a href="javascript:void(0)" onclick="DupPro.Pack.ApplyDataCurrent('s1-installer-dbbasic')">[use current]</a>
</div>
</div>
<table class="dpro-install-tbl" id="s1-installer-dbbasic">
<tr>
<td style="width:130px"><b><?php esc_html_e("Host", 'duplicator-pro') ?>:</b></td>
<td><input type="text" name="dbhost" id="dbhost" maxlength="200" placeholder="<?php esc_html_e("example: localhost (value is optional)", 'duplicator-pro') ?>" data-current="<?php echo DB_HOST ?>"/></td>
</tr>
<tr>
<td><b><?php esc_html_e("Database", 'duplicator-pro') ?>:</b></td>
<td><input type="text" name="dbname" id="dbname" maxlength="100" placeholder="<?php esc_attr_e("example: DatabaseName (value is optional)", 'duplicator-pro') ?>" data-current="<?php echo DB_NAME ?>" /></td>
</tr>
<tr>
<td><b><?php esc_html_e("User", 'duplicator-pro') ?>:</b></td>
<td><input type="text" name="dbuser" id="dbuser" maxlength="100" placeholder="<?php esc_attr_e("example: DatabaseUser (value is optional)", 'duplicator-pro') ?>" data-current="<?php echo DB_USER ?>"/></td>
</tr>
</table>
</div>
<!-- ===================
TAB2: cPanel -->
<div>
<table class="dpro-install-tbl">
<tr>
<td colspan="2"><div class="dup-package-hdr-2"><?php esc_html_e("cPanel Login", 'duplicator-pro') ?></div></td>
</tr>
<tr>
<td style="width:130px"><b><?php esc_html_e("Automation", 'duplicator-pro') ?>:</b></td>
<td>
<input type="checkbox" name="cpnl-enable" id="cpnl-enable" value="1" >
<label for="cpnl-enable"><?php esc_html_e("Auto Select cPanel", 'duplicator-pro') ?></label>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Auto Select cPanel", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e('Enabling this options will automatically select the cPanel tab when step one of the installer is shown.', 'duplicator-pro'); ?>">
</i>
</td>
</tr>
<tr>
<td><b><?php esc_html_e("Host", 'duplicator-pro') ?>:</b></td>
<td><input type="text" name="cpnl-host" id="cpnl-host" maxlength="200" placeholder="<?php esc_attr_e("example: cpanelHost (value is optional)", 'duplicator-pro') ?>"/></td>
</tr>
<tr>
<td><b><?php esc_html_e("User", 'duplicator-pro') ?>:</b></td>
<td><input type="text" name="cpnl-user" id="cpnl-user" maxlength="200" placeholder="<?php esc_attr_e("example: cpanelUser (value is optional)", 'duplicator-pro') ?>"/></td>
</tr>
</table><br/>
<div class="dup-package-hdr-2">
<?php esc_html_e("MySQL Server", 'duplicator-pro') ?>
<div class="dup-package-hdr-usecurrent">
<a href="javascript:void(0)" onclick="DupPro.Pack.ApplyDataCurrent('s1-installer-dbcpanel')">[use current]</a>
</div>
</div>
<table class="dpro-install-tbl" id="s1-installer-dbcpanel">
<tr>
<td style="width:130px"><b><?php esc_html_e("Action", 'duplicator-pro') ?>:</b></td>
<td>
<select name="cpnl-dbaction" id="cpnl-dbaction">
<option value=""><?php _e('Default', 'duplicator-pro'); ?></option>
<option value="create"><?php _e('Create A New Database', 'duplicator-pro'); ?></option>
<option value="empty"><?php _e('Connect and Delete Any Existing Data', 'duplicator-pro'); ?></option>
<option value="rename"><?php _e('Connect and Backup Any Existing Data', 'duplicator-pro'); ?></option>
<option value="manual"><?php _e('Skip Database Extraction', 'duplicator-pro'); ?></option>
</select>
</td>
</tr>
<tr>
<td style="width:130px"><b><?php esc_html_e("Host", 'duplicator-pro') ?>:</b></td>
<td><input type="text" name="cpnl-dbhost" id="cpnl-dbhost" maxlength="200" placeholder="<?php esc_attr_e("example: localhost (value is optional)", 'duplicator-pro') ?>" data-current="<?php echo esc_html(DB_HOST); ?>"/></td>
</tr>
<tr>
<td><b><?php esc_html_e("Database", 'duplicator-pro') ?>:</b></td>
<td>
<input
type="text"
name="cpnl-dbname"
id="cpnl-dbname"
data-parsley-pattern="/^[a-zA-Z0-9-_]+$/"
maxlength="100"
placeholder="<?php esc_attr_e("example: DatabaseName (value is optional)", 'duplicator-pro') ?>"
data-current="<?php echo esc_html(DB_NAME); ?>"
>
</td>
</tr>
<tr>
<td><b><?php esc_html_e("User", 'duplicator-pro') ?>:</b></td>
<td>
<input
type="text"
name="cpnl-dbuser"
id="cpnl-dbuser"
data-parsley-pattern="/^[a-zA-Z0-9-_]+$/"
maxlength="100"
placeholder="<?php esc_attr_e("example: DatabaseUserName (value is optional)", 'duplicator-pro') ?>"
data-current="<?php echo esc_html(DB_USER); ?>"
>
</td>
</tr>
</table>
</div>
</div><br/>
<small><?php esc_html_e("Additional inputs can be entered at install time.", 'duplicator-pro') ?></small>
<br/><br/>
</div>
</div><br/>
<script>
(function ($) {
DupPro.Pack.ApplyDataCurrent = function (id)
{
$('#' + id + ' input').each(function ()
{
var attr = $(this).attr('data-current');
if (typeof attr !== typeof undefined && attr !== false) {
$(this).val($(this).attr('data-current'));
}
});
};
<?php if (License::can(License::CAPABILITY_BRAND)) : ?>
// brand-preview
var $brand = $("#brand"),
brandCheck = function (e) {
var $this = $(this) || $brand;
var $id = $this.val();
<?php
$prewURLs = [
ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND,
[
'view' => 'edit',
'action' => 'default',
]
),
ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND,
[
'view' => 'edit',
'action' => 'edit',
]
),
];
?>
var $url = <?php echo json_encode($prewURLs); ?>;
$url[1] += "&id=" + $id;
$("#brand-preview").attr('href', $url[ $id > 0 ? 1 : 0 ]);
$this.find('option[value="' + $id + '"]')
.prop('selected', true)
.parent();
};
$brand.on('select change', brandCheck);
<?php endif; ?>
}(window.jQuery));
</script>

View File

@@ -0,0 +1,681 @@
<?php
defined("ABSPATH") or die("");
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Libs\Snap\SnapJson;
require_once(DUPLICATOR____PATH . '/classes/package/class.pack.php');
wp_enqueue_script('dup-pro-handlebars');
if (empty($_POST)) {
// Refresh 'fix'
$redirect = PackagesPageController::getInstance()->getPackageBuildS1Url();
ob_start();
?>
<script>
window.location.href = <?php echo SnapJson::jsonEncode($redirect); ?>;
</script>
<?php
$html = (string) ob_get_clean();
die($html);
}
$global = DUP_PRO_Global_Entity::getInstance();
//echo '<pre>', var_export($_REQUEST, true), '</pre>';
if (!empty($_REQUEST['action']) && $_REQUEST['action'] === 'template-create') {
$storage_ids = isset($_REQUEST['_storage_ids']) ? $_REQUEST['_storage_ids'] : array();
$template_id = (int) $_REQUEST['template_id'];
$template = DUP_PRO_Package_Template_Entity::getById($template_id);
// always set the manual template since it represents the last thing that was run
DUP_PRO_Package::set_manual_template_from_post($_REQUEST);
$global->setManualModeStorageIds($storage_ids);
$global->save();
$name_chars = array(
".",
"-",
);
$name = ( isset($_REQUEST['package-name']) && !empty($_REQUEST['package-name'])) ? $_REQUEST['package-name'] : DUP_PRO_Package::get_default_name();
$name = substr(sanitize_file_name($name), 0, 40);
$name = str_replace($name_chars, '', $name);
DUP_PRO_Package::set_temporary_package_from_template_and_storages($template_id, $storage_ids, $name);
}
$Package = DUP_PRO_Package::get_temporary_package();
$package_list_url = ControllersManager::getMenuLink(ControllersManager::PACKAGES_SUBMENU_SLUG);
$archive_export_onlydb = $Package->isDBOnly();
$messageText = TplMng::getInstance()->render('admin_pages/packages/scan/error_message', [], false);
/** @var bool */
$blur = TplMng::getInstance()->getGlobalValue('blurCreate');
?>
<style>
/*PROGRESS-BAR - RESULTS - ERROR */
form#form-duplicator {text-align:center; max-width:825px; min-height:200px; margin:0px auto 0px auto; padding:0px;}
div.dup-progress-title {font-size:22px; padding:5px 0 20px 0; font-weight:bold}
div#dup-msg-success {padding:0 5px 5px 5px; text-align:left}
div#dup-msg-success div.details {padding:10px 15px 10px 15px; margin:5px 0 15px 0; background:#fff; border-radius:4px; border:1px solid #ddd;box-shadow:0 8px 6px -6px #999; }
div#dup-msg-success div.details-title {font-size:20px; border-bottom:1px solid #dfdfdf; padding:5px; margin:0 0 10px 0; font-weight:bold}
div#dup-msg-success-subtitle {color:#999; margin:0; font-size:11px}
div.dup-scan-filter-status {display:inline; font-size:11px; margin-right:10px; color:#630f0f;}
div#dup-msg-error {color:#A62426; padding:5px; max-width:790px;}
div#dup-msg-error-response-text { max-height:500px; overflow-y:scroll; border:1px solid silver; border-radius:2px; padding:10px;background:#fff}
div.dup-hdr-error-details {text-align:left; margin:20px 0}
i[data-tooltip].fa-question-circle {color:#555}
/*SCAN ITEMS: Sections */
sup.dup-small-ext-type {font-size:11px; font-weight: normal; font-style: italic}
div.scan-header { font-size:16px; padding:7px 5px 7px 7px; font-weight:bold; background-color:#E0E0E0; border-bottom:0px solid #C0C0C0 }
div.scan-header-details {float:right; margin-top:-5px}
div.scan-item {border:1px solid #E0E0E0; border-top:none;}
div.scan-item-first {border-top:1px solid #E0E0E0}
div.scan-item div.title {background-color:#F1F1F1; width:100%; padding:4px 0 4px 0; cursor:pointer; height:20px;}
@media screen and (min-width: 1280px) {
div.scan-item div.title {padding:10px 0 10px 0;}
}
div.scan-item div.title:hover {background-color:#ECECEC;}
div.scan-item div.text {font-weight:bold; font-size:14px; float:left; position:relative; left:10px}
div.scan-item div.info {display:none; padding:10px; background:#fff}
div.scan-good {display:inline-block; color:green;font-weight:bold;}
div.scan-warn {display:inline-block; color:#630f0f;font-weight:bold;}
div.dup-more-details {float:right; font-size:14px}
div.dup-more-details:hover {color:#777; cursor:pointer}
div.dup-more-details a {color:#222}
div.dup-more-details a:hover {color:#777}
i.scan-warn {color:#630f0f;}
div#scan-unreadable-items div.directory {font-size:11px}
div.subsite-filter-info {margin-left: 15px;}
div.subsite-filter-info ol {margin-top: 0px;}
/*DIALOG WINDOWS*/
div#arc-details-dlg {font-size:12px}
div#arc-details-dlg h2 {margin:0; padding:0 0 5px 0; border-bottom:1px solid #dfdfdf;}
div#arc-details-dlg hr {margin:3px 0 10px 0}
div#arc-details-dlg div.filter-area {height:230px; overflow-y:scroll; border:1px solid #dfdfdf; padding:8px; margin:2px 0}
div#arc-details-dlg div.file-info {padding:0 0 10px 15px; width:500px; white-space:nowrap;}
div#arc-details-dlg div.info{line-height:18px}
div#arc-details-dlg div.info label{font-size:12px !important; font-weight: bold; display: inline-block; min-width: 100px}
div#arc-paths-dlg textarea.path-dirs,
textarea.path-files {font-size:12px; border: 1px solid silver; padding: 10px; background: #fff; margin:5px; height:125px; width:100%; white-space:pre}
div#arc-paths-dlg div.copy-button {float:right;}
div#arc-paths-dlg div.copy-button button {font-size:12px}
/*FILES */
div#data-arc-size1 {display:inline-block; font-size:11px; margin-right:1px;}
i.data-size-help { font-size:12px; display:inline-block; margin:0; padding:0}
div.dup-data-size-uncompressed {font-size:10px; text-align: right; padding:0; margin:-7px 0 0 0; font-style: italic; font-weight: normal; border:0px solid red; clear:both}
div.hb-files-style > div.container {border:1px solid #E0E0E0; border-radius:2px; margin:5px 0 10px 0}
div.hb-files-style > div.container b {font-weight:bold}
div.hb-files-style > div.container div.divider {margin-bottom:2px; font-weight:bold}
div.hb-files-style div.data {line-height:21px; min-height:100px; max-height:70vh; overflow-y:scroll; }
div.hb-files-style div.data-padded {padding:10px }
div.hb-files-style div.hdrs {background:#fff; padding:2px 4px 4px 6px; border-bottom:1px solid #E0E0E0; font-weight:bold}
div.hb-files-style div.hdrs sup i.fa {font-size:11px}
div.hb-files-style div.hdrs-up-down {float:right; margin:2px 12px 0 0}
div.hb-files-style i.dup-nav-toggle:hover {cursor:pointer; color:#999}
div.hb-files-style div.directory {margin-left:12px; white-space: nowrap;}
div.hb-files-style div.directory i.size {font-size:11px; font-style:normal; display:inline-block; min-width:50px}
div.hb-files-style div.directory i.count {font-size:11px; font-style:normal; display:inline-block; min-width:20px}
div.hb-files-style div.directory i.empty {width:15px; display:inline-block}
div.hb-files-style div.directory i.dup-nav {cursor:pointer}
div.hb-files-style div.directory i.fa {width:8px}
div.hb-files-style div.directory i.chk-off {width:20px; color:#777; cursor: help; margin:0; font-size:1.25em}
div.hb-files-style div.directory label {font-weight:bold; cursor:pointer; vertical-align:top;}
div.hb-files-style div.directory label:hover {color:#025d02}
div.hb-files-style div.files {padding:2px 0 0 35px; font-size:12px; display:none; line-height:18px}
div.hb-files-style div.files i.size {font-style:normal; display:inline-block; min-width:50px}
div.hb-files-style div.files label {font-weight: normal; font-size:11px; vertical-align:top;display:inline-block;width:450px; white-space: nowrap; overflow:hidden; text-overflow:ellipsis;}
div.hb-files-style div.files label:hover {color:#025d02; cursor: pointer}
div.hb-files-style div.apply-btn {text-align:right; margin: 1px 0 10px 0}
div.hb-files-style div.apply-warn {float:left; font-size:11px; color:maroon; margin-top:-7px; font-style: italic}
div#size-more-details {display:none; margin:5px 0 20px 0; border:1px solid #dfdfdf; padding:8px; border-radius:2px; background-color: #F1F1F1}
div#size-more-details ul {list-style-type:circle; padding-left:20px; margin:0}
div#size-more-details li {margin:0}
/* SERVER-CHECKS */
div.dup-scan-title {display:inline-block; padding:1px; font-weight: bold;}
div.dup-scan-title a {display:inline-block; min-width:200px; padding:3px; }
div.dup-scan-title a:focus {outline: 1px solid #fff; box-shadow: none}
div.dup-scan-title div {display:inline-block; }
div.dup-scan-info {display:none;}
div.dup-scan-good {display:inline-block; color:green;font-weight: bold;}
div.dup-scan-warn {display:inline-block; color:#F0AC00;font-weight: bold;}
span.dup-toggle {float:left; margin:0 2px 2px 0; }
div.dup-scan-files-migrae-status {max-height:250px; overflow-y:scroll; border:1px solid silver; padding:0 4px 0 4px; background: #efefef; border-radius:2px}
/*DATABASE*/
table.dup-scan-db-details {line-height: 14px; margin:5px 0px 0px 20px; width:98%}
table.dup-scan-db-details td {padding:2px;}
table.dup-scan-db-details td:first-child {font-weight: bold; white-space: nowrap; width:105px}
div#dup-scan-db-info {margin-top:5px}
div#data-db-tablelist {max-height:250px; overflow-y:scroll; border:1px solid silver; padding:8px; background: #efefef; border-radius:2px}
div#data-db-tablelist td{padding:0 5px 3px 20px; min-width:100px}
div#data-db-size1 {display: inline-block; font-size:11px; margin-right:1px;}
/*WARNING-CONTINUE*/
div#dpro-scan-warning-continue {display:none; text-align:center; padding:0 0 15px 0}
div#dpro-scan-warning-continue div.msg2 {padding:2px; line-height:13px; font-size:11px !important;}
/*FILES */
div#dpro-confirm-area {color:maroon; display:none; font-size:14px; line-height:24px; font-weight: bold; margin: -5px 0 10px 0}
div#dpro-confirm-area label {font-size:14px !important}
/*Footer*/
div.dup-button-footer {text-align:center; margin:0}
/** JSTREE **/
.jstree .root-node > .jstree-anchor { font-weight: bold; }
.jstree .info-node > .jstree-anchor { font-weight: bold; }
.jstree .info-node > .jstree-anchor .jstree-checkbox {display: none;}
.jstree .warning-node > .jstree-anchor {color: red;}
.jstree .filtered-node .jstree-anchor {opacity: 0.3; text-decoration: line-through; }
.jstree .jstree-checkbox-disabled {opacity: 0.3;}
.dup-tree-section {
position: relative;
}
.tree-nav-bar {
line-height: 30px;
background-color: #EFEFEF;
border-bottom: 1px solid darkgray;
}
.tree-nav-bar .container {
padding: 3px 30px 3px 5px;
}
.dup-tree-section .tree-loader {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0,0,0,.3);
top: 0;
left: 0;
z-index: 9999;
}
.dup-tree-section .tree-loader .container-wrapper {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
color: white;
width: 100%;
text-align: center;
font-size: 14px;
}
.jstree .jstree-node > .jstree-anchor {
display: inline-block;
width: calc(100% - 30px);
}
.tree-nav-bar .size,
.tree-nav-bar .nodes,
.jstree-anchor .size,
.jstree-anchor .nodes {
float: right;
text-align: right;
display: block;
min-width: 90px;
border-left: 1px solid black;
padding-left: 5px;
margin-left: 5px;
box-sizing: border-box;
}
.tree-nav-bar .size,
.tree-nav-bar .nodes {
border: none;
}
.warning-node > .jstree-anchor .size,
.warning-node > .jstree-anchor .nodes {
color: #9f2a2a;
font-weight: bold;
}
</style>
<?php
$validator = $Package->validateInputs();
if (!$validator->isSuccess()) {
?>
<form id="form-duplicator" method="post" action="<?php echo $package_list_url ?>">
<!-- ERROR MESSAGE -->
<div id="dup-msg-error">
<div class="dup-hdr-error"><i class="fa fa-exclamation-circle"></i> <?php esc_html_e('Input fields not valid', 'duplicator-pro'); ?></div>
<i><?php esc_html_e('Please try again!', 'duplicator-pro'); ?></i><br/>
<div style="text-align:left">
<b><?php esc_html_e("Server Status:", 'duplicator-pro'); ?></b> &nbsp;
<div id="dup-msg-error-response-status" style="display:inline-block"></div><br/>
<b><?php esc_html_e("Error Message:", 'duplicator-pro'); ?></b>
<div id="dup-msg-error-response-text">
<ul>
<?php
$validator->getErrorsFormat("<li>%s</li>");
?>
</ul>
</div>
</div>
</div>
<input
type="button"
value="&#9664; <?php esc_html_e("Back", 'duplicator-pro') ?>"
class="button button-large dup-go-back-to-new1"
>
</form>
<?php
return;
}
?>
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar <?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
<tr>
<td>
<div id="dup-wiz">
<div id="dup-wiz-steps">
<div class="completed-step"><a>1 <?php esc_html_e('Setup', 'duplicator-pro'); ?></a></div>
<div class="active-step"><a>2 <?php esc_html_e('Scan', 'duplicator-pro'); ?> </a></div>
<div><a>3 <?php esc_html_e('Build', 'duplicator-pro'); ?> </a></div>
</div>
<div id="dup-wiz-title" style="white-space: nowrap">
<?php esc_html_e('Step 2: System Scan', 'duplicator-pro'); ?>
</div>
</div>
</td>
</tr>
</table>
<hr class="dpro-edit-toolbar-divider"/>
<form
id="form-duplicator"
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
method="post"
action="<?php echo $package_list_url ?>"
>
<input type="hidden" name="create_from_temp" value="1" />
<div id="dup-progress-area">
<!-- PROGRESS BAR -->
<div id="dup-progress-bar-area">
<div class="dup-pro-title" >
<i class="fa fa-circle-notch fa-spin"></i> <?php esc_html_e('Scanning Site', 'duplicator-pro'); ?>
</div>
<div class="dup-pro-meter-wrapper" >
<div class="dup-pro-meter blue dup-pro-fullsize">
<span></span>
</div>
<span class="text"></span>
</div>
<b><?php esc_html_e('Please Wait...', 'duplicator-pro'); ?></b><br/><br/>
<i><?php esc_html_e('Keep this window open during the scan process.', 'duplicator-pro'); ?></i><br/>
<i><?php esc_html_e('This can take several minutes.', 'duplicator-pro'); ?></i><br/>
</div>
<!-- SCAN DETAILS REPORT -->
<div id="dup-msg-success" style="display:none">
<div style="text-align:center">
<div class="dup-hdr-success"><i class="far fa-check-square"></i> <?php esc_html_e('Scan Complete', 'duplicator-pro'); ?></div>
<div id="dup-msg-success-subtitle">
<?php esc_html_e("Process Time:", 'duplicator-pro'); ?> <span id="data-rpt-scantime"></span>
</div>
</div>
<div class="details">
<?php
include(DUPLICATOR____PATH . '/views/packages/main/s2.scan2.server.php');
echo '<br/>';
include(DUPLICATOR____PATH . '/views/packages/main/s2.scan3.archive.php');
?>
</div>
</div>
<!-- ERROR MESSAGE -->
<div id="dup-msg-error" style="display:none">
<div class="dup-hdr-error"><i class="fa fa-exclamation-circle"></i> <?php esc_html_e('Scan Error', 'duplicator-pro'); ?></div>
<i><?php esc_html_e('Please try again!', 'duplicator-pro'); ?></i><br/>
<div style="text-align:left">
<b><?php esc_html_e("Server Status:", 'duplicator-pro'); ?></b> &nbsp;
<div id="dup-msg-error-response-status" style="display:inline-block"></div><br/>
<b><?php esc_html_e("Error Message:", 'duplicator-pro'); ?></b>
<div id="dup-msg-error-response-text"></div>
</div>
</div>
</div>
<!-- WARNING CONTINUE -->
<div id="dpro-scan-warning-continue">
<div class="msg2">
<?php
_e("Scan checks are not required to pass, however they could cause issues on some systems.", 'duplicator-pro');
echo '<br/>';
_e("Please review the details for each section by clicking on the detail title.", 'duplicator-pro');
?>
</div>
</div>
<div id="dpro-confirm-area">
<label for="dpro-confirm-check"><?php
esc_html_e('Do you want to continue?', 'duplicator-pro');
echo '<br/> ';
esc_html_e('At least one or more checkboxes were checked in "Quick Filters".', 'duplicator-pro')
?><br/>
<i style="font-weight:normal"><?php esc_html_e('To apply a "Quick Filter" click the "Add Filters & Rescan" button', 'duplicator-pro') ?></i><br/>
<input type="checkbox" id="dpro-confirm-check" onclick="jQuery('#dup-build-button').removeAttr('disabled');">
<?php esc_html_e('Yes. Continue without applying any file filters.', 'duplicator-pro') ?></label><br/>
</div>
<div class="dup-button-footer" style="display:none">
<input
type="button"
value="&#9664; <?php esc_html_e("Back", 'duplicator-pro') ?>"
class="button button-large dup-go-back-to-new1"
>
<input type="button" value="<?php esc_attr_e("Rescan", 'duplicator-pro') ?>" onclick=" DupPro.Pack.reRunScanner()" class="button button-large" />
<input type="button" onclick="DupPro.Pack.startBuild();" class="button button-primary button-large" id="dup-build-button" value='<?php esc_attr_e("Build", 'duplicator-pro') ?> &#9654'/>
</div>
</form>
<script>
jQuery(document).ready(function ($)
{
let errorMessage = <?php echo SnapJson::jsonEncode($messageText); ?>;
DupPro.Pack.WebServiceStatus = {
Pass: 1,
Warn: 2,
Error: 3,
Incomplete: 4,
ScheduleRunning: 5
}
DupPro.Pack.runScanner = function (callbackOnSuccess) {
$.ajax({
type: "POST",
cache: false,
dataType: "text",
url: ajaxurl,
timeout: 10000000,
data: {
action: 'duplicator_pro_package_scan',
nonce: '<?php echo wp_create_nonce('duplicator_pro_package_scan'); ?>'
},
complete: function () {},
success: function (respData, textStatus, xHr) {
try {
var data = DupPro.parseJSON(respData);
} catch (err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
var status = xHr.status + ' -' + xHr.statusText;
$('#dup-progress-bar-area, #dup-build-button').hide();
$('#dup-msg-error-response-status').html(status)
$('#dup-msg-error-response-text').html(xHr.responseText);
$('#dup-msg-error, .dup-button-footer').show();
console.log(data);
return false;
}
var data = data || new Object();
if (data.ScanStatus !== undefined && data.ScanStatus == 'running') {
DupPro.Pack.runScanner();
} else {
var status = data.Status || 3;
var message = data.Message || "Unable to read JSON from service. <br/> See: /wp-admin/admin-ajax.php?action=duplicator_pro_package_scan";
console.log(data);
if (status == DupPro.Pack.WebServiceStatus.Pass) {
DupPro.Pack.loadScanData(data);
if (typeof callbackOnSuccess === "function") {
callbackOnSuccess(data);
}
$('.dup-button-footer').show();
} else if (status == DupPro.Pack.WebServiceStatus.ScheduleRunning) {
// as long as its just saying that someone blocked us keep trying
console.log('retrying scan in 300 ms...');
setTimeout(DupPro.Pack.runScanner, 300);
} else {
$('#dup-progress-bar-area, #dup-build-button').hide();
$('#dup-msg-error-response-status').html(status);
$('#dup-msg-error-response-text').html(message + errorMessage);
$('#dup-msg-error').show();
$('.dup-button-footer').show();
}
}
},
error: function (data) {
var status = data.status + ' -' + data.statusText;
$('#dup-progress-bar-area, #dup-build-button').hide();
$('#dup-msg-error-response-status').html(status)
$('#dup-msg-error-response-text').html(data.responseText + errorMessage);
$('#dup-msg-error, .dup-button-footer').show();
console.log(data);
}
});
}
DupPro.Pack.reRunScanner = function (callbackOnSuccess)
{
$('#dup-msg-success,#dup-msg-error,.dup-button-footer,#dpro-confirm-area').hide();
$('#dpro-confirm-check').prop('checked', false);
$('#dup-progress-bar-area').show();
$('#dpro-scan-warning-continue').hide();
DupPro.Pack.runScanner(callbackOnSuccess);
}
DupPro.Pack.loadScanData = function (data)
{
try {
var errMsg = "unable to read";
$('#dup-progress-bar-area').hide();
//****************
// BRAND
// #data-srv-brand-check
// #data-srv-brand-name
// #data-srv-brand-note
$("#data-srv-brand-name").text(data.SRV.Brand.Name);
if (data.SRV.Brand.LogoImageExists)
$("#data-srv-brand-note").html(data.SRV.Brand.Notes);
else
$("#data-srv-brand-note")
.html("<?php
esc_html_e(
"WARNING! Logo images no longer can be found inside brand. Please edit this brand and place new images. After that you can build your package with this brand.",
'duplicator-pro'
); ?>"
);
$("#data-srv-brand-check").html(DupPro.Pack.setScanStatus(data.SRV.Brand.LogoImageExists));
//****************
//REPORT
var base = $('#data-rpt-scanfile').attr('href');
$('#data-rpt-scanfile').attr('href', base + '&scanfile=' + data.RPT.ScanFile);
$('#data-rpt-scantime').text(data.RPT.ScanTime || 0);
DupPro.Pack.intServerData(data);
DupPro.Pack.initArchiveFilesData(data);
//Addon Sites
$('#data-arc-status-addonsites').html(DupPro.Pack.setScanStatus(data.ARC.Status.AddonSites));
if (data.ARC.FilterInfo.Dirs.AddonSites !== undefined && data.ARC.FilterInfo.Dirs.AddonSites.length > 0) {
$("#addonsites-block").show();
}
$('#dup-msg-success').show();
//****************
//DATABASE
var html = "";
var DB_TableRowMax = <?php echo DUPLICATOR_PRO_SCAN_DB_TBL_ROWS; ?>;
var DB_TableSizeMax = <?php echo DUPLICATOR_PRO_SCAN_DB_TBL_SIZE; ?>;
if (data.DB.DBExcluded && data.DB.Status.Success) {
$('#data-db-status-size1').html(DupPro.Pack.setScanStatus(data.DB.Status.Excluded));
$('#data-db-size1').text(data.DB.Size || errMsg);
} else if (data.DB.Status.Success) {
$('#data-db-status-size1').html(DupPro.Pack.setScanStatus(data.DB.Status.Size));
$('#data-db-size1').text(data.DB.Size || errMsg);
$('#data-db-size2').text(data.DB.Size || errMsg);
$('#data-db-rows').text(data.DB.Rows || errMsg);
$('#data-db-tablecount').text(data.DB.TableCount || errMsg);
//Table Details
if (data.DB.TableList == undefined || data.DB.TableList.length == 0) {
html = '<?php esc_html_e("Unable to report on any tables", 'duplicator-pro') ?>';
} else {
$.each(data.DB.TableList, function (i) {
html += '<b>' + i + '</b><br/>';
html += '<table><tr>';
$.each(data.DB.TableList[i], function (key, val) {
switch (key) {
case 'Case':
color = (val == 1) ? 'maroon' : 'black';
html += '<td style="color:' + color + '">Uppercase: ' + val + '</td>';
break;
case 'Rows':
color = (val > DB_TableRowMax) ? 'red' : 'black';
html += '<td style="color:' + color + '">Rows: ' + val + '</td>';
break;
case 'USize':
color = (parseInt(val) > DB_TableSizeMax) ? 'red' : 'black';
html += '<td style="color:' + color + '">Size: ' + data.DB.TableList[i]['Size'] + '</td>';
break;
}
});
html += '</tr></table>';
});
}
$('#data-db-tablelist').html(html);
} else {
html = '<?php esc_html_e("Unable to report on database stats", 'duplicator-pro') ?>';
$('#dup-scan-db').html(html);
}
var isWarn = false;
for (key in data.ARC.Status) {
if ('Big' != key && 'Warn' == data.ARC.Status[key]) {
isWarn = true;
}
}
if (!isWarn) {
if ('Warn' == data.DB.Status.Size) {
isWarn = true;
}
}
if (!isWarn && 'Warn' == data.DB.Status.Rows) {
isWarn = true;
}
if (!isWarn && 'Warn' == data.SRV.PHP.ALL) {
isWarn = true;
}
if (!isWarn && (data.SRV.WP.version == false || data.SRV.WP.core == false)) {
isWarn = true;
}
if (isWarn) {
$('#dpro-scan-warning-continue').show();
} else {
$('#dpro-scan-warning-continue').hide();
$('#dup-build-button').prop("disabled", false).addClass('button-primary');
}
} catch (err) {
err += '<br/> Please try again!'
$('#dup-msg-error-response-status').html("n/a")
$('#dup-msg-error-response-text').html(err);
$('#dup-msg-error, .dup-button-footer').show();
$('#dup-build-button').hide();
}
}
//Starts the build process
DupPro.Pack.startBuild = function ()
{
// disable to prevent double click
$('#dup-build-button').prop('disabled', true);
if ($('#dpro-confirm-check').is(":checked")) {
$('#form-duplicator').submit();
}
var sizeChecks = $('#hb-files-large-jstree').length ? $('#hb-files-large-jstree').jstree(true).get_checked() : 0;
var addonChecks = $('#hb-addon-sites-result input:checked');
var utf8Checks = $('#hb-files-utf8-jstree').length ? $('#hb-files-utf8-jstree').jstree(true).get_checked() : 0;
if (sizeChecks.length > 0 || addonChecks.length > 0 || utf8Checks.length > 0) {
$('#dpro-confirm-area').show();
} else {
$('#form-duplicator').submit();
}
}
//Toggles each scan item to hide/show details
DupPro.Pack.toggleScanItem = function (item)
{
var $info = $(item).parents('div.scan-item').children('div.info');
var $text = $(item).find('div.text i.fa');
if ($info.is(":hidden")) {
$text.addClass('fa-caret-down').removeClass('fa-caret-right');
$info.show();
} else {
$text.addClass('fa-caret-right').removeClass('fa-caret-down');
$info.hide(250);
}
}
//Set Good/Warn Badges and checkboxes
DupPro.Pack.setScanStatus = function (status)
{
var result;
switch (status) {
case false :
result = '<div class="scan-warn"><i class="fa fa-exclamation-triangle fa-sm"></i></div>';
break;
case 'Warn' :
result = '<div class="badge badge-warn">Notice</div>';
break;
case true :
result = '<div class="scan-good"><i class="fa fa-check"></i></div>';
break;
case 'Good' :
result = '<div class="badge badge-pass">Good</div>';
break;
default :
result = 'unable to read';
}
return result;
}
//Allows user to continue with build if warnings found
DupPro.Pack.warningContinue = function (checkbox)
{
($(checkbox).is(':checked'))
? $('#dup-build-button').prop('disabled', false).addClass('button-primary')
: $('#dup-build-button').prop('disabled', true).removeClass('button-primary');
}
//Page Init:
DupPro.Pack.runScanner();
$('.dup-go-back-to-new1').click(function (event) {
event.preventDefault();
window.location.href = <?php echo SnapJson::jsonEncode(PackagesPageController::getInstance()->getPackageBuildS1Url()); ?>;
});
});
</script>

View File

@@ -0,0 +1,429 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Addons\DropboxAddon\Models\DropboxStorage;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Libs\Snap\SnapUtil;
use Duplicator\Models\DynamicGlobalEntity;
/**
* Variables
*
* @var ?DUP_PRO_Package $Package
* @var bool $archive_export_onlydb
*/
$global = DUP_PRO_Global_Entity::getInstance();
global $wp_version;
$diagnosticUrl = ToolsPageController::getInstance()->getMenuLink(ToolsPageController::L2_SLUG_DISAGNOSTIC);
?>
<!-- ================================================================
SETUP
================================================================ -->
<div class="details-title">
<i class="fas fa-tasks fa-sm fa-fw"></i> <?php esc_html_e("Setup", 'duplicator-pro'); ?>
<div class="dup-more-details">
<a href="<?php echo esc_url($diagnosticUrl); ?>" target="_blank" title="<?php esc_attr_e('Show Diagnostics', 'duplicator-pro'); ?>">
<i class="fa fa-microchip"></i>
</a>&nbsp;
<a href="site-health.php" target="_blank" title="<?php esc_attr_e('Site Health', 'duplicator-pro'); ?>"><i class="fas fa-file-medical-alt"></i></a>
</div>
</div>
<!-- ==========================
SYSTEM SETTINGS -->
<div class="scan-item scan-item-first">
<div class='title' onclick="DupPro.Pack.toggleScanItem(this);">
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('System', 'duplicator-pro'); ?></div>
<div id="data-srv-php-all"></div>
</div>
<div class="info">
<?php
//DIVIDER
echo "<div class='scan-system-divider'><i class='fa fa-list'></i>&nbsp;" . __('General Checks', 'duplicator-pro') . "</div>";
if (License::can(License::CAPABILITY_BRAND)) :
?>
<span id="data-srv-brand-check"></span>&nbsp;<b><?php esc_html_e('Brand', 'duplicator-pro'); ?>: </b>&nbsp;<span id="data-srv-brand-name"><?php esc_html_e('Default', 'duplicator-pro'); ?></span><br />
<div class="scan-system-subnote" id="data-srv-brand-note"><?php esc_html_e('The default content used when a brand is not defined.', 'duplicator-pro'); ?></div>
<hr size="1" />
<?php
endif;
//WEB SERVER
$web_servers = implode(', ', $GLOBALS['DUPLICATOR_PRO_SERVER_LIST']);
echo '<span id="data-srv-php-websrv"></span>&nbsp;<b>' . __('Web Server', 'duplicator-pro') . ":</b>&nbsp; '{$_SERVER['SERVER_SOFTWARE']}' <br/>";
echo '<div class="scan-system-subnote">';
esc_html_e("Supported Web Servers:", 'duplicator-pro');
echo "&nbsp;{$web_servers}";
echo '</div>';
//MYSQLI
echo '<hr size="1" /><span id="data-srv-php-mysqli"></span>&nbsp;<b>' . __('MySQLi', 'duplicator-pro') . "</b> <br/>";
echo '<div class="scan-system-subnote">';
esc_html_e('Creating the package does not require the mysqli module. However the installer file requires that the PHP module mysqli be installed on the server it is deployed on.', 'duplicator-pro');
echo "&nbsp;<i><a href='http://php.net/manual/en/mysqli.installation.php' target='_blank'>[" . __('details', 'duplicator-pro') . "]</a></i>";
echo '</div>';
//DROPBOX ONLY
if ($Package->contains_storage_type(DropboxStorage::getSType())) {
$transferMode = DynamicGlobalEntity::getInstance()->getVal('dropbox_transfer_mode');
//OPENSSL
echo '<hr size="1" /><span id="data-srv-php-openssl"></span>&nbsp;<b>' . __('Open SSL - Dropbox', 'duplicator-pro') . '</b>';
echo '<div class="scan-system-subnote">';
esc_html_e('Dropbox storage requires an HTTPS connection. On windows systems enable "extension=php_openssl.dll" in the php.ini configuration file. ', 'duplicator-pro');
esc_html_e('On Linux based systems check for the --with-openssl[=DIR] flag.', 'duplicator-pro');
echo "&nbsp;<i><a href='http://php.net/manual/en/openssl.installation.php' target='_blank'>[" . __('details', 'duplicator-pro') . "]</a></i>";
echo '</div>';
if ($transferMode == DUP_PRO_Dropbox_Transfer_Mode::FOpen_URL) {
//FOpen
$test = DUP_PRO_Server::isURLFopenEnabled();
echo '<hr size="1" /><span id="data-srv-php-allowurlfopen"></span>&nbsp;<b>' . __('Allow URL Fopen', 'duplicator-pro') . ":</b>&nbsp; '{$test}'<br/>";
echo '<div class="scan-system-subnote">';
esc_html_e('Dropbox communications requires that [allow_url_fopen] be set to 1 in the php.ini file.', 'duplicator-pro');
echo "&nbsp;<i><a href='http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen' target='_blank'>[" . __('details', 'duplicator-pro') . "]</a></i><br/>";
echo '</div>';
} elseif ($transferMode == DUP_PRO_Dropbox_Transfer_Mode::cURL) {
//FOpen
$test = SnapUtil::isCurlEnabled() ? __('True', 'duplicator-pro') : __('False', 'duplicator-pro');
echo '<hr size="1" /><span id="data-srv-php-curlavailable"></span>&nbsp;<b>' . __('cURL - Dropbox', 'duplicator-pro') . ":</b>&nbsp; '{$test}'<br/>";
echo '<div class="scan-system-subnote">';
esc_html_e('Dropbox communications requires that extension=php_curl.dll be present in the php.ini file.', 'duplicator-pro');
echo "&nbsp;<i><a href='http://php.net/manual/en/curl.installation.php' target='_blank'>[" . __('details', 'duplicator-pro') . "]</a></i><br/>";
echo '</div>';
}
}
//DIVIDER
echo "<div class='scan-system-divider margin-top-1'><i class='fa fa-list'></i>&nbsp;" . __('PHP Checks', 'duplicator-pro') . "</div>";
//PHP VERSION
echo '<span id="data-srv-php-version"></span>&nbsp;<b>' . __('PHP Version: ', 'duplicator-pro') . "</b>" . PHP_VERSION . " <br/>";
echo '<div class="scan-system-subnote">';
printf(
esc_html__(
'The minimum PHP version supported by Duplicator is %1$s, however it is highly recommended to use PHP %2$s or higher for improved stability.',
'duplicator-pro'
),
DUPLICATOR_PRO_PHP_MINIMUM_VERSION,
DUPLICATOR_PRO_PHP_SUGGESTED_VERSION
);
echo "&nbsp;<i><a href='http://php.net/ChangeLog-5.php' target='_blank'>[" . __('details', 'duplicator-pro') . "]</a></i>";
echo '</div>';
//OPEN_BASEDIR
$openBaseDir = ini_get("open_basedir");
$test = empty($openBaseDir) ? 'off' : 'on';
echo '<hr size="1" /><span id="data-srv-php-openbase"></span>&nbsp;<b>' . __('PHP Open Base Dir', 'duplicator-pro') . ":</b>&nbsp; '{$test}' <br/>";
echo '<div class="scan-system-subnote">';
esc_html_e('Issues might occur when [open_basedir] is enabled. Work with your server admin or hosting provider to disable this value in the php.ini file if youre having issues building a package.', 'duplicator-pro');
echo "&nbsp;<i><a href='http://php.net/manual/en/ini.core.php#ini.open-basedir' target='_blank'>[" . __('details', 'duplicator-pro') . "]</a></i><br/>";
echo '</div>';
//MAX_EXECUTION_TIME
$test = (set_time_limit(0)) ? 0 : ini_get("max_execution_time");
echo '<hr size="1" /><span id="data-srv-php-maxtime"></span>&nbsp;<b>' . __('PHP Max Execution Time', 'duplicator-pro') . ":</b>&nbsp; '{$test}' <br/>";
echo '<div class="scan-system-subnote">';
printf(
__(
'Issues might occur for larger packages when the [max_execution_time] value in the php.ini is too low.
The minimum recommended timeout is "%1$s" seconds or higher.
An attempt is made to override this value if the server allows it. A value of 0 (recommended) indicates that PHP has no time limits.',
'duplicator-pro'
),
DUPLICATOR_PRO_SCAN_TIMEOUT
);
echo "&nbsp;<i><a href='http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time' target='_blank'>[" . __('details', 'duplicator-pro') . "]</a></i>";
echo '</div>';
//MEMORY_LIMIT
$test = @ini_get("memory_limit");
echo '<hr size="1" /><span id="data-srv-php-minmemory"></span>&nbsp;<b>' . __('PHP Memory Limit', 'duplicator-pro') . ":</b>&nbsp; '{$test}' <br/>";
echo '<div class="scan-system-subnote">';
printf(
__(
'Issues might occur for larger packages when the [memory_limit] value in the php.ini is too low.
The minimum recommended memory limit is "%1$s" or higher. An attempt is made to override this value if the server allows it.
To manually increase the memory limit have a look at this %2$s[FAQ item]%3$s',
'duplicator-pro'
),
DUPLICATOR_PRO_MIN_MEMORY_LIMIT,
"<i><a href='" . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . "how-to-manage-server-resources-cpu-memory-disk' target='_blank'>",
"</a></i>"
);
echo '</div>';
//PHP 32-bit
$test = SnapUtil::getArchitectureString();
echo '<hr size="1" /><span id="data-srv-php-arch64bit"></span>&nbsp;<b>' . __('PHP 64 Bit Architecture', 'duplicator-pro') . ":</b>&nbsp; '{$test}' <br/>";
echo '<div class="scan-system-subnote">';
printf(
__(
'Servers that run a PHP 32-bit architecture are not capable of creating packages larger than 2GB.
If you need to create a package that is larger than 2GB in size talk with your host or server admin to change your version of PHP to 64-bit. %1$s[FAQ item]%2$s',
'duplicator-pro'
),
"<i><a href='" . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . "how-to-resolve-file-io-related-build-issues' target='_blank'>",
"</a></i>"
);
echo '</div>';
?><br/>
</div>
</div>
<!-- ======================
WP SETTINGS -->
<div class="scan-item">
<?php
if (!$archive_export_onlydb && isset($_POST['filter-on'])) {
$file_filter_data = array(
'filter-dir' => DUP_PRO_Archive::parsePathFilter(SnapUtil::sanitizeNSChars($_POST['filter-paths'])),
'filter-files' => DUP_PRO_Archive::parsePathFilter(SnapUtil::sanitizeNSChars($_POST['filter-paths'])),
);
$_SESSION['filter_data'] = $file_filter_data;
} else {
if (isset($_SESSION['filter_data'])) {
unset($_SESSION['filter_data']);
}
}
//TODO Login Need to go here
$core_dir_included = array();
$core_files_included = array();
//by default fault
$core_dir_notice = false;
$core_file_notice = false;
if (!$archive_export_onlydb && isset($_POST['filter-on']) && isset($_POST['filter-paths'])) {
//findout matched core directories
$filter_dirs = DUP_PRO_Archive::parsePathFilter(SnapUtil::sanitizeNSChars($_POST['filter-paths']), true);
// clean possible blank spaces before and after the paths
for ($i = 0; $i < count($filter_dirs); $i++) {
$filter_dirs[$i] = trim($filter_dirs[$i]);
$filter_dirs[$i] = (substr($filter_dirs[$i], -1) == "/") ? substr($filter_dirs[$i], 0, strlen($filter_dirs[$i]) - 1) : $filter_dirs[$i];
}
$core_dir_included = array_intersect($filter_dirs, DUP_PRO_U::getWPCoreDirs());
$core_dir_notice = !empty($core_dir_included);
//find out core files
$filter_files = DUP_PRO_Archive::parsePathFilter(SnapUtil::sanitizeNSChars($_POST['filter-paths']), true);
// clean possible blank spaces before and after the paths
for ($i = 0; $i < count($filter_files); $i++) {
$filter_files[$i] = trim($filter_files[$i]);
}
$core_files_included = array_intersect($filter_files, DUP_PRO_U::getWPCoreFiles());
$core_file_notice = !empty($core_files_included);
}
?>
<div class='title' onclick="DupPro.Pack.toggleScanItem(this);">
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('WordPress', 'duplicator-pro'); ?></div>
<div id="data-srv-wp-all"></div>
</div>
<div class="info">
<?php
//VERSION CHECK
echo '<span id="data-srv-wp-version"></span>&nbsp;<b>' . __('WordPress Version', 'duplicator-pro') . ":</b>&nbsp; '{$wp_version}' <br/>";
echo '<div class="scan-system-subnote">';
printf(
__(
'It is recommended to have a version of WordPress that is greater than %1$s.
Older version of WordPress can lead to migration issues and are a security risk.
If possible please update your WordPress site to the latest version.',
'duplicator-pro'
),
DUPLICATOR_PRO_SCAN_MIN_WP
);
echo '</div>';
//CORE FILES
echo '<hr size="1" /><span id="data-srv-wp-core"></span>&nbsp;<b>' . __('Core Files', 'duplicator-pro') . "</b> <br/>";
$filter_text = "";
if ($core_dir_notice) {
echo '<div id="data-srv-wp-core-missing-dirs">';
echo wp_kses(__("The core WordPress paths below will <u>not</u> be included in the archive. These paths are required for WordPress to function!", 'duplicator-pro'), array('u' => array()));
echo "<br/>";
foreach ($core_dir_included as $core_dir) {
echo '&nbsp; &nbsp; <b><i class="fa fa-exclamation-circle scan-warn"></i>&nbsp;' . $core_dir . '</b><br/>';
}
echo '</small><br/>';
echo '</div>';
$filter_text = "directories";
}
if ($core_file_notice) {
echo '<div id="data-srv-wp-core-missing-dirs">';
echo wp_kses(__("The core WordPress file below will <u>not</u> be included in the archive. This file is required for WordPress to function!", 'duplicator-pro'), array('u' => array()));
echo "<br/>";
foreach ($core_files_included as $core_file) {
echo '&nbsp; &nbsp; <b><i class="fa fa-exclamation-circle scan-warn"></i>&nbsp;' . $core_file . '</b><br/>';
}
echo '</div><br/>';
$filter_text .= (strlen($filter_text) > 0) ? " and file" : "files";
}
if (strlen($filter_text) > 0) {
echo '<div class="scan-system-subnote">';
printf(
__(
'Note: Please change the %1$s filters if you wish to include the WordPress core files
otherwise the data will have to be manually copied to the new location for the site to function properly.',
'duplicator-pro'
),
$filter_text
);
echo '</div>';
}
if (!$core_dir_notice && !$core_file_notice) {
echo '<div class="scan-system-subnote">';
esc_html_e(
"If the scanner is unable to locate the wp-config.php file in the root directory, then you will need to manually copy it to its new location.
This check will also look for core WordPress paths that should be included in the archive for WordPress to work correctly.",
'duplicator-pro'
);
echo '</div>';
}
if (!is_multisite()) {
//Normal Site
echo '<hr size="1" /><span><div class="dup-scan-good"><i class="fa fa-check"></i></div></span>&nbsp;<b>' . __('Multisite: N/A', 'duplicator-pro') . "</b> <br/>";
echo '<div class="scan-system-subnote">';
esc_html_e('Multisite was not detected on this site. It is currently configured as a standard WordPress site.', 'duplicator-pro');
echo "&nbsp;<i><a href='https://codex.wordpress.org/Create_A_Network' target='_blank'>[" . __('details', 'duplicator-pro') . "]</a></i>";
echo '</div>';
} elseif (License::can(License::CAPABILITY_MULTISITE_PLUS)) {
//MU Gold
echo '<hr size="1" /><span><div class="dup-scan-good"><i class="fa fa-check"></i></div></span>&nbsp;<b>' . __('Multisite: Detected', 'duplicator-pro') . "</b> <br/>";
echo '<div class="scan-system-subnote">';
esc_html_e('This license level has full access to all Multisite Plus+ features.', 'duplicator-pro');
echo '</div>';
} else {
//MU Personal, Freelancer
echo '<hr size="1" /><span><div class="dup-scan-warn"><i class="fa fa-exclamation-triangle fa-sm"></i></div></span>&nbsp;';
echo '<b>' . __('Multisite: Detected', 'duplicator-pro') . "</b> <br/>";
echo '<div class="scan-system-subnote">';
printf(
esc_html__(
'Duplicator Pro is at the %1$s license level which allows for backups and migrations of an entire Multisite network.&nbsp;',
'duplicator-pro'
),
License::getLicenseToString()
);
echo '<br>';
_e("To unlock all <b>Multisite Plus</b> features please upgrade the license before building a package.", 'duplicator-pro');
echo '<br/>';
echo "<a href='" . esc_url(License::getUpsellURL()) . "' target='_blank'>" . __('Upgrade Here', 'duplicator-pro') . "</a>&nbsp;|&nbsp;";
echo "&nbsp;<a href='" . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . "how-does-duplicator-handle-multisite-support' target='_blank'>"
. __('Multisite Plus Feature Overview', 'duplicator-pro') . "</a>";
echo '</div>';
}
?>
</div>
</div>
<!-- ======================
Restore only package -->
<div id="migration-status-scan-item" class="scan-item">
<div class='title' onclick="DupPro.Pack.toggleScanItem(this);">
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Import Status', 'duplicator-pro');?></div>
<div id="data-arc-status-migratepackage"></div>
</div>
<div class="info">
<script id="hb-migrate-package-result" type="text/x-handlebars-template">
<div class="container">
<div class="data">
{{#if ARC.Status.PackageIsNotImportable}}
<hr>
<p>
<span class="maroon">
<?php esc_html_e("This package is not be compatible with", 'duplicator-pro'); ?>
<i data-tooltip-title="<?php esc_attr_e("Drag and Drop Import", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_html_e('The Drag and Drop import method is a new way to migrate packages you can find under Duplicator Pro > Tools > Import.', 'duplicator-pro'); ?>">
<u><?php esc_html_e("Drag and Drop import", 'duplicator-pro'); ?></u>.&nbsp;
</i>
<?php esc_html_e("However it can still be used it to perform a database migration.", 'duplicator-pro'); ?>
</span>
{{#if ARC.Status.IsDBOnly}}
<?php
esc_attr_e(
"Database only packages can only be installed via the installer.php file.
The Drag and Drop interface only processes packages that have all WordPress core directories and all database tables.",
'duplicator-pro'
);
?>
{{else}}
<?php esc_attr_e("To make the package compatible with Drag and Drop import don't filter any tables or core directories.", 'duplicator-pro'); ?>
{{/if}}
</p>
{{#if ARC.Status.HasFilteredCoreFolders}}
<p>
<b><?php esc_attr_e("FILTERED CORE DIRS:", 'duplicator-pro'); ?></b>
</p>
<ol>
{{#each ARC.FilteredCoreDirs as |dir|}}
<li>{{dir}} </li>
{{/each}}
</ol>
{{/if}}
{{#if ARC.Status.HasFilteredSiteTables}}
<b><?php esc_attr_e("FILTERED SITE TABLES:", 'duplicator-pro'); ?></b>
<div class="dup-scan-files-migrae-status">
<ol>
{{#each DB.FilteredTables as |table|}}
<li>{{table}} </li>
{{/each}}
</ol>
</div>
{{/if}}
{{else}}
<?php esc_html_e("The package you are about to create is compatible with Drag and Drop import.", 'duplicator-pro'); ?>
{{/if}}
</div>
</div>
</script>
<div id="migrate-package-result"></div>
</div>
</div>
<script>
(function ($)
{
//Ints the various server data responses from the scan results
DupPro.Pack.intServerData = function(data)
{
$('#data-srv-php-websrv').html(DupPro.Pack.setScanStatus(data.SRV.PHP.websrv));
$('#data-srv-php-openbase').html(DupPro.Pack.setScanStatus(data.SRV.PHP.openbase));
$('#data-srv-php-maxtime').html(DupPro.Pack.setScanStatus(data.SRV.PHP.maxtime));
$('#data-srv-php-minmemory').html(DupPro.Pack.setScanStatus(data.SRV.PHP.minMemory));
$('#data-srv-php-arch64bit').html(DupPro.Pack.setScanStatus(data.SRV.PHP.arch64bit));
$('#data-srv-php-mysqli').html(DupPro.Pack.setScanStatus(data.SRV.PHP.mysqli));
$('#data-srv-php-openssl').html(DupPro.Pack.setScanStatus(data.SRV.PHP.openssl));
$('#data-srv-php-allowurlfopen').html(DupPro.Pack.setScanStatus(data.SRV.PHP.allowurlfopen));
$('#data-srv-php-curlavailable').html(DupPro.Pack.setScanStatus(data.SRV.PHP.curlavailable));
$('#data-srv-php-version').html(DupPro.Pack.setScanStatus(data.SRV.PHP.version));
$('#data-srv-php-all').html(DupPro.Pack.setScanStatus(data.SRV.PHP.ALL));
//Wordpress
$('#data-srv-wp-version').html(DupPro.Pack.setScanStatus(data.SRV.WP.version));
$('#data-srv-wp-core').html(DupPro.Pack.setScanStatus(data.SRV.WP.core));
$('#data-srv-wp-all').html(DupPro.Pack.setScanStatus(data.SRV.WP.ALL));
}
})(jQuery);
</script>

View File

@@ -0,0 +1,8 @@
<?php
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
?>
<div id="dup-pro-ajax-loader" >
<div id="dup-ajax-loader-img-wrapper" >
<img src="<?php echo esc_url(DUPLICATOR_PRO_PLUGIN_URL . '/assets/img/logo-black.svg'); ?>" alt="<?php _e('wait ...', 'duplicator-pro'); ?>">
</div>
</div>

View File

@@ -0,0 +1,316 @@
<?php
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Utils\Settings\MigrateSettings;
/* FOR PERSONAL LICENSE JUST SHOW MESSAGE */
if (!License::can(License::CAPABILITY_IMPORT_SETTINGS)) : ?>
<div class="width-large" >
<p>
<?php _e(
"The migrate settings screen allows you to import or export Duplicator Pro settings from one site to another.",
'duplicator-pro'
); ?>
</p>
<p>
<?php _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
printf(
__(
'This option isn\'t available at the <b>%1$s</b> license level.',
'duplicator-pro'
),
License::getLicenseToString()
);
?>
<b>
<?php
printf(
_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>
</p>
</div>
<?php else :
/* LET'S PERFORM FREELANCE+ SETTINGS */
$nonce = wp_create_nonce('duplicator_pro_import_export_settings');
$view_state = DUP_PRO_UI_ViewState::getArray();
$ui_css_export_panel = (isset($view_state['dpro-tools-export-panel']) && $view_state['dpro-tools-export-panel']) ? 'display:block' : 'display:block';
$ui_css_import_panel = (isset($view_state['dpro-tools-import-panel']) && $view_state['dpro-tools-import-panel']) ? 'display:block' : 'display:block';
// POST BACK
$_REQUEST['action'] = !empty($_REQUEST['action']) ? $_REQUEST['action'] : 'display';
$error_message = null;
$success_message = null;
switch ($_REQUEST['action']) {
case 'dpro-export':
case 'dpro-import':
try {
if (MigrateSettings::import($_FILES['import-file']['tmp_name'], $_POST['import-opts']) == false) {
throw new Exception('Import failed.');
}
$success_message = 'Successfully imported.';
} catch (Exception $ex) {
$error_message = 'Import Error: ' . $ex->getMessage() . "<br>\n" . $ex->getFile() . ':' . $ex->getLine();
}
break;
}
?>
<style>
<?php echo isset($css_hide_msg) ? $css_hide_msg : ''; ?>
div.dup-box {margin-top:20px}
div#message {margin:0px 0px 10px 0px}
div.success {color:#4A8254}
div.failed {color:#BB1506}
table.dpro-check-tbl td {padding:5px 30px 10px 10px}
div#message {margin-top:10px !important}
div#TB_ajaxContent p {font-size:14px !important}
</style>
<?php
if ($error_message !== null) {
echo "<div id='message' class='below-h2 error'><p>{$error_message}</p></div>";
} elseif ($success_message !== null) {
echo "<div id='message' class='below-h2 updated'><p>{$success_message}</p></div>";
}
?>
<br/>
<?php
esc_html_e(
"The migrate settings screen allows you to import or export Duplicator Pro settings from one site to another.
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'
); ?>
<br>
<!-- ==============================
EXPORT -->
<!-- action is unnecessary, uses ajax -->
<form id="dup-tools-form-export" method="post">
<?php wp_nonce_field('dpro_tools_data_export'); ?>
<input type="hidden" name="action" value="dpro-export">
<div class="dup-box">
<div class="dup-box-title">
<i class="fa fa-upload"></i>
<?php esc_html_e("Export Settings", 'duplicator-pro') ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Export Settings', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dpro-tools-export-panel" style="<?php echo esc_attr($ui_css_export_panel); ?>">
<?php
esc_html_e(
"Exports all schedules, storage locations, templates and settings from this Duplicator Pro instance into a downloadable export file.",
'duplicator-pro'
);
?>
<br/>
<?php
esc_html_e(
"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'
);
?>
<br/><br/><br/>
<input type="button" class="button button-primary" value="<?php esc_attr_e("Export Data", 'duplicator-pro'); ?>" onclick="return DupPro.Tools.ExportDialog();" />
<br/><br/>
</div>
</div>
</form>
<!-- ==============================
IMPORT -->
<form enctype="multipart/form-data" id="dup-tools-form-import" action="<?php echo ControllersManager::getCurrentLink(); ?>" method="post" data-parsley-validate data-parsley-ui-enabled="true" >
<?php wp_nonce_field('dpro_tools_data_import'); ?>
<input type="hidden" name="action" value="dpro-import">
<div class="dup-box">
<div class="dup-box-title">
<i class="fa fa-download"></i>
<?php esc_html_e("Import Settings", 'duplicator-pro'); ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Import Settings', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dpro-tools-import-panel" style="<?php echo esc_attr($ui_css_import_panel); ?>" >
<?php _e('Import settings from another Duplicator Pro plugin into this instance of Duplicator Pro.', 'duplicator-pro'); ?>
<br>
<?php _e('Schedule, storage and template data will be appended to current data, while existing settings will be replaced.', 'duplicator-pro'); ?>
<br>
<b>
<?php _e('For security reasons, capabilities, license data and license visibility will not be imported.', 'duplicator-pro'); ?>
</b>
<br>
<i>
<?php
_e(
"Schedules depend on storage and templates so importing schedules will require that storage and templates be checked.",
'duplicator-pro'
); ?>
</i>
<br/>
<br/>
<br/>
<label for="import-file"><b><?php esc_html_e("Choose Duplicator Data File", 'duplicator-pro'); ?></b> </label><br/>
<input type="file" accept=".dup" name="import-file" id="import-file" required="true" />
<br/><br/>
<b><?php esc_html_e("Include in Import", 'duplicator-pro'); ?>:</b>
<table class="dpro-check-tbl">
<tr>
<td>
<input onclick="DupPro.Tools.ChangeImportButtonState();DupPro.Tools.SchedulesClicked();" type="checkbox" name="import-opts[]" id="import-schedules" value="schedules" />
<label for="import-schedules"><?php esc_html_e("Schedules", 'duplicator-pro'); ?></label>
</td>
<td>
<input onclick="DupPro.Tools.ChangeImportButtonState();" type="checkbox" name="import-opts[]" id="import-storages" value="storages" />
<label for="import-storages"><?php esc_html_e("Storage", 'duplicator-pro'); ?></label>
</td>
<td>
<input onclick="DupPro.Tools.ChangeImportButtonState();" type="checkbox" name="import-opts[]" id="import-templates" value="templates" />
<label for="import-templates"><?php esc_html_e("Templates", 'duplicator-pro'); ?></label>
</td>
</tr>
<tr>
<td colspan="3">
<input onclick="DupPro.Tools.ChangeImportButtonState();" type="checkbox" name="import-opts[]" id="import-settings" value="settings" />
<label for="import-settings"><?php esc_html_e("Settings", 'duplicator-pro'); ?></label>
</td>
</tr>
</table>
<br/>
<input id="import-button" type="button" class="button button-primary" value="<?php esc_attr_e("Import Data", 'duplicator-pro'); ?>" onclick="return DupPro.Tools.ImportDialog();" disabled/>
<br/><br/>
</div>
</div>
</form>
<br/><br/>
<?php add_thickbox(); ?>
<!-- EXPORT DIALOG -->
<div id="modal-window-export" style="display:none;">
<h2><?php esc_html_e("Export Duplicator Pro Data?", 'duplicator-pro') ?></h2>
<p>
<?php esc_html_e("This process will:", 'duplicator-pro') ?><br/><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 style="color:#BB1506"><i class="fas fa-exclamation-triangle fa-sm"></i></i> <?php esc_html_e("For security purposes, restrict access to this file and delete after use.", 'duplicator-pro'); ?></span> <br/>
<br/>
<?php esc_html_e("Click the 'Run Export' button to generate and download the export file.", 'duplicator-pro') ?><br/><br/>
</p>
<div style="position:absolute; right:10px; bottom: 10px">
<input type="button" class="button" value="<?php esc_attr_e("Run Export", 'duplicator-pro') ?>" onclick="DupPro.Tools.ExportProcess();setTimeout(function() { tb_remove(); }, 4000);" />
<input type="button" class="button" value="<?php esc_attr_e("Cancel", 'duplicator-pro') ?>" onclick="tb_remove();" />
</div>
</div>
<!-- IMPORT DIALOG -->
<div id="modal-window-import" style="display:none;">
<h2><?php esc_html_e("Import Duplicator Pro Data?", 'duplicator-pro') ?></h2>
<p>
<?php esc_html_e("This process will:", 'duplicator-pro') ?><br/><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'); ?> <br/></span>
<br/>
<?php esc_html_e("Click the 'Run Import' button to process the import file.", 'duplicator-pro') ?><br/><br/>
</p>
<div style="position:absolute; right:10px; bottom: 10px">
<input type="button" class="button" value="<?php esc_attr_e("Run Import", 'duplicator-pro') ?>" onclick="DupPro.Tools.ImportProcess();" />
<input type="button" class="button" value="<?php esc_attr_e("Cancel", 'duplicator-pro') ?>" onclick="tb_remove();" />
</div>
</div>
<script>
DupPro.Tools.ExportProcess = function ()
{
var actionLocation = ajaxurl + '?action=duplicator_pro_export_settings' + '&nonce=' + '<?php echo $nonce; ?>';
location.href = actionLocation;
}
DupPro.Tools.ExportDialog = function ()
{
var url = "#TB_inline?width=610&height=250&inlineId=modal-window-export";
tb_show("<?php esc_html_e("Export Data", 'duplicator-pro') ?>", url);
return false;
}
DupPro.Tools.ImportProcess = function ()
{
jQuery('#dup-tools-form-import').submit();
}
DupPro.Tools.ImportDialog = function ()
{
var url = "#TB_inline?width=610&height=300&inlineId=modal-window-import";
tb_show("<?php esc_html_e("Import Data", 'duplicator-pro') ?>", url);
return false;
}
//PAGE INIT
jQuery(document).ready(function ($)
{
DupPro.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);
}
DupPro.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;
}
}
$("#dpro-tools-import-panel").on("change", "#import-file", function() { DupPro.Tools.ChangeImportButtonState(); });
});
</script>
<?php endif; ?>

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,529 @@
<?php
defined("ABSPATH") or die("");
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Libs\Snap\SnapUtil;
use Duplicator\Models\BrandEntity;
// 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;
});
$brand_list_url = ControllersManager::getCurrentLink(array('view' => 'list'));
$brand_edit_url = ControllersManager::getCurrentLink(array('view' => 'edit'));
$was_updated = false;
$acceptedActions = array(
'new',
'edit',
'save',
'default',
);
//Set proper ID
$brandId = SnapUtil::filterInputRequest('id', FILTER_VALIDATE_INT, [ 'options' => ['default' => 0]]);
$brandAction = !empty($_REQUEST['action']) && in_array($_REQUEST['action'], $acceptedActions) ? $_REQUEST['action'] : 'new';
if (
(isset($_REQUEST['brand']) && $_REQUEST['brand'] == 'default') ||
($brandId <= 0 && !in_array($brandAction, array('new', 'save')))
) {
$brandAction = 'default';
}
switch ($brandAction) {
case 'new':
$brand = new BrandEntity();
$brand->name = __('New Brand', 'duplicator-pro');
break;
case 'default':
$brand = BrandEntity::getDefaultBrand();
$brands = BrandEntity::getAllWithDefault();
break;
case 'edit':
// Redirect to new brand if wrong ID is provided
$editId = SnapUtil::filterInputRequest('id', FILTER_VALIDATE_INT, array('options' => array('default' => -1)));
if (($brand = BrandEntity::getById($editId)) === false) {
$redirect_url = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND,
[
'view' => 'edit',
'action' => 'new',
]
);
exit('
<h1>' . __('This brand is not found or deleted. Please create new one.', 'duplicator-pro') . '</h1>
<meta http-equiv="refresh" content="0; url=' . $redirect_url . '">
<script type="text/javascript">
window.location.href = "' . $redirect_url . '"
</script>
');
}
break;
case 'save':
DUP_PRO_U::verifyNonce($_POST['_wpnonce'], 'duplicator-pro-brand-edit');
$was_updated = true;
$saveId = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT, array('options' => array('default' => -1)));
if (($brand = BrandEntity::getById($saveId)) === false) {
$brand = new BrandEntity();
}
$brand->name = DUP_PRO_U::setVal(stripslashes($_POST['name']), __('New Brand', 'duplicator-pro'));
$brand->setAttachments(DUP_PRO_U::isEmpty((isset($_POST['attachments']) ? $_POST['attachments'] : array()), array()));
$brand->notes = DUP_PRO_U::setVal(stripslashes($_POST['notes']), '');
$brand->logo = stripcslashes(DUP_PRO_U::setVal($_POST['logo'], ''));
$brand->save();
break;
default:
$brand = new BrandEntity();
break;
}
// DEBUG
//echo '<pre>',print_r($_POST),'</pre><hr>';
//$a = BrandEntity::get_active();
//echo '<pre>',print_r($a),'</pre><hr>';
?>
<style>
#dup-storage-form input[type="text"], input[type="password"] { width: 250px;}
#dup-storage-form input#name {width:100%; max-width: 500px}
#dup-storage-form input#_local_storage_folder {width:100% !important; max-width: 500px}
td.dpro-sub-title {padding:0; margin: 0}
td.dpro-sub-title b{padding:20px 0; margin: 0; display:block; font-size:1.25em;}
input#max_default_store_files {width:50px !important}
form#dpro-package-brand-form {padding: 0}
form#dpro-package-brand-form input[type="text"] { width:350px;}
form#dpro-package-brand-form .readonly {background:transparent; border:none;}
textarea#brand-notes {width:350px;}
textarea#brand-logo {width:600px; height:120px; font-size: 12px}
textarea#brand-default-logo {width:600px;; height:50px; font-size: 12px}
div.style-guide-link {text-align: right; width: 100%; display: inline-block; margin:0 0 5px 0}
table.form-table {width:800px}
div.dpro-dlg-alert-txt {line-height: 20px; font-size: 14px !important}
div.preview-area {border:2px dashed #CDCDCD; width:95%; height:auto; background:#fff; font-family: Verdana,Arial,sans-serif;}
div.preview-box {border:1px solid #CDCDCD; border-radius: 5px; max-width: 750px; margin: 10px auto 0 auto; height:auto; border-bottom: 1px dashed #999}
div.preview-header {height:auto; background: #F1F1F1; box-shadow: 0 5px 3px -3px #999;}
div.preview-title {font-size:26px; padding:10px 0 7px 15px; font-weight: bold; min-height:30px; display: flex; justify-content: space-between;}
div.preview-content {padding:8px 15px 0 15px; clear:both}
div.preview-version {white-space:nowrap; color:#777; font-size:11px; font-style:italic; text-align:right; padding:0 15px 5px 0; line-height: 14px; font-weight:normal; align-self: center;}
div.preview-version a {color:#999}
div.preview-mode {text-align: right; color:#999; font-style: italic; font-size: 12px}
div.preview-steps {font-size: 22px; padding: 0 0 5px 0; border-bottom: 1px solid #D3D3D3; font-weight: bold; margin: 15px 0 20px 0;}
div.preview-steps b {color:red}
div#preview-logo {display: inline-block}
#preview-logo img {max-width:100%}
div.preview-notes {text-align:center; font-style: italic; font-size: 12px; margin:5px}
</style>
<?php
if ($was_updated) {
$update_message = 'Brand Saved!';
echo "<div class='notice notice-success is-dismissible dpro-wpnotice-box'><p>{$update_message}</p></div>";
}
?>
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar">
<tr>
<td></td>
<td>
<div class="btnnav">
<a href="<?php echo $brand_list_url; ?>" class="button"> <i class="far fa-image"></i> <?php esc_html_e('Brands', 'duplicator-pro'); ?></a>
<?php if ($brandAction != 'new') : ?>
<a href="<?php echo esc_url($brand_edit_url . "&action=new"); ?>" class="button"><?php esc_html_e('Add New', 'duplicator-pro'); ?></a>
<?php endif; ?>
</div>
</td>
</tr>
</table>
<hr class="dpro-edit-toolbar-divider"/>
<form id="dpro-package-brand-form" class="dup-monitored-form" action="<?php echo esc_url($brand_edit_url); ?>" method="post" data-parsley-ui-enabled="true">
<?php wp_nonce_field(Duplicator\Controllers\SettingsPageController::NONCE_ACTION); ?>
<input type="hidden" name="id" id="brand-id" value="<?php echo $brand->getId(); ?>" />
<input type="hidden" name="attachments" id="brand-attachments" value="<?php echo join(";", $brand->attachments); ?>" />
<input type="hidden" name="action" id="brand-action" value="<?php echo esc_attr($brandAction); ?>" />
<?php if ($brandAction == 'default') : ?>
<table class="provider form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Name", 'duplicator-pro'); ?></label></th>
<td><?php echo $brand->name; ?></td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Notes", 'duplicator-pro'); ?></label></th>
<td><?php echo $brand->notes; ?></td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Logo", 'duplicator-pro'); ?></label></th>
<td>
<div class="style-guide-link">
<a href="javascript:void" class="button button-small" onclick="DupPro.Brand.ShowStyleGuide();"><?php esc_html_e("Style Guide", 'duplicator-pro'); ?></a>
</div>
<textarea id="brand-default-logo" readonly="true"><?php echo $brand->logo; ?></textarea>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Activation", 'duplicator-pro'); ?></label></th>
<td><?php esc_html_e("This brand can be activated by using the installer brand drop-down during the package creation process. It can also be set via a template.", 'duplicator-pro'); ?></td>
</tr>
</table>
<i><?php esc_html_e("The default brand cannot be changed", 'duplicator-pro'); ?></i>
<br/><br/>
<?php else : ?>
<table class="provider form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Name", 'duplicator-pro'); ?></label></th>
<td>
<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>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Notes", 'duplicator-pro'); ?></label></th>
<td><textarea name="notes" id="brand-notes"><?php echo $brand->notes; ?></textarea></td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Logo", 'duplicator-pro'); ?></label></th>
<td>
<div class="style-guide-link">
<a href="javascript:void" class="button button-small" onclick="DupPro.Brand.ShowStyleGuide();"><?php esc_html_e("Style Guide", 'duplicator-pro'); ?></a>
</div>
<?php
wp_editor(
$brand->logo,
'brand-logo',
array(
'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' => array('buttons' => 'strong,em,i,ins,close,img,link'),
)
);
?>
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Activation", 'duplicator-pro'); ?></label></th>
<td>
<?php esc_html_e("This brand can be activated by using the installer brand drop-down during the package creation process. It can also be set via a template.", 'duplicator-pro'); ?>
</td>
</tr>
</table>
<?php endif; ?>
<!-- ================================
PREVIEW AREA -->
<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; ?>
</div>
<div class="preview-version">
<?php esc_html_e("version: ", 'duplicator-pro');
echo DUPLICATOR_PRO_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="fas fa-question-circle fa-sm"></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 echo __("Step <b>1</b> 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" />
<?php
wp_nonce_field('duplicator-pro-brand-edit');
?>
<button
id="dup-save-brand-button"
class="button button-primary" type="button"
onclick="return DupPro.Settings.Brand.Save();"
<?php
//$brands is only defined for the default brand
if (isset($brands) && $brand->getId() === $brands[0]->getId()) {
disabled(true);
}
?>
>
<?php esc_html_e('Save Brand', 'duplicator-pro'); ?>
</button>
</form>
<!-- ==========================================
THICK-BOX DIALOGS: -->
<?php
$guide_msg = __('The brandable area allows for a loose set of html and custom styling. Below is a general guide.', 'duplicator-pro');
$guide_msg .= '<br/><br/>';
$guide_msg .= __('- <b>Embed Image:</b><br/> &lt;img src="/wp-content/uploads/image.png /&gt; <br/><br/>', 'duplicator-pro');
$guide_msg .= __('- <b>Text Only:</b><br/> My Installer Name <br/><br/>', 'duplicator-pro');
$guide_msg .= __(
'- <b>Text &amp; Font-Awesome:</b><br/> &lt;i class="fa fa-cube"&gt;&lt;/i&gt;
My Company <br/><small>Note: <a href="http://fontawesome.io/icons/" target="_blank">Font-Awesome 4.7</a>
is the referenced library</small><br/><br/>',
'duplicator-pro'
);
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('Branding Guide', 'duplicator-pro');
$alert1->message = $guide_msg;
$alert1->width = 650;
$alert1->height = 350;
$alert1->initAlert();
$alert2 = new DUP_PRO_UI_Dialog();
$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 DUP_PRO_UI_Dialog();
$alert3->title = __('Brand Logo', 'duplicator-pro');
$alert3->message = __("WARNING: Brand logo have a wrong URL.", 'duplicator-pro');
$alert3->initAlert();
?>
<script>
DupPro.Brand = new Object();
/* Shows the style Guide */
DupPro.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>)
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) {
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
});
}
DupPro.Settings.Debounce;
DupPro.Settings.Brand.Save = function(e) {
clearTimeout(DupPro.Settings.Debounce);
if ($('#dpro-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');
}
});
}
DupPro.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
{
DupPro.UI.hasUnsavedChanges = false;
$('#dpro-package-brand-form').submit();
}
}, 200);
}
}
<?php if ($brandAction != 'default') : ?>
//INIT
$('#dpro-package-brand-form #brand-name').focus();
// Let's automate this things
DupPro.Settings.Automatization = function(e){
if (e.originalEvent !== undefined)
{
clearTimeout(DupPro.Settings.Debounce);
var $this = $("#dpro-package-brand-form #brand-logo"),
$debounce = 800
$button = $('#dpro-package-brand-form .button-primary');
// Smart debounce
if(e.currentTarget)
{
if($(e.currentTarget).hasClass('button')) $debounce = 5;
if($(e.currentTarget).hasClass('preview-area')) $debounce = 200;
}
// $button.find('.fa-circle-notch').remove();
// if(!$(e.currentTarget).hasClass('button')) $button.prop('disabled',true).prepend('<i class="fas fa-circle-notch fa-spin"></i> ');
DupPro.Settings.Debounce = setTimeout(function() {
var $value = $this.val();
// $button.prop('disabled',false).find('.fa-circle-notch').remove();
$this.val(strip_tags($value,'<a><i><b><u><em><ins><div><img><span><strong>'));
// Do preview
$("#dpro-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);
$("#dpro-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_PLUGIN_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) $("#dpro-package-brand-form #brand-attachments").val(path.join(';'));
}
},$debounce);
}
};
// On textarea change
$(document).on('change keyup paste input mouseout mouseover propertychange',"#dpro-package-brand-form #brand-logo", DupPro.Settings.Automatization);
// On other boxes
$(document).on('mouseover',"#dpro-package-brand-form .button-primary, #dpro-package-brand-form .preview-area", DupPro.Settings.Automatization);
<?php endif; ?>
});
</script>

View File

@@ -0,0 +1,387 @@
<?php
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Models\BrandEntity;
$brand_list_url = ControllersManager::getCurrentLink(array('view' => 'list'));
$brand_edit_url = ControllersManager::getCurrentLink(array('view' => 'edit'));
if (!empty($_REQUEST['action'])) {
//check_admin_referer(Duplicator\Controllers\SettingsPageController::NONCE_ACTION);
$action = $_REQUEST['action'];
switch ($action) {
case 'bulk-delete':
$brand_ids = $_REQUEST['selected_id'];
foreach ($brand_ids as $brand_id) {
BrandEntity::deleteById($brand_id);
}
break;
case 'delete':
$brand_id = (int) $_REQUEST['brand_id'];
BrandEntity::deleteById($brand_id);
break;
}
}
$brands = BrandEntity::getAllWithDefault();
$brand_count = count($brands);
?>
<style>
/*Detail Tables */
table.brand-tbl td {height: 45px}
table.brand-tbl a.name {font-weight: bold}
table.brand-tbl input[type='checkbox'] {margin-left: 5px}
table.brand-tbl div.sub-menu {margin: 5px 0 0 2px; display: none}
table tr.brand-detail {display:none; margin: 0;}
table tr.brand-detail td { padding: 3px 0 5px 20px}
table tr.brand-detail div {line-height: 20px; padding: 2px 2px 2px 15px}
table tr.brand-detail td button {margin:5px 0 5px 0 !important; display: block}
tr.brand-detail label {min-width: 150px; display: inline-block; font-weight: bold}
form#dup-brand-form {padding:0}
</style>
<div <?php echo (License::can(License::CAPABILITY_BRAND) ? "style='display:none'" : ""); ?>>
<h2><?php esc_html_e("Installer Branding", 'duplicator-pro') ?></h2>
<hr size="1"/>
<div style="width:850px">
<?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 package is built (example shown below).",
'duplicator-pro'
);
?>
<br/><br/>
<?php
printf(
__(
'This option isn\'t available at the <b>%1$s</b> license level.',
'duplicator-pro'
),
License::getLicenseToString()
);
?>
<b>
<?php
printf(
_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 DUPLICATOR_PRO_IMG_URL ?>/dpro-brand.png" style='' />
</div>
<br/><br/>
</div>
<!-- ====================
TOOL-BAR -->
<div <?php echo (License::can(License::CAPABILITY_BRAND) ? "" : "style='display:none'"); ?>>
<table class="dpro-edit-toolbar">
<tr>
<td>
<select id="bulk_action">
<option value="-1" selected="selected"><?php _e('Bulk Actions', 'duplicator-pro'); ?></option>
<option value="delete" title="<?php esc_attr_e('Delete selected brand endpoint(s)', 'duplicator-pro'); ?>"><?php _e('Delete', 'duplicator-pro'); ?></option>
</select>
<input type="button" class="button action" value="<?php esc_html_e("Apply", 'duplicator-pro') ?>" onclick="DupPro.Settings.Brand.BulkAction()">
</td>
<td>
<div class="btnnav">
<a href="javascript:void(0)" onclick="DupPro.Settings.Brand.AddNew()" class="button"><?php esc_html_e('Add New', 'duplicator-pro'); ?></a>
</div>
</td>
</tr>
</table>
<form id="dup-brand-form" action="<?php echo $brand_list_url; ?>" method="post">
<?php wp_nonce_field(Duplicator\Controllers\SettingsPageController::NONCE_ACTION); ?>
<input type="hidden" id="dup-brand-form-action" name="action" value=""/>
<input type="hidden" id="dup-selected-brand" name="brand_id" value="-1"/>
<!-- ====================
LIST ALL STORAGE -->
<table class="widefat brand-tbl">
<thead>
<tr>
<th style='width:10px;'><input type="checkbox" id="dpro-chk-all" title="Select all brand endpoints" onclick="DupPro.Settings.Brand.SetAll(this)"></th>
<th style='width:100%;'><?php esc_html_e('Name', 'duplicator-pro'); ?></th>
</tr>
</thead>
<tbody>
<?php
ob_start(); // Must transfer data after default brand item
$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 $brand->getId() ?>' class="brand-row<?php echo ($i % 2) ? ' alternate' : ''; ?>">
<td>
<?php if ($brand->editable) : ?>
<input name="selected_id[]" type="checkbox" value="<?php echo $brand->getId(); ?>" class="item-chk" />
<?php else : ?>
<input type="checkbox" disabled="disabled" />
<?php endif; ?>
</td>
<td>
<a href="javascript:void(0);" onclick="DupPro.Settings.Brand.Edit('<?php echo $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="DupPro.Settings.Brand.Edit('<?php echo $brand->getId(); ?>')"><?php esc_html_e('Edit', 'duplicator-pro') ?></a> |
<a href="javascript:void(0);" onclick="DupPro.Settings.Brand.View('<?php echo $brand->getId(); ?>');"><?php esc_html_e('Quick View', 'duplicator-pro') ?></a> |
<a href="javascript:void(0);" onclick="DupPro.Settings.Brand.Delete('<?php echo $brand->getId(); ?>');"><?php esc_html_e('Delete', 'duplicator-pro') ?></a>
</div>
<?php else : ?>
<div class="sub-menu">
<a href="javascript:void(0);" onclick="DupPro.Settings.Brand.Edit(0)"><?php esc_html_e('View', 'duplicator-pro') ?></a> |
<a href="javascript:void(0);" onclick="DupPro.Settings.Brand.View('<?php echo $brand->getId(); ?>');"><?php esc_html_e('Quick View', 'duplicator-pro') ?></a>
</div>
<?php endif; ?>
</td>
</tr>
<tr id='quick-view-<?php echo $brand->getId() ?>' class='<?php echo ($i % 2) ? 'alternate ' : ''; ?>brand-detail'>
<td colspan="3">
<b><?php esc_html_e('QUICK VIEW', 'duplicator-pro') ?></b> <br/>
<div>
<label><?php esc_html_e('Name', 'duplicator-pro') ?>:</label>
<?php echo esc_html($brand->name); ?>
</div>
<div>
<label><?php esc_html_e('Notes', 'duplicator-pro') ?>:</label>
<?php echo (strlen($brand->notes)) ? esc_html($brand->notes) : __('(no notes)', 'duplicator-pro'); ?>
</div>
<div>
<label><?php esc_html_e('Logo', 'duplicator-pro') ?>:</label>
<?php echo $brand->logo ?>
</div>
<button type="button" class="button" onclick="DupPro.Settings.Brand.View('<?php echo $brand->getId(); ?>');"><?php esc_html_e('Close', 'duplicator-pro') ?></button>
</td>
</tr>
<?php
endforeach;
$display_brand_list = ob_get_clean(); // save generated list into string
?>
<!-- DEFAULT BRAND ITEM -->
<tr id='main-view-<?php echo $brands[0]->getId(); ?>' class="brand-row">
<td>
<input type="checkbox" disabled="disabled" />
</td>
<td>
<a href="javascript:void(0);" onclick="DupPro.Settings.Brand.Edit(0)"><b><?php esc_html_e('Default', 'duplicator-pro'); ?></b></a>
<div class="sub-menu">
<a href="javascript:void(0);" onclick="DupPro.Settings.Brand.Edit(0)"><?php esc_html_e('View', 'duplicator-pro'); ?></a> |
<a href="javascript:void(0);" onclick="DupPro.Settings.Brand.View('<?php echo $brands[0]->getId(); ?>');"><?php esc_html_e('Quick View', 'duplicator-pro'); ?></a>
</div>
</td>
</tr>
<tr id="quick-view-<?php echo $brands[0]->getId() ?>" class="brand-detail">
<td colspan="3">
<b><?php esc_html_e('QUICK VIEW', 'duplicator-pro') ?></b> <br/>
<div>
<label><?php esc_html_e('Name', 'duplicator-pro') ?>:</label>
<?php echo $brands[0]->name ?>
</div>
<div>
<label><?php esc_html_e('Notes', 'duplicator-pro') ?>:</label>
<?php echo (strlen($brands[0]->notes)) ? $brands[0]->notes : __('(no notes)', 'duplicator-pro'); ?>
</div>
<div>
<label><?php esc_html_e('Logo', 'duplicator-pro') ?>:</label>
<?php echo $brands[0]->logo ?>
</div>
<button type="button" class="button" onclick="DupPro.Settings.Brand.View('<?php echo $brands[0]->getId(); ?>');"><?php esc_html_e('Close', 'duplicator-pro') ?></button>
</td>
</tr>
<!-- END DEFAULT BRAND ITEM -->
<!-- DYNAMIC BRAND ITEMS -->
<?php echo $display_brand_list; ?>
<!-- END DYNAMIC BRAND ITEMS -->
</tbody>
<tfoot>
<tr>
<th colspan="8" style="text-align:right; font-size:12px">
<?php echo __('Total', 'duplicator-pro') . ': ' . $brand_count; ?>
</th>
</tr>
</tfoot>
</table>
</form>
</div>
<!-- ==========================================
THICK-BOX DIALOGS: -->
<?php
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('Bulk Action Required', 'duplicator-pro');
$alert1->message = __('Please select an action from the "Bulk Actions" drop down menu!', 'duplicator-pro');
$alert1->initAlert();
$alert2 = new DUP_PRO_UI_Dialog();
$alert2->title = __('Selection Required', 'duplicator-pro');
$alert2->message = __('Please select at least one brand to delete!', 'duplicator-pro');
$alert2->initAlert();
$confirm1 = new DUP_PRO_UI_Dialog();
$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 = 'DupPro.Settings.Brand.BulkDelete()';
$confirm1->initConfirm();
$confirm2 = new DUP_PRO_UI_Dialog();
$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 = 'DupPro.Settings.Brand.DeleteThis(this)';
$confirm2->initConfirm();
$delete_nonce = wp_create_nonce('duplicator_pro_brand_delete');
?>
<script>
jQuery(document).ready(function ($) {
//Shows detail view
DupPro.Settings.Brand.AddNew = function ()
{
document.location.href = '<?php echo "{$brand_edit_url}&action=new"; ?>';
}
DupPro.Settings.Brand.Edit = function (id)
{
if (id == 0) {
document.location.href = '<?php echo "{$brand_edit_url}&action=default&id="; ?>' + id;
} else {
document.location.href = '<?php echo "{$brand_edit_url}&action=edit&id="; ?>' + id;
}
}
//Shows detail view
DupPro.Settings.Brand.View = function (id)
{
$('#quick-view-' + id).toggle();
$('#main-view-' + id).toggle();
}
//Delets a single record
DupPro.Settings.Brand.Delete = function (id)
{
<?php $confirm2->showConfirm(); ?>
$("#<?php echo $confirm2->getID(); ?>-confirm").attr('data-id', id);
}
DupPro.Settings.Brand.DeleteThis = function (e)
{
var id = $(e).attr('data-id');
jQuery("#dup-brand-form-action").val('delete');
jQuery("#dup-selected-brand").val(id);
jQuery("#dup-brand-form").submit()
}
// Creats a comma seperate list of all selected package ids
DupPro.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
DupPro.Settings.Brand.BulkDelete = function ()
{
var list = DupPro.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_pro_brand_delete',
brand_ids: list,
nonce: '<?php echo $delete_nonce; ?>'
},
}).done(function (data) {
$('#dup-brand-form').submit();
});
}
// Confirm bulk action
DupPro.Settings.Brand.BulkAction = function ()
{
var list = DupPro.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
DupPro.Settings.Brand.SetAll = function (chkbox) {
$('.item-chk').each(function () {
this.checked = chkbox.checked;
});
}
//Name hover show menu
$("tr.brand-row").hover(
function () {
$(this).find(".sub-menu").show();
},
function () {
$(this).find(".sub-menu").hide();
}
);
});
</script>

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,44 @@
<?php
/* @var $global DUP_PRO_Global_Entity */
defined("ABSPATH") or die("");
?>
<style>
input#package_mysqldump_path_found {margin-top:5px}
div.dup-feature-found {padding:0; color: green; display: inline-block;}
div.dup-feature-notfound {padding:5px; color: maroon; width:600px;}
input#_package_mysqldump_path {width:500px}
#dpro-ziparchive-mode-st, #dpro-ziparchive-mode-mt {height: 28px; padding-top:5px; display: none}
div.engine-radio {float: left; min-width: 100px}
div.engine-sub-opts {padding-top:10px}
div.engine-sub-opts fieldset {
border: 1px solid #999;
padding: 15px ;
line-height: 30px;
}
div.engine-sub-opts label {
display: inline-block;
min-width: 100px;
margin-bottom: 5px;
line-height: 30px !important;
}
div.engine-sub-opts input:not([type=checkbox]):not([type=radio]):not([type=button]),
div.engine-sub-opts select {
box-sizing: border-box;
min-width: 150px;
}
div#engine-details-match-message {display:none; margin: -5px 0 20px 220px; border: 1px solid silver; padding:5px 8px 5px 8px; background: #dfdfdf; border-radius: 5px; width:650px}
table#archive-build-schedule {display:none}
span#archive-build-schedule-icon {display:none}
form.dup-settings-pack-basic table.form-table {margin-bottom:50px}
</style>
<script>
DupPro.Settings.Brand = new Object();
</script>

View File

@@ -0,0 +1,100 @@
<?php
/* @var $global DUP_PRO_Global_Entity */
defined("ABSPATH") or die("");
use Duplicator\Core\Controllers\ControllersManager;
$nonce_action = 'duppro-settings-schedule-edit';
$action_updated = null;
$action_response = __("Schedule Settings Saved", 'duplicator-pro');
$global = DUP_PRO_Global_Entity::getInstance();
//SAVE RESULTS
if (!empty($_POST['action']) && $_POST['action'] == 'save') {
DUP_PRO_U::verifyNonce($_POST['_wpnonce'], $nonce_action);
$global->send_email_on_build_mode = (int)$_REQUEST['send_email_on_build_mode'];
$global->notification_email_address = stripslashes($_REQUEST['notification_email_address']);
$action_updated = $global->save();
}
?>
<style>
table.form-table tr td { padding-top: 25px; }
</style>
<form id="dup-settings-form" action="<?php echo ControllersManager::getCurrentLink(); ?>" method="post" data-parsley-validate>
<?php wp_nonce_field($nonce_action); ?>
<input type="hidden" name="action" value="save">
<?php if ($action_updated) : ?>
<div class="notice notice-success is-dismissible dpro-wpnotice-box"><p><?php echo $action_response; ?></p></div>
<?php endif; ?>
<!-- ===============================
SCHEDULE SETTINGS -->
<h3 class="title"><?php esc_html_e("Notifications", 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table">
<tr>
<th scope="row"><label><?php esc_html_e("Send Build Email", 'duplicator-pro'); ?></label></th>
<td>
<input
type="radio"
name="send_email_on_build_mode"
id="send_email_on_build_mode_never"
value="<?php echo DUP_PRO_Email_Build_Mode::No_Emails; ?>"
<?php checked($global->send_email_on_build_mode, DUP_PRO_Email_Build_Mode::No_Emails); ?>
>
<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"
value="<?php echo DUP_PRO_Email_Build_Mode::Email_On_Failure; ?>"
<?php checked($global->send_email_on_build_mode, DUP_PRO_Email_Build_Mode::Email_On_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"
value="<?php echo DUP_PRO_Email_Build_Mode::Email_On_All_Builds; ?>"
<?php checked($global->send_email_on_build_mode, DUP_PRO_Email_Build_Mode::Email_On_All_Builds); ?>
>
<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>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Email Address", 'duplicator-pro'); ?></label></th>
<td>
<input
style="display:block;margin-right:6px; width:25em;"
data-parsley-errors-container="#notification_email_address_error_container"
data-parsley-type="email"
type="email"
name="notification_email_address"
id="notification_email_address" value="<?php echo esc_attr($global->notification_email_address); ?>"
>
<p class="description"> <?php esc_html_e('Admin email will be used if empty.', 'duplicator-pro'); ?> </p>
<div id="notification_email_address_error_container" class="duplicator-error-container"></div>
</td>
</tr>
</table>
<p class="submit dpro-save-submit">
<input type="submit" name="submit" id="submit" class="button-primary" value="<?php esc_attr_e('Save Schedule Settings', 'duplicator-pro') ?>" style="display: inline-block;" />
</p>
</form>
<script>
jQuery(document).ready(function ($) {
//Data
});
</script>

View File

@@ -0,0 +1,53 @@
<?php
defined("ABSPATH") or die("");
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
?>
<?php TplMng::getInstance()->render('admin_pages/diagnostics/purge_orphans_message'); ?>
<?php TplMng::getInstance()->render('admin_pages/diagnostics/clean_tmp_cache_message'); ?>
<?php TplMng::getInstance()->render('parts/migration/migration-message'); ?>
<form id="dup-settings-form" action="<?php echo ControllersManager::getCurrentLink(); ?>" method="post">
<?php
include_once(DUPLICATOR____PATH . '/views/tools/diagnostics/inc.data.php');
include_once(DUPLICATOR____PATH . '/views/tools/diagnostics/inc.settings.php');
include_once(DUPLICATOR____PATH . '/views/tools/diagnostics/inc.validator.php');
include_once(DUPLICATOR____PATH . '/views/tools/diagnostics/inc.phpinfo.php');
?>
</form>
<?php
$deleteOptConfirm = new DUP_PRO_UI_Dialog();
$deleteOptConfirm->title = __('Are you sure you want to delete?', 'duplicator-pro');
$deleteOptConfirm->message = __('Delete this option value.', 'duplicator-pro');
$deleteOptConfirm->progressText = __('Removing, Please Wait...', 'duplicator-pro');
$deleteOptConfirm->jsCallback = 'DupPro.Settings.DeleteThisOption(this)';
$deleteOptConfirm->initConfirm();
$removeCacheConfirm = new DUP_PRO_UI_Dialog();
$removeCacheConfirm->title = __('This process will remove all build cache files.', 'duplicator-pro');
$removeCacheConfirm->message = __('Be sure no packages are currently building or else they will be cancelled.', 'duplicator-pro');
$removeCacheConfirm->progressText = $deleteOptConfirm->progressText;
$removeCacheConfirm->jsCallback = 'DupPro.Tools.ClearBuildCacheRun()';
$removeCacheConfirm->initConfirm();
?>
<script>
jQuery(document).ready(function ($) {
DupPro.Tools.removeInstallerFiles = function () {
window.location = <?php echo json_encode(ToolsPageController::getInstance()->getCleanFilesAcrtionUrl()); ?>;
return false;
};
DupPro.Tools.ClearBuildCache = function () {
<?php $removeCacheConfirm->showConfirm(); ?>
};
DupPro.Tools.ClearBuildCacheRun = function () {
window.location = <?php echo json_encode(ToolsPageController::getInstance()->getRemoveCacheActionUrl()); ?>;
};
});
</script>

View File

@@ -0,0 +1,123 @@
<?php
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\MigrationMng;
defined("ABSPATH") or die("");
global $wpdb;
$orphaned_filepaths = DUP_PRO_Server::getOrphanedPackageFiles();
$view_state = DUP_PRO_UI_ViewState::getArray();
$ui_css_data_panel = (isset($view_state['dup-settings-diag-opts-panel']) && $view_state['dup-settings-diag-opts-panel']) ? 'display:block' : 'display:none';
$ui_css_data_panel = (isset($_GET['orphanpurge']) && $_GET['orphanpurge'] == '1') ? 'display:block' : $ui_css_data_panel;
?>
<!-- ==============================
STORED DATA -->
<div class="dup-box">
<div class="dup-box-title">
<i class="fas fa-th-list fa-sm"></i>
<?php esc_html_e("Data Cleanup", 'duplicator-pro'); ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Stored Data', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dup-settings-diag-opts-panel" style="<?php echo esc_attr($ui_css_data_panel) ?>" >
<table class="dpro-reset-opts">
<tr valign="top">
<td>
<button
type="button"
class="dpro-store-fixed-btn button button-small"
id="dpro-remove-installer-files-btn"
onclick="DupPro.Tools.removeInstallerFiles()"
>
<?php esc_html_e("Delete Installation Files", 'duplicator-pro'); ?>
</button>
</td>
<td>
<?php esc_html_e("Removes all reserved installation files.", 'duplicator-pro'); ?>
<a href="javascript:void(0)" onclick="jQuery('#dpro-tools-delete-moreinfo').toggle()">[<?php esc_html_e("more info", 'duplicator-pro'); ?>]</a>
<br/>
<div id="dpro-tools-delete-moreinfo">
<p>
<?php
esc_html_e(
"Clicking on the 'Remove Installation Files' button will remove the following installation files.
These files are typically from a previous Duplicator install.
If you are unsure of the source, please validate the files.
These files should never be left on production systems for security reasons.
Below is a list of all the installation files used by Duplicator.
Please be sure these are removed from your server.",
'duplicator-pro'
);
?>
<p>
<p>
<?php
foreach (MigrationMng::getGenericInstallerFiles() as $instFileName) {
?>
<span class="success">
<?php echo esc_html($instFileName); ?>
</span><br>
<?php
}
?>
</p>
</div>
</td>
</tr>
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<tr valign="top">
<td>
<a
type="button"
class="dpro-store-fixed-btn button button-small"
href="<?php echo esc_url(ToolsPageController::getInstance()->getPurgeOrphanActionUrl()); ?>"
>
<?php esc_html_e("Delete Package Orphans", 'duplicator-pro'); ?>
</a>
</td>
<td>
<?php esc_html_e("Removes all package files NOT found in the packages screen.", 'duplicator-pro'); ?>
<a href="javascript:void(0)" onclick="jQuery('#dpro-tools-delete-orphans-moreinfo').toggle()">[<?php esc_html_e("more info", 'duplicator-pro'); ?>]</a>
<br/>
<div id="dpro-tools-delete-orphans-moreinfo">
<?php
if (count($orphaned_filepaths) > 0) {
esc_html_e(
"Clicking on the 'Delete Package Orphans' button will remove the following files.
Orphaned files are typically generated from previous installations of Duplicator.
They may also exist if they did not get properly removed when they were selected from the main packages screen.
The files below are no longer associated with active packages in the main Packages screen and should be safe to remove.
<b>IMPORTANT: Don't click button if you want to retain any of the following files:</b>",
'duplicator-pro'
);
echo "<br/><br/>";
foreach ($orphaned_filepaths as $filepath) {
echo "<div class='failed'><i class='fa fa-exclamation-triangle'></i> " . esc_html($filepath) . " </div>";
}
} else {
esc_html_e('No orphaned package files found.', 'duplicator-pro');
}
?>
</div>
</td>
</tr>
<tr>
<td>
<button type="button" class="dpro-store-fixed-btn button button-small" onclick="DupPro.Tools.ClearBuildCache()">
<?php esc_html_e("Clear Build Cache", 'duplicator-pro'); ?>
</button>
</td>
<td><?php esc_html_e('Removes all build data from:', 'duplicator-pro'); ?> [<?php echo esc_html(DUPLICATOR_PRO_SSDIR_PATH_TMP); ?>].</td>
</tr>
<?php } ?>
</table>
</div>
</div>
<br/>

View File

@@ -0,0 +1,32 @@
<?php
use Duplicator\Libs\Snap\SnapUtil;
defined("ABSPATH") or die("");
ob_start();
SnapUtil::phpinfo();
$serverinfo = preg_replace('/.*<body>(.*?)<\/body>.*/s', '$1', ob_get_clean());
?>
<!-- ==============================
PHP INFORMATION -->
<div class="dup-box">
<div class="dup-box-title">
<i class="fa fa-info-circle"></i>
<?php esc_html_e("PHP Information", 'duplicator-pro'); ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('PHP Information', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" style="display:none">
<div id="dup-phpinfo" style="width:95%">
<?php
echo "<div id='dpro-phpinfo'>{$serverinfo}</div>";
$serverinfo = null;
?>
</div><br/>
</div>
</div>
<br/>

View File

@@ -0,0 +1,358 @@
<?php
/**
* Standard: PSR-2 (almost)
*
* @link http://www.php-fig.org/psr/psr-2
*
* @package DUP_PRO
* @subpackage classes/package
* @copyright (c) 2019, Snapcreek LLC
* @license https://opensource.org/licenses/GPL-3.0 GNU Public License
* @since 1.0.0
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Addons\ProBase\LicensingController;
use Duplicator\Libs\Shell\Shell;
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Libs\Snap\SnapUtil;
global $wp_version;
$view_state = DUP_PRO_UI_ViewState::getArray();
$ui_css_srv_panel = (isset($view_state['dup-settings-diag-srv-panel']) && $view_state['dup-settings-diag-srv-panel']) ? 'display:block' : 'display:none';
$dbvar_maxtime = DUP_PRO_DB::getVariable('wait_timeout');
$dbvar_maxpacks = DUP_PRO_DB::getVariable('max_allowed_packet');
$dbvar_maxtime = is_null($dbvar_maxtime) ? __("unknow", 'duplicator-pro') : $dbvar_maxtime;
$dbvar_maxpacks = is_null($dbvar_maxpacks) ? __("unknow", 'duplicator-pro') : $dbvar_maxpacks;
$home_path = duplicator_pro_get_home_path();
$space = SnapIO::diskTotalSpace($home_path);
$space_free = SnapIO::diskFreeSpace($home_path);
if ($space > 0 && $space_free >= 0) {
$perc = round((100 / $space) * $space_free, 2);
} else {
$perc = -1;
}
$mysqldumpPath = DUP_PRO_DB::getMySqlDumpPath();
$mysqlDumpSupport = ($mysqldumpPath) ? $mysqldumpPath : 'Path Not Found';
$client_ip_address = DUP_PRO_Server::getClientIP();
$error_log_path = ini_get('error_log');
$timezone_string = function_exists('wp_timezone_string') ? wp_timezone_string() : __('Unknown', 'duplicator-pro');
?>
<!-- ==============================
SERVER SETTINGS -->
<div class="dup-box">
<div class="dup-box-title">
<i class="fas fa-tachometer-alt"></i>
<?php esc_html_e("Server Settings", 'duplicator-pro') ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Server Settings', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dup-settings-diag-srv-panel" style="<?php echo esc_attr($ui_css_srv_panel); ?>">
<table class="widefat" cellspacing="0">
<tr>
<td class='dpro-settings-diag-header' colspan="2"><?php esc_html_e("General", 'duplicator-pro'); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Duplicator Version", 'duplicator-pro'); ?></td>
<td>
<?php echo esc_html(DUPLICATOR_PRO_VERSION); ?> -
<small>
<i>
<a href="<?php echo esc_url(LicensingController::getForceUpgradeCheckURL()); ?>">
<?php esc_html_e("Check WordPress updates", 'duplicator-pro'); ?>
</a>
</i>
</small>
</td>
</tr>
<tr>
<td><?php esc_html_e("Operating System", 'duplicator-pro'); ?></td>
<td><?php echo esc_html(PHP_OS); ?></td>
</tr>
<tr>
<td><?php _e('Timezone', 'duplicator-pro'); ?></td>
<td><?php echo esc_html($timezone_string); ?> &nbsp; <small><i>This is a <a href='options-general.php'>WordPress setting</a></i></small></td>
</tr>
<tr>
<td><?php _e('Server Time', 'duplicator-pro'); ?></td>
<td><?php echo esc_html(current_time("Y-m-d H:i:s")); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Web Server", 'duplicator-pro'); ?></td>
<td><?php echo esc_html($_SERVER['SERVER_SOFTWARE']); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Loaded PHP INI", 'duplicator-pro'); ?></td>
<td><?php echo php_ini_loaded_file(); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Server IP", 'duplicator-pro'); ?></td>
<?php
if (isset($_SERVER['SERVER_ADDR'])) {
$server_address = $_SERVER['SERVER_ADDR'];
} elseif (isset($_SERVER['SERVER_NAME']) && function_exists('gethostbyname')) {
$server_address = gethostbyname($_SERVER['SERVER_NAME']);
} else {
$server_address = __("Can't detect", 'duplicator-pro');
}
?>
<td><?php echo esc_html($server_address); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Outbound IP", 'duplicator-pro'); ?></td>
<?php
$outbound_ip = DUP_PRO_Server::getOutboundIP();
if ($outbound_ip === false) {
$outbound_ip = __("Can't detect", 'duplicator-pro');
}
?>
<td><?php echo esc_html($outbound_ip); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Client IP", 'duplicator-pro'); ?></td>
<td><?php echo esc_html($client_ip_address); ?></td>
</tr>
<tr style="font-style: italic">
<td>
<?php esc_html_e("Host", 'duplicator-pro'); ?><br/>
<small><?php esc_html_e("version scope", 'duplicator-pro'); ?></small>
</td>
<td>
<?php
$url = parse_url(get_site_url(), PHP_URL_HOST);
echo esc_url($url);
?>
<br/>
<small><?php echo "WP-" . esc_html($wp_version) . ", DP-" . esc_html(DUPLICATOR_PRO_VERSION) . " | PHP-" . esc_html(phpversion()) . ', DB-' . esc_html(DUP_PRO_DB::getVersion()); ?></small>
</td>
</tr>
<tr>
<td class='dpro-settings-diag-header' colspan="2">WordPress</td>
</tr>
<tr>
<td><?php esc_html_e("Version", 'duplicator-pro'); ?></td>
<td><?php echo esc_html($wp_version); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Langugage", 'duplicator-pro'); ?></td>
<td><?php bloginfo('language'); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Charset", 'duplicator-pro'); ?></td>
<td><?php bloginfo('charset'); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Memory Limit ", 'duplicator-pro'); ?></td>
<td><?php echo esc_html(WP_MEMORY_LIMIT); ?> (<?php
esc_html_e("Max", 'duplicator-pro');
echo '&nbsp;' . esc_html(WP_MAX_MEMORY_LIMIT);
?>)</td>
</tr>
<tr>
<td><?php esc_html_e("Managed hosting ", 'duplicator-pro'); ?></td>
<td><?php
echo (DUP_PRO_Custom_Host_Manager::getInstance()->isManaged() === false) ?
__('No managed hosting detected', 'duplicator-pro') :
implode(', ', DUP_PRO_Custom_Host_Manager::getInstance()->getActiveHostings());
?>
</td>
</tr>
<tr>
<td class='dpro-settings-diag-header' colspan="2">PHP</td>
</tr>
<tr>
<td><?php esc_html_e("Version", 'duplicator-pro'); ?></td>
<td><?php echo esc_html(phpversion()); ?></td>
</tr>
<tr>
<td>SAPI</td>
<td><?php echo PHP_SAPI ?></td>
</tr>
<tr>
<td><?php esc_html_e("User", 'duplicator-pro'); ?></td>
<td><?php echo DUP_PRO_Server::getCurrentUser(); ?></td>
</tr>
<tr>
<td><a href="http://php.net/manual/en/features.safe-mode.php" target="_blank"><?php esc_html_e("Safe Mode", 'duplicator-pro'); ?></a></td>
<td>
<?php
echo (((strtolower(@ini_get('safe_mode')) == 'on') || (strtolower(@ini_get('safe_mode')) == 'yes') ||
(strtolower(@ini_get('safe_mode')) == 'true') || (ini_get("safe_mode") == 1 ))) ? __('On', 'duplicator-pro') : __('Off', 'duplicator-pro');
?>
</td>
</tr>
<tr>
<td><a href="http://www.php.net/manual/en/ini.core.php#ini.memory-limit" target="_blank"><?php esc_html_e("Memory Limit", 'duplicator-pro'); ?></a></td>
<?php
$memory_limit = @ini_get('memory_limit');
?>
<td><?php echo empty($memory_limit) ? '' : esc_html($memory_limit); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Memory In Use", 'duplicator-pro'); ?></td>
<td><?php echo esc_html(size_format(@memory_get_usage(true), 2)); ?></td>
</tr>
<tr>
<td><a href="http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time" target="_blank"><?php esc_html_e("Max Execution Time", 'duplicator-pro'); ?></a></td>
<td>
<?php
echo esc_html(@ini_get('max_execution_time'));
$try_update = set_time_limit(0);
$try_update = $try_update ? 'is dynamic' : 'value is fixed';
echo " (default) - {$try_update}";
$tipCont = __(
'If the value shows dynamic then this means its possible for PHP to run longer than the default.
If the value is fixed then PHP will not be allowed to run longer than the default.',
'duplicator-pro'
);
?>
<i class="fa fa-question-circle data-size-help"
data-tooltip-title="<?php esc_attr_e("Max Execution Time", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipCont); ?>"></i>
</td>
</tr>
<tr>
<td><a href="http://php.net/manual/en/ini.core.php#ini.open-basedir" target="_blank"><?php esc_html_e("open_basedir", 'duplicator-pro'); ?></a></td>
<td>
<?php
$open_base_set = @ini_get('open_basedir');
echo empty($open_base_set) ? __('Off', 'duplicator-pro') : esc_html($open_base_set);
?>
</td>
</tr>
<tr>
<td><a href="http://us3.php.net/shell_exec" target="_blank"><?php esc_html_e("Shell (shell_exec)", 'duplicator-pro'); ?></a></td>
<td><?php echo (!Shell::hasDisabledFunctions('shell_exec')) ? esc_html__("Is Supported", 'duplicator-pro') : esc_html__("Not Supported", 'duplicator-pro'); ?></td>
</tr>
<tr>
<td><a href="http://us3.php.net/popen" target="_blank"><?php esc_html_e("Shell (popen)", 'duplicator-pro'); ?></a></td>
<td><?php echo (!Shell::hasDisabledFunctions('popen')) ? esc_html__("Is Supported", 'duplicator-pro') : esc_html__("Not Supported", 'duplicator-pro'); ?></td>
</tr>
<tr>
<td><a href="https://www.php.net/manual/en/function.exec.php" target="_blank"><?php esc_html_e("Shell (exec)", 'duplicator-pro'); ?></a></td>
<td><?php echo !Shell::hasDisabledFunctions('exec') ? esc_html__("Is Supported", 'duplicator-pro') : esc_html__("Not Supported", 'duplicator-pro'); ?></td>
</tr>
<tr>
<td><?php esc_html_e("Shell Exec Zip", 'duplicator-pro'); ?></td>
<td><?php echo (DUP_PRO_Zip_U::getShellExecZipPath() != null) ? esc_html__("Is Supported", 'duplicator-pro') : esc_html__("Not Supported", 'duplicator-pro'); ?></td>
</tr>
<tr>
<td><a href="https://suhosin.org/stories/index.html" target="_blank"><?php esc_html_e("Suhosin Extension", 'duplicator-pro'); ?></a></td>
<td><?php echo Shell::isSuhosinEnabled() ? esc_html__("Enabled", 'duplicator-pro') : esc_html__("Disabled", 'duplicator-pro'); ?></td>
</tr>
<tr>
<td>Architecture</td>
<td>
<?php echo SnapUtil::getArchitectureString(); ?>
</td>
</tr>
<tr>
<td><?php esc_html_e("Error Log File ", 'duplicator-pro'); ?></td>
<td><?php echo esc_html($error_log_path); ?></td>
</tr>
<tr>
<td class='dpro-settings-diag-header' colspan="2">MySQL</td>
</tr>
<tr>
<td><?php esc_html_e("Version", 'duplicator-pro'); ?></td>
<td><?php echo DUP_PRO_DB::getVersion() ?></td>
</tr>
<tr>
<td><?php esc_html_e("Charset", 'duplicator-pro'); ?></td>
<td><?php echo DB_CHARSET ?></td>
</tr>
<tr>
<td><a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_wait_timeout" target="_blank"><?php esc_html_e("Wait Timeout", 'duplicator-pro'); ?></a></td>
<td><?php echo esc_html($dbvar_maxtime); ?></td>
</tr>
<tr>
<td style="white-space:nowrap"><a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_max_allowed_packet" target="_blank"><?php esc_html_e("Max Allowed Packets", 'duplicator-pro'); ?></a></td>
<td><?php echo esc_html($dbvar_maxpacks); ?></td>
</tr>
<tr>
<td><a href="http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html" target="_blank"><?php esc_html_e("msyqldump Path", 'duplicator-pro'); ?></a></td>
<td><?php echo esc_html($mysqlDumpSupport); ?></td>
</tr>
<tr>
<td class='dpro-settings-diag-header' colspan="2"><?php esc_html_e("Paths info", 'duplicator-pro'); ?></td>
</tr
<tr>
<td><?php esc_html_e("Target root path", 'duplicator-pro'); ?></a></td>
<td><?php echo esc_html(DUP_PRO_Archive::getTargetRootPath()); ?></td>
</tr>
<?php
$scanPaths = DUP_PRO_Archive::getScanPaths();
foreach ($scanPaths as $path) {
?>
<tr>
<td><?php echo esc_html__("Scan path", 'duplicator-pro'); ?></a></td>
<td><?php echo esc_html($path); ?></td>
</tr>
<?php
}
?>
<tr><td>&nbsp;</td><td></td></tr>
<?php
$originalPaths = DUP_PRO_Archive::getOriginalPaths();
foreach ($originalPaths as $key => $value) {
?>
<tr>
<td><?php echo esc_html__("Original ", 'duplicator-pro') . $key; ?></a></td>
<td><?php echo esc_html($value); ?></td>
</tr>
<?php
}
?>
<tr><td>&nbsp;</td><td></td></tr>
<?php
$archivePaths = DUP_PRO_Archive::getArchiveListPaths();
foreach ($archivePaths as $key => $value) {
?>
<tr>
<td><?php echo esc_html__("Archive ", 'duplicator-pro') . $key; ?></a></td>
<td><?php echo esc_html($value); ?></td>
</tr>
<?php
} ?>
<tr>
<td class='dpro-settings-diag-header' colspan="2"><?php esc_html_e("URLs info", 'duplicator-pro'); ?></td>
</tr>
<?php
$urls = DUP_PRO_Archive::getOriginalUrls();
foreach ($urls as $key => $value) {
?>
<tr>
<td><?php echo esc_html__("URL ", 'duplicator-pro') . $key; ?></a></td>
<td><?php echo esc_html($value); ?></td>
</tr>
<?php
} ?>
<?php if ($space >= 0) : ?>
<tr>
<td class='dpro-settings-diag-header' colspan="2"><?php esc_html_e("Server Disk", 'duplicator-pro'); ?></td>
</tr>
<tr valign="top">
<td><?php esc_html_e('Free space', 'duplicator-pro'); ?></td>
<td>
<?php echo $perc; ?>% -- <?php echo esc_html(DUP_PRO_U::byteSize($space_free)); ?> from <?php echo esc_html(DUP_PRO_U::byteSize($space)); ?>
<br/>
<small>
<?php esc_html_e("Note: This value is the physical servers hard-drive allocation.", 'duplicator-pro'); ?> <br/>
<?php esc_html_e("On shared hosts check your control panel for the 'TRUE' disk space quota value.", 'duplicator-pro'); ?>
</small>
</td>
</tr>
<?php endif; ?>
</table>
<br/>
</div>
</div>
<br/>

View File

@@ -0,0 +1,195 @@
<?php
use Duplicator\Core\CapMng;
defined("ABSPATH") or die("");
if (!CapMng::can(CapMng::CAP_CREATE, false)) {
return;
}
?>
<style>
div#hb-result {padding: 10px 5px 0 5px; line-height:20px; font-size: 12px}
</style>
<!-- ==========================================
THICK-BOX DIALOGS: -->
<?php
$confirm1 = new DUP_PRO_UI_Dialog();
$confirm1->title = __('Run Validator', 'duplicator-pro');
$confirm1->message = __('This will run the scan validation check. This may take several minutes. Do you want to Continue?', 'duplicator-pro');
$confirm1->progressOn = false;
$confirm1->jsCallback = 'DupPro.Tools.runScanValidator()';
$confirm1->initConfirm();
?>
<!-- ==============================
SCAN VALIDATOR -->
<div class="dup-box">
<div class="dup-box-title">
<i class="far fa-check-square"></i>
<?php esc_html_e("Scan Validator", 'duplicator-pro'); ?>
<button class="dup-box-arrow">
<span class="screen-reader-text">
<?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Scan Validator', 'duplicator-pro') ?>
</span>
</button>
</div>
<div class="dup-box-panel" style="display: none;">
<?php
esc_html_e(
"This utility will help to find unreadable files and sys-links in your environment that can lead to issues during the scan process.",
'duplicator-pro'
);
echo ' ';
esc_html_e(
"The utility will also shows how many files and directories you have in your system. This process may take several minutes to run.",
'duplicator-pro'
);
echo ' ';
esc_html_e(
"If there is a recursive loop on your system then the process has a built in check to stop after a large set
of files and directories have been scanned.",
'duplicator-pro'
);
echo ' ';
esc_html_e(
"A message will show indicated that that a scan depth has been reached.
If you have issues with the package scanner (step 2) during the build process then try to add
The paths below to your file filters to allow the scanner to finish.",
'duplicator-pro'
);
?>
<br/><br/>
<button id="scan-run-btn" type="button" class="button button-large button-primary" onclick="DupPro.Tools.ConfirmScanValidator()">
<?php esc_html_e("Run Scan Integrity Validation", 'duplicator-pro'); ?>
</button>
<script id="hb-template" type="text/x-handlebars-template">
<b><?php esc_html_e('Scan Paths:', 'duplicator-pro'); ?></b><br/>
{{#if scanData.scanPaths}}
{{#each scanData.scanPaths}}
&nbsp; &nbsp; {{@index}} : {{this}}<br/>
{{/each}}
{{else}}
<i><?php esc_html_e('Empty scan path', 'duplicator-pro'); ?></i> <br/>
{{/if}}
<br/>
<b><?php esc_html_e('Scan Results', 'duplicator-pro'); ?></b><br/>
<table>
<tr>
<td><b><?php esc_html_e('Files:', 'duplicator-pro'); ?></b></td>
<td>{{scanData.fileCount}} </td>
<td> &nbsp; </td>
<td><b><?php esc_html_e('Dirs:', 'duplicator-pro'); ?></b></td>
<td>{{scanData.dirCount}} </td>
</tr>
</table>
<br/>
<b>Unreadable Dirs/Files:</b> <br/>
{{#if scanData.unreadable}}
{{#each scanData.unreadable}}
&nbsp; &nbsp; {{@index}} : {{this}}<br/>
{{/each}}
{{else}}
<i><?php esc_html_e('No Unreadable items found', 'duplicator-pro'); ?></i> <br/>
{{/if}}
<br/>
<b><?php esc_html_e('Symbolic Links:', 'duplicator-pro'); ?></b> <br/>
{{#if scanData.symLinks}}
{{#each scanData.symLinks}}
&nbsp; &nbsp; {{@index}} : {{this}}<br/>
{{/each}}
{{else}}
<i>No Sym-links found</i> <br/>
<small> <?php esc_html_e("Note: Symlinks are not discoverable on Windows OS with PHP", 'duplicator-pro'); ?></small> <br/>
{{/if}}
<br/>
<b>Directory Name Checks:</b> <br/>
{{#if scanData.nameTestDirs}}
{{#each scanData.nameTestDirs}}
&nbsp; &nbsp; {{@index}} : {{this}}<br/>
{{/each}}
{{else}}
<i><?php esc_html_e('No name check warnings located for directory paths', 'duplicator-pro'); ?></i> <br/>
{{/if}}
<br/>
<b>File Name Checks:</b> <br/>
{{#if scanData.nameTestFiles}}
{{#each scanData.nameTestFiles}}
&nbsp; &nbsp; {{@index}} : {{this}}<br/>
{{/each}}
{{else}}
<i><?php esc_html_e('No name check warnings located for directory paths', 'duplicator-pro'); ?></i> <br/>
{{/if}}
<br/>
</script>
<div id="hb-result"></div>
</div>
</div>
<br/>
<script>
jQuery(document).ready(function($)
{
DupPro.Tools.ConfirmScanValidator = function()
{
<?php $confirm1->showConfirm(); ?>
}
//Run request to: admin-ajax.php?action=DUP_CTRL_Tools_runScanValidator
DupPro.Tools.runScanValidator = function()
{
tb_remove();
var data = {
action : 'DUP_PRO_CTRL_Tools_runScanValidator',
nonce: '<?php echo wp_create_nonce('DUP_PRO_CTRL_Tools_runScanValidator'); ?>',
'scan-recursive': 1
};
$('#hb-result').html('<?php esc_html_e("Scanning Environment... This may take a few minutes.", 'duplicator-pro'); ?>');
$('#scan-run-btn').html('<i class="fas fa-circle-notch fa-spin fa-fw"></i> Running Please Wait...');
$.ajax({
type: "POST",
url: ajaxurl,
dataType: "text",
data: data,
success: function(respData) {
try {
var data = DupPro.parseJSON(respData);
} catch(err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
console.log(respData);
return false;
}
DupPro.Tools.IntScanValidator(data);
},
error: function(data) {console.log(data)},
done: function(data) {console.log(data)}
});
}
//Process Ajax Template
DupPro.Tools.IntScanValidator= function(data)
{
var template = $('#hb-template').html();
var templateScript = Handlebars.compile(template);
var html = templateScript(data);
$('#hb-result').html(html);
$('#scan-run-btn').html('<?php esc_html_e("Run Scan Integrity Validation", 'duplicator-pro'); ?>');
}
});
</script>

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,263 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\CapMng;
$trace_log_filepath = DUP_PRO_Log::getTraceFilepath();
$trace_filename = basename($trace_log_filepath);
$logs = ToolsPageController::getLogsList();
$global = DUP_PRO_Global_Entity::getInstance();
$logname = (isset($_GET['logname'])) ? trim($_GET['logname']) : "";
$refresh = (isset($_POST['refresh']) && $_POST['refresh'] == 1) ? 1 : 0;
$auto = (isset($_POST['auto']) && $_POST['auto'] == 1) ? 1 : 0;
//Check for invalid file
if (isset($_GET['logname'])) {
$validFiles = array_map('basename', $logs);
if (validate_file($logname, $validFiles) > 0) {
unset($logname);
}
unset($validFiles);
}
if (!isset($logname) || !$logname) {
$logname = (count($logs) > 0) ? basename($logs[0]) : "";
}
$nocache = @date("ymdHis");
$logurl = DUPLICATOR_PRO_SSDIR_URL . "/{$logname}?{$nocache}";
$logurl_base = DUPLICATOR_PRO_SSDIR_URL . "/{$logname}";
$logfound = (strlen($logname) > 0) ? true : false;
?>
<style>
span#dup-refresh-count {display:inline;}
table#dpro-log-pnls {width:100%;}
td#dpro-log-pnl-left {width:80%; vertical-align: top}
td#dpro-log-pnl-left div.name {float:left; margin: 0px 0px 5px 5px; font-weight: bold}
td#dpro-log-pnl-left div.opts {float:right;}
td#dpro-log-pnl-right {vertical-align: top; padding:5px 0 0 15px; max-width: 375px;}
iframe#dpro-log-content {padding:5px; background: #fff; min-height:500px; width:99%; border:1px solid silver}
/* OPTIONS */
div.dpro-opts-items {border:1px solid silver; background: #efefef; padding: 5px; border-radius: 4px; margin:2px 0px 10px -2px; }
div.dpro-log-hdr {font-weight: bold; font-size:16px; padding:2px; }
div.dpro-log-hdr small{font-weight:normal; font-style: italic}
div.dpro-log-file-list {font-family:monospace;line-height: 24px}
div.dpro-log-file-list a span{display: inline-block; white-space: nowrap; text-overflow: ellipsis; max-width: 375px; line-height:20px; overflow:hidden}
div.dpro-log-file-list span {color:green}
div.dup-opts-items {border:1px solid silver; background: #efefef; padding: 5px; border-radius: 4px; margin:2px 0px 10px -2px;}
label#dup-auto-refresh-lbl {display: inline-block;}
div#dpro-monitor-trace-area {bottom:70px}
</style>
<script>
jQuery(document).ready(function ($)
{
DupPro.Tools.FullLog = function () {
var $panelL = $('#dpro-log-pnl-left');
var $panelR = $('#dpro-log-pnl-right');
if ($panelR.is(":visible")) {
$panelR.hide(400);
$panelL.css({width: '100%'});
} else {
$panelR.show(200);
$panelL.css({width: '75%'});
}
}
DupPro.Tools.Refresh = function () {
$('#refresh').val(1);
$('#dup-form-logs').submit();
}
DupPro.Tools.RefreshAuto = function () {
if ($("#dup-auto-refresh").is(":checked")) {
$('#auto').val(1);
startTimer();
} else {
$('#auto').val(0);
}
}
DupPro.Tools.WinResize = function () {
var height = $(window).height() - 210;
$("#dpro-log-content").css({height: height + 'px'});
}
var duration = 9;
var count = duration;
var timerInterval;
function timer() {
count = count - 1;
$("#dup-refresh-count").html(count.toString());
if (!$("#dup-auto-refresh").is(":checked")) {
clearInterval(timerInterval);
$("#dup-refresh-count").text(count.toString().trim());
return;
}
if (count <= 0) {
count = duration + 1;
DupPro.Tools.Refresh();
}
}
function startTimer() {
timerInterval = setInterval(timer, 1000);
}
//INIT Events
$(window).resize(DupPro.Tools.WinResize);
$('#dup-options').click(DupPro.Tools.FullLog);
$("#dup-refresh").click(DupPro.Tools.Refresh);
$("#dup-auto-refresh").click(DupPro.Tools.RefreshAuto);
$("#dup-refresh-count").html(duration.toString());
//INIT
DupPro.Tools.WinResize();
<?php if ($refresh) : ?>
//Scroll to Bottom
$('#dpro-log-content').on('load', function() {
var $contents = $('#dpro-log-content').contents();
$contents.scrollTop($contents.height());
});
<?php if ($auto) : ?>
$("#dup-auto-refresh").prop('checked', true);
DupPro.Tools.RefreshAuto();
<?php endif; ?>
<?php endif; ?>
// formatting log
$('#dpro-log-content').on('load', function() {
$('#dpro-log-content').contents().find("head")
.append($("<style type='text/css'>pre {line-height: 2;white-space: pre;}</style>"));
});
});
</script>
<form id="dup-form-logs" method="post" action="">
<input type="hidden" id="refresh" name="refresh" value="<?php echo ($refresh) ? 1 : 0 ?>" />
<input type="hidden" id="auto" name="auto" value="<?php echo ($auto) ? 1 : 0 ?>" />
<?php if (!$logfound) : ?>
<div style="padding:20px">
<h2><?php esc_html_e("Log file not found or unreadable", 'duplicator-pro') ?>.</h2>
<?php esc_html_e("Try to create a package, since no log files were found in the snapshots directory ending in *_log.txt", 'duplicator-pro') ?>.<br/><br/>
<?php esc_html_e("Reasons for log file not showing", 'duplicator-pro') ?>: <br/>
- <?php esc_html_e("The web server does not support returning .txt file extensions", 'duplicator-pro') ?>. <br/>
- <?php esc_html_e("The snapshots directory does not have the correct permissions to write files. Try setting the permissions to 755", 'duplicator-pro') ?>. <br/>
- <?php esc_html_e("The process that PHP runs under does not have enough permissions to create files. Please contact your hosting provider for more details", 'duplicator-pro') ?>. <br/>
</div>
<?php else : ?>
<table id="dpro-log-pnls">
<tr>
<td id="dpro-log-pnl-left">
<div class="name"><i class="fas fa-file-contract fa-fw"></i> <?php echo basename($logurl); ?></div>
<div class="opts"><a href="javascript:void(0)" id="dup-options"><?php esc_html_e("Options", 'duplicator-pro') ?> <i class="fa fa-angle-double-right"></i></a> &nbsp;</div>
<br style="clear:both" />
<iframe id="dpro-log-content" src="<?php echo esc_url($logurl); ?>" ></iframe>
</td>
<td id="dpro-log-pnl-right">
<h2><?php esc_html_e("Options", 'duplicator-pro') ?></h2>
<div class="dpro-opts-items">
<input type="button" class="button button-small" id="dup-refresh" value="<?php esc_attr_e("Refresh", 'duplicator-pro') ?>" /> &nbsp;
<div style="display:inline-block;margin-top:1px;">
<input type='checkbox' id="dup-auto-refresh" style="margin-top:3px" />
<label id="dup-auto-refresh-lbl" for="dup-auto-refresh">
<?php esc_html_e("Auto Refresh", 'duplicator-pro') ?> [<span id="dup-refresh-count"></span>]
</label>
</div>
</div>
<div class="dpro-log-hdr">
<?php esc_html_e('Trace Log:', 'duplicator-pro') ?> &nbsp;
<span style="font-size:11px; font-weight: normal">
<?php
$trace_on = get_option('duplicator_pro_trace_log_enabled', false);
$txt_clear_trace = esc_html__('Clear', 'duplicator-pro');
$txt_profile = '';
$html = "";
if (CapMng::can(CapMng::CAP_SETTINGS, false)) {
if (!$trace_on) {
$url = SettingsPageController::getInstance()->getTraceActionUrl(true);
$html = '<a href="' . esc_url($url) . '" target="_blank">' . __("Turn On", 'duplicator-pro') . $txt_profile . '</a>';
} else {
$url = SettingsPageController::getInstance()->getTraceActionUrl(false);
$html = '<a href="' . esc_url($url) . '" target="_blank">' . __("Turn Off", 'duplicator-pro') . $txt_profile . '</a>';
}
$html .= " | ";
}
if (CapMng::can(CapMng::CAP_CREATE, false)) {
$html .= "<a href='javascript:void(0)' onclick='DupPro.UI.ClearTraceLog(1);'>{$txt_clear_trace}</a>";
}
echo $html;
?>
</span>
</div>
<div class="dpro-log-file-list">
<?php
$trace_log_filepath = DUP_PRO_Log::getTraceFilepath();
if (file_exists($trace_log_filepath)) {
$time = date('m/d/y h:i:s', @filemtime($trace_log_filepath));
} else {
$time = __('No trace log found', 'duplicator-pro');
}
$active_filename = basename($logurl_base);
$trace_log_url = ControllersManager::getMenuLink(ControllersManager::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_DISAGNOSTIC, ToolsPageController::L3_SLUG_DISAGNOSTIC_LOG, array('logname' => $trace_filename));
$is_trace_active = ($active_filename == $trace_filename);
echo ($is_trace_active)
? '<div class="dpro-trace-log-link-green"><i class="fa fa-caret-right"></i> ' . $time . '</div>'
: '<a href="' . esc_url($trace_log_url) . '">' . $time . '</a>';
?>
</div>
<br/>
<div class="dpro-log-hdr">
<?php esc_html_e('Package Logs', 'duplicator-pro'); ?>
<small><?php esc_html_e('Top 20', 'duplicator-pro'); ?></small>
</div>
<div class="dpro-log-file-list" style="white-space: nowrap">
<?php
$count = 0;
$active = basename($logurl_base);
foreach ($logs as $log) {
$time = date('m/d/y h:i:s', filemtime($log));
$name = sanitize_text_field(basename($log));
$url = ControllersManager::getMenuLink(ControllersManager::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_DISAGNOSTIC, ToolsPageController::L3_SLUG_DISAGNOSTIC_LOG, array('logname' => $name));
if ($name !== $trace_filename) {
$shortname = substr($name, 0, 15) . '***.log';
echo ($active == $name)
? '<span title="' . esc_attr($name) . '"><i class="fa fa-caret-right"></i> ' . $time . '-' . $shortname . '</span><br/>'
: '<a href="' . esc_url($url) . '" title="' . esc_attr($name) . '">' . $time . '-' . $shortname . '</a><br/>';
if ($count > 20) {
break;
}
$count++;
}
}
?>
</div>
</td>
</tr>
</table>
<?php endif; ?>
</form>

View File

@@ -0,0 +1,39 @@
<?php
defined("ABSPATH") or die("");
wp_enqueue_script('dup-handlebars');
?>
<style>
<?php echo isset($css_hide_msg) ? $css_hide_msg : ''; ?>
div#message {margin:0px 0px 10px 0px}
td.dpro-settings-diag-header {background-color:#D8D8D8; font-weight: bold; border-style: none; color:black}
table.widefat th {font-weight:bold; }
table.widefat td {padding:2px 2px 2px 8px; }
table.widefat td:nth-child(1) {width:10px;}
table.widefat td:nth-child(2) {padding-left: 20px; width:100% !important}
textarea.dup-opts-read {width:100%; height:40px; font-size:12px}
.dpro-store-fixed-btn {
min-width: 165px;
text-align: center
}
div.success,span.success {color:#4A8254}
div.failed {color:red}
table.dpro-reset-opts td:first-child {
font-weight: bold
}
table.dpro-reset-opts td {
padding: 0 10px 10px 0;
}
div#dpro-tools-delete-moreinfo {display: none; padding: 5px 0 0 20px; border:1px solid #dfdfdf; border-radius: 5px; padding:10px; margin:5px; width:98% }
div#dpro-tools-delete-orphans-moreinfo {display: none; padding: 5px 0 0 20px; border:1px solid #dfdfdf; border-radius: 5px; padding:10px; margin:5px; width:98% }
/*PHP_INFO*/
div#dpro-phpinfo {padding:10px 5px;}
div#dpro-phpinfo table {padding:1px; background:#dfdfdf; -webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px; width:100% !important; box-shadow:0 8px 6px -6px #777;}
div#dpro-phpinfo td, th {padding:3px; background:#fff; -webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;}
div#dpro-phpinfo tr.h img {display:none;}
div#dpro-phpinfo tr.h td {background:none;}
div#dpro-phpinfo tr.h th {text-align:center; background-color:#efefef;}
div#dpro-phpinfo td.e {font-weight:bold}
</style>

View File

@@ -0,0 +1,382 @@
<?php
defined("ABSPATH") or die("");
if (isset($_POST['clear_log']) && $_POST['clear_log'] == 'true') {
DUP_PRO_PHP_Log::clear_log();
}
$refresh = (isset($_POST['refresh']) && $_POST['refresh'] == 1) ? 1 : 0;
$auto = (isset($_POST['auto']) && $_POST['auto'] == 1) ? 1 : 0;
$filter = (isset($_POST['filter'])) ? $_POST['filter'] : '';
$error = false;
$lines = 200;
$log_path = DUP_PRO_PHP_Log::get_path(null, true);
$error_log = DUP_PRO_PHP_Log::get_log($lines, "M d, H:i:s");
$log_path_size = 0;
if ($log_path !== false) {
$log_path_size = @filesize($log_path);
if (!is_readable($log_path)) {
$error = sprintf(
__(
"PHP error log is available on location %s but is not readable. Try setting the permissions to 755.",
'duplicator-pro'
),
'<b>' . esc_html($log_path) . '</b>'
);
} elseif ($error_log === false) {
if ($log_path > (PHP_INT_MAX / 2)) {
$error = sprintf(
__(
"PHP error log is available on location %1\$s but can't be read because file size is over %2\$s. You must open this file manualy.",
'duplicator-pro'
),
'<b>' . esc_html($log_path) . '</b>',
'<b>' . DUP_PRO_U::byteSize($log_path_size) . '</b>'
);
} else {
$error = sprintf(
__(
"PHP error log is available on location %s but can't be read because some unexpected error. Try to open file manually and investigate all problems what can cause this error.",
'duplicator-pro'
),
'<b>' . esc_html($log_path) . '</b>'
);
}
} else {
}
} else {
$error = __('This can be good for you because there is no errors.', 'duplicator-pro') . '<br><br>';
$error .= sprintf(
__(
'But if you in any case experience some errors and not see log here,
that mean your error log file is placed on some unusual location or can\'t be created because some %1$s setup.
In that case you must open %2$s file and define %3$s or call your system administrator to setup it properly.',
'duplicator-pro'
),
"<b><i>php.ini</i></b>",
"<b><i>php.ini</i></b>",
"<code>error_log</code>"
) .
'<br><br>';
$error .= sprintf(
__('It would be great if you define new error log path to be inside root of your WordPress installation ( %1$s ) and name of file to be %2$s. That will solve this problem.', 'duplicator-pro'),
'<i><b>' . duplicator_pro_get_home_path() . '</b></i>',
'<b>error.log</b>'
);
}
if ($error) : ?>
<h2><?php
if ($log_path !== false) {
esc_html_e("Log file is found but have error or is unreadable", 'duplicator-pro');
} else {
esc_html_e("PHP error log not found", 'duplicator-pro');
}
?></h2>
<?php echo $error; ?>
<?php else : ?>
<style>
span#dup-refresh-count {display:inline;}
table#dpro-log-pnls {width:100%;}
td#dpro-log-pnl-left div.opts {float:right;}
td#dpro-log-pnl-left {width:80%; vertical-align: top}
td#dpro-log-pnl-right {vertical-align: top; padding:5px 0 0 15px; max-width: 375px;}
td#dpro-log-pnl-left div.name{float:left;margin:0 0 5px 5px;font-weight:700}
#error-log{width:100%;border:none;table-layout:fixed;border-spacing:0}
#error-log td,#error-log th{padding:8px 10px;border:none}
#error-log th{border-bottom:1px solid #e1e1e1;font-weight:600;text-align:center;color:#000}
#error-log th:last-child{padding-right:2.1%}
#error-log td{text-align:left;vertical-align:top}
div.tableContainer{clear:both;border:1px solid #ccc;height:500px;overflow:auto;width:100%;padding-bottom:35px;background:#fff}
/* Reset overflow value to hidden for all non-IE browsers. */
html>body div.tableContainer {overflow: hidden; width: 100%;}
div.tableContainer #error-log {float: left;}
#error-log tr{width:100%;}
#error-log thead tr {position: relative;}
#error-log tbody {display: block; height: 500px; overflow: auto; width: 100%}
html>body #error-log thead {display: table; overflow: auto; width: 100%}
#error-log td ul{padding:10px 15px; background: rgba(200, 200, 200, 0.1); color:#000; box-shadow:#ccc 0px 0px 1px; -webkit-box-shadow:#ccc 0px 0px 1px; -ms-box-shadow:#ccc 0px 0px 1px; -o-box-shadow:#ccc 0px 0px 1px; }
#error-log td ul li+li{margin-top:15px;}
#error-log td ul li.title{font-weight: bold;}
.info{display: inline-table; border-bottom:1px dotted #ccc; cursor:pointer;}
div.dpro-opts-items {border:1px solid silver; background: #efefef; padding: 5px; border-radius: 4px; margin:2px 0px 10px -2px; }
div.dpro-log-hdr {font-weight: bold; font-size:16px; padding:2px; }
div.dpro-log-hdr small{font-weight:normal; font-style: italic}
</style>
<table id="dpro-log-pnls">
<tr>
<td id="dpro-log-pnl-left">
<div class="name"><i class="fas fa-file-contract fa-fw"></i> <?php echo esc_html($log_path); ?></div>
<div class="opts"><a href="javascript:void(0)" id="dup-options"><?php esc_html_e('Options', 'duplicator-pro'); ?> <i class="fa fa-angle-double-right"></i></a> &nbsp;</div>
<div id="tableContainer" class="tableContainer">
<table class="wp-list-table fixed striped" id="error-log">
<thead>
<tr>
<th scope="col" style="width: 10%; text-align: center"><?php esc_html_e('Date', 'duplicator-pro'); ?></th>
<th scope="col" style="width: 8%; text-align: center"><?php esc_html_e('Type', 'duplicator-pro'); ?></th>
<th scope="col" style="width: 34%;"><?php esc_html_e('Error', 'duplicator-pro'); ?></th>
<th scope="col" style="width: 30%;"><?php esc_html_e('File', 'duplicator-pro'); ?></th>
<th scope="col" style="width: 6%;"><?php esc_html_e('Line', 'duplicator-pro'); ?></th>
</tr>
</thead>
<tbody id="the-list"<?php echo (count($error_log) === 0) ? ' style="overflow: hidden;"' : ''; ?>>
<?php if (count($error_log) === 0) : ?>
<tr style="width:100%; display:table">
<td colspan="5" style="width:100%; display:table"><h3><?php esc_html_e('PHP Error Log is empty.', 'duplicator-pro'); ?></h3></td>
</tr>
<?php else : ?>
<?php foreach ($error_log as $line => $log) : ?>
<tr>
<td scope="col" style="width: 15%; text-align: center">
<b class="info" title="<?php echo date("Y-m-d H:i:s T (P)", strtotime($log['dateTime'])); ?>">
<?php echo esc_html($log['dateTime']); ?>
</b>
</td>
<td scope="col" style="width: 8%; text-align: center"><?php echo esc_html($log['type']); ?></td>
<td scope="col" style="width: 35.5%;">
<?php echo esc_html($log['message']); ?>
<?php if (count($log['stackTrace']) > 0) : ?>
<ul>
<li class="title"><?php esc_html_e('Stack trace:', 'duplicator-pro'); ?></li>
<?php foreach ($log['stackTrace'] as $i => $trace) : ?>
<li><b>#<?php echo esc_html($i); ?></b> <?php echo esc_html($trace); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</td>
<td scope="col" style="width: 35.5%;"><?php echo esc_html($log['file']); ?></td>
<td scope="col" style="width: 6%; text-align: center"><?php echo esc_html($log['line']); ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</td>
<td id="dpro-log-pnl-right">
<h2><?php esc_html_e("Options", 'duplicator-pro') ?></h2>
<form id="dup-form-logs" method="post" action="">
<div class="dpro-opts-items">
<strong><?php esc_html_e('PHP Error Filter:', 'duplicator-pro'); ?></strong>
<select type="text" id="filter" name="filter" style="width:100%;">
<option value="">--- <?php esc_html_e('None', 'duplicator-pro'); ?> ---</option>
<?php
foreach (
array(
'WARNING' => __('Warnings', 'duplicator-pro'),
'NOTICE' => __('Notices', 'duplicator-pro'),
'FATAL' => __('Fatal Error', 'duplicator-pro'),
'SYNTAX' => __('Syntax Error', 'duplicator-pro'),
'EXCEPTION' => __('Exceptions', 'duplicator-pro'),
) as $option => $name
) :
?>
<option value="<?php echo esc_attr($option); ?>"<?php echo ($filter == $option ? ' selected' : ''); ?>><?php echo esc_html($name); ?></option>
<?php endforeach; ?>
</select>
<hr>
<input type="button" class="button button-small" id="dup-refresh" value="<?php esc_attr_e("Refresh", 'duplicator-pro') ?>" /> &nbsp;
<div style="display:inline-block;margin-top:1px;">
<input type='checkbox' id="dup-auto-refresh" style="margin-top:3px" />
<label id="dup-auto-refresh-lbl" for="dup-auto-refresh">
<?php esc_html_e("Auto Refresh", 'duplicator-pro') ?> [<span id="dup-refresh-count"></span>]
</label>
</div>
</div>
<input type="hidden" id="refresh" name="refresh" value="<?php echo ($refresh) ? 1 : 0 ?>" />
<input type="hidden" id="auto" name="auto" value="<?php echo ($auto) ? 1 : 0 ?>" />
</form>
<div class="dpro-log-file-list">
<div style="color:green"><i class="fa fa-caret-right"></i> <?php
echo DUP_PRO_PHP_Log::get_filename($log_path);
echo ' (', DUP_PRO_U::byteSize($log_path_size),') &nbsp;|&nbsp; ';
echo date("Y-m-d H:i:s", filemtime($log_path));
?></div>
</div>
<?php if (isset($line) && $line + 30 > $lines) : ?>
<br>
<div style="color:#cc0000">
<i class="fa fa-info-circle"></i> <?php printf(__("You see only last %1\$s logs inside %2\$s file.", 'duplicator-pro'), $line, esc_html(DUP_PRO_PHP_Log::get_filename($log_path))); ?>
</div>
<?php endif; ?>
<?php if (isset($line)) : ?>
<br>
<form id="dup-form-clear-log" method="post" action="">
<button class="button" type="button" onclick="return DupPro.Tools.ClearLog();"><?php esc_html_e('Clear Log', 'duplicator-pro'); ?></button>
<input type="hidden" id="clear_log" name="clear_log" value="true" />
</form>
<?php endif; ?>
</td>
</tr>
</table>
<?php
$confirm1 = new DUP_PRO_UI_Dialog();
$confirm1->title = __('Clear PHP Log?', 'duplicator-pro');
$confirm1->message = __('Are you sure you want to clear PHP log??', 'duplicator-pro');
$confirm1->message .= '<br/>';
$confirm1->message .= '<small><i>' . __('Note: This action will delete all data and can\'t be stopped.', 'duplicator-pro') . '</i></small>';
$confirm1->progressText = __('Clear PHP log, Please Wait...', 'duplicator-pro');
$confirm1->jsCallback = 'DupPro.Tools.ClearLogSubmit()';
$confirm1->initConfirm();
?>
<script>
jQuery(document).ready(function ($)
{
var duration = 9,
count = duration,
timerInterval;
DupPro.Tools.errorFilter = function() {
// Declare variables
var input, filter, table, tr, td, i;
input = $("#filter");
filter = input.val().toUpperCase();
table = $("#error-log");
tr = table.find("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[1];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "block";
} else {
tr[i].style.display = "none";
}
}
}
}
$("#dup-refresh-count").html(duration);
function timer() {
count = count - 1;
$("#dup-refresh-count").html(count.toString());
if (!$("#dup-auto-refresh").is(":checked")) {
clearInterval(timerInterval);
$("#dup-refresh-count").text(count.toString().trim());
return;
}
if (count <= 0) {
count = duration + 1;
DupPro.Tools.Refresh();
}
}
function startTimer() {
timerInterval = setInterval(timer, 1000);
}
DupPro.Tools.ClearLogSubmit = function() {
$('#dup-form-clear-log').submit();
}
DupPro.Tools.ClearLog = function() {
<?php $confirm1->showConfirm(); ?>
}
DupPro.Tools.Refresh = function () {
$('#refresh').val(1);
$('#dup-form-logs').submit();
}
DupPro.Tools.RefreshAuto = function () {
if ($("#dup-auto-refresh").is(":checked")) {
$('#auto').val(1);
startTimer();
} else {
$('#auto').val(0);
}
}
DupPro.Tools.FullLog = function () {
var $panelL = $('#dpro-log-pnl-left');
var $panelR = $('#dpro-log-pnl-right');
if ($panelR.is(":visible")) {
$panelR.hide(400);
$panelL.css({width: '100%'});
} else {
$panelR.show(200);
$panelL.css({width: '75%'});
}
}
/* TABLE SIZE */
DupPro.Tools.TableSize = function() {
var size = [],
offset = ($('#tableContainer').width() - $($('#error-log tbody tr').get(0)).width()) / ($('#error-log th').length);
$('#error-log th').each(function(i,$this) {
size[i] = $($this).width();
});
$('#error-log tr').each(function(x,$tr) {
$($tr).find('td').each(function(i,$this) {
$($this).width(size[i]+offset);
});
});
};
DupPro.Tools.BoxHeight = function() {
var position = $('#tableContainer').position(),
winHeight = $(window).height(),
height = (winHeight - position.top - $("#wpfooter").height()) - 55;
if(height >= 500) {
$('#error-log tbody, div.tableContainer').height(height);
}
};
<?php if (count($error_log) > 0) : ?>
DupPro.Tools.TableSize();
DupPro.Tools.BoxHeight();
<?php endif; ?>
$(window).resize(function() {
<?php if (count($error_log) > 0) : ?>
DupPro.Tools.TableSize();
DupPro.Tools.BoxHeight();
<?php endif; ?>
});
$('#dup-options').click(function() {
DupPro.Tools.FullLog();
DupPro.Tools.TableSize();
});
$("#dup-refresh").click(DupPro.Tools.Refresh);
$("#dup-auto-refresh").click(DupPro.Tools.RefreshAuto);
$("#filter").on('input change select', function(){
DupPro.Tools.errorFilter();
});
DupPro.Tools.errorFilter();
<?php if ($auto) : ?>
$("#dup-auto-refresh").prop('checked', true);
DupPro.Tools.RefreshAuto();
<?php endif; ?>
});
</script>
<?php endif;

View File

@@ -0,0 +1,122 @@
<?php
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\LicensingController;
use Duplicator\Core\Controllers\ControllersManager;
$thanks_display = 'none';
$error_display = 'none';
$form_display = 'block';
$message = '';
$settingsLicensingUrl = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
LicensingController::L2_SLUG_LICENSING
);
?>
<style>
div.dup-support-all {font-size:13px; line-height:20px;}
div.dup-support-txts-links {width:100%;font-size:14px; font-weight:bold; line-height:26px; text-align:center}
div.dup-support-hlp-area {width:375px; height:160px; float:left; border:1px solid #dfdfdf; border-radius:4px; margin:10px; line-height:18px;box-shadow: 0 8px 6px -6px #ccc;}
table.dup-support-hlp-hdrs {border-collapse:collapse; width:100%; border-bottom:1px solid #dfdfdf}
table.dup-support-hlp-hdrs {background-color:#efefef;}
div.dup-support-hlp-hdrs {
font-weight:bold; font-size:17px; height: 35px; padding:5px 5px 5px 10px;
background-image:-ms-linear-gradient(top, #FFFFFF 0%, #DEDEDE 100%);
background-image:-moz-linear-gradient(top, #FFFFFF 0%, #DEDEDE 100%);
background-image:-o-linear-gradient(top, #FFFFFF 0%, #DEDEDE 100%);
background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #FFFFFF), color-stop(1, #DEDEDE));
background-image:-webkit-linear-gradient(top, #FFFFFF 0%, #DEDEDE 100%);
background-image:linear-gradient(to bottom, #FFFFFF 0%, #DEDEDE 100%);
}
div.dup-support-hlp-hdrs div {padding:5px; margin:4px 20px 0px -20px; text-align: center;}
div.dup-support-hlp-txt{padding:10px 4px 4px 4px; text-align:center}
</style>
<div class="dup-support-all">
<div style="display:<?php echo $form_display; ?>;">
<div style="width:800px; margin:auto; margin-top: 20px">
<!-- HELP LINKS -->
<div class="dup-support-hlp-area" >
<div class="dup-support-hlp-hdrs">
<i class="fas fa-cube fa-2x fa-pull-left"></i>
<div><?php esc_html_e('Knowledgebase', 'duplicator-pro') ?></div>
</div>
<div class="dup-support-hlp-txt">
<?php esc_html_e('Complete Online Documentation', 'duplicator-pro'); ?><br/>
<select id="dup-support-kb-lnks" style="margin-top:18px; font-size:16px; min-width: 170px">
<option value="NULL"> <?php esc_html_e('Choose A Section', 'duplicator-pro') ?> </option>
<option value="<?php echo DUPLICATOR_PRO_BLOG_URL; ?>knowledge-base-article-categories/quick-start/"><?php esc_html_e('Quick Start', 'duplicator-pro') ?></option>
<option value="<?php echo DUPLICATOR_PRO_DUPLICATOR_DOCS_URL; ?>"><?php esc_html_e('User Guide', 'duplicator-pro') ?></option>
<option value="<?php echo DUPLICATOR_PRO_TECH_FAQ_URL; ?>"><?php esc_html_e('FAQs', 'duplicator-pro') ?></option>
<option value="<?php echo DUPLICATOR_PRO_DUPLICATOR_DOCS_URL; ?>changelog/"><?php esc_html_e('Change Log', 'duplicator-pro') ?></option>
<option value="<?php echo esc_url(DUPLICATOR_PRO_BLOG_URL . 'my-account'); ?>"><?php esc_html_e('Dashboard', 'duplicator-pro') ?></option>
</select>
</div>
</div>
<!-- ONLINE SUPPORT -->
<div style="margin: auto; height: 350px; text-align: center">
<!-- HELP TICKET-->
<div class="dup-support-hlp-area">
<div class="dup-support-hlp-hdrs">
<i class="far fa-lightbulb fa-2x fa-pull-left"></i>
<div><?php esc_html_e('Submit Help Ticket', 'duplicator-pro') ?></div>
</div>
<div class="dup-support-hlp-txt">
<?php esc_html_e("Submit support ticket to Duplicator Pro support.", 'duplicator-pro'); ?> <br/>
<i>
<?php esc_html_e("Please have your", 'duplicator-pro'); ?>
<a class="dup-license-page-link" href="<?php echo esc_url($settingsLicensingUrl); ?>">
<?php esc_html_e("license key", 'duplicator-pro'); ?>
</a>
<?php esc_html_e("ready to enter ticket.", 'duplicator-pro'); ?>
</i>
<br/><br/>
<div class="dup-support-txts-links">
<button
class="button button-primary button-large"
data-dup-open-window="<?php echo esc_attr('https://duplicator.com/my-account/support/'); ?>"
data-dup-window-name="<?php echo esc_attr('Duplicator Pro Support'); ?>"
>
<?php esc_html_e('Get Support!', 'duplicator-pro') ?>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="margin-top:112px; text-align:center; display:<?php echo $thanks_display; ?>">
<p style="margin-bottom:0px; font-size:32px"><?php esc_html_e('Thanks, we\'ll get back to you shortly.', 'duplicator-pro'); ?></p>
<p style="font-size:12px">
<?php esc_html_e('*Contact support@duplicator.com if you don\'t get a confirmation email within an hour.', 'duplicator-pro'); ?>
</p>
</div>
<div style="margin-top:112px; text-align:center; display:<?php echo $error_display; ?>">
<p style="margin-bottom:0px; font-size:32px"><?php esc_html_e('There was a problem sending the email.', 'duplicator-pro'); ?></p>
<p>
<?php esc_html_e("We had a problem sending the support email. Instead, send your problem or question to", 'duplicator-pro') ?>
<a href='mailto:support@duplicator.com' target='_blank'>support@duplicator.com.</a>
</p>
<p style='font-weight:bold'><?php echo $message; ?></p>
</div>
</div><br/><br/><br/><br/>
<script>
jQuery(document).ready(function ($) {
//ATTACHED EVENTS
jQuery('#dup-support-kb-lnks').change(function () {
if (jQuery(this).val() != "NULL")
window.open(jQuery(this).val())
});
});
</script>

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,10 @@
<?php
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
?><div class="dup-pro-recovery-message" >
<p class="recovery-reset-message-error">
<i class="fa fa-exclamation-triangle"></i> <b><?php _e('Recovery Point reset issue!', 'duplicator-pro'); ?></b>
<p>
<p class="recovery-error-message">
<!-- here is set the message received from the server -->
</p>
</div>

View File

@@ -0,0 +1,7 @@
<?php
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
?><div class="dup-pro-recovery-message" >
<p class="recovery-reset-message-ok">
<?php _e('The Recovery Point has been reset, all previously copied Recovery URLs are no longer valid.', 'duplicator-pro'); ?>
</p>
</div>

View File

@@ -0,0 +1,23 @@
<?php
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
?><div class="dup-pro-recovery-message" >
<p class="recovery-set-message-error">
<i class="fa fa-exclamation-triangle"></i>&nbsp;<b><?php _e('Recovery Package Issue Detected!', 'duplicator-pro'); ?></b>
<p>
<p class="recovery-error-message">
<!-- here is set the message received from the server -->
</p>
<p>
<?php
printf(
_x(
'For more information see %1$s[the documentation]%2$s',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-handle-recovery-install-setup-launch-issues" target="_blank">',
'</a>'
);
?>
</p>
</div>

View File

@@ -0,0 +1,6 @@
<?php
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
?><div class="dup-pro-recovery-message recovery-set-message-ok" >
<!-- message from js -->
</div>

View File

@@ -0,0 +1,112 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Controllers\RecoveryController;
use Duplicator\Libs\Snap\SnapIO;
/**
* passed values
*
* @var int $recoverPackageId
* @var array<int, array{id: int, created: string, nameHash: string, name: string}> $recoveablePackages
* @var bool $selector
* @var string $subtitle
* @var bool $displayCopyLink
* @var bool $displayCopyButton
* @var bool $displayLaunch
* @var bool $displayDownload
* @var bool $displayInfo
* @var string $viewMode
* @var string $importFailMessage
*/
/** @var \Duplicator\Package\Recovery\RecoveryPackage $recoverPackage */
switch ($viewMode) {
case RecoveryController::VIEW_WIDGET_NO_PACKAGE_SET:
?>
<div class="dup-pro-recovery-active-link-header">
<i class="fa-solid fa-house-fire main-icon"></i>
<div class="main-title">
<?php esc_html_e('Disaster Recovery Backup is Not Set', 'duplicator-pro'); ?>
</div>
<div class="main-subtitle margin-bottom-1">
<b><?php esc_html_e('Backup Age:', 'duplicator-pro'); ?></b>&nbsp;
<span class="dup-pro-recovery-status red"><?php _e('not set', 'duplicator-pro'); ?></span>
</div>
</div>
<div class="margin-bottom-1">
<?php
_e(
'A Disaster Recovery feathure allows one to quickly restore the site to a prior state.
To use this, mark a Backup as the Disaster Recovery Backup, then copy and save off the associated Disaster Recovery URL.
Then, if a problem occurs, browse to the URL to launch a streamlined installer to quickly restore the site.',
'duplicator-pro'
);
?>
</div>
<?php
break;
case RecoveryController::VIEW_WIDGET_NOT_VALID:
?>
<div class="orangered margin-bottom-1">
<?php echo esc_html($importFailMessage); ?>
</div>
<?php
break;
case RecoveryController::VIEW_WIDGET_VALID:
?>
<div class="dup-pro-recovery-active-link-wrapper" >
<div class="dup-pro-recovery-active-link-header" >
<i class="fas fa-house-fire main-icon"></i>
<div class="main-title" >
<?php _e('Disaster Recovery Backup is Set', 'duplicator-pro'); ?>
</div>
<div class="main-subtitle margin-bottom-1" >
<b><?php esc_html_e('Backup Age:', 'duplicator-pro'); ?></b>&nbsp;
<span class="dup-pro-recovery-status green">
<?php echo $recoverPackage->getPackageLife('human'); ?>
</span>
</div>
</div>
<?php if (strlen($subtitle)) { ?>
<p>
<?php echo $subtitle; ?>
</p>
<?php } ?>
<?php if ($displayInfo) { ?>
<div class="dup-pro-recovery-package-info margin-bottom-1" >
<table>
<tbody>
<tr>
<td><?php _e('Name', 'duplicator-pro'); ?>:</td>
<td><b><?php echo esc_html($recoverPackage->getPackageName()); ?></b></td>
</tr>
<tr>
<td><?php _e('Date', 'duplicator-pro'); ?>:</td>
<td><b><?php echo esc_html($recoverPackage->getCreated()); ?></b></td>
</tr>
</tbody>
</table>
</div>
<?php
}
?>
</div>
<?php
break;
default:
?>
<p class="orangered">
<?php echo __('Invalid view mode.', 'duplicator-pro'); ?>
</p>
<?php
}

View File

@@ -0,0 +1,99 @@
<?php
use Duplicator\Package\Recovery\RecoveryPackage;
use Duplicator\Views\ViewHelper;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
/**
* passed values
*
* @var ?RecoveryPackage $recoverPackage
* @var int $recoverPackageId
* @var array<int, array{id: int, created: string, nameHash: string, name: string}> $recoveablePackages
* @var bool $selector
* @var string $subtitle
* @var bool $displayCopyLink
* @var bool $displayCopyButton
* @var bool $displayLaunch
* @var bool $displayDownload
* @var bool $displayInfo
* @var string $viewMode
* @var string $importFailMessage
*/
if (empty($recoveablePackages)) {
return;
}
$installerLink = ($recoverPackage instanceof RecoveryPackage) ? $recoverPackage->getInstallLink() : '';
$disabledClass = empty($installerLink) ? 'disabled' : '';
if ($displayCopyLink) {
$toolTipContent = __(
'The recovery point URL is the link to the recovery point package installer.
The link will run the installer wizard used to re-install and recover the site.
Copy this link and keep it in a safe location to easily restore this site.',
'duplicator-pro'
);
$toolTipContent .= '<br><br><b>';
$toolTipContent .= __('This URL is valid until another recovery point is set.', 'duplicator-pro');
$toolTipContent .= '</b>';
?>
<label>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Recovery Point URL", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($toolTipContent); ?>"
>
</i>
<b><?php _e('Step 2 ', 'duplicator-pro'); ?>:</b> <i><?php _e('Copy Recovery URL &amp; Store in Safe Place', 'duplicator-pro'); ?></i>
</label>
<div class="copy-link <?php echo $disabledClass; ?>"
data-dup-copy-value="<?php echo esc_url($installerLink); ?>"
data-dup-copy-title="<?php _e("Copy Recovery URL to clipboard", 'duplicator-pro'); ?>"
data-dup-copied-title="<?php _e("Recovery URL copied to clipboard", 'duplicator-pro'); ?>" >
<div class="content" >
<?php echo empty($installerLink) ? __('Please set the Recovery Point to generate the Recovery URL', 'duplicator-pro') : $installerLink; ?>
</div>
<i class="far fa-copy copy-icon"></i>
</div>
<?php } ?>
<div class="dup-pro-recovery-buttons" >
<?php
if ($displayLaunch) { ?>
<a href="<?php echo esc_url($installerLink); ?>"
class="button button-primary dup-pro-launch <?php echo $disabledClass; ?>" target="_blank"
title="<?php _e('Initiates system recovery using the Recovery Point URL.', 'duplicator-pro'); ?>"
>
<?php ViewHelper::restoreIcon(); ?>&nbsp;<?php _e('Restore Backup', 'duplicator-pro'); ?>
</a>
<?php
}
if ($displayDownload) {
$title = __(
'This button downloads a recovery launcher that allows you to perform the recovery with a simple click of the downloaded file.',
'duplicator-pro'
);
?>
<button
type="button"
class="button button-primary dup-pro-recovery-download-launcher <?php echo $disabledClass; ?>"
title="<?php echo esc_attr($title); ?>"
>
<i class="fa fa-rocket" ></i>&nbsp;<?php _e('Download Launcher', 'duplicator-pro'); ?>
</button>
<?php
}
if ($displayCopyButton) {
?>
<button type="button" class="button button-primary dup-pro-recovery-copy-url <?php echo $disabledClass; ?>"
data-dup-copy-value="<?php echo $installerLink; ?>"
data-dup-copy-title="<?php _e("Copy Recovery URL to clipboard", 'duplicator-pro'); ?>"
data-dup-copied-title="<?php _e("Recovery URL copied to clipboard", 'duplicator-pro'); ?>" >
<i class="far fa-copy copy-icon"></i>&nbsp;<?php _e('Copy LINK', 'duplicator-pro'); ?>
</button>
<?php
}
?>
</div>

View File

@@ -0,0 +1,245 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Libs\Snap\SnapIO;
?>
<script>
DupPro.Pack.SetRecoveryPoint = function (packageId, callbackOnSuccess, callbackOnError, topHeaderMessage) {
topHeaderMessage = (typeof topHeaderMessage !== 'undefined') ? topHeaderMessage : true;
let okMsgContent = <?php echo json_encode(SnapIO::getInclude(dirname(__FILE__) . '/recovery-message-set-ok.php')); ?>;
let errorMsgContent = <?php echo json_encode(SnapIO::getInclude(dirname(__FILE__) . '/recovery-message-set-error.php')); ?>;
DupPro.Pack.removeRecoveryMessages();
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_set_recovery',
recovery_package: packageId,
fromPageTab: <?php echo json_encode(\Duplicator\Core\Controllers\ControllersManager::getUniqueIdOfCurrentPage()); ?>,
nonce: '<?php echo wp_create_nonce('duplicator_pro_set_recovery'); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
if (topHeaderMessage) {
DupPro.addAdminMessage(okMsgContent, 'notice', {
updateCallback: function (msgNode) {
msgNode.find('.recovery-set-message-ok').html(funcData.adminMessage);
DuplicatorTooltip.reload();
msgNode.find('.dup-pro-recovery-download-launcher').click(function () {
DupPro.Pack.downloadLauncher();
});
}
});
}
if (typeof callbackOnSuccess === "function") {
callbackOnSuccess(funcData, data, textStatus, jqXHR);
}
return '';
},
function (result, data, funcData, textStatus, jqXHR) {
DupPro.addAdminMessage(errorMsgContent, 'error', {
'updateCallback': function (msgNode) {
msgNode.find('.recovery-error-message').html(data.message);
}
});
if (typeof callbackOnError === "function") {
callbackOnError(funcData, data, textStatus, jqXHR);
}
return '';
}
);
};
DupPro.Pack.ResetRecoveryPoint = function (callbackOnSuccess) {
let okMsgContent = <?php echo json_encode(SnapIO::getInclude(dirname(__FILE__) . '/recovery-message-reset-ok.php')); ?>;
let errorMsgContent = <?php echo json_encode(SnapIO::getInclude(dirname(__FILE__) . '/recovery-message-reset-error.php')); ?>;
DupPro.Pack.removeRecoveryMessages();
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_reset_recovery',
nonce: '<?php echo wp_create_nonce('duplicator_pro_reset_recovery'); ?>',
fromPageTab: <?php echo json_encode(\Duplicator\Core\Controllers\ControllersManager::getUniqueIdOfCurrentPage()); ?>,
},
function (result, data, funcData, textStatus, jqXHR) {
DupPro.addAdminMessage(okMsgContent, 'notice');
if (typeof callbackOnSuccess === "function") {
callbackOnSuccess(funcData, data, textStatus, jqXHR);
}
return '';
},
function (result, data, funcData, textStatus, jqXHR) {
DupPro.addAdminMessage(errorMsgContent, 'error', {
'updateCallback': function (msgNode) {
msgNode.find('.recovery-error-message').html(data.message);
}
});
return '';
}
);
};
DupPro.Pack.UpdatgeRecoveryWidget = function (callbackOnSuccess) {
let okMsgContent = <?php echo json_encode(SnapIO::getInclude(dirname(__FILE__) . '/recovery-message-reset-ok.php')); ?>;
let errorMsgContent = <?php echo json_encode(SnapIO::getInclude(dirname(__FILE__) . '/recovery-message-reset-error.php')); ?>;
DupPro.Pack.removeRecoveryMessages();
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_get_recovery_widget',
nonce: '<?php echo wp_create_nonce('duplicator_pro_get_recovery_widget'); ?>',
fromPageTab: <?php echo json_encode(\Duplicator\Core\Controllers\ControllersManager::getUniqueIdOfCurrentPage()); ?>,
},
function (result, data, funcData, textStatus, jqXHR) {
if (typeof callbackOnSuccess === "function") {
callbackOnSuccess(funcData, data, textStatus, jqXHR);
}
return '';
},
function (result, data, funcData, textStatus, jqXHR) {
return <?php json_encode(__('Can\'t update recovery widget', 'duplicator-pro')); ?>;
}
);
};
DupPro.Pack.removeRecoveryMessages = function () {
jQuery('#wpcontent .dup-pro-recovery-message').closest('.notice').remove();
};
DupPro.Pack.SetRecoveryPackageDetails = function (wrapper, details, setColor) {
const setDelayAnimation = 1000;
const setDurationAnimationStart = 500;
const setDurationAnimationEnd = 1000;
let newDetails = jQuery(details);
wrapper.replaceWith(newDetails);
wrapper = newDetails;
wrapper.closest('.dup-pro-import-box').find('.box-title .badge').each(function () {
if (wrapper.find('.dup-pro-recovery-active-link-header .dup-pro-recovery-status').hasClass('green')) {
jQuery(this).removeClass('badge-warn').addClass('badge-pass').text('Good');
} else {
jQuery(this).removeClass('badge-pass').addClass('badge-warn').text('Notice');
}
});
wrapper.find('.dup-pro-recovery-point-selector-area select, .dup-pro-recovery-point-actions .copy-link')
.stop()
.animate({
backgroundColor: setColor
}, setDurationAnimationStart)
.delay(setDelayAnimation)
.animate({
backgroundColor: "transparent"
}, setDurationAnimationEnd);
wrapper.find('.dup-pro-recovery-point-details')
.stop()
.css({
'outline': '5px solid transparent',
'outline-offset': '5px'
})
.animate({
outlineColor: setColor
}, setDurationAnimationStart)
.delay(setDelayAnimation)
.animate({
outlineColor: "transparent",
'outline-width': '0',
'outline-offset': '0'
}, setDurationAnimationEnd);
DupPro.Pack.initRecoveryWidget(wrapper);
};
DupPro.Pack.downloadLauncher = function () {
Duplicator.Util.ajaxWrapper(
{
action: 'duplicator_pro_disaster_launcher_download',
nonce: '<?php echo wp_create_nonce('duplicator_pro_disaster_launcher_download'); ?>'
},
function (result, data, funcData, textStatus, jqXHR) {
if (funcData.success) {
DupPro.downloadContentAsfile(funcData.fileName, funcData.fileContent, 'text/html');
} else {
DupPro.addAdminMessage(funcData.message, 'error');
}
return '';
}
);
};
DupPro.Pack.initRecoveryWidget = function (widgetWrapper) {
widgetWrapper.find('.recovery-reset').off().click(function () {
DupPro.Pack.ResetRecoveryPoint(function (funcData, data, textStatus, jqXHR) {
widgetWrapper.find('.recovery-select').val('');
DupPro.Pack.SetRecoveryPackageDetails(widgetWrapper, funcData.packageDetails, '#e1f5c1');
});
});
widgetWrapper.find('.recovery-set').off().click(function () {
let packageId = widgetWrapper.find('.recovery-select').val();
if (!packageId) {
DupPro.Pack.ResetRecoveryPoint(function (funcData, data, textStatus, jqXHR) {
DupPro.Pack.SetRecoveryPackageDetails(widgetWrapper, funcData.packageDetails, '#e1f5c1');
});
} else {
DupPro.Pack.SetRecoveryPoint(packageId,
function (funcData, data, textStatus, jqXHR) {
DupPro.Pack.SetRecoveryPackageDetails(widgetWrapper, funcData.packageDetails, '#e1f5c1');
},
function (funcData, data, textStatus, jqXHR) {
widgetWrapper.find('.recovery-select').val('');
DupPro.Pack.SetRecoveryPackageDetails(widgetWrapper, '<p class="red" >' + data.message + '</span>', '#fcc3bd');
},
false);
}
});
DuplicatorTooltip.reload();
widgetWrapper.find('.dup-pro-recovery-windget-refresh').off().click(function () {
DupPro.Pack.UpdatgeRecoveryWidget(function (funcData, data, textStatus, jqXHR) {
DupPro.Pack.SetRecoveryPackageDetails(widgetWrapper, funcData.widget, '#e1f5c1');
});
});
widgetWrapper.find('.dup-pro-recovery-download-launcher').off().click(function () {
DupPro.Pack.downloadLauncher();
});
};
jQuery(document).ready(function ($)
{
$('.dup-pro-recovery-widget-wrapper').each(function () {
let widgetWrapper = jQuery(this);
DupPro.Pack.initRecoveryWidget(widgetWrapper);
});
$('.dup-pro-open-help-link').click(function (event) {
event.stopPropagation();
let helpLink = $('#contextual-help-link');
$("html, body").animate({scrollTop: 0}, "fast");
if (helpLink.hasClass('screen-meta-active')) {
return;
}
helpLink.trigger('click');
});
});
</script>

View File

@@ -0,0 +1,107 @@
<?php
use Duplicator\Controllers\PackagesPageController;
use Duplicator\Core\CapMng;
use Duplicator\Package\Recovery\RecoveryPackage;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
/**
* Variables
*
* @var RecoveryPackage $recoverPackage
* @var int $recoverPackageId
* @var array<int, array{id: int, created: string, nameHash: string, name: string}> $recoveablePackages
* @var bool $selector
* @var string $subtitle
* @var bool $displayCopyLink
* @var bool $displayCopyButton
* @var bool $displayLaunch
* @var bool $displayDownload
* @var bool $displayInfo
* @var string $viewMode
* @var string $importFailMessage
*/
if (!$selector) {
return;
}
$packagesURL = PackagesPageController::getInstance()->getPageUrl();
?>
<div class="dup-pro-recovery-point-selector">
<?php if (empty($recoveablePackages)) { ?>
<div class="dup-pro-notice-details">
<div class="margin-bottom-1" >
<b><?php _e('Would you like to create a Recovery Point before running this import?', 'duplicator-pro'); ?></b>
</div>
<b><?php _e('How to create:', 'duplicator-pro'); ?></b>
<ol class="dup-pro-simple-style-list" >
<li>
<?php _e('Open the ', 'duplicator-pro'); ?>
<a href="<?php echo esc_url($packagesURL); ?>" target="_blank">
<?php _e('packages screen', 'duplicator-pro'); ?>
</a>
<i class="fas fa-external-link-alt fa-small" ></i>
<?php _e('and create a valid recovery package.', 'duplicator-pro'); ?>
</li>
<li>
<?php _e('On the packages screen click the package\'s Hamburger menu and select "Set Recovery Point".', 'duplicator-pro'); ?>
</li>
<li>
<span class="dup-pro-recovery-windget-refresh link-style"><?php _e('Refresh', 'duplicator-pro'); ?></span>
<?php _e('this page to show and choose the recovery point', 'duplicator-pro'); ?>.
</li>
</ol>
</div>
<?php } else {
$tooltipContent = __(
'A Recovery Point allows one to quickly restore the site to a prior state.
To use this, mark a package as the Recovery Point, then copy and save off the associated URL.
Then, if a problem occurs, browse to the URL to launch a streamlined installer to quickly restore the site.',
'duplicator-pro'
);
?>
<div class="dup-pro-recovery-point-selector-area-wrapper" >
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
<span class="dup-pro-opening-packages-windows" >
<a href="<?php echo esc_url($packagesURL); ?>" >[<?php _e('Create New', 'duplicator-pro'); ?>]</a>
</span>
<?php } ?>
<label>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Choose Recovery Point Archive", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tooltipContent); ?>">
</i>
<b><?php _e('Step 1 ', 'duplicator-pro'); ?>:</b> <i><?php _e('Choose Recovery Point Archive', 'duplicator-pro'); ?></i>
</label>
<div class="dup-pro-recovery-point-selector-area">
<select class="recovery-select" name="recovery_package" >
<option value=""> -- <?php _e('Not selected', 'duplicator-pro'); ?> -- </option>
<?php
$currentDay = null;
foreach ($recoveablePackages as $package) {
$packageDay = date("Y/m/d", strtotime($package['created']));
if ($packageDay != $currentDay) {
if (!is_null($currentDay)) {
?>
</optgroup>
<?php } ?>
<optgroup label="<?php echo esc_attr($packageDay); ?>">
<?php
$currentDay = $packageDay;
}
?>
<option value="<?php echo $package['id']; ?>" <?php selected($recoverPackageId, $package['id']) ?>>
<?php echo '[' . $package['created'] . '] ' . $package['name']; ?>
</option>
<?php } ?>
</optgroup>
</select>
<button type="button" class="button recovery-reset" ><?php echo _e('Reset', 'duplicator-pro'); ?></button>
<button type="button" class="button button-primary recovery-set" ><?php echo _e('Set', 'duplicator-pro'); ?></button>
</div>
</div>
<?php } ?>
</div>

View File

@@ -0,0 +1,36 @@
<?php
use Duplicator\Package\Recovery\RecoveryPackage;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
/**
* Variables
*
* @var RecoveryPackage $recoverPackage
* @var int $recoverPackageId
* @var array<int, array{id: int, created: string, nameHash: string, name: string}> $recoveablePackages
* @var bool $displayDetails
* @var bool $selector
* @var string $subtitle
* @var bool $displayCopyLink
* @var bool $displayCopyButton
* @var bool $displayLaunch
* @var bool $displayDownload
* @var bool $displayInfo
* @var string $viewMode
* @var string $importFailMessage
*/
?>
<div class="dup-pro-recovery-widget-wrapper" >
<?php if ($displayDetails) { ?>
<div class="dup-pro-recovery-point-details margin-bottom-1">
<?php require dirname(__FILE__) . '/recovery-widget-details.php'; ?>
</div>
<?php } ?>
<?php require dirname(__FILE__) . '/recovery-widget-selector.php'; ?>
<div class="dup-pro-recovery-point-actions">
<?php require dirname(__FILE__) . '/recovery-widget-link-actions.php'; ?>
</div>
</div>

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,14 @@
<?php
defined("ABSPATH") or die("");
$inner_page = isset($_REQUEST['inner_page']) ? sanitize_text_field($_REQUEST['inner_page']) : 'templates';
switch ($inner_page) {
case 'templates':
include(DUPLICATOR____PATH . '/views/tools/templates/template.list.php');
break;
case 'edit':
include(DUPLICATOR____PATH . '/views/tools/templates/template.edit.php');
break;
}

View File

@@ -0,0 +1,604 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Libs\Snap\SnapJson;
use Duplicator\Libs\Snap\SnapUtil;
use Duplicator\Models\BrandEntity;
$tplMng = TplMng::getInstance();
/** @var bool */
$blur = TplMng::getInstance()->getGlobalValue('blur');
$templates_tab_url = ControllersManager::getMenuLink(
ControllersManager::TOOLS_SUBMENU_SLUG,
ToolsPageController::L2_SLUG_TEMPLATE
);
$edit_template_url = ControllersManager::getMenuLink(
ControllersManager::TOOLS_SUBMENU_SLUG,
ToolsPageController::L2_SLUG_TEMPLATE,
null,
array('inner_page' => 'edit')
);
$bandListUrl = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND
);
$brandDefaultEditUrl = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND,
[
'view' => 'edit',
'action' => 'default',
]
);
$brandBaseEditUrl = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE,
SettingsPageController::L3_SLUG_PACKAGE_BRAND,
[
'view' => 'edit',
'action' => 'edit',
]
);
global $wp_version;
global $wpdb;
$global = DUP_PRO_Global_Entity::getInstance();
$nonce_action = 'duppro-template-edit';
$was_updated = false;
$package_template_id = SnapUtil::sanitizeIntInput(SnapUtil::INPUT_REQUEST, 'package_template_id', -1);
if (($package_templates = DUP_PRO_Package_Template_Entity::getAll()) === false) {
$package_templates = array();
}
$package_template_count = count($package_templates);
// For now not including in filters since don't want to encourage use
// with schedules since filtering creates incomplete multisite
$displayMultisiteTab = (is_multisite() && License::can(License::CAPABILITY_MULTISITE_PLUS));
$view_state = DUP_PRO_UI_ViewState::getArray();
$ui_css_archive = (DUP_PRO_UI_ViewState::getValue('dup-template-archive-panel') ? 'display:block' : 'display:none');
$ui_css_install = (DUP_PRO_UI_ViewState::getValue('dup-template-install-panel') ? 'display:block' : 'display:none');
if (
$package_template_id == -1 ||
($package_template = DUP_PRO_Package_Template_Entity::getById($package_template_id)) == false
) {
$package_template = new DUP_PRO_Package_Template_Entity();
}
DUP_PRO_Log::traceObject("getting template $package_template_id", $package_template);
if (!empty($_REQUEST['action'])) {
DUP_PRO_U::verifyNonce($_REQUEST['_wpnonce'], $nonce_action);
if ($_REQUEST['action'] == 'save') {
DUP_PRO_Log::traceObject('request', $_REQUEST);
// Checkboxes don't set post values when off so have to manually set these
$package_template->setFromInput(SnapUtil::INPUT_REQUEST);
$package_template->save();
$was_updated = true;
} elseif ($_REQUEST['action'] == 'copy-template') {
$source_template_id = SnapUtil::sanitizeIntInput(SnapUtil::INPUT_REQUEST, 'duppro-source-template-id', -1);
if ($source_template_id > 0) {
$package_template->copy_from_source_id($source_template_id);
$package_template->save();
}
}
}
$installer_cpnldbaction = $package_template->installer_opts_cpnl_db_action;
$upload_dir = DUP_PRO_Archive::getArchiveListPaths('uploads');
$content_path = DUP_PRO_Archive::getArchiveListPaths('wpcontent');
$archive_format = ($global->getBuildMode() == DUP_PRO_Archive_Build_Mode::DupArchive ? 'daf' : 'zip');
?>
<form
id="dpro-template-form"
class="dup-monitored-form <?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
data-parsley-validate data-parsley-ui-enabled="true"
action="<?php echo esc_url($edit_template_url); ?>"
method="post"
>
<?php wp_nonce_field($nonce_action); ?>
<input type="hidden" id="dpro-template-form-action" name="action" value="save">
<input type="hidden" name="package_template_id" value="<?php echo intval($package_template->getId()); ?>">
<!-- ====================
SUB-TABS -->
<?php if ($was_updated) : ?>
<div class="notice notice-success is-dismissible dpro-wpnotice-box">
<p>
<?php esc_html_e('Template Updated', 'duplicator-pro'); ?>
</p>
</div>
<?php endif; ?>
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar">
<tr>
<td>
<?php
if ($package_template_count > 0) :
$general_templates = array();
$existing_templates = array();
foreach ($package_templates as $copy_package_template) {
if ($copy_package_template->getId() != $package_template->getId()) {
if ($copy_package_template->is_default || $copy_package_template->is_manual) {
$general_templates[$copy_package_template->getId()] = $copy_package_template->is_manual
? __("Active Build Settings", 'duplicator-pro')
: $copy_package_template->name;
} else {
$existing_templates[$copy_package_template->getId()] = $copy_package_template->name;
}
}
}
?>
<select name="duppro-source-template-id">
<option value="-1"><?php esc_html_e("Copy From", 'duplicator-pro'); ?></option>
<?php
if (!empty($general_templates)) {
asort($general_templates);
?>
<optgroup label="<?php esc_attr_e("General Templates", 'duplicator-pro'); ?>">
<?php
foreach ($general_templates as $id => $val) {
?>
<option value="<?php echo $id; ?>"><?php echo esc_html($val); ?></option>
<?php
}
?>
</optgroup>
<?php
}
?>
<?php
if (!empty($existing_templates)) {
asort($existing_templates);
?>
<optgroup label="<?php esc_attr_e("Existing Templates", 'duplicator-pro'); ?>">
<?php
foreach ($existing_templates as $id => $val) {
?>
<option value="<?php echo $id; ?>"><?php echo esc_html($val); ?></option>
<?php
}
?>
</optgroup>
<?php
}
?>
</select>
<input type="button" class="button action" value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>" onclick="DupPro.Template.Copy()">
<?php else : ?>
<select disabled="disabled"><option value="-1" selected="selected"><?php _e('Copy From', 'duplicator-pro'); ?></option></select>
<input type="button" class="button action" value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>" onclick="DupPro.Template.Copy()" disabled="disabled">
<?php endif; ?>
</td>
<td>
<div class="btnnav">
<a href="<?php echo esc_url($templates_tab_url); ?>" class="button dup-goto-templates-btn">
<i class="far fa-clone"></i> <?php esc_html_e('Templates', 'duplicator-pro'); ?>
</a>
<?php if ($package_template_id != -1) : ?>
<a href="<?php echo esc_url($edit_template_url); ?>" class="button">
<?php esc_html_e("Add New", 'duplicator-pro'); ?>
</a>
<?php endif; ?>
</div>
</td>
</tr>
</table>
<hr class="dpro-edit-toolbar-divider"/>
<div class="dpro-template-general">
<div class="margin-b-10px">
<label><?php _e("Recovery Status", 'duplicator-pro'); ?>:</label> &nbsp;
<?php $package_template->recoveableHtmlInfo(); ?> <br/><br/>
</div>
<label><?php _e("Template", 'duplicator-pro'); ?>:</label>
<input type="text" id="template-name" name="name" data-parsley-errors-container="#template_name_error_container"
data-parsley-required="true" value="<?php echo esc_attr($package_template->name); ?>" autocomplete="off" maxlength="125">
<div id="template_name_error_container" class="duplicator-error-container"></div>
<label><?php _e("Notes", 'duplicator-pro'); ?>:</label> <br/>
<textarea id="template-notes" name="notes" style="height:50px"><?php echo esc_textarea($package_template->notes); ?></textarea>
</div>
<!-- ===============================
ARCHIVE -->
<div class="dup-box dup-archive-filters-wrapper">
<div class="dup-box-title">
<i class="far fa-file-archive fa-sm"></i> <?php esc_html_e('Archive', 'duplicator-pro') ?>
<sup class="dup-box-title-badge">
<?php echo esc_html($archive_format); ?>
</sup> &nbsp; &nbsp;
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Archive', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dup-template-archive-panel" style="<?php echo esc_attr($ui_css_archive); ?>">
<!-- ===================
NESTED TABS -->
<div data-dpro-tabs="true">
<ul>
<li class="filter-files-tab"><?php esc_html_e('Files', 'duplicator-pro') ?></li>
<li class="filter-db-tab"><?php esc_html_e('Database', 'duplicator-pro') ?></li>
<?php if ($displayMultisiteTab) { ?>
<li class="filter-mu-tab"><?php esc_html_e('Multisite', 'duplicator-pro') ?></li>
<?php } ?>
<li class="archive-setup-tab"><?php esc_html_e('Setup', 'duplicator-pro') ?></li>
</ul>
<!-- ===================
TAB1: FILES -->
<div class="filter-files-tab-content" >
<?php $tplMng->render(
'parts/filters/package_components',
array(
'archiveFilterOn' => $package_template->archive_filter_on,
'archiveFilterDirs' => $package_template->archive_filter_dirs,
'archiveFilterFiles' => $package_template->archive_filter_files,
'archiveFilterExtensions' => $package_template->archive_filter_exts,
'components' => $package_template->components,
)
); ?>
</div>
<!-- ===================
TAB2: DATABASE -->
<div>
<div class="dup-template-db-area">
<?php
$tableList = explode(',', $package_template->database_filter_tables);
$tplMng->render(
'parts/filters/tables_list_filter',
array(
'dbFilterOn' => $package_template->database_filter_on,
'dbPrefixFilter' => $package_template->databasePrefixFilter,
'dbPrefixSubFilter' => $package_template->databasePrefixSubFilter,
'tablesSlected' => $tableList,
)
);
?><br/>
<div class="dup-form-item">
<span class="title">
<?php esc_html_e("Compatibility Mode", 'duplicator-pro') ?>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Legacy Support", 'duplicator-pro'); ?>"
data-tooltip="<?php
esc_attr_e(
'This option is not available as a template setting.
It can only be used when creating a new package. Please see the FAQ for a full overview of using this feature.',
'duplicator-pro'
); ?>"
>
</i>
</span>
</div>
<i><?php
$url = "<a href='" . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . "how-to-fix-database-write-issues' target='_blank'>"
. esc_html__('FAQ details', 'duplicator-pro') . "</a>";
printf(esc_html__("Not enabled for template settings. Please see the full %s", 'duplicator-pro'), $url);
?>
</i>
</div>
</div>
<!-- ===================
MULTI-SITE TAB 3: -->
<?php if ($displayMultisiteTab) : ?>
<div>
<div class="dup-template-mu-area">
<?php esc_html_e("Support for multisite filters is only available when creating a new package.", 'duplicator-pro'); ?> <br/>
<?php esc_html_e("To create a new package goto the Packages screen and click the 'Create New' button.", 'duplicator-pro'); ?>
</div>
</div>
<?php endif; ?>
<!-- ===================
SETUP TAB 4: -->
<?php
$tplMng->render(
'admin_pages/packages/setup/archive-setup-tab',
[
'secureOn' => $package_template->installer_opts_secure_on,
'securePass' => $package_template->installerPassowrd,
]
);
?>
</div>
<!-- end tab control -->
</div>
</div>
<br />
<!-- ===============================
INSTALLER -->
<div class="dup-box">
<div class="dup-box-title">
<i class="fa fa-bolt fa-sm"></i> <?php esc_html_e('Installer', 'duplicator-pro') ?>
<button class="dup-box-arrow">
<span class="screen-reader-text"><?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Installer', 'duplicator-pro') ?></span>
</button>
</div>
<div class="dup-box-panel" id="dup-template-install-panel" style="<?php echo esc_attr($ui_css_install); ?>">
<div class="dpro-panel-optional-txt">
<b><?php esc_html_e('All values in this section are', 'duplicator-pro'); ?> <u><?php esc_html_e('optional', 'duplicator-pro'); ?></u></b>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Setup/Prefills", 'duplicator-pro'); ?>"
data-tooltip="<?php
esc_attr_e(
'All values in this section are OPTIONAL! If you know ahead of time the database input fields the installer will use,
then you can optionally enter them here and they will be prefilled at install time.
Otherwise you can just enter them in at install time and ignore all these options in the Installer section.',
'duplicator-pro'
);
?>"></i>
</div>
<table class="dpro-install-setup" style="margin-top:-10px">
<tr>
<td colspan="2"><div class="dup-package-hdr-1"><?php esc_html_e("Setup", 'duplicator-pro') ?></div></td>
</tr>
<tr>
<td style="width:130px"><b><?php esc_html_e("Branding", 'duplicator-pro') ?>:</b></td>
<td>
<?php
if (License::can(License::CAPABILITY_BRAND)) :
$brands = BrandEntity::getAllWithDefault();
?>
<select name="installer_opts_brand" id="installer_opts_brand" onchange="DupPro.Template.BrandChange();">
<?php
$active_brand_id = $package_template->installer_opts_brand;
foreach ($brands as $i => $brand) :
?>
<option value="<?php echo $brand->getId(); ?>" title="<?php echo esc_attr($brand->notes); ?>"<?php if (isset($_REQUEST['inner_page']) && $_REQUEST['inner_page'] == 'edit') {
selected($brand->getId(), $active_brand_id);
} ?>>
<?php echo esc_html($brand->name); ?>
</option>
<?php endforeach; ?>
</select>
<a href="javascript:void(0)" target="_blank" class="button" id="brand-preview">
<?php esc_html_e("Preview", 'duplicator-pro'); ?>
</a> &nbsp;
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Choose Brand", 'duplicator-pro'); ?>"
data-tooltip="<?php esc_attr_e('This option changes the branding of the installer file. Click the preview button to see the selected style.', 'duplicator-pro'); ?>"></i>
<?php else : ?>
<a href="<?php echo esc_url($bandListUrl); ?>" class="upgrade-link" target="_blank">
<?php esc_html_e("Enable Branding", 'duplicator-pro'); ?>
</a>
<?php endif; ?>
<br/><br/>
</td>
</tr>
</table>
<br/>
<table style="width:100%">
<tr>
<td colspan="2"><div class="dup-package-hdr-1"><?php esc_html_e("Prefills", 'duplicator-pro') ?></div></td>
</tr>
</table>
<!-- ===================
STEP1 TABS -->
<div data-dpro-tabs="true">
<ul>
<li><?php esc_html_e('Basic', 'duplicator-pro') ?></li>
<li id="dpro-cpnl-tab-lbl"><?php esc_html_e('cPanel', 'duplicator-pro') ?></li>
</ul>
<!-- ===================
TAB1: Basic -->
<div class="dup-template-basic-tab">
<table class="form-table" role="presentation">
<tr>
<td colspan="2">
<b class="dpro-hdr"><?php esc_html_e('MySQL Server', 'duplicator-pro'); ?></b>
</td>
</tr>
<tr>
<th scope="row"><?php _e("Host", 'duplicator-pro'); ?>:</th>
<td><input type="text" placeholder="localhost" name="installer_opts_db_host" value="<?php echo esc_attr($package_template->installer_opts_db_host); ?>"></td>
</tr>
<tr>
<th><label><?php _e("Database", 'duplicator-pro'); ?>:</label></th>
<td><input type="text" placeholder="<?php esc_attr_e('valid database name', 'duplicator-pro'); ?>" name="installer_opts_db_name" value="<?php echo esc_attr($package_template->installer_opts_db_name); ?>"></td>
</tr>
<tr>
<th><label><?php _e("User", 'duplicator-pro'); ?>:</label></th>
<td><input type="text" placeholder="<?php esc_attr_e('valid database user', 'duplicator-pro'); ?>" name="installer_opts_db_user" value="<?php echo esc_attr($package_template->installer_opts_db_user); ?>"></td>
</tr>
</table>
<br/><br/>
</div>
<!-- ===================
TAB2: cPanel -->
<div class="dup-template-cpanel-tab">
<table class="form-table" role="presentation">
<tr>
<td colspan="2"><b class="dpro-hdr"><?php esc_html_e('cPanel Login', 'duplicator-pro'); ?></b></td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Automation", 'duplicator-pro'); ?>:</label></th>
<td>
<input type="checkbox" name="installer_opts_cpnl_enable" id="installer_opts_cpnl_enable" <?php checked($package_template->installer_opts_cpnl_enable); ?> >
<label for="installer_opts_cpnl_enable">Auto Select cPanel</label>
<i
class="fas fa-question-circle fa-sm"
data-tooltip-title="Auto Select cPanel:"
data-tooltip="<?php esc_attr_e('Enabling this options will automatically select the cPanel tab when step one of the installer is shown.', 'duplicator-pro'); ?>" >
</i>
&nbsp; &nbsp;
</td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("Host", 'duplicator-pro'); ?>:</label></th>
<td><input type="text" name="installer_opts_cpnl_host" value="<?php echo esc_attr($package_template->installer_opts_cpnl_host); ?>" placeholder="<?php esc_attr_e('valid cpanel host address', 'duplicator-pro'); ?>"></td>
</tr>
<tr>
<th scope="row"><label><?php esc_html_e("User", 'duplicator-pro'); ?>:</label></th>
<td><input type="text" name="installer_opts_cpnl_user" value="<?php echo esc_attr($package_template->installer_opts_cpnl_user); ?>" placeholder="<?php esc_attr_e('valid cpanel user login', 'duplicator-pro'); ?>"></td>
</tr>
<tr>
<td colspan="2">
<b class="dpro-hdr"><?php esc_html_e('MySQL Server', 'duplicator-pro'); ?></b>
</td>
</tr>
<tr>
<th scope="row"><label><?php _e("Action", 'duplicator-pro'); ?>:</label></th>
<td>
<select name="installer_opts_cpnl_db_action" id="cpnl-dbaction">
<option value="create" <?php echo ($installer_cpnldbaction == 'create') ? 'selected' : ''; ?>>Create A New Database</option>
<option value="empty" <?php echo ($installer_cpnldbaction == 'empty') ? 'selected' : ''; ?>>Connect to Existing Database and Remove All Data</option>
<!--option value="rename">Connect to Existing Database and Rename Existing Tables</option-->
</select>
</td>
</tr>
<tr>
<th scope="row"><label><?php _e("Host", 'duplicator-pro'); ?>:</label></th>
<td><input type="text" name="installer_opts_cpnl_db_host" value="<?php echo esc_attr($package_template->installer_opts_cpnl_db_host); ?>" placeholder="<?php esc_attr_e('localhost', 'duplicator-pro'); ?>" /></td>
</tr>
<tr>
<th scope="row"><label><?php _e("Database", 'duplicator-pro'); ?>:</label></th>
<td><input type="text" name="installer_opts_cpnl_db_name" value="<?php echo esc_attr($package_template->installer_opts_cpnl_db_name); ?>" placeholder="<?php esc_attr_e('valid database name', 'duplicator-pro'); ?>" /></td>
</tr>
<tr>
<th scope="row"><label><?php _e("User", 'duplicator-pro'); ?>::</label></th>
<td><input type="text" name="installer_opts_cpnl_db_user" value="<?php echo esc_attr($package_template->installer_opts_cpnl_db_user); ?>" placeholder="<?php esc_attr_e('valid database user', 'duplicator-pro'); ?>" /></td>
</tr>
</table>
</div>
</div><br/>
<small><?php esc_html_e("All other inputs can be entered at install time.", 'duplicator-pro') ?></small>
<br/><br/>
</div>
</div>
<br/>
<button
class="button button-primary dup-save-template-btn"
type="submit"
>
<?php esc_html_e('Save Template', 'duplicator-pro'); ?>
</button>
</form>
<?php
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('Transfer Error', 'duplicator-pro');
$alert1->message = __('You can\'t exclude all sites!', 'duplicator-pro');
$alert1->initAlert();
?>
<script>
jQuery(document).ready(function ($) {
/* When installer brand changes preview button is updated */
DupPro.Template.BrandChange = function ()
{
var $brand = $("#installer_opts_brand");
var $id = $brand.val();
var $url = new Array();
$url = [
<?php echo SnapJson::jsonEncode($brandDefaultEditUrl); ?>,
<?php echo SnapJson::jsonEncode($brandBaseEditUrl); ?> + '&id=' + $id
];
$("#brand-preview").attr('href', $url[ $id > 0 ? 1 : 0 ]);
};
/* Enables strike through on excluded DB table */
DupPro.Template.ExcludeTable = function (check)
{
var $cb = $(check);
if ($cb.is(":checked")) {
$cb.closest("label").css('textDecoration', 'line-through');
} else {
$cb.closest("label").css('textDecoration', 'none');
}
}
/* Used to duplicate a template */
DupPro.Template.Copy = function ()
{
$("#dpro-template-form-action").val('copy-template');
$("#dpro-template-form").parsley().destroy();
$("#dpro-template-form").submit();
};
//INIT
$('#template-name').focus().select();
// $('#_archive_filter_files').val($('#_archive_filter_files').val().trim());
//Default to cPanel tab if used
$('#cpnl-enable').is(":checked") ? $('#dpro-cpnl-tab-lbl').trigger("click") : null;
DupPro.EnableInstallerPassword();
DupPro.Template.BrandChange();
//MU-Transfer buttons
$('#mu-include-btn').click(function () {
return !$('#mu-exclude option:selected').remove().appendTo('#mu-include');
});
$('#mu-exclude-btn').click(function () {
var include_all_count = $('#mu-include option').length;
var include_selected_count = $('#mu-include option:selected').length;
if (include_all_count > include_selected_count) {
return !$('#mu-include option:selected').remove().appendTo('#mu-exclude');
} else {
<?php $alert1->showAlert(); ?>
}
});
$('#dpro-template-form').submit(function () {
DupPro.Pack.FillExcludeTablesList();
});
//Defaults to Installer cPanel tab if 'Auto Select cPanel' is checked
$('#installer_opts_cpnl_enable').is(":checked") ? $('#dpro-cpnl-tab-lbl').trigger("click") : null;
});
</script>

View File

@@ -0,0 +1,315 @@
<?php
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
defined("ABSPATH") or die("");
/**
* @var DUP_PRO_Package_Template_Entity $package_template
*/
$nonce_action = 'duppro-template-list';
$display_edit = false;
/** @var bool */
$blur = TplMng::getInstance()->getGlobalValue('blur');
$templates_tab_url = ControllersManager::getMenuLink(
ControllersManager::TOOLS_SUBMENU_SLUG,
ToolsPageController::L2_SLUG_TEMPLATE
);
$edit_template_url = ControllersManager::getMenuLink(
ControllersManager::TOOLS_SUBMENU_SLUG,
ToolsPageController::L2_SLUG_TEMPLATE,
null,
array('inner_page' => 'edit')
);
if (!empty($_REQUEST['action'])) {
$nonce_val = isset($_POST['_wpnonce']) ? $_POST['_wpnonce'] : $_GET['_wpnonce'];
DUP_PRO_U::verifyNonce($nonce_val, $nonce_action);
$action = sanitize_text_field($_REQUEST['action']);
switch ($action) {
case 'add':
case 'edit':
$display_edit = true;
break;
case 'bulk-delete':
if (is_array($_REQUEST['selected_id'])) {
$package_template_ids = array_map("intval", $_REQUEST['selected_id']);
} else {
$package_template_ids = [ ((int) $_REQUEST['selected_id']) ];
}
foreach ($package_template_ids as $package_template_id) {
DUP_PRO_Log::trace("attempting to delete $package_template_id");
DUP_PRO_Package_Template_Entity::deleteById($package_template_id);
}
break;
case 'delete':
$package_template_id = (int) $_REQUEST['package_template_id'];
DUP_PRO_Log::trace("attempting to delete $package_template_id");
DUP_PRO_Package_Template_Entity::deleteById($package_template_id);
break;
default:
break;
}
}
if (($package_templates = DUP_PRO_Package_Template_Entity::getAllWithoutManualMode()) === false) {
$package_templates = array();
}
$package_template_count = count($package_templates);
?>
<form
id="dup-package-form"
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
action="<?php echo esc_url($templates_tab_url); ?>"
method="post"
>
<?php wp_nonce_field($nonce_action); ?>
<input type="hidden" id="dup-package-form-action" name="action" value=""/>
<input type="hidden" id="dup-package-selected-package-template" name="package_template_id" value="-1"/>
<!-- ====================
TOOL-BAR -->
<table class="dpro-edit-toolbar">
<tr>
<td>
<select id="bulk_action">
<option value="-1" selected="selected"><?php esc_html_e("Bulk Actions", 'duplicator-pro'); ?></option>
<option value="delete" title="Delete selected package(s)"><?php esc_html_e("Delete", 'duplicator-pro'); ?></option>
</select>
<input type="button" class="button action" value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>" onclick="DupPro.Template.BulkAction()">
</td>
<td>
<div class="btnnav">
<a href="<?php echo esc_url($edit_template_url); ?>" class="button dup-add-template-btn"><?php esc_html_e('Add New', 'duplicator-pro'); ?></a>
</div>
</td>
</tr>
</table>
<!-- ====================
LIST ALL SCHEDULES -->
<table class="widefat dup-template-list-tbl striped">
<thead>
<tr>
<th class="col-check"><input type="checkbox" id="dpro-chk-all" title="Select all packages" onclick="DupPro.Template.SetDeleteAll(this)"></th>
<th class="col-name"><?php _e('Name', 'duplicator-pro'); ?></th>
<th class="col-recover"><?php _e('Recovery', 'duplicator-pro'); ?></th>
<th class="col-empty"></th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
foreach ($package_templates as $package_template) :
$i++;
$schedules = DUP_PRO_Schedule_Entity::get_by_template_id($package_template->getId());
$schedule_count = count($schedules);
?>
<tr class="package-row <?php echo ($i % 2) ? 'alternate' : ''; ?>">
<td class="col-check">
<?php if ($package_template->is_default == false) : ?>
<input name="selected_id[]" type="checkbox" value="<?php echo intval($package_template->getId()); ?>" class="item-chk" />
<?php else : ?>
<input type="checkbox" disabled />
<?php endif; ?>
</td>
<td class="col-name" >
<a
href="javascript:void(0);"
onclick="DupPro.Template.Edit(<?php echo intval($package_template->getId()); ?>);"
class="name"
data-template-id="<?php echo intval($package_template->getId()); ?>"
>
<?php echo esc_html($package_template->name); ?>
</a>
<div class="sub-menu">
<a class="dup-edit-template-btn" href="javascript:void(0);"onclick="DupPro.Template.Edit(<?php echo $package_template->getId(); ?>);" ><?php esc_html_e('Edit', 'duplicator-pro'); ?></a> |
<a class="dup-copy-template-btn" href="javascript:void(0);"onclick="DupPro.Template.Copy(<?php echo $package_template->getId(); ?>);" ><?php esc_html_e('Copy', 'duplicator-pro'); ?></a>
<?php if ($package_template->is_default == false) : ?>
| <a
class="dup-delete-template-btn"
href="javascript:void(0);"
onclick="DupPro.Template.Delete(<?php echo $package_template->getId() ?>, <?php echo intval($schedule_count); ?>);"
>
<?php esc_html_e('Delete', 'duplicator-pro'); ?>
</a>
<?php endif; ?>
</div>
</td>
<td class="col-recover" >
<?php $package_template->recoveableHtmlInfo(true); ?>
</td>
<td>&nbsp;</td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot>
<tr>
<th colspan="8" style="text-align:right; font-size:12px">
<?php echo esc_html__('Total', 'duplicator-pro') . ': ' . $package_template_count; ?>
</th>
</tr>
</tfoot>
</table>
</form>
<?php
$alert1 = new DUP_PRO_UI_Dialog();
$alert1->title = __('Bulk Action Required', 'duplicator-pro');
$alert1->message = __('Please select an action from the "Bulk Actions" drop down menu!', 'duplicator-pro');
$alert1->initAlert();
$alert2 = new DUP_PRO_UI_Dialog();
$alert2->title = __('Selection Required', 'duplicator-pro');
$alert2->message = __('Please select at least one template to delete!', 'duplicator-pro');
$alert2->initAlert();
$confirm1 = new DUP_PRO_UI_Dialog();
$confirm1->wrapperClassButtons = 'dup-delete-template-dialog-bulk';
$confirm1->title = __('Delete the selected templates?', 'duplicator-pro');
$confirm1->message = __('All schedules using this template will be reassigned to the "Default" Template.', 'duplicator-pro');
$confirm1->message .= '<br/><br/>';
$confirm1->message .= '<small><i>' . __('Note: This action removes all selected custom templates.', 'duplicator-pro') . '</i></small>';
$confirm1->progressText = __('Removing Templates, Please Wait...', 'duplicator-pro');
$confirm1->jsCallback = 'DupPro.Storage.BulkDelete()';
$confirm1->initConfirm();
$confirm2 = new DUP_PRO_UI_Dialog();
$confirm2->wrapperClassButtons = 'dup-delete-template-dialog-single';
$confirm2->title = __('Are you sure you want to delete this template?', 'duplicator-pro');
$confirm2->message = __('All schedules using this template will be reassigned to the "Default" Template.', 'duplicator-pro');
$confirm2->progressText = $confirm1->progressText;
$confirm2->jsCallback = 'DupPro.Template.DeleteThis(this)';
$confirm2->initConfirm();
?>
<script>
jQuery(document).ready(function ($) {
//Shows detail view
DupPro.Template.View = function (id) {
$('#' + id).toggle();
}
// Edit template
DupPro.Template.Edit = function (id) {
document.location.href = '<?php echo "$edit_template_url&package_template_id="; ?>' + id;
};
// Copy template
DupPro.Template.Copy = function (id) {
<?php
$params = array(
'action=copy-template',
'_wpnonce=' . wp_create_nonce('duppro-template-edit'),
'package_template_id=-1',
'duppro-source-template-id=', // last params get id from js param function
);
$edit_template_url .= '&' . implode('&', $params);
?>
document.location.href = '<?php echo "$edit_template_url"; ?>' + id;
};
//Delets a single record
DupPro.Template.Delete = function (id, schedule_count) {
var message = "";
<?php $confirm2->showConfirm(); ?>
if (schedule_count > 0)
{
message += "<?php esc_html_e('There currently are', 'duplicator-pro') ?>" + " ";
message += schedule_count + " " + "<?php esc_html_e('schedule(s) using this template.', 'duplicator-pro'); ?>" + " ";
message += "<?php esc_html_e('All schedules using this template will be reassigned to the \"Default\" template.', 'duplicator-pro') ?>" + " ";
$("#<?php echo esc_js($confirm2->getID()); ?>_message").html(message);
}
$("#<?php echo esc_js($confirm2->getID()); ?>-confirm").attr('data-id', id);
}
DupPro.Template.DeleteThis = function (e) {
var id = $(e).attr('data-id');
jQuery("#dup-package-form-action").val('delete');
jQuery("#dup-package-selected-package-template").val(id);
jQuery("#dup-package-form").submit();
}
// Creats a comma seperate list of all selected package ids
DupPro.Template.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.join(',');
}
// Bulk Action
DupPro.Template.BulkAction = function () {
var list = DupPro.Template.DeleteList();
if (list.length == 0) {
<?php $alert2->showAlert(); ?>
return;
}
var action = $('#bulk_action').val(),
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;
}
}
}
DupPro.Storage.BulkDelete = function ()
{
jQuery("#dup-package-form-action").val('bulk-delete');
jQuery("#dup-package-form").submit();
}
//Sets all for deletion
DupPro.Template.SetDeleteAll = function (chkbox) {
$('.item-chk').each(function () {
this.checked = chkbox.checked;
});
}
//Name hover show menu
$("tr.package-row").hover(
function () {
$(this).find(".sub-menu").show();
},
function () {
$(this).find(".sub-menu").hide();
}
);
});
</script>

View File

@@ -0,0 +1,95 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Package\Recovery\RecoveryStatus;
use Duplicator\Views\ViewHelper;
/**
* @var DUP_PRO_Package_Template_Entity $template
* @var DUP_PRO_Schedule_Entity|null $schedule
* @var bool $isList
*/
if (isset($schedule)) {
$recoveryStatus = new RecoveryStatus($schedule);
} else {
$recoveryStatus = new RecoveryStatus($template);
}
$isRecoveable = $recoveryStatus->isRecoveable();
$templareRecoveryAlter = new DUP_PRO_UI_Dialog();
if (!$isRecoveable) {
$templareRecoveryAlter->title = (
isset($schedule) ?
__('Schedule: Recovery Point', 'duplicator-pro') :
__('Template: Recovery Point', 'duplicator-pro')
);
$templareRecoveryAlter->width = 600;
$templareRecoveryAlter->height = 600;
$templareRecoveryAlter->showButtons = false;
$templareRecoveryAlter->message = SnapIO::getInclude(
__DIR__ . '/template-filters-info.php',
array('recoveryStatus' => $recoveryStatus)
);
$templareRecoveryAlter->initAlert();
?>
<script>
jQuery(document).ready(function ($) {
$('#dup-template-recoveable-info-<?php echo $templareRecoveryAlter->getUniqueIdCounter(); ?>').click(function () {
<?php $templareRecoveryAlter->showAlert(); ?>
});
});
</script>
<?php
}
?>
<span class="dup-template-recoveable-info-wrapper" >
<?php
if ($isRecoveable) {
?>
<?php _e('Available', 'duplicator-pro'); ?>
<sup><?php ViewHelper::disasterIcon(); ?></sup>
<?php
} else {
?>
<a href="javascript:void(0)"
id="dup-template-recoveable-info-<?php echo $templareRecoveryAlter->getUniqueIdCounter(); ?>"
class="dup-template-recoveable-info"><u><?php _e('Disabled', 'duplicator-pro'); ?></u></a>
<?php
}
if (!$isList) {
?>
<sup>
<i class="fas fa-question-circle fa-sm"
data-tooltip-title="<?php esc_attr_e("Recovery Status", 'duplicator-pro'); ?>"
data-tooltip="<?php
if (!isset($schedule)) {
_e(
"The Recovery Status can be either 'Available' or 'Disabled'.
An 'Available' status allows the templates archive to be restored through the recovery point wizard.
A 'Disabled' status means the archive can still be used but just not ran as a rapid recovery point.",
'duplicator-pro'
);
} else {
_e(
"The Recovery Status can be either 'Available' or 'Disabled'.
An 'Available' status allows the schedules archive to be restored through the recovery point wizard.
A 'Disabled' status means the archive can still be used but just not ran as a rapid recovery point.",
'duplicator-pro'
);
}
?>"
></i>
</sup>
<?php } ?>
</span>

View File

@@ -0,0 +1,79 @@
<?php
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Views\TplMng;
use Duplicator\Package\Recovery\RecoveryStatus;
use Duplicator\Views\ViewHelper;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
/**
* @var RecoveryStatus $recoveryStatus
*/
if ($recoveryStatus->getType() == RecoveryStatus::TYPE_SCHEDULE) {
/** @var DUP_PRO_Schedule_Entity */
$schedule = $recoveryStatus->getObject();
if (($template = $schedule->getTemplate()) === false) {
$template = new DUP_PRO_Package_Template_Entity();
$template->name = __('Template not found', 'duplicator-pro');
}
$tooltipContent = esc_attr__(
'A Schedule is not required to have a recovery point. For example if a schedule is backing up
only a database then the recovery will always be disabled and may be desirable.',
'duplicator-pro'
);
} else {
$schedule = null;
/** @var DUP_PRO_Package_Template_Entity */
$template = $recoveryStatus->getObject();
$tooltipContent = esc_attr__(
'A Template is not required to have a recovery point. For example if backing up only a database
then the recovery will always be disabled and may be desirable.',
'duplicator-pro'
);
}
?>
<div class="dup-recover-dlg-title">
<b><?php ViewHelper::disasterIcon(); ?>&nbsp;<?php _e('Status', 'duplicator-pro'); ?>:</b>
<?php _e('Disabled', 'duplicator-pro'); ?>
<sup>
<i class="fas fa-question-circle fa-xs"
data-tooltip-title="<?php _e('Recovery Status', 'duplicator-pro'); ?>"
data-tooltip="<?php echo $tooltipContent; ?>">
</i>
</sup>
</div>
<div class="dup-recover-dlg-subinfo">
<table>
<?php if ($recoveryStatus->getType() == RecoveryStatus::TYPE_SCHEDULE) { ?>
<tr>
<td><b><?php _e("Schedule", 'duplicator-pro'); ?>:</b></td>
<td> <?php echo esc_html($schedule->name); ?></td>
</tr>
<tr>
<td> <b><?php _e("Template", 'duplicator-pro'); ?>:</b></td>
<td>
<a href="<?php echo esc_url(ToolsPageController::getTemplateEditURL($template->getId())); ?>" >
<?php echo esc_html($template->name); ?>
</a>
</td>
</tr>
<?php } else { ?>
<tr>
<td> <b><?php _e("Template", 'duplicator-pro'); ?>:</b> </td>
<td><?php echo esc_html($template->name); ?></td>
</tr>
<tr>
<td><b><?php esc_html_e('Notes', 'duplicator-pro'); ?>:</b>&nbsp; </td>
<td><?php echo (strlen($template->notes)) ? $template->notes : __("- no notes -", 'duplicator-pro'); ?></td>
</tr>
<?php } ?>
</table>
</div>
<?php
TplMng::getInstance()->render(
'parts/recovery/exclude_data_box',
array('recoverStatus' => $recoveryStatus)
);