first commit

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,34 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string,mixed> $tplData
* @var string $pageTitle
*/
$pageTitle = $tplData['pageTitle'];
/** @var string */
$templateSecondaryPart = ($tplData['templateSecondaryPart'] ?? '');
/** @var array<string,mixed> */
$templateSecondaryArgs = ($tplData['templateSecondaryArgs'] ?? []);
?>
<div class="dup-body-header">
<h1><?php echo esc_html($pageTitle); ?></h1>
<?php
$tplMng->render('parts/tabs_menu_l2');
if (strlen($templateSecondaryPart) > 0) {
$tplMng->render($templateSecondaryPart, $templateSecondaryArgs);
}
?>
</div>
<hr class="wp-header-end margin-top-0">

View File

@@ -0,0 +1,37 @@
<?php
defined("ABSPATH") or die("");
/**
* Dialog Confirm Progress Template
*
* Variables
*
* @var array<string, mixed> $tplData
* @var string $function_name
* @var string $progress_text
*/
$id = $tplData["id"];
$function_name = $tplData["function_name"];
$progress_text = $tplData["progress_text"];
?>
<div class='dupli-dlg-confirm-progress' id="<?php echo esc_attr($id) ?>-progress">
<br/><br/>
<i class='fa fa-circle-notch fa-spin fa-lg fa-fw'></i> <?php echo esc_html($progress_text) ?></div>
<script>
function <?php echo esc_js($function_name) ?>(obj)
{
(function($,obj){
console.log($('#<?php echo esc_attr($id) ?>'));
// Set object for reuse
var e = $(obj);
// Check and set progress
if($('#<?php echo esc_attr($id) ?>-progress')) $('#<?php echo esc_attr($id) ?>-progress').show();
// Check and set confirm button
if($('#<?php echo esc_attr($id) ?>-confirm')) $('#<?php echo esc_attr($id) ?>-confirm').attr('disabled', 'true');
// Check and set cancel button
if($('#<?php echo esc_attr($id) ?>-cancel')) $('#<?php echo esc_attr($id) ?>-cancel').attr('disabled', 'true');
}(window.jQuery, obj));
}
</script>

View File

@@ -0,0 +1,37 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
?>
<p>
<?php esc_html_e('The brandable area allows for a loose set of html and custom styling. Below is a general guide.', 'duplicator-pro'); ?>
</p>
<p>
- <b><?php esc_html_e('Embed Image:', 'duplicator-pro'); ?></b><br/> &lt;img src="/wp-content/uploads/image.png /&gt;<br/><br/>
- <b><?php esc_html_e('Text Only:', 'duplicator-pro'); ?></b><br/> <?php esc_html_e('My Installer Name', 'duplicator-pro'); ?><br/><br/>
- <b><?php esc_html_e('Text & Font-Awesome:', 'duplicator-pro'); ?></b><br/> &lt;i class="fa fa-cube"&gt;&lt;/i&gt;
<?php esc_html_e('My Company', 'duplicator-pro'); ?>
</p>
<p>
<small>
<?php
wp_kses(
sprintf(
_x(
'Note: %1$sFont-Awesome 4.7%2$s is the referenced library',
'1: opening anchor tag, 2: closing anchor tag',
'duplicator-pro'
),
"<a href='http://fontawesome.io/icons/' target='_blank'>",
"</a>"
),
['a' => ['href' => []]]
);
?>
</small>
</p>

View File

@@ -0,0 +1,13 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
?>
<i class="fa fa-exclamation-triangle fa-sm"></i>
<?php
esc_html_e('No selections made! Please select an action from the "Bulk Actions" drop down menu!', 'duplicator-pro');
?>

View File

@@ -0,0 +1,13 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
?>
<i class="fa fa-exclamation-triangle fa-sm"></i>
<?php
esc_html_e('No selections made! Please select at least one Backup to delete!', 'duplicator-pro');
?>

View File

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

View File

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

View File

@@ -0,0 +1,87 @@
<?php
/**
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Utils\Help\Help;
use Duplicator\Utils\Support\SupportToolkit;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<div id="dupli-help-wrapper">
<div id="dupli-help-header">
<img src="<?php echo esc_url(DUPLICATOR_PLUGIN_URL . 'assets/img/duplicator-header-logo.svg'); ?>" />
</div>
<div id="dupli-help-content">
<div id="dupli-help-search">
<input type="text" placeholder="<?php esc_attr_e("Search", "duplicator-pro"); ?>" />
<ul id="dupli-help-search-results"></ul>
<div id="dupli-help-search-results-empty"><?php esc_html_e("No results found", "duplicator-pro"); ?></div>
</div>
<div id="dupli-context-articles">
<?php if (count(Help::getInstance()->getArticlesByTag($tplData['tag'])) > 0) : ?>
<h2><?php esc_html_e("Related Articles", "duplicator-pro"); ?></h2>
<?php $tplMng->render('parts/help/article-list', ['articles' => Help::getInstance()->getArticlesByTag($tplData['tag'])]); ?>
<?php endif; ?>
</div>
<div id="dupli-help-categories">
<?php $tplMng->render('parts/help/category-list', ['categories' => Help::getInstance()->getTopLevelCategories()]); ?>
</div>
<div id="dupli-help-footer">
<div class="dupli-help-footer-block">
<i aria-hidden="true" class="fa fa-file-alt"></i>
<h3><?php esc_html_e("View Documentation", "duplicator-pro"); ?></h3>
<p>
<?php esc_html_e("Browse documentation, reference material, and tutorials for Duplicator.", "duplicator-pro"); ?>
</p>
<a
href="<?php echo esc_url(DUPLICATOR_BLOG_URL . 'docs'); ?>"
rel="noopener noreferrer"
target="_blank"
class="button">
<?php esc_html_e("View All Documentation", "duplicator-pro"); ?>
</a>
</div>
<div class="dupli-help-footer-block">
<i aria-hidden="true" class="fa fa-life-ring"></i>
<h3><?php esc_html_e("Get Support", "duplicator-pro"); ?></h3>
<p>
<?php esc_html_e("You can access our world-class support below.", "duplicator-pro"); ?>
<?php echo wp_kses(
sprintf(
_x(
'If reporting a bug, remember to include the %1$s to speed up the debugging process.',
'1: diagnostic data link with label or link to instructions to download logs manually',
'duplicator-pro'
),
SupportToolkit::getDiagnosticInfoLinks()
),
[
'a' => [
'href' => [],
'target' => [],
],
]
); ?>
</p>
<a
href="<?php echo esc_url(DUPLICATOR_BLOG_URL . 'my-account/support/'); ?>"
rel="noopener noreferrer"
target="_blank"
class="button">
<?php esc_html_e("Get Support", "duplicator-pro"); ?>
</a>
</div>
</div>
</div>
</div>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,111 @@
<?php
/**
* Duplicator Backup row in table Backups list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Libs\WpUtils\WpDbUtils;
use Duplicator\Models\TemplateEntity;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $isTemplateEdit
*/
$isTemplateEdit = $tplData['isTemplateEdit'];
/** @var ?TemplateEntity */
$template = ($tplData['template'] ?? null);
$dbbuild_mode = WpDbUtils::getBuildMode();
if ($dbbuild_mode != 'MYSQLDUMP') {
return;
}
?>
<div class="dup-form-item margin-top-1">
<label class="lbl-larger">
<?php esc_html_e("Compatibility Mode", 'duplicator-pro') ?>:
<?php
$tipCont = __(
'This is an advanced database backwards compatibility feature that should ONLY be used if having problems installing Backups.
If the database server version is lower than the version where the Backup was built then these options may help generate
a script that is more compliant with the older database server. It is recommended to try each option separately starting with mysql40.',
'duplicator-pro'
);
?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
title="<?php echo esc_attr($tipCont); ?>"
aria-expanded="false"></i>
</label>
<div>
<?php if ($isTemplateEdit) { ?>
<i>
<?php
printf(
esc_html_x(
'This option is not available as a template setting.
It can only be used when creating a new Backup. Please see the full %1$sFAQ details%2$s',
'1 and 2 are opening and closing anchor/link tags',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'how-to-fix-database-write-issues') . '" target="_blank">',
'</a>'
);
?>
</i>
<?php } else { ?>
<div class="dup-form-horiz-opts">
<span>
<input
type="checkbox"
name="dbcompat[]"
id="dbcompat-mysql40"
class="margin-0"
value="mysql40">
<label for="dbcompat-mysql40"><?php esc_html_e("mysql40", 'duplicator-pro') ?></label>
</span>
<span>
<input
type="checkbox"
name="dbcompat[]"
id="dbcompat-no_table_options"
value="no_table_options"
class="margin-0">
<label for="dbcompat-no_table_options"><?php esc_html_e("no_table_options", 'duplicator-pro') ?></label>
</span>
<span>
<input
type="checkbox"
name="dbcompat[]"
id="dbcompat-no_key_options"
value="no_key_options"
class="margin-0">
<label for="dbcompat-no_key_options"><?php esc_html_e("no_key_options", 'duplicator-pro') ?></label>
</span>
<span>
<input
type="checkbox"
name="dbcompat[]"
id="dbcompat-no_field_options"
value="no_field_options"
class="margin-0">
<label for="dbcompat-no_field_options"><?php esc_html_e("no_field_options", 'duplicator-pro') ?></label>
</span>
</div>
<div class="dup-tabs-opts-help">
<?php esc_html_e("Compatibility mode settings are not persistent. They must be enabled with every new build.", 'duplicator-pro'); ?>&nbsp;
<a href="<?php echo esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'how-to-fix-database-write-issues'); ?>" target="_blank">
[<?php esc_html_e('full overview', 'duplicator-pro'); ?>]
</a>
</div>
<?php } ?>
</div>
</div>

View File

