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,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)
);