@@ -0,0 +1,463 @@
<?php
/**
* Duplicator Backup row in table Backups list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Libs\WpUtils\WpArchiveUtils;
use Duplicator\Package\Create\BuildComponents;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$activeComponents = $tplData['components'] ?? [];
$archiveFilterOn = $tplData['archiveFilterOn'] ?? false;
$archiveFilterDirs = $tplData['archiveFilterDirs'] ?? '';
$archiveFilterFiles = $tplData['archiveFilterFiles'] ?? '';
$archiveFilterPaths = strlen($archiveFilterDirs) > 0 && strlen($archiveFilterFiles) > 0
? $archiveFilterDirs . ';' . $archiveFilterFiles : $archiveFilterDirs . $archiveFilterFiles;
$archiveFilterPaths = str_replace(';', ";\n", $archiveFilterPaths);
$archiveFilterExtensions = $tplData['archiveFilterExtensions'] ?? '';
$licenseDisabledClass = License::can(License::CAPABILITY_PACKAGE_COMPONENTS_PLUS) ? '' : 'disabled';
$pathFiltersTooltip = __('File filters allow you to exclude files and folders from the Backup.', 'duplicator-pro') . ' ' .
__('To enable path and extension filters check the checkbox.', 'duplicator-pro') . ' ' .
__('Enter the full path of the files and folders you want to exclude from the backup as a semicolon (;) seperated list.', 'duplicator-pro');
$extensionFilterTooltip = __(
"File extension filters allow you to exclude files with certain file extensions from the backup e.g. zip;rar;pdf etc.",
'duplicator-pro'
) . ' ' . __("Enter the file extensions you want to exclude from the backup as a semicolon (;) seperated list.", 'duplicator-pro');
$presetsTooltip = __(
'Presets allow you to quickly include/exclude differents part of your WordPress installation in the backup.',
'duplicator-pro'
);
$componentsTooltip = $tplMng->render('parts/packages/filters/package_components_tootip', [], false);
?>
<div class="dup-package-components">
<div class="component-section">
<label class="lbl-larger">
<?php esc_html_e('Presets:', 'duplicator-pro'); ?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
title="<?php echo esc_attr($presetsTooltip); ?>"
aria-expanded="false"></i>
</label>
<div class="components-shortcut-select">
<div class="dup-radio-button-group-wrapper">
<?php foreach (BuildComponents::COMPONENTS_ACTIONS as $action) {
$inputId = 'dup-component-shortcut-action-' . $action;
if (
in_array($action, BuildComponents::COMPONENTS_PLUS_ACTIONS) &&
!License::can(License::CAPABILITY_PACKAGE_COMPONENTS_PLUS)
) {
$disabled = 'disabled';
} else {
$disabled = '';
}
?>
<input
type="radio"
id="<?php echo esc_attr($inputId); ?>"
name="auto-select-components"
class="dup-components-shortcut-radio"
value="<?php echo esc_html($action); ?>"
<?php checked($action === BuildComponents::getActionFromComponents($activeComponents)); ?>>
<label
for="<?php echo esc_attr($inputId); ?>"
class="button hollow secondary small <?php echo esc_attr($disabled); ?>">
<?php
echo wp_kses(
BuildComponents::getActionLabel($action, true),
[
'i' => [
'class' => [],
],
]
);
?>
</label>
<?php } ?>
</div>
<div class="dup-tabs-opts-help">
<?php
if (!License::can(License::CAPABILITY_PACKAGE_COMPONENTS_PLUS)) { ?>
<div id="dup-upgrade-license-info" class="margin-top-1">
<?php
printf(
esc_html_x(
'The %1$s and %2$s options are not included in your license plan.',
'%1$s and %2$s are the options not included in the license.',
'duplicator-pro'
),
'<b>' . esc_html(BuildComponents::getActionLabel(BuildComponents::COMP_ACTION_MEDIA)) . '</b>',
'<b>' . esc_html(BuildComponents::getActionLabel(BuildComponents::COMP_ACTION_CUSTOM)) . '</b>'
);
?>
<br>
<?php
printf(
esc_html_x(
'To enable advanced options please %1$supgrade your license%2$s.',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link.',
'duplicator-pro'
),
'<a href="' . esc_url(License::getUpsellURL()) . '" target="_blank">',
'</a>'
);
?>
</div>
<?php } ?>
</div>
</div>
<hr>
<label class="lbl-larger">
<?php esc_html_e('Components:', 'duplicator-pro'); ?>&nbsp;
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e('Backup Components', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($componentsTooltip); ?>"
aria-expanded="false"></i>
</label>
<div>
<ul class="custom-components-select no-bullet">
<?php foreach (BuildComponents::COMPONENTS as $component) { ?>
<li>
<label class="<?php echo in_array($component, BuildComponents::SUB_OPTIONS) ? 'secondary license-disabled' : 'license-disabled' ?>">
<input
type="checkbox"
<?php echo !in_array($component, BuildComponents::SUB_OPTIONS) ? 'data-parsley-multiple="package_components"' : '' ?>
name="<?php echo esc_attr($component) ?>"
id="<?php echo esc_attr($component) ?>"
class="dup-components-checkbox"
<?php checked(in_array($component, $activeComponents)); ?>>
<?php echo esc_html(BuildComponents::getLabel($component)); ?>
</label>
</li>
<?php } ?>
</ul>
<span id="components_error_container" class="duplicator-error-container"></span>
</div>
</div>
<div class="files-filter-section">
<hr>
<label class="lbl-larger">
<?php esc_html_e('File Filters:', 'duplicator-pro'); ?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
title="<?php esc_attr_e('File filters allow you to exclude files and folders from the backup.', 'duplicator-pro'); ?>"
aria-expanded="false"></i>
</label>
<div class="margin-bottom-1">
<label>
<input
id="files-filter-on"
name="filter-on"
type="checkbox" <?php checked($archiveFilterOn); ?>
class="margin-0">&nbsp;<?php esc_html_e('Enable', 'duplicator-pro'); ?>
</label>
</div>
<div class="filters <?php echo ($archiveFilterOn ? 'no-display' : ''); ?>">
<label class="lbl-larger">
<?php
esc_html_e('Filters:', 'duplicator-pro');
$tooltip = __(
'- Use full path for directories or specific files.<br>
- Use filenames without paths to filter same-named files across multiple directories.<br>
- Use semicolons to separate all items.<br>
- Use # to comment a line.',
'duplicator-pro'
);
?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
title="<?php echo esc_attr($tooltip); ?>"
aria-expanded="false"></i>
</label>
<div>
<textarea
id="filter-paths"
name="filter-paths"
class="margin-0"
placeholder="/full_path/dir/;&#10;/full_path/file;"
readonly><?php echo esc_html($archiveFilterPaths); ?></textarea>
<small class="filter-links margin-bottom-1">
<a href="#" data-filter-path="<?php echo esc_attr(SnapIO::trailingslashit(WpArchiveUtils::getOriginalPaths('home'))); ?>">
[<?php esc_html_e('root path', 'duplicator-pro') ?>]
</a>
<a href="#" data-filter-path="<?php echo esc_attr(SnapIO::trailingslashit(WpArchiveUtils::getOriginalPaths('wpcontent'))); ?>">
[wp-content]
</a>
<a href="#" data-filter-path="<?php echo esc_attr(SnapIO::trailingslashit(WpArchiveUtils::getOriginalPaths('uploads'))); ?>">
[wp-uploads]
</a>
<a href="#" data-filter-path="<?php echo esc_attr(SnapIO::trailingslashit(WpArchiveUtils::getOriginalPaths('wpcontent')) . 'cache/'); ?>">
[<?php esc_html_e('cache', 'duplicator-pro') ?>]
</a>
<a href="#" id="clear-path-filters">(<?php esc_html_e('clear', 'duplicator-pro') ?>)</a>
</small>
</div>
<label class="lbl-larger">
<?php esc_html_e('File Extensions', 'duplicator-pro'); ?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e('File Extensions', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($extensionFilterTooltip); ?>"
aria-expanded="false"></i>
</label>
<div>
<textarea
id="filter-exts"
name="filter-exts"
class="margin-bottom-0"
placeholder="ext1;ext2;ext3;"
readonly><?php echo esc_html($archiveFilterExtensions); ?></textarea>
<small class="filter-links">
<a href="#" data-filter-exts="avi;mov;mp4;mpeg;mpg;swf;wmv;aac;m3u;mp3;mpa;wav;wma">[media]</a>
<a href="#" data-filter-exts="zip;rar;tar;gz;bz2;7z">[archive]</a>
<a href="#" id="clear-extension-filters">(<?php esc_html_e('clear', 'duplicator-pro'); ?>)</a>
</small>
</div>
</div>
</div>
</div>
<script>
jQuery(document).ready(function($) {
$('#package_component_db').attr('data-parsley-required', 'true');
$('#package_component_db').attr('data-parsley-mincheck', '1');
$('#package_component_db').attr('data-parsley-errors-container', '#components_error_container');
$('#package_component_db')
.attr('data-parsley-required-message', '<?php echo esc_js(__("Please select at least one component.", "duplicator-pro")); ?>');
$('.dup-package-components .component-section input[type=checkbox]').on('change', function() {
$('#package_component_db').parsley().validate();
});
DupliJs.Pack.ToggleFileFilters = function() {
if ($("#files-filter-on").is(':checked')) {
$('#dup-archive-filter-file-icon').show();
$('.files-filter-section .filters').removeClass('no-display');
$('#filter-exts, #filter-paths').prop('readonly', false);
} else {
$('#dup-archive-filter-file-icon').hide();
$('.files-filter-section .filters').addClass('no-display');
$('#filter-exts, #filter-paths').prop('readonly', true);
}
};
DupliJs.Pack.ToggleDBExcluded = function() {
if (!$('#package_component_db').is(":checked")) {
$('.filter-db-tab-content').hide();
} else {
$('.filter-db-tab-content').show();
}
}
DupliJs.Pack.ToggleDBOnly = function() {
let allComponentCheckboxes = $('.dup-package-components .component-section input[type=checkbox]');
if (allComponentCheckboxes.filter(':checked').length === 1 && $('#package_component_db').is(":checked")) {
$('#dup-archive-filter-file-icon').hide();
$("#dup-archive-db-only-icon").show();
$('.files-filter-section').hide();
$('.db-only-message').show();
} else {
if ($('#files-filter-on').is(':checked')) {
$('#dup-archive-filter-file-icon').show();
}
$("#dup-archive-db-only-icon").hide();
$('.files-filter-section').show();
$('.db-only-message').hide();
}
}
DupliJs.Pack.ToggleMediaOnly = function() {
let allComponentCheckboxes = $('.dup-package-components .component-section input[type=checkbox]');
if (allComponentCheckboxes.filter(':checked').length === 1 && $('#package_component_uploads').is(":checked")) {
$("#dup-archive-media-only-icon").show();
} else {
$("#dup-archive-media-only-icon").hide();
}
}
DupliJs.Pack.SetDBOnly = function() {
$('.dup-components-checkbox').prop('checked', false);
$('.custom-components-select label').addClass('disabled');
$('#package_component_db').prop('checked', true);
}
DupliJs.Pack.SetMediaOnly = function() {
$('.dup-components-checkbox').prop('checked', false);
$('.custom-components-select label').addClass('disabled');
$('#package_component_uploads').prop('checked', true);
}
DupliJs.Pack.SetDefault = function() {
$('.dup-components-checkbox').prop('checked', false);
$('label:not(.secondary) .dup-components-checkbox').prop('checked', true);
$('.custom-components-select label').addClass('disabled');
}
DupliJs.Pack.SetCustom = function() {
$('.custom-components-select label').removeClass('disabled');
}
DupliJs.Pack.ToggleComponentsSelect = function() {
let checkedSelect = $('.dup-components-shortcut-radio:checked').val();
console.log(checkedSelect);
switch (checkedSelect) {
case 'all':
DupliJs.Pack.SetDefault();
break;
case 'database':
DupliJs.Pack.SetDBOnly();
break;
case 'media':
DupliJs.Pack.SetMediaOnly();
break;
case 'custom':
DupliJs.Pack.SetCustom();
break;
}
$('.dup-components-checkbox').trigger('change');
}
DupliJs.Pack.SetComponentsSelect = function() {
let allComponentCheckboxes = $('.dup-components-checkbox');
let checkedComponentsCount = allComponentCheckboxes.filter(':checked').length;
let activeOnlyDisabled = (!$('#package_component_plugins_active').is(":checked") && !$('#package_component_themes_active').is(":checked"));
if (checkedComponentsCount === (allComponentCheckboxes.length - 2) && activeOnlyDisabled) {
$('#dup-component-shortcut-action-all').prop('checked', true);
} else if (checkedComponentsCount === 1 && $('#package_component_db').is(":checked")) {
$('#dup-component-shortcut-action-database').prop('checked', true);
} else if (checkedComponentsCount === 1 && $('#package_component_uploads').is(":checked")) {
$('#dup-component-shortcut-action-media').prop('checked', true);
} else {
$('#dup-component-shortcut-action-custom').prop('checked', true);
}
DupliJs.Pack.ToggleComponentsSelect();
}
DupliJs.Pack.ToggleActivePlugins = function() {
let activePluginsInput = $('#package_component_plugins_active');
if (activePluginsInput.parent().hasClass('disabled')) {
activePluginsInput.prop('disabled', true);
return;
}
if (!$('#package_component_plugins').is(':checked')) {
activePluginsInput.prop('disabled', true);
activePluginsInput.prop('checked', false);
} else {
activePluginsInput.prop('disabled', false);
}
}
DupliJs.Pack.ToggleActiveThemes = function() {
let activeThemesInput = $('#package_component_themes_active');
if (activeThemesInput.parent().hasClass('disabled')) {
activeThemesInput.prop('disabled', true);
return;
}
if (!$('#package_component_themes').is(':checked')) {
activeThemesInput.prop('disabled', true);
activeThemesInput.prop('checked', false);
} else {
activeThemesInput.prop('disabled', false);
}
}
DupliJs.Pack.ToggleFileFilters();
DupliJs.Pack.ToggleActiveThemes();
DupliJs.Pack.ToggleActivePlugins();
DupliJs.Pack.ToggleDBExcluded();
DupliJs.Pack.ToggleDBOnly();
DupliJs.Pack.ToggleMediaOnly();
DupliJs.Pack.SetComponentsSelect();
$('a[data-filter-path]').click(function(e) {
e.preventDefault()
if ($('#filter-paths').is("[readonly]")) {
return;
}
let currentVal = $('#filter-paths').val()
let newVal = currentVal.length > 0 ? currentVal + ";\n" + $(this).data('filter-path') : $(this).data('filter-path')
$('#filter-paths').val(newVal)
})
$('#clear-path-filters').click(function(e) {
e.preventDefault()
if ($('#filter-paths').is("[readonly]")) {
return;
}
$('#filter-paths').val('')
})
$('a[data-filter-exts]').click(function(e) {
e.preventDefault()
if ($('#filter-exts').is("[readonly]")) {
return;
}
let currentVal = $('#filter-exts').val()
let newVal = currentVal.length > 0 ? currentVal + ";" + $(this).data('filter-exts') : $(this).data('filter-exts')
$('#filter-exts').val(newVal)
})
$('#clear-extension-filters').click(function(e) {
e.preventDefault()
if ($('#filter-exts').is("[readonly]")) {
return;
}
$('#filter-exts').val('')
})
$('#files-filter-on').change(DupliJs.Pack.ToggleFileFilters)
$('#package_component_db').change(function() {
DupliJs.Pack.ToggleDBExcluded();
})
$('.dup-components-shortcut-radio').change(function() {
DupliJs.Pack.ToggleComponentsSelect();
})
$('.dup-components-checkbox').change(function() {
DupliJs.Pack.ToggleDBOnly()
DupliJs.Pack.ToggleMediaOnly()
})
$('#package_component_plugins').change(function() {
DupliJs.Pack.ToggleActivePlugins();
});
$('#package_component_themes').change(function() {
DupliJs.Pack.ToggleActiveThemes();
});
});
</script>

View File

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

View File

@@ -0,0 +1,116 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Installer\Package\ArchiveDescriptor;
use Duplicator\Models\GlobalEntity;
use Duplicator\Models\TemplateEntity;
use Duplicator\Package\Archive\PackageArchive;
use Duplicator\Views\UI\UiDialog;
use Duplicator\Views\UI\UiViewState;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $isTemplateEdit
*/
$isTemplateEdit = $tplData['isTemplateEdit'];
/** @var ?TemplateEntity */
$template = ($tplData['template'] ?? null);
$archive_format = (GlobalEntity::getInstance()->getBuildMode() == PackageArchive::BUILD_MODE_DUP_ARCHIVE ? 'daf' : 'zip');
?>
<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('Backup', 'duplicator-pro') ?>
<?php if (!$isTemplateEdit) { ?>
<sup class="dup-box-title-badge">
<?php echo esc_html($archive_format); ?>
</sup>
<?php } ?>
&nbsp;&nbsp;
<?php $tplMng->render('parts/packages/filters/section_filters_incons'); ?>
<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
id="dup-pack-archive-panel"
class="dup-box-panel <?php echo UiViewState::getValue('dup-pack-archive-panel') ? '' : 'no-display'; ?>">
<div data-dupli-tabs="true">
<ul>
<li class="filter-files-tab">
<?php esc_html_e('Filters', 'duplicator-pro') ?>
</li>
<?php if (is_multisite()) { ?>
<li class="filter-mu-tab">
<?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('parts/packages/filters/section_filters_subtab_filters_files');
if (is_multisite()) {
$tplMng->render('admin_pages/packages/setup/archive-filter-mu-tab');
}
if ($isTemplateEdit && $template != null) {
$setupParams = [
'secureOn' => $template->installer_opts_secure_on,
'securePass' => $template->installerPassowrd,
];
} else {
$setupParams = [
'secureOn' => ArchiveDescriptor::SECURE_MODE_NONE,
'securePass' => '',
];
}
$tplMng->render('parts/packages/filters/section_filters_subtab_setup', $setupParams);
?>
</div>
</div>
</div>
<div class="duplicator-error-container"></div>
<?php
$alert1 = new UiDialog();
$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,34 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<span class="dup-archive-filters-icons">
<span id="dup-archive-filter-file-icon" title="<?php esc_attr_e('Folder/File Filters Enabled', 'duplicator-pro'); ?>">
<i class="fa-solid fa-folder-minus fa-sm primary-color"></i>
</span>
<span id="dup-archive-filter-db-icon" title="<?php esc_attr_e('Database Filters Enabled', 'duplicator-pro'); ?>">
<i class="fa-solid fa-table fa-sm primary-color"></i>
</span>
<span id="dup-archive-db-only-icon" title="<?php esc_attr_e('Backup Only the Database', 'duplicator-pro'); ?>">
<i class="fa-solid fa-database fa-sm primary-color"></i>
</span>
<span id="dup-archive-media-only-icon" title="<?php esc_attr_e('Backup Only Media files', 'duplicator-pro'); ?>">
<i class="fa-solid fa-file-image fa-sm primary-color"></i>
</span>
<span id="dupli-install-secure-lock-icon" title="<?php esc_attr_e('Backup Password Protection is On', 'duplicator-pro'); ?>" >
<i class="fa-solid fa-lock fa-sm primary-color"></i>
</span>
</span>

View File

@@ -0,0 +1,93 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Libs\WpUtils\WpDbUtils;
use Duplicator\Models\TemplateEntity;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $isTemplateEdit
*/
$isTemplateEdit = $tplData['isTemplateEdit'];
/** @var ?TemplateEntity */
$template = ($tplData['template'] ?? null);
$dbbuild_mode = WpDbUtils::getBuildMode();
$settingsPackageUrl = SettingsPageController::getInstance()->getMenuLink(SettingsPageController::L2_SLUG_PACKAGE);
if ($isTemplateEdit && $template != null) {
$tableList = explode(',', $template->database_filter_tables);
$tableListFilterParams = [
'dbFilterOn' => $template->database_filter_on,
'dbPrefixFilter' => $template->databasePrefixFilter,
'dbPrefixSubFilter' => $template->databasePrefixSubFilter,
'tablesSlected' => $tableList,
];
} else {
$tableListFilterParams = [
'dbFilterOn' => false,
'dbPrefixFilter' => '',
'dbPrefixSubFilter' => '',
'tablesSlected' => [],
];
}
?>
<div class="filter-db-tab-content">
<hr>
<div class="db-only-message margin-bottom-1">
<label class="lbl-larger">
<?php esc_html_e("Database Only", 'duplicator-pro') ?>
</label>
<div class="input">
<?php
esc_html_e(
'This advanced option excludes all files from the archive.
Only the database and a copy of the installer.php will be included in the Backup file.',
'duplicator-pro'
);
?><br>
<?php
esc_html_e(
'The option can be used for backing up and moving only the database.',
'duplicator-pro'
);
?><br>
<?php
printf(
esc_html_x(
'When installing a database only backup please visit the %1$sdatabase only quick start%2$s',
'%1$s and %2$s are opening and closing anchor tags',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'database-install') . '" target="_blank">',
'</a>'
);
?>
</div>
</div>
<div class="margin-bottom-1">
<?php $tplMng->render('parts/packages/filters/tables_list_filter', $tableListFilterParams); ?>
</div>
<div class="dup-form-item">
<label class="lbl-larger">
<?php esc_html_e("SQL Mode", 'duplicator-pro') ?>
</label>
<span class="input">
<a href="<?php echo esc_url($settingsPackageUrl); ?>" target="settings">
<?php echo esc_html($dbbuild_mode); ?>
</a>
</span>
</div>
<?php $tplMng->render('parts/packages/filters/mysqldump_compatibility_mode'); ?>
</div>

View File

@@ -0,0 +1,45 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Models\TemplateEntity;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $isTemplateEdit
*/
$isTemplateEdit = $tplData['isTemplateEdit'];
/** @var ?TemplateEntity */
$template = ($tplData['template'] ?? null);
if ($isTemplateEdit && $template != null) {
$componentsParams = [
'archiveFilterOn' => $template->archive_filter_on,
'archiveFilterDirs' => $template->archive_filter_dirs,
'archiveFilterFiles' => $template->archive_filter_files,
'archiveFilterExtensions' => $template->archive_filter_exts,
'components' => $template->components,
];
} else {
$componentsParams = [
'archiveFilterOn' => 0,
'archiveFilterDirs' => '',
'archiveFilterFiles' => '',
'archiveFilterExtensions' => '',
'components' => [],
];
}
?>
<div class="filter-files-tab-content">
<?php $tplMng->render('parts/packages/filters/package_components', $componentsParams); ?>
<?php $tplMng->render('parts/packages/filters/section_filters_subtab_filters_db'); ?>
</div>

View File

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

View File

@@ -0,0 +1,409 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Models\BrandEntity;
use Duplicator\Models\TemplateEntity;
use Duplicator\Views\UI\UiViewState;
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var int $activeBrandId
*/
$activeBrandId = ($tplData['activeBrandId'] ?? -1);
/** @var string */
$dbHost = ($tplData['dbHost'] ?? '');
/** @var string */
$dbName = ($tplData['dbName'] ?? '');
/** @var string */
$dbUser = ($tplData['dbUser'] ?? '');
/** @var bool */
$cpnlEnable = ($tplData['cpnlEnable'] ?? false);
/** @var string */
$cpnlHost = ($tplData['cpnlHost'] ?? '');
/** @var string */
$cpnlUser = ($tplData['cpnlUser'] ?? '');
/** @var string */
$cpnlDbAction = ($tplData['cpnlDbAction'] ?? '');
/** @var string */
$cpnlDbHost = ($tplData['cpnlDbHost'] ?? '');
/** @var string */
$cpnlDbName = ($tplData['cpnlDbName'] ?? '');
/** @var string */
$cpnlDbUser = ($tplData['cpnlDbUser'] ?? '');
$ui_css_installer = (UiViewState::getValue('dupli-pack-installer-panel') ? 'display:block' : 'display:none');
?>
<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="dupli-pack-installer-panel" style="<?php echo esc_attr($ui_css_installer); ?>">
<div class="dup-package-hdr-1">
<?php esc_html_e("Setup", 'duplicator-pro') ?>
</div>
<label class="lbl-larger">
<?php esc_html_e('Branding', 'duplicator-pro'); ?>
<?php
$tipContent = __(
'This option changes the branding of the installer file. Click the preview button to see the selected style.',
'duplicator-pro'
);
?>
<i
class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e("Choose Brand", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>"></i>
</label>
<div>
<?php
if (License::can(License::CAPABILITY_BRAND)) :
$brands = BrandEntity::getAllWithDefault();
/** @todo remove this */
/*
$activeBrandId = TemplateEntity::get_manual_template()->installer_opts_brand;
if ($activeBrandId < 0) {
$activeBrandId = -1; // for old brand version
}
*/
?>
<select name="installer_opts_brand" id="brand" class="width-auto">
<?php foreach ($brands as $i => $brand) { ?>
<option
value="<?php echo (int) $brand->getId(); ?>"
title="<?php echo esc_attr($brand->notes); ?>"
<?php selected($brand->getId(), $activeBrandId); ?>>
<?php echo esc_html($brand->name); ?>
</option>
<?php } ?>
</select>
<?php
if ($activeBrandId > 0) {
$preview_url = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE_BRAND,
null,
[
ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_EDIT,
'action' => 'edit',
'id' => intval($activeBrandId),
]
);
} else {
$preview_url = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE_BRAND,
null,
[
ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_EDIT,
'action' => 'default',
]
);
}
?>
&nbsp;
<a href="<?php echo esc_url($preview_url); ?>" target="_blank" class="button hollow secondary small" id="brand-preview">
<?php esc_html_e("Preview", 'duplicator-pro'); ?>
</a> &nbsp;
<?php else :
$link = ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE_BRAND
);
?>
<a href="<?php echo esc_url($link); ?>"><?php esc_html_e("Enable Branding", 'duplicator-pro'); ?></a>
<?php endif; ?>
</div>
<div class="dup-package-hdr-1">
<?php esc_html_e("Prefills", 'duplicator-pro') ?>&nbsp;
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
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>
<!-- ===================
BASIC/CPANEL TABS -->
<div data-dupli-tabs="true">
<ul>
<li id="dupli-bsc-tab-lbl"><?php esc_html_e('Basic', 'duplicator-pro') ?></li>
<li id="dupli-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="DupliJs.Pack.ApplyDataCurrent('s1-installer-dbbasic')">
[<?php esc_html_e('use current', 'duplicator-pro') ?>]
</a>
</div>
</div>
<div id="s1-installer-dbbasic">
<label class="lbl-larger">
<?php esc_html_e("Host", 'duplicator-pro') ?>:
</label>
<div>
<input
type="text"
name="installer_opts_db_host"
id="dbhost"
maxlength="200"
placeholder="<?php esc_html_e("example: localhost (value is optional)", 'duplicator-pro') ?>"
data-current="<?php echo esc_attr(DB_HOST); ?>"
value="<?php echo esc_attr($dbHost); ?>">
</div>
<label class="lbl-larger">
<?php esc_html_e("Database", 'duplicator-pro') ?>:
</label>
<div>
<input
type="text"
name="installer_opts_db_name"
id="dbname"
maxlength="100"
placeholder="<?php esc_html_e("example: DatabaseName (value is optional)", 'duplicator-pro') ?>"
data-current="<?php echo esc_attr(DB_NAME) ?>"
value="<?php echo esc_attr($dbName); ?>">
</div>
<label class="lbl-larger">
<?php esc_html_e("User", 'duplicator-pro') ?>:
</label>
<div>
<input
type="text"
name="installer_opts_db_user"
id="dbuser"
maxlength="100"
placeholder="<?php esc_html_e("example: DatabaseUser (value is optional)", 'duplicator-pro') ?>"
data-current="<?php echo esc_attr(DB_USER); ?>"
value="<?php echo esc_attr($dbUser); ?>">
</div>
</div>
</div>
<!-- ===================
TAB2: cPanel -->
<div>
<div class="dup-package-hdr-2">
<?php esc_html_e("cPanel Login", 'duplicator-pro') ?>
</div>
<label class="lbl-larger">
<?php esc_html_e("Automation", 'duplicator-pro') ?>:
</label>
<div>
<?php
$tipContent = __(
'Enabling this options will automatically select the cPanel tab when step one of the installer is shown.',
'duplicator-pro'
);
?>
<input
type="checkbox"
name="installer_opts_cpnl_enable"
id="cpnl-enable"
value="1"
<?php checked($cpnlEnable); ?>>
<label for="cpnl-enable"><?php esc_html_e('Auto Select cPanel', 'duplicator-pro') ?></label>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e('Auto Select cPanel', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tipContent); ?>">
</i>
</div>
<label class="lbl-larger">
<?php esc_html_e("Host", 'duplicator-pro') ?>:
</label>
<div>
<input
type="text"
name="installer_opts_cpnl_host"
id="cpnl-host"
maxlength="200"
value="<?php echo esc_attr($cpnlHost); ?>"
placeholder="<?php esc_attr_e("example: cpanelHost (value is optional)", 'duplicator-pro') ?>">
</div>
<label class="lbl-larger">
<?php esc_html_e("User", 'duplicator-pro') ?>:
</label>
<div>
<input
type="text"
name="installer_opts_cpnl_user"
id="cpnl-user"
value="<?php echo esc_attr($cpnlUser); ?>"
maxlength="200"
placeholder="<?php esc_attr_e("example: cpanelUser (value is optional)", 'duplicator-pro') ?>">
</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="DupliJs.Pack.ApplyDataCurrent('s1-installer-dbcpanel')">
[<?php esc_html_e('use current', 'duplicator-pro') ?>]
</a>
</div>
</div>
<div id="s1-installer-dbcpanel">
<label class="lbl-larger">
<?php esc_html_e("Action", 'duplicator-pro') ?>:
</label>
<div>
<select name="installer_opts_cpnl_db_action" id="cpnl-dbaction">
<option value="" <?php selected($cpnlDbAction, ''); ?>>
<?php esc_html_e('Default', 'duplicator-pro'); ?>
</option>
<option value="create" <?php selected($cpnlDbAction, 'create'); ?>>
<?php esc_html_e('Create A New Database', 'duplicator-pro'); ?>
</option>
<option value="empty" <?php selected($cpnlDbAction, 'empty'); ?>>
<?php esc_html_e('Connect and Delete Any Existing Data', 'duplicator-pro'); ?>
</option>
<option value="rename" <?php selected($cpnlDbAction, 'rename'); ?>>
<?php esc_html_e('Connect and Backup Any Existing Data', 'duplicator-pro'); ?>
</option>
<option value="manual" <?php selected($cpnlDbAction, 'manual'); ?>>
<?php esc_html_e('Skip Database Extraction', 'duplicator-pro'); ?>
</option>
</select>
</div>
<label class="lbl-larger">
<?php esc_html_e("Host", 'duplicator-pro') ?>:
</label>
<div>
<input
type="text"
name="installer_opts_cpnl_db_host"
id="cpnl-dbhost"
value="<?php echo esc_attr($cpnlDbHost); ?>"
maxlength="200"
placeholder="<?php esc_attr_e("example: localhost (value is optional)", 'duplicator-pro') ?>"
data-current="<?php echo esc_html(DB_HOST); ?>">
</div>
<label class="lbl-larger">
<?php esc_html_e("Database", 'duplicator-pro') ?>:
</label>
<div>
<input
type="text"
name="installer_opts_cpnl_db_name"
value="<?php echo esc_attr($cpnlDbName); ?>"
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); ?>">
</div>
<label class="lbl-larger">
<?php esc_html_e("User", 'duplicator-pro') ?>:
</label>
<div>
<input
type="text"
name="installer_opts_cpnl_db_user"
value="<?php echo esc_attr($cpnlDbUser); ?>"
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); ?>">
</div>
</div>
</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($) {
DupliJs.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_BRAND,
null,
[
ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_EDIT,
'action' => 'default',
]
),
ControllersManager::getMenuLink(
ControllersManager::SETTINGS_SUBMENU_SLUG,
SettingsPageController::L2_SLUG_PACKAGE_BRAND,
null,
[
ControllersManager::QUERY_STRING_INNER_PAGE => SettingsPageController::BRAND_INNER_PAGE_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,304 @@
<?php
/**
* Duplicator Backup row in table Backups list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Libs\Snap\SnapWP;
use Duplicator\Libs\WpUtils\WpDbUtils;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var \wpdb $wpdb
*/
$dbFilterOn = $tplData['dbFilterOn'] ?? false;
$dbPrefixFilter = $tplData['dbPrefixFilter'] ?? false;
$dbPrefixSubFilter = $tplData['dbPrefixSubFilter'] ?? false;
$tSelected = $tplData['tablesSlected'] ?? [];
$dbTableCount = 1;
global $wpdb;
$toolTipPrefixFilterContent = sprintf(
__(
'By enabling this option all tables that do not start with the prefix <b>"%s"</b> are excluded from the Backup.',
'duplicator-pro'
),
esc_html($wpdb->prefix)
) . ' ' .
__(
'This option is useful for multiple WordPress installs in the same database or if several applications are installed in the same database.',
'duplicator-pro'
);
$toolTipSubsiteFilterContent =
__('Enabling this option excludes all tables associated with deleted sites from the Backup.', 'duplicator-pro') . '<br><br>' .
__(
'When deleting a site in a multisite; WordPress deletes the tables of items related to the core, however it is not assumed that the tables of third party plugins are removed.', // phpcs:ignore Generic.Files.LineLength
'duplicator-pro'
) . ' ' .
__('With a multisite with a large number of deleted sites the database may be full of unused tables.', 'duplicator-pro') . ' ' .
__('With this option only the tables of currently existing sites will be included in the backup.', 'duplicator-pro');
$toolTipTablesFilters = __(
"Checked tables will be <b>excluded</b> from the database script.
Excluding certain tables can cause your site or plugins to not work correctly after install!",
'duplicator-pro'
) . '<br><br>' .
__(
"Use caution when excluding tables! It is highly recommended to not exclude WordPress core tables in red with an *,
unless you know the impact.",
'duplicator-pro'
);
?>
<label class="lbl-larger">
<?php esc_html_e('Database Filters:', 'duplicator-pro'); ?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
title="<?php esc_attr_e('Database filters allow you to exclude table from the backup.', 'duplicator-pro'); ?>"
aria-expanded="false"></i>
</label>
<div class="margin-bottom-1">
<label>
<input
type="checkbox"
id="dbfilter-on"
name="dbfilter-on" <?php checked($dbFilterOn); ?>
class="margin-0">&nbsp;<?php esc_html_e('Enable', 'duplicator-pro'); ?>
</label>
</div>
<div class="db-filter-section">
<label class="lbl-larger">
<?php esc_html_e("Table Prefixes:", 'duplicator-pro') ?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
title="<?php echo esc_attr($toolTipPrefixFilterContent); ?>"
aria-expanded="false"></i>
</label>
<div class="margin-bottom-1">
<label>
<input
type="checkbox"
id="db-prefix-filter"
name="db-prefix-filter"
class="margin-0"
<?php checked($dbPrefixFilter); ?>
<?php disabled(!$dbFilterOn); ?>
data-prefix-value="<?php echo esc_attr($wpdb->prefix); ?>" />
<?php
esc_html_e('Filter tables without current WordPress prefix', 'duplicator-pro');
echo isset($wpdb->prefix) ? '&nbsp;<i>(' . esc_html($wpdb->prefix) . ')</i>&nbsp;' : '';
?>
</label>
</div>
<?php if (is_multisite()) { ?>
<label class="lbl-larger">
<?php esc_html_e("Subsites:", 'duplicator-pro') ?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e("Multisite-Subsite Filters", 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($toolTipSubsiteFilterContent); ?>">
</i>
</label>
<div class="margin-bottom-1">
<label>
<input
type="checkbox"
id="db-prefix-sub-filter"
name="db-prefix-sub-filter"
class="margin-0"
<?php checked($dbPrefixSubFilter); ?>
<?php disabled(!$dbFilterOn); ?>>
<?php esc_html_e("Filter/Hide Tables of Deleted Multisite-Subsites", 'duplicator-pro') ?>
</label>
</div>
<?php } ?>
<label class="lbl-larger">
<?php esc_html_e("Exclude Tables:", 'duplicator-pro') ?>
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip="<?php echo esc_attr($toolTipTablesFilters); ?>">
</i>
</label>
<div id="dup-db-filter-items">
<div class="dup-db-filter-buttons">
<span id="dbnone" class="link-style gray dup-db-filter-none">
<i class="fa-regular fa-square-minus fa-lg" title="<?php esc_html_e('Unfilter All Tables', 'duplicator-pro'); ?>"></i>
</span>&nbsp;
<span id="dball" class="link-style gray dup-db-filter-all">
<i class="fa-regular fa-square-check fa-lg" title="<?php esc_html_e('Filter All Tables', 'duplicator-pro'); ?>"></i>
</span>
</div>
<div id="dup-db-tables-exclude-wrapper">
<div id="dup-db-tables-exclude">
<input type="hidden" id="dup-db-tables-lists" name="dbtables-list" value="">
<?php
$substesIds = SnapWP::getSitesIds();
foreach (WpDbUtils::getTablesList() as $table) {
$info = SnapWP::getTableInfoByName($table, $wpdb->prefix);
$classes = ['table-item'];
if ($info['isCore']) {
$classes[] = 'core-table';
$core_note = '*';
if ($info['subsiteId'] > 0) {
$classes[] = ' subcore-table-' . ($info['subsiteId'] % 2);
}
} else {
$core_note = '';
}
$dbTableCount++;
$cboxClasses = ['dup-pseudo-checkbox'];
$checked = in_array($table, $tSelected);
if ($info['subsiteId'] > 1 && !in_array($info['subsiteId'], $substesIds)) {
$classes[] = 'no-subsite-exists';
if ($dbPrefixSubFilter) {
$cboxClasses[] = 'disabled';
$checked = true;
}
}
if ($info['havePrefix'] == false) {
$classes[] = 'no-prefix-table';
if ($dbPrefixFilter) {
$cboxClasses[] = 'disabled';
$checked = true;
}
}
if ($checked) {
$cboxClasses[] = 'checked';
}
?>
<label class="<?php echo esc_attr(implode(' ', $classes)); ?>">
<span
class="<?php echo esc_attr(implode(' ', $cboxClasses)); ?>"
aria-checked="<?php echo $checked ? "true" : "false"; ?>"
role="checkbox"
data-value="<?php echo esc_attr($table); ?>">
</span>
&nbsp;<span><?php echo esc_html($table . $core_note); ?></span>
</label>
<?php } ?>
</div>
</div>
</div>
</div>
<script>
jQuery(function($) {
/* METHOD: Toggle Database table filter red icon */
DupliJs.Pack.ToggleDBFiltersRedIcon = function() {
if (
$("#dbfilter-on").is(':checked')
) {
$('#dup-archive-filter-db-icon').show();
$('#db-prefix-filter').prop('disabled', false);
$('#db-prefix-sub-filter').prop('disabled', false);
} else {
$('#dup-archive-filter-db-icon').hide();
$('#db-prefix-filter').prop('disabled', true);
$('#db-prefix-sub-filter').prop('disabled', true);
}
}
DupliJs.Pack.ToggleDBFilters = function() {
var filterItems = $('#dup-db-filter-items');
if (
$("#dbfilter-on").is(':checked')
) {
$('.db-filter-section').removeClass('no-display');
filterItems.removeClass('disabled');
$('#dup-db-filter-items-no-filters').hide();
} else {
$('.db-filter-section').addClass('no-display');
filterItems.addClass('disabled');
$('#dup-db-filter-items-no-filters').show();
}
DupliJs.Pack.ToggleDBFiltersRedIcon();
};
DupliJs.Pack.FillExcludeTablesList = function() {
let values = $("#dup-db-tables-exclude .dup-pseudo-checkbox.checked")
.map(function() {
return this.getAttribute('data-value');
})
.get()
.join();
$('#dup-db-tables-lists').val(values);
};
DupliJs.Pack.ToggleNoPrefixTables = function(removeCheckOnEnable = true) {
let checkNode = $('#db-prefix-filter');
let display = !checkNode.is(":checked");
$("#dup-db-tables-exclude .no-prefix-table").each(function() {
let checkBox = $(this).find(".dup-pseudo-checkbox").first();
if (display) {
checkBox.removeClass('disabled');
if (removeCheckOnEnable) {
checkBox.removeClass("checked");
}
} else {
checkBox
.addClass('disabled')
.addClass("checked");
}
});
DupliJs.Pack.ToggleDBFiltersRedIcon();
}
DupliJs.Pack.ToggleNoSubsiteExistsTables = function(removeCheckOnEnable = true) {
let checkNode = $('#db-prefix-sub-filter');
let display = !checkNode.is(":checked");
$("#dup-db-tables-exclude .no-subsite-exists").each(function() {
let checkBox = $(this).find(".dup-pseudo-checkbox").first();
if (display) {
checkBox.removeClass('disabled');
if (removeCheckOnEnable) {
checkBox.removeClass("checked");
}
} else {
checkBox
.addClass('disabled')
.addClass("checked");
}
});
DupliJs.Pack.ToggleDBFiltersRedIcon();
}
});
jQuery(document).ready(function($) {
let tablesToExclude = $("#dup-db-tables-exclude");
$('.dup-db-filter-none').click(function() {
tablesToExclude.find(".dup-pseudo-checkbox.checked").removeClass("checked");
});
$('.dup-db-filter-all').click(function() {
tablesToExclude.find(".dup-pseudo-checkbox:not(.checked)").addClass("checked");
});
$('#db-prefix-sub-filter').change(DupliJs.Pack.ToggleNoSubsiteExistsTables);
$('#db-prefix-filter').change(DupliJs.Pack.ToggleNoPrefixTables);
$('#dbfilter-on').change(DupliJs.Pack.ToggleDBFilters);
DupliJs.Pack.ToggleDBFilters();
});
</script>

View File

@@ -0,0 +1,48 @@
<?php
/**
* Activity Log integration upgrade notice template
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<div>
<p><b><?php esc_html_e('Activity Log Integration Update', 'duplicator-pro'); ?></b></p>
<p>
<?php esc_html_e('Failed backups are no longer shown in the main backup list.', 'duplicator-pro'); ?>
<?php
echo esc_html(
sprintf(
_n(
'%d failed backup has been moved to the Activity Log.',
'%d failed backups have been moved to the Activity Log.',
$tplData['count'],
'duplicator-pro'
),
$tplData['count']
)
);
?>
<?php
printf(
esc_html__(
'You can view them in the %1$sActivity Log%2$s.',
'duplicator-pro'
),
'<a href="' . esc_url($tplData['activityLogUrl']) . '">',
'</a>'
);
?>
</p>
</div>

View File

@@ -0,0 +1,34 @@
<?php
/**
* Failed backups notice template
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<img src="<?php echo esc_url(plugins_url('duplicator-pro/assets/img/warning.png')); ?>"
style="float:left; padding:0 10px 0 5px"
alt="<?php esc_attr_e('Warning', 'duplicator-pro'); ?>" />
<div style="margin-left: 70px;">
<p><b><?php esc_html_e('Failed Backups Detected', 'duplicator-pro'); ?></b></p>
<p>
<?php
printf(
esc_html__(
'One or more backups have failed. To view failure details, check the %1$sActivity Log%2$s.',
'duplicator-pro'
),
'<a href="' . esc_url($tplData['activityLogUrl']) . '">',
'</a>'
);
?>
</p>
</div>

View File

@@ -0,0 +1,40 @@
<?php
/**
* Duplicator Backup row in table Backups list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<?php echo esc_html(
sprintf(
_x(
'There are currently (%1$s) orphaned Backup files taking up %2$s of space.
These Backup files are no longer visible in the backups list below and are safe to remove.',
'%1$s is the number of orphaned packages, %2$s is the total size of orphaned packages',
'duplicator-pro'
),
$tplData['count'],
$tplData['size']
)
); ?>
<br>
<?php esc_html_e(
'Go to: Tools > General > Information > Stored Data > look for the [Delete Backups Orphans] button for more details.',
'duplicator-pro'
); ?>
<br>
<a href="<?php echo esc_url($tplData['url']); ?>">
<?php esc_html_e('Take me there now!', 'duplicator-pro'); ?>
</a>

View File

@@ -0,0 +1,317 @@
<?php
/**
* Duplicator Backup row in table Backups list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\RecoveryController;
use Duplicator\Controllers\StoragePageController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Package\Create\BuildComponents;
use Duplicator\Package\Recovery\RecoveryStatus;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var ControllersManager $ctrlMng
* @var TplMng $tplMng
* @var array<string, mixed> $tplData
* @var RecoveryStatus $recoverStatus
*/
$recoverStatus = $tplData['recoverStatus'];
$filteredData = $recoverStatus->getFilteredData();
$activeType = $recoverStatus->getType();
$activeLabel = strtolower($recoverStatus->getTypeLabel());
$isLocalStorageSafe = $recoverStatus->isLocalStorageEnabled();
$isWordPressCoreSafe = $recoverStatus->isWordPressCoreComplete();
$isDatabaseSafe = $recoverStatus->isDatabaseComplete();
$isMultisiteComplete = $recoverStatus->isMultisiteComplete();
$editDefaultStorageURL = StoragePageController::getEditDefaultUrl();
//echo '<pre>';var_export($isWordPressCoreSafe); echo '</pre>';
//echo '<pre>';var_export($recoverStatus->activeTemplate); echo '</pre>';
/**
* @var wpdb $wpdb
*/
global $wpdb;
?>
<div class="dup-recover-dlg-notice-box">
<div class="title-area">
<div class="title">
<?php esc_html_e("REQUIREMENTS", 'duplicator-pro'); ?>:
</div>
</div>
<!-- ===============
LOCAL SERVER STORAGE -->
<div class="req-data">
<?php
if ($activeType == $recoverStatus::TYPE_TEMPLATE) {
echo '<i class="far fa-question-circle fa-fw pass"></i>';
} else {
echo $isLocalStorageSafe
? '<i class="far fa-check-circle fa-fw pass"></i>'
: '<i class="far fa-times-circle fa-fw fail"></i>';
}
?>
<a class="req-title" href="javascript:void(0)" onclick="jQuery(this).parent().children('div.req-info').toggle();">
<?php esc_html_e("Local Server Storage", 'duplicator-pro'); ?>
</a>
<div class="req-info">
<i class="fas fa-server fa-fw fa-lg"></i>
<?php esc_html_e("Recovery points require one of the following 'Local Server' storage types:", 'duplicator-pro'); ?>
<ul class="req-info-list">
<li>
<?php
echo sprintf(
"<i class='far fa-hdd fa-fw'></i><sup>"
. wp_kses(ViewHelper::disasterIcon(false), ['i' => ['class' => []]])
. "</sup>&nbsp; "
. "<b><a href='" . esc_url($editDefaultStorageURL) . "' target='_blank'>%s</a></b> %s",
esc_html__('[Local Default]', 'duplicator-pro'),
esc_html__('This is the default built-in local storage type.', 'duplicator-pro')
);
?>
</li>
<li>
<?php
echo sprintf(
"<i class='fas fa-hdd'></i><sup>"
. wp_kses(ViewHelper::disasterIcon(false), ['i' => ['class' => []]])
. "</sup>&nbsp; <b>%s</b> %s",
esc_html__('[Local Non-Default]', 'duplicator-pro'),
esc_html__('This is a custom directory on this server.', 'duplicator-pro')
);
?>
</li>
</ul>
<div class="req-status">
<b><?php esc_html_e("STATUS", 'duplicator-pro'); ?>:</b><br/>
<?php
if ($activeType == $recoverStatus::TYPE_TEMPLATE) {
esc_html_e(
"Templates do not control storage locations, only schedules and new backup creation control this process.",
'duplicator-pro'
);
echo ' ';
esc_html_e('No changes can be made to affect this test.', 'duplicator-pro');
} elseif ($isLocalStorageSafe) {
echo '<span class="darkgreen">';
echo esc_html__("At least one local server storage is associated with this ", 'duplicator-pro') . esc_html($activeLabel) . '.';
echo '</span>';
} else {
echo '<span class="maroon">';
echo esc_html__("No local server storage found for this ", 'duplicator-pro') . esc_html($activeLabel) . '.';
echo '</span>';
}
?>
</div>
</div>
</div>
<!-- ===============
WordPress CORE -->
<div class="req-data">
<?php
echo $isWordPressCoreSafe
? '<i class="far fa-check-circle fa-fw pass"></i>'
: '<i class="far fa-times-circle fa-fw fail"></i>';
?>
<a class="req-title" href="javascript:void(0)" onclick="jQuery(this).parent().children('div.req-info').toggle();">
<?php esc_html_e("WordPress Core Folders", 'duplicator-pro'); ?>
</a>
<div class="req-info">
<i class="fab fa-wordpress-simple fa-fw fa-lg"></i>
<?php esc_html_e(
"A recovery point needs all WordPress core folders included in the backup (wp-admin, wp-content &amp; wp-includes).",
'duplicator-pro'
); ?>
<div class="req-status">
<b><?php esc_html_e("STATUS", 'duplicator-pro'); ?>:</b><br/>
<?php if (($filteredData['dbonly'])) : ?>
<span class="maroon">
<?php esc_html_e(
"Backup is setup as a database only configuration, the core WordPress folders have been excluded automatically.",
'duplicator-pro'
); ?>
</span>
<?php elseif (count($filteredData['filterDirs']) > 0) : ?>
<span class="maroon">
<?php esc_html_e("Filtered out WordPress core folders.", 'duplicator-pro'); ?>
<?php foreach ($filteredData['filterDirs'] as $path) { ?>
<small class="req-paths-data"><?php echo esc_html($path); ?></small>
<?php } ?>
</span>
<?php else : ?>
<span class="darkgreen">
<?php esc_html_e("No WordPress core folder filters set", 'duplicator-pro'); ?>.
</span>
<?php endif; ?>
</div>
</div>
</div>
<?php if (is_multisite()) { ?>
<!-- ===============
Multisite complete-->
<div class="req-data">
<?php
echo $isMultisiteComplete
? '<i class="far fa-check-circle fa-fw pass"></i>'
: '<i class="far fa-times-circle fa-fw fail"></i>';
?>
<a class="req-title" href="javascript:void(0)" onclick="jQuery(this).parent().children('div.req-info').toggle();">
<?php esc_html_e("Multisite", 'duplicator-pro'); ?>
</a>
<div class="req-info">
<?php esc_html_e(
'Some subsites are filterd.',
'duplicator-pro'
); ?>
</div>
</div>
<?php } ?>
<!-- ===============
DATABASE TABLES -->
<div class="req-data">
<?php
echo $isDatabaseSafe
? '<i class="far fa-check-circle fa-fw pass"></i>'
: '<i class="far fa-times-circle fa-fw fail"></i>';
?>
<a class="req-title" href="javascript:void(0)" onclick="jQuery(this).parent().children('div.req-info').toggle();">
<?php esc_html_e("Primary Database Tables", 'duplicator-pro'); ?>
</a>
<div class="req-info">
<i class="fas fa-database fa-fw fa-lg"></i>
<?php
printf(
esc_html_x(
'All database tables with the prefix %1$s must be included in the %2$s for this to be an eligible recovery point.',
'%1$s representes the database prefix and %2$s is one of the following: backup, schedule or template',
'duplicator-pro'
),
'<i>' . esc_html($wpdb->prefix) . '</i>',
esc_html($activeLabel)
);
?>
<div class="req-status">
<b><?php esc_html_e("STATUS", 'duplicator-pro'); ?>:</b><br/>
<?php if (count($filteredData['filterTables']) > 0) : ?>
<?php esc_html_e("Filtered table list", 'duplicator-pro'); ?>:
<?php
foreach ($filteredData['filterTables'] as $table) {
if (strpos($table, $wpdb->prefix) !== false) {
echo '<small class="req-paths-data maroon">' . esc_html($table) . '</small>';
} else {
echo '<small class="req-paths-data darkgreen">' . esc_html($table) . '</small>';
}
}
?>
<?php else : ?>
<span class="darkgreen">
<?php esc_html_e("No table filters set on this backup.", 'duplicator-pro'); ?>
</span>
<?php endif; ?>
</div>
</div>
</div>
<!-- ===============
PACKAGE COMPONENTS-->
<div class="req-data">
<?php if ($recoverStatus->hasRequiredComponents()) { ?>
<i class="far fa-check-circle fa-fw pass"></i>
<?php } else { ?>
<i class="far fa-times-circle fa-fw fail"></i>
<?php } ?>
<a class="req-title" href="javascript:void(0)" onclick="jQuery(this).parent().children('div.req-info').toggle();">
<?php esc_html_e("Backup Components", 'duplicator-pro'); ?>
</a>
<div class="req-info">
<b><?php esc_html_e('Required components:', 'duplicator-pro'); ?>:</b>
<ul class="dup-recovery-package-components-required">
<?php foreach (RecoveryStatus::COMPONENTS_REQUIRED as $component) { ?>
<li>
<span class="label"><?php echo esc_html(BuildComponents::getLabel($component)); ?></span>
<span class="value">
<?php if ($recoverStatus->hasComponent($component)) { ?>
<i class="fas fa-check-circle green"></i> <?php esc_html_e('included', 'duplicator-pro'); ?>
<?php } else { ?>
<i class="fas fa-times-circle maroon"></i> <?php esc_html_e('excluded', 'duplicator-pro'); ?>
<?php } ?>
</span>
</li>
<?php } ?>
</ul>
</div>
</div><br/>
<div class="title-area">
<div class="title">
<?php esc_html_e("NOTES", 'duplicator-pro'); ?>:
</div>
</div>
<div class="req-notes">
<?php
switch ($recoverStatus->getType()) {
case $recoverStatus::TYPE_PACKAGE:
esc_html_e(
'To create a recovery-point enabled backup change the conditions of the backup build or template to meet the requirements listed above.',
'duplicator-pro'
);
echo ' ';
printf(
esc_html_x(
'Then use either the %1$sRecovery Point%2$s tool or the Recovery Point button to set which backup you would like as the active recovery-point.', // phpcs:ignore Generic.Files.LineLength
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . esc_url(RecoveryController::getRecoverPageLink()) . '" target="_blank" >',
'</a>'
);
break;
case $recoverStatus::TYPE_SCHEDULE:
esc_html_e(
'To change the recovery status visit the template link above and make sure that it passes the recovery status test.',
'duplicator-pro'
);
esc_html_e(
'If the local storage test does not pass check the schedule storage types and make sure the local server storage type is selected.',
'duplicator-pro'
);
esc_html_e(
'These steps are optional and only required if you want to enable this schedule as an active recovery point.',
'duplicator-pro'
);
break;
case $recoverStatus::TYPE_TEMPLATE:
esc_html_e(
'To change a template recovery point status to enabled, edit the template and make sure that it passes the recovery status test.',
'duplicator-pro'
);
break;
}
?>
</div>
</div>

View File

@@ -0,0 +1,48 @@
<?php
/**
* Duplicator Backup row in table Backups list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Package\Recovery\RecoveryPackage;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var RecoveryPackage $recoverPackage
*/
$recoverPackage = $tplData['recoverPackage'];
?><!DOCTYPE html>
<html lang="en-US" >
<head>
<title><?php esc_html_e('Recovery Backup Launcher', 'duplicator-pro'); ?></title>
</head>
<body>
<h2><?php printf(esc_html__('Recovery Backup Launcher created on %s', 'duplicator-pro'), esc_html($recoverPackage->getCreated())); ?></h2>
<p>
<?php
printf(
esc_html_x(
'If the installer does not start automatically, you can click on this %1$slink and start it manually%2$s.',
'%1$s and %2$s represent the opening and closing link tags (<a> and </a>)',
'duplicator-pro'
),
'<a href="' . esc_url($recoverPackage->getInstallLink()) . '">',
'</a>'
);
?>
</p>
<script>
window.location.href = <?php echo json_encode($recoverPackage->getInstallLink()); ?>;
</script>
</body>
</html>

View File

@@ -0,0 +1,39 @@
<?php
/**
* Duplicator Backup row in table Backups list
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var \Duplicator\Package\DupPackage $package
*/
$package = $tplData['package'];
$timeDiff = sprintf(
_x('%s ago', '%s represents the time diff, eg. 2 days', 'duplicator-pro'),
$package->getPackageLife('human')
);
?>
<table>
<tr>
<td><b><?php esc_html_e('Backup', 'duplicator-pro'); ?>:</b></td>
<td><?php echo esc_html($package->getName()); ?></td>
</tr>
<tr>
<td><b><?php esc_html_e('Created', 'duplicator-pro'); ?>:</b>&nbsp; </td>
<td>
<?php echo esc_html($package->getCreated()); ?>&nbsp;-&nbsp;<i><?php echo esc_html($timeDiff); ?></i>
</td>
</tr>
</table>

View File

@@ -0,0 +1,98 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Models\ScheduleEntity;
use Duplicator\Models\TemplateEntity;
use Duplicator\Package\Recovery\RecoveryStatus;
use Duplicator\Views\UI\UiDialog;
use Duplicator\Views\ViewHelper;
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
*/
$isList = $tplMng->getDataValueBool('isList');
$template = $tplMng->getDataValueObj('template', TemplateEntity::class);
$schedule = $tplMng->getDataValueObj('schedule', ScheduleEntity::class);
if (isset($schedule)) {
$recoveryStatus = new RecoveryStatus($schedule);
} else {
$recoveryStatus = new RecoveryStatus($template);
}
$isRecoverable = $recoveryStatus->isRecoverable();
$templareRecoveryAlter = new UiDialog();
if (!$isRecoverable) {
$templareRecoveryAlter->title = (
isset($schedule) ?
__('Schedule: Recovery Point', 'duplicator-pro') :
__('Template: Recovery Point', 'duplicator-pro')
);
$templareRecoveryAlter->width = 600;
$templareRecoveryAlter->height = 600;
$templareRecoveryAlter->showButtons = false;
$templareRecoveryAlter->templatePath = 'parts/recovery/widget/template-filters-info';
$templareRecoveryAlter->templateArgs = ['recoveryStatus' => $recoveryStatus];
$templareRecoveryAlter->initAlert();
?>
<script>
jQuery(document).ready(function($) {
$('#dup-template-recoveable-info-<?php echo (int) $templareRecoveryAlter->getUniqueIdCounter(); ?>').click(function() {
<?php $templareRecoveryAlter->showAlert(); ?>
});
});
</script>
<?php
}
?>
<span class="dup-template-recoveable-info-wrapper">
<?php
if ($isRecoverable) {
?>
<?php esc_html_e('Available', 'duplicator-pro'); ?>
<sup><?php ViewHelper::disasterIcon(); ?></sup>
<?php
} else {
?>
<a href="javascript:void(0)"
id="dup-template-recoveable-info-<?php echo (int) $templareRecoveryAlter->getUniqueIdCounter(); ?>"
class="dup-template-recoveable-info"><u><?php esc_html_e('Disabled', 'duplicator-pro'); ?></u></a>
<?php
}
if (!$isList) {
?>
&nbsp;
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
data-tooltip-title="<?php esc_attr_e("Recovery Status", 'duplicator-pro'); ?>"
data-tooltip="<?php
if (!isset($schedule)) {
esc_html_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 {
esc_html_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>
<?php } ?>
</span>

View File

@@ -0,0 +1,86 @@
<?php
use Duplicator\Controllers\ToolsPageController;
use Duplicator\Core\Views\TplMng;
use Duplicator\Models\ScheduleEntity;
use Duplicator\Models\TemplateEntity;
use Duplicator\Package\Recovery\RecoveryStatus;
use Duplicator\Views\ViewHelper;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
/**
* Variables
*
* @var array<string, mixed> $tplData
* @var RecoveryStatus $recoveryStatus
*/
$recoveryStatus = $tplData['recoveryStatus'];
if ($recoveryStatus->getType() == RecoveryStatus::TYPE_SCHEDULE) {
/** @var ScheduleEntity */
$schedule = $recoveryStatus->getObject();
if (($template = $schedule->getTemplate()) === false) {
$template = new TemplateEntity();
$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 TemplateEntity */
$template = $recoveryStatus->getObject();
$tooltipContent = __(
'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 esc_html_e('Status', 'duplicator-pro'); ?>: </b>
<?php esc_html_e('Disabled', 'duplicator-pro'); ?>
<sup>
<i class="fas fa-question-circle fa-xs"
data-tooltip-title="<?php esc_html_e('Recovery Status', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($tooltipContent); ?>">
</i>
</sup>
</div>
<div class="dup-recover-dlg-subinfo">
<table>
<?php if ($recoveryStatus->getType() == RecoveryStatus::TYPE_SCHEDULE) { ?>
<tr>
<td><b><?php esc_html_e("Schedule", 'duplicator-pro'); ?>:</b></td>
<td> <?php echo esc_html($schedule->name); ?></td>
</tr>
<tr>
<td> <b><?php esc_html_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 esc_html_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)) ? esc_html($template->notes) : esc_html__("- no notes -", 'duplicator-pro'); ?></td>
</tr>
<?php } ?>
</table>
</div>
<?php
TplMng::getInstance()->render(
'parts/recovery/exclude_data_box',
['recoverStatus' => $recoveryStatus]
);

View File

@@ -0,0 +1,78 @@
<?php
use Duplicator\Libs\Shell\ShellZipUtils;
use Duplicator\Libs\Snap\SnapServer;
use Duplicator\Package\Archive\PackageArchive;
defined("ABSPATH") or die("");
/**
* Settings > Packages, shell zip message
*
* Variables
*
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
* @var bool $hasShellZip
*/
$hasShellZip = $tplData['hasShellZip'];
if ($hasShellZip) {
esc_html_e('The "Shell Zip" mode allows Duplicator to use the server\'s internal zip command.', 'duplicator-pro');
?>
<br />
<?php
esc_html_e('When available this mode is recommended over the PHP "ZipArchive" mode.', 'duplicator-pro');
} else {
$scanPath = PackageArchive::getScanPaths();
if (count($scanPath) > 1) {
?>
<i style='color:maroon'>
<i class='fa fa-exclamation-triangle'></i>
<?php esc_html_e("This server is not configured for the Shell Zip engine - please use a different engine mode.", 'duplicator-pro'); ?>
</i>
<?php } else { ?>
<i style='color:maroon'>
<i class='fa fa-exclamation-triangle'></i>
<?php esc_html_e("This server is not configured for the Shell Zip engine - please use a different engine mode.", 'duplicator-pro'); ?>
<br />
<?php
printf(
esc_html_x(
'Shell Zip is %1$srecommended%2$s when available. ',
'%1$s and %2$s are html anchor tags or link',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'how-to-work-with-the-different-zip-engines') . '" target="_blank">',
'</a> '
);
printf(
esc_html_x(
'For a list of supported hosting providers %1$sclick here%2$s.',
'%1$s and %2$s are html anchor tags or link',
'duplicator-pro'
),
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'what-host-providers-are-recommended-for-duplicator/') . '" target="_blank">',
'</a> '
);
?>
</i>
<?php
// Show possible solutions for some linux setups
$problems = ShellZipUtils::getShellExecZipProblems();
if (count($problems) > 0 && !SnapServer::isWindows()) {
$shell_tooltip = ' ';
$shell_tooltip .= __("To make 'Shell Zip' available, ask your host to:", 'duplicator-pro');
echo '<br/>';
$i = 1;
foreach ($problems as $problem) {
$shell_tooltip .= "{$i}. {$problem['fix']}<br/>";
$i++;
}
$shell_tooltip .= '<br/>';
echo wp_kses($shell_tooltip, ['br' => []]);
}
}
}
?>

View File

@@ -0,0 +1,46 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<tr>
<th scope="row">
<?php echo esc_html($tplData['fieldLabel']); ?>
</th>
<td>
<fieldset>
<legend class="screen-reader-text">
<span><?php echo esc_html($tplData['fieldLabel']); ?></span>
</legend>
<label>
<input
id="<?php echo esc_attr('dup-id-' . $tplData['fieldName']); ?>"
name="<?php echo esc_attr($tplData['fieldName']); ?>"
type="checkbox"
value="1"
<?php checked($tplData['fieldChecked']); ?>
>
<?php echo esc_html($tplData['fieldCheckboxLabel']); ?>
</label>
<?php if (!empty($tplData['fieldDescription'])) { ?>
<p class="description">
<?php echo esc_html($tplData['fieldDescription']); ?>
</p>
<?php } ?>
</fieldset>
</td>
</tr>

View File

@@ -0,0 +1,197 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Controllers\StoragePageController;
use Duplicator\Core\CapMng;
use Duplicator\Models\Storages\AbstractStorageEntity;
use Duplicator\Models\Storages\StoragesUtil;
use Duplicator\Utils\Logging\DupLog;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$storageList = AbstractStorageEntity::getAll(0, 0, [StoragesUtil::class, 'sortByPriority']);
$filteredStorageIds = $tplData['filteredStorageIds'] ?? [];
$selectedStorageIds = $tplData['selectedStorageIds'] ?? [];
$showAddNew = $tplData['showAddNew'] ?? true;
$minCheck = $tplData['minCheck'] ?? true;
$recoveryPointMsg = $tplData['recoveryPointMsg'] ?? false;
$newStorageUrl = StoragePageController::getEditUrl();
$hasInvalidStorage = false;
?>
<table class="widefat dup-table-list storage-select-list small striped">
<thead>
<tr>
<th></th>
<th><?php esc_html_e('Type', 'duplicator-pro') ?></th>
<th><?php esc_html_e('Name', 'duplicator-pro') ?></th>
<th><?php esc_html_e('Location', 'duplicator-pro') ?></th>
</tr>
</thead>
<tbody>
<?php
foreach ($storageList as $storage) {
$rowClasses = [
'package-row',
'storage-row',
];
try {
$invalidErrorMsg = __('Invalid storage configuration', 'duplicator-pro');
$isValid = $storage->isValid($invalidErrorMsg);
if ($storage->isSupported() && ! $storage->isHidden() && ! $isValid) {
$hasInvalidStorage = true;
}
if (
!$storage->isSupported()
|| $storage->isHidden()
|| in_array($storage->getId(), $filteredStorageIds)
) {
continue;
}
$storageId = (int) $storage->getId();
$isChecked = in_array($storage->getId(), $selectedStorageIds) && $isValid;
$storageEditUrl = esc_url(StoragePageController::getEditUrl($storage));
if (!$isValid) {
$rowClasses[] = 'invalid';
}
?>
<tr class="<?php echo esc_attr(implode(' ', $rowClasses)); ?>">
<td class="storage-checkbox">
<?php
// Build parsley attributes
$parsleyAttrs = [];
if ($minCheck) {
$parsleyAttrs['data-parsley-mincheck'] = '1';
$parsleyAttrs['data-parsley-required'] = 'true';
}
?>
<input
type="checkbox"
id="dup-chkbox-<?php echo esc_attr((string) $storageId); ?>"
name="_storage_ids[]"
class="dupli-storage-input margin-bottom-0"
data-parsley-errors-container="#storage_error_container"
<?php
foreach ($parsleyAttrs as $name => $value) {
printf(
'%s="%s" ',
esc_attr($name),
esc_attr($value)
);
}
?>
value="<?php echo esc_attr((string) $storageId); ?>"
<?php disabled(!$isValid); ?>
<?php checked($isChecked); ?>>
</td>
<td class="storage-type">
<label for="dup-chkbox-<?php echo esc_attr((string) $storageId); ?>" class="dup-store-lbl">
<?php
echo wp_kses(
$storage->getStypeIcon(),
[
'i' => [
'class' => [],
],
'img' => [
'src' => [],
'class' => [],
'alt' => [],
],
]
);
echo '&nbsp;' . esc_html($storage->getStypeName());
if ($recoveryPointMsg && $storage->isLocal()) {
?>
<sup title="<?php esc_attr_e('Recovery Point Capable', 'duplicator-pro'); ?>">
<i class="fas fa-house-fire fa-fw fa-sm"></i>
</sup>
<?php
}
?>
</label>
</td>
<td class="storage-name">
<a href="<?php echo esc_attr($storageEditUrl); ?>" target="_blank">
<?php echo esc_html($storage->getName()); ?>
</a>
<?php if (!$isValid) : ?>
&nbsp;<i class="fas fa-exclamation-triangle alert-color"
title="<?php echo esc_attr($invalidErrorMsg); ?>"
></i>
<?php endif; ?>
</td>
<td class="storage-location">
<?php
echo wp_kses(
$storage->getHtmlLocationLink(),
[
'a' => [
'href' => [],
'target' => [],
],
]
);
?>
</td>
</tr>
<?php
} catch (Exception $e) {
$rowClasses[] = 'invalid';
?>
<tr class="<?php echo esc_attr(implode(' ', $rowClasses)); ?>">
<td class="storage-checkbox">
<input type="checkbox" <?php disabled(true); ?> <?php checked(false); ?>>
</td>
<td colspan='4'>
<i class="fas fa-exclamation-triangle alert-color" ></i>
<?php esc_html_e('Unable to load storage type. Please validate the setup.', 'duplicator-pro'); ?>
<strong><?php esc_html_e('Error:', 'duplicator-pro'); ?></strong>
<?php echo esc_html($e->getMessage()); ?>
</td>
</tr>
<?php
}
}
?>
</tbody>
</table>
<div id="storage_error_container" class="duplicator-error-container"></div>
<?php if ($hasInvalidStorage) : ?>
<div class="notice notice-warning storage-warning-notice inline padding-half margin-top-1">
<i class="fas fa-exclamation-triangle alert-color"></i>
<?php esc_html_e(
'Some storage locations are invalid and cannot be used. Please update their configurations to make them available for backups.',
'duplicator-pro'
); ?>
</div>
<?php endif; ?>
<?php if ($showAddNew) : ?>
<div class="text-right">
<?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 endif; ?>
</div>
<?php endif; ?>

View File

@@ -0,0 +1,72 @@
<?php
/**
* Duplicator page header
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Core\Controllers\SubMenuItem;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (empty($tplData['menuItemsL2'])) {
return;
}
/** @var SubMenuItem[] */ // @phpstan-ignore varTag.nativeType
$items = $tplData['menuItemsL2'];
foreach ($items as $item) {
$id = 'dup-submenu-l2-' . $tplData['currentLevelSlugs'][0] . '-' . $item->slug;
$classes = [
'dup-submenu-l2',
'dup-nav-item',
];
if ($item->active) {
$classes[] = 'active';
}
$attrString = [];
foreach ($item->attributes as $key => $value) {
$attrString[] = $key . '="' . esc_attr($value) . '"';
}
$attrString = count($attrString) > 0 ? implode(' ', $attrString) : '';
if (strlen($item->link) > 0) {
?>
<a
href="<?php echo esc_url($item->link); ?>"
id="<?php echo esc_attr($id); ?>"
class="<?php echo esc_attr(implode(' ', $classes)); ?>"
<?php
echo $attrString; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
>
<?php echo esc_html($item->label); ?>
</a>
<?php
} else {
?>
<span
id="<?php echo esc_attr($id); ?>"
class="<?php echo esc_attr(implode(' ', $classes)); ?>"
<?php
echo $attrString; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
>
<?php echo esc_html($item->label); ?>
</span>
<?php
}
}

View File

@@ -0,0 +1,45 @@
<?php
/**
* Duplicator page header
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
use Duplicator\Core\Controllers\SubMenuItem;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (empty($tplData['menuItemsL3'])) {
return;
}
/** @var SubMenuItem[] */ // @phpstan-ignore varTag.nativeType
$items = $tplData['menuItemsL3'];
?>
<div class="dup-sub-tabs">
<?php
foreach ($items as $item) {
$nodeId = 'dup-submenu-l3-' . $tplData['currentLevelSlugs'][0] . '-' . $tplData['currentLevelSlugs'][1] . '-' . $item->slug;
$classes = ['dup-submenu-l3'];
?>
<span id="<?php echo esc_attr($nodeId); ?>" class="dup-sub-tab-item <?php echo ($item->active ? 'dup-sub-tab-active' : ''); ?>" >
<?php if ($item->active) { ?>
<b><?php echo esc_html($item->label); ?></b>
<?php } else { ?>
<a href="<?php echo esc_url($item->link); ?>" class="<?php echo esc_attr(implode(' ', $classes)); ?>" >
<span><?php echo esc_html($item->label); ?></span>
</a>
<?php } ?>
</span>
<?php } ?>
</div>

View File

@@ -0,0 +1,21 @@
<?php
/**
* Duplicator page header
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<p>TEMPLATE <?php echo __FILE__; ?></p>
<pre><?php var_dump($tplData); ?></pre>

View File

@@ -0,0 +1,82 @@
<?php
/**
* Duplicator messages sections
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var \Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$serverSettings = $tplData['serverSettings'];
?>
<table class="widefat" cellspacing="0">
<?php foreach ($serverSettings as $section) : ?>
<tr>
<td class="dupli-settings-diag-header" colspan="2"><?php echo esc_html($section['title']); ?></td>
</tr>
<?php foreach ($section['settings'] as $setting) : ?>
<tr>
<td>
<?php if (!empty($setting['labelLink'])) : ?>
<a href="<?php echo esc_url($setting['labelLink']); ?>" target="_blank">
<?php echo esc_html($setting['label']); ?>
</a>
<?php else : ?>
<?php echo esc_html($setting['label']); ?>
<?php endif; ?>
</td>
<td>
<?php echo esc_html($setting['value']); ?>
<?php if (!empty($setting['valueNote'])) : ?>
<small>
<i>
<?php echo wp_kses(
$setting['valueNote'],
[
'a' => [
'href' => [],
'target' => [],
],
]
); ?>
</i>
</small>
<?php endif; ?>
<?php if (!empty($setting['valueNoteBottom'])) : ?>
<p>
<small>
<i>
<?php echo wp_kses(
$setting['valueNoteBottom'],
[
'a' => [
'href' => [],
'target' => [],
],
]
); ?>
</i>
</small>
</p>
<?php endif; ?>
<?php if (!empty($setting['valueTooltip'])) : ?>
<i
class="fa fa-question-circle data-size-help"
data-tooltip-title="<?php echo __('Info', 'duplicator-pro'); ?>"
data-tooltip="<?php echo esc_attr($setting['valueTooltip']); ?>">
</i>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
</table